[
  {
    "path": ".dependabot/config.yml",
    "content": "version: 1\nupdate_configs:\n  - package_manager: 'javascript'\n    directory: '/'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'chore'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-react'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'chore'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-html'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'chore'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-electron'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-hapi'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-express'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-koa'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-lambda'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-hapi/examples/basic'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-express/examples/basic'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-express/examples/graphcool'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-lambda/examples/basic'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n  - package_manager: 'javascript'\n    directory: '/packages/graphql-playground-middleware-koa/examples/basic'\n    update_schedule: 'live'\n    allowed_updates:\n      - match:\n          update_type: 'security'\n    commit_message:\n      prefix: 'fix'\n      prefix_development: 'fix'\n      include_scope: true\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing to this project\n\n[fork]: https://github.com/graphcool/graphql-playground/fork\n[pr]: https://github.com/graphcool/graphql-playground/compare\n[code-of-conduct]: ../CODE_OF_CONDUCT.md\n\nHi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.\n\nPlease note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms.\n\n## Contribution Agreement\n\nAs a contributor, you represent that the code you submit is your original work or that of your employer (in which case you represent you have the right to bind your employer). By submitting code, you (and, if applicable, your employer) are licensing the submitted code to the open source community subject to the MIT license.\n\n\n## Submitting a pull request\n\n0. [Fork][fork] and clone the repository\n0. Create a new branch: `git checkout -b feature/my-new-feature-name`\n0. Run `npm install` or `yarn install` to make sure you've got the latest dependencies.\n0. Make your change\n0. Run the unit tests and make sure they pass and have 100% coverage. (`npm test`)\n0. Push to your fork and [submit a pull request][pr]\n0. Pat your self on the back and wait for your pull request to be reviewed and merged.\n\nHere are a few things you can do that will increase the likelihood of your pull request being accepted:\n\n- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.\n- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).\n- In your pull request description, provide as much detail as possible. This context helps the reviewer to understand the motivation for and impact of the change.\n- Make sure that all the unit tests still pass. PRs with failing tests won't be merged.\n\n## Resources\n\n- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)\n- [Contributing to Open Source on GitHub](https://guides.github.com/activities/contributing-to-open-source/)\n- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)\n- [GitHub Help](https://help.github.com)\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "#### This issue pertains to the following package(s):\n\n- [ ] GraphQL Playground - Electron App\n- [ ] GraphQL Playground HTML\n- [ ] GraphQL Playground\n- [ ] GraphQL Playground Express Middleware\n- [ ] GraphQL Playground Hapi Middleware\n- [ ] GraphQL Playground Koa Middleware\n- [ ] GraphQL Playground Lambda Middleware\n\n#### What OS and OS version are you experiencing the issue(s) on?\n\n\n#### What version of graphql-playground(-electron/-middleware) are you experiencing the issue(s) on?\n\n\n#### What is the expected behavior?\n\n\n#### What is the actual behavior?\n\n\n#### What steps may we take to reproduce the behavior?\n\n\n_Please provide a gif or image of the issue for a quicker response/fix._\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Fixes #.\n\nChanges proposed in this pull request:\n\n- \n\n- \n\n- \n"
  },
  {
    "path": ".gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\nlib\n/middleware\nplayground.css\n*.log\n**/examples/*/yarn.lock\n"
  },
  {
    "path": ".nvmrc",
    "content": "lts/dubnium\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"prettier.singleQuote\": true,\n  \"prettier.trailingComma\": \"all\",\n  \"prettier.semi\": false,\n}\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@graph.cool. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Graphcool\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\"><img src=\"https://imgur.com/5fzMbyV.png\" width=\"269\"></p>\n\n[![npm version](https://badge.fury.io/js/graphql-playground-react.svg)](https://badge.fury.io/js/graphql-playground-react)\n[![graphql](https://circleci.com/gh/graphql/graphql-playground.svg?style=shield)](https://circleci.com/gh/graphql/graphql-playground)\n\n> **SECURITY WARNING:** both `graphql-playground-html` and [all four (4) of it's middleware dependents](#impacted-packages) until `graphql-playground-html@1.6.22` were subject to an  **XSS Reflection attack vulnerability only to unsanitized user input strings** to the functions therein. This was resolved in `graphql-playground-html@^1.6.22`. [More Information](#security-details) [CVE-2020-4038](https://github.com/graphql/graphql-playground/security/advisories/GHSA-4852-vrh7-28rf)\n\n\n**Future of this repository**: See [this issue](https://github.com/graphql/graphql-playground/issues/1366#issuecomment-1062088978) for details.\n\n---\n\nGraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration). <br />\n\n[![](https://i.imgur.com/AE5W6OW.png)](https://graphqlbin.com/v2/6RQ6TM)\n\n## Installation\n\n```sh\n$ brew install --cask graphql-playground\n```\n\n## Features\n\n- ✨ Context-aware autocompletion & error highlighting\n- 📚 Interactive, multi-column docs (keyboard support)\n- ⚡️ Supports real-time GraphQL Subscriptions\n- ⚙ GraphQL Config support with multiple Projects & Endpoints\n- 🚥 Apollo Tracing support\n\n## Security Details\n> **NOTE: only _unsanitized user input_ to the functions in these packages is vulnerable** to the recently reported XSS Reflection attack.\n\n### Impact\n\n> Impacted are any and all unsanitized **user-defined** input to:\n-`renderPlaygroundPage()`\n-`koaPlayground()`\n-`expressPlayground()`\n-`koaPlayground()`\n-`lambdaPlayground()\n\n>  If you used static values, such as `graphql-playground-electron` does in [it's webpack config](https://github.com/prisma-labs/graphql-playground/blob/main/packages/graphql-playground-electron/webpack.config.build.js#L16), as well as the most common middleware implementations out there, they were not vulnerable to the attack.\n\nThe only reason this vulnerability exists is because we are using template strings in `renderPlaygroundPage()` with potentially unsanitized user defined variables. This allows an attacker to inject html and javascript into the page. \n- [Read more about preventing XSS in react](https://pragmaticwebsecurity.com/files/cheatsheets/reactxss.pdf)\n\nCommon examples may be user-defined path parameters, query string, unsanitized UI provided values in database, etc., that are used to build template strings or passed directly to a `renderPlaygroundPage()` or the matching middleware function equivalent listed above.\n\n### Impacted Packages\n\n**All versions of these packages are impacted until the ones specified below**, which are now safe for user defined input:\n\n- `graphql-playground-html`: **☔ safe** @ `1.6.22`\n- `graphql-playground-express` **☔ safe** @ `1.7.16`\n- `graphql-playground-koa` **☔ safe** @ `1.6.15`\n- `graphql-playground-hapi` **☔ safe** @ `1.6.13`\n- `graphql-playground-lambda` **☔ safe** @ `1.7.17`\n- `graphql-playground-electron` has always been **☔ safe** from XSS attacks! This is because configuration is statically defined [it's webpack config](https://github.com/prisma-labs/graphql-playground/blob/main/packages/graphql-playground-electron/webpack.config.build.js#L16)\n- `graphql-playground-react` is safe because it does not use `renderPlaygroundPage()` anywhere, and thus is not susceptible to template string XSS reflection attacks.\n\n### More Information\n\nSee the [security docs](./SECURITY.md) for more details on how your implementation might be impacted by this vulnerability. It contains safe examples, unsafe examples, workarounds, and more details.\n\nWe've also provided ['an example of the xss using the express middleware]('https://github.com/prisma-labs/graphql-playground/tree/main/packages/graphql-playground-html/examples/xss-attack')\n\n## FAQ\n\n### How is this different from [GraphiQL](https://github.com/graphql/graphiql)?\n\nGraphQL Playground uses components of GraphiQL under the hood but is meant as a more powerful GraphQL IDE enabling better (local) development workflows. Compared to GraphiQL, the GraphQL Playground ships with the following additional features:\n\n- Interactive, multi-column schema documentation\n- Automatic schema reloading\n- Support for GraphQL Subscriptions\n- Query history\n- Configuration of HTTP headers\n- Tabs\n\nSee the following question for more additonal features.\n\n### What's the difference between the desktop app and the web version?\n\nThe desktop app is the same as the web version but includes these additional features:\n\n- Partial support for [graphql-config](https://github.com/prismagraphql/graphql-config) enabling features like multi-environment setups (no support for sending HTTP headers).\n- Double click on `*.graphql` files.\n\n### How does GraphQL Bin work?\n\nYou can easily share your Playgrounds with others by clicking on the \"Share\" button and sharing the generated link. You can think about GraphQL Bin like Pastebin for your GraphQL queries including the context (endpoint, HTTP headers, open tabs etc).\n\n<a href=\"https://graphqlbin.com/OksD\" target=\"_blank\">\n <img src=\"https://camo.githubusercontent.com/daf8c64dbde3097fdbe782c0645552550d530a73/68747470733a2f2f696d6775722e636f6d2f48316e36346c4c2e706e67\" alt=\"\" data-canonical-src=\"https://imgur.com/H1n64lL.png\" style=\"max-width:100%;\">\n</a>\n\n> You can also find the announcement blog post [here](https://blog.graph.cool/introducing-graphql-playground-f1e0a018f05d).\n\n## Settings\n\nIn the top right corner of the Playground window you can click on the settings icon.\nThese are the settings currently available:\n\n```js\n{\n  'editor.cursorShape': 'line', // possible values: 'line', 'block', 'underline'\n  'editor.fontFamily': `'Source Code Pro', 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace`,\n  'editor.fontSize': 14,\n  'editor.reuseHeaders': true, // new tab reuses headers from last tab\n  'editor.theme': 'dark', // possible values: 'dark', 'light'\n  'general.betaUpdates': false,\n  'prettier.printWidth': 80,\n  'prettier.tabWidth': 2,\n  'prettier.useTabs': false,\n  'request.credentials': 'omit', // possible values: 'omit', 'include', 'same-origin'\n  'schema.polling.enable': true, // enables automatic schema polling\n  'schema.polling.endpointFilter': '*localhost*', // endpoint filter for schema polling\n  'schema.polling.interval': 2000, // schema polling interval in ms\n  'schema.disableComments': boolean,\n  'tracing.hideTracingResponse': true,\n  'tracing.tracingSupported': true, // set false to remove x-apollo-tracing header from Schema fetch requests\n}\n```\n\n## Usage\n\n### Properties\n\nThe React component `<Playground />` and all middlewares expose the following options:\n\n- `props` (Middlewares & React Component)\n  - `endpoint` [`string`](optional) - the GraphQL endpoint url.\n  - `subscriptionEndpoint` [`string`](optional) - the GraphQL subscriptions endpoint url.\n  - `workspaceName` [`string`](optional) - in case you provide a GraphQL Config, you can name your workspace here\n  - `config` [`string`](optional) - the JSON of a GraphQL Config. See an example [here](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-react/src/localDevIndex.tsx#L47)\n  - `settings` [`ISettings`](optional) - Editor settings in json format as [described here](https://github.com/prismagraphql/graphql-playground#settings)\n\n```ts\ninterface ISettings {\n  'editor.cursorShape': 'line' | 'block' | 'underline'\n  'editor.fontFamily': string\n  'editor.fontSize': number\n  'editor.reuseHeaders': boolean\n  'editor.theme': 'dark' | 'light'\n  'general.betaUpdates': boolean\n  'prettier.printWidth': number\n  'prettier.tabWidth': number\n  'prettier.useTabs': boolean\n  'request.credentials': 'omit' | 'include' | 'same-origin'\n  'request.globalHeaders': { [key: string]: string }\n  'schema.polling.enable': boolean\n  'schema.polling.endpointFilter': string\n  'schema.polling.interval': number\n  'schema.disableComments': boolean\n  'tracing.hideTracingResponse': boolean\n  'tracing.tracingSupported': boolean\n}\n```\n\n- `schema` [`IntrospectionResult`](optional) - The result of an introspection query (an object of this form: `{__schema: {...}}`) The playground automatically fetches the schema from the endpoint. This is only needed when you want to override the schema.\n- `tabs` [`Tab[]`](optional) - An array of tabs to inject. **Note: When using this feature, tabs will be resetted each time the page is reloaded**\n\n```ts\ninterface Tab {\n  endpoint: string\n  query: string\n  name?: string\n  variables?: string\n  responses?: string[]\n  headers?: { [key: string]: string }\n}\n```\n\nIn addition to this, the React app provides some more properties:\n\n- `props` (React Component)\n- `createApolloLink` [`(session: Session, subscriptionEndpoint?: string) => ApolloLink`] - this is the equivalent to the `fetcher` of GraphiQL. For each query that is being executed, this function will be called\n\n`createApolloLink` is only available in the React Component and not the middlewares, because the content must be serializable as it is being printed into a HTML template.\n\n### As HTML Page\n\nIf you simply want to render the Playground HTML on your own, for example when implementing a GraphQL Server, there are 2 options for you:\n\n1.  [The bare minimum HTML needed to render the Playground](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-html/minimal.html)\n2.  [The Playground HTML with full loading animation](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-html/withAnimation.html)\n\nNote: In case you do not want to serve assets from a CDN (like jsDelivr) and instead use a local copy, you will need to install `graphql-playground-react` from npm, and then replace all instances of `//cdn.jsdelivr.net/npm` with `./node_modules`. An example can be found [here](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-html/minimalWithoutCDN.html)\n\n### As React Component\n\n#### Install\n\n```sh\nyarn add graphql-playground-react\n```\n\n#### Use\n\nGraphQL Playground provides a React component responsible for rendering the UI and Session management.\nThere are **3 dependencies** needed in order to run the `graphql-playground-react` React component.\n\n1.  _Open Sans_ and _Source Code Pro_ fonts\n2.  Rendering the `<Playground />` component\n\nThe GraphQL Playground requires **React 16**.\n\nIncluding Fonts (`1.`)\n\n```html\n<link\n  href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,700\"\n  rel=\"stylesheet\"\n/>\n```\n\nIncluding stylesheet and the component (`2., 3.`)\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport { Provider } from 'react-redux'\nimport { Playground, store } from 'graphql-playground-react'\n\nReactDOM.render(\n  <Provider store={store}>\n    <Playground endpoint='https://api.graph.cool/simple/v1/swapi' />\n  </Provider>,\n  document.body,\n)\n```\n\n### As Server Middleware\n\n#### Install\n\n```sh\n# Pick the one that matches your server framework\nyarn add graphql-playground-middleware-express  # for Express or Connect\nyarn add graphql-playground-middleware-hapi\nyarn add graphql-playground-middleware-koa\nyarn add graphql-playground-middleware-lambda\n```\n\n#### Usage with example\n\nWe have a full example for each of the frameworks below:\n\n- **Express:** See [packages/graphql-playground-middleware-express/examples/basic](https://github.com/prismagraphql/graphql-playground/tree/main/packages/graphql-playground-middleware-express/examples/basic)\n\n- **Hapi:** See [packages/graphql-playground-middleware-hapi](https://github.com/prismagraphql/graphql-playground/tree/main/packages/graphql-playground-middleware-hapi)\n\n- **Koa:** See [packages/graphql-playground-middleware-koa](https://github.com/prismagraphql/graphql-playground/tree/main/packages/graphql-playground-middleware-koa)\n\n- **Lambda (as serverless handler):** See [serverless-graphql-apollo](https://github.com/serverless/serverless-graphql-apollo) or a quick example below.\n\n### As serverless handler\n\n#### Install\n\n```sh\nyarn add graphql-playground-middleware-lambda\n```\n\n#### Usage\n\n`handler.js`\n\n```js\nimport lambdaPlayground from 'graphql-playground-middleware-lambda'\n// or using require()\n// const lambdaPlayground = require('graphql-playground-middleware-lambda').default\n\nexports.graphqlHandler = function graphqlHandler(event, context, callback) {\n  function callbackFilter(error, output) {\n    // eslint-disable-next-line no-param-reassign\n    output.headers['Access-Control-Allow-Origin'] = '*'\n    callback(error, output)\n  }\n\n  const handler = graphqlLambda({ schema: myGraphQLSchema })\n  return handler(event, context, callbackFilter)\n}\n\nexports.playgroundHandler = lambdaPlayground({\n  endpoint: '/dev/graphql',\n})\n```\n\n`serverless.yml`\n\n```yaml\nfunctions:\n  graphql:\n    handler: handler.graphqlHandler\n    events:\n      - http:\n          path: graphql\n          method: post\n          cors: true\n  playground:\n    handler: handler.playgroundHandler\n    events:\n      - http:\n          path: playground\n          method: get\n          cors: true\n```\n\n#### Security Issue\n\nThere is an [XSS Reflection Vulnerability](./SECURITY.md) when using these middlewares with unsanitized user input before\n\n## Development\n\n```sh\n$ cd packages/graphql-playground-react\n$ yarn\n$ yarn start\n```\n\nOpen\n[localhost:3000/localDev.html?endpoint=https://api.graph.cool/simple/v1/swapi](http://localhost:3000/localDev.html?endpoint=https://api.graph.cool/simple/v1/swapi) for local development!\n\n### Contributing to this project\n\nThis repository is managed by EasyCLA. Project participants must sign the free ([GraphQL Specification Membership agreement](https://preview-spec-membership.graphql.org) before making a contribution. You only need to do this one time, and it can be signed by [individual contributors](http://individual-spec-membership.graphql.org/) or their [employers](http://corporate-spec-membership.graphql.org/).\n\nTo initiate the signature process please open a PR against this repo. The EasyCLA bot will block the merge if we still need a membership agreement from you.\n\nYou can find [detailed information here](https://github.com/graphql/graphql-wg/tree/main/membership). If you have issues, please email [operations@graphql.org](mailto:operations@graphql.org).\n\nIf your company benefits from GraphQL and you would like to provide essential financial support for the systems and people that power our community, please also consider membership in the [GraphQL Foundation](https://foundation.graphql.org/join).\n\n## Custom Theme\n\nFrom `graphql-playground-react@1.7.0` on you can provide a `codeTheme` property to the React Component to customize your color theme.\nThese are the available options:\n\n```ts\nexport interface EditorColours {\n  property: string\n  comment: string\n  punctuation: string\n  keyword: string\n  def: string\n  qualifier: string\n  attribute: string\n  number: string\n  string: string\n  builtin: string\n  string2: string\n  variable: string\n  meta: string\n  atom: string\n  ws: string\n  selection: string\n  cursorColor: string\n  editorBackground: string\n  resultBackground: string\n  leftDrawerBackground: string\n  rightDrawerBackground: string\n}\n```\n\n### Versions\n\nThis is repository is a \"mono repo\" and contains multiple packages using [Yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/). Please be aware that versions are **not** synchronised between packages. The versions of the [release page](https://github.com/graphcool/graphql-playground/releases) refer to the electron app.\n\n### Packages\n\nIn the folder `packages` you'll find the following packages:\n\n- `graphql-playground-electron`: Cross-platform electron app which uses `graphql-playground-react`\n- `graphql-playground-html`: Simple HTML page rendering a version of `graphql-playground-react` hosted on JSDeliver\n- `graphql-playground-middleware-express`: Express middleware using `graphql-playground-html`\n- `graphql-playground-middleware-hapi`: Hapi middleware using `graphql-playground-html`\n- `graphql-playground-middleware-koa`: Koa middleware using `graphql-playground-html`\n- `graphql-playground-middleware-lambda`: AWS Lambda middleware using `graphql-playground-html`\n- `graphql-playground-react`: Core of GraphQL Playground built with ReactJS\n\n<a name=\"help-and-community\" />\n\n## Help & Community [![Discord](https://img.shields.io/discord/586999333447270440.svg)](https://discord.gg/EXUYPaY)\n\nJoin our [Discord Server](https://discord.gg/EXUYPaY) if you run into issues or have questions. We love talking to you!\n\n<p align=\"center\"><a href=\"https://oss.prisma.io\"><img src=\"https://imgur.com/IMU2ERq.png\" alt=\"Prisma\" height=\"170px\"></a></p>\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Known Vulnerabilities\n\n- [2021: Introspection Schema Phishing Attack XSS Vulnerability](docs/security/2021-schema-xss-phishing-attack.md)\n- [2020: XSS Reflection Vulnerability](docs/security/2020-xss-template-injection.md)\n"
  },
  {
    "path": "docs/security/2020-xss-template-injection.md",
    "content": "## XSS Reflection Vulnerability\n\nthe origin of the vulnerability is in `renderPlaygroundPage`, found in `graphql-playground-html`\n\n### Impact\n\nWhen using\n\n- `renderPlaygroundPage()`,\n- `koaPlayground()`\n- `expressPlayground()`\n- `koaPlayground()`\n- `lambdaPlayground()`\n- any downstream dependent packages that use these functions\n\nwithout sanitization of user input, your application is vulnerable to an XSS Reflection Attack. This is a serious vulnerability that could allow for exfiltration of data or user credentials, or to disrupt systems.\n\nWe've provided ['an example of the xss using the express middleware]('https://github.com/prisma-labs/graphql-playground/tree/main/packages/graphql-playground-middleware-express/examples/xss-attack')\n\n### Impacted Packages\n\n**All versions of these packages are impacted until those specified below**, which are now safe for user defined input:\n\n- `graphql-playground-html`: **☔ safe** @ `1.6.22`\n- `graphql-playground-express` **☔ safe** @ `1.7.16`\n- `graphql-playground-koa` **☔ safe** @ `1.6.15`\n- `graphql-playground-hapi` **☔ safe** @ `1.6.13`\n- `graphql-playground-lambda` **☔ safe** @ `1.7.17`\n\n### Static input was always safe\n\nThese examples are safe for _all versions_ **because input is static**\n\nwith `express` and `renderPlaygroundPage`:\n\n```js\napp.get('/playground', (req) => {\n  res.html(\n    renderPlaygroundPage({\n      endpoint: `/our/graphql`,\n    }),\n  )\n  next()\n})\n```\n\nwith `expressPlayground`:\n\n```js\n// params\napp.get('/playground', (req) =>\n  expressPlayground({\n    endpoint: `/our/graphql`,\n    settings: { 'editor.theme': req.query.darkMode ? 'dark' : 'light' },\n  }),\n)\n```\n\nwith `koaPlayground`:\n\n```js\nconst koa = require('koa')\nconst koaRouter = require('koa-router')\nconst koaPlayground = require('graphql-playground-middleware-koa')\n\nconst app = new koa()\nconst router = new koaRouter()\n\nrouter.all('/playground', koaPlayground({ endpoint: '/graphql' }))\n```\n\n### Vulnerable Examples\n\nHere are some examples where the vulnerability would be present before the patch, because of unfiltered user input\n\n```js\nconst express = require('express')\nconst expressPlayground = require('graphql-playground-middleware-express')\n  .default\n\nconst app = express()\n\napp.use(express.json())\n\n// params\napp.get('/playground/:id', (req) =>\n  expressPlayground({\n    endpoint: `/our/graphql/${req.params.id}`,\n  }),\n)\n\n// params\napp.get('/playground', (req) =>\n  expressPlayground({\n    endpoint: `/our/graphql`,\n    // any settings that are unsanitized user input, not just `endpoint`\n    settings: { 'editor.fontFamily': req.query.font },\n  }),\n)\n```\n\n[See a proof of concept](packages/graphql-playground-html/examples/xss-attack) to understand the vulnerability better\n\n### Workaround\n\nTo fix this issue without the update, you can sanitize however you want.\n\nWe suggest using [`xss`](https://www.npmjs.com/package/xss) (what we use for our own fix)\n\nFor example, with `graphql-playground-middleware-express`:\n\n```js\nconst express = require('express')\nconst { filterXSS } = require('xss')\nconst expressPlayground = require('graphql-playground-middleware-express')\n  .default\n\n\nconst app = express()\n\nconst filter = (val) => filterXSS(val, {\n  whitelist: [],\n  stripIgnoreTag: true,\n  stripIgnoreTagBody: ['script']\n})\n\n// simple example\napp.get('/playground/:id', (req) =>\n  expressPlayground({ endpoint: `/graphql/${filter(req.params.id)}` })\n\n// advanced params\napp.get('/playground', (req) =>\n  expressPlayground(JSON.parse(filter(JSON.stringify(req.query))))\n```\n\n[See a proof of concept workaround](packages/graphql-playground-html/examples/xss-attack), example #3\n"
  },
  {
    "path": "docs/security/2021-schema-xss-phishing-attack.md",
    "content": "## GraphQL Playground introspection schema template injection attack: Advisory Statement\n\nThis is a security advisory for an XSS vulnerability in `graphql-playground`.\n\nA similar vulnerability affects `graphiql`, the package from which `graphql-playground` was forked. There is a corresponding `graphiql` [advisory](https://github.com/graphql/graphiql/security/advisories/GHSA-x4r7-m2q9-69c8).\n\n- [1. Impact](#1-impact)\n- [2. Scope](#2-scope)\n- [3. Patches](#3-patches)\n- [4. Reproducing the exploit](#4-reproducing-the-exploit)\n- [5. Credit](#5-credit)\n- [6. For more information](#6-for-more-information)\n\n### 1. Impact\n\nAll versions of `graphql-playground-react` older than `graphql-playground-react@1.7.28` are vulnerable to compromised HTTP schema introspection responses or `schema` prop values with malicious GraphQL type names, exposing a dynamic XSS attack surface that can allow code injection on operation autocomplete.\n\nIn order for the attack to take place, the user must load a malicious schema in `graphql-playground`. There are several ways this can occur, including by specifying the URL to a malicious schema in the `endpoint` query parameter. If a user clicks on a link to a GraphQL Playground installation that specifies a malicious server, arbitrary JavaScript can run in the user's browser, which can be used to exfiltrate user credentials or other harmful goals.\n\n### 2. Scope\n\nThis advisory describes the impact on the `graphql-playground-react` package. The vulnerability also affects `graphiql`, the package from which `graphql-playground` was forked, with a less severe impact; see the [`graphiql` advisory](https://github.com/graphql/graphiql/security/advisories/GHSA-x4r7-m2q9-69c8) for details. It affects all versions of `graphql-playground-react` older than `v1.7.28`.\n\nThis vulnerability was introduced with the first public release of `graphql-playground`, so it impacts both the original legacy `graphql-playground` and the contemporary `graphql-playground-react` npm package. It is most easily exploited on `graphql-playground-react@1.7.0` and newer, as that release added functionality which made it possible to override the endpoint URL via query parameter even if it is explicitly specified in the code.\n\n`graphql-playground-react` is commonly loaded via the `graphql-playground-html` package or a middleware package that wraps it (`graphql-playground-express`, `graphql-playground-middleware-koa`, `graphql-playground-middleware-hapi`, or `graphql-playground-middleware-lambda`). By default, these packages render an HTML page which loads the *latest* version of `graphql-playground-react` through a CDN. If you are using one of these packages to install GraphQL Playground on your domain *and you do not explicitly pass the `version` option to `renderPlaygroundPage` or the middleware function*, then you do not need to take any action to resolve this vulnerability, as the latest version of the React app will automatically be loaded.\n\n`graphql-playground-react` is also commonly loaded via HTML served by Apollo Server. Apollo Server always pins a specific version of `graphql-playground-react`, so if you are using Apollo Server you do need to take action to resolve this vulnerability. See the [Apollo Server advisory](https://github.com/apollographql/apollo-server/security/advisories/GHSA-qm7x-rc44-rrqw) for details.\n\n\n### 3. Patches\n\n`graphql-playground-react@1.7.28` addresses this issue via defense in depth:\n\n- **HTML-escaping text** that should be treated as text rather than HTML. In most of the app, this happens automatically because React escapes all interpolated text by default. However, one vulnerable component uses the unsafe `innerHTML` API and interpolated type names directly into HTML. We now properly escape that type name, which fixes the known vulnerability.\n\n- **Validates the schema** upon receiving the introspection response or schema changes. Schemas with names that violate the GraphQL spec will no longer be loaded. (This includes preventing the Doc Explorer from loading.) This change is also sufficient to fix the known vulnerability.\n\n- **Ensuring that user-generated HTML is safe**. Schemas can contain Markdown in `description` and `deprecationReason` fields, and the web app renders them to HTML using the `markdown-it` library. Prior to `graphql-playground-react@1.7.28`, GraphQL Playground used two separate libraries to render Markdown: `markdown-it` and `marked`. As part of the development of `graphql-playground-react@1.7.28`, we verified that our use of `markdown-it` prevents the inclusion of arbitrary HTML. We use `markdown-it` without setting `html: true`, so we are comfortable relying on [`markdown-it`'s HTML escaping](https://github.com/markdown-it/markdown-it/blob/master/docs/security.md) here. We considered running a second level of sanitization over all rendered Markdown using a library such as `dompurify` but believe that is unnecessary as `markdown-it`'s sanitization appears to be adequate. `graphiql@1.4.3` does update to the latest version of `markdown-it` (v12, from v10) so that any security fixes in v11 and v12 will take effect. On the other hand, [`marked`](https://github.com/markedjs/marked) recommends the use of a separate HTML sanitizer if its input is untrusted. In this release, we switch the one component which uses `marked` to use `markdown-it` like the rest of the app.\n\n**If you are using `graphql-playground-react` directly in your client app**, upgrade to version 1.7.28 or later.\n\n**If you are using `graphql-playground-html` or a package which starts with `graphql-playground-middleware-` in your server** and you are passing the `version` option to a function imported from that package, change that `version` option to be at least `\"1.7.28\"`.\n\n**If you are using `graphql-playground-html` or a package which starts with `graphql-playground-middleware-` in your server** and you are **NOT** passing the `version` option to a function imported from that package, no action is necessary; your app automatically loads the latest version of `graphql-playground-react` from CDN.\n\n\n### 4. Reproducing the exploit\n\nWe are hosting a \"malicious\" server at https://graphql-xss-schema.netlify.app/graphql . This server has a hard-coded introspection result that includes unsafe HTML in type names.\n\nIf you manually change a GraphQL Playground installation to use that endpoint, clear the operation pane, and type `{x` into the operation pane, an alert will pop up; this demonstrates execution of code provided by the malicious server.\n\nAn URL like https://YOUR-PLAYGROUND-SERVER/?endpoint=https%3A%2F%2Fgraphql-xss-schema.netlify.app%2Fgraphql&query=%7B will load already configured with the endpoint in question. (This URL-based exploit works on `graphql-playground-react@1.7.0` and newer; older versions may be protected from this particular URL-based exploit depending on their configuration.)\n### 5. Credit\n\nThis vulnerability was discovered by [@Ry0taK](https://github.com/Ry0taK), thank you! :1st_place_medal:\n\nOthers who contributed:\n\n- extensive help from [@glasser](https://github.com/glasser) at [Apollo](https://github.com/apollographql)\n- [@acao](https://github.com/acao)\n- [@imolorhe](https://github.com/imolorhe)\n- [@divyenduz](https://github.com/divyenduz)\n- [@dotansimha](https://github.com/dotansimha)\n- [@timsuchanek](http://github.com/timsuchanek)\n- [@benjie](https://github.com/Ry0taK) and many others who provided morale support\n\n### 6. For more information\n\nIf you have any questions or comments about this advisory:\n\n- The `graphiql` advisory document contains [more information](https://github.com/graphql/graphiql/blob/main/docs/security/2021-introspection-schema-xss.md#2-more-details-on-the-vulnerability) about how both the client-side and server-side vulnerabilities work\n- Open an issue in the [graphql-playground repo](https://github.com/graphql/graphql-playground/new/issues)\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"version\": \"independent\",\n  \"packages\": [\"packages/*\"],\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true,\n  \"command\": {\n    \"publish\": {\n      \"allowBranch\": [\"main\"],\n      \"preDistTag\": \"next\",\n      \"distTag\": \"latest\",\n      \"conventionalCommits\": true\n    },\n    \"version\": {\n      \"ignoreChanges\": [\n        \"'__tests__' '**/*.spec.js' '**/*.spec.js' '**/*.spec.ts'\",\n        \"**/examples/**\",\n        \"**/public/**\",\n        \"public/**\",\n        \"packages/*/yarn.lock\",\n        \"**/*.md\"\n      ],\n      \"message\": \"chore(release): publish\"\n    }\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"workspaces\": [\n    \"packages/*\"\n  ],\n  \"scripts\": {\n    \"build\": \"bash scripts/build.sh\",\n    \"show-versions\": \"bash scripts/versions.sh\",\n    \"release-html\": \"bash scripts/release-html.sh\",\n    \"release-react\": \"bash scripts/release-react.sh\",\n    \"prepublishOnly\": \"yarn build\"\n  },\n  \"devDependencies\": {\n    \"@hapi/hapi\": \"19.1.1\",\n    \"@types/node\": \"12.12.34\",\n    \"aws-lambda\": \"1.0.5\",\n    \"express\": \"4.17.1\",\n    \"koa\": \"2.11.0\",\n    \"lerna\": \"^3.22.0\",\n    \"rimraf\": \"3.0.2\"\n  },\n  \"dependencies\": {\n    \"dotenv\": \"8.2.0\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/.babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/preset-env\", \"@babel/preset-react\"\n  ],\n  \"plugins\": [\n    \"styled-jsx-postcss/babel\",\n    \"@babel/plugin-proposal-object-rest-spread\",\n    \"babel-plugin-styled-components\"\n  ]\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/.gitignore",
    "content": ".DS_STORE\n*.log\n.vscode\nnode_modules\ndist\n.tmp\nlib\n.idea\n*.iml\n*.swp\n*.swo\n.envrc\n.netlify\n.tags\n.yarnclean\n.awcache\ndll\n.happypack\nbuild-electron\n"
  },
  {
    "path": "packages/graphql-playground-electron/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.8.15](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.14...graphql-playground-electron@1.8.15) (2020-10-20)\n\n**Note:** Version bump only for package graphql-playground-electron\n\n\n\n\n\n## [1.8.14](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.13...graphql-playground-electron@1.8.14) (2020-09-15)\n\n**Note:** Version bump only for package graphql-playground-electron\n\n\n\n\n\n## [1.8.13](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.12...graphql-playground-electron@1.8.13) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-electron\n\n\n\n\n\n## [1.8.12](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.11...graphql-playground-electron@1.8.12) (2020-08-30)\n\n\n### Bug Fixes\n\n* upgrades, schema viewer display & width adjustment ([2bb34bb](https://github.com/graphcool/graphql-playground/commit/2bb34bb8fb8c356e10435727a3f82cd23464b6b6))\n\n\n\n\n\n## 1.8.11 (2020-06-07)\n\n\n### Bug Fixes\n\n* hapi and koa mws for next release ([#1217](https://github.com/graphcool/graphql-playground/issues/1217)) ([40c35fc](https://github.com/graphcool/graphql-playground/commit/40c35fc4c73b939d002c9d2dff51eed5dd0b6aa9))\n* **deps:** [security] bump lodash.merge ([2e6b2e5](https://github.com/graphcool/graphql-playground/commit/2e6b2e5fc59c9f7fbbad5398d0defc1a0b3bd849))\n* **deps:** [security] bump minimist ([a77ca5d](https://github.com/graphcool/graphql-playground/commit/a77ca5d64d9fe7b209e8a732d189570ba750eb3e))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n* **deps-dev:** [security] bump electron ([98ffd72](https://github.com/graphcool/graphql-playground/commit/98ffd722362820a867a9eef9ef51e5098f45afde))\n* **deps-dev:** [security] bump webpack-dev-server ([a0a784d](https://github.com/graphcool/graphql-playground/commit/a0a784dd57af53799e781b876c9c80354e37c6a0))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n\n## 1.8.2 (2018-11-14)\n\n\n\n# 1.8.0 (2018-10-16)\n\n\n### Features\n\n* update graphql-config dependency ([bb6baa1](https://github.com/graphcool/graphql-playground/commit/bb6baa1c26a0f72af73018acbe722c979f892322))\n\n\n\n## 1.6.2 (2018-07-06)\n\n\n\n## 1.6.1 (2018-06-26)\n\n\n\n# 1.6.0 (2018-05-31)\n\n\n### Bug Fixes\n\n* **deps:** update dependency styled-jsx to v2.2.6 ([#543](https://github.com/graphcool/graphql-playground/issues/543)) ([b110cc9](https://github.com/graphcool/graphql-playground/commit/b110cc95c3d68cb7fae136b5d1dbbeb49b8a603d))\n\n\n\n## 1.5.9 (2018-05-25)\n\n\n### Bug Fixes\n\n* update react dep ([9588758](https://github.com/graphcool/graphql-playground/commit/95887589a7d56570ce6007cd7d164bfc89c8a690))\n\n\n\n## 1.5.7 (2018-05-08)\n\n\n### Bug Fixes\n\n* bump version ([2fdab26](https://github.com/graphcool/graphql-playground/commit/2fdab263f904fc38e3373f5cc3c8dcaa9342d42e))\n\n\n\n## 1.5.6 (2018-04-24)\n\n\n### Bug Fixes\n\n* **electron:** update graphql-config-extension-prisma ([8fd45a1](https://github.com/graphcool/graphql-playground/commit/8fd45a1c27172722c335b4c84b793813c2d52b7e))\n\n\n\n## 1.5.4 (2018-04-12)\n\n\n\n## 1.5.2 (2018-04-02)\n\n\n\n## 1.5.1 (2018-04-02)\n\n\n\n# 1.5.0 (2018-04-01)\n\n\n\n# 1.5.0-rc.5 (2018-03-28)\n\n\n### Bug Fixes\n\n* **electron:** endpoint injection ([39a1110](https://github.com/graphcool/graphql-playground/commit/39a1110a0284ef05c73ada3892c585c85e6e14a2))\n\n\n\n# 1.5.0-rc.4 (2018-03-26)\n\n\n\n# 1.5.0-rc.2 (2018-03-26)\n\n\n\n# 1.5.0-rc.1 (2018-03-23)\n\n\n\n## 1.4.5 (2018-03-15)\n\n\n\n## 1.4.4 (2018-03-02)\n\n\n### Bug Fixes\n\n* **deps:** rm not needed graphql-playground dep ([79b3ef1](https://github.com/graphcool/graphql-playground/commit/79b3ef1f987484923c272dbbc18890433e5f3340))\n* **deps:** update dependency electron-updater to v2.20.1 ([#528](https://github.com/graphcool/graphql-playground/issues/528)) ([ab2e9c3](https://github.com/graphcool/graphql-playground/commit/ab2e9c3d43f2225b546d93473bbde47535365f8e))\n* **deps:** update dependency graphql-config-extension-graphcool to v1.0.6 ([#545](https://github.com/graphcool/graphql-playground/issues/545)) ([9ef55be](https://github.com/graphcool/graphql-playground/commit/9ef55bec0fd3359121ab65fa2a5ff55231feeaec))\n* **deps:** update deps ([c17a8d2](https://github.com/graphcool/graphql-playground/commit/c17a8d25779ba7d3e6e0b18e9b45df86c410c4f5))\n* **deps:** update deps in electron app ([772a04c](https://github.com/graphcool/graphql-playground/commit/772a04cfc684c2e38c376a9ef3abe311090c96d4))\n* **settings:** Expose settings programmatically, update deps ([0356557](https://github.com/graphcool/graphql-playground/commit/03565573869f240675aaa5399bb5f0ac097455c5))\n\n\n\n## 1.4.2 (2018-01-22)\n\n\n\n## 1.4.1 (2018-01-22)\n\n\n### Bug Fixes\n\n* **electron:** Add zoom on CMD + and CMD - ([cc2c4ed](https://github.com/graphcool/graphql-playground/commit/cc2c4edc48c986aa55a76c56362e5109eb393b1f))\n* **electron:** postcss config ([55187dc](https://github.com/graphcool/graphql-playground/commit/55187dcbed2be9c48f24424e6d3ee5f2d60e11e5))\n\n\n\n## 1.3.24 (2018-01-13)\n\n\n### Bug Fixes\n\n* **build:** Fix build, temporarily disable yarn workspace, update graphcool-styles & graphcool-ui de ([af501d7](https://github.com/graphcool/graphql-playground/commit/af501d7a754a14dbacc76439a77434f892828482))\n* **deps:** Updated graphql-config-extension-graphcool ([ef83c09](https://github.com/graphcool/graphql-playground/commit/ef83c097c018a42f7ee65529d6af4ea3928a4281))\n\n\n\n## 1.3.21 (2018-01-04)\n\n\n\n## 1.3.20 (2018-01-04)\n\n\n\n## 1.3.19 (2018-01-03)\n\n\n### Bug Fixes\n\n* electron without graphql config ([bf5a722](https://github.com/graphcool/graphql-playground/commit/bf5a722f484a644a1a64e536ba6bd375dbfce928))\n\n\n\n## 1.3.17 (2018-01-03)\n\n\n\n## 1.3.16 (2017-12-27)\n\n\n\n## 1.3.14 (2017-12-26)\n\n\n\n## 1.3.12 (2017-12-24)\n\n\n\n## 1.3.10 (2017-12-20)\n\n\n### Bug Fixes\n\n* should suggest `graphql-cli` instead of `graphql` ([bbfa0ca](https://github.com/graphcool/graphql-playground/commit/bbfa0ca935dea618208f76c58b86363f27ddf595))\n\n\n\n## 1.3.9 (2017-12-14)\n\n\n\n## 1.3.8-beta.1 (2017-12-12)\n\n\n### Bug Fixes\n\n* Capture keyboard event so it's always called (regardless of any stopPropagation by children) ([56634d0](https://github.com/graphcool/graphql-playground/commit/56634d0c7079854888a7d2d5ec0936d8fd0b06a5))\n* change package.json > author > url to match URI schema ([0a84b89](https://github.com/graphcool/graphql-playground/commit/0a84b89f6a94aeecdf48217b1de661181e0b5741))\n\n\n### Features\n\n* Add Settings to the menu with the shortcut to open on CMD + , (Fixes [#290](https://github.com/graphcool/graphql-playground/issues/290)) ([ead0cae](https://github.com/graphcool/graphql-playground/commit/ead0cae5c4d069f87b61a6cd17d5855f5e215b81))\n\n\n\n# 1.3.0 (2017-12-01)\n\n\n\n# 1.2.0 (2017-11-24)\n\n\n\n## 1.1.1 (2017-11-03)\n\n\n### Bug Fixes\n\n* **desktop:** allow urls without tld - fixes [#138](https://github.com/graphcool/graphql-playground/issues/138) ([be3d2cf](https://github.com/graphcool/graphql-playground/commit/be3d2cfe219211393b6438332b553e6e3d9b7493))\n"
  },
  {
    "path": "packages/graphql-playground-electron/README.md",
    "content": "# Playground\n\nRepository for the electron playground app.\n\n## Development\n```sh\nyarn install\nyarn start\n```\n\n## Production build\n\n```sh\nyarn release\n```\n\nThis will create a `build-electron` folder where you will have the compiled electron app. (The assets will automatically be uploaded to Github if the `GH_TOKEN` env variable is set. See [here](https://www.electron.build/publishing-artifacts) for more.)\n"
  },
  {
    "path": "packages/graphql-playground-electron/package.json",
    "content": "{\n  \"name\": \"graphql-playground-electron\",\n  \"productName\": \"GraphQL Playground\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playground\",\n  \"repository\": \"graphcool/graphql-playground\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration)\",\n  \"version\": \"1.8.15\",\n  \"private\": true,\n  \"author\": {\n    \"name\": \"Graphcool\",\n    \"email\": \"hello@graph.cool\",\n    \"url\": \"https://www.graph.cool\"\n  },\n  \"main\": \"lib/main\",\n  \"build\": {\n    \"appId\": \"cool.graph.playground\",\n    \"mac\": {\n      \"category\": \"public.app-category.developer-tools\",\n      \"icon\": \"static/icons/icon.icns\"\n    },\n    \"win\": {\n      \"icon\": \"static/icons/icon.ico\"\n    },\n    \"linux\": {\n      \"category\": \"Development\",\n      \"target\": [\n        \"AppImage\",\n        \"snap\",\n        \"deb\"\n      ]\n    },\n    \"nsis\": {\n      \"oneClick\": false,\n      \"perMachine\": true,\n      \"allowElevation\": true,\n      \"allowToChangeInstallationDirectory\": true,\n      \"runAfterFinish\": false\n    },\n    \"files\": [\n      \"lib/**/!(*.map)\"\n    ],\n    \"directories\": {\n      \"output\": \"build-electron\"\n    },\n    \"fileAssociations\": {\n      \"ext\": \"graphql\",\n      \"name\": \"GraphQL\",\n      \"role\": \"Editor\"\n    },\n    \"protocols\": {\n      \"name\": \"graphql-playground-protocol\",\n      \"schemes\": [\n        \"graphql-playground\"\n      ]\n    }\n  },\n  \"scripts\": {\n    \"build:ts\": \"rimraf lib && tsc\",\n    \"build:webpack\": \"rimraf ./dist && NODE_ENV=production GRAPHQL_ENDPOINT=$BACKEND_ADDR/system webpack --config webpack.config.build.js && cp -r static/* dist\",\n    \"build\": \"npm run build:ts && npm run build:webpack && cp -r dist lib && rimraf ./build:electron\",\n    \"release\": \"npm run build && electron-builder -lmw\",\n    \"release:mac\": \"npm run build && electron-builder -m\",\n    \"release:win\": \"npm run build && electron-builder -w\",\n    \"release:linux\": \"npm run build && electron-builder -l\",\n    \"library\": \"rimraf .happypack && NODE_ENV=production webpack --config webpack.library.js -p\",\n    \"lint\": \"tslint \\\"src/**/*.ts{,x}\\\" && lint-staged\",\n    \"start\": \"yarn build:ts && concurrently \\\"yarn start:react\\\" \\\"wait-on http://localhost:4040/ && yarn start:electron\\\"\",\n    \"start:react\": \"webpack-dev-server --hot --profile --history-api-fallback --host 0.0.0.0 --port 4040\",\n    \"start:electron\": \"electron lib/main\",\n    \"stats\": \"NODE_ENV=production webpack --config webpack.library.js  --profile --json > stats.json\",\n    \"test\": \"npm run lint\",\n    \"precommit\": \"lint-staged\",\n    \"prettier\": \"prettier --single-quote --no-semi --trailing-comma all --write '*.{js,ts,tsx}' 'src/**/*.{js,ts,tsx}'\"\n  },\n  \"lint-staged\": {\n    \"*.{ts,tsx}\": [\n      \"prettier --single-quote --no-semi --trailing-comma all --write\",\n      \"tslint\",\n      \"git add\"\n    ]\n  },\n  \"pre-push\": [\n    \"test-quick\"\n  ],\n  \"dependencies\": {\n    \"@types/ms\": \"0.7.30\",\n    \"classnames\": \"2.2.5\",\n    \"core-js\": \"^3.6.5\",\n    \"date-fns\": \"1.29.0\",\n    \"electron-is-dev\": \"0.3.0\",\n    \"electron-localshortcut\": \"3.1.0\",\n    \"electron-log\": \"2.2.14\",\n    \"electron-updater\": \"^4.0.0\",\n    \"find-up\": \"^2.1.0\",\n    \"graphcool-styles\": \"0.2.7\",\n    \"graphcool-ui\": \"^0.0.14\",\n    \"graphql\": \"^15.3.0\",\n    \"graphql-config\": \"^2.2.2\",\n    \"graphql-config-extension-graphcool\": \"^1.0.11\",\n    \"graphql-config-extension-prisma\": \"^0.3.0\",\n    \"graphql-playground-html\": \"^1.6.29\",\n    \"graphql-playground-react\": \"^1.7.27\",\n    \"immutable\": \"4.0.0-rc.9\",\n    \"js-yaml\": \"^3.11.0\",\n    \"lodash.merge\": \"^4.6.2\",\n    \"minimist\": \"^1.2.3\",\n    \"ms\": \"^2.1.1\",\n    \"query-string\": \"^5.0.1\",\n    \"raven\": \"^2.4.2\",\n    \"react\": \"16.13.1\",\n    \"react-dom\": \"^16.4.0\",\n    \"react-redux\": \"^7.2.1\",\n    \"redux\": \"^4.0.5\",\n    \"redux-localstorage\": \"^1.0.0-rc5\",\n    \"redux-localstorage-filter\": \"^0.1.1\",\n    \"regenerator-runtime\": \"^0.13.7\",\n    \"reselect\": \"^3.0.1\",\n    \"semver\": \"^5.5.0\",\n    \"styled-jsx\": \"2.2.6\",\n    \"styled-jsx-postcss\": \"git+https://github.com/timsuchanek/styled-jsx-postcss#build3\",\n    \"sweetalert2\": \"^7.21.0\",\n    \"validator\": \"^9.2.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.0.0\",\n    \"@babel/core\": \"^7.0.0\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.0.0\",\n    \"@babel/plugin-proposal-json-strings\": \"^7.0.0\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.0.0\",\n    \"@babel/plugin-syntax-import-meta\": \"^7.0.0\",\n    \"@babel/plugin-transform-runtime\": \"^7.12.0\",\n    \"@babel/preset-env\": \"^7.0.0\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@types/classnames\": \"2.2.3\",\n    \"@types/deasync\": \"0.1.0\",\n    \"@types/jest\": \"22.2.3\",\n    \"@types/node\": \"12.12.34\",\n    \"@types/react\": \"16.9.32\",\n    \"@types/react-addons-test-utils\": \"0.14.20\",\n    \"@types/react-dom\": \"~16.9.6\",\n    \"@types/react-redux\": \"7.1.9\",\n    \"@types/zen-observable\": \"^0.5.3\",\n    \"awesome-typescript-loader\": \"5.0.0\",\n    \"babel-core\": \"^7.0.0-bridge.0\",\n    \"babel-jest\": \"^23.4.2\",\n    \"babel-loader\": \"^8.0.0\",\n    \"babel-plugin-styled-components\": \"^1.8.0\",\n    \"babili-webpack-plugin\": \"0.1.2\",\n    \"concurrently\": \"3.5.1\",\n    \"css-loader\": \"0.28.11\",\n    \"electron\": \"2.0.18\",\n    \"electron-builder\": \"^22.8.1\",\n    \"electron-devtools-installer\": \"3.1.1\",\n    \"extract-text-webpack-plugin\": \"3.0.2\",\n    \"file-loader\": \"1.1.11\",\n    \"fork-ts-checker-webpack-plugin\": \"0.4.1\",\n    \"happypack\": \"5.0.0\",\n    \"html-loader\": \"^1.3.1\",\n    \"html-webpack-plugin\": \"3.2.0\",\n    \"identity-obj-proxy\": \"3.0.0\",\n    \"json-loader\": \"0.5.7\",\n    \"lint-staged\": \"7.1.2\",\n    \"node-noop\": \"1.0.0\",\n    \"polished\": \"1.9.2\",\n    \"postcss-inherit\": \"git+https://github.com/timsuchanek/postcss-inherit#build3\",\n    \"postcss-loader\": \"0.9.1\",\n    \"postcss-simple-vars\": \"3.1.0\",\n    \"prettier\": \"2.0.2\",\n    \"raw-loader\": \"0.5.1\",\n    \"react-addons-test-utils\": \"15.6.2\",\n    \"react-test-renderer\": \"16.4.0\",\n    \"redux-mock-store\": \"1.5.1\",\n    \"rimraf\": \"3.0.2\",\n    \"style-loader\": \"0.20.1\",\n    \"svgo-loader\": \"1.2.1\",\n    \"ts-loader\": \"3.4.0\",\n    \"tslint\": \"5.10.0\",\n    \"tslint-graphcool-frontend\": \"0.0.3\",\n    \"tslint-loader\": \"3.6.0\",\n    \"typescript\": \"3.8.3\",\n    \"url-loader\": \"0.6.2\",\n    \"wait-on\": \"2.1.0\",\n    \"webpack\": \"4.44.1\",\n    \"webpack-bundle-analyzer\": \"3.3.2\",\n    \"webpack-cli\": \"^3.3.12\",\n    \"webpack-dev-server\": \"3.11.0\",\n    \"webpack-uglify-parallel\": \"0.1.4\"\n  },\n  \"resolutions\": {\n    \"**/graphql\": \"0.13.2\",\n    \"**/**/graphql\": \"0.13.2\",\n    \"**/**/**/graphql\": \"0.13.2\",\n    \"**/**/**/**/graphql\": \"0.13.2\",\n    \"**/**/**/**/**/graphql\": \"0.13.2\",\n    \"**/**/**/**/**/**/graphql\": \"0.13.2\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/postcss.config.js",
    "content": "module.exports = ctx => ({\n  plugins: [\n    require('postcss-simple-vars')({\n      variables: () => require('graphcool-styles/dist/variables/variables.js'),\n    }),\n    require('postcss-inherit')({\n      globalStyles: 'node_modules/graphcool-styles/dist/styles.css',\n      propertyRegExp: /^(inherit|extend|p)s?:?$/i,\n    }),\n  ],\n})\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/createWindow.ts",
    "content": "import { BrowserWindow, app, ipcMain } from 'electron'\nimport * as path from 'path'\nimport dev = require('electron-is-dev')\nimport { newWindowConfig } from '../shared/utils'\nimport * as log from 'electron-log'\nimport { WindowContext } from './types'\n\nexport function createWindow(windowContext: WindowContext) {\n  // Create the browser window.\n  const newWindow = new BrowserWindow(newWindowConfig)\n\n  newWindow.loadURL(\n    dev\n      ? 'http://localhost:4040' // Dev server ran by react-scripts\n      : `file://${path.join(__dirname, '..', '/dist/index.html')}`, // Bundled application\n  )\n\n  if (dev) {\n    // If dev mode install react and redux extension\n    // Also open the devtools\n    const {\n      default: installExtension,\n      REACT_DEVELOPER_TOOLS,\n      REDUX_DEVTOOLS,\n    } = require('electron-devtools-installer')\n\n    installExtension(REACT_DEVELOPER_TOOLS)\n      .then(name => log.info(`Added Extension:  ${name}`))\n      .catch(err => log.info('An error occurred: ', err))\n\n    installExtension(REDUX_DEVTOOLS)\n      .then(name => log.info(`Added Extension:  ${name}`))\n      .catch(err => log.info('An error occurred: ', err))\n\n    // newWindow.webContents.openDevTools()\n  }\n\n  windowContext.windows.add(newWindow)\n  windowContext.windowById.set(newWindow.id, newWindow)\n\n  // Emitted when the window is closed.\n  const id = newWindow.id\n  newWindow.on('closed', () => {\n    if (process.platform !== 'darwin' && windowContext.windows.size === 0) {\n      app.quit()\n    }\n    windowContext.windows.delete(newWindow)\n    windowContext.windowById.delete(id)\n    windowContext.windowByPath.forEach((window, cwd) => {\n      if (window === newWindow) {\n        windowContext.windowByPath.delete(cwd)\n      }\n    })\n  })\n\n  // electronLocalShortcut.register(newWindow, 'Cmd+Shift+]', () => {\n  //   send('Tab', 'Next')\n  // })\n\n  // electronLocalShortcut.register(newWindow, 'Cmd+Shift+[', () => {\n  //   send('Tab', 'Prev')\n  // })\n\n  windowContext.readyWindowsPromises[newWindow.id] = new Promise(resolve =>\n    ipcMain.once('ready', resolve),\n  )\n\n  return newWindow\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/index.ts",
    "content": "// TODO enable tslint\n// /* tslint:disable */\nimport {\n  app,\n  BrowserWindow,\n  globalShortcut,\n  ipcMain,\n  protocol,\n  Menu,\n} from 'electron'\nimport * as queryString from 'query-string'\nimport * as fs from 'fs'\nimport * as log from 'electron-log'\nimport { buildTemplate } from './menu'\nimport { createWindow } from './createWindow'\nimport { WindowContext } from './types'\nimport { startUpdates } from './updates'\nimport * as Raven from 'raven'\nRaven.config(\n  'https://cce868d3730e473e9350f1436da7d908:ff5d65389e404b28b5af1d97d8024414@sentry.io/297194',\n).install()\n\nlog.transports.file.level = 'info'\nlog.transports.console.level = 'debug'\n\n\nconst windowContext: WindowContext = {\n  readyWindowsPromises: {},\n  windows: new Set(),\n  windowById: new Map(),\n  windowByPath: new Map(),\n}\n\nlet appResolve\nconst appPromise = new Promise(resolve => (appResolve = resolve))\n\napp.setAsDefaultProtocolClient('graphql-playground')\n\napp.on('open-url', (event, url) => {\n  event.preventDefault()\n\n  const cutIndex = url.indexOf('//')\n  const query = url.slice(cutIndex + 2)\n  const input = queryString.parse(query)\n  let env\n  if (input.env) {\n    try {\n      env = JSON.parse(input.env)\n    } catch (e) {\n      // could\n      console.log('could not get env')\n    }\n  }\n  if (input.envPath) {\n    try {\n      env = JSON.parse(fs.readFileSync(input.envPath, 'utf-8'))\n      fs.unlinkSync(input.envPath)\n    } catch (e) {\n      //\n    }\n  }\n  const msg = JSON.stringify({\n    ...input,\n    env,\n  })\n  forceSend('OpenUrl', msg, input.cwd)\n})\n\napp.on('open-file', (event, filePath) => {\n  event.preventDefault()\n  forceSend('OpenSelectedFile', filePath, filePath)\n})\n\nipcMain.on('online-status-changed', (event, status) => {\n  process.env.CONNECTION = status\n})\n\nipcMain.on('async', (event, arg) => {\n  const focusedWindow = BrowserWindow.getFocusedWindow()\n  if (focusedWindow) {\n    focusedWindow.close()\n  }\n})\n\nipcMain.on('cwd', (event, msg) => {\n  const { cwd, id } = JSON.parse(msg)\n  const window = windowContext.windowById.get(id)\n  windowContext.windowByPath.set(cwd, window)\n})\n\nipcMain.on('CloseWindow', (event, msg) => {\n  const { id } = JSON.parse(msg)\n  const window = windowContext.windowById.get(id)\n  window.close()\n})\n\n// This method will be called when Electron has finished\n// initialization and is ready to create browser windows.\n// Some APIs can only be used after this event occurs.\napp.on('ready', () => {\n  createWindow(windowContext)\n\n  startUpdates()\n\n  const menu = Menu.buildFromTemplate(buildTemplate(windowContext))\n  Menu.setApplicationMenu(menu)\n\n  ipcMain.on('get-file-data', event => {\n    log.info('get-file-data', event)\n    // this.fileAdded(event)\n  })\n\n  ipcMain.on('load-file-content', (event, filePath) => {\n    log.info('load-file-content', event, filePath)\n  })\n\n  protocol.registerFileProtocol('file:', (request, filePath) => {\n    log.info('file:', request, filePath)\n  })\n\n  if (appResolve) {\n    appResolve()\n  }\n})\n\n// Quit when all windows are closed.\napp.on('window-all-closed', () => {\n  // On OS X it is common for applications and their menu bar\n  // to stay active until the user quits explicitly with Cmd + Q\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () => {\n  // On OS X it's common to re-create a window in the app when the\n  // dock icon is clicked and there are no other windows open.\n  if (BrowserWindow.getAllWindows().length === 0) {\n    createWindow(windowContext)\n  }\n})\n\napp.on('will-quit', () => {\n  // Unregister all shortcuts.\n  globalShortcut.unregisterAll()\n})\n\nasync function forceSend(channel: string, arg: string, byPath?: string) {\n  await appPromise\n\n  const currentWindows = BrowserWindow.getAllWindows()\n  let window\n  if (byPath) {\n    window = windowContext.windowByPath.get(byPath)\n    if (\n      !window &&\n      currentWindows.length === 1 &&\n      windowContext.windowByPath.size === 0\n    ) {\n      window = currentWindows[0]\n    }\n  } else {\n    window = currentWindows[0]\n  }\n  let destroyed = null\n  try {\n    destroyed = window ? window.isDestroyed() : null\n  } catch (e) {\n    //\n  }\n  if (!window || destroyed) {\n    window = createWindow(windowContext)\n  }\n  await windowContext.readyWindowsPromises[window.id]\n  window.webContents.send(channel, arg)\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/menu.ts",
    "content": "import {\n  MenuItemConstructorOptions,\n  BrowserWindow,\n  app,\n  autoUpdater,\n} from 'electron'\nimport * as log from 'electron-log'\nimport { WindowContext } from './types'\nimport { createWindow } from './createWindow'\nimport { notify } from './notify'\n\nexport const buildTemplate = (\n  windowContext: WindowContext,\n): MenuItemConstructorOptions[] => [\n  {\n    label: 'Application',\n    submenu: [\n      {\n        label: 'About GraphQL Playground',\n        selector: 'orderFrontStandardAboutPanel:',\n      } as MenuItemConstructorOptions,\n      {\n        label: 'Check For Updates',\n        click: () => {\n          autoUpdater.once('update-not-available', () => {\n            notify({\n              title: 'GraphQL Playground Updates',\n              body: 'Already up to date.',\n            })\n          })\n\n          autoUpdater.checkForUpdates()\n        },\n      },\n      { type: 'separator' },\n      {\n        label: 'Settings',\n        accelerator: 'CmdOrCtrl+,',\n        click: () => send('Tab', 'Settings'),\n      },\n      { type: 'separator' },\n      {\n        label: 'Hide GraphQL Playground',\n        accelerator: 'Cmd+H',\n        role: 'hide',\n      },\n      {\n        label: 'Hide Others',\n        accelerator: 'Option+Cmd+H',\n        role: 'hideOthers',\n      },\n      {\n        label: 'Show All',\n        role: 'unhide',\n      },\n      { type: 'separator', visible: process.platform === 'darwin' },\n      {\n        label: 'Quit',\n        accelerator: 'CmdOrCtrl+Q',\n        click: () => app.quit(),\n      },\n    ],\n  },\n  {\n    label: 'Workspace',\n    submenu: [\n      {\n        label: 'New Workspace',\n        accelerator: 'CmdOrCtrl+N',\n        click: () => {\n          createWindow(windowContext)\n        },\n      },\n      {\n        label: 'New Tab',\n        accelerator: 'CmdOrCtrl+T',\n        click: () => send('Tab', 'New'),\n      },\n      { type: 'separator' },\n      {\n        label: 'Close Workspace',\n        accelerator: 'CmdOrCtrl+Shift+W',\n        role: 'close',\n      },\n      {\n        label: 'Close Tab',\n        accelerator: 'CmdOrCtrl+W',\n        click: () => send('Tab', 'Close'),\n      },\n      {\n        label: 'Open File',\n        accelerator: 'CmdOrCtrl+O',\n        click: () => send('File', 'Open'),\n      },\n      {\n        label: 'Save File',\n        accelerator: 'CmdOrCtrl+S',\n        click: () => send('File', 'Save'),\n      },\n      {\n        label: 'Reload Schema',\n        accelerator: 'CmdOrCtrl+R',\n        click: () => send('Tab', 'ReloadSchema'),\n      },\n    ],\n  },\n  {\n    label: 'Edit',\n    submenu: [\n      {\n        label: 'Undo',\n        accelerator: 'CmdOrCtrl+Z',\n        selector: 'undo:',\n      } as MenuItemConstructorOptions,\n      {\n        label: 'Redo',\n        accelerator: 'Shift+CmdOrCtrl+Z',\n        selector: 'redo:',\n      } as MenuItemConstructorOptions,\n      { type: 'separator' },\n      {\n        label: 'Cut',\n        accelerator: 'CmdOrCtrl+X',\n        selector: 'cut:',\n      } as MenuItemConstructorOptions,\n      {\n        label: 'Copy',\n        accelerator: 'CmdOrCtrl+C',\n        selector: 'copy:',\n      } as MenuItemConstructorOptions,\n      {\n        label: 'Paste',\n        accelerator: 'CmdOrCtrl+V',\n        selector: 'paste:',\n      } as MenuItemConstructorOptions,\n      {\n        label: 'Select All',\n        accelerator: 'CmdOrCtrl+A',\n        selector: 'selectAll:',\n      } as MenuItemConstructorOptions,\n    ],\n  },\n  {\n    label: 'Window',\n    submenu: [\n      {\n        label: 'Next Tab',\n        accelerator: 'CmdOrCtrl+Alt+Right',\n        click: () => send('Tab', 'Next'),\n      },\n      {\n        label: 'Previous Tab',\n        accelerator: 'CmdOrCtrl+Alt+Left',\n        click: () => send('Tab', 'Next'),\n      },\n      {\n        label: 'Minimize',\n        accelerator: 'CmdOrCtrl+M',\n        click: () => {\n          const focusedWindow = BrowserWindow.getFocusedWindow()\n          if (focusedWindow) {\n            focusedWindow.minimize()\n          }\n        },\n      },\n      { type: 'separator' },\n      { label: 'Toggle Developer Tools', role: 'toggledevtools' },\n    ],\n  },\n]\n\nfunction send(channel: string, arg: string) {\n  const focusedWindow = BrowserWindow.getFocusedWindow()\n  if (focusedWindow) {\n    log.info('sending to focused window', channel, arg)\n    focusedWindow.webContents.send(channel, arg)\n  } else {\n    log.info('no focused window')\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/notify.ts",
    "content": "import { shell, Notification } from 'electron'\n\ninterface NotificationOptions {\n  title: string\n  body: string\n  url?: string\n  onClick?: () => void\n}\n\nexport const notify = ({ title, body, url, onClick }: NotificationOptions) => {\n  const notification = new Notification({\n    title,\n    body,\n    silent: true,\n  })\n\n  if (url || onClick) {\n    notification.on('click', () => {\n      if (onClick) {\n        return onClick()\n      }\n\n      shell.openExternal(url)\n    })\n  }\n\n  notification.show()\n  console.log(`[Notification] ${title}: ${body}`)\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/types.ts",
    "content": "import { BrowserWindow } from 'electron'\n\nexport interface WindowContext {\n  readyWindowsPromises: { [windowId: number]: Promise<void> }\n  windows: Set<BrowserWindow>\n  windowById: Map<number, BrowserWindow>\n  windowByPath: Map<string, BrowserWindow>\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/updates.ts",
    "content": "import { app, autoUpdater, ipcMain, BrowserWindow, dialog } from 'electron'\nimport ms = require('ms')\nimport dev = require('electron-is-dev')\nimport * as log from 'electron-log'\nimport { notify } from './notify'\n\nexport const startUpdates = () => {\n  if (!dev) {\n    startAppUpdates()\n  }\n}\n\nconst setUpdateURL = async () => {\n  let betaUpdates = false\n\n  await new Promise(resolve => {\n    ipcMain.once('SettingsResponse', (event, settingsString) => {\n      log.info('settings', settingsString)\n      betaUpdates = getBetaUpdates(settingsString)\n      resolve()\n    })\n\n    send('SettingsRequest', '')\n  })\n\n  const channel = betaUpdates ? 'kygnjrcroc' : 'ppbimurjwk'\n  const server = `https://hazel-server-${channel}.now.sh/update`\n  autoUpdater.setFeedURL({url: `${server}/${process.platform}/${app.getVersion()}`})\n}\n\nconst checkForUpdates = async () => {\n  if (process.env.CONNECTION === 'offline') {\n    // Try again after half an hour\n    setTimeout(checkForUpdates, ms('30m'))\n    return\n  }\n\n  // Ensure we're pulling from the correct channel\n  try {\n    await setUpdateURL()\n  } catch (err) {\n    log.error(err)\n    // Retry later if setting the update URL failed\n    return\n  }\n\n  // Then ask the server for updates\n  autoUpdater.checkForUpdates()\n}\n\nconst startAppUpdates = () => {\n  autoUpdater.on('error', error => {\n    log.error(error)\n    setTimeout(checkForUpdates, ms('15m'))\n  })\n\n  autoUpdater.on('checking-for-update', () => {\n    log.info('Checking for app updates...')\n  })\n\n  autoUpdater.on('update-downloaded', () => {\n    log.info('Update downloaded')\n    const buttonIndex = dialog.showMessageBox({\n      message: `Update downloaded. Install now?`,\n      buttons: ['Install Update & Restart', 'Later'],\n    })\n    if (buttonIndex === 0) {\n      autoUpdater.quitAndInstall()\n      app.quit()\n    }\n  })\n\n  autoUpdater.on('update-available', () => {\n    log.info('Found update for the app! Downloading...')\n    notify({\n      title: 'GraphQL Playground Updates',\n      body: 'Update available. Downloading...',\n    })\n  })\n\n  autoUpdater.on('update-not-available', () => {\n    log.info('No updates found. Checking again in 5 minutes...')\n    setTimeout(checkForUpdates, ms('5m'))\n  })\n\n  setTimeout(checkForUpdates, ms('10s'))\n}\n\nfunction send(channel: string, arg: string) {\n  const window = BrowserWindow.getAllWindows()[0]\n  if (window) {\n    log.info('sending to open window', channel, arg)\n    window.webContents.send(channel, arg)\n  } else {\n    log.info('no opened window')\n  }\n}\n\nfunction getBetaUpdates(settingsString: string | undefined): boolean {\n  try {\n    const settings = JSON.parse(settingsString)\n    return !!settings['general.betaUpdates']\n  } catch (e) {\n    //\n  }\n\n  return false\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/App.tsx",
    "content": "import * as React from 'react'\nimport 'core-js/stable'\nimport 'regenerator-runtime/runtime'\nimport { remote, ipcRenderer, webFrame } from 'electron'\nimport * as cx from 'classnames'\nimport { Playground as IPlayground } from 'graphql-playground-react/lib/components/Playground'\nimport { merge, set } from 'immutable'\nimport Playground, {\n  openSettingsTab,\n  selectNextTab,\n  selectPrevTab,\n  closeSelectedTab,\n  refetchSchema,\n  newSession,\n  store,\n  getSessionsState,\n  saveFile,\n  newFileTab,\n  getEndpoint,\n  selectAppHistoryItem,\n  AppHistoryItem,\n} from 'graphql-playground-react'\nimport {\n  getGraphQLConfig,\n  findGraphQLConfigFile,\n  GraphQLConfigData,\n  resolveEnvsInValues,\n} from 'graphql-config'\nimport { createRemoteWindow } from '../../shared/utils'\nimport InitialView from './InitialView/InitialView'\nimport * as minimist from 'minimist'\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport * as os from 'os'\nimport * as yaml from 'js-yaml'\nimport * as findUp from 'find-up'\nimport {\n  patchEndpointsToConfigData as patchPrismaEndpointsToConfigData,\n  makeConfigFromPath,\n} from 'graphql-config-extension-prisma'\nimport { patchEndpointsToConfigData } from 'graphql-config-extension-graphcool'\nimport { connect } from 'react-redux'\nimport { errify } from '../utils/errify'\nimport { createStructuredSelector } from 'reselect'\nimport * as dotenv from 'dotenv'\n\n// import { PermissionSession } from 'graphql-playground/lib/types'\n\nconst { dialog } = remote\n\n// declare var p: IPlayground\n\ninterface State {\n  endpoint?: string\n  openTooltipTheme: boolean\n  theme: string\n  shareUrl?: string\n  loading: boolean\n  session?: any\n  platformToken?: string\n  configString?: string\n  configPath?: string\n\n  folderName?: string\n  env?: any\n  config?: GraphQLConfigData\n}\n\nipcRenderer.on('SettingsRequest', () => {\n  ipcRenderer.send('SettingsResponse', localStorage.getItem('settings'))\n})\n\nconst events: any[] = []\n\nipcRenderer.on('OpenSelectedFile', pushSelectedFile)\nipcRenderer.on('OpenUrl', pushOpenUrl)\n\nfunction pushSelectedFile() {\n  events.push({\n    type: 'OpenSelectedFile',\n    args: arguments,\n  })\n}\n\nfunction pushOpenUrl() {\n  events.push({\n    type: 'OpenUrl',\n    args: arguments,\n  })\n}\n\ninterface ReduxProps {\n  openSettingsTab: () => void\n  selectNextTab: () => void\n  selectPrevTab: () => void\n  closeSelectedTab: () => void\n  refetchSchema: () => void\n  newSession: (endpoint: string) => void\n  saveFile: () => void\n  newFileTab: (fileName: string, filePath: string, file: string) => void\n  selectAppHistoryItem: (item: AppHistoryItem) => void\n  endpoint: string\n}\n\nclass App extends React.Component<ReduxProps, State> {\n  private playground: IPlayground\n\n  constructor(props) {\n    super(props)\n    const { endpoint, platformToken } = this.getArgs()\n    this.state = {\n      openTooltipTheme: false,\n      theme: 'dark',\n      endpoint,\n      platformToken,\n      loading: false,\n    }\n      ; (global as any).a = this\n      ; (global as any).r = remote\n  }\n\n  fileAdded = event => {\n    // console.log(event)\n  }\n\n  getArgs(): any {\n    const argv = remote.process.argv\n    const args = minimist(argv.slice(1))\n\n    return {\n      endpoint: args.endpoint,\n      subscriptionsEndpoint: args['subscriptions-endpoint'],\n      platformToken:\n        args['platform-token'] || localStorage.getItem('platformToken'),\n      env: args.env,\n    }\n  }\n\n  handleSelectEndpoint = (endpoint: string) => {\n    this.setState({ endpoint } as State)\n  }\n\n  handleSelectFolder = async (folderPath: string) => {\n    try {\n      // Get config from folderPath\n      const envPath = path.join(folderPath, '.env')\n      let env = process.env\n      if (fs.existsSync(envPath)) {\n        const envString = fs.readFileSync(envPath)\n        const localEnv = dotenv.parse(envString)\n        if (localEnv) {\n          env = merge(env, localEnv)\n        }\n      }\n      const configPath = findGraphQLConfigFile(folderPath)\n      const configString = fs.readFileSync(configPath, 'utf-8')\n\n      /* tslint:disable-next-line */\n      //       if (configString.includes('${env:')) {\n      //         errify(`You opened a .graphqlconfig file that includes environment variables.\n      // In order to use environment variables in the Playground, please start it from the graphql cli. Install with\n      // npm install -g graphql-cli\n      // Then open the graphql config with:\n      // cd ${folderPath}; graphql playground`)\n      //       }\n\n      const configDir = path.dirname(configPath)\n      let config\n      try {\n        config = await patchEndpointsToConfigData(\n          resolveEnvsInValues(getGraphQLConfig(configDir).config, env),\n          configDir,\n          env,\n        )\n        config = await patchPrismaEndpointsToConfigData(\n          resolveEnvsInValues(getGraphQLConfig(configDir).config, env),\n          configDir,\n          env,\n        )\n      } catch (e) {\n        const ymlPath = path.join(configDir, 'prisma.yml')\n        if (!fs.existsSync(ymlPath)) {\n          throw e\n        }\n        config = await makeConfigFromPath(configDir)\n      }\n\n      ipcRenderer.send(\n        'cwd',\n        JSON.stringify({ cwd: configDir, id: remote.getCurrentWindow().id }),\n      )\n      const state = {\n        configString,\n        configPath,\n        config,\n        folderName: path.basename(folderPath),\n        env,\n      }\n      this.setState(state as State)\n      this.props.selectAppHistoryItem(merge(state, {\n        type: 'local',\n        path: configPath,\n      }) as any)\n    } catch (error) {\n      errify(error)\n    }\n  }\n\n  handleOpenNewWindow = () => {\n    createRemoteWindow()\n  }\n\n  openSettingsTab = () => {\n    this.props.openSettingsTab()\n  }\n\n  nextTab = () => {\n    this.props.selectNextTab()\n  }\n\n  prevTab = () => {\n    this.props.selectPrevTab()\n  }\n\n  newTab = () => {\n    this.props.newSession(this.props.endpoint)\n  }\n\n  closeTab = () => {\n    this.props.closeSelectedTab()\n  }\n\n  reloadSchema = () => {\n    this.props.refetchSchema()\n  }\n\n  componentDidMount() {\n    ipcRenderer.removeListener('OpenUrl', pushOpenUrl)\n    ipcRenderer.removeListener('OpenSelectedFile', pushSelectedFile)\n    ipcRenderer.on('Tab', this.readTabMessage)\n    ipcRenderer.on('File', this.readFileMessage)\n    ipcRenderer.on('OpenSelectedFile', this.readOpenSelectedFileMessage)\n    ipcRenderer.on('OpenUrl', this.handleUrl)\n    window.addEventListener('keydown', this.handleKeyDown, true)\n    this.consumeEvents()\n    ipcRenderer.send('ready', '')\n    // if (\n    //   !this.state.endpoint &&\n    //   !this.state.config &&\n    //   !this.state.configPath &&\n    //   !this.state.configString\n    // ) {\n    //   const workspace = this.deserializeWorkspace()\n    //   if (workspace) {\n    //     this.setState(workspace)\n    //   }\n    // }\n  }\n\n  consumeEvents() {\n    while (events.length > 0) {\n      const event = events.shift()\n      switch (event.type) {\n        case 'OpenSelectedFile':\n          return this.readOpenSelectedFileMessage.call(this, ...event.args)\n        case 'OpenUrl':\n          return this.handleUrl.call(this, ...event.args)\n      }\n    }\n  }\n\n  componentWillUnmount() {\n    ipcRenderer.removeListener('Tab', this.readTabMessage)\n    ipcRenderer.removeListener('File', this.readFileMessage)\n    ipcRenderer.removeListener(\n      'OpenSelectedFile',\n      this.readOpenSelectedFileMessage,\n    )\n    ipcRenderer.removeListener('OpenUrl', this.handleUrl)\n    window.removeEventListener('keydown', this.handleKeyDown, true)\n  }\n\n  handleKeyDown = e => {\n    if (e.key === '{' && e.metaKey) {\n      this.prevTab()\n    } else if (e.key === '}' && e.metaKey) {\n      this.nextTab()\n    } else if (e.key >= 1 && e.key <= 9 && e.metaKey) {\n      this.playground.switchTab(e.key)\n    } else if (e.key === '=' && e.metaKey) {\n      const zoom = webFrame.getZoomFactor()\n      webFrame.setZoomFactor(zoom + 0.1)\n    } else if (e.key === '-' && e.metaKey) {\n      const zoom = webFrame.getZoomFactor()\n      webFrame.setZoomFactor(zoom - 0.1)\n    }\n  }\n\n  handleUrl = async (event, msg) => {\n    const input = JSON.parse(msg)\n\n    const endpoint = input.endpoint\n    let configString\n    let folderName\n    let configPath\n    const platformToken = input.platformToken\n    let config\n\n    if (input.cwd) {\n      // use the endpoint as an alternative, only log the error\n      try {\n        configPath = findUp.sync(['.graphqlconfig', '.graphqlconfig.yml'], {\n          cwd: input.cwd,\n        })\n        configString = configPath\n          ? fs.readFileSync(configPath, 'utf-8')\n          : undefined\n        folderName = configPath\n          ? path.basename(path.dirname(configPath))\n          : undefined\n        try {\n          const rawConfig = getGraphQLConfig(input.cwd).config\n          const resolvedConfig = resolveEnvsInValues(rawConfig, input.env)\n          config = await patchEndpointsToConfigData(\n            resolvedConfig,\n            input.cwd,\n            input.env,\n          )\n          config = await patchPrismaEndpointsToConfigData(\n            resolvedConfig,\n            input.cwd,\n            input.env,\n          )\n        } catch (e) {\n          const ymlPath = path.join(input.cwd, 'prisma.yml')\n          if (!fs.existsSync(ymlPath)) {\n            throw e\n          }\n          config = (await makeConfigFromPath(input.cwd, input.env)).config\n          configPath = ymlPath\n          folderName = path.basename(input.cwd)\n          configString = JSON.stringify(config)\n        }\n\n        if (!this.configContainsEndpoints(config)) {\n          const graphcoolNote = configString.includes('graphcool')\n            ? 'Please make sure to add stages to your graphcool.yml'\n            : ''\n          errify(\n            `${configPath} does not include any endpoints. ${graphcoolNote}`,\n          )\n          return\n        }\n      } catch (e) {\n        console.error(e)\n        errify(e)\n      }\n    }\n\n    ipcRenderer.send(\n      'cwd',\n      JSON.stringify({ cwd: input.cwd, id: remote.getCurrentWindow().id }),\n    )\n\n    const state = {\n      configString,\n      folderName,\n      configPath,\n      env: input.env,\n      endpoint,\n      config,\n      platformToken,\n    }\n\n    this.props.selectAppHistoryItem(merge(state, {\n      type: 'endpoint',\n      path: configPath,\n    }) as any)\n\n    this.setState(state)\n  }\n\n  configContainsEndpoints(config: GraphQLConfigData): boolean {\n    if (\n      Object.keys((config.extensions && config.extensions.endpoints) || {})\n        .length > 0\n    ) {\n      return true\n    }\n    return Object.keys(config.projects).reduce((acc, curr) => {\n      const project = config.projects[curr]\n      if (\n        project.extensions &&\n        project.extensions.endpoints &&\n        Object.keys(project.extensions.endpoints).length > 0\n      ) {\n        return true\n      }\n\n      return acc\n    }, false)\n  }\n\n  readFileMessage = (event, message) => {\n    switch (message) {\n      case 'Open':\n        this.showOpenDialog()\n        break\n      case 'Save':\n        this.getSaveFileName()\n        break\n    }\n  }\n\n  readOpenSelectedFileMessage = (event, selectedFile) => {\n    if (selectedFile) {\n      this.openFile(selectedFile)\n    }\n  }\n\n  async openFile(fileName: string) {\n    const file = fs.readFileSync(fileName, 'utf-8')\n    if (!this.playground) {\n      this.handleSelectFolder(path.dirname(fileName))\n    }\n    while (!this.playground) {\n      await new Promise(r => setTimeout(r, 200))\n    }\n    await new Promise(r => setTimeout(r, 200))\n    this.props.newFileTab(path.basename(fileName), fileName, file)\n  }\n\n  showOpenDialog() {\n    dialog.showOpenDialog(\n      {\n        title: 'Choose a .graphql file to edit',\n        properties: ['openFile'],\n        // filters: [{\n        //   name: '*',\n        //   extensions: ['graphql']\n        // }]\n      },\n      fileNames => {\n        if (fileNames && fileNames.length > 0) {\n          const file = fileNames[0]\n          this.openFile(file)\n        }\n      },\n    )\n  }\n\n  getSaveFileName(): Promise<string> {\n    return new Promise((resolve, reject) => {\n      // save current tab\n\n      if (this.playground) {\n        const session = getSessionsState(store.getState())\n        if (session.isConfigTab) {\n          this.playground.handleSaveConfig()\n        }\n\n        if (session.isSettingsTab) {\n          this.playground.handleSaveSettings()\n        }\n\n        if (session.isFile && session.filePath) {\n          // TODO\n          // dialog.showSaveDialog(\n          //   {\n          //     title: 'Save Permission Query',\n          //     filters: [\n          //       {\n          //         name: 'Permission File',\n          //         extensions: ['graphql'],\n          //       },\n          //     ],\n          //   },\n          //   (fileName: any) => {\n          //     resolve(fileName)\n          //   },\n          // )\n          this.props.saveFile()\n          fs.writeFileSync(session.filePath, session.file)\n        }\n\n        this.playground.handleSaveConfig()\n      }\n    })\n  }\n\n  saveConfig = (configString: string) => {\n    fs.writeFileSync(this.state.configPath, configString)\n    this.setState({ configString })\n  }\n\n  // async saveFile() {\n  //   const session = this.playground.state.sessions[\n  //     this.playground.state.selectedSessionIndex\n  //   ]\n  //   ;(this.playground as any).setValueInSession(session.id, 'hasChanged', false)\n  //   const fileName =\n  //     (session as any).absolutePath || (await this.getSaveFileName())\n  //   // if (!(session as any).absolutePath) {\n  //   ;(this.playground as any).setValueInSession(\n  //     session.id,\n  //     'name',\n  //     path.basename(fileName),\n  //   )\n  //   ;(this.playground as any).setValueInSession(\n  //     session.id,\n  //     'absolutePath',\n  //     fileName,\n  //   )\n  //   // }\n  //   const query = session.query\n  //   fs.writeFileSync(fileName, query)\n  // }\n\n  getGraphcoolYml(from: string): { ymlPath: string; yml: any } | null {\n    const ymlPath = findUp.sync('graphcool.yml', { cwd: from })\n    if (ymlPath) {\n      const file = fs.readFileSync(ymlPath)\n      try {\n        return {\n          yml: yaml.safeLoad(file),\n          ymlPath,\n        }\n      } catch (e) {\n        // console.error(e)\n      }\n    }\n\n    return null\n  }\n\n  getGraphcoolRc(): any | null {\n    const graphcoolRc = path.join(os.homedir(), '.graphcoolrc')\n    if (fs.existsSync(graphcoolRc)) {\n      const file = fs.readFileSync(graphcoolRc)\n      try {\n        return yaml.safeLoad(file)\n      } catch (e) {\n        // console.error(e)\n      }\n    }\n\n    return null\n  }\n\n  readTabMessage = (error, message) => {\n    switch (message) {\n      case 'Next':\n        this.nextTab()\n        break\n      case 'Prev':\n        this.prevTab()\n        break\n      case 'New':\n        this.newTab()\n        break\n      case 'Close':\n        if (!this.state.endpoint && !this.state.config) {\n          ipcRenderer.send(\n            'CloseWindow',\n            JSON.stringify({ id: remote.getCurrentWindow().id }),\n          )\n        } else {\n          this.closeTab()\n        }\n        break\n      case 'Settings':\n        this.openSettingsTab()\n        break\n      case 'ReloadSchema':\n        this.reloadSchema()\n        break\n    }\n  }\n\n  render() {\n    const { theme, endpoint, platformToken, configString, config } = this.state\n\n    return (\n      <div\n        className={\n          'flex flexColumn bgDarkestBlue overflowHidden ' +\n          cx('root', theme, { noConfig: !configString })\n        }\n      >\n        <style jsx={true} global={true}>{`\n          .app-content .left-content {\n            letter-spacing: 0.5px;\n          }\n          body .root.noConfig .tabs {\n            padding-left: 80px;\n          }\n        `}</style>\n        <style jsx={true}>{`\n          .root {\n            @p: .flex, .flexColumn, .bgDarkestBlue, .overflowHidden;\n          }\n          .root.light {\n            background-color: #dbdee0;\n          }\n          .app-content .playground {\n            @p: .flex1;\n          }\n          .light .sidenav-footer {\n            background-color: #eeeff0;\n          }\n          .sidenav-footer .button {\n            @p: .br2, .black90, .pointer, .pa10, .fw6, .flex, .itemsCenter,\n              .ml20;\n          }\n        `}</style>\n        <InitialView\n          isOpen={!endpoint && !configString}\n          onSelectFolder={this.handleSelectFolder}\n          onSelectEndpoint={this.handleSelectEndpoint}\n          selectHistory={this.handleSelectItem}\n        />\n        {(endpoint || configString) && (\n          <div className=\"playground\">\n            <Playground\n              getRef={this.setRef}\n              endpoint={endpoint}\n              isElectron={true}\n              platformToken={platformToken}\n              configString={configString}\n              config={config}\n              configPath={this.state.configPath}\n              onSaveConfig={this.saveConfig}\n              canSaveConfig={true}\n              env={this.state.env}\n              folderName={this.state.folderName}\n              showNewWorkspace={true}\n              onNewWorkspace={this.handleOpenNewWindow}\n            />\n          </div>\n        )}\n      </div>\n    )\n  }\n\n  private handleSelectItem = ({ type, ...item }) => {\n    this.setState(item as any)\n    this.props.selectAppHistoryItem(set(item, 'lastOpened', new Date()) as any)\n  }\n\n  private setRef = ref => {\n    this.playground = ref\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  endpoint: getEndpoint,\n})\n\nexport default connect(\n  mapStateToProps,\n  {\n    openSettingsTab,\n    selectNextTab,\n    selectPrevTab,\n    closeSelectedTab,\n    refetchSchema,\n    newSession,\n    saveFile,\n    newFileTab,\n    selectAppHistoryItem,\n  },\n)(App)\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/InitialView/InitialView.tsx",
    "content": "import * as React from 'react'\nimport * as isURL from 'validator/lib/isURL'\nimport { remote } from 'electron'\nimport { existsSync } from 'fs'\nimport { resolve } from 'path'\nimport { Icon, $v } from 'graphcool-styles'\nimport Modal from 'graphcool-ui/lib/Modal'\nimport { connect } from 'react-redux'\nimport * as format from 'date-fns/format'\nimport Toggle from './Toggle'\nimport { examples } from './data'\nimport { getAppHistory, AppHistoryItem } from 'graphql-playground-react'\nimport { createStructuredSelector, createSelector } from 'reselect'\nimport { OrderedMap } from 'immutable'\n\ninterface StateFromProps {\n  history: OrderedMap<string, AppHistoryItem>\n}\n\ninterface State {\n  endpoint: string\n  selectedMode: string\n}\n\nexport interface Props {\n  isOpen: boolean\n  onSelectEndpoint: (endpoint: string) => void\n  onSelectFolder: (config: string) => void\n  selectHistory: (history: AppHistoryItem) => any\n}\n\nconst modalStyle = {\n  overlay: {\n    zIndex: 20,\n    backgroundColor: 'rgba(15,32,46,.9)',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n    '-webkit-app-region': 'drag',\n  },\n  content: {\n    position: 'relative',\n    width: 976,\n    height: 'auto',\n    top: 'initial',\n    left: 'initial',\n    right: 'initial',\n    bottom: 'initial',\n    borderRadius: 2,\n    padding: 0,\n    border: 'none',\n    background: 'none',\n    boxShadow: '0 1px 7px rgba(0,0,0,.2)',\n  },\n}\n\nclass InitialView extends React.Component<Props & StateFromProps, State> {\n  state = {\n    endpoint: '',\n    selectedMode: 'local',\n  }\n\n  handleRequestClose = () => null\n\n  handleSubmit = e => {\n    e.preventDefault()\n    if (isURL(this.state.endpoint, { require_tld: false })) {\n      this.props.selectHistory(\n        new AppHistoryItem({\n          type: 'endpoint',\n          path: this.state.endpoint,\n        }),\n      )\n      this.props.onSelectEndpoint(this.state.endpoint)\n    } else {\n      alert('Endpoint is not a valid url')\n    }\n  }\n\n  handleClickLocal = () => {\n    const paths = remote.dialog.showOpenDialog({\n      properties: ['openDirectory'],\n    })\n    if (paths && paths[0]) {\n      const path = paths[0]\n      // Check if there is a .graphqlconfig file in the folder\n      if (\n        !existsSync(resolve(path, '.graphqlconfig')) &&\n        !existsSync(resolve(path, '.graphqlconfig.yml')) &&\n        !existsSync(resolve(path, '.graphqlconfig.yaml'))\n      ) {\n        alert('No .graphqlconfig found in this folder')\n        return\n      }\n      this.setState({ endpoint: path } as State)\n      this.props.onSelectFolder(path)\n    }\n  }\n\n  handleChangeEndpoint = e => {\n    this.setState({ endpoint: e.target.value } as State)\n  }\n\n  handleChangeMode = selectedMode => {\n    this.setState({ selectedMode } as State)\n  }\n\n  handleClickHistory = (history: AppHistoryItem) => {\n    this.props.selectHistory(history)\n  }\n\n  render() {\n    const { isOpen, history } = this.props\n    const { endpoint, selectedMode } = this.state\n    const choicesMode = ['local', 'url endpoint']\n    const items = history.toJS()\n\n    return (\n      <div>\n        <style jsx={true}>{`\n          .initial-view-content {\n            @p: .bgWhite, .flex, .flexRow;\n          }\n          .initial-view-recent {\n            @p: .br, .bBlack10, .overflowHidden, .flex, .flexColumn;\n            flex: 0 30%;\n            max-height: 350px;\n          }\n          .initial-view-recent-header {\n            @p: .pv10, .ph20, .bgBlack07, .black50, .bb, .bBlack10;\n          }\n          .initial-view-recent-list {\n            @p: .flex1;\n            overflow: auto;\n          }\n          .list-item {\n            @p: .pv10, .ph20, .bb, .bBlack10, .pointer;\n          }\n          .list-item-name {\n            @p: .f20, .black70, .fw6, .mb6, .toe, .overflowHidden, .nowrap;\n          }\n          .list-item-date {\n            @p: .f12, .black40, .flex;\n          }\n          .list-item-date span {\n            @p: .ml10;\n          }\n          .initial-view-workspace {\n            @p: .flex1, .tc, .pv20;\n          }\n          .initial-view-workspace .title {\n            @p: .maAuto, .black90;\n          }\n          .initial-view-workspace .description {\n            @p: .maAuto, .black50, .mt16;\n            max-width: 266px;\n            margin-bottom: 80px !important;\n          }\n          .initial-view-workspace .toggle {\n            @p: .justifyCenter, .flex;\n          }\n          .initial-view-workspace .container-input {\n            @p: .ph10, .pv6, .mh38, .mt20, .darkBlue40, .ba, .bBlack10, .br2,\n              .flex, .f14;\n          }\n          .initial-view-workspace .container-input input {\n            @p: .darkBlue60, .w100, .f14;\n          }\n          .initial-view-workspace .container-input button {\n            @p: .white, .br2, .pv6, .ph10, .pointer, .f14, .fw6;\n            letter-spacing: 0.53px;\n            background-color: #2a7ed3;\n          }\n        `}</style>\n        <div className=\"dragable\" />\n        <Modal\n          isOpen={isOpen}\n          contentLabel=\"initial view\"\n          onRequestClose={this.handleRequestClose}\n          style={modalStyle}\n        >\n          <div className=\"initial-view-content bgWhite flex flexRow\">\n            {history.size > 0 ? (\n              <div className=\"initial-view-recent br bBlack10 overflowHidden flex flexColumn\">\n                <div className=\"initial-view-recent-header pv10 ph20 bgBlack07 black50 bb bBlack10\">\n                  RECENT\n                </div>\n                <div className=\"initial-view-recent-list flex1\">\n                  {Object.keys(items)\n                    .reverse()\n                    .map((key) => {\n                      const data = items[key]\n                      const name = data.folderName || data.endpoint || data.path\n                      return (\n                        <div\n                          className=\"list-item pv10 ph20 bb bBlack10 pointer\"\n                          // tslint:disable-next-line\n                          onClick={() => this.handleClickHistory(data)}\n                        >\n                          <div\n                            className=\"list-item-name f20 black70 fw6 mb6 toe overflowHidden nowrap\"\n                            title={name}\n                          >\n                            {name}\n                          </div>\n                          <div className=\"list-item-date f12 black40 flex\">\n                            <Icon\n                              src={\n                                data.type === 'local'\n                                  ? require('../../icons/folder.svg')\n                                  : require('graphcool-styles/icons/fill/world.svg')\n                              }\n                              color={$v.gray40}\n                              width={14}\n                              height={14}\n                            />\n                            <span>\n                              Last opened{' '}\n                              {format(data.lastOpened, 'DD.MM.YYYY')}\n                            </span>\n                          </div>\n                        </div>\n                      )\n                    })}\n                </div>\n              </div>\n            ) : (\n              <div className=\"initial-view-recent br bBlack10 overflowHidden flex flexColumn\">\n                <div className=\"initial-view-recent-header pv10 ph20 bgBlack07 black50 bb bBlack10\">\n                  EXAMPLES\n                </div>\n                <div className=\"initial-view-recent-list flex1\">\n                  {examples.map((example) => (\n                    <div\n                      key={example.endpoint}\n                      className=\"list-item pv10 ph20 bb bBlack10 pointer\"\n                      onClick={() =>\n                        this.props.onSelectEndpoint(example.endpoint)\n                      }\n                    >\n                      <div\n                        className=\"list-item-name f20 black70 fw6 mb6 toe overflowHidden nowrap\"\n                        title={example.endpoint}\n                      >\n                        {example.name}\n                      </div>\n                      <div className=\"list-item-date f12 black40 flex\">\n                        <Icon\n                          src={require('graphcool-styles/icons/fill/world.svg')}\n                          color={$v.gray40}\n                          width={14}\n                          height={14}\n                        />\n                        <span>{example.endpoint}</span>\n                      </div>\n                    </div>\n                  ))}\n                </div>\n              </div>\n            )}\n            <div className=\"initial-view-workspace flex1 tc pv20\">\n              <h1 className=\"title flex1 tc pv20\">New Workspace</h1>\n              <p className=\"description maAuto black50 mt16\">\n                Either load a local repository with a .graphqlconfig file, or\n                just open a HTTP endpoint\n              </p>\n              <div className=\"toggle justifyCenter flex\">\n                <Toggle\n                  choices={choicesMode}\n                  activeChoice={selectedMode}\n                  onChange={this.handleChangeMode}\n                />\n              </div>\n              {selectedMode === 'url endpoint' && (\n                <form\n                  className=\"container-input ph10 pv6 mh38 mt20 darkBlue40 ba bBlack10 br2 flex f14\"\n                  onSubmit={this.handleSubmit}\n                >\n                  <input\n                    className=\"input darkBlue60 w100 f14\"\n                    placeholder=\"Enter endpoint url...\"\n                    value={endpoint}\n                    onChange={this.handleChangeEndpoint}\n                  />\n                  <button className=\"white br2 pv6 ph10 pointer f14 fw6\">\n                    OPEN\n                  </button>\n                </form>\n              )}\n              {selectedMode === 'local' && (\n                <div\n                  className=\"container-input ph10 pv6 mh38 mt20 darkBlue40 ba bBlack10 br2 flex f14\"\n                  onClick={this.handleClickLocal}\n                >\n                  <input\n                    className=\"input darkBlue60 w100 f14\"\n                    placeholder=\"Select a folder...\"\n                    value={endpoint}\n                    onChange={this.handleChangeEndpoint}\n                  />\n                  <button className=\"white br2 pv6 ph10 pointer f14 fw6\">\n                    OPEN\n                  </button>\n                </div>\n              )}\n            </div>\n          </div>\n        </Modal>\n      </div>\n    )\n  }\n}\n\nconst itemsSelector = createSelector([getAppHistory], state => state.items)\n\nconst mapStateToProps = createStructuredSelector({\n  history: itemsSelector,\n})\n\nexport default connect(mapStateToProps)(InitialView as any) as any\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/InitialView/Toggle.tsx",
    "content": "import * as React from 'react'\nimport * as cn from 'classnames'\n\nexport interface ToggleProps {\n  choices: string[]\n  onChange: (choice: string, i: number) => void\n  activeChoice: string\n}\n\n/* tslint:disable */\nconst Toggle = ({ choices, onChange, activeChoice }: ToggleProps) => {\n  return (\n    <div className=\"toggle flex\">\n      <style jsx={true}>{`\n        .toggle {\n          @p: .flex;\n        }\n        .choice {\n          @p: .f14, .ttu, .br2, .mr6, .fw6, .darkBlue40, .pointer;\n          letter-spacing: 0.53px;\n          padding: 5px 9px;\n        }\n        .choice.active {\n          @p: .darkBlue50, .bgDarkBlue10;\n        }\n        .choice:not(.active):hover {\n          @p: .darkBlue50;\n        }\n      `}</style>\n      {choices.map((choice, i) => (\n        <div\n          className={\n            'f14 ttu br2 mr6 fw6 darkBlue40 pointer ' +\n            cn('choice', {\n              'active darkBlue50 bgDarkBlue10': choice === activeChoice,\n            })\n          }\n          key={choice}\n          onClick={() => onChange(choice, i)}\n        >\n          {choice}\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default Toggle\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/InitialView/data.ts",
    "content": "export const examples = [\n  {\n    name: 'Movie Database',\n    endpoint: 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr',\n  },\n  {\n    name: 'Instagram',\n    endpoint: 'https://api.graph.cool/simple/v1/cixne4sn40c7m0122h8fabni1',\n  },\n  {\n    name: 'Pokemon',\n    endpoint: 'https://graphql-pokemon.now.sh',\n  },\n]\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/Loading.tsx",
    "content": "import * as React from 'react'\n\ninterface Props {\n  color?: string\n  width?: number\n  height?: number\n  className?: string\n}\n\nexport default class Loading extends React.Component<Props, {}> {\n  render() {\n    const width = this.props.width || 30\n    const height = this.props.height || 30\n    const backgroundColor = this.props.color || '#000'\n    return (\n      <div\n        style={{ width, height, backgroundColor }}\n        className={`root ${this.props.className}`}\n      >\n        <style jsx={true}>{`\n          div {\n            border-radius: 100%;\n            animation: sk-scaleout 1s infinite ease-in-out;\n          }\n\n          @keyframes sk-scaleout {\n            0% {\n              transform: scale(0);\n            }\n            100% {\n              transform: scale(1);\n              opacity: 0;\n            }\n          }\n        `}</style>\n      </div>\n    )\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/Root.tsx",
    "content": "import * as React from 'react'\nimport App from './App'\nimport { store } from 'graphql-playground-react'\nimport { Provider } from 'react-redux'\n\nexport default class Root extends React.Component {\n  render() {\n    return (\n      <Provider store={store}>\n        <App />\n      </Provider>\n    )\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/index.css",
    "content": "body {\n    overflow: hidden;\n}"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui\">\n  <title>GraphQL Playground</title>\n  <link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,500,700\" rel=\"stylesheet\">\n\n</head>\n\n<body>\n  <style type=\"text/css\">\n    html {\n      font-family: \"Open Sans\", sans-serif;\n      overflow: hidden;\n    }\n\n    body {\n      margin: 0;\n      background: #172a3a;\n    }\n\n    .playgroundIn {\n      -webkit-animation: playgroundIn 0.5s ease-out forwards;\n      animation: playgroundIn 0.5s ease-out forwards;\n    }\n\n    @-webkit-keyframes playgroundIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(10px);\n        -ms-transform: translateY(10px);\n        transform: translateY(10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes playgroundIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(10px);\n        -ms-transform: translateY(10px);\n        transform: translateY(10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n  </style>\n\n  <style type=\"text/css\">\n    .fadeOut {\n      -webkit-animation: fadeOut 0.5s ease-out forwards;\n      animation: fadeOut 0.5s ease-out forwards;\n    }\n\n    @-webkit-keyframes fadeIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes fadeIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @-webkit-keyframes fadeOut {\n      from {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n      to {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n    }\n\n    @keyframes fadeOut {\n      from {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n      to {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n    }\n\n    @-webkit-keyframes appearIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(0px);\n        -ms-transform: translateY(0px);\n        transform: translateY(0px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes appearIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(0px);\n        -ms-transform: translateY(0px);\n        transform: translateY(0px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @-webkit-keyframes scaleIn {\n      from {\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        transform: scale(0);\n      }\n      to {\n        -webkit-transform: scale(1);\n        -ms-transform: scale(1);\n        transform: scale(1);\n      }\n    }\n\n    @keyframes scaleIn {\n      from {\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        transform: scale(0);\n      }\n      to {\n        -webkit-transform: scale(1);\n        -ms-transform: scale(1);\n        transform: scale(1);\n      }\n    }\n\n    @-webkit-keyframes innerDrawIn {\n      0% {\n        stroke-dashoffset: 70;\n      }\n      50% {\n        stroke-dashoffset: 140;\n      }\n      100% {\n        stroke-dashoffset: 210;\n      }\n    }\n\n    @keyframes innerDrawIn {\n      0% {\n        stroke-dashoffset: 70;\n      }\n      50% {\n        stroke-dashoffset: 140;\n      }\n      100% {\n        stroke-dashoffset: 210;\n      }\n    }\n\n    @-webkit-keyframes outerDrawIn {\n      0% {\n        stroke-dashoffset: 76;\n      }\n      100% {\n        stroke-dashoffset: 152;\n      }\n    }\n\n    @keyframes outerDrawIn {\n      0% {\n        stroke-dashoffset: 76;\n      }\n      100% {\n        stroke-dashoffset: 152;\n      }\n    }\n\n    .hHWjkv {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n    }\n\n    .gCDOzd {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n    }\n\n    .hmCcxi {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n    }\n\n    .eHamQi {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n    }\n\n    .byhgGu {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n    }\n\n    .llAKP {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n    }\n\n    .bglIGM {\n      -webkit-transform-origin: 64px 28px;\n      -ms-transform-origin: 64px 28px;\n      transform-origin: 64px 28px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n    }\n\n    .ksxRII {\n      -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;\n      -ms-transform-origin: 95.98500061035156px 46.510000228881836px;\n      transform-origin: 95.98500061035156px 46.510000228881836px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n    }\n\n    .cWrBmb {\n      -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;\n      -ms-transform-origin: 95.97162628173828px 83.4900016784668px;\n      transform-origin: 95.97162628173828px 83.4900016784668px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n    }\n\n    .Wnusb {\n      -webkit-transform-origin: 64px 101.97999572753906px;\n      -ms-transform-origin: 64px 101.97999572753906px;\n      transform-origin: 64px 101.97999572753906px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n    }\n\n    .bfPqf {\n      -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;\n      -ms-transform-origin: 32.03982162475586px 83.4900016784668px;\n      transform-origin: 32.03982162475586px 83.4900016784668px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n    }\n\n    .edRCTN {\n      -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;\n      -ms-transform-origin: 32.033552169799805px 46.510000228881836px;\n      transform-origin: 32.033552169799805px 46.510000228881836px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n    }\n\n    .iEGVWn {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .bsocdx {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .jAZXmP {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .hSeArx {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .bVgqGk {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .hEFqBt {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .dzEKCM {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    .DYnPx {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    .hjPEAQ {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    #loading-wrapper {\n      position: absolute;\n      width: 100vw;\n      height: 100vh;\n      display: -webkit-box;\n      display: -webkit-flex;\n      display: -ms-flexbox;\n      display: flex;\n      -webkit-align-items: center;\n      -webkit-box-align: center;\n      -ms-flex-align: center;\n      align-items: center;\n      -webkit-box-pack: center;\n      -webkit-justify-content: center;\n      -ms-flex-pack: center;\n      justify-content: center;\n      -webkit-flex-direction: column;\n      -ms-flex-direction: column;\n      flex-direction: column;\n    }\n\n    .logo {\n      width: 75px;\n      height: 75px;\n      margin-bottom: 20px;\n      opacity: 0;\n      -webkit-animation: fadeIn 0.5s ease-out forwards;\n      animation: fadeIn 0.5s ease-out forwards;\n    }\n\n    .text {\n      font-size: 32px;\n      font-weight: 200;\n      text-align: center;\n      color: rgba(255, 255, 255, 0.6);\n      opacity: 0;\n      -webkit-animation: fadeIn 0.5s ease-out forwards;\n      animation: fadeIn 0.5s ease-out forwards;\n    }\n\n    .dGfHfc {\n      font-weight: 400;\n    }\n  </style>\n  <div id=\"loading-wrapper\">\n    <svg class=\"logo\" viewBox=\"0 0 128 128\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n      <title>GraphQL Playground Logo</title>\n      <defs>\n        <linearGradient id=\"linearGradient-1\" x1=\"4.86%\" x2=\"96.21%\" y1=\"0%\" y2=\"99.66%\">\n          <stop stop-color=\"#E00082\" stop-opacity=\".8\" offset=\"0%\"></stop>\n          <stop stop-color=\"#E00082\" offset=\"100%\"></stop>\n        </linearGradient>\n      </defs>\n      <g>\n        <rect id=\"Gradient\" width=\"127.96\" height=\"127.96\" y=\"1\" fill=\"url(#linearGradient-1)\" rx=\"4\"></rect>\n        <path id=\"Border\" fill=\"#E00082\" fill-rule=\"nonzero\" d=\"M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z\"></path>\n        <path class=\"bglIGM\" x=\"64\" y=\"28\" fill=\"#fff\" d=\"M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8\" style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"ksxRII\" x=\"95.98500061035156\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"cWrBmb\" x=\"95.97162628173828\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"Wnusb\" x=\"64\" y=\"101.97999572753906\" fill=\"#fff\" d=\"M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"bfPqf\" x=\"32.03982162475586\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"edRCTN\" x=\"32.033552169799805\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"iEGVWn\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M63.55 27.5l32.9 19-32.9-19z\"></path>\n        <path class=\"bsocdx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96 46v38-38z\"></path>\n        <path class=\"jAZXmP\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96.45 84.5l-32.9 19 32.9-19z\"></path>\n        <path class=\"hSeArx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M64.45 103.5l-32.9-19 32.9 19z\"></path>\n        <path class=\"bVgqGk\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M32 84V46v38z\"></path>\n        <path class=\"hEFqBt\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M31.55 46.5l32.9-19-32.9 19z\"></path>\n        <path class=\"dzEKCM\" id=\"Triangle-Bottom\" stroke=\"#fff\" stroke-width=\"4\" d=\"M30 84h70\" stroke-linecap=\"round\"></path>\n        <path class=\"DYnPx\" id=\"Triangle-Left\" stroke=\"#fff\" stroke-width=\"4\" d=\"M65 26L30 87\" stroke-linecap=\"round\"></path>\n        <path class=\"hjPEAQ\" id=\"Triangle-Right\" stroke=\"#fff\" stroke-width=\"4\" d=\"M98 87L63 26\" stroke-linecap=\"round\"></path>\n      </g>\n    </svg>\n    <div class=\"text\">Loading\n      <span class=\"dGfHfc\">GraphQL Playground</span>\n    </div>\n  </div>\n\n  <div id=\"root\" />\n  <script type=\"text/javascript\">\n    window.addEventListener('load', function (event) {\n      const loadingWrapper = document.getElementById('loading-wrapper');\n      if (loadingWrapper) {\n        loadingWrapper.classList.add('fadeOut');\n      }\n\n      const root = document.getElementById('root');\n      root.classList.add('playgroundIn');\n    })\n  </script>\n</body>\n\n</html>"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/index.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport Root from './components/Root'\nimport 'graphcool-styles/dist/styles.css'\nimport './index.css'\n\nReactDOM.render(<Root />, document.getElementById('root'))\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/actions/history.ts",
    "content": "export type SELECT_HISTORY = 'select history'\nexport const SELECT_HISTORY: SELECT_HISTORY = 'select history'\n\nexport interface SelectHistoryAction {\n  type: SELECT_HISTORY\n  history: History\n}\n\nexport interface History {\n  type: 'local' | 'endpoint'\n  path: string\n  lastOpened?: Date\n}\n\nexport const selectHistory = (history: History): SelectHistoryAction => ({\n  type: SELECT_HISTORY,\n  history,\n})\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/createStore.ts",
    "content": "import { compose, createStore } from 'redux'\nimport persistState, { mergePersistedState } from 'redux-localstorage'\nimport filter from 'redux-localstorage-filter'\nimport * as adapter from 'redux-localstorage/lib/adapters/localStorage'\nimport { merge } from 'lodash'\nimport combinedReducers from './reducers'\n\nlet localStorage: any = null\n\nif (typeof window !== 'undefined') {\n  localStorage = window.localStorage\n} else {\n  localStorage = {\n    clearItem: () => null,\n    getItem: () => null,\n    setItem: () => null,\n  }\n}\n\nconst composeEnhancers = compose\n\nconst storage = composeEnhancers(filter(['history.history']))(\n  adapter(localStorage),\n)\n\nconst reducer = composeEnhancers(\n  mergePersistedState((initialState, persistedState) => {\n    return merge({}, initialState, persistedState)\n  }),\n)(combinedReducers)\n\nconst enhancer = composeEnhancers(\n  persistState(storage, 'graphql-playground-electron'),\n)\n\nconst functions = [enhancer]\n//\n// if (window.__REDUX_DEVTOOLS_EXTENSION__) {\n//   functions.push(window.__REDUX_DEVTOOLS_EXTENSION__())\n// }\n\nexport default () =>\n  createStore(reducer, composeEnhancers.apply(null, functions))\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/reducers/history.ts",
    "content": "import {\n  SELECT_HISTORY,\n  SelectHistoryAction,\n  History,\n} from '../actions/history'\n\nexport type HistoryAction = SelectHistoryAction\n\nexport interface State {\n  readonly history: History[]\n}\n\nconst defaultState: State = {\n  history: [],\n}\n\nexport default function historyReducer(\n  state: State = defaultState,\n  action: HistoryAction,\n): State {\n  switch (action.type) {\n    case SELECT_HISTORY:\n      const { history } = action\n      history.lastOpened = new Date()\n      // See if already in list\n      const index = state.history.findIndex(data => data.path === history.path)\n      let newHistory = state.history\n      if (index !== -1) {\n        newHistory[index] = history\n      } else {\n        newHistory = [...state.history, history]\n      }\n      // Sort by date\n      newHistory.sort(\n        (a, b) => (new Date(a.lastOpened) < new Date(b.lastOpened) ? -1 : 1),\n      )\n      return {\n        ...state,\n        history: newHistory,\n      }\n  }\n  return state\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/reducers/index.ts",
    "content": "import { combineReducers } from 'redux'\nimport graphiqlDocs from 'graphql-playground-react/lib/reducers/graphiql-docs'\nimport history from './history'\n\nconst combinedReducers = combineReducers({\n  graphiqlDocs,\n  history,\n})\n\nexport default combinedReducers\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/utils/errify.ts",
    "content": "import swal from 'sweetalert2'\n\nexport function errify(error: Error | string) {\n  const message = typeof error === 'string' ? error : error.message\n  swal({\n    title: 'Error',\n    text: message,\n    type: 'error',\n    confirmButtonText: 'Ok',\n  })\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/shared/utils.ts",
    "content": "import { remote } from 'electron'\nimport * as dev from 'electron-is-dev'\nimport * as path from 'path'\n\nexport const newWindowConfig: Electron.BrowserWindowConstructorOptions = {\n  title: 'GraphQL Playground',\n  width: 1200,\n  height: 800,\n  titleBarStyle: 'hiddenInset',\n  icon: path.join(__dirname, '../static/icons/icon.icns'),\n  backgroundColor: '#0F202D',\n}\n\nexport function createRemoteWindow() {\n  const win = new remote.BrowserWindow(newWindowConfig)\n  const url = dev\n    ? 'http://localhost:4040'\n    : `file://${path.join(__dirname, '..', '/dist/index.html')}`\n\n  win.loadURL(url)\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"removeComments\": true,\n    \"module\": \"commonjs\",\n    \"jsx\": \"react\",\n    \"sourceMap\": true,\n    \"target\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"allowJs\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noUnusedLocals\": true,\n    \"lib\": [\"es2015\", \"dom\"],\n    \"outDir\": \"lib\",\n    \"baseUrl\": \"./\",\n    \"skipDefaultLibCheck\": true,\n    \"skipLibCheck\": true\n  },\n  \"exclude\": [\"node_modules\", \"dist\", \"lib\"],\n  \"include\": [\"typings/custom.d.ts\", \"typings/styled-jsx.d.ts\"],\n  \"files\": [\"src/renderer/index.tsx\", \"src/main/index.ts\"]\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/tslint.json",
    "content": "{\n  \"extends\": [\n    \"tslint-graphcool-frontend\"\n  ],\n  \"rules\": {\n    \"no-console\": false,\n    \"no-implicit-dependencies\": false,\n    \"no-submodule-imports\": false,\n    \"jsx-no-lambda\": false\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/typings/custom.d.ts",
    "content": "interface Window {\n  GraphQLPlayground: any\n  __REDUX_DEVTOOLS_EXTENSION__: any\n  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/typings/styled-jsx.d.ts",
    "content": "import 'react'\n\ndeclare module 'react' {\n  interface HTMLProps<T> {\n    jsx?: boolean\n    global?: boolean\n  }\n}\n\ndeclare module 'react' {\n  interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {\n    jsx?: boolean\n    global?: boolean\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/webpack.config.build.js",
    "content": "const webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst cssnano = require('cssnano')\nconst path = require('path')\nconst config = require('./webpack.config')\nconst HappyPack = require('happypack')\nconst os = require('os')\nconst fs = require('fs')\nconst UglifyJSParallelPlugin = require('webpack-uglify-parallel')\nconst { renderPlaygroundPage } = require('graphql-playground-html')\n\nconst appEntrypoint = 'src/renderer/index.html'\n\n// Create the playground entry point if it doesn't exist\nif (!fs.existsSync(appEntrypoint)) {\n  fs.writeFileSync(appEntrypoint, renderPlaygroundPage({ env: 'react' }))\n}\n\nmodule.exports = {\n  devtool: 'source-map',\n  mode: 'production',\n  target: 'electron-renderer',\n  entry: {\n    app: ['./src/renderer'],\n  },\n  output: {\n    path: __dirname + '/dist',\n    filename: '[name].[hash].js',\n    sourceMapFilename: '[file].map',\n    publicPath: './',\n  },\n  node: {\n    __dirname: false,\n    __filename: false,\n  },\n  module: {\n    rules: [\n      {\n        enforce: 'pre',\n        test: /\\.ts(x?)$/,\n        loader: 'tslint-loader',\n        exclude: /node_modules/,\n      },\n      {\n        test: /\\.css$/,\n        loader: 'style-loader!css-loader',\n      },\n      {\n        test: /\\.scss$/,\n        loader:\n          'style-loader!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader!sass-loader',\n      },\n      {\n        test: /\\.ts(x?)$/,\n        include: __dirname + '/src',\n        use: [\n          {\n            loader: 'happypack/loader?id=babel',\n          },\n          {\n            loader: 'happypack/loader?id=ts',\n          },\n        ],\n      },\n      {\n        test: /\\.js$/,\n        loader: 'happypack/loader?id=babel',\n        include: __dirname + '/src',\n      },\n      {\n        test: /\\.mp3$/,\n        loader: 'file-loader',\n      },\n      {\n        test: /icons\\/.*\\.svg$/,\n        loader:\n          'raw-loader!svgo-loader?{\"plugins\":[{\"removeStyleElement\":true}]}',\n      },\n      {\n        test: /graphics\\/.*\\.svg$/,\n        loader: 'file-loader',\n      },\n      {\n        test: /.*\\.(png|gif)$/,\n        loader: 'file-loader',\n      },\n    ],\n  },\n  plugins: [\n    new webpack.DefinePlugin({\n      'process.env': {\n        NODE_ENV: JSON.stringify('production'),\n      },\n      __EXAMPLE_ADDR__: '\"https://dynamic-resources.graph.cool\"',\n    }),\n    new HtmlWebpackPlugin({\n      favicon: 'static/favicon.png',\n      template: appEntrypoint,\n    }),\n    new webpack.optimize.OccurrenceOrderPlugin(),\n    /* new UglifyJSParallelPlugin({\n      workers: os.cpus().length,\n      compress: {\n        unused: true,\n        dead_code: true,\n        warnings: false,\n      },\n      sourceMap: false,\n      mangle: false,\n    }), */\n    // https://github.com/graphql/graphql-language-service/issues/111\n    new webpack.ContextReplacementPlugin(\n      /graphql-language-service-interface[\\/\\\\]dist/,\n      /\\.js$/,\n    ),\n    new webpack.NormalModuleReplacementPlugin(/\\/iconv-loader$/, 'node-noop'),\n    // new webpack.optimize.CommonsChunkPlugin('vendor'),\n    new webpack.optimize.ModuleConcatenationPlugin(),\n    new webpack.LoaderOptionsPlugin({\n      options: {\n        postcss: [\n          cssnano({\n            autoprefixer: {\n              add: true,\n              remove: true,\n              browsers: ['last 2 versions'],\n            },\n            discardComments: {\n              removeAll: true,\n            },\n            safe: true,\n          }),\n        ],\n        svgo: {\n          plugins: [{ removeStyleElement: true }],\n        },\n      },\n    }),\n    new HappyPack({\n      id: 'ts',\n      threads: 2,\n      loaders: ['ts-loader?' + JSON.stringify({ happyPackMode: true })],\n    }),\n    new HappyPack({\n      id: 'babel',\n      threads: 2,\n      loaders: ['babel-loader'],\n    }),\n  ],\n  resolve: {\n    modules: [path.resolve('./src'), 'node_modules'],\n    extensions: ['.mjs', '.js', '.ts', '.tsx'],\n  },\n}\n"
  },
  {
    "path": "packages/graphql-playground-electron/webpack.config.js",
    "content": "const webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst BundleAnalyzerPlugin = require('webpack-bundle-analyzer')\n  .BundleAnalyzerPlugin\nconst path = require('path')\nconst fs = require('fs')\nconst ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')\nconst HappyPack = require('happypack')\nconst { renderPlaygroundPage } = require('graphql-playground-html')\n\nconst appEntrypoint = 'src/renderer/index.html'\n\n// Create the playground entry point if it doesn't exist\nif (!fs.existsSync(appEntrypoint)) {\n  fs.writeFileSync(appEntrypoint, renderPlaygroundPage({ env: 'react' }))\n}\n\nmodule.exports = {\n  devtool: 'cheap-module-eval-source-map',\n  mode: 'development',\n  entry: './src/renderer',\n  target: 'electron-renderer',\n  output: {\n    filename: '[name].[hash].js',\n    publicPath: '/'\n  },\n  module: {\n    rules: [\n      {\n        enforce: 'pre',\n        test: /\\.ts(x?)$/,\n        loader: 'tslint-loader',\n        exclude: /node_modules/,\n      },\n      {\n        test: /\\.css$/,\n        loader: 'style-loader!css-loader',\n      },\n      {\n        test: /\\.ts(x?)$/,\n        include: [__dirname + '/src'],\n        use: [\n          {\n            loader: 'happypack/loader?id=babel',\n          },\n          {\n            loader: 'happypack/loader?id=ts',\n          },\n        ],\n      },\n      {\n        test: /\\.js$/,\n        loader: 'babel-loader',\n      },\n      {\n        test: /\\.mp3$/,\n        loader: 'file-loader',\n      },\n      {\n        test: /(icons|node_modules)\\/.*\\.svg$/,\n        loader: 'raw-loader!svgo-loader',\n      },\n      {\n        test: /graphics\\/.*\\.svg$/,\n        loader: 'file-loader',\n      },\n      {\n        test: /.*\\.(png|gif)$/,\n        loader: 'file-loader',\n      },\n    ],\n  },\n  plugins: [\n    new webpack.HotModuleReplacementPlugin(),\n    new ForkTsCheckerWebpackPlugin({}),\n    new webpack.DefinePlugin({\n      'process.env': {\n        NODE_ENV: JSON.stringify('development'),\n      },\n      __EXAMPLE_ADDR__: '\"https://dynamic-resources.graph.cool\"',\n    }),\n    new HtmlWebpackPlugin({\n      favicon: 'static/favicon.png',\n      template: 'src/renderer/index.html',\n    }),\n    new webpack.NormalModuleReplacementPlugin(/\\/iconv-loader$/, 'node-noop'),\n    // See https://github.com/graphql/graphql-language-service/issues/111\n    new webpack.ContextReplacementPlugin(\n      /graphql-language-service-interface[\\/\\\\]dist/,\n      /\\.js$/,\n    ),\n    new webpack.LoaderOptionsPlugin({\n      options: {\n        svgo: {\n          plugins: [{ removeStyleElement: true }],\n        },\n      },\n    }),\n    new HappyPack({\n      id: 'ts',\n      threads: 2,\n      loaders: ['ts-loader?' + JSON.stringify({ happyPackMode: true })],\n    }),\n    new HappyPack({\n      id: 'babel',\n      threads: 2,\n      loaders: ['babel-loader'],\n    }),\n    // new BundleAnalyzerPlugin(),\n  ],\n  resolve: {\n    modules: [path.resolve('./src'), 'node_modules'],\n    extensions: ['.mjs', '.js', '.ts', '.tsx'],\n  },\n}\n"
  },
  {
    "path": "packages/graphql-playground-html/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/dist\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\n"
  },
  {
    "path": "packages/graphql-playground-html/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.6.29](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.28...graphql-playground-html@1.6.29) (2020-10-20)\n\n**Note:** Version bump only for package graphql-playground-html\n\n\n\n\n\n## [1.6.28](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.27...graphql-playground-html@1.6.28) (2020-09-15)\n\n\n### Bug Fixes\n\n* add schema.polling* to ISettings interface. ([#1212](https://github.com/graphcool/graphql-playground/issues/1212)) ([b7e6d4d](https://github.com/graphcool/graphql-playground/commit/b7e6d4d7590766183a77910a517ea946b95f2a84))\n\n\n\n\n\n## [1.6.27](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.26...graphql-playground-html@1.6.27) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-html\n\n\n\n\n\n## [1.6.26](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.23...graphql-playground-html@1.6.26) (2020-08-30)\n\n\n### Bug Fixes\n\n* cdn url ([#1238](https://github.com/graphcool/graphql-playground/issues/1238)) ([e574bb6](https://github.com/graphcool/graphql-playground/commit/e574bb69e8adcda816fa62acc7e3adf19f31947a))\n* **examples:** fix examples of reflected XSS attack ([#1256](https://github.com/graphcool/graphql-playground/issues/1256)) ([12b61b9](https://github.com/graphcool/graphql-playground/commit/12b61b9d69286b12a6ac74b12aae705e6b060f3b))\n\n\n\n\n\n## 1.6.23 (2020-06-07)\n\n\n### Bug Fixes\n\n* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))\n* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))\n* X-Apollo-Tracing No Schema Issue ([#1112](https://github.com/graphcool/graphql-playground/issues/1112)) ([1ca035d](https://github.com/graphcool/graphql-playground/commit/1ca035d06f71cbe02aa8f36e7fce2095c2854ba6))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n\n## 1.8.6 (2019-01-27)\n\n\n### Bug Fixes\n\n* **graphql 14:** version bump via graphql-config ([#861](https://github.com/graphcool/graphql-playground/issues/861)) ([5ea711c](https://github.com/graphcool/graphql-playground/commit/5ea711c590c1265c873324b28cd3483d3e05dc98))\n* close body tag ([#833](https://github.com/graphcool/graphql-playground/issues/833)) ([3d2732d](https://github.com/graphcool/graphql-playground/commit/3d2732dbd90f71f8b48465b95c7b7b5bc8bc7a1c))\n\n\n\n# 1.6.0 (2018-05-31)\n\n\n\n# 1.4.0 (2018-01-15)\n\n\n### Bug Fixes\n\n* **deps:** make graphql-config a normal dep ([9e4d93e](https://github.com/graphcool/graphql-playground/commit/9e4d93e0cf7ebd3ba1806407383e071fda37cb55))\n* **deps:** Remove extension dependencies ([72ce36c](https://github.com/graphcool/graphql-playground/commit/72ce36cdd96f35efefd916993a949e646c5f94b2)), closes [#493](https://github.com/graphcool/graphql-playground/issues/493)\n* **deps:** Updated graphql-config-extension-graphcool ([ef83c09](https://github.com/graphcool/graphql-playground/commit/ef83c097c018a42f7ee65529d6af4ea3928a4281))\n\n\n\n## 1.3.13 (2017-12-24)\n\n\n\n## 1.3.12 (2017-12-24)\n\n\n\n## 1.3.9 (2017-12-14)\n\n\n\n## 1.3.6 (2017-12-04)\n\n\n\n## 1.3.5 (2017-12-04)\n\n\n### Features\n\n* **middleware:** draft animated loading screen ([c082c07](https://github.com/graphcool/graphql-playground/commit/c082c07cdcfeae50dd0c43a5ae225729a91556ef))\n"
  },
  {
    "path": "packages/graphql-playground-html/README.md",
    "content": "# graphql-playground-html\n\n> **SECURITY WARNING:** This package and all of it's dependendents had a severe XSS Reflection attack vulnerability until version `1.6.22` of this package. You must sanitize any and all user input values to `renderPlaygroundPage()` values. If you used static values in your middlewares, including ours, you were not vulnerable to the attack.\n\nThis package is being used by the GraphQL Playground middlewares.\n\nFor local development, you can `yarn link` this package, then use `yarn link graphql-playground-html` in the\nmiddleware you want to develop.\n"
  },
  {
    "path": "packages/graphql-playground-html/examples/xss-attack/README.md",
    "content": "# GraphQL Playground HTML XSS Reflection Attack Example\n\nThis shows the simplest possible example for how one might re-create the XSS Reflection Vulnerability reported by Cure53.\n\nNotice we force the resolution to `graphql-playground-html@1.6.20`, which is the last version susceptible. All prior versions are susceptible to the attack.\n\nDynamic, unsanitized input that resembles some of the configuration you see is a simple example - if url parameters, query parameters, unsanitized database text strings, etc are passed to `expressPlayground()`, `renderPlaygroundPage()` or equivalent middleware functions such as `koaPlayground()`, they are all vulnerable to this attack.\n\n## Reccomendations\n\nHere we use `xss` because it was easy to provide for node.js, however [DOMPurify](https://github.com/cure53/DOMPurify) is also an excellent choice for sanitizing strings for unwanted html. By default it requires the browser DOM, but you can load it with JSDOM for server side purposes as well.\n\nhere are a few more tips to prevent other XSS vulnerabilities that might exist in your own applications:\n\n- `DOMPurify.sanitize` url values with user input to be used for rendering `<a href=` or `<script src=`, `<img src=` etc. whether using react or not!\n- in react,`dangerouslySetInnerHtml={{ __html: { DOMPurify.sanitize(userInputString) }}` always!\n- when doing direct dom manipulation, avoid `domElement.innerHTML = string` at all costs, but at least `DOMPurify.sanitize(string)` first if you must\n- when generating an entire html file, sanitize *all* user input values (this was our mistake)\n\n## Setup\n\n```sh\n$ yarn\n$ yarn start\n```\n\n## Examples\n\nNow that you've set up the example, you can view the examples:\n\n### Example 1 - Query params\n\nthis one uses query parameters\n\nhttp://localhost:4000/example-1?id=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E\n\n### Example 2 - DB Example\n\nthis one uses a mock database, to demonstrate more ways in which the function is susceptible\n\nhttp://localhost:4000/example-2\n\n### Example 3 - Upgrade workaround example\n\nthis one uses query like number 1, but shows how to use [`xss`](https://npmjs.com/xss) module to workaround the issue if you aren't able to upgrade\n\nhttp://localhost:4000/example-3?id=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E\n\n### Example 4 - Always Safe example\n\nthis one uses static values, so it's safe without any workarounds! (try removing the ?darkMode parameter)\n\nhttp://localhost:4000/example-4?darkMode=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E\n\n[XSS Safe using static configuration strings](\"http://localhost:4000/example-3?darkMode\")\n\n## More Details\n\nSee more details in [SECURITY.md](../../../../SECURITY.md)\n"
  },
  {
    "path": "packages/graphql-playground-html/examples/xss-attack/index.js",
    "content": "const express = require('express')\nconst { ApolloServer, gql } = require('apollo-server-express')\nconst { filterXSS } = require('xss')\nconst { renderPlaygroundPage } = require('graphql-playground-html')\n\nconst typeDefs = gql`\n  type Query {\n    hello: String!\n  }\n  schema {\n    query: Query\n  }\n`\nconst resolvers = {\n  Query: {\n    hello: () => 'world',\n  },\n}\n\nconst PORT = 4000\n\nconst server = new ApolloServer({ typeDefs, resolvers })\n\nconst app = express()\nserver.applyMiddleware({ app })\n\n// Example 1: Query Parameters\n\napp.get('/example-1', (req, res, next) => {\n  res.write(\n    renderPlaygroundPage({\n      endpoint: `/graphql/${req.query.id}`,\n    }),\n  )\n  res.status(200)\n  next()\n})\n\n// Example 2: mock database example\n\nconst db = {\n  async get() {\n    return {\n      'editor.fontFamily': `</script><script>alert('I <3 GraphQL. Hack the Planet!!')</script><script>`,\n    }\n  },\n}\n\napp.get('/example-2', async (req, res, next) => {\n  const settings = await db.get()\n  res.write(\n    renderPlaygroundPage({\n      endpoint: '/graphql',\n      settings,\n    }),\n  )\n  next()\n})\n\n// Example 3: Manual Workaround\n\nconst filter = (val) => {\n  return filterXSS(val, {\n    // @ts-ignore\n    whiteList: [],\n    stripIgnoreTag: true,\n    stripIgnoreTagBody: ['script'],\n  })\n}\n\napp.get('/example-3', (req, res, next) => {\n  res.write(\n    renderPlaygroundPage({\n      endpoint: `/graphql/${filter(req.query.id)}`,\n    }),\n  )\n  res.status(200)\n  next()\n})\n\n// Example 4: Safe\n\napp.get('/example-4', (req, res, next) => {\n  res.write(\n    renderPlaygroundPage({\n      endpoint: `/graphql`,\n      settings: {\n        'editor.theme': req.query.darkMode ? 'dark' : 'light',\n      },\n    }),\n  )\n  res.status(200)\n  next()\n})\n\napp.listen(PORT)\n\nconsole.log(\n  `Serving the GraphQL Playground on http://localhost:${PORT}/example-2`,\n)\n"
  },
  {
    "path": "packages/graphql-playground-html/examples/xss-attack/package.json",
    "content": "{\n  \"name\": \"xss-attack\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node index.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"apollo-server-express\": \"^2.16.0\",\n    \"express\": \"^4.17.1\",\n    \"graphql\": \"^15.0.0\",\n    \"graphql-playground-html\": \"1.6.20\",\n    \"xss\": \"^1.0.6\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-html/minimal.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8/>\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui\">\n  <title>GraphQL Playground</title>\n  <link rel=\"stylesheet\" href=\"//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css\" />\n  <link rel=\"shortcut icon\" href=\"//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png\" />\n  <script src=\"//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js\"></script>\n</head>\n\n<body>\n  <div id=\"root\">\n    <style>\n      body {\n        background-color: rgb(23, 42, 58);\n        font-family: Open Sans, sans-serif;\n        height: 90vh;\n      }\n\n      #root {\n        height: 100%;\n        width: 100%;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n      }\n\n      .loading {\n        font-size: 32px;\n        font-weight: 200;\n        color: rgba(255, 255, 255, .6);\n        margin-left: 20px;\n      }\n\n      img {\n        width: 78px;\n        height: 78px;\n      }\n\n      .title {\n        font-weight: 400;\n      }\n    </style>\n    <img src='//cdn.jsdelivr.net/npm/graphql-playground-react/build/logo.png' alt=''>\n    <div class=\"loading\"> Loading\n      <span class=\"title\">GraphQL Playground</span>\n    </div>\n  </div>\n  <script>window.addEventListener('load', function (event) {\n      GraphQLPlayground.init(document.getElementById('root'), {\n        // options as 'endpoint' belong here\n      })\n    })</script>\n</body>\n\n</html>"
  },
  {
    "path": "packages/graphql-playground-html/minimalWithoutCDN.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui\">\n  <title>GraphQL Playground</title>\n  <link rel=\"stylesheet\" href=\"./node_modules/graphql-playground-react/build/static/css/index.css\" />\n  <link rel=\"shortcut icon\" href=\"./node_modules/graphql-playground-react/build/favicon.png\" />\n  <script src=\"./node_modules/graphql-playground-react/build/static/js/middleware.js\"></script>\n</head>\n\n<body>\n  <div id=\"root\">\n    <style>\n      body {\n        background-color: rgb(23, 42, 58);\n        font-family: Open Sans, sans-serif;\n        height: 90vh;\n      }\n\n      #root {\n        height: 100%;\n        width: 100%;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n      }\n\n      .loading {\n        font-size: 32px;\n        font-weight: 200;\n        color: rgba(255, 255, 255, .6);\n        margin-left: 20px;\n      }\n\n      img {\n        width: 78px;\n        height: 78px;\n      }\n\n      .title {\n        font-weight: 400;\n      }\n    </style>\n    <img src='./node_modules/graphql-playground-react/build/logo.png' alt=''>\n    <div class=\"loading\"> Loading\n      <span class=\"title\">GraphQL Playground</span>\n    </div>\n  </div>\n  <script>window.addEventListener('load', function (event) {\n      GraphQLPlayground.init(document.getElementById('root'), {\n        // options as 'endpoint' belong here\n      })\n    })</script>\n</body>\n\n</html>"
  },
  {
    "path": "packages/graphql-playground-html/package.json",
    "content": "{\n  \"name\": \"graphql-playground-html\",\n  \"version\": \"1.6.29\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playground/tree/main/packages/graphql-playground-html\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).\",\n  \"contributors\": [\n    \"Tim Suchanek <tim@graph.cool>\",\n    \"Johannes Schickling <johannes@graph.cool>\",\n    \"Mohammad Rajabifard <mo.rajbi@gmail.com>\"\n  ],\n  \"repository\": \"http://github.com/graphcool/graphql-playground.git\",\n  \"license\": \"MIT\",\n  \"main\": \"dist/index.js\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"build\": \"rimraf dist && tsc\",\n    \"prepare\": \"npm run build\"\n  },\n  \"keywords\": [\n    \"graphql\",\n    \"graphiql\",\n    \"playground\",\n    \"graphcool\"\n  ],\n  \"devDependencies\": {\n    \"@types/node\": \"12.12.34\",\n    \"rimraf\": \"3.0.2\",\n    \"typescript\": \"3.8.3\"\n  },\n  \"typings\": \"dist/index.d.ts\",\n  \"typescript\": {\n    \"definition\": \"dist/index.d.ts\"\n  },\n  \"dependencies\": {\n    \"xss\": \"^1.0.6\"\n  },\n  \"gitHead\": \"53d233f9deb9dcc86f99e41268ff92b6367e0713\"\n}\n"
  },
  {
    "path": "packages/graphql-playground-html/src/get-loading-markup.ts",
    "content": "const getLoadingMarkup = () => ({\n  script: `\n    const loadingWrapper = document.getElementById('loading-wrapper');\n    if (loadingWrapper) {\n      loadingWrapper.classList.add('fadeOut');\n    }\n    `,\n  container: `\n<style type=\"text/css\">\n.fadeOut {\n  -webkit-animation: fadeOut 0.5s ease-out forwards;\n  animation: fadeOut 0.5s ease-out forwards;\n}\n\n@-webkit-keyframes fadeIn {\n  from {\n    opacity: 0;\n    -webkit-transform: translateY(-10px);\n    -ms-transform: translateY(-10px);\n    transform: translateY(-10px);\n  }\n  to {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -ms-transform: translateY(0);\n    transform: translateY(0);\n  }\n}\n\n@keyframes fadeIn {\n  from {\n    opacity: 0;\n    -webkit-transform: translateY(-10px);\n    -ms-transform: translateY(-10px);\n    transform: translateY(-10px);\n  }\n  to {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -ms-transform: translateY(0);\n    transform: translateY(0);\n  }\n}\n\n@-webkit-keyframes fadeOut {\n  from {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -ms-transform: translateY(0);\n    transform: translateY(0);\n  }\n  to {\n    opacity: 0;\n    -webkit-transform: translateY(-10px);\n    -ms-transform: translateY(-10px);\n    transform: translateY(-10px);\n  }\n}\n\n@keyframes fadeOut {\n  from {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -ms-transform: translateY(0);\n    transform: translateY(0);\n  }\n  to {\n    opacity: 0;\n    -webkit-transform: translateY(-10px);\n    -ms-transform: translateY(-10px);\n    transform: translateY(-10px);\n  }\n}\n\n@-webkit-keyframes appearIn {\n  from {\n    opacity: 0;\n    -webkit-transform: translateY(0px);\n    -ms-transform: translateY(0px);\n    transform: translateY(0px);\n  }\n  to {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -ms-transform: translateY(0);\n    transform: translateY(0);\n  }\n}\n\n@keyframes appearIn {\n  from {\n    opacity: 0;\n    -webkit-transform: translateY(0px);\n    -ms-transform: translateY(0px);\n    transform: translateY(0px);\n  }\n  to {\n    opacity: 1;\n    -webkit-transform: translateY(0);\n    -ms-transform: translateY(0);\n    transform: translateY(0);\n  }\n}\n\n@-webkit-keyframes scaleIn {\n  from {\n    -webkit-transform: scale(0);\n    -ms-transform: scale(0);\n    transform: scale(0);\n  }\n  to {\n    -webkit-transform: scale(1);\n    -ms-transform: scale(1);\n    transform: scale(1);\n  }\n}\n\n@keyframes scaleIn {\n  from {\n    -webkit-transform: scale(0);\n    -ms-transform: scale(0);\n    transform: scale(0);\n  }\n  to {\n    -webkit-transform: scale(1);\n    -ms-transform: scale(1);\n    transform: scale(1);\n  }\n}\n\n@-webkit-keyframes innerDrawIn {\n  0% {\n    stroke-dashoffset: 70;\n  }\n  50% {\n    stroke-dashoffset: 140;\n  }\n  100% {\n    stroke-dashoffset: 210;\n  }\n}\n\n@keyframes innerDrawIn {\n  0% {\n    stroke-dashoffset: 70;\n  }\n  50% {\n    stroke-dashoffset: 140;\n  }\n  100% {\n    stroke-dashoffset: 210;\n  }\n}\n\n@-webkit-keyframes outerDrawIn {\n  0% {\n    stroke-dashoffset: 76;\n  }\n  100% {\n    stroke-dashoffset: 152;\n  }\n}\n\n@keyframes outerDrawIn {\n  0% {\n    stroke-dashoffset: 76;\n  }\n  100% {\n    stroke-dashoffset: 152;\n  }\n}\n\n.hHWjkv {\n  -webkit-transform-origin: 0px 0px;\n  -ms-transform-origin: 0px 0px;\n  transform-origin: 0px 0px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n  animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n}\n\n.gCDOzd {\n  -webkit-transform-origin: 0px 0px;\n  -ms-transform-origin: 0px 0px;\n  transform-origin: 0px 0px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n  animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n}\n\n.hmCcxi {\n  -webkit-transform-origin: 0px 0px;\n  -ms-transform-origin: 0px 0px;\n  transform-origin: 0px 0px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n  animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n}\n\n.eHamQi {\n  -webkit-transform-origin: 0px 0px;\n  -ms-transform-origin: 0px 0px;\n  transform-origin: 0px 0px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n  animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n}\n\n.byhgGu {\n  -webkit-transform-origin: 0px 0px;\n  -ms-transform-origin: 0px 0px;\n  transform-origin: 0px 0px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n  animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n}\n\n.llAKP {\n  -webkit-transform-origin: 0px 0px;\n  -ms-transform-origin: 0px 0px;\n  transform-origin: 0px 0px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n  animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n}\n\n.bglIGM {\n  -webkit-transform-origin: 64px 28px;\n  -ms-transform-origin: 64px 28px;\n  transform-origin: 64px 28px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n  animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n}\n\n.ksxRII {\n  -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;\n  -ms-transform-origin: 95.98500061035156px 46.510000228881836px;\n  transform-origin: 95.98500061035156px 46.510000228881836px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n  animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n}\n\n.cWrBmb {\n  -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;\n  -ms-transform-origin: 95.97162628173828px 83.4900016784668px;\n  transform-origin: 95.97162628173828px 83.4900016784668px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n  animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n}\n\n.Wnusb {\n  -webkit-transform-origin: 64px 101.97999572753906px;\n  -ms-transform-origin: 64px 101.97999572753906px;\n  transform-origin: 64px 101.97999572753906px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n  animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n}\n\n.bfPqf {\n  -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;\n  -ms-transform-origin: 32.03982162475586px 83.4900016784668px;\n  transform-origin: 32.03982162475586px 83.4900016784668px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n  animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n}\n\n.edRCTN {\n  -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;\n  -ms-transform-origin: 32.033552169799805px 46.510000228881836px;\n  transform-origin: 32.033552169799805px 46.510000228881836px;\n  -webkit-transform: scale(0);\n  -ms-transform: scale(0);\n  transform: scale(0);\n  -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n  animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n}\n\n.iEGVWn {\n  opacity: 0;\n  stroke-dasharray: 76;\n  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n  animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n  -webkit-animation-iteration-count: 1, 1;\n  animation-iteration-count: 1, 1;\n}\n\n.bsocdx {\n  opacity: 0;\n  stroke-dasharray: 76;\n  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n  animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n  -webkit-animation-iteration-count: 1, 1;\n  animation-iteration-count: 1, 1;\n}\n\n.jAZXmP {\n  opacity: 0;\n  stroke-dasharray: 76;\n  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n  animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n  -webkit-animation-iteration-count: 1, 1;\n  animation-iteration-count: 1, 1;\n}\n\n.hSeArx {\n  opacity: 0;\n  stroke-dasharray: 76;\n  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n  animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n  -webkit-animation-iteration-count: 1, 1;\n  animation-iteration-count: 1, 1;\n}\n\n.bVgqGk {\n  opacity: 0;\n  stroke-dasharray: 76;\n  -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n  animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n  -webkit-animation-iteration-count: 1, 1;\n  animation-iteration-count: 1, 1;\n}\n\n.hEFqBt {\n  opacity: 0;\n  stroke-dasharray: 76;\n  -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n  animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n  -webkit-animation-iteration-count: 1, 1;\n  animation-iteration-count: 1, 1;\n}\n\n.dzEKCM {\n  opacity: 0;\n  stroke-dasharray: 70;\n  -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n  animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n  -webkit-animation-iteration-count: infinite, 1;\n  animation-iteration-count: infinite, 1;\n}\n\n.DYnPx {\n  opacity: 0;\n  stroke-dasharray: 70;\n  -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n  animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n  -webkit-animation-iteration-count: infinite, 1;\n  animation-iteration-count: infinite, 1;\n}\n\n.hjPEAQ {\n  opacity: 0;\n  stroke-dasharray: 70;\n  -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n  animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n  -webkit-animation-iteration-count: infinite, 1;\n  animation-iteration-count: infinite, 1;\n}\n\n#loading-wrapper {\n  position: absolute;\n  width: 100vw;\n  height: 100vh;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-align-items: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  align-items: center;\n  -webkit-box-pack: center;\n  -webkit-justify-content: center;\n  -ms-flex-pack: center;\n  justify-content: center;\n  -webkit-flex-direction: column;\n  -ms-flex-direction: column;\n  flex-direction: column;\n}\n\n.logo {\n  width: 75px;\n  height: 75px;\n  margin-bottom: 20px;\n  opacity: 0;\n  -webkit-animation: fadeIn 0.5s ease-out forwards;\n  animation: fadeIn 0.5s ease-out forwards;\n}\n\n.text {\n  font-size: 32px;\n  font-weight: 200;\n  text-align: center;\n  color: rgba(255, 255, 255, 0.6);\n  opacity: 0;\n  -webkit-animation: fadeIn 0.5s ease-out forwards;\n  animation: fadeIn 0.5s ease-out forwards;\n}\n\n.dGfHfc {\n  font-weight: 400;\n}\n</style>\n<div id=\"loading-wrapper\">\n<svg class=\"logo\" viewBox=\"0 0 128 128\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n  <title>GraphQL Playground Logo</title>\n  <defs>\n    <linearGradient id=\"linearGradient-1\" x1=\"4.86%\" x2=\"96.21%\" y1=\"0%\" y2=\"99.66%\">\n      <stop stop-color=\"#E00082\" stop-opacity=\".8\" offset=\"0%\"></stop>\n      <stop stop-color=\"#E00082\" offset=\"100%\"></stop>\n    </linearGradient>\n  </defs>\n  <g>\n    <rect id=\"Gradient\" width=\"127.96\" height=\"127.96\" y=\"1\" fill=\"url(#linearGradient-1)\" rx=\"4\"></rect>\n    <path id=\"Border\" fill=\"#E00082\" fill-rule=\"nonzero\" d=\"M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z\"></path>\n    <path class=\"bglIGM\" x=\"64\" y=\"28\" fill=\"#fff\" d=\"M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8\" style=\"transform: translate(100px, 100px);\"></path>\n    <path class=\"ksxRII\" x=\"95.98500061035156\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94\"\n      style=\"transform: translate(100px, 100px);\"></path>\n    <path class=\"cWrBmb\" x=\"95.97162628173828\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96\"\n      style=\"transform: translate(100px, 100px);\"></path>\n    <path class=\"Wnusb\" x=\"64\" y=\"101.97999572753906\" fill=\"#fff\" d=\"M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02\"\n      style=\"transform: translate(100px, 100px);\"></path>\n    <path class=\"bfPqf\" x=\"32.03982162475586\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94\"\n      style=\"transform: translate(100px, 100px);\"></path>\n    <path class=\"edRCTN\" x=\"32.033552169799805\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96\"\n      style=\"transform: translate(100px, 100px);\"></path>\n    <path class=\"iEGVWn\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M63.55 27.5l32.9 19-32.9-19z\"></path>\n    <path class=\"bsocdx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96 46v38-38z\"></path>\n    <path class=\"jAZXmP\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96.45 84.5l-32.9 19 32.9-19z\"></path>\n    <path class=\"hSeArx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M64.45 103.5l-32.9-19 32.9 19z\"></path>\n    <path class=\"bVgqGk\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M32 84V46v38z\"></path>\n    <path class=\"hEFqBt\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M31.55 46.5l32.9-19-32.9 19z\"></path>\n    <path class=\"dzEKCM\" id=\"Triangle-Bottom\" stroke=\"#fff\" stroke-width=\"4\" d=\"M30 84h70\" stroke-linecap=\"round\"></path>\n    <path class=\"DYnPx\" id=\"Triangle-Left\" stroke=\"#fff\" stroke-width=\"4\" d=\"M65 26L30 87\" stroke-linecap=\"round\"></path>\n    <path class=\"hjPEAQ\" id=\"Triangle-Right\" stroke=\"#fff\" stroke-width=\"4\" d=\"M98 87L63 26\" stroke-linecap=\"round\"></path>\n  </g>\n</svg>\n<div class=\"text\">Loading\n  <span class=\"dGfHfc\">GraphQL Playground</span>\n</div>\n</div>\n`,\n})\n\nexport default getLoadingMarkup\n"
  },
  {
    "path": "packages/graphql-playground-html/src/index.ts",
    "content": "export {\n  renderPlaygroundPage,\n  MiddlewareOptions,\n  RenderPageOptions,\n} from './render-playground-page'\n"
  },
  {
    "path": "packages/graphql-playground-html/src/render-playground-page.ts",
    "content": "import { filterXSS } from 'xss';\n\nimport getLoadingMarkup from './get-loading-markup'\n\nexport interface MiddlewareOptions {\n  endpoint?: string\n  subscriptionEndpoint?: string\n  workspaceName?: string\n  env?: any\n  config?: any\n  settings?: Partial<ISettings>\n  schema?: IntrospectionResult\n  tabs?: Tab[]\n  codeTheme?: EditorColours\n}\n\nexport type CursorShape = 'line' | 'block' | 'underline'\nexport type Theme = 'dark' | 'light'\n\nexport interface ISettings {\n  'general.betaUpdates': boolean\n  'editor.cursorShape': CursorShape\n  'editor.theme': Theme\n  'editor.reuseHeaders': boolean\n  'tracing.hideTracingResponse': boolean\n  'tracing.tracingSupported': boolean\n  'editor.fontSize': number\n  'editor.fontFamily': string\n  'request.credentials': string\n  'request.globalHeaders': { [key: string]: string; }\n  'schema.polling.enable': boolean\n  'schema.polling.endpointFilter': string\n  'schema.polling.interval': number\n}\n\nexport interface EditorColours {\n  property: string\n  comment: string\n  punctuation: string\n  keyword: string\n  def: string\n  qualifier: string\n  attribute: string\n  number: string\n  string: string\n  builtin: string\n  string2: string\n  variable: string\n  meta: string\n  atom: string\n  ws: string\n  selection: string\n  cursorColor: string\n  editorBackground: string\n  resultBackground: string\n  leftDrawerBackground: string\n  rightDrawerBackground: string\n}\n\nexport interface IntrospectionResult {\n  __schema: any\n}\n\nexport interface RenderPageOptions extends MiddlewareOptions {\n  version?: string\n  cdnUrl?: string\n  env?: any\n  title?: string\n  faviconUrl?: string | null\n}\n\nexport interface Tab {\n  endpoint: string\n  query: string\n  name?: string\n  variables?: string\n  responses?: string[]\n  headers?: { [key: string]: string }\n}\n\nconst filter = (val) => {\n  return filterXSS(val, {\n    // @ts-ignore\n    whiteList: [],\n    stripIgnoreTag: true,\n    stripIgnoreTagBody: [\"script\"]\n  })\n}\n\n\nconst loading = getLoadingMarkup()\n\nconst CONFIG_ID = 'playground-config';\n\nconst getCdnMarkup = ({ version, cdnUrl = '//cdn.jsdelivr.net/npm', faviconUrl }) => {\n  const buildCDNUrl = (packageName: string, suffix: string) => filter(`${cdnUrl}/${packageName}${version ? `@${version}` : ''}/${suffix}` || '')\n  return `\n    <link \n      rel=\"stylesheet\" \n      href=\"${buildCDNUrl('graphql-playground-react', 'build/static/css/index.css')}\"\n    />\n    ${typeof faviconUrl === 'string' ? `<link rel=\"shortcut icon\" href=\"${filter(faviconUrl || '')}\" />` : ''}\n    ${faviconUrl === undefined ? `<link rel=\"shortcut icon\" href=\"${buildCDNUrl('graphql-playground-react', 'build/favicon.png')}\" />` : ''}\n    <script \n      src=\"${buildCDNUrl('graphql-playground-react', 'build/static/js/middleware.js')}\"\n    ></script>\n`}\n\n\nconst renderConfig = (config) => {\n  return filterXSS(`<div id=\"${CONFIG_ID}\">${JSON.stringify(config)}</div>`, {\n    whiteList: { div: ['id'] },\n  })\n}\n\nexport function renderPlaygroundPage(options: RenderPageOptions) {\n  const extendedOptions: any = {\n    ...options,\n    canSaveConfig: false,\n  }\n  // for compatibility\n  if ((options as any).subscriptionsEndpoint) {\n    extendedOptions.subscriptionEndpoint = filter((options as any).subscriptionsEndpoint || '')\n  }\n  if (options.config) {\n    extendedOptions.configString = JSON.stringify(options.config, null, 2)\n  }\n  if (!extendedOptions.endpoint && !extendedOptions.configString) {\n    /* tslint:disable-next-line */\n    console.warn(\n      `WARNING: You didn't provide an endpoint and don't have a .graphqlconfig. Make sure you have at least one of them.`,\n    )\n  }\n  else if (extendedOptions.endpoint) {\n    extendedOptions.endpoint = filter(extendedOptions.endpoint || '')\n  }\n\n  return `\n  <!DOCTYPE html>\n  <html>\n  <head>\n    <meta charset=utf-8 />\n    <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui\">\n    <link href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,700\" rel=\"stylesheet\">\n    <title>${extendedOptions.title || 'GraphQL Playground'}</title>\n    ${extendedOptions.env === 'react' || extendedOptions.env === 'electron'\n      ? ''\n      : getCdnMarkup(extendedOptions)\n    }\n  </head>\n  <body>\n    <style type=\"text/css\">\n      html {\n        font-family: \"Open Sans\", sans-serif;\n        overflow: hidden;\n      }\n  \n      body {\n        margin: 0;\n        background: #172a3a;\n      }\n\n      #${CONFIG_ID} {\n        display: none;\n      }\n  \n      .playgroundIn {\n        -webkit-animation: playgroundIn 0.5s ease-out forwards;\n        animation: playgroundIn 0.5s ease-out forwards;\n      }\n  \n      @-webkit-keyframes playgroundIn {\n        from {\n          opacity: 0;\n          -webkit-transform: translateY(10px);\n          -ms-transform: translateY(10px);\n          transform: translateY(10px);\n        }\n        to {\n          opacity: 1;\n          -webkit-transform: translateY(0);\n          -ms-transform: translateY(0);\n          transform: translateY(0);\n        }\n      }\n  \n      @keyframes playgroundIn {\n        from {\n          opacity: 0;\n          -webkit-transform: translateY(10px);\n          -ms-transform: translateY(10px);\n          transform: translateY(10px);\n        }\n        to {\n          opacity: 1;\n          -webkit-transform: translateY(0);\n          -ms-transform: translateY(0);\n          transform: translateY(0);\n        }\n      }\n    </style>\n    ${loading.container}\n    ${renderConfig(extendedOptions)}\n    <div id=\"root\" />\n    <script type=\"text/javascript\">\n      window.addEventListener('load', function (event) {\n        ${loading.script}\n  \n        const root = document.getElementById('root');\n        root.classList.add('playgroundIn');\n        const configText = document.getElementById('${CONFIG_ID}').innerText;\n        \n        if(configText && configText.length) {\n          try {\n            GraphQLPlayground.init(root, JSON.parse(configText));\n          }\n          catch(err) {\n            console.error(\"could not find config\")\n          }\n        }\n        else {\n          GraphQLPlayground.init(root);\n        }\n      })\n    </script>\n  </body>\n  </html>\n`\n}\n"
  },
  {
    "path": "packages/graphql-playground-html/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": false,\n    \"strictNullChecks\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-html/withAnimation.html",
    "content": "<!DOCTYPE html>\n\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui\">\n  <title>GraphQL Playground</title>\n  <link rel=\"stylesheet\" href=\"//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css\" />\n  <link rel=\"shortcut icon\" href=\"//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png\" />\n  <script src=\"//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js\"></script>\n\n</head>\n\n<body>\n  <style type=\"text/css\">\n    html {\n      font-family: \"Open Sans\", sans-serif;\n      overflow: hidden;\n    }\n\n    body {\n      margin: 0;\n      background: #172a3a;\n    }\n\n    .playgroundIn {\n      -webkit-animation: playgroundIn 0.5s ease-out forwards;\n      animation: playgroundIn 0.5s ease-out forwards;\n    }\n\n    @-webkit-keyframes playgroundIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(10px);\n        -ms-transform: translateY(10px);\n        transform: translateY(10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes playgroundIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(10px);\n        -ms-transform: translateY(10px);\n        transform: translateY(10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n  </style>\n\n  <style type=\"text/css\">\n    .fadeOut {\n      -webkit-animation: fadeOut 0.5s ease-out forwards;\n      animation: fadeOut 0.5s ease-out forwards;\n    }\n\n    @-webkit-keyframes fadeIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes fadeIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @-webkit-keyframes fadeOut {\n      from {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n      to {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n    }\n\n    @keyframes fadeOut {\n      from {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n      to {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n    }\n\n    @-webkit-keyframes appearIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(0px);\n        -ms-transform: translateY(0px);\n        transform: translateY(0px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes appearIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(0px);\n        -ms-transform: translateY(0px);\n        transform: translateY(0px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @-webkit-keyframes scaleIn {\n      from {\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        transform: scale(0);\n      }\n      to {\n        -webkit-transform: scale(1);\n        -ms-transform: scale(1);\n        transform: scale(1);\n      }\n    }\n\n    @keyframes scaleIn {\n      from {\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        transform: scale(0);\n      }\n      to {\n        -webkit-transform: scale(1);\n        -ms-transform: scale(1);\n        transform: scale(1);\n      }\n    }\n\n    @-webkit-keyframes innerDrawIn {\n      0% {\n        stroke-dashoffset: 70;\n      }\n      50% {\n        stroke-dashoffset: 140;\n      }\n      100% {\n        stroke-dashoffset: 210;\n      }\n    }\n\n    @keyframes innerDrawIn {\n      0% {\n        stroke-dashoffset: 70;\n      }\n      50% {\n        stroke-dashoffset: 140;\n      }\n      100% {\n        stroke-dashoffset: 210;\n      }\n    }\n\n    @-webkit-keyframes outerDrawIn {\n      0% {\n        stroke-dashoffset: 76;\n      }\n      100% {\n        stroke-dashoffset: 152;\n      }\n    }\n\n    @keyframes outerDrawIn {\n      0% {\n        stroke-dashoffset: 76;\n      }\n      100% {\n        stroke-dashoffset: 152;\n      }\n    }\n\n    .hHWjkv {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n    }\n\n    .gCDOzd {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n    }\n\n    .hmCcxi {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n    }\n\n    .eHamQi {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n    }\n\n    .byhgGu {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n    }\n\n    .llAKP {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n    }\n\n    .bglIGM {\n      -webkit-transform-origin: 64px 28px;\n      -ms-transform-origin: 64px 28px;\n      transform-origin: 64px 28px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n    }\n\n    .ksxRII {\n      -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;\n      -ms-transform-origin: 95.98500061035156px 46.510000228881836px;\n      transform-origin: 95.98500061035156px 46.510000228881836px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n    }\n\n    .cWrBmb {\n      -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;\n      -ms-transform-origin: 95.97162628173828px 83.4900016784668px;\n      transform-origin: 95.97162628173828px 83.4900016784668px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n    }\n\n    .Wnusb {\n      -webkit-transform-origin: 64px 101.97999572753906px;\n      -ms-transform-origin: 64px 101.97999572753906px;\n      transform-origin: 64px 101.97999572753906px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n    }\n\n    .bfPqf {\n      -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;\n      -ms-transform-origin: 32.03982162475586px 83.4900016784668px;\n      transform-origin: 32.03982162475586px 83.4900016784668px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n    }\n\n    .edRCTN {\n      -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;\n      -ms-transform-origin: 32.033552169799805px 46.510000228881836px;\n      transform-origin: 32.033552169799805px 46.510000228881836px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n    }\n\n    .iEGVWn {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .bsocdx {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .jAZXmP {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .hSeArx {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .bVgqGk {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .hEFqBt {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .dzEKCM {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    .DYnPx {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    .hjPEAQ {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    #loading-wrapper {\n      position: absolute;\n      width: 100vw;\n      height: 100vh;\n      display: -webkit-box;\n      display: -webkit-flex;\n      display: -ms-flexbox;\n      display: flex;\n      -webkit-align-items: center;\n      -webkit-box-align: center;\n      -ms-flex-align: center;\n      align-items: center;\n      -webkit-box-pack: center;\n      -webkit-justify-content: center;\n      -ms-flex-pack: center;\n      justify-content: center;\n      -webkit-flex-direction: column;\n      -ms-flex-direction: column;\n      flex-direction: column;\n    }\n\n    .logo {\n      width: 75px;\n      height: 75px;\n      margin-bottom: 20px;\n      opacity: 0;\n      -webkit-animation: fadeIn 0.5s ease-out forwards;\n      animation: fadeIn 0.5s ease-out forwards;\n    }\n\n    .text {\n      font-size: 32px;\n      font-weight: 200;\n      text-align: center;\n      color: rgba(255, 255, 255, 0.6);\n      opacity: 0;\n      -webkit-animation: fadeIn 0.5s ease-out forwards;\n      animation: fadeIn 0.5s ease-out forwards;\n    }\n\n    .dGfHfc {\n      font-weight: 400;\n    }\n  </style>\n  <div id=\"loading-wrapper\">\n    <svg class=\"logo\" viewBox=\"0 0 128 128\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n      <title>GraphQL Playground Logo</title>\n      <defs>\n        <linearGradient id=\"linearGradient-1\" x1=\"4.86%\" x2=\"96.21%\" y1=\"0%\" y2=\"99.66%\">\n          <stop stop-color=\"#E00082\" stop-opacity=\".8\" offset=\"0%\"></stop>\n          <stop stop-color=\"#E00082\" offset=\"100%\"></stop>\n        </linearGradient>\n      </defs>\n      <g>\n        <rect id=\"Gradient\" width=\"127.96\" height=\"127.96\" y=\"1\" fill=\"url(#linearGradient-1)\" rx=\"4\"></rect>\n        <path id=\"Border\" fill=\"#E00082\" fill-rule=\"nonzero\" d=\"M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z\"></path>\n        <path class=\"bglIGM\" x=\"64\" y=\"28\" fill=\"#fff\" d=\"M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8\" style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"ksxRII\" x=\"95.98500061035156\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"cWrBmb\" x=\"95.97162628173828\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"Wnusb\" x=\"64\" y=\"101.97999572753906\" fill=\"#fff\" d=\"M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"bfPqf\" x=\"32.03982162475586\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"edRCTN\" x=\"32.033552169799805\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"iEGVWn\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M63.55 27.5l32.9 19-32.9-19z\"></path>\n        <path class=\"bsocdx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96 46v38-38z\"></path>\n        <path class=\"jAZXmP\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96.45 84.5l-32.9 19 32.9-19z\"></path>\n        <path class=\"hSeArx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M64.45 103.5l-32.9-19 32.9 19z\"></path>\n        <path class=\"bVgqGk\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M32 84V46v38z\"></path>\n        <path class=\"hEFqBt\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M31.55 46.5l32.9-19-32.9 19z\"></path>\n        <path class=\"dzEKCM\" id=\"Triangle-Bottom\" stroke=\"#fff\" stroke-width=\"4\" d=\"M30 84h70\" stroke-linecap=\"round\"></path>\n        <path class=\"DYnPx\" id=\"Triangle-Left\" stroke=\"#fff\" stroke-width=\"4\" d=\"M65 26L30 87\" stroke-linecap=\"round\"></path>\n        <path class=\"hjPEAQ\" id=\"Triangle-Right\" stroke=\"#fff\" stroke-width=\"4\" d=\"M98 87L63 26\" stroke-linecap=\"round\"></path>\n      </g>\n    </svg>\n    <div class=\"text\">Loading\n      <span class=\"dGfHfc\">GraphQL Playground</span>\n    </div>\n  </div>\n\n  <div id=\"root\" />\n  <script type=\"text/javascript\">\n    window.addEventListener('load', function (event) {\n\n      const loadingWrapper = document.getElementById('loading-wrapper');\n      loadingWrapper.classList.add('fadeOut');\n\n\n      const root = document.getElementById('root');\n      root.classList.add('playgroundIn');\n\n      GraphQLPlayground.init(root, {\n        // you can add more options here\n      })\n    })\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/dist\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.7.22](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.21...graphql-playground-middleware-express@1.7.22) (2020-10-20)\n\n**Note:** Version bump only for package graphql-playground-middleware-express\n\n\n\n\n\n## [1.7.21](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.20...graphql-playground-middleware-express@1.7.21) (2020-09-15)\n\n**Note:** Version bump only for package graphql-playground-middleware-express\n\n\n\n\n\n## [1.7.20](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.19...graphql-playground-middleware-express@1.7.20) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-express\n\n\n\n\n\n## [1.7.19](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.15...graphql-playground-middleware-express@1.7.19) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-express\n\n\n\n\n\n## 1.7.15 (2020-06-07)\n\n\n### Bug Fixes\n\n* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))\n* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n* **deps:** Update express mw to latest graphql-playground-html ([#984](https://github.com/graphcool/graphql-playground/issues/984)) ([0bc65e8](https://github.com/graphcool/graphql-playground/commit/0bc65e8643b10b0c3b2158865e817e7910411afe))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n### Bug Fixes\n\n* **graphql 14:** version bump via graphql-config ([#861](https://github.com/graphcool/graphql-playground/issues/861)) ([5ea711c](https://github.com/graphcool/graphql-playground/commit/5ea711c590c1265c873324b28cd3483d3e05dc98))\n\n\n\n## 1.6.2 (2018-07-06)\n\n\n\n## 1.6.1 (2018-06-26)\n\n\n\n## 1.5.9 (2018-05-25)\n\n\n\n## 1.5.8 (2018-05-10)\n\n\n\n# 1.4.0 (2018-01-15)\n\n\n### Bug Fixes\n\n* **deps:** make graphql-config a normal dep ([9e4d93e](https://github.com/graphcool/graphql-playground/commit/9e4d93e0cf7ebd3ba1806407383e071fda37cb55))\n* **deps:** Remove extension dependencies ([72ce36c](https://github.com/graphcool/graphql-playground/commit/72ce36cdd96f35efefd916993a949e646c5f94b2)), closes [#493](https://github.com/graphcool/graphql-playground/issues/493)\n* **subscriptions:** fixed subscriptions url normalization ([f675517](https://github.com/graphcool/graphql-playground/commit/f67551718fb93d9170ca393e996e588a8fa834c8))\n\n\n\n## 1.3.23 (2018-01-08)\n\n\n### Bug Fixes\n\n* **deps:** Update graphql-playground-middleware-express ([0ac03f3](https://github.com/graphcool/graphql-playground/commit/0ac03f3557ef2b348de606eb8a24b88d5f0b0a0b))\n\n\n\n## 1.3.22 (2018-01-05)\n\n\n\n## 1.3.12 (2017-12-24)\n\n\n\n## 1.3.11 (2017-12-24)\n\n\n\n## 1.3.9 (2017-12-14)\n\n\n\n## 1.3.6 (2017-12-04)\n\n\n\n## 1.3.5 (2017-12-04)\n\n\n### Features\n\n* **middleware:** draft animated loading screen ([c082c07](https://github.com/graphcool/graphql-playground/commit/c082c07cdcfeae50dd0c43a5ae225729a91556ef))\n\n\n\n# 1.3.0 (2017-12-01)\n\n\n\n# 1.2.0 (2017-11-24)\n\n\n### Bug Fixes\n\n* fix example ([714d571](https://github.com/graphcool/graphql-playground/commit/714d571b530143a1b55a349714e5c6679a757fa8))\n\n\n### Features\n\n* sparate express into its own package ([8e250d4](https://github.com/graphcool/graphql-playground/commit/8e250d4b4929e3bceba61484d8f85444036c3dc5))\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/README.md",
    "content": "# graphql-playground-middleware-express\n\n> Express middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURITY NOTE**: All versions of `graphql-playground-express` until `1.7.16` or later have a security vulnerability when unsanitized user input is used while invoking `expressPlayground()`. [Read more below](#security-notes)\n\n## Installation\n\nUsing yarn:\n\n```console\nyarn add graphql-playground-middleware-express\n```\n\nOr npm:\n\n```console\nnpm install graphql-playground-middleware-express --save\n```\n\n## Usage\n\nSee full example in [examples/basic](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-express/examples/basic).\n\n```js\nconst express = require('express')\nconst expressPlayground = require('graphql-playground-middleware-express')\n  .default\n\nconst app = express()\n\napp.get('/playground', expressPlayground({ endpoint: '/graphql' }))\n```\n\n## Security Notes\n\nAll versions before `1.7.16` were vulnerable to user-defined input to `expressPlayground()`. Read more in [the security notes](https://github.com/prisma/graphql-playground/tree/main/SECURITY.md)\n\n### Security Upgrade Steps\n\nTo fix the issue, you can upgrade to `1.6.12` or later. If you aren't able to upgrade, see the security notes for a workaround.\n\n**yarn:**\n`yarn add graphql-playground-express@^1.7.16`\n\n**npm:**\n`npm install --save graphql-playground-express@^1.7.16`\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/.envrc",
    "content": "export PORT=4000"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/.graphqlconfig.yml",
    "content": "schemaPath: schema.graphql\nextensions:\n  endpoints:\n    default:\n      url: 'https://airbnb.now.sh'\n      subscription: 'wss://airbnb.now.sh'\n    local:\n      url: 'http://localhost:${env:PORT}/graphql'\n      subscription: 'ws://localhost:${env:PORT}'\n\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/README.md",
    "content": "# GraphQL Playground Express.js Example\n\n```sh\n$ yarn\n$ node index.js\n```"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/index.js",
    "content": "const express = require('express')\nconst { ApolloServer, gql } = require('apollo-server-express')\nconst expressPlayground = require('../../dist/index').default\n\nconst typeDefs = gql`\n  type Query {\n    hello: String!\n  }\n  schema {\n    query: Query\n  }\n`\nconst resolvers = {\n  Query: {\n    hello: () => 'world',\n  },\n}\n\nconst PORT = 4000\n\nconst server = new ApolloServer({ typeDefs, resolvers })\nconst app = express()\nserver.applyMiddleware({ app })\n\napp.get(\n  '/playground',\n  expressPlayground({\n    endpoint: '/graphql/</script><script>alert(1)</script><script>',\n  }),\n)\napp.listen(PORT)\n\nconsole.log(\n  `Serving the GraphQL Playground on http://localhost:${PORT}/playground`,\n)\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/package.json",
    "content": "{\n  \"name\": \"basic\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node index.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"apollo-server-express\": \"^2.11.0\",\n    \"express\": \"^4.17.1\",\n    \"graphql\": \"^15.0.0\",\n    \"graphql-playground-middleware-express\": \"^1.7.12\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/.envrc",
    "content": "export PORT=4000"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/.graphqlconfig.yml",
    "content": "schemaPath: schema.graphql\nprojects:\n  db:\n    extensions:\n      # graphcool: graphcool.yml\n      prisma: prisma.yml\n  gateway:\n    extensions:\n      endpoints:\n        default:\n          url: 'https://airbnb.now.sh'\n          subscription: 'wss://airbnb.now.sh'\n        local:\n          url: 'http://localhost:${env:PORT}/graphql'\n          subscription: 'ws://localhost:${env:PORT}'\n\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/README.md",
    "content": "# GraphQL Playground Express.js Example\n\n```sh\n$ yarn\n$ node index.js\n```"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/datamodel.graphql",
    "content": "type User {\n  id: ID! @unique\n  name: String!\n  trolo: Int\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/graphcool.yml",
    "content": "service: whh\nstage: dev\ncluster: workspace-asd/graphcool-eu1\n\ndatamodel:\n- datamodel.graphql\n\ndisableAuth: true\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/index.js",
    "content": "const express = require(\"express\");\nconst { gql, ApolloServer } = require(\"apollo-server-express\");\nconst expressPlayground = require(\"../../dist/index\").default;\n\nconst typeDefs = gql`\n  type Query {\n    hello: String!\n  }\n  schema {\n    query: Query\n  }\n`;\nconst resolvers = {\n  Query: {\n    hello: () => \"world\"\n  }\n};\nconst PORT = 4001;\n\nconst server = new ApolloServer({ typeDefs, resolvers });\nconst app = express();\nserver.applyMiddleware({ app });\n\napp.get(\n  \"/playground\",\n  expressPlayground({\n    endpoint: \"/graphql\",\n    env: process.env,\n    useGraphQLConfig: true\n  })\n);\n\napp.listen(PORT);\n\nconsole.log(\n  `Serving the GraphQL Playground on http://localhost:${PORT}/playground`\n);\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/package.json",
    "content": "{\n  \"name\": \"basic\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node index.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"apollo-server-express\": \"^2.11.0\",\n    \"express\": \"^4.17.1\",\n    \"graphql\": \"^15.0.0\",\n    \"graphql-playground-middleware-express\": \"^1.7.12\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/prisma.yml",
    "content": "service: whh\nstage: dev\ncluster: workspace-asd/prisma-eu1\n\ndatamodel:\n- datamodel.graphql\n\ndisableAuth: true\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/schema.graphql",
    "content": "# THIS FILE HAS BEEN AUTO-GENERATED BY THE \"GRAPHCOOL DEPLOY\"\n# DO NOT EDIT THIS FILE DIRECTLY\n\n#\n# Model Types\n#\n\ntype User implements Node {\n  id: ID!\n  name: String!\n  trolo: Int\n}\n\n\n#\n# Other Types\n#\n\ntype BatchPayload {\n  count: Long!\n}\n\nscalar Long\n\ntype Mutation {\n  createUser(data: UserCreateInput!): User!\n  updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User\n  deleteUser(where: UserWhereUniqueInput!): User\n  upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User!\n  updateManyUsers(data: UserUpdateInput!, where: UserWhereInput!): BatchPayload!\n  deleteManyUsers(where: UserWhereInput!): BatchPayload!\n  resetData: Boolean\n}\n\ninterface Node {\n  id: ID!\n}\n\ntype PageInfo {\n  hasNextPage: Boolean!\n  hasPreviousPage: Boolean!\n  startCursor: String\n  endCursor: String\n}\n\ntype Query {\n  users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]!\n  user(where: UserWhereUniqueInput!): User\n  usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection!\n  node(id: ID!): Node\n}\n\ntype UserConnection {\n  pageInfo: PageInfo!\n  edges: [UserEdge!]\n}\n\ninput UserCreateInput {\n  name: String!\n  trolo: Int\n}\n\ntype UserEdge {\n  node: User!\n  cursor: String!\n}\n\nenum UserOrderByInput {\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  trolo_ASC\n  trolo_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  createdAt_ASC\n  createdAt_DESC\n}\n\ninput UserUpdateInput {\n  name: String\n  trolo: Int\n}\n\ninput UserWhereInput {\n  AND: [UserWhereInput!]\n  OR: [UserWhereInput!]\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  name: String\n  name_not: String\n  name_in: [String!]\n  name_not_in: [String!]\n  name_lt: String\n  name_lte: String\n  name_gt: String\n  name_gte: String\n  name_contains: String\n  name_not_contains: String\n  name_starts_with: String\n  name_not_starts_with: String\n  name_ends_with: String\n  name_not_ends_with: String\n  trolo: Int\n  trolo_not: Int\n  trolo_in: [Int!]\n  trolo_not_in: [Int!]\n  trolo_lt: Int\n  trolo_lte: Int\n  trolo_gt: Int\n  trolo_gte: Int\n}\n\ninput UserWhereUniqueInput {\n  id: ID\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/package.json",
    "content": "{\n  \"name\": \"graphql-playground-middleware-express\",\n  \"version\": \"1.7.22\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playground/tree/main/packages/graphql-playground-middleware-express\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).\",\n  \"contributors\": [\n    \"Tim Suchanek <tim@graph.cool>\",\n    \"Johannes Schickling <johannes@graph.cool>\",\n    \"Mohammad Rajabifard <mo.rajbi@gmail.com>\"\n  ],\n  \"repository\": \"http://github.com/graphcool/graphql-playground.git\",\n  \"license\": \"MIT\",\n  \"main\": \"dist/index.js\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"build\": \"rimraf dist && tsc\",\n    \"prepare\": \"npm run build\"\n  },\n  \"keywords\": [\n    \"graphql\",\n    \"graphiql\",\n    \"playground\",\n    \"graphcool\"\n  ],\n  \"peerDependencies\": {\n    \"express\": \"^4.16.2\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"12.12.34\",\n    \"express\": \"^4.17.1\",\n    \"rimraf\": \"3.0.2\",\n    \"typescript\": \"3.8.3\"\n  },\n  \"dependencies\": {\n    \"graphql-playground-html\": \"^1.6.29\"\n  },\n  \"typings\": \"dist/index.d.ts\",\n  \"typescript\": {\n    \"definition\": \"dist/index.d.ts\"\n  },\n  \"gitHead\": \"53d233f9deb9dcc86f99e41268ff92b6367e0713\"\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/src/index.ts",
    "content": "import { Request, Response } from 'express'\nimport {\n  MiddlewareOptions,\n  renderPlaygroundPage,\n} from 'graphql-playground-html'\n\n/* tslint:disable */\n\nexport type ExpressPlaygroundMiddleware = (\n  req: Request,\n  res: Response,\n  next: () => void,\n) => void\n\nexport type Register = (\n  options: MiddlewareOptions,\n) => ExpressPlaygroundMiddleware\n\nconst express: Register = function voyagerExpress(options: MiddlewareOptions) {\n  return (req, res, next) => {\n    res.setHeader('Content-Type', 'text/html')\n    const playground = renderPlaygroundPage(options)\n    res.write(playground)\n    res.end()\n  }\n}\n\nexport default express\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": false,\n    \"strictNullChecks\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/dist\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.6.19](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-hapi@1.6.18...graphql-playground-middleware-hapi@1.6.19) (2020-10-20)\n\n**Note:** Version bump only for package graphql-playground-middleware-hapi\n\n\n\n\n\n## [1.6.18](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-hapi@1.6.17...graphql-playground-middleware-hapi@1.6.18) (2020-09-15)\n\n**Note:** Version bump only for package graphql-playground-middleware-hapi\n\n\n\n\n\n## [1.6.17](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-hapi@1.6.16...graphql-playground-middleware-hapi@1.6.17) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-hapi\n\n\n\n\n\n## [1.6.16](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-hapi@1.6.14...graphql-playground-middleware-hapi@1.6.16) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-hapi\n\n\n\n\n\n## 1.6.14 (2020-06-07)\n\n\n### Bug Fixes\n\n* hapi and koa mws for next release ([#1217](https://github.com/graphcool/graphql-playground/issues/1217)) ([40c35fc](https://github.com/graphcool/graphql-playground/commit/40c35fc4c73b939d002c9d2dff51eed5dd0b6aa9))\n* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))\n* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))\n* **deps:** [security] bump cryptiles ([6e84bbc](https://github.com/graphcool/graphql-playground/commit/6e84bbcd381627bd790c256c74994aed0371f293))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n\n## 1.6.2 (2018-07-06)\n\n\n\n## 1.6.1 (2018-06-26)\n\n\n\n## 1.5.9 (2018-05-25)\n\n\n### Bug Fixes\n\n* update to support hapi 17 ([#396](https://github.com/graphcool/graphql-playground/issues/396)) ([a4ddbd6](https://github.com/graphcool/graphql-playground/commit/a4ddbd62332b73bb67773ddd58dfecb76f1ef28d))\n* **deps:** update dependency graphql-playground-html to v1.5.2 ([29a6065](https://github.com/graphcool/graphql-playground/commit/29a6065f5c93d5efebb9c80549ef5467cc80da54))\n\n\n\n## 1.3.6 (2017-12-04)\n\n\n\n## 1.3.5 (2017-12-04)\n\n\n\n# 1.3.0 (2017-12-01)\n\n\n\n# 1.2.0 (2017-11-24)\n\n\n### Features\n\n* extract hapi middlewate into its own package ([a53568b](https://github.com/graphcool/graphql-playground/commit/a53568b575c80672db1194aeb96bc4c1d5b7f2d2))\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/README.md",
    "content": "# graphql-playground-middleware-hapi\n\n> Koa middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURITY NOTE**: All versions of `graphql-playground-middleware-hapi` until `1.6.13` or later have a security vulnerability when unsanitized user input is used while invoking `hapiPlayground()`. [Read more below](#security-notes)\n\n## Installation\n\nUsing yarn:\n\n```console\nyarn add graphql-playground-middleware-hapi\n```\n\nOr npm:\n\n```console\nnpm install graphql-playground-middleware-hapi --save\n```\n\n## Usage\n\nSee full example in [examples/basic](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-hapi/examples/basic).\n\nminimal example:\n\n```js\nconst hapiPlayground = require('graphql-playground-middleware-hapi').default\n\nconst playground = {\n  plugin: hapiPlayground,\n  options: {\n    path: '/playground',\n    endpoint: '/graphql',\n  },\n}\n\nconst app = new Hapi.server({\n  port: 3000,\n})\n\napp.register(playground)\n;(async () => await app.start())()\n```\n\n## Security Notes\n\nAll versions before `1.6.13` were vulnerable to user-defined input to `hapiPlayground()`. Read more in [the security notes](https://github.com/prisma/graphql-playground/tree/main/SECURITY.md)\n\n### Security Upgrade Steps\n\nTo fix the issue, you can upgrade to `1.6.13` or later. If you aren't able to upgrade, see the security notes for a workaround.\n\n**yarn:**\n`yarn add graphql-playground-middleware-hapi@^1.6.13`\n\n**npm:**\n`npm install --save graphql-playground-middleware-hapi@^1.6.13`\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/examples/basic/README.md",
    "content": "# GraphQL Playground Hapi Example\n\n> Note: `graphql-playground-middleware-hapi` @^2.0.0 requires `hapi` 17, for `hapi` 16 please use @^1.3.6\n\n```sh\n$ yarn\n$ node index.js\n```\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/examples/basic/index.js",
    "content": "const Hapi = require('@hapi/hapi')\nconst { ApolloServer, gql } = require('apollo-server-hapi')\nconst hapiPlayground = require('../../dist').default\nconst { makeExecutableSchema } = require('graphql-tools')\n\nconst HOST = 'localhost'\nconst PORT = 4000\n\nconst schema = makeExecutableSchema({\n  typeDefs: `\n    type Query {\n      hello: String!\n    }\n    schema {\n      query: Query\n    }\n  `,\n  resolvers: {\n    Query: {\n      hello: () => 'world',\n    },\n  },\n})\n\nconst playground = {\n  plugin: hapiPlayground,\n  options: {\n    path: '/playground',\n    endpoint: '/graphql',\n  },\n}\n\nasync function start() {\n  console.log(`Setting up server...`)\n  try {\n    const server = new ApolloServer({ schema })\n\n    const app = new Hapi.server({\n      host: HOST,\n      port: PORT,\n      debug: { request: '*' },\n    })\n    app.register(playground)\n\n    await server.applyMiddleware({\n      app,\n    })\n\n    await server.installSubscriptionHandlers(app.listener)\n\n    await app.start()\n    console.log(`Server running at: ${app.info.uri}`)\n  } catch (err) {\n    console.log(`Failed to start server!`, err)\n  }\n}\n\nstart()\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/examples/basic/package.json",
    "content": "{\n  \"name\": \"hapi\",\n  \"version\": \"2.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"apollo-server-hapi\": \"^2.14.0\",\n    \"graphql\": \"^15.0.0\",\n    \"graphql-tools\": \"^6.0.3\",\n    \"@hapi/hapi\": \"^19.1.1\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/package.json",
    "content": "{\n  \"name\": \"graphql-playground-middleware-hapi\",\n  \"version\": \"1.6.19\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playground/tree/main/packages/graphql-playground-middleware-hapi\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).\",\n  \"contributors\": [\n    \"Tim Suchanek <tim@graph.cool>\",\n    \"Johannes Schickling <johannes@graph.cool>\",\n    \"Mohammad Rajabifard <mo.rajbi@gmail.com>\",\n    \"Drake Costa <drake@saeris.io>\"\n  ],\n  \"repository\": \"http://github.com/graphcool/graphql-playground.git\",\n  \"license\": \"MIT\",\n  \"main\": \"dist/index.js\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"build\": \"rimraf dist && tsc\",\n    \"prepare\": \"npm run build\"\n  },\n  \"keywords\": [\n    \"graphql\",\n    \"graphiql\",\n    \"playground\",\n    \"graphcool\",\n    \"hapi\"\n  ],\n  \"peerDependencies\": {\n    \"@hapi/hapi\": \"^19.1.1\"\n  },\n  \"devDependencies\": {\n    \"@hapi/hapi\": \"^19.1.1\",\n    \"@types/node\": \"12.12.34\",\n    \"rimraf\": \"3.0.2\",\n    \"typescript\": \"3.8.3\"\n  },\n  \"typings\": \"dist/index.d.ts\",\n  \"typescript\": {\n    \"definition\": \"dist/index.d.ts\"\n  },\n  \"dependencies\": {\n    \"graphql-playground-html\": \"^1.6.29\"\n  },\n  \"gitHead\": \"53d233f9deb9dcc86f99e41268ff92b6367e0713\"\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/src/index.ts",
    "content": "import { Server, Plugin } from '@hapi/hapi'\nimport {\n  MiddlewareOptions,\n  RenderPageOptions,\n  renderPlaygroundPage,\n} from 'graphql-playground-html'\n\nexport interface Register {\n  (server: Server, options: MiddlewareOptions): void\n}\n\nconst plugin: Plugin = {\n  name: 'graphql-playground',\n  register: function (server, options: any) {\n    if (arguments.length !== 2) {\n      throw new Error(\n        `Playground middleware expects exactly 2 arguments, got ${\n        arguments.length\n        }`,\n      )\n    }\n\n    const { path, route: config = {}, ...rest } = options\n\n    const middlewareOptions: RenderPageOptions = {\n      ...rest,\n    }\n\n    server.route({\n      method: 'GET',\n      path,\n      config,\n      handler: (_request, h) =>\n        h.response(renderPlaygroundPage(middlewareOptions)).type('text/html'),\n    })\n  },\n}\n\nexport default plugin\n"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": false,\n    \"strictNullChecks\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/dist\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.6.21](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-koa@1.6.20...graphql-playground-middleware-koa@1.6.21) (2020-10-20)\n\n**Note:** Version bump only for package graphql-playground-middleware-koa\n\n\n\n\n\n## [1.6.20](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-koa@1.6.19...graphql-playground-middleware-koa@1.6.20) (2020-09-15)\n\n**Note:** Version bump only for package graphql-playground-middleware-koa\n\n\n\n\n\n## [1.6.19](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-koa@1.6.18...graphql-playground-middleware-koa@1.6.19) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-koa\n\n\n\n\n\n## [1.6.18](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-koa@1.6.16...graphql-playground-middleware-koa@1.6.18) (2020-08-30)\n\n\n### Bug Fixes\n\n* Koa middleware interface ([#1242](https://github.com/graphcool/graphql-playground/issues/1242)) ([b596775](https://github.com/graphcool/graphql-playground/commit/b5967759f05cc610f615ec73744dfa3cda156fe3))\n\n\n\n\n\n## 1.6.16 (2020-06-07)\n\n\n### Bug Fixes\n\n* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))\n* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n\n## 1.6.2 (2018-07-06)\n\n\n\n## 1.6.1 (2018-06-26)\n\n\n\n## 1.5.9 (2018-05-25)\n\n\n### Bug Fixes\n\n* **deps:** update dependency graphql-playground-html to v1.5.2 ([29a6065](https://github.com/graphcool/graphql-playground/commit/29a6065f5c93d5efebb9c80549ef5467cc80da54))\n\n\n\n## 1.3.6 (2017-12-04)\n\n\n\n## 1.3.5 (2017-12-04)\n\n\n\n# 1.3.0 (2017-12-01)\n\n\n\n# 1.2.0 (2017-11-24)\n\n\n### Features\n\n* extract koa middleware into its own package ([8f3a1a8](https://github.com/graphcool/graphql-playground/commit/8f3a1a81468e909f3ff7ac4f61efe62844a226bb))\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/README.md",
    "content": "# graphql-playground-middleware-koa\n\n> Koa middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURITY NOTE**: All versions of `graphql-playground-koa` until `1.6.15` or later have a security vulnerability when unsanitized user input is used while invoking `koaPlayground()`. [Read more below](#security-notes)\n\n## Installation\n\nUsing yarn:\n\n```console\nyarn add graphql-playground-middleware-koa\n```\n\nOr npm:\n\n```console\nnpm install graphql-playground-middleware-koa --save\n```\n\n## Usage\n\nSee full example in [examples/basic](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-koa/examples/basic).\n\n```js\nconst koa = require('koa')\nconst koaRouter = require('koa-router')\nconst koaPlayground = require('graphql-playground-middleware-koa')\n\nconst app = new koa()\nconst router = new koaRouter()\n\nrouter.all('/playground', koaPlayground({ endpoint: '/graphql' }))\n```\n\n## Security Notes\n\nAll versions before `1.6.15` were vulnerable to user-defined input to `koaPlayground()`. Read more in [the security notes](https://github.com/prisma/graphql-playground/tree/main/SECURITY.md)\n\n### Security Upgrade Steps\n\nTo fix the issue, you can upgrade to `1.6.15` or later. If you aren't able to upgrade, see the security notes for a workaround.\n\n**yarn:**\n`yarn add graphql-playground-koa@^1.6.15`\n\n**npm:**\n`npm install --save graphql-playground-koa@^1.6.15`\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/.graphqlconfig.yml",
    "content": "schemaPath: schema.graphql\nextensions:\n  endpoints:\n    default:\n      url: 'https://airbnb.now.sh'\n      subscription: 'wss://airbnb.now.sh'\n    local:\n      url: 'http://localhost:4000'\n      subscription: 'ws://localhost:4000'\n\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/README.md",
    "content": "# GraphQL Playground Koa.js Example\n\n```sh\n$ yarn\n$ node index.js\n```\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/index.js",
    "content": "const gql = require('graphql-tag')\nconst koa = require('koa')\nconst koaRouter = require('koa-router')\nconst koaBody = require('koa-bodyparser')\nconst { ApolloServer } = require('apollo-server-koa')\nconst { makeExecutableSchema } = require('graphql-tools')\nconst koaPlayground = require('../../dist/index').default\n\nconst typeDefs = gql`\n    type Query {\n      hello: String!\n    }\n    schema {\n      query: Query\n    }\n  `\nconst resolvers = {\n  Query: {\n    hello: () => 'world',\n  },\n}\n\nconst app = new koa()\nconst router = new koaRouter()\nconst PORT = 4000\nconst schema = makeExecutableSchema({ typeDefs, resolvers })\nconst graphql = new ApolloServer({ schema });\ngraphql.applyMiddleware({ app });\n\n// koaBody is needed just for POST.\napp.use(koaBody())\n\nrouter.all(\n  '/playground',\n  koaPlayground({\n    endpoint: '/graphql',\n  }),\n)\n\napp.use(router.routes())\napp.use(router.allowedMethods())\napp.listen(PORT)\n\nconsole.log(\n  `Serving the GraphQL Playground on http://localhost:${PORT}/playground`,\n)\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/package.json",
    "content": "{\n  \"name\": \"koa\",\n  \"version\": \"1.2.1-beta.1\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"apollo-server-koa\": \"^2.11.0\",\n    \"graphql\": \"^15.0.0\",\n    \"graphql-playground-middleware-koa\": \"^1.6.12\",\n    \"graphql-tag\": \"^2.10.3\",\n    \"graphql-tools\": \"^4.0.7\",\n    \"koa\": \"^2.11.0\",\n    \"koa-bodyparser\": \"^4.3.0\",\n    \"koa-router\": \"^8.0.8\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/package.json",
    "content": "{\n  \"name\": \"graphql-playground-middleware-koa\",\n  \"version\": \"1.6.21\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playground/tree/main/packages/graphql-playground-middleware-koa\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).\",\n  \"contributors\": [\n    \"Tim Suchanek <tim@graph.cool>\",\n    \"Johannes Schickling <johannes@graph.cool>\",\n    \"Mohammad Rajabifard <mo.rajbi@gmail.com>\"\n  ],\n  \"repository\": \"http://github.com/graphcool/graphql-playground.git\",\n  \"license\": \"MIT\",\n  \"main\": \"dist/index.js\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"build\": \"rimraf dist && tsc\",\n    \"prepare\": \"npm run build\"\n  },\n  \"keywords\": [\n    \"graphql\",\n    \"graphiql\",\n    \"playground\",\n    \"graphcool\",\n    \"koa\"\n  ],\n  \"peerDependencies\": {\n    \"koa\": \"^2\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"12.12.34\",\n    \"koa\": \"^2.11.0\",\n    \"rimraf\": \"3.0.2\",\n    \"typescript\": \"3.8.3\"\n  },\n  \"typings\": \"dist/index.d.ts\",\n  \"typescript\": {\n    \"definition\": \"dist/index.d.ts\"\n  },\n  \"dependencies\": {\n    \"graphql-playground-html\": \"^1.6.29\"\n  },\n  \"gitHead\": \"53d233f9deb9dcc86f99e41268ff92b6367e0713\"\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/src/index.ts",
    "content": "import { Context, Next } from 'koa'\nimport {\n  MiddlewareOptions,\n  renderPlaygroundPage,\n} from 'graphql-playground-html'\n\nexport declare type KoaPlaygroundMiddlewareOptions = MiddlewareOptions\n\n/* tslint:disable-next-line */\nexport type KoaPlaygroundMiddleware = (ctx: Context, next: Next) => Promise<void>\n\nexport type Register = (options: KoaPlaygroundMiddlewareOptions) => KoaPlaygroundMiddleware\n\nconst koa: Register = options => {\n  return async function voyager(ctx, next) {\n    try {\n      ctx.body = await renderPlaygroundPage(options)\n      await next()\n    } catch (err) {\n      ctx.body = { message: err.message }\n      ctx.status = err.status || 500\n    }\n  }\n}\n\nexport default koa\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": false,\n    \"strictNullChecks\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/dist\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.7.23](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-lambda@1.7.22...graphql-playground-middleware-lambda@1.7.23) (2020-10-20)\n\n**Note:** Version bump only for package graphql-playground-middleware-lambda\n\n\n\n\n\n## [1.7.22](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-lambda@1.7.21...graphql-playground-middleware-lambda@1.7.22) (2020-09-15)\n\n**Note:** Version bump only for package graphql-playground-middleware-lambda\n\n\n\n\n\n## [1.7.21](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-lambda@1.7.20...graphql-playground-middleware-lambda@1.7.21) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-lambda\n\n\n\n\n\n## [1.7.20](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-lambda@1.7.18...graphql-playground-middleware-lambda@1.7.20) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-middleware-lambda\n\n\n\n\n\n## 1.7.18 (2020-06-07)\n\n\n### Bug Fixes\n\n* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))\n* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))\n* **deps:** [security] bump content ([2ce2a37](https://github.com/graphcool/graphql-playground/commit/2ce2a376481f25b0bff5f2fdad164479415b1932))\n* **deps:** [security] bump lodash ([9b3c61a](https://github.com/graphcool/graphql-playground/commit/9b3c61a6ae7e84748eeffffca54c63bc1b6d1553))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n### Bug Fixes\n\n* **graphql 14:** version bump via graphql-config ([#861](https://github.com/graphcool/graphql-playground/issues/861)) ([5ea711c](https://github.com/graphcool/graphql-playground/commit/5ea711c590c1265c873324b28cd3483d3e05dc98))\n\n\n\n## 1.6.2 (2018-07-06)\n\n\n\n## 1.6.1 (2018-06-26)\n\n\n\n## 1.5.9 (2018-05-25)\n\n\n### Bug Fixes\n\n* **deps:** Remove extension dependencies ([72ce36c](https://github.com/graphcool/graphql-playground/commit/72ce36cdd96f35efefd916993a949e646c5f94b2)), closes [#493](https://github.com/graphcool/graphql-playground/issues/493)\n* **deps:** update dependency graphql-playground-html to v1.5.2 ([29a6065](https://github.com/graphcool/graphql-playground/commit/29a6065f5c93d5efebb9c80549ef5467cc80da54))\n* **subscriptions:** fixed subscriptions url normalization ([f675517](https://github.com/graphcool/graphql-playground/commit/f67551718fb93d9170ca393e996e588a8fa834c8))\n\n\n\n## 1.3.6 (2017-12-04)\n\n\n\n## 1.3.5 (2017-12-04)\n\n\n\n# 1.3.0 (2017-12-01)\n\n\n\n# 1.2.0 (2017-11-24)\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Graphcool\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/README.md",
    "content": "# graphql-playground-middleware-lambda\n\n> Koa middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURITY NOTE**: All versions of `graphql-playground-middleware-lambda` until `1.7.17` or later have a security vulnerability when unsanitized user input is used while invoking `lambdaPlayground()`. [Read more below](#security-notes)\n\n## Installation\n\nUsing yarn:\n\n```console\nyarn add graphql-playground-middleware-lambda\n```\n\nOr npm:\n\n```console\nnpm install graphql-playground-middleware-lambda --save\n```\n\n## Usage\n\nSee full example in [examples/basic](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-lambda/examples/basic).\n\nminimal example:\n\n```js\nconst lambdaPlayground = require('graphql-playground-middleware-lambda').default\n\nexports.handler = lambdaPlayground({\n  endpoint: '/dev',\n})\n```\n\n## Security Notes\n\nAll versions before `1.7.17` were vulnerable to user-defined input to `lambdaPlayground()`. Read more in [the security notes](https://github.com/prisma/graphql-playground/tree/SECURITY.md)\n\n### Security Upgrade Steps\n\nTo fix the issue, you can upgrade to `1.7.17`. If you aren't able to upgrade, see the security notes for a workaround.\n\n**yarn:**\n`yarn add graphql-playground-middleware-lambda@^1.7.17`\n\n**npm:**\n`npm install --save graphql-playground-middleware-lambda@^1.7.17`\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/.gitignore",
    "content": "node_modules\n.serverless\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/README.md",
    "content": "# graphql playground serverless example\n\n## Deploy\n\n```\n$ sls deploy\n```\n\n## Hosted Example\n\nThis example is also hosted here:\nhttps://1rp2h4rth8.execute-api.us-east-1.amazonaws.com/dev/playground\n\nexports.playgroundHandler = lambdaPlayground({\nendpoint: '/dev',\n})\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/handler.js",
    "content": "// or using require()\nconst { makeExecutableSchema } = require('graphql-tools')\nconst lambdaPlayground = require('graphql-playground-middleware-lambda').default\nconst { graphqlLambda } = require('apollo-server-lambda')\n\nconst typeDefs = `\ntype Post {\n  id: ID!\n  title: String\n}\n\ntype Query {\n  posts: [Post]\n}\nschema {\n  query: Query\n}\n`\n\nconst resolvers = {\n  Query: {\n    posts() {\n      return [{ id: '1', title: 'Awesome Post' }]\n    },\n  },\n}\n\nexports.graphqlHandler = function graphqlHandler(event, context, callback) {\n  function callbackFilter(error, output) {\n    // eslint-disable-next-line no-param-reassign\n    output.headers['Access-Control-Allow-Origin'] = '*'\n    callback(error, output)\n  }\n\n  const myGraphQLSchema = makeExecutableSchema({ typeDefs, resolvers })\n\n  const handler = graphqlLambda({ schema: myGraphQLSchema })\n  return handler(event, context, callbackFilter)\n}\n\nexports.playgroundHandler = lambdaPlayground({\n   endpoint: '/dev',\n})\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/package.json",
    "content": "{\n  \"name\": \"example\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"apollo-server-lambda\": \"^2.11.0\",\n    \"graphql\": \"^15.0.0\",\n    \"graphql-playground-middleware-lambda\": \"^1.7.13\",\n    \"graphql-tools\": \"^4.0.7\"\n  },\n  \"devDependencies\": {\n    \"serverless-offline\": \"^6.1.4\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/serverless.yml",
    "content": "service: playground-test\n\nprovider:\n  name: aws\n  runtime: nodejs6.10\n\n\nfunctions:\n  graphql:\n    handler: handler.graphqlHandler\n    events:\n    - http:\n        path: /\n        method: post\n        cors: true\n  playground:\n    handler: handler.playgroundHandler\n    events:\n    - http:\n        path: /\n        method: get\n        cors: true\n\nplugins:\n  - serverless-offline\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/package.json",
    "content": "{\n  \"name\": \"graphql-playground-middleware-lambda\",\n  \"version\": \"1.7.23\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playground/tree/main/packages/graphql-playground-middleware-lambda\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).\",\n  \"contributors\": [\n    \"Tim Suchanek <tim@graph.cool>\",\n    \"Johannes Schickling <johannes@graph.cool>\",\n    \"Mohammad Rajabifard <mo.rajbi@gmail.com>\"\n  ],\n  \"repository\": \"http://github.com/graphcool/graphql-playground.git\",\n  \"license\": \"MIT\",\n  \"main\": \"dist/index.js\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"build\": \"rimraf dist && tsc\",\n    \"prepare\": \"npm run build\"\n  },\n  \"keywords\": [\n    \"graphql\",\n    \"graphiql\",\n    \"playground\",\n    \"graphcool\",\n    \"lambada\"\n  ],\n  \"peerDependencies\": {\n    \"aws-lambda\": \"^1.0.5\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"12.12.34\",\n    \"aws-lambda\": \"1.0.5\",\n    \"rimraf\": \"3.0.2\",\n    \"typescript\": \"3.8.3\"\n  },\n  \"typings\": \"dist/index.d.ts\",\n  \"typescript\": {\n    \"definition\": \"dist/index.d.ts\"\n  },\n  \"dependencies\": {\n    \"graphql-playground-html\": \"^1.6.29\"\n  },\n  \"gitHead\": \"53d233f9deb9dcc86f99e41268ff92b6367e0713\"\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/src/index.ts",
    "content": "import * as lambda from 'aws-lambda'\nimport {\n  MiddlewareOptions,\n  renderPlaygroundPage,\n} from 'graphql-playground-html'\n\nexport default function lambdaPlayground(options: MiddlewareOptions) {\n  return async (\n    _event,\n    _lambdaContext: lambda.Context,\n    callback: lambda.Callback,\n  ) => {\n    const body = await renderPlaygroundPage(options)\n    callback(null, {\n      statusCode: 200,\n      headers: {\n        'Content-Type': 'text/html',\n      },\n      body,\n    })\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": false,\n    \"strictNullChecks\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/.babelrc",
    "content": "{\n  \"presets\": [\n    \"@babel/preset-env\",\n    \"@babel/preset-react\"\n  ],\n  \"plugins\": [\n    \"@babel/plugin-proposal-object-rest-spread\",\n    \"babel-plugin-styled-components\"\n  ]\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/.gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modules\nexample/yarn.lock\n\n# testing\n/coverage\n\n# production\n/build\n/dist\n\n# misc\n.DS_Store\n.env\nnpm-debug.log\n.idea\nlib\n/middleware\nplayground.css\n/middleware-build\n\n# editors\n.vscode\n"
  },
  {
    "path": "packages/graphql-playground-react/CHANGELOG.md",
    "content": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://conventionalcommits.org) for commit guidelines.\n\n## [1.7.27](https://github.com/graphcool/graphql-playground/compare/graphql-playground-react@1.7.26...graphql-playground-react@1.7.27) (2020-10-20)\n\n\n### Bug Fixes\n\n* bump codemirror graphql ([#1286](https://github.com/graphcool/graphql-playground/issues/1286)) ([4a4ea29](https://github.com/graphcool/graphql-playground/commit/4a4ea299033b59e14ec130cf85e5ddc11a3698d2))\n\n\n\n\n\n## [1.7.26](https://github.com/graphcool/graphql-playground/compare/graphql-playground-react@1.7.24...graphql-playground-react@1.7.26) (2020-08-30)\n\n**Note:** Version bump only for package graphql-playground-react\n\n\n\n\n\n## [1.7.24](https://github.com/graphcool/graphql-playground/compare/graphql-playground-react@1.7.23...graphql-playground-react@1.7.24) (2020-08-30)\n\n\n### Bug Fixes\n\n* 'addLineBreaks' regex in 'createSDL' to avoid line-breaking comment lines ([#1245](https://github.com/graphcool/graphql-playground/issues/1245)) ([f3b1e03](https://github.com/graphcool/graphql-playground/commit/f3b1e03f887a6dec36301577cdaa7184aff50cce))\n* upgrades, schema viewer display & width adjustment ([2bb34bb](https://github.com/graphcool/graphql-playground/commit/2bb34bb8fb8c356e10435727a3f82cd23464b6b6))\n\n\n\n\n\n## 1.7.23 (2020-06-07)\n\n\n### Bug Fixes\n\n* 'false' into a non-boolean attribute 'color' ([#1003](https://github.com/graphcool/graphql-playground/issues/1003)) ([1613643](https://github.com/graphcool/graphql-playground/commit/16136437270c1943ff9d7ce57ff58368dcebbc59))\n* allow results to fill the entire pane horizontally ([#1142](https://github.com/graphcool/graphql-playground/issues/1142)) ([d418b02](https://github.com/graphcool/graphql-playground/commit/d418b026dc98f008c2af4403b00ac2247078e838))\n* Allow scroll in result panel ([#1023](https://github.com/graphcool/graphql-playground/issues/1023)) ([8ee2f40](https://github.com/graphcool/graphql-playground/commit/8ee2f40ce10736c763b4bbc1d3476611e71dff1f))\n* graphql-playground -> graphql-playground-react ([#1210](https://github.com/graphcool/graphql-playground/issues/1210)) ([462cfdd](https://github.com/graphcool/graphql-playground/commit/462cfddc11a5c132dbb0bc460614529ff265a247))\n* hapi and koa mws for next release ([#1217](https://github.com/graphcool/graphql-playground/issues/1217)) ([40c35fc](https://github.com/graphcool/graphql-playground/commit/40c35fc4c73b939d002c9d2dff51eed5dd0b6aa9))\n* not showing deprecated fields on root level ([#995](https://github.com/graphcool/graphql-playground/issues/995)) ([2c33ecb](https://github.com/graphcool/graphql-playground/commit/2c33ecb1935725ad5347b38f61527e25ad9379a9))\n* Removed unnecessary } ([#1104](https://github.com/graphcool/graphql-playground/issues/1104)) ([6745aff](https://github.com/graphcool/graphql-playground/commit/6745aff4d945b9c107582a776f2ad5300518fc26))\n* schemaGetter props handling ([#1203](https://github.com/graphcool/graphql-playground/issues/1203)) ([d8d655e](https://github.com/graphcool/graphql-playground/commit/d8d655e8ded50034f5f8a83f05069769fc652463))\n* workaround for bug in SettingsEditor ([#1198](https://github.com/graphcool/graphql-playground/issues/1198)) ([02fff61](https://github.com/graphcool/graphql-playground/commit/02fff61f7872cc91f2fc026fd925f7af579d9e66))\n* X-Apollo-Tracing No Schema Issue ([#1112](https://github.com/graphcool/graphql-playground/issues/1112)) ([1ca035d](https://github.com/graphcool/graphql-playground/commit/1ca035d06f71cbe02aa8f36e7fce2095c2854ba6))\n* **deps:** [security] bump handlebars ([ba1fb9d](https://github.com/graphcool/graphql-playground/commit/ba1fb9d56e20806cf759d40abfe4b455993d1d13))\n* **deps:** [security] bump lodash in /packages/graphql-playground-react ([27c5368](https://github.com/graphcool/graphql-playground/commit/27c536825d89d112504109205fd2a111ab9c5c40))\n* **deps:** [security] bump react-dom ([a79c05e](https://github.com/graphcool/graphql-playground/commit/a79c05e49d937a1319a206c14e394a92a014e1de))\n* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))\n* **graphql-playground-react:** prevent selection of text ([#998](https://github.com/graphcool/graphql-playground/issues/998)) ([4482f5d](https://github.com/graphcool/graphql-playground/commit/4482f5d0faa656ad2b0ea1a54fea9bccb71b619a))\n* **graphql-playground-react:** Remove internal scrollbars for subscription results ([#986](https://github.com/graphcool/graphql-playground/issues/986)) ([fc871b6](https://github.com/graphcool/graphql-playground/commit/fc871b6b021a07664f2fd57d91f72693d8af8d3a))\n\n\n### Features\n\n* run query on variable, header editor through ctrl+enter ([#1141](https://github.com/graphcool/graphql-playground/issues/1141)) ([416694e](https://github.com/graphcool/graphql-playground/commit/416694ed0bdc3c8e4348095b79c8b16e36d6042a))\n\n\n\n## 1.8.10 (2019-02-23)\n\n\n\n## 1.8.9 (2019-02-01)\n\n\n\n## 1.8.8 (2019-01-30)\n\n\n\n## 1.8.7 (2019-01-28)\n\n\n### Bug Fixes\n\n* focus state of sidetabs on button clicks ([#913](https://github.com/graphcool/graphql-playground/issues/913)) ([4c05a53](https://github.com/graphcool/graphql-playground/commit/4c05a53588dfad18bdc129b5a07d2bc02eecb1e5))\n* support non primitive types in default value via JSON.strigify ([#914](https://github.com/graphcool/graphql-playground/issues/914)) ([562e1ef](https://github.com/graphcool/graphql-playground/commit/562e1efa23f28450fd13d063e504a2adb00c1a80))\n\n\n\n## 1.8.5 (2018-12-10)\n\n\n\n## 1.8.4 (2018-11-23)\n\n\n### Bug Fixes\n\n* do not throw error when server response with empty array errors ([#879](https://github.com/graphcool/graphql-playground/issues/879)) ([874d2ff](https://github.com/graphcool/graphql-playground/commit/874d2ff057fb2879a4f265a46811e08509b955d0))\n\n\n\n## 1.6.2 (2018-07-06)\n\n\n\n## 1.6.1 (2018-06-26)\n\n\n\n# 1.6.0 (2018-05-31)\n\n\n### Bug Fixes\n\n* empty history. Closes [#643](https://github.com/graphcool/graphql-playground/issues/643) ([84463b8](https://github.com/graphcool/graphql-playground/commit/84463b88ac8d5529bd75240e1230740858c12190))\n* new session error. Closes [#701](https://github.com/graphcool/graphql-playground/issues/701) ([5926762](https://github.com/graphcool/graphql-playground/commit/5926762bfba0379f628d62d71c4ab7ce5cf0fea6))\n* schema fetching for custom endpoints ([d8a17e8](https://github.com/graphcool/graphql-playground/commit/d8a17e82c0a24d10e1fa7c06b236c3742783825c))\n\n\n\n## 1.5.6 (2018-04-24)\n\n\n### Bug Fixes\n\n* **electron:** update graphql-config-extension-prisma ([8fd45a1](https://github.com/graphcool/graphql-playground/commit/8fd45a1c27172722c335b4c84b793813c2d52b7e))\n\n\n\n## 1.5.4 (2018-04-12)\n\n\n### Bug Fixes\n\n* correctly clearTimeout ([fbb5c1e](https://github.com/graphcool/graphql-playground/commit/fbb5c1ec55250015ef99c2c0dc27394fdf07683c))\n* error formatting for json error ([133de56](https://github.com/graphcool/graphql-playground/commit/133de565130ebfc50494a22898abc1d16c48c3d8))\n* less aggressive retry ([41ae3fe](https://github.com/graphcool/graphql-playground/commit/41ae3fe4d4590782a2b850d2fae967ade55b8ba8))\n* only inject headers to session when injected per url ([66f4a05](https://github.com/graphcool/graphql-playground/commit/66f4a050eece31dc17319eeb22d370785c765fbf))\n* prev tab selection ([dbdec7a](https://github.com/graphcool/graphql-playground/commit/dbdec7a0f42a50db4ed5a810cfde7923669754f3))\n* schema reloading ([4af733e](https://github.com/graphcool/graphql-playground/commit/4af733ebbc16fc356b09f5e5c209e9b9122e65ef))\n* show scrollbar, hide when not hovered (for windows) ([5c79d70](https://github.com/graphcool/graphql-playground/commit/5c79d70fbbed884ad658364e104eb196d1390b4f))\n* stop backoff when new starts ([12c41a3](https://github.com/graphcool/graphql-playground/commit/12c41a38a5f166f2cc3baef717d827b3db5d4a62))\n* temporarily disable animation until performance problem fixed ([59a39eb](https://github.com/graphcool/graphql-playground/commit/59a39ebbf2f8eb680d64db576d25828db129cf01))\n\n\n\n## 1.5.2 (2018-04-02)\n\n\n\n## 1.5.1 (2018-04-02)\n\n\n\n# 1.5.0 (2018-04-01)\n\n\n\n# 1.5.0-rc.5 (2018-03-28)\n\n\n### Bug Fixes\n\n* **electron:** endpoint injection ([39a1110](https://github.com/graphcool/graphql-playground/commit/39a1110a0284ef05c73ada3892c585c85e6e14a2))\n\n\n\n# 1.5.0-rc.2 (2018-03-26)\n\n\n\n## 1.4.5 (2018-03-15)\n\n\n### Bug Fixes\n\n* **cleanup:** Remove platform token, use origin ([2c9c160](https://github.com/graphcool/graphql-playground/commit/2c9c1606445119e7172045da2e4f8f14cfaab26a))\n* **deps:** update dependency styled-components to ^3.0.1 ([#526](https://github.com/graphcool/graphql-playground/issues/526)) ([12eb0f3](https://github.com/graphcool/graphql-playground/commit/12eb0f35228b3d24f34fff651434ac8d05c93e9c))\n* **link:** Fix 2 regression bugs introduced by switching to Apollo Link ([f0b139e](https://github.com/graphcool/graphql-playground/commit/f0b139ec19bc2269058c6030322074b195b48f7a)), closes [#579](https://github.com/graphcool/graphql-playground/issues/579) [#581](https://github.com/graphcool/graphql-playground/issues/581)\n* **props:** Make headers injectable via url ([f01ca8b](https://github.com/graphcool/graphql-playground/commit/f01ca8b767780e2dbf56ccc2bdd23430b192b502))\n* **settings:** Expose settings programmatically, update deps ([0356557](https://github.com/graphcool/graphql-playground/commit/03565573869f240675aaa5399bb5f0ac097455c5))\n\n\n### Features\n\n* migrate to apollo link as a network transport ([46d08f2](https://github.com/graphcool/graphql-playground/commit/46d08f282f8acff961f5b6167e5465069256b559))\n\n\n\n## 1.4.2 (2018-01-22)\n\n\n### Bug Fixes\n\n* **build:** Fix build, temporarily disable yarn workspace, update graphcool-styles & graphcool-ui de ([af501d7](https://github.com/graphcool/graphql-playground/commit/af501d7a754a14dbacc76439a77434f892828482))\n* **curl:** Fixed curl command generation ([0eb2492](https://github.com/graphcool/graphql-playground/commit/0eb2492545d8c58de80eb8e435840e3fadc144b2)), closes [#333](https://github.com/graphcool/graphql-playground/issues/333)\n* **graphql-playground-react:** Fix variable editor ([90af813](https://github.com/graphcool/graphql-playground/commit/90af8135be85b7088799c17e4f0b2994dcf2abb5)), closes [#372](https://github.com/graphcool/graphql-playground/issues/372)\n* **graphql-playground-react:** Replaced triangle Icon component with React SVG component ([0ef92d0](https://github.com/graphcool/graphql-playground/commit/0ef92d02e10493726a368de5000589bd6e1a0d28))\n* **graphql-playground-react:** Selected tab index is now properly persisted ([802b62e](https://github.com/graphcool/graphql-playground/commit/802b62e53a457ed10db5e39b3f7f7d4aa211d0bb))\n* **GraphQLEditor:** init state.isReloadingSchema to false ([b59c6e6](https://github.com/graphcool/graphql-playground/commit/b59c6e65725540ef19ded88e677070ab0f8db945))\n* **PlaygroundStorage:** Fix deserialization defaullt ([6766bb0](https://github.com/graphcool/graphql-playground/commit/6766bb001d98d4f131ac71c9bb07804891a7d287))\n* **react:** fix subscription payload ([b432655](https://github.com/graphcool/graphql-playground/commit/b4326555c84d90b96e10bad5cf5a0c826b4e500f))\n* **subscription:** fix subscription url handling ([e8a7d42](https://github.com/graphcool/graphql-playground/commit/e8a7d42d4a4458b6f0d0e27b7e31a5386ff50be8))\n* **subscriptions:** Fixed subscriptions ([8dc1769](https://github.com/graphcool/graphql-playground/commit/8dc17691734362853f2fd84c6bd56530f2ce7329))\n* **subscriptions:** fixed subscriptions url normalization ([f675517](https://github.com/graphcool/graphql-playground/commit/f67551718fb93d9170ca393e996e588a8fa834c8))\n* **subscriptions:** update subscriptions-transport-ws + update api calls ([e187c47](https://github.com/graphcool/graphql-playground/commit/e187c470a97a7ea6c03ce1ed6097eae2855fa251))\n* react app subscription handling ([362abf5](https://github.com/graphcool/graphql-playground/commit/362abf5a401bf73e377f941c52578ed78523d625))\n\n\n### Features\n\n* **graphql-playground-react:** added spinner for schema fetching ([24072cb](https://github.com/graphcool/graphql-playground/commit/24072cbd1d332fff402c4a829cfa25784f982f32))\n* **TopBar:** animate the icon when reloading schema ([9a4cb0a](https://github.com/graphcool/graphql-playground/commit/9a4cb0a587cae09cdfbe8781eef8ad3f92fbc3cd))\n* **TopBar:** notify the user when reloading the schema fails ([4df1da3](https://github.com/graphcool/graphql-playground/commit/4df1da30e6cbbc23510fbb6c36928e9e28cf3f08))\n\n\n### Reverts\n\n* Revert \"style(TopBar): fade in/out the error message if the endpoint is unreachable\" ([000946f](https://github.com/graphcool/graphql-playground/commit/000946fd2f334e5c46f1157731c5073010043281))\n"
  },
  {
    "path": "packages/graphql-playground-react/LICENSE",
    "content": "\nMIT License\n\nCopyright (c) 2017 Contributors et.al.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "packages/graphql-playground-react/README.md",
    "content": "<p align=\"center\"><img src=\"https://imgur.com/5fzMbyV.png\" width=\"269\"></p>\n\nGraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration). <br />\n**You can download the [desktop app](https://github.com/graphcool/graphql-playground/releases) or use the web version at graphqlbin.com: [Demo](https://www.graphqlbin.com/RVIn)**\n\n[![](https://imgur.com/6IC6Huj.png)](https://www.graphqlbin.com/RVIn)\n\n## Features\n\n- ✨ Context-aware autocompletion & error highlighting\n- 📚 Interactive, multi-column docs (keyboard support)\n- ⚡️ Supports real-time GraphQL Subscriptions\n\n## FAQ\n\n### How is this different from [GraphiQL](https://github.com/graphql/graphiql)?\n\nGraphQL Playground uses components of GraphiQL under the hood but is meant as a more powerful GraphQL IDE enabling better (local) development workflows. Compared to GraphiQL, the GraphQL Playground ships with the following additional features:\n\n- Interactive, multi-column schema documentation\n- Automatic schema reloading\n- Support for GraphQL Subscriptions\n- Query history\n- Configuration of HTTP headers\n- Tabs\n\nSee the following question for more additional features.\n\n### What's the difference between the desktop app and the web version?\n\nThe desktop app is the same as the web version but includes these additional features:\n\n- Support for [graphql-config](https://github.com/prisma/graphql-config) enabling features like multi-environment setups.\n- Double click on `*.graphql` files.\n\n### How does GraphQL Bin work?\n\nYou can easily share your Playgrounds with others by clicking on the \"Share\" button and sharing the generated link. You can think about GraphQL Bin like Pastebin for your GraphQL queries including the context (endpoint, HTTP headers, open tabs etc).\n\n![](https://imgur.com/H1n64lL.png)\n\n> You can also find the announcement blog post [here](https://www.prisma.io/blog/introducing-graphql-playground-f1e0a018f05d).\n\n## Usage\n\n### Properties\n\nAll interfaces, the React component `<Playground />` and all middlewares expose the same set of options:\n\n- `properties`\n  - `endpoint` [`string`] - the GraphQL endpoint url.\n  - `subscriptionEndpoint` [`string`] - the GraphQL subscriptions endpoint url.\n  - `setTitle` [`boolean`] - reflect the current endpoint in the page title\n\n### As React Component\n\n#### Install\n\n```sh\nyarn add graphql-playground-react\n```\n\n#### Use\n\nGraphQL Playground provides a React component responsible for rendering the UI and Session management.\nThere are **3 dependencies** needed in order to run the `graphql-playground` React component.\n\n1.  _Open Sans_ and _Source Code Pro_ fonts\n2.  Rendering the `<Playground />` component\n\nThe GraphQL Playground requires **React 16**.\n\nIncluding Fonts (`1.`)\n\n```html\n<link\n  href=\"https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,700\"\n  rel=\"stylesheet\"\n/>\n```\n\nIncluding stylesheet and the component (`2., 3.`)\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport Playground from 'graphql-playground'\n\nReactDOM.render(\n  <Playground endpoint='https://api.graph.cool/simple/v1/swapi' />,\n  document.body,\n)\n```\n\n### As Server Middleware\n\n#### Install\n\n```sh\n# Pick the one that matches your server framework\nyarn add graphql-playground-middleware-express  # for Express or Connect\nyarn add graphql-playground-middleware-hapi\nyarn add graphql-playground-middleware-koa\nyarn add graphql-playground-middleware-lambda\n```\n\n#### Usage with example\n\nWe have a full example for each of the frameworks below:\n\n- **Express:** See [packages/graphql-playground-middleware-express/examples/basic](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-express/examples/basic)\n\n- **Hapi:** See [packages/graphql-playground-middleware/examples/hapi](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-hapi/examples/basic)\n\n- **Koa:** See [packages/graphql-playground-middleware/examples/koa](https://github.com/prisma/graphql-playground/tree/main/packages/graphql-playground-middleware-koa/examples/basic)\n\n- **Lambda (as serverless handler):** See [serverless-graphql-apollo](https://github.com/serverless/serverless-graphql-apollo) or a quick example below.\n\n### As serverless handler\n\n#### Install\n\n```sh\nyarn add graphql-playground-middleware-lambda\n```\n\n#### Usage\n\n`handler.js`\n\n```js\nimport lambdaPlayground from 'graphql-playground-middleware-lambda'\n// or using require()\n// const lambdaPlayground = require('graphql-playground-middleware-lambda').default\n\nexports.graphqlHandler = function graphqlHandler(event, context, callback) {\n  function callbackFilter(error, output) {\n    // eslint-disable-next-line no-param-reassign\n    output.headers['Access-Control-Allow-Origin'] = '*'\n    callback(error, output)\n  }\n\n  const handler = graphqlLambda({ schema: myGraphQLSchema })\n  return handler(event, context, callbackFilter)\n}\n\nexports.playgroundHandler = lambdaPlayground({\n  endpoint: '/dev/graphql',\n})\n```\n\n`serverless.yml`\n\n```yaml\nfunctions:\n  graphql:\n    handler: handler.graphqlHandler\n    events:\n      - http:\n          path: graphql\n          method: post\n          cors: true\n  playground:\n    handler: handler.playgroundHandler\n    events:\n      - http:\n          path: playground\n          method: get\n          cors: true\n```\n\n## Development [![npm version](https://badge.fury.io/js/graphql-playground-react.svg)](https://badge.fury.io/js/graphql-playground-react)\n\nThis is a mono-repo setup containing packages for the `graphql-playground` and `graphql-playground-electron`.\n\n```sh\n$ cd packages/graphql-playground\n$ yarn\n$ yarn start\n```\n\nOpen\n[localhost:3000/localDev.html?endpoint=https://api.graph.cool/simple/v1/swapi](http://localhost:3000/localDev.html?endpoint=https://api.graph.cool/simple/v1/swapi) for local development!\n\n<a name=\"help-and-community\" />\n\n## Help & Community [![Discord](https://img.shields.io/discord/586999333447270440.svg)](https://discord.gg/EXUYPaY)\n\nJoin our [Discord Server](https://discord.gg/EXUYPaY) if you run into issues or have questions. We love talking to you!\n\n[![](http://i.imgur.com/5RHR6Ku.png)](https://www.graph.cool/)\n"
  },
  {
    "path": "packages/graphql-playground-react/config/env.js",
    "content": "'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst paths = require('./paths');\n\n// Make sure that including paths.js after env.js will read .env variables.\ndelete require.cache[require.resolve('./paths')];\n\nconst NODE_ENV = process.env.NODE_ENV;\nif (!NODE_ENV) {\n  throw new Error(\n    'The NODE_ENV environment variable is required but was not specified.'\n  );\n}\n\n// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use\nvar dotenvFiles = [\n  `${paths.dotenv}.${NODE_ENV}.local`,\n  `${paths.dotenv}.${NODE_ENV}`,\n  // Don't include `.env.local` for `test` environment\n  // since normally you expect tests to produce the same\n  // results for everyone\n  NODE_ENV !== 'test' && `${paths.dotenv}.local`,\n  paths.dotenv,\n].filter(Boolean);\n\n// Load environment variables from .env* files. Suppress warnings using silent\n// if this file is missing. dotenv will never modify any environment variables\n// that have already been set.\n// https://github.com/motdotla/dotenv\ndotenvFiles.forEach(dotenvFile => {\n  if (fs.existsSync(dotenvFile)) {\n    require('dotenv').config({\n      path: dotenvFile,\n    });\n  }\n});\n\n// We support resolving modules according to `NODE_PATH`.\n// This lets you use absolute paths in imports inside large monorepos:\n// https://github.com/facebookincubator/create-react-app/issues/253.\n// It works similar to `NODE_PATH` in Node itself:\n// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders\n// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.\n// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.\n// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421\n// We also resolve them to make sure all tools using them work consistently.\nconst appDirectory = fs.realpathSync(process.cwd());\nprocess.env.NODE_PATH = (process.env.NODE_PATH || '')\n  .split(path.delimiter)\n  .filter(folder => folder && !path.isAbsolute(folder))\n  .map(folder => path.resolve(appDirectory, folder))\n  .join(path.delimiter);\n\n// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be\n// injected into the application via DefinePlugin in Webpack configuration.\nconst REACT_APP = /^REACT_APP_/i;\n\nfunction getClientEnvironment(publicUrl) {\n  const raw = Object.keys(process.env)\n    .filter(key => REACT_APP.test(key))\n    .reduce(\n      (env, key) => {\n        env[key] = process.env[key];\n        return env;\n      },\n      {\n        // Useful for determining whether we’re running in production mode.\n        // Most importantly, it switches React into the correct mode.\n        NODE_ENV: process.env.NODE_ENV || 'development',\n        // Useful for resolving the correct path to static assets in `public`.\n        // For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.\n        // This should only be used as an escape hatch. Normally you would put\n        // images into the `src` and `import` them in code to get their paths.\n        PUBLIC_URL: publicUrl,\n      }\n    );\n  // Stringify all values so we can feed into Webpack DefinePlugin\n  const stringified = {\n    'process.env': Object.keys(raw).reduce((env, key) => {\n      env[key] = JSON.stringify(raw[key]);\n      return env;\n    }, {}),\n  };\n\n  return { raw, stringified };\n}\n\nmodule.exports = getClientEnvironment;\n"
  },
  {
    "path": "packages/graphql-playground-react/config/jest/cssTransform.js",
    "content": "// This is a custom Jest transformer turning style imports into empty objects.\n// http://facebook.github.io/jest/docs/tutorial-webpack.html\n\nmodule.exports = {\n  process() {\n    return 'module.exports = {};';\n  },\n  getCacheKey(fileData, filename) {\n    // The output is always the same.\n    return 'cssTransform';\n  },\n};\n"
  },
  {
    "path": "packages/graphql-playground-react/config/jest/fileTransform.js",
    "content": "const path = require('path');\n\n// This is a custom Jest transformer turning file imports into filenames.\n// http://facebook.github.io/jest/docs/tutorial-webpack.html\n\nmodule.exports = {\n  process(src, filename) {\n    return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';\n  },\n};\n"
  },
  {
    "path": "packages/graphql-playground-react/config/jest/typescriptTransform.js",
    "content": "// Copyright 2004-present Facebook. All Rights Reserved.\n\nconst tsc = require('typescript');\n\nmodule.exports = {\n  process(src, path) {\n    if (path.endsWith('.ts') || path.endsWith('.tsx')) {\n      return tsc.transpile(\n        src,\n        {\n          module: tsc.ModuleKind.CommonJS,\n          jsx: tsc.JsxEmit.React,\n        },\n        path,\n        []\n      );\n    }\n    return src;\n  },\n};\n"
  },
  {
    "path": "packages/graphql-playground-react/config/paths.js",
    "content": "'use strict'\n\nconst path = require('path')\nconst fs = require('fs')\nconst url = require('url')\n\n// Make sure any symlinks in the project folder are resolved:\n// https://github.com/facebookincubator/create-react-app/issues/637\nconst appDirectory = fs.realpathSync(process.cwd())\nconst resolveApp = relativePath => path.resolve(appDirectory, relativePath)\n\nconst envPublicUrl = process.env.PUBLIC_URL\n\nfunction ensureSlash(path, needsSlash) {\n  const hasSlash = path.endsWith('/')\n  if (hasSlash && !needsSlash) {\n    return path.substr(path, path.length - 1)\n  } else if (!hasSlash && needsSlash) {\n    return `${path}/`\n  } else {\n    return path\n  }\n}\n\nconst getPublicUrl = appPackageJson =>\n  envPublicUrl || require(appPackageJson).homepage\n\n// We use `PUBLIC_URL` environment variable or \"homepage\" field to infer\n// \"public path\" at which the app is served.\n// Webpack needs to know it to put the right <script> hrefs into HTML even in\n// single-page apps that may serve index.html for nested URLs like /todos/42.\n// We can't use a relative path in HTML because we don't want to load something\n// like /todos/42/static/js/bundle.7289d.js. We have to know the root.\nfunction getServedPath(appPackageJson) {\n  const publicUrl = getPublicUrl(appPackageJson)\n  const servedUrl =\n    envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/')\n  return ensureSlash(servedUrl, true)\n}\n\n// config after eject: we're in ./config/\nmodule.exports = {\n  dotenv: resolveApp('.env'),\n  appBuild: resolveApp('build'),\n  appPublic: resolveApp('public'),\n  appHtml: resolveApp('public/index.html'),\n  appIndexJs: resolveApp('src/index.tsx'),\n  middlewareIndexJs: resolveApp('src/middlewareIndex.tsx'),\n  localDevIndexJs: resolveApp('src/localDevIndex.tsx'),\n  appPackageJson: resolveApp('package.json'),\n  appSrc: resolveApp('src'),\n  yarnLockFile: resolveApp('yarn.lock'),\n  testsSetup: resolveApp('src/setupTests.ts'),\n  appNodeModules: resolveApp('node_modules'),\n  appTsConfig: resolveApp('tsconfig.json'),\n  publicUrl: getPublicUrl(resolveApp('package.json')),\n  servedPath: getServedPath(resolveApp('package.json')),\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/config/polyfills.js",
    "content": "if (typeof Promise === 'undefined') {\n  // Rejection tracking prevents a common issue where React gets into an\n  // inconsistent state due to an error, but it gets swallowed by a Promise,\n  // and the user has no idea what causes React's erratic future behavior.\n  require('promise/lib/rejection-tracking').enable();\n  window.Promise = require('promise/lib/es6-extensions.js');\n}\n\n// fetch() polyfill for making API calls.\nrequire('whatwg-fetch');\n\n// Object.assign() is commonly used with React.\n// It will use the native implementation if it's present and isn't buggy.\nObject.assign = require('object-assign');\n"
  },
  {
    "path": "packages/graphql-playground-react/config/webpack.config.dev.js",
    "content": "'use strict'\n\nconst path = require('path')\nconst webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')\nconst InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin')\nconst WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin')\nconst ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin')\nconst getClientEnvironment = require('./env')\nconst paths = require('./paths')\n\n// Webpack uses `publicPath` to determine where the app is being served from.\n// In development, we always serve from the root. This makes config easier.\nconst publicPath = '/'\n// `publicUrl` is just like `publicPath`, but we will provide it to our app\n// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.\n// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.\nconst publicUrl = ''\n// Get environment variables to inject into our app.\nconst env = getClientEnvironment(publicUrl)\n\n// This is the development configuration.\n// It is focused on developer experience and fast rebuilds.\n// The production configuration is different and lives in a separate file.\nmodule.exports = {\n  mode: 'development',\n  // You may want 'eval' instead if you prefer to see the compiled output in DevTools.\n  // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.\n  devtool: 'cheap-module-source-map',\n  // These are the \"entry points\" to our application.\n  // This means they will be the \"root\" imports that are included in JS bundle.\n  // The first two entry points enable \"hot\" CSS and auto-refreshes for JS.\n  entry: {\n    index: [\n      require.resolve('./polyfills'),\n      require.resolve('react-dev-utils/webpackHotDevClient'),\n      paths.appIndexJs\n    ],\n    // middleware: [\n    //   require.resolve('./polyfills'),\n    //   require.resolve('react-dev-utils/webpackHotDevClient'),\n    //   paths.middlewareIndexJs,\n    // ],\n    localDev: [\n      require.resolve('./polyfills'),\n      require.resolve('react-dev-utils/webpackHotDevClient'),\n      paths.localDevIndexJs\n    ]\n  },\n  output: {\n    // Next line is not used in dev but WebpackDevServer crashes without it:\n    path: paths.appBuild,\n    // Add /* filename */ comments to generated require()s in the output.\n    pathinfo: true,\n    // This does not produce a real file. It's just the virtual path that is\n    // served by WebpackDevServer in development. This is the JS bundle\n    // containing code from all our entry points, and the Webpack runtime.\n    filename: 'static/js/[name].bundle.js',\n    // There are also additional JS chunk files if you use code splitting.\n    chunkFilename: 'static/js/[name].chunk.js',\n    // This is the URL that app is served from. We use \"/\" in development.\n    publicPath: publicPath,\n    // Point sourcemap entries to original disk location (format as URL on Windows)\n    devtoolModuleFilenameTemplate: info =>\n      path.resolve(info.absoluteResourcePath).replace(/\\\\/g, '/')\n  },\n  resolve: {\n    // This allows you to set a fallback for where Webpack should look for modules.\n    // We placed these paths second because we want `node_modules` to \"win\"\n    // if there are any conflicts. This matches Node resolution mechanism.\n    // https://github.com/facebookincubator/create-react-app/issues/253\n    modules: ['node_modules', paths.appNodeModules].concat(\n      // It is guaranteed to exist because we tweak it in `env.js`\n      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)\n    ),\n    // These are the reasonable defaults supported by the Node ecosystem.\n    // We also include JSX as a common component filename extension to support\n    // some tools, although we do not recommend using it, see:\n    // https://github.com/facebookincubator/create-react-app/issues/290\n    // `web` extension prefixes have been added for better support\n    // for React Native Web.\n    extensions: [\n      '.mjs',\n      '.web.ts',\n      '.ts',\n      '.web.tsx',\n      '.tsx',\n      '.web.js',\n      '.js',\n      '.json',\n      '.web.jsx',\n      '.jsx'\n    ],\n    alias: {\n      // Support React Native Web\n      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/\n      'react-native': 'react-native-web'\n    },\n    plugins: [\n      // Prevents users from importing files from outside of src/ (or node_modules/).\n      // This often causes confusion because we only process files within src/ with babel.\n      // To fix this, we prevent you from importing files out of src/ -- if you'd like to,\n      // please link the files into your node_modules/ and let module-resolution kick in.\n      // Make sure your source files are compiled, as they will not be processed in any way.\n      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson])\n    ]\n  },\n  module: {\n    strictExportPresence: true,\n    rules: [\n      // TODO: Disable require.ensure as it's not a standard language feature.\n      // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.\n      // { parser: { requireEnsure: false } },\n\n      // First, run the linter.\n      // It's important to do this before Babel processes the JS.\n      {\n        test: /\\.(ts|tsx)$/,\n        loader: require.resolve('tslint-loader'),\n        enforce: 'pre',\n        include: paths.appSrc\n      },\n      {\n        test: /\\.js$/,\n        loader: require.resolve('source-map-loader'),\n        enforce: 'pre',\n        include: paths.appSrc\n      },\n      {\n        // \"oneOf\" will traverse all following loaders until one will\n        // match the requirements. When no loader matches it will fall\n        // back to the \"file\" loader at the end of the loader list.\n        oneOf: [\n          // \"url\" loader works like \"file\" loader except that it embeds assets\n          // smaller than specified limit in bytes as data URLs to avoid requests.\n          // A missing `test` is equivalent to a match.\n          {\n            test: [/\\.bmp$/, /\\.gif$/, /\\.jpe?g$/, /\\.png$/],\n            loader: require.resolve('url-loader'),\n            options: {\n              limit: 10000,\n              name: 'static/media/[name].[hash:8].[ext]'\n            }\n          },\n          // Compile .tsx?\n          {\n            test: /\\.(ts|tsx)$/,\n            include: paths.appSrc,\n            use: [\n              {\n                loader: require.resolve('babel-loader')\n              },\n              {\n                loader: require.resolve('ts-loader')\n              }\n            ]\n          },\n          {\n            test: /\\.mjs$/,\n            include: /node_modules/,\n            type: \"javascript/auto\"\n          },\n          // \"css\" loader resolves paths in CSS and adds assets as dependencies.\n          // \"style\" loader turns CSS into JS modules that inject <style> tags.\n          // In production, we use a plugin to extract that CSS to a file, but\n          // in development \"style\" loader enables hot editing of CSS.\n          {\n            test: /\\.css$/,\n            use: [\n              require.resolve('style-loader'),\n              {\n                loader: require.resolve('css-loader'),\n                options: {\n                  importLoaders: 1\n                }\n              }\n            ]\n          },\n          // \"file\" loader makes sure those assets get served by WebpackDevServer.\n          // When you `import` an asset, you get its (virtual) filename.\n          // In production, they would get copied to the `build` folder.\n          // This loader don't uses a \"test\" so it will catch all modules\n          // that fall through the other loaders.\n          {\n            // Exclude `js` files to keep \"css\" loader working as it injects\n            // it's runtime that would otherwise processed through \"file\" loader.\n            // Also exclude `html` and `json` extensions so they get processed\n            // by webpacks internal loaders.\n            exclude: [/\\.js$/, /\\.html$/, /\\.json$/],\n            loader: require.resolve('file-loader'),\n            options: {\n              name: 'static/media/[name].[hash:8].[ext]'\n            }\n          }\n        ]\n      }\n      // ** STOP ** Are you adding a new loader?\n      // Make sure to add the new loader(s) before the \"file\" loader.\n    ]\n  },\n  plugins: [\n    // Makes some environment variables available in index.html.\n    // The public URL is available as %PUBLIC_URL% in index.html, e.g.:\n    // <link rel=\"shortcut icon\" href=\"%PUBLIC_URL%/favicon.ico\">\n    // In development, this will be an empty string.\n    new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),\n    // Generates an `index.html` file with the <script> injected.\n    new HtmlWebpackPlugin({\n      inject: true,\n      chunks: ['index'],\n      template: paths.appHtml\n    }),\n    // new HtmlWebpackPlugin({\n    //   inject: true,\n    //   chunks: ['middleware'],\n    //   template: paths.appHtml,\n    //   filename: 'middleware.html',\n    // }),\n    new HtmlWebpackPlugin({\n      inject: true,\n      chunks: ['localDev'],\n      template: paths.appHtml,\n      filename: 'localDev.html'\n    }),\n    // Add module names to factory functions so they appear in browser profiler.\n    new webpack.NamedModulesPlugin(),\n    // Makes some environment variables available to the JS code, for example:\n    // if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.\n    new webpack.DefinePlugin(env.stringified),\n    // This is necessary to emit hot updates (currently CSS only):\n    new webpack.HotModuleReplacementPlugin(),\n    // Watcher doesn't work well if you mistype casing in a path so we use\n    // a plugin that prints an error when you attempt to do this.\n    // See https://github.com/facebookincubator/create-react-app/issues/240\n    new CaseSensitivePathsPlugin(),\n    // If you require a missing module and then `npm install` it, you still have\n    // to restart the development server for Webpack to discover it. This plugin\n    // makes the discovery automatic so you don't have to restart.\n    // See https://github.com/facebookincubator/create-react-app/issues/186\n    new WatchMissingNodeModulesPlugin(paths.appNodeModules),\n    // Moment.js is an extremely popular library that bundles large locale files\n    // by default due to how Webpack interprets its code. This is a practical\n    // solution that requires the user to opt into importing specific locales.\n    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack\n    // You can remove this if you don't use Moment.js:\n    new webpack.IgnorePlugin(/^\\.\\/locale$/, /moment$/)\n  ],\n  // Some libraries import Node modules but don't use them in the browser.\n  // Tell Webpack to provide empty mocks for them so importing them works.\n  node: {\n    dgram: 'empty',\n    fs: 'empty',\n    net: 'empty',\n    tls: 'empty',\n    child_process: 'empty'\n  },\n  // Turn off performance hints during development because we don't do any\n  // splitting or minification in interest of speed. These warnings become\n  // cumbersome.\n  performance: {\n    hints: false\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/config/webpack.config.prod.js",
    "content": "'use strict'\n\nconst path = require('path')\nconst webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst ExtractTextPlugin = require('extract-text-webpack-plugin')\nconst ManifestPlugin = require('webpack-manifest-plugin')\nconst InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin')\nconst ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin')\nconst paths = require('./paths')\nconst getClientEnvironment = require('./env')\n\n// Webpack uses `publicPath` to determine where the app is being served from.\n// It requires a trailing slash, or the file assets will get an incorrect path.\nconst publicPath = paths.servedPath\n// Some apps do not use client-side routing with pushState.\n// For these, \"homepage\" can be set to \".\" to enable relative asset paths.\nconst shouldUseRelativeAssetPaths = publicPath === './'\n// Source maps are resource heavy and can cause out of memory issue for large source files.\nconst shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'\n// `publicUrl` is just like `publicPath`, but we will provide it to our app\n// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.\n// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.\nconst publicUrl = publicPath.slice(0, -1)\n// Get environment variables to inject into our app.\nconst env = getClientEnvironment(publicUrl)\n\n// Assert this just to be safe.\n// Development builds of React are slow and not intended for production.\nif (env.stringified['process.env'].NODE_ENV !== '\"production\"') {\n  throw new Error('Production builds must have NODE_ENV=production.')\n}\n\n// Note: defined here because it will be used more than once.\nconst cssFilename = 'static/css/[name].css'\n\n// ExtractTextPlugin expects the build output to be flat.\n// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)\n// However, our output is structured with css, js and media folders.\n// To have this structure working with relative paths, we have to use custom options.\nconst extractTextPluginOptions = shouldUseRelativeAssetPaths\n  ? // Making sure that the publicPath goes back to to build folder.\n    { publicPath: Array(cssFilename.split('/').length).join('../') }\n  : {}\n\n// This is the production configuration.\n// It compiles slowly and is focused on producing a fast and minimal bundle.\n// The development configuration is different and lives in a separate file.\nmodule.exports = {\n  mode: 'production',\n  // Don't attempt to continue if there are any errors.\n  bail: true,\n  // We generate sourcemaps in production. This is slow but gives good results.\n  // You can exclude the *.map files from the build during deployment.\n  devtool: shouldUseSourceMap ? 'source-map' : false,\n  // In production, we only want to load the polyfills and the app code.\n  entry: {\n    index: [require.resolve('./polyfills'), paths.appIndexJs],\n    middleware: [require.resolve('./polyfills'), paths.middlewareIndexJs]\n  },\n  output: {\n    // The build folder.\n    path: paths.appBuild,\n    // Generated JS file names (with nested folders).\n    // There will be one main bundle, and one file per asynchronous chunk.\n    // We don't currently advertise code splitting but Webpack supports it.\n    filename: 'static/js/[name].js',\n    chunkFilename: 'static/js/[name].chunk.js',\n    // We inferred the \"public path\" (such as / or /my-project) from homepage.\n    publicPath: publicPath,\n    // Point sourcemap entries to original disk location (format as URL on Windows)\n    devtoolModuleFilenameTemplate: info =>\n      path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\\\/g, '/')\n  },\n  resolve: {\n    // This allows you to set a fallback for where Webpack should look for modules.\n    // We placed these paths second because we want `node_modules` to \"win\"\n    // if there are any conflicts. This matches Node resolution mechanism.\n    // https://github.com/facebookincubator/create-react-app/issues/253\n    modules: ['node_modules', paths.appNodeModules].concat(\n      // It is guaranteed to exist because we tweak it in `env.js`\n      process.env.NODE_PATH.split(path.delimiter).filter(Boolean)\n    ),\n    // These are the reasonable defaults supported by the Node ecosystem.\n    // We also include JSX as a common component filename extension to support\n    // some tools, although we do not recommend using it, see:\n    // https://github.com/facebookincubator/create-react-app/issues/290\n    // `web` extension prefixes have been added for better support\n    // for React Native Web.\n    extensions: [\n      '.web.ts',\n      '.ts',\n      '.web.tsx',\n      '.tsx',\n      '.mjs',\n      '.web.js',\n      '.js',\n      '.json',\n      '.web.jsx',\n      '.jsx'\n    ],\n    alias: {\n      // Support React Native Web\n      // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/\n      'react-native': 'react-native-web'\n    },\n    plugins: [\n      // Prevents users from importing files from outside of src/ (or node_modules/).\n      // This often causes confusion because we only process files within src/ with babel.\n      // To fix this, we prevent you from importing files out of src/ -- if you'd like to,\n      // please link the files into your node_modules/ and let module-resolution kick in.\n      // Make sure your source files are compiled, as they will not be processed in any way.\n      new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson])\n    ]\n  },\n  module: {\n    strictExportPresence: true,\n    rules: [\n      // TODO: Disable require.ensure as it's not a standard language feature.\n      // We are waiting for https://github.com/facebookincubator/create-react-app/issues/2176.\n      // { parser: { requireEnsure: false } },\n\n      // First, run the linter.\n      // It's important to do this before Typescript runs.\n      {\n        test: /\\.(ts|tsx)$/,\n        loader: require.resolve('tslint-loader'),\n        enforce: 'pre',\n        include: paths.appSrc\n      },\n      {\n        test: /\\.js$/,\n        loader: require.resolve('source-map-loader'),\n        enforce: 'pre',\n        include: paths.appSrc\n      },\n      {\n        // \"oneOf\" will traverse all following loaders until one will\n        // match the requirements. When no loader matches it will fall\n        // back to the \"file\" loader at the end of the loader list.\n        oneOf: [\n          // \"url\" loader works just like \"file\" loader but it also embeds\n          // assets smaller than specified size as data URLs to avoid requests.\n          {\n            test: [/\\.bmp$/, /\\.gif$/, /\\.jpe?g$/, /\\.png$/],\n            loader: require.resolve('url-loader'),\n            options: {\n              limit: 10000,\n              name: 'static/media/[name].[hash:8].[ext]'\n            }\n          },\n          //Compile .tsx?\n          {\n            test: /\\.(ts|tsx)$/,\n            include: paths.appSrc,\n            use: [\n              {\n                loader: require.resolve('babel-loader')\n              },\n              {\n                loader: require.resolve('ts-loader')\n              }\n            ]\n          },\n          {\n            test: /\\.mjs$/,\n            include: /node_modules/,\n            type: \"javascript/auto\"\n          },\n          // The notation here is somewhat confusing.\n          // \"postcss\" loader applies autoprefixer to our CSS.\n          // \"css\" loader resolves paths in CSS and adds assets as dependencies.\n          // \"style\" loader normally turns CSS into JS modules injecting <style>,\n          // but unlike in development configuration, we do something different.\n          // `ExtractTextPlugin` first applies the \"postcss\" and \"css\" loaders\n          // (second argument), then grabs the result CSS and puts it into a\n          // separate file in our build process. This way we actually ship\n          // a single CSS file in production instead of JS code injecting <style>\n          // tags. If you use code splitting, however, any async bundles will still\n          // use the \"style\" loader inside the async code so CSS from them won't be\n          // in the main CSS file.\n          {\n            test: /\\.css$/,\n            loader: ExtractTextPlugin.extract(\n              Object.assign(\n                {\n                  fallback: require.resolve('style-loader'),\n                  use: [\n                    {\n                      loader: require.resolve('css-loader'),\n                      options: {\n                        importLoaders: 1,\n                        sourceMap: shouldUseSourceMap\n                      }\n                    }\n                  ]\n                },\n                extractTextPluginOptions\n              )\n            )\n            // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.\n          },\n          {\n            test: /\\.svg$/,\n            loader: require.resolve('svg-inline-loader')\n          },\n          // \"file\" loader makes sure assets end up in the `build` folder.\n          // When you `import` an asset, you get its filename.\n          // This loader don't uses a \"test\" so it will catch all modules\n          // that fall through the other loaders.\n          {\n            loader: require.resolve('file-loader'),\n            // Exclude `js` files to keep \"css\" loader working as it injects\n            // it's runtime that would otherwise processed through \"file\" loader.\n            // Also exclude `html` and `json` extensions so they get processed\n            // by webpacks internal loaders.\n            exclude: [/\\.js$/, /\\.html$/, /\\.json$/],\n            options: {\n              name: 'static/media/[name].[hash:8].[ext]'\n            }\n          }\n          // ** STOP ** Are you adding a new loader?\n          // Make sure to add the new loader(s) before the \"file\" loader.\n        ]\n      }\n    ]\n  },\n  plugins: [\n    // Makes some environment variables available in index.html.\n    // The public URL is available as %PUBLIC_URL% in index.html, e.g.:\n    // <link rel=\"shortcut icon\" href=\"%PUBLIC_URL%/favicon.ico\">\n    // In production, it will be an empty string unless you specify \"homepage\"\n    // in `package.json`, in which case it will be the pathname of that URL.\n    new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),\n    // Generates an `index.html` file with the <script> injected.\n    new HtmlWebpackPlugin({\n      inject: true,\n      chunks: ['index'],\n      template: paths.appHtml,\n      minify: {\n        removeComments: true,\n        collapseWhitespace: true,\n        removeRedundantAttributes: true,\n        useShortDoctype: true,\n        removeEmptyAttributes: true,\n        removeStyleLinkTypeAttributes: true,\n        keepClosingSlash: true,\n        minifyJS: true,\n        minifyCSS: true,\n        minifyURLs: true\n      }\n    }),\n    new HtmlWebpackPlugin({\n      inject: true,\n      chunks: ['middleware'],\n      template: paths.appHtml,\n      minify: {\n        removeComments: true,\n        collapseWhitespace: true,\n        removeRedundantAttributes: true,\n        useShortDoctype: true,\n        removeEmptyAttributes: true,\n        removeStyleLinkTypeAttributes: true,\n        keepClosingSlash: true,\n        minifyJS: true,\n        minifyCSS: true,\n        minifyURLs: true\n      },\n      filename: 'middleware.html'\n    }),\n    // Makes some environment variables available to the JS code, for example:\n    // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.\n    // It is absolutely essential that NODE_ENV was set to production here.\n    // Otherwise React will be compiled in the very slow development mode.\n    new webpack.DefinePlugin(env.stringified),\n    // Minify the code.\n    // Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.\n    new ExtractTextPlugin({\n      filename: cssFilename\n    }),\n    // Generate a manifest file which contains a mapping of all asset filenames\n    // to their corresponding output file so that tools can pick it up without\n    // having to parse `index.html`.\n    new ManifestPlugin({\n      fileName: 'asset-manifest.json'\n    }),\n    // Moment.js is an extremely popular library that bundles large locale files\n    // by default due to how Webpack interprets its code. This is a practical\n    // solution that requires the user to opt into importing specific locales.\n    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack\n    // You can remove this if you don't use Moment.js:\n    new webpack.IgnorePlugin(/^\\.\\/locale$/, /moment$/)\n  ],\n  // Some libraries import Node modules but don't use them in the browser.\n  // Tell Webpack to provide empty mocks for them so importing them works.\n  node: {\n    dgram: 'empty',\n    fs: 'empty',\n    net: 'empty',\n    tls: 'empty',\n    child_process: 'empty'\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/config/webpackDevServer.config.js",
    "content": "'use strict';\n\nconst errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');\nconst noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');\nconst config = require('./webpack.config.dev');\nconst paths = require('./paths');\n\nconst protocol = process.env.HTTPS === 'true' ? 'https' : 'http';\nconst host = process.env.HOST || '0.0.0.0';\n\nmodule.exports = function(proxy, allowedHost) {\n  return {\n    // WebpackDevServer 2.4.3 introduced a security fix that prevents remote\n    // websites from potentially accessing local content through DNS rebinding:\n    // https://github.com/webpack/webpack-dev-server/issues/887\n    // https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a\n    // However, it made several existing use cases such as development in cloud\n    // environment or subdomains in development significantly more complicated:\n    // https://github.com/facebookincubator/create-react-app/issues/2271\n    // https://github.com/facebookincubator/create-react-app/issues/2233\n    // While we're investigating better solutions, for now we will take a\n    // compromise. Since our WDS configuration only serves files in the `public`\n    // folder we won't consider accessing them a vulnerability. However, if you\n    // use the `proxy` feature, it gets more dangerous because it can expose\n    // remote code execution vulnerabilities in backends like Django and Rails.\n    // So we will disable the host check normally, but enable it if you have\n    // specified the `proxy` setting. Finally, we let you override it if you\n    // really know what you're doing with a special environment variable.\n    disableHostCheck:\n    !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',\n    // Enable gzip compression of generated files.\n    compress: true,\n    // Silence WebpackDevServer's own logs since they're generally not useful.\n    // It will still show compile warnings and errors with this setting.\n    clientLogLevel: 'none',\n    // By default WebpackDevServer serves physical files from current directory\n    // in addition to all the virtual build products that it serves from memory.\n    // This is confusing because those files won’t automatically be available in\n    // production build folder unless we copy them. However, copying the whole\n    // project directory is dangerous because we may expose sensitive files.\n    // Instead, we establish a convention that only files in `public` directory\n    // get served. Our build script will copy `public` into the `build` folder.\n    // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:\n    // <link rel=\"shortcut icon\" href=\"%PUBLIC_URL%/favicon.ico\">\n    // In JavaScript code, you can access it with `process.env.PUBLIC_URL`.\n    // Note that we only recommend to use `public` folder as an escape hatch\n    // for files like `favicon.ico`, `manifest.json`, and libraries that are\n    // for some reason broken when imported through Webpack. If you just want to\n    // use an image, put it in `src` and `import` it from JavaScript instead.\n    contentBase: paths.appPublic,\n    // By default files from `contentBase` will not trigger a page reload.\n    watchContentBase: true,\n    // Enable hot reloading server. It will provide /sockjs-node/ endpoint\n    // for the WebpackDevServer client so it can learn when the files were\n    // updated. The WebpackDevServer client is included as an entry point\n    // in the Webpack development configuration. Note that only changes\n    // to CSS are currently hot reloaded. JS changes will refresh the browser.\n    hot: true,\n    // It is important to tell WebpackDevServer to use the same \"root\" path\n    // as we specified in the config. In development, we always serve from /.\n    publicPath: config.output.publicPath,\n    // WebpackDevServer is noisy by default so we emit custom message instead\n    // by listening to the compiler events with `compiler.plugin` calls above.\n    quiet: true,\n    // Reportedly, this avoids CPU overload on some systems.\n    // https://github.com/facebookincubator/create-react-app/issues/293\n    watchOptions: {\n      ignored: /node_modules/,\n    },\n    // Enable HTTPS if the HTTPS environment variable is set to 'true'\n    https: protocol === 'https',\n    host: host,\n    overlay: false,\n    historyApiFallback: {\n      // Paths with dots should still use the history fallback.\n      // See https://github.com/facebookincubator/create-react-app/issues/387.\n      disableDotRule: true,\n      rewrites: [\n        { from: /^\\/middleware.html/, to: '/build/middleware.html' },\n      ]\n    },\n    public: allowedHost,\n    proxy,\n    setup(app) {\n      // This lets us open files from the runtime error overlay.\n      app.use(errorOverlayMiddleware());\n      // This service worker file is effectively a 'no-op' that will reset any\n      // previous service worker registered for the same host:port combination.\n      // We do this in development to avoid hitting the production cache if\n      // it used the same host and port.\n      // https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432\n      app.use(noopServiceWorkerMiddleware());\n    },\n  };\n};\n"
  },
  {
    "path": "packages/graphql-playground-react/jest.config.js",
    "content": "module.exports = {\n  roots: ['<rootDir>/src'],\n  transform: {\n    '^.+\\\\.css$': '<rootDir>/config/jest/cssTransform.js',\n    '^.+\\\\.tsx?$': '<rootDir>/config/jest/typescriptTransform.js',\n    '^(?!.*\\\\.(css|json)$)': '<rootDir>/config/jest/fileTransform.js',\n  },\n  transformIgnorePatterns: ['[/\\\\\\\\]node_modules[/\\\\\\\\].+\\\\.(js|jsx)$'],\n  testRegex: '(/__tests__/.*|(\\\\.|/)(test|spec))\\\\.tsx?$',\n  testPathIgnorePatterns: ['<rootDir>[/\\\\\\\\](build|docs|node_modules)[/\\\\\\\\]'],\n  testEnvironment: 'jsdom',\n  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],\n  snapshotSerializers: ['enzyme-to-json/serializer'],\n  setupTestFrameworkScriptFile: '<rootDir>/src/setupEnzyme.ts',\n  globals: {\n    'ts-jest': {\n      tsConfigFile: 'tsconfig.jest.json',\n    },\n  },\n  testURL: 'https://localhost',\n  setupFiles: ['<rootDir>/config/polyfills.js', 'jest-localstorage-mock'],\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/package.json",
    "content": "{\n  \"name\": \"graphql-playground-react\",\n  \"version\": \"1.7.27\",\n  \"main\": \"./lib/lib.js\",\n  \"typings\": \"./lib/lib.d.ts\",\n  \"description\": \"GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).\",\n  \"contributors\": [\n    \"Tim Suchanek <tim@graph.cool>\",\n    \"Johannes Schickling <johannes@graph.cool>\",\n    \"Lukas Huvar <lukas@huvar.cz>\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"http://github.com/graphcool/graphql-playground.git\"\n  },\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"node scripts/start.js\",\n    \"start:analyze\": \"ANALYZE_BUNDLE=true node scripts/start.js\",\n    \"start:graphql-bin\": \"ACTIVE_APP=graphqlbin node scripts/start.js\",\n    \"prepublishOnly\": \"yarn build\",\n    \"build\": \"rimraf dist build dist && yarn build-app && yarn build-package\",\n    \"tsc\": \"tsc -p tsconfig.build.json\",\n    \"build-package\": \"rimraf lib build/dist && npm run tsc && babel lib -d lib && cp -r ./src/assets/ ./lib/assets/ && cd lib && rimraf *.jsx;\",\n    \"build-app\": \"node scripts/build.js\",\n    \"test\": \"jest\",\n    \"bundlesize\": \"bundlesize\",\n    \"bump\": \"npm version patch --no-git-tag-version && git add package.json\",\n    \"graphql-faker\": \"graphql-faker ./tests/schema.faker.graphql\",\n    \"lint\": \"tslint \\\"src/**/*.ts{,x}\\\"\",\n    \"precommit\": \"lint-staged\",\n    \"prettier\": \"prettier --single-quote --no-semi --trailing-comma all --write *.{ts,tsx} 'src/**/*.{ts,tsx}'\"\n  },\n  \"files\": [\n    \"build\",\n    \"lib\",\n    \"playground.css\"\n  ],\n  \"bundlesize\": [\n    {\n      \"path\": \"build/static/js/index.js\",\n      \"maxSize\": \"674 kB\"\n    }\n  ],\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.0.0\",\n    \"@babel/core\": \"^7.0.0\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.0.0\",\n    \"@babel/plugin-proposal-json-strings\": \"^7.0.0\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.0.0\",\n    \"@babel/plugin-syntax-import-meta\": \"^7.0.0\",\n    \"@babel/preset-env\": \"^7.0.0\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"@types/deasync\": \"0.1.0\",\n    \"@types/escape-html\": \"^1.0.1\",\n    \"@types/jest\": \"22.2.3\",\n    \"@types/markdown-it\": \"^12.2.3\",\n    \"@types/node\": \"12.12.34\",\n    \"@types/react\": \"16.9.32\",\n    \"@types/zen-observable\": \"^0.5.3\",\n    \"babel-core\": \"^7.0.0-bridge.0\",\n    \"babel-jest\": \"^23.4.2\",\n    \"babel-loader\": \"^8.0.0\",\n    \"babel-plugin-styled-components\": \"^1.8.0\",\n    \"bundlesize\": \"^0.17.0\",\n    \"case-sensitive-paths-webpack-plugin\": \"2.3.0\",\n    \"chalk\": \"2.4.1\",\n    \"connect-history-api-fallback\": \"1.5.0\",\n    \"cross-spawn\": \"6.0.5\",\n    \"css-loader\": \"3.4.2\",\n    \"detect-port\": \"1.2.3\",\n    \"dotenv\": \"5.0.1\",\n    \"enzyme\": \"^3.3.0\",\n    \"enzyme-adapter-react-16\": \"^1.1.1\",\n    \"enzyme-to-json\": \"^3.3.4\",\n    \"extract-text-webpack-plugin\": \"4.0.0-beta.0\",\n    \"file-loader\": \"6.0.0\",\n    \"filesize\": \"6.1.0\",\n    \"fs-extra\": \"5.0.0\",\n    \"graphql-playground-html\": \"1.5.6\",\n    \"gzip-size\": \"4.1.0\",\n    \"html-webpack-plugin\": \"4.0.4\",\n    \"http-proxy-middleware\": \"0.17.4\",\n    \"husky\": \"0.14.3\",\n    \"jest\": \"22.1.4\",\n    \"jest-localstorage-mock\": \"^2.2.0\",\n    \"json-loader\": \"0.5.7\",\n    \"lint-staged\": \"6.1.0\",\n    \"node-noop\": \"1.0.0\",\n    \"object-assign\": \"4.1.1\",\n    \"promise\": \"8.0.1\",\n    \"raw-loader\": \"4.0.0\",\n    \"react-dev-utils\": \"10.1.0\",\n    \"recursive-readdir\": \"2.2.2\",\n    \"rimraf\": \"3.0.2\",\n    \"source-map-loader\": \"0.2.4\",\n    \"strip-ansi\": \"4.0.0\",\n    \"style-loader\": \"1.1.3\",\n    \"svg-inline-loader\": \"0.8.2\",\n    \"sw-precache-webpack-plugin\": \"1.0.0\",\n    \"ts-loader\": \"6.2.2\",\n    \"tslint\": \"5.10.0\",\n    \"tslint-graphcool-frontend\": \"0.0.3\",\n    \"tslint-loader\": \"3.6.0\",\n    \"typescript\": \"3.8.3\",\n    \"typescript-styled-plugin\": \"^0.11.0\",\n    \"url-loader\": \"4.0.0\",\n    \"webpack\": \"4.44.1\",\n    \"webpack-dev-server\": \"3.11.0\",\n    \"webpack-manifest-plugin\": \"2.2.0\",\n    \"why-did-you-update\": \"0.1.1\"\n  },\n  \"dependencies\": {\n    \"@types/lru-cache\": \"^4.1.1\",\n    \"apollo-link\": \"^1.2.13\",\n    \"apollo-link-http\": \"^1.5.16\",\n    \"apollo-link-ws\": \"^1.0.19\",\n    \"calculate-size\": \"^1.1.1\",\n    \"codemirror\": \"^5.58.1\",\n    \"codemirror-graphql\": \"^0.12.3\",\n    \"copy-to-clipboard\": \"^3.0.8\",\n    \"cryptiles\": \"4.1.2\",\n    \"cuid\": \"^1.3.8\",\n    \"escape-html\": \"^1.0.3\",\n    \"graphiql\": \"^0.17.5\",\n    \"graphql\": \"^15.3.0\",\n    \"graphql-ws\": \"^4.5.0\",\n    \"immutable\": \"^4.0.0-rc.9\",\n    \"isomorphic-fetch\": \"^2.2.1\",\n    \"js-yaml\": \"^3.10.0\",\n    \"json-stable-stringify\": \"^1.0.1\",\n    \"keycode\": \"^2.1.9\",\n    \"lodash\": \"^4.17.11\",\n    \"lodash.debounce\": \"^4.0.8\",\n    \"lru-cache\": \"^6.0.0\",\n    \"markdown-it\": \"^12.2.0\",\n    \"prettier\": \"2.0.2\",\n    \"prop-types\": \"^15.7.2\",\n    \"query-string\": \"5\",\n    \"react\": \"16.13.1\",\n    \"react-addons-shallow-compare\": \"^15.6.2\",\n    \"react-codemirror\": \"^1.0.0\",\n    \"react-copy-to-clipboard\": \"^5.0.1\",\n    \"react-display-name\": \"^0.2.3\",\n    \"react-dom\": \"^16.13.1\",\n    \"react-helmet\": \"^5.2.0\",\n    \"react-input-autosize\": \"^2.2.1\",\n    \"react-modal\": \"^3.1.11\",\n    \"react-redux\": \"^7.2.1\",\n    \"react-router-dom\": \"^4.2.2\",\n    \"react-sortable-hoc\": \"^0.8.3\",\n    \"react-transition-group\": \"^2.2.1\",\n    \"react-virtualized\": \"^9.12.0\",\n    \"redux\": \"^4.0.5\",\n    \"redux-actions\": \"^2.6.5\",\n    \"redux-immutable\": \"^4.0.0\",\n    \"redux-localstorage\": \"^1.0.0-rc5\",\n    \"redux-localstorage-debounce\": \"^0.1.0\",\n    \"redux-localstorage-filter\": \"^0.1.1\",\n    \"redux-saga\": \"^1.1.3\",\n    \"reselect\": \"^4.0.0\",\n    \"seamless-immutable\": \"^7.0.1\",\n    \"styled-components\": \"^4.0.0\",\n    \"subscriptions-transport-ws\": \"^0.9.5\",\n    \"utility-types\": \"^1.0.0\",\n    \"webpack-bundle-analyzer\": \"^3.3.2\",\n    \"zen-observable\": \"^0.7.1\"\n  },\n  \"lint-staged\": {\n    \"*.{ts,tsx}\": [\n      \"prettier --single-quote --no-semi --write\",\n      \"tslint\",\n      \"git add\"\n    ],\n    \"gitDir\": \"../../\"\n  },\n  \"jest\": {\n    \"collectCoverageFrom\": [\n      \"src/**/*.{ts,tsx}\"\n    ],\n    \"setupFiles\": [\n      \"<rootDir>/config/polyfills.js\"\n    ],\n    \"testPathIgnorePatterns\": [\n      \"<rootDir>[/\\\\\\\\](build|docs|node_modules)[/\\\\\\\\]\"\n    ],\n    \"testEnvironment\": \"node\",\n    \"testURL\": \"http://localhost\",\n    \"transform\": {\n      \"^.+\\\\.css$\": \"<rootDir>/config/jest/cssTransform.js\",\n      \"^.+\\\\.tsx?$\": \"<rootDir>/config/jest/typescriptTransform.js\",\n      \"^(?!.*\\\\.(css|json)$)\": \"<rootDir>/config/jest/fileTransform.js\"\n    },\n    \"transformIgnorePatterns\": [\n      \"[/\\\\\\\\]node_modules[/\\\\\\\\].+\\\\.(js|jsx)$\"\n    ],\n    \"moduleNameMapper\": {\n      \"^react-native$\": \"react-native-web\"\n    },\n    \"moduleFileExtensions\": [\n      \"ts\",\n      \"tsx\",\n      \"js\"\n    ],\n    \"testRegex\": \"(/__tests__/.*|\\\\.(test|spec))\\\\.(ts|tsx|js)$\"\n  },\n  \"gitHead\": \"53d233f9deb9dcc86f99e41268ff92b6367e0713\"\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/_headers",
    "content": "/*.graphql\n  Content-Type: text/plain\n  Access-Control-Allow-Origin: *\n"
  },
  {
    "path": "packages/graphql-playground-react/public/_redirects",
    "content": "# general fallback\n/*        /index.html   200\n"
  },
  {
    "path": "packages/graphql-playground-react/public/affiliates.graphql",
    "content": "type Affiliate @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  company: String!\n  author: User! @relation(name: \"AffiliateOnUser\")\n}\n\ntype User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  affiliates: [Affiliate!]! @relation(name: \"AffiliateOnUser\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/auth.graphql",
    "content": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/blogging.graphql",
    "content": "enum UserRole { Standard, Admin }\n\ntype User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  role: UserRole!\n  posts: [Post!]! @relation(name: \"PostAuthor\")\n  collaborationPosts: [Post!]! @relation(name: \"PostCollaborators\")\n  friends: [User!]! @relation(name: \"Friends\")\n}\n\ntype Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  isPublished: Boolean!\n  text: String!\n  author: User! @relation(name: \"PostAuthor\")\n  collaborators: [User!]! @relation(name: \"PostCollaborators\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/chat.graphql",
    "content": "type Person @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String! @isUnique\n  messages: [Message!]! @relation(name: \"UserMessages\")\n}\n\ntype Message @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  text: String! @isUnique\n  sentBy: Person @relation(name: \"UserMessages\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/conferences.graphql",
    "content": "type Conference @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  city: String!\n  year: String!\n  attendees: [Attendee] @relation(name: \"Attendees\")\n}\n\ntype Attendee @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  conferences: [Conference] @relation(name: \"Attendees\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/empty.graphql",
    "content": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n}\n\n# type Tweet {\n#   text: String!\n# }\n"
  },
  {
    "path": "packages/graphql-playground-react/public/freecom.graphql",
    "content": "type File @model {\n  contentType: String!\n  createdAt: DateTime!\n  id: ID! @isUnique\n  name: String!\n  secret: String!\n  size: Int!\n  updatedAt: DateTime!\n  url: String!\n}\n\ntype User @model {\n  createdAt: DateTime!\n  id: ID! @isUnique\n  updatedAt: DateTime!\n}\n\ntype Message @model {\n  agent: Agent @relation(name: \"MessagesFromAgents\")\n  conversation: Conversation @relation(name: \"MessagesInConversation\")\n  createdAt: DateTime!\n  id: ID! @isUnique\n  text: String!\n  updatedAt: DateTime!\n}\n\ntype Conversation @model {\n  agent: Agent @relation(name: \"ConversationsFromAgent\")\n  createdAt: DateTime!\n  customer: Customer @relation(name: \"ConversationsFromCustomer\")\n  id: ID! @isUnique\n  messages: [Message!]! @relation(name: \"MessagesInConversation\")\n  slackChannelIndex: Int!\n  updatedAt: DateTime!\n}\n\ntype Agent @model {\n  conversations: [Conversation!]! @relation(name: \"ConversationsFromAgent\")\n  createdAt: DateTime!\n  id: ID! @isUnique\n  imageUrl: String!\n  messages: [Message!]! @relation(name: \"MessagesFromAgents\")\n  slackUserId: String!\n  slackUserName: String!\n  updatedAt: DateTime!\n}\n\ntype Customer @model {\n  conversations: [Conversation!]! @relation(name: \"ConversationsFromCustomer\")\n  createdAt: DateTime!\n  id: ID! @isUnique\n  name: String!\n  updatedAt: DateTime!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/hn-relay-full.graphql",
    "content": "input AUTH_PROVIDER_EMAIL {\n  email: String!\n  password: String!\n}\n\ninput AddToUsersLinksLinkInput {\n  postedByUserId: ID!\n  linksLinkId: ID!\n  clientMutationId: String!\n}\n\ntype AddToUsersLinksPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  linksLink: Link\n  postedByUser: User\n  linksLinkEdge: LinkEdge\n  postedByUserEdge: UserEdge\n}\n\ntype AddToUsersVotesPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  userUser: User\n  votesVote: Vote\n  userUserEdge: UserEdge\n  votesVoteEdge: VoteEdge\n}\n\ninput AddToUsersVotesUserInput {\n  votesVoteId: ID!\n  userUserId: ID!\n  clientMutationId: String!\n}\n\ninput AddToVotesOnLinkLinkInput {\n  votesVoteId: ID!\n  linkLinkId: ID!\n  clientMutationId: String!\n}\n\ntype AddToVotesOnLinkPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  linkLink: Link\n  votesVote: Vote\n  linkLinkEdge: LinkEdge\n  votesVoteEdge: VoteEdge\n}\n\ninput AuthProviderSignupData {\n  email: AUTH_PROVIDER_EMAIL\n}\n\n# The `BigDecimal` scalar type represents signed fractional values with arbitrary precision.\nscalar BigDecimal\n\n# The `BigInt` scalar type represents non-fractional signed whole numeric values. BigInt can represent arbitrary big values.\nscalar BigInt\n\ninput CreateFile {\n  name: String!\n}\n\ninput CreateFileInput {\n  name: String!\n  clientMutationId: String!\n}\n\ntype CreateFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n}\n\ninput CreateLink {\n  description: String!\n  url: String!\n  postedById: ID\n  votesIds: [ID!]\n  votes: [LinkvotesVote!]\n}\n\ninput CreateLinkInput {\n  description: String!\n  url: String!\n  postedById: ID\n  votesIds: [ID!]\n  votes: [LinkvotesVote!]\n  clientMutationId: String!\n}\n\ntype CreateLinkPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  link: Link\n  edge: LinkEdge\n  postedBy: User\n}\n\ninput CreateUser {\n  name: String!\n  linksIds: [ID!]\n  links: [UserlinksLink!]\n  votesIds: [ID!]\n  votes: [UservotesVote!]\n}\n\n# If authentication was successful the payload contains the user and a token. If unsuccessful this payload is null.\ntype CreateUserPayload {\n  user: User\n  clientMutationId: String\n  viewer: Viewer!\n}\n\ninput CreateVote {\n  linkId: ID\n  link: VotelinkLink\n  userId: ID\n}\n\ninput CreateVoteInput {\n  linkId: ID\n  link: VotelinkLink\n  userId: ID\n  clientMutationId: String!\n}\n\ntype CreateVotePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  vote: Vote\n  edge: VoteEdge\n  link: Link\n  user: User\n}\n\nscalar DateTime\n\ninput DeleteFileInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeleteFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n  deletedId: ID\n}\n\ninput DeleteLinkInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeleteLinkPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  link: Link\n  edge: LinkEdge\n  postedBy: User\n  deletedId: ID\n}\n\ninput DeleteUserInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeleteUserPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  user: User\n  edge: UserEdge\n  deletedId: ID\n}\n\ninput DeleteVoteInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeleteVotePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  vote: Vote\n  edge: VoteEdge\n  link: Link\n  user: User\n  deletedId: ID\n}\n\ntype File implements Node {\n  contentType: String!\n  createdAt: DateTime!\n  id: ID!\n  name: String!\n  secret: String!\n  size: Int!\n  updatedAt: DateTime!\n  url: String!\n}\n\n# A connection to a list of items.\ntype FileConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo!\n\n  # A list of edges.\n  edges: [FileEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype FileEdge {\n  # The item at the end of the edge.\n  node: File!\n\n  # A cursor for use in pagination.\n  cursor: String!\n}\n\ninput FileFilter {\n  AND: [FileFilter!]\n  OR: [FileFilter!]\n  contentType: String\n  contentType_not: String\n  contentType_in: [String!]\n  contentType_not_in: [String!]\n  contentType_lt: String\n  contentType_lte: String\n  contentType_gt: String\n  contentType_gte: String\n  contentType_contains: String\n  contentType_not_contains: String\n  contentType_starts_with: String\n  contentType_not_starts_with: String\n  contentType_ends_with: String\n  contentType_not_ends_with: String\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  name: String\n  name_not: String\n  name_in: [String!]\n  name_not_in: [String!]\n  name_lt: String\n  name_lte: String\n  name_gt: String\n  name_gte: String\n  name_contains: String\n  name_not_contains: String\n  name_starts_with: String\n  name_not_starts_with: String\n  name_ends_with: String\n  name_not_ends_with: String\n  secret: String\n  secret_not: String\n  secret_in: [String!]\n  secret_not_in: [String!]\n  secret_lt: String\n  secret_lte: String\n  secret_gt: String\n  secret_gte: String\n  secret_contains: String\n  secret_not_contains: String\n  secret_starts_with: String\n  secret_not_starts_with: String\n  secret_ends_with: String\n  secret_not_ends_with: String\n  size: Int\n  size_not: Int\n  size_in: [Int!]\n  size_not_in: [Int!]\n  size_lt: Int\n  size_lte: Int\n  size_gt: Int\n  size_gte: Int\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n  url: String\n  url_not: String\n  url_in: [String!]\n  url_not_in: [String!]\n  url_lt: String\n  url_lte: String\n  url_gt: String\n  url_gte: String\n  url_contains: String\n  url_not_contains: String\n  url_starts_with: String\n  url_not_starts_with: String\n  url_ends_with: String\n  url_not_ends_with: String\n}\n\nenum FileOrderBy {\n  contentType_ASC\n  contentType_DESC\n  createdAt_ASC\n  createdAt_DESC\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  secret_ASC\n  secret_DESC\n  size_ASC\n  size_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  url_ASC\n  url_DESC\n}\n\ntype Link implements Node {\n  createdAt: DateTime!\n  description: String!\n  id: ID!\n  postedBy(filter: UserFilter): User\n  updatedAt: DateTime!\n  url: String!\n  votes(filter: VoteFilter, orderBy: VoteOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): VoteConnection\n  _votesMeta: _QueryMeta!\n}\n\n# Meta information about the query.\ntype _QueryMeta {\n  count: Int!\n}\n\n\n\n# A connection to a list of items.\ntype LinkConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo\n\n  # A list of edges.\n  edges: [LinkEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype LinkEdge {\n  # The item at the end of the edge.\n  node: Link\n\n  # A cursor for use in pagination.\n  cursor: String\n}\n\ninput LinkFilter {\n  AND: [LinkFilter!]\n  OR: [LinkFilter!]\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  description: String\n  description_not: String\n  description_in: [String!]\n  description_not_in: [String!]\n  description_lt: String\n  description_lte: String\n  description_gt: String\n  description_gte: String\n  description_contains: String\n  description_not_contains: String\n  description_starts_with: String\n  description_not_starts_with: String\n  description_ends_with: String\n  description_not_ends_with: String\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n  url: String\n  url_not: String\n  url_in: [String!]\n  url_not_in: [String!]\n  url_lt: String\n  url_lte: String\n  url_gt: String\n  url_gte: String\n  url_contains: String\n  url_not_contains: String\n  url_starts_with: String\n  url_not_starts_with: String\n  url_ends_with: String\n  url_not_ends_with: String\n  postedBy: UserFilter\n  votes_every: VoteFilter\n  votes_some: VoteFilter\n  votes_none: VoteFilter\n}\n\nenum LinkOrderBy {\n  createdAt_ASC\n  createdAt_DESC\n  description_ASC\n  description_DESC\n  id_ASC\n  id_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  url_ASC\n  url_DESC\n}\n\ninput LinkvotesVote {\n  userId: ID\n}\n\n# The `Long` scalar type represents non-fractional signed whole numeric values.\n# Long can represent values between -(2^63) and 2^63 - 1.\nscalar Long\n\ntype Mutation {\n  createFile(input: CreateFileInput!): CreateFilePayload\n  createLink(input: CreateLinkInput!): CreateLinkPayload\n  createVote(input: CreateVoteInput!): CreateVotePayload\n  updateFile(input: UpdateFileInput!): UpdateFilePayload\n  updateLink(input: UpdateLinkInput!): UpdateLinkPayload\n  updateUser(input: UpdateUserInput!): UpdateUserPayload\n  updateVote(input: UpdateVoteInput!): UpdateVotePayload\n  updateOrCreateFile(input: UpdateOrCreateFileInput!): UpdateOrCreateFilePayload\n  updateOrCreateLink(input: UpdateOrCreateLinkInput!): UpdateOrCreateLinkPayload\n  updateOrCreateUser(input: UpdateOrCreateUserInput!): UpdateOrCreateUserPayload\n  updateOrCreateVote(input: UpdateOrCreateVoteInput!): UpdateOrCreateVotePayload\n  deleteFile(input: DeleteFileInput!): DeleteFilePayload\n  deleteLink(input: DeleteLinkInput!): DeleteLinkPayload\n  deleteUser(input: DeleteUserInput!): DeleteUserPayload\n  deleteVote(input: DeleteVoteInput!): DeleteVotePayload\n  addToUsersLinks(input: AddToUsersLinksLinkInput!): AddToUsersLinksPayload\n  addToUsersVotes(input: AddToUsersVotesUserInput!): AddToUsersVotesPayload\n  addToVotesOnLink(input: AddToVotesOnLinkLinkInput!): AddToVotesOnLinkPayload\n  removeFromUsersLinks(input: RemoveFromUsersLinksLinkInput!): RemoveFromUsersLinksPayload\n  createUser(input: SignupUserInput!): CreateUserPayload!\n  signinUser(input: SigninUserInput!): SigninPayload!\n  createUser(input: SignupUserInput!): CreateUserPayload!\n}\n\n# If authentication was successful the payload contains the user and a token. If unsuccessful this payload is null.\ntype SigninPayload {\n  token: String\n  user: User\n  clientMutationId: String\n  viewer: Viewer!\n}\n\ninput SigninUserInput {\n  email: AUTH_PROVIDER_EMAIL\n  clientMutationId: String!\n}\n\ninput SignupUserInput {\n  name: String!\n  linksIds: [ID!]\n  links: [UserlinksLink!]\n  votesIds: [ID!]\n  votes: [UservotesVote!]\n  clientMutationId: String!\n  authProvider: AuthProviderSignupData!\n}\n\n# An object with an ID\ninterface Node {\n  # The id of the object.\n  id: ID!\n}\n\n# Information about pagination in a connection.\ntype PageInfo {\n  # When paginating forwards, are there more items?\n  hasNextPage: Boolean\n\n  # When paginating backwards, are there more items?\n  hasPreviousPage: Boolean\n\n  # When paginating backwards, the cursor to continue.\n  startCursor: String\n\n  # When paginating forwards, the cursor to continue.\n  endCursor: String\n}\n\ntype Query {\n  viewer: Viewer!\n\n  # Fetches an object given its ID\n  node(\n    # The ID of an object\n    id: ID!\n  ): Node\n}\n\ninput RemoveFromUsersLinksLinkInput {\n  postedByUserId: ID!\n  linksLinkId: ID!\n  clientMutationId: String!\n}\n\ntype RemoveFromUsersLinksPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  linksLink: Link\n  postedByUser: User\n  linksLinkEdge: LinkEdge\n  postedByUserEdge: UserEdge\n}\n\ninput UpdateFile {\n  id: ID!\n  name: String\n}\n\ninput UpdateFileInput {\n  id: ID!\n  name: String\n  clientMutationId: String!\n}\n\ntype UpdateFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n}\n\ninput UpdateLink {\n  description: String\n  id: ID!\n  url: String\n  postedById: ID\n  votesIds: [ID!]\n  votes: [LinkvotesVote!]\n}\n\ninput UpdateLinkInput {\n  description: String\n  id: ID!\n  url: String\n  postedById: ID\n  votesIds: [ID!]\n  votes: [LinkvotesVote!]\n  clientMutationId: String!\n}\n\ntype UpdateLinkPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  link: Link\n  edge: LinkEdge\n  postedBy: User\n}\n\ninput UpdateOrCreateFileInput {\n  update: UpdateFile!\n  create: CreateFile!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreateFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n}\n\ninput UpdateOrCreateLinkInput {\n  update: UpdateLink!\n  create: CreateLink!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreateLinkPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  link: Link\n  edge: LinkEdge\n  postedBy: User\n}\n\ninput UpdateOrCreateUserInput {\n  update: UpdateUser!\n  create: CreateUser!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreateUserPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  user: User\n  edge: UserEdge\n}\n\ninput UpdateOrCreateVoteInput {\n  update: UpdateVote!\n  create: CreateVote!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreateVotePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  vote: Vote\n  edge: VoteEdge\n  link: Link\n  user: User\n}\n\ninput UpdateUser {\n  id: ID!\n  name: String\n  linksIds: [ID!]\n  links: [UserlinksLink!]\n  votesIds: [ID!]\n  votes: [UservotesVote!]\n}\n\ninput UpdateUserInput {\n  id: ID!\n  name: String\n  linksIds: [ID!]\n  links: [UserlinksLink!]\n  votesIds: [ID!]\n  votes: [UservotesVote!]\n  clientMutationId: String!\n}\n\ntype UpdateUserPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  user: User\n  edge: UserEdge\n}\n\ninput UpdateVote {\n  id: ID!\n  linkId: ID\n  link: VotelinkLink\n  userId: ID\n}\n\ninput UpdateVoteInput {\n  id: ID!\n  linkId: ID\n  link: VotelinkLink\n  userId: ID\n  clientMutationId: String!\n}\n\ntype UpdateVotePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  vote: Vote\n  edge: VoteEdge\n  link: Link\n  user: User\n}\n\ntype User implements Node {\n  createdAt: DateTime!\n  id: ID!\n  links(filter: LinkFilter, orderBy: LinkOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): LinkConnection\n  name: String!\n  updatedAt: DateTime!\n  votes(filter: VoteFilter, orderBy: VoteOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): VoteConnection\n}\n\n# A connection to a list of items.\ntype UserConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo!\n\n  # A list of edges.\n  edges: [UserEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype UserEdge {\n  # The item at the end of the edge.\n  node: User!\n\n  # A cursor for use in pagination.\n  cursor: String!\n}\n\ninput UserFilter {\n  AND: [UserFilter!]\n  OR: [UserFilter!]\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  name: String\n  name_not: String\n  name_in: [String!]\n  name_not_in: [String!]\n  name_lt: String\n  name_lte: String\n  name_gt: String\n  name_gte: String\n  name_contains: String\n  name_not_contains: String\n  name_starts_with: String\n  name_not_starts_with: String\n  name_ends_with: String\n  name_not_ends_with: String\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n  links_every: LinkFilter\n  links_some: LinkFilter\n  links_none: LinkFilter\n  votes_every: VoteFilter\n  votes_some: VoteFilter\n  votes_none: VoteFilter\n}\n\nenum UserOrderBy {\n  createdAt_ASC\n  createdAt_DESC\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n}\n\ninput UserlinksLink {\n  description: String!\n  url: String!\n  votesIds: [ID!]\n  votes: [UserlinksLinkvotesVote!]\n}\n\ninput UserlinksLinkvotesVote {\n  userId: ID\n}\n\ninput UservotesVote {\n  linkId: ID\n  link: UservotesVotelinkLink\n}\n\ninput UservotesVotelinkLink {\n  description: String!\n  url: String!\n  postedById: ID\n  votesIds: [ID!]\n  votes: [UservotesVotelinkLinkvotesVote!]\n}\n\ninput UservotesVotelinkLinkvotesVote {\n  linkId: ID\n  userId: ID\n}\n\n# This is the famous Relay viewer object\ntype Viewer {\n  allFiles(filter: FileFilter, orderBy: FileOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): FileConnection!\n  allLinks(filter: LinkFilter, orderBy: LinkOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): LinkConnection\n  allUsers(filter: UserFilter, orderBy: UserOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection!\n  allVotes(filter: VoteFilter, orderBy: VoteOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): VoteConnection!\n  user: User\n  File(id: ID, secret: String, url: String): File\n  Link(id: ID): Link\n  User(id: ID): User\n  Vote(id: ID): Vote\n  id: ID!\n}\n\ntype Vote implements Node {\n  createdAt: DateTime!\n  id: ID!\n  link(filter: LinkFilter): Link!\n  updatedAt: DateTime!\n  user(filter: UserFilter): User!\n}\n\n# A connection to a list of items.\ntype VoteConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo\n\n  # A list of edges.\n  edges: [VoteEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype VoteEdge {\n  # The item at the end of the edge.\n  node: Vote\n\n  # A cursor for use in pagination.\n  cursor: String\n}\n\ninput VoteFilter {\n  AND: [VoteFilter!]\n  OR: [VoteFilter!]\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n  link: LinkFilter\n  user: UserFilter\n}\n\nenum VoteOrderBy {\n  createdAt_ASC\n  createdAt_DESC\n  id_ASC\n  id_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n}\n\ninput VotelinkLink {\n  description: String!\n  url: String!\n  postedById: ID\n  votesIds: [ID!]\n  votes: [VotelinkLinkvotesVote!]\n}\n\ninput VotelinkLinkvotesVote {\n  userId: ID\n}\n\ntype Subscription {\n  Link: LinkSubscriptionPayload\n  Vote: VoteSubscriptionPayload\n}\n\ntype LinkSubscriptionPayload {\n  mutation: _ModelMutationType!\n  node: Link\n  updatedFields: [String!]\n  previousValues: LinkPreviousValues\n}\n\nenum _ModelMutationType {\n  CREATED\n  UPDATED\n  DELETED\n}\n\ntype LinkPreviousValues {\n  createdAt: DateTime!\n  description: String!\n  id: ID!\n  updatedAt: DateTime!\n  url: String!\n}\n\ntype VoteSubscriptionPayload {\n  mutation: _ModelMutationType!\n  node: Vote\n  updatedFields: [String!]\n  previousValues: VotePreviousValues\n}\n\ntype VotePreviousValues {\n  createdAt: DateTime!\n  id: ID!\n  updatedAt: DateTime!\n}\n\n"
  },
  {
    "path": "packages/graphql-playground-react/public/hn-relay.graphql",
    "content": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  links: [Link!] @relation(name: \"UsersLinks\")\n  votes: [Vote!] @relation(name: \"UsersVotes\")\n}\n\ntype Link @model { \n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  url: String!\n  description: String!\n  postedBy: User @relation(name: \"UsersLinks\")\n  votes: [Vote!] @relation(name: \"VotesOnLink\")\n}\n\ntype Vote @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  user: User @relation(name: \"UsersVotes\")\n  link: Link @relation(name: \"VotesOnLink\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/hn-starter.graphql",
    "content": "type Link @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  url: String!\n  description: String!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/hn.graphql",
    "content": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  links: [Link!] @relation(name: \"UsersLinks\")\n  votes: [Vote!] @relation(name: \"UsersVotes\")\n}\n\ntype Link @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  url: String!\n  description: String!\n  postedBy: User @relation(name: \"UsersLinks\")\n  votes: [Vote!] @relation(name: \"VotesOnLink\")\n}\n\ntype Vote @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  user: User @relation(name: \"UsersVotes\")\n  link: Link @relation(name: \"VotesOnLink\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui\">\n  <title>GraphQL Playground</title>\n\n</head>\n\n<body>\n  <style type=\"text/css\">\n    html {\n      font-family: \"Open Sans\", sans-serif;\n      overflow: hidden;\n    }\n\n    body {\n      margin: 0;\n      background: #172a3a;\n    }\n\n    .playgroundIn {\n      -webkit-animation: playgroundIn 0.5s ease-out forwards;\n      animation: playgroundIn 0.5s ease-out forwards;\n    }\n\n    @-webkit-keyframes playgroundIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(10px);\n        -ms-transform: translateY(10px);\n        transform: translateY(10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes playgroundIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(10px);\n        -ms-transform: translateY(10px);\n        transform: translateY(10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n  </style>\n\n  <style type=\"text/css\">\n    .fadeOut {\n      -webkit-animation: fadeOut 0.5s ease-out forwards;\n      animation: fadeOut 0.5s ease-out forwards;\n    }\n\n    @-webkit-keyframes fadeIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes fadeIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @-webkit-keyframes fadeOut {\n      from {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n      to {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n    }\n\n    @keyframes fadeOut {\n      from {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n      to {\n        opacity: 0;\n        -webkit-transform: translateY(-10px);\n        -ms-transform: translateY(-10px);\n        transform: translateY(-10px);\n      }\n    }\n\n    @-webkit-keyframes appearIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(0px);\n        -ms-transform: translateY(0px);\n        transform: translateY(0px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @keyframes appearIn {\n      from {\n        opacity: 0;\n        -webkit-transform: translateY(0px);\n        -ms-transform: translateY(0px);\n        transform: translateY(0px);\n      }\n      to {\n        opacity: 1;\n        -webkit-transform: translateY(0);\n        -ms-transform: translateY(0);\n        transform: translateY(0);\n      }\n    }\n\n    @-webkit-keyframes scaleIn {\n      from {\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        transform: scale(0);\n      }\n      to {\n        -webkit-transform: scale(1);\n        -ms-transform: scale(1);\n        transform: scale(1);\n      }\n    }\n\n    @keyframes scaleIn {\n      from {\n        -webkit-transform: scale(0);\n        -ms-transform: scale(0);\n        transform: scale(0);\n      }\n      to {\n        -webkit-transform: scale(1);\n        -ms-transform: scale(1);\n        transform: scale(1);\n      }\n    }\n\n    @-webkit-keyframes innerDrawIn {\n      0% {\n        stroke-dashoffset: 70;\n      }\n      50% {\n        stroke-dashoffset: 140;\n      }\n      100% {\n        stroke-dashoffset: 210;\n      }\n    }\n\n    @keyframes innerDrawIn {\n      0% {\n        stroke-dashoffset: 70;\n      }\n      50% {\n        stroke-dashoffset: 140;\n      }\n      100% {\n        stroke-dashoffset: 210;\n      }\n    }\n\n    @-webkit-keyframes outerDrawIn {\n      0% {\n        stroke-dashoffset: 76;\n      }\n      100% {\n        stroke-dashoffset: 152;\n      }\n    }\n\n    @keyframes outerDrawIn {\n      0% {\n        stroke-dashoffset: 76;\n      }\n      100% {\n        stroke-dashoffset: 152;\n      }\n    }\n\n    .hHWjkv {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n    }\n\n    .gCDOzd {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n    }\n\n    .hmCcxi {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n    }\n\n    .eHamQi {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n    }\n\n    .byhgGu {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n    }\n\n    .llAKP {\n      -webkit-transform-origin: 0px 0px;\n      -ms-transform-origin: 0px 0px;\n      transform-origin: 0px 0px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n    }\n\n    .bglIGM {\n      -webkit-transform-origin: 64px 28px;\n      -ms-transform-origin: 64px 28px;\n      transform-origin: 64px 28px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;\n    }\n\n    .ksxRII {\n      -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;\n      -ms-transform-origin: 95.98500061035156px 46.510000228881836px;\n      transform-origin: 95.98500061035156px 46.510000228881836px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;\n    }\n\n    .cWrBmb {\n      -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;\n      -ms-transform-origin: 95.97162628173828px 83.4900016784668px;\n      transform-origin: 95.97162628173828px 83.4900016784668px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;\n    }\n\n    .Wnusb {\n      -webkit-transform-origin: 64px 101.97999572753906px;\n      -ms-transform-origin: 64px 101.97999572753906px;\n      transform-origin: 64px 101.97999572753906px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;\n    }\n\n    .bfPqf {\n      -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;\n      -ms-transform-origin: 32.03982162475586px 83.4900016784668px;\n      transform-origin: 32.03982162475586px 83.4900016784668px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;\n    }\n\n    .edRCTN {\n      -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;\n      -ms-transform-origin: 32.033552169799805px 46.510000228881836px;\n      transform-origin: 32.033552169799805px 46.510000228881836px;\n      -webkit-transform: scale(0);\n      -ms-transform: scale(0);\n      transform: scale(0);\n      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;\n    }\n\n    .iEGVWn {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .bsocdx {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .jAZXmP {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .hSeArx {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .bVgqGk {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .hEFqBt {\n      opacity: 0;\n      stroke-dasharray: 76;\n      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n      animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;\n      -webkit-animation-iteration-count: 1, 1;\n      animation-iteration-count: 1, 1;\n    }\n\n    .dzEKCM {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    .DYnPx {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    .hjPEAQ {\n      opacity: 0;\n      stroke-dasharray: 70;\n      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n      animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;\n      -webkit-animation-iteration-count: infinite, 1;\n      animation-iteration-count: infinite, 1;\n    }\n\n    #loading-wrapper {\n      position: absolute;\n      width: 100vw;\n      height: 100vh;\n      display: -webkit-box;\n      display: -webkit-flex;\n      display: -ms-flexbox;\n      display: flex;\n      -webkit-align-items: center;\n      -webkit-box-align: center;\n      -ms-flex-align: center;\n      align-items: center;\n      -webkit-box-pack: center;\n      -webkit-justify-content: center;\n      -ms-flex-pack: center;\n      justify-content: center;\n      -webkit-flex-direction: column;\n      -ms-flex-direction: column;\n      flex-direction: column;\n    }\n\n    .logo {\n      width: 75px;\n      height: 75px;\n      margin-bottom: 20px;\n      opacity: 0;\n      -webkit-animation: fadeIn 0.5s ease-out forwards;\n      animation: fadeIn 0.5s ease-out forwards;\n    }\n\n    .text {\n      font-size: 32px;\n      font-weight: 200;\n      text-align: center;\n      color: rgba(255, 255, 255, 0.6);\n      opacity: 0;\n      -webkit-animation: fadeIn 0.5s ease-out forwards;\n      animation: fadeIn 0.5s ease-out forwards;\n    }\n\n    .dGfHfc {\n      font-weight: 400;\n    }\n  </style>\n  <div id=\"loading-wrapper\">\n    <svg class=\"logo\" viewBox=\"0 0 128 128\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n      <title>GraphQL Playground Logo</title>\n      <defs>\n        <linearGradient id=\"linearGradient-1\" x1=\"4.86%\" x2=\"96.21%\" y1=\"0%\" y2=\"99.66%\">\n          <stop stop-color=\"#E00082\" stop-opacity=\".8\" offset=\"0%\"></stop>\n          <stop stop-color=\"#E00082\" offset=\"100%\"></stop>\n        </linearGradient>\n      </defs>\n      <g>\n        <rect id=\"Gradient\" width=\"127.96\" height=\"127.96\" y=\"1\" fill=\"url(#linearGradient-1)\" rx=\"4\"></rect>\n        <path id=\"Border\" fill=\"#E00082\" fill-rule=\"nonzero\" d=\"M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z\"></path>\n        <path class=\"bglIGM\" x=\"64\" y=\"28\" fill=\"#fff\" d=\"M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8\" style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"ksxRII\" x=\"95.98500061035156\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"cWrBmb\" x=\"95.97162628173828\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"Wnusb\" x=\"64\" y=\"101.97999572753906\" fill=\"#fff\" d=\"M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"bfPqf\" x=\"32.03982162475586\" y=\"83.4900016784668\" fill=\"#fff\" d=\"M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"edRCTN\" x=\"32.033552169799805\" y=\"46.510000228881836\" fill=\"#fff\" d=\"M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96\"\n          style=\"transform: translate(100px, 100px);\"></path>\n        <path class=\"iEGVWn\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M63.55 27.5l32.9 19-32.9-19z\"></path>\n        <path class=\"bsocdx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96 46v38-38z\"></path>\n        <path class=\"jAZXmP\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M96.45 84.5l-32.9 19 32.9-19z\"></path>\n        <path class=\"hSeArx\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M64.45 103.5l-32.9-19 32.9 19z\"></path>\n        <path class=\"bVgqGk\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M32 84V46v38z\"></path>\n        <path class=\"hEFqBt\" stroke=\"#fff\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M31.55 46.5l32.9-19-32.9 19z\"></path>\n        <path class=\"dzEKCM\" id=\"Triangle-Bottom\" stroke=\"#fff\" stroke-width=\"4\" d=\"M30 84h70\" stroke-linecap=\"round\"></path>\n        <path class=\"DYnPx\" id=\"Triangle-Left\" stroke=\"#fff\" stroke-width=\"4\" d=\"M65 26L30 87\" stroke-linecap=\"round\"></path>\n        <path class=\"hjPEAQ\" id=\"Triangle-Right\" stroke=\"#fff\" stroke-width=\"4\" d=\"M98 87L63 26\" stroke-linecap=\"round\"></path>\n      </g>\n    </svg>\n    <div class=\"text\">Loading\n      <span class=\"dGfHfc\">GraphQL Playground</span>\n    </div>\n  </div>\n\n  <div id=\"root\" />\n  <script type=\"text/javascript\">\n    window.addEventListener('load', function (event) {\n\n      const loadingWrapper = document.getElementById('loading-wrapper');\n      loadingWrapper.classList.add('fadeOut');\n\n\n      const root = document.getElementById('root');\n      root.classList.add('playgroundIn');\n\n      GraphQLPlayground.init(root, {\n        \"env\": \"react\",\n        \"canSaveConfig\": false,\n        \"headers\": {\n          \"test\": \"test\",\n        }\n      })\n    })\n  </script>\n</body>\n\n</html>"
  },
  {
    "path": "packages/graphql-playground-react/public/insta-auth0.graphql",
    "content": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: String!\n}\n\ntype User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  emailAddress: String!\n  emailSubscription: Boolean!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/insta-email.graphql",
    "content": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: String!\n}\n\ntype User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  email: String!\n  emailSubscription: Boolean!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/insta-expo-auth.graphql",
    "content": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  posts: [Post!]!  @relation(name: \"PostsByUser\")\n  name: String!\n  comments: [Comment!]! @relation(name: \"CommentsByUser\")\n}\n\ntype Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: String!\n  createdBy: User!  @relation(name: \"PostsByUser\")\n  comments: [Comment!]! @relation(name: \"CommentsOnPost\")\n}\n\ntype Comment @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  content: String!\n  post: Post! @relation(name: \"CommentsOnPost\")\n  author: User! @relation(name: \"CommentsByUser\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/insta-files.graphql",
    "content": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  image: File @relation(name: \"PostImage\")\n}\n\ntype File @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  post: Post @relation(name: \"PostImage\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/instagram-full.graphql",
    "content": "# The `BigDecimal` scalar type represents signed fractional values with arbitrary precision.\nscalar BigDecimal\n\n# The `BigInt` scalar type represents non-fractional signed whole numeric values. BigInt can represent arbitrary big values.\nscalar BigInt\n\ninput CreateFile {\n  name: String!\n}\n\ninput CreateFileInput {\n  name: String!\n  clientMutationId: String!\n}\n\ntype CreateFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n}\n\ninput CreatePost {\n  description: String!\n  imageUrl: String!\n}\n\ninput CreatePostInput {\n  description: String!\n  imageUrl: String!\n  clientMutationId: String!\n}\n\ntype CreatePostPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  post: Post\n  edge: PostEdge\n}\n\n# If authentication was successful the payload contains the user and a token. If unsuccessful this payload is null.\ntype CreateUserPayload {\n  user: User\n  clientMutationId: String\n  viewer: Viewer!\n}\n\nscalar DateTime\n\ninput DeleteFileInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeleteFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n  deletedId: ID\n}\n\ninput DeletePostInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeletePostPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  post: Post\n  edge: PostEdge\n  deletedId: ID\n}\n\ninput DeleteUserInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype DeleteUserPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  user: User\n  edge: UserEdge\n  deletedId: ID\n}\n\ntype File implements Node {\n  contentType: String!\n  createdAt: DateTime!\n  id: ID!\n  name: String!\n  secret: String!\n  size: Int!\n  updatedAt: DateTime!\n  url: String!\n}\n\n# A connection to a list of items.\ntype FileConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo!\n\n  # A list of edges.\n  edges: [FileEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype FileEdge {\n  # The item at the end of the edge.\n  node: File!\n\n  # A cursor for use in pagination.\n  cursor: String!\n}\n\ninput FileFilter {\n  AND: [FileFilter!]\n  OR: [FileFilter!]\n  contentType: String\n  contentType_not: String\n  contentType_in: [String!]\n  contentType_not_in: [String!]\n  contentType_lt: String\n  contentType_lte: String\n  contentType_gt: String\n  contentType_gte: String\n  contentType_contains: String\n  contentType_not_contains: String\n  contentType_starts_with: String\n  contentType_not_starts_with: String\n  contentType_ends_with: String\n  contentType_not_ends_with: String\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  name: String\n  name_not: String\n  name_in: [String!]\n  name_not_in: [String!]\n  name_lt: String\n  name_lte: String\n  name_gt: String\n  name_gte: String\n  name_contains: String\n  name_not_contains: String\n  name_starts_with: String\n  name_not_starts_with: String\n  name_ends_with: String\n  name_not_ends_with: String\n  secret: String\n  secret_not: String\n  secret_in: [String!]\n  secret_not_in: [String!]\n  secret_lt: String\n  secret_lte: String\n  secret_gt: String\n  secret_gte: String\n  secret_contains: String\n  secret_not_contains: String\n  secret_starts_with: String\n  secret_not_starts_with: String\n  secret_ends_with: String\n  secret_not_ends_with: String\n  size: Int\n  size_not: Int\n  size_in: [Int!]\n  size_not_in: [Int!]\n  size_lt: Int\n  size_lte: Int\n  size_gt: Int\n  size_gte: Int\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n  url: String\n  url_not: String\n  url_in: [String!]\n  url_not_in: [String!]\n  url_lt: String\n  url_lte: String\n  url_gt: String\n  url_gte: String\n  url_contains: String\n  url_not_contains: String\n  url_starts_with: String\n  url_not_starts_with: String\n  url_ends_with: String\n  url_not_ends_with: String\n}\n\nenum FileOrderBy {\n  contentType_ASC\n  contentType_DESC\n  createdAt_ASC\n  createdAt_DESC\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  secret_ASC\n  secret_DESC\n  size_ASC\n  size_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  url_ASC\n  url_DESC\n}\n\n# The `Long` scalar type represents non-fractional signed whole numeric values.\n# Long can represent values between -(2^63) and 2^63 - 1.\nscalar Long\n\ntype Mutation {\n  createFile(input: CreateFileInput!): CreateFilePayload\n  createPost(input: CreatePostInput!): CreatePostPayload\n  updateFile(input: UpdateFileInput!): UpdateFilePayload\n  updatePost(input: UpdatePostInput!): UpdatePostPayload\n  updateUser(input: UpdateUserInput!): UpdateUserPayload\n  updateOrCreateFile(input: UpdateOrCreateFileInput!): UpdateOrCreateFilePayload\n  updateOrCreatePost(input: UpdateOrCreatePostInput!): UpdateOrCreatePostPayload\n  updateOrCreateUser(input: UpdateOrCreateUserInput!): UpdateOrCreateUserPayload\n  deleteFile(input: DeleteFileInput!): DeleteFilePayload\n  deletePost(input: DeletePostInput!): DeletePostPayload\n  deleteUser(input: DeleteUserInput!): DeleteUserPayload\n  createUser(input: SignupUserInput!): CreateUserPayload!\n}\n\n# An object with an ID\ninterface Node {\n  # The id of the object.\n  id: ID!\n}\n\n# Information about pagination in a connection.\ntype PageInfo {\n  # When paginating forwards, are there more items?\n  hasNextPage: Boolean\n\n  # When paginating backwards, are there more items?\n  hasPreviousPage: Boolean\n\n  # When paginating backwards, the cursor to continue.\n  startCursor: String\n\n  # When paginating forwards, the cursor to continue.\n  endCursor: String\n}\n\ntype Post implements Node {\n  createdAt: DateTime!\n  description: String!\n  id: ID!\n  imageUrl: String!\n  updatedAt: DateTime!\n}\n\n# A connection to a list of items.\ntype PostConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo\n\n  # A list of edges.\n  edges: [PostEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype PostEdge {\n  # The item at the end of the edge.\n  node: Post\n\n  # A cursor for use in pagination.\n  cursor: String\n}\n\ninput PostFilter {\n  AND: [PostFilter!]\n  OR: [PostFilter!]\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  description: String\n  description_not: String\n  description_in: [String!]\n  description_not_in: [String!]\n  description_lt: String\n  description_lte: String\n  description_gt: String\n  description_gte: String\n  description_contains: String\n  description_not_contains: String\n  description_starts_with: String\n  description_not_starts_with: String\n  description_ends_with: String\n  description_not_ends_with: String\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  imageUrl: String\n  imageUrl_not: String\n  imageUrl_in: [String!]\n  imageUrl_not_in: [String!]\n  imageUrl_lt: String\n  imageUrl_lte: String\n  imageUrl_gt: String\n  imageUrl_gte: String\n  imageUrl_contains: String\n  imageUrl_not_contains: String\n  imageUrl_starts_with: String\n  imageUrl_not_starts_with: String\n  imageUrl_ends_with: String\n  imageUrl_not_ends_with: String\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n}\n\nenum PostOrderBy {\n  createdAt_ASC\n  createdAt_DESC\n  description_ASC\n  description_DESC\n  id_ASC\n  id_DESC\n  imageUrl_ASC\n  imageUrl_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n}\n\ntype Query {\n  viewer: Viewer!\n\n  # Fetches an object given its ID\n  node(\n    # The ID of an object\n    id: ID!\n  ): Node\n}\n\ninput SignupUserInput {\n  clientMutationId: String!\n}\n\ninput UpdateFile {\n  id: ID!\n  name: String\n}\n\ninput UpdateFileInput {\n  id: ID!\n  name: String\n  clientMutationId: String!\n}\n\ntype UpdateFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n}\n\ninput UpdateOrCreateFileInput {\n  update: UpdateFile!\n  create: CreateFile!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreateFilePayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  file: File\n  edge: FileEdge\n}\n\ninput UpdateOrCreatePostInput {\n  update: UpdatePost!\n  create: CreatePost!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreatePostPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  post: Post\n  edge: PostEdge\n}\n\ninput UpdateOrCreateUserInput {\n  update: UpdateUser!\n  clientMutationId: String!\n}\n\ntype UpdateOrCreateUserPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  user: User\n  edge: UserEdge\n}\n\ninput UpdatePost {\n  description: String\n  id: ID!\n  imageUrl: String\n}\n\ninput UpdatePostInput {\n  description: String\n  id: ID!\n  imageUrl: String\n  clientMutationId: String!\n}\n\ntype UpdatePostPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  post: Post\n  edge: PostEdge\n}\n\ninput UpdateUser {\n  id: ID!\n}\n\ninput UpdateUserInput {\n  id: ID!\n  clientMutationId: String!\n}\n\ntype UpdateUserPayload {\n  viewer: Viewer!\n  clientMutationId: String!\n  user: User\n  edge: UserEdge\n}\n\ntype User implements Node {\n  createdAt: DateTime!\n  id: ID!\n  updatedAt: DateTime!\n}\n\n# A connection to a list of items.\ntype UserConnection {\n  # Information to aid in pagination.\n  pageInfo: PageInfo!\n\n  # A list of edges.\n  edges: [UserEdge]\n\n  # Count of filtered result set without considering pagination arguments\n  count: Int!\n}\n\n# An edge in a connection.\ntype UserEdge {\n  # The item at the end of the edge.\n  node: User!\n\n  # A cursor for use in pagination.\n  cursor: String!\n}\n\ninput UserFilter {\n  AND: [UserFilter!]\n  OR: [UserFilter!]\n  createdAt: DateTime\n  createdAt_not: DateTime\n  createdAt_in: [DateTime!]\n  createdAt_not_in: [DateTime!]\n  createdAt_lt: DateTime\n  createdAt_lte: DateTime\n  createdAt_gt: DateTime\n  createdAt_gte: DateTime\n  id: ID\n  id_not: ID\n  id_in: [ID!]\n  id_not_in: [ID!]\n  id_lt: ID\n  id_lte: ID\n  id_gt: ID\n  id_gte: ID\n  id_contains: ID\n  id_not_contains: ID\n  id_starts_with: ID\n  id_not_starts_with: ID\n  id_ends_with: ID\n  id_not_ends_with: ID\n  updatedAt: DateTime\n  updatedAt_not: DateTime\n  updatedAt_in: [DateTime!]\n  updatedAt_not_in: [DateTime!]\n  updatedAt_lt: DateTime\n  updatedAt_lte: DateTime\n  updatedAt_gt: DateTime\n  updatedAt_gte: DateTime\n}\n\nenum UserOrderBy {\n  createdAt_ASC\n  createdAt_DESC\n  id_ASC\n  id_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n}\n\n# This is the famous Relay viewer object\ntype Viewer {\n  allFiles(filter: FileFilter, orderBy: FileOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): FileConnection!\n  allPosts(filter: PostFilter, orderBy: PostOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): PostConnection\n  allUsers(filter: UserFilter, orderBy: UserOrderBy, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection!\n  user: User\n  File(id: ID, secret: String, url: String): File\n  Post(id: ID): Post\n  User(id: ID): User\n  id: ID!\n}\n\n"
  },
  {
    "path": "packages/graphql-playground-react/public/instagram.graphql",
    "content": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: String!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/movies-import.graphql",
    "content": "type Movie @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  oldid: String\n  description: String\n  released: String\n  title: String\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/pokedex.graphql",
    "content": "type Pokemon @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/simple-pokedex.graphql",
    "content": "type Pokemon @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  url: String!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/todo.graphql",
    "content": "type Todo @model {\n  id: ID! @isUnique\n  text: String!\n  complete: Boolean!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/twitter.graphql",
    "content": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  username: String!\n  followers: [User!]! @relation(name: \"Followers\")\n  tweets: [Tweet!]! @relation(name: \"Tweets\")\n}\n\ntype Tweet @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  text: String!\n  author: User @relation(name: \"Tweets\")\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/welcome-rp.graphql",
    "content": "type Customer @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  email: String!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/welcome.graphql",
    "content": "type Customer @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  email: String\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/worldchat.graphql",
    "content": "type Traveller @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  location: Location! @relation(name: \"TravellerLocation\")\n  messages: [Message!]! @relation(name: \"MessagesFromTraveller\")\n}\n\ntype Message @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  text: String!\n  sentBy: Traveller!  @relation(name: \"MessagesFromTraveller\")\n}\n\ntype Location @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  traveller: Traveller! @relation(name: \"TravellerLocation\")\n  latitude: Float!\n  longitude: Float!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/release.sh",
    "content": "#!/bin/bash\n\nset -e\n\n#npm publish\n\ncurl -X POST \\\n  http://purge.jsdelivr.net/ \\\n  -H 'cache-control: no-cache' \\\n  -H 'content-type: application/json' \\\n  -d '{\n\t\"path\": [\n\t\t\"/npm/graphql-playground-react/build/static/css/middleware.css\",\n\t\t\"/npm/graphql-playground-react/build/static/js/middleware.js\"\n\t]\n}'\n\n"
  },
  {
    "path": "packages/graphql-playground-react/scripts/build.js",
    "content": "// Do this as the first thing so that any code reading it knows the right env.\nprocess.env.NODE_ENV = 'production';\n\n// Load environment variables from .env file. Suppress warnings using silent\n// if this file is missing. dotenv will never modify any environment variables\n// that have already been set.\n// https://github.com/motdotla/dotenv\nrequire('dotenv').config({silent: true});\n\nvar chalk = require('chalk');\nvar fs = require('fs-extra');\nvar path = require('path');\nvar filesize = require('filesize');\nvar gzipSize = require('gzip-size').sync;\nvar webpack = require('webpack');\nvar config = require('../config/webpack.config.prod');\nvar paths = require('../config/paths');\nvar checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');\nvar recursive = require('recursive-readdir');\nvar stripAnsi = require('strip-ansi');\n\nvar useYarn = fs.existsSync(paths.yarnLockFile);\n\nconst { renderPlaygroundPage } = require('graphql-playground-html');\n\n// Create the playground entry point if it doesn't exist\nif(!fs.existsSync(paths.appHtml)) {\n  fs.writeFileSync(paths.appHtml, renderPlaygroundPage({env: 'react'}));\n}\n\n// Warn and crash if required files are missing\nif (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {\n  process.exit(1);\n}\n\n// Input: /User/dan/app/build/static/js/main.82be8.js\n// Output: /static/js/main.ts\nfunction removeFileNameHash(fileName) {\n  return fileName\n    .replace(paths.appBuild, '')\n    .replace(/\\/?(.*)(\\.\\w+)(\\.js|\\.css)/, (match, p1, p2, p3) => p1 + p3);\n}\n\n// Input: 1024, 2048\n// Output: \"(+1 KB)\"\nfunction getDifferenceLabel(currentSize, previousSize) {\n  var FIFTY_KILOBYTES = 1024 * 50;\n  var difference = currentSize - previousSize;\n  var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;\n  if (difference >= FIFTY_KILOBYTES) {\n    return chalk.red('+' + fileSize);\n  } else if (difference < FIFTY_KILOBYTES && difference > 0) {\n    return chalk.yellow('+' + fileSize);\n  } else if (difference < 0) {\n    return chalk.green(fileSize);\n  } else {\n    return '';\n  }\n}\n\n// First, read the current file sizes in build directory.\n// This lets us display how much they changed later.\nrecursive(paths.appBuild, (err, fileNames) => {\n  var previousSizeMap = (fileNames || [])\n    .filter(fileName => /\\.(js|css)$/.test(fileName))\n    .reduce((memo, fileName) => {\n      var contents = fs.readFileSync(fileName);\n      var key = removeFileNameHash(fileName);\n      memo[key] = gzipSize(contents);\n      return memo;\n    }, {});\n\n  // Remove all content but keep the directory so that\n  // if you're in it, you don't end up in Trash\n  fs.emptyDirSync(paths.appBuild);\n\n  // Start the webpack build\n  build(previousSizeMap);\n\n  // Merge with the public folder\n  copyPublicFolder();\n});\n\n// Print a detailed summary of build files.\nfunction printFileSizes(stats, previousSizeMap) {\n  var assets = stats.toJson().assets\n    .filter(asset => /\\.(js|css)$/.test(asset.name))\n    .map(asset => {\n      var fileContents = fs.readFileSync(paths.appBuild + '/' + asset.name);\n      var size = gzipSize(fileContents);\n      var previousSize = previousSizeMap[removeFileNameHash(asset.name)];\n      var difference = getDifferenceLabel(size, previousSize);\n      return {\n        folder: path.join('build', path.dirname(asset.name)),\n        name: path.basename(asset.name),\n        size: size,\n        sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : '')\n      };\n    });\n  assets.sort((a, b) => b.size - a.size);\n  var longestSizeLabelLength = Math.max.apply(null,\n    assets.map(a => stripAnsi(a.sizeLabel).length)\n  );\n  assets.forEach(asset => {\n    var sizeLabel = asset.sizeLabel;\n    var sizeLength = stripAnsi(sizeLabel).length;\n    if (sizeLength < longestSizeLabelLength) {\n      var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength);\n      sizeLabel += rightPadding;\n    }\n    console.log(\n      '  ' + sizeLabel +\n      '  ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name)\n    );\n  });\n}\n\n// Print out errors\nfunction printErrors(summary, errors) {\n  console.log(chalk.red(summary));\n  console.log();\n  errors.forEach(err => {\n    console.log(err.message || err);\n    console.log();\n  });\n}\n\n// Create the production build and print the deployment instructions.\nfunction build(previousSizeMap) {\n  console.log('Creating an optimized production build...');\n  webpack(config).run((err, stats) => {\n    if (err) {\n      printErrors('Failed to compile.', [err]);\n      process.exit(1);\n    }\n\n    if (stats.compilation.errors.length) {\n      printErrors('Failed to compile.', stats.compilation.errors);\n      process.exit(1);\n    }\n\n    if (process.env.CI && stats.compilation.warnings.length) {\n     printErrors('Failed to compile.', stats.compilation.warnings);\n     process.exit(1);\n   }\n\n    console.log(chalk.green('Compiled successfully.'));\n    console.log();\n\n    console.log('File sizes after gzip:');\n    console.log();\n    printFileSizes(stats, previousSizeMap);\n    console.log();\n\n    var openCommand = process.platform === 'win32' ? 'start' : 'open';\n    var appPackage  = require(paths.appPackageJson);\n    var homepagePath = appPackage.homepage;\n    var publicPath = config.output.publicPath;\n    if (homepagePath && homepagePath.indexOf('.github.io/') !== -1) {\n      // \"homepage\": \"http://user.github.io/project\"\n      console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.');\n      console.log('You can control this with the ' + chalk.green('homepage') + ' field in your '  + chalk.cyan('package.json') + '.');\n      console.log();\n      console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');\n      console.log('To publish it at ' + chalk.green(homepagePath) + ', run:');\n      // If script deploy has been added to package.json, skip the instructions\n      if (typeof appPackage.scripts.deploy === 'undefined') {\n        console.log();\n        if (useYarn) {\n          console.log('  ' + chalk.cyan('yarn') +  ' add --dev gh-pages');\n        } else {\n          console.log('  ' + chalk.cyan('npm') +  ' install --save-dev gh-pages');\n        }\n        console.log();\n        console.log('Add the following script in your ' + chalk.cyan('package.json') + '.');\n        console.log();\n        console.log('    ' + chalk.dim('// ...'));\n        console.log('    ' + chalk.yellow('\"scripts\"') + ': {');\n        console.log('      ' + chalk.dim('// ...'));\n        console.log('      ' + chalk.yellow('\"deploy\"') + ': ' + chalk.yellow('\"npm run build&&gh-pages -d build\"'));\n        console.log('    }');\n        console.log();\n        console.log('Then run:');\n      }\n      console.log();\n      console.log('  ' + chalk.cyan(useYarn ? 'yarn' : 'npm') +  ' run deploy');\n      console.log();\n    } else if (publicPath !== '/') {\n      // \"homepage\": \"http://mywebsite.com/project\"\n      console.log('The project was built assuming it is hosted at ' + chalk.green(publicPath) + '.');\n      console.log('You can control this with the ' + chalk.green('homepage') + ' field in your '  + chalk.cyan('package.json') + '.');\n      console.log();\n      console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');\n      console.log();\n    } else {\n      // no homepage or \"homepage\": \"http://mywebsite.com\"\n      console.log('The project was built assuming it is hosted at the server root.');\n      if (homepagePath) {\n        // \"homepage\": \"http://mywebsite.com\"\n        console.log('You can control this with the ' + chalk.green('homepage') + ' field in your '  + chalk.cyan('package.json') + '.');\n        console.log();\n      } else {\n        // no homepage\n        console.log('To override this, specify the ' + chalk.green('homepage') + ' in your '  + chalk.cyan('package.json') + '.');\n        console.log('For example, add this to build it for GitHub Pages:')\n        console.log();\n        console.log('  ' + chalk.green('\"homepage\"') + chalk.cyan(': ') + chalk.green('\"http://myname.github.io/myapp\"') + chalk.cyan(','));\n        console.log();\n      }\n      console.log('The ' + chalk.cyan('build') + ' folder is ready to be deployed.');\n      console.log('You may also serve it locally with a static server:')\n      console.log();\n      if (useYarn) {\n        console.log('  ' + chalk.cyan('yarn') +  ' global add pushstate-server');\n      } else {\n        console.log('  ' + chalk.cyan('npm') +  ' install -g pushstate-server');\n      }\n      console.log('  ' + chalk.cyan('pushstate-server') + ' build');\n      console.log('  ' + chalk.cyan(openCommand) + ' http://localhost:9000');\n      console.log();\n    }\n  });\n}\n\nfunction copyPublicFolder() {\n  fs.copySync(paths.appPublic, paths.appBuild, {\n    dereference: true,\n    filter: file => file !== paths.appHtml\n  });\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/scripts/start.js",
    "content": "'use strict';\n\n// Do this as the first thing so that any code reading it knows the right env.\nprocess.env.BABEL_ENV = 'development';\nprocess.env.NODE_ENV = 'development';\n\n// Makes the script crash on unhandled rejections instead of silently\n// ignoring them. In the future, promise rejections that are not handled will\n// terminate the Node.js process with a non-zero exit code.\nprocess.on('unhandledRejection', err => {\n  throw err;\n});\n\n// Ensure environment variables are read.\nrequire('../config/env');\n\nconst fs = require('fs');\nconst chalk = require('chalk');\nconst webpack = require('webpack');\nconst WebpackDevServer = require('webpack-dev-server');\nconst clearConsole = require('react-dev-utils/clearConsole');\nconst checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');\nconst {\n  choosePort,\n  createCompiler,\n  prepareProxy,\n  prepareUrls,\n} = require('react-dev-utils/WebpackDevServerUtils');\nconst openBrowser = require('react-dev-utils/openBrowser');\nconst paths = require('../config/paths');\nconst config = require('../config/webpack.config.dev');\nconst createDevServerConfig = require('../config/webpackDevServer.config');\n\nconst useYarn = fs.existsSync(paths.yarnLockFile);\nconst isInteractive = process.stdout.isTTY;\n\nconst { renderPlaygroundPage } = require('graphql-playground-html');\n\n// Create the playground entry point if it doesn't exist\nif(!fs.existsSync(paths.appHtml)) {\n  fs.writeFileSync(paths.appHtml, renderPlaygroundPage({env: 'react'}));\n}\n\n// Warn and crash if required files are missing\nif (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {\n  process.exit(1);\n}\n\n// Tools like Cloud9 rely on this.\nconst DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;\nconst HOST = process.env.HOST || '0.0.0.0';\n\n// We attempt to use the default port but if it is busy, we offer the user to\n// run on a different port. `detect()` Promise resolves to the next free port.\nchoosePort(HOST, DEFAULT_PORT)\n  .then(port => {\n  if (port == null) {\n  // We have not found a port.\n  return;\n}\nconst protocol = process.env.HTTPS === 'true' ? 'https' : 'http';\nconst appName = require(paths.appPackageJson).name;\nconst urls = prepareUrls(protocol, HOST, port);\n// Create a webpack compiler that is configured with custom messages.\nconst compiler = createCompiler({webpack, config, appName, urls, useYarn});\n// Load proxy config\nconst proxySetting = require(paths.appPackageJson).proxy;\nconst proxyConfig = prepareProxy(proxySetting, paths.appPublic);\n// Serve webpack assets generated by the compiler over a web sever.\nconst serverConfig = createDevServerConfig(\n  proxyConfig,\n  urls.lanUrlForConfig\n);\nconst devServer = new WebpackDevServer(compiler, serverConfig);\n// Launch WebpackDevServer.\ndevServer.listen(port, HOST, err => {\n  if (err) {\n    return console.log(err);\n  }\n  if (isInteractive) {\n    clearConsole();\n  }\n  console.log(chalk.cyan('Starting the development server...\\n'));\nopenBrowser(urls.localUrlForBrowser);\n});\n\n['SIGINT', 'SIGTERM'].forEach(function(sig) {\n  process.on(sig, function() {\n    devServer.close();\n    process.exit();\n  });\n});\n})\n.catch(err => {\n  if (err && err.message) {\n  console.log(err.message);\n}\nprocess.exit(1);\n});\n"
  },
  {
    "path": "packages/graphql-playground-react/scripts/test.js",
    "content": "process.env.NODE_ENV = 'test';\nprocess.env.PUBLIC_URL = '';\n\n// Load environment variables from .env file. Suppress warnings using silent\n// if this file is missing. dotenv will never modify any environment variables\n// that have already been set.\n// https://github.com/motdotla/dotenv\nrequire('dotenv').config({silent: true});\n\nconst jest = require('jest');\nconst argv = process.argv.slice(2);\n\n// Watch unless on CI or in coverage mode\nif (!process.env.CI && argv.indexOf('--coverage') < 0) {\n  argv.push('--watch');\n}\n\n// A temporary hack to clear terminal correctly.\n// You can remove this after updating to Jest 18 when it's out.\n// https://github.com/facebook/jest/pull/2230\nvar realWrite = process.stdout.write;\nvar CLEAR = process.platform === 'win32' ? '\\x1Bc' : '\\x1B[2J\\x1B[3J\\x1B[H';\nprocess.stdout.write = function(chunk, encoding, callback) {\n  if (chunk === '\\x1B[2J\\x1B[H') {\n    chunk = CLEAR;\n  }\n  return realWrite.call(this, chunk, encoding, callback);\n};\n\n\njest.run(argv);\n"
  },
  {
    "path": "packages/graphql-playground-react/src/__snapshots__/index.test.tsx.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`test MiddleWareApp passed default headers 1`] = `\n<div>\n  <div\n    class=\"sc-jtggT lbSfdq\"\n  >\n    <div\n      class=\"sc-fONwsr jNppkf playground\"\n    >\n      <div\n        class=\"sc-daURTG dROqMf\"\n      >\n        <div\n          class=\"sc-bXGyLb dDuAEY\"\n        >\n          <div\n            class=\"sc-cmthru bfVYLy\"\n          >\n            <div\n              class=\"sc-gqPbQI SEbZC\"\n            >\n              <div\n                class=\"sc-hORach fyhdOf\"\n              />\n            </div>\n            <div\n              class=\"sc-hMFtBS gtvAeD\"\n            >\n              New Tab\n            </div>\n            <div\n              class=\"sc-gojNiO izjFJN close\"\n            >\n              <svg\n                height=\"11\"\n                stroke-width=\"7\"\n                viewBox=\"0 0 50 50\"\n                width=\"12\"\n              >\n                <title>\n                  Close Tab\n                </title>\n                <line\n                  x1=\"4\"\n                  x2=\"46\"\n                  y1=\"4\"\n                  y2=\"46\"\n                />\n                <line\n                  x1=\"46\"\n                  x2=\"4\"\n                  y1=\"4\"\n                  y2=\"46\"\n                />\n              </svg>\n            </div>\n          </div>\n          <div\n            class=\"sc-lkqHmb hrrKPQ\"\n          >\n            <svg\n              height=\"34\"\n              stroke-width=\"4\"\n              viewBox=\"0 0 50 50\"\n              width=\"34\"\n            >\n              <title>\n                Opens a New Tab\n              </title>\n              <line\n                x1=\"25\"\n                x2=\"25\"\n                y1=\"13.1\"\n                y2=\"36.9\"\n              />\n              <line\n                x1=\"36.9\"\n                x2=\"13.1\"\n                y1=\"25\"\n                y2=\"25\"\n              />\n            </svg>\n          </div>\n        </div>\n      </div>\n      <div\n        class=\"sc-VJcYb jsBJIl\"\n      >\n        <div\n          class=\"sc-ipXKqB iPMBQr graphiql-wrapper active\"\n        >\n          <div\n            class=\"sc-EHOje cIypmL\"\n          >\n            <div\n              class=\"sc-ifAKCX cEPVvT\"\n            >\n              <div\n                class=\"sc-cvbbAY kOflzg\"\n              >\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  Prettify\n                </button>\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  History\n                </button>\n                <div\n                  class=\"sc-brqgnP kOowTR\"\n                >\n                  <input\n                    class=\"sc-jWBwVP cljqcK\"\n                    value=\"https://localhost/\"\n                  />\n                  <div\n                    style=\"display:flex;flex-direction:row;align-items:center;position:absolute;left:6px\"\n                  >\n                    <div\n                      class=\"sc-jKJlTe sc-iAyFgw cVhxIQ\"\n                      title=\"Polling Schema\"\n                    >\n                      <div\n                        class=\"sc-hSdWYo vFglF\"\n                      />\n                    </div>\n                  </div>\n                </div>\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  Copy CURL\n                </button>\n              </div>\n              <div\n                class=\"sc-ibxdXY biDfcz\"\n              >\n                <div\n                  class=\"sc-cMhqgX dUUizb\"\n                >\n                  <div\n                    class=\"sc-ifAKCX cEPVvT\"\n                  >\n                    <div\n                      class=\"sc-bZQynM imcoIY\"\n                    />\n                  </div>\n                  <div\n                    class=\"sc-eTuwsz sc-hXRMBi bihGhC\"\n                    height=\"200\"\n                  >\n                    <div\n                      class=\"sc-gwVKww jmsfqV sc-epnACN cATAit\"\n                    >\n                      <span\n                        class=\"sc-iQNlJl bpxsnM\"\n                      >\n                        Query Variables\n                      </span>\n                      <span\n                        class=\"sc-iQNlJl gArUSm\"\n                      >\n                        HTTP Headers (1)\n                      </span>\n                    </div>\n                    <div\n                      class=\"sc-gPEVay ihtVGC\"\n                    />\n                  </div>\n                  <div\n                    class=\"sc-iQKALj sc-bwCtUz hLmxzl\"\n                  />\n                </div>\n                <div\n                  class=\"sc-RefOD iqiKGG\"\n                >\n                  <div\n                    class=\"sc-iQKALj sc-hrWEMg fHZBGP\"\n                  />\n                  <div\n                    class=\"sc-bdVaJa bFURGJ\"\n                  >\n                    <div\n                      class=\"sc-bwzfXH kJytub\"\n                      title=\"Execute Query (Ctrl-Enter)\"\n                    >\n                      <svg\n                        height=\"35\"\n                        viewBox=\"3.5,4.5,24,24\"\n                        width=\"35\"\n                      >\n                        <path\n                          d=\"M 11 9 L 24 16 L 11 23 z\"\n                        />\n                      </svg>\n                    </div>\n                  </div>\n                  <div\n                    class=\"sc-csuQGl jqqEqQ\"\n                  >\n                    <div\n                      class=\"sc-Rmtcm izeTTo\"\n                    >\n                      <div\n                        class=\"sc-jhAzac czBwBS\"\n                      >\n                        <div\n                          class=\"sc-gipzik jWCgLV\"\n                        />\n                      </div>\n                    </div>\n                  </div>\n                  <div\n                    class=\"sc-iuJeZd PkTkM\"\n                  >\n                    Press the Play Button to get a response here\n                  </div>\n                  <div\n                    class=\"sc-eTuwsz sc-bsbRJL jvVfGJ\"\n                    height=\"300\"\n                  >\n                    <div\n                      class=\"sc-gwVKww jmsfqV sc-hZSUBg hQHJtw\"\n                    >\n                      <span\n                        class=\"sc-iQNlJl bpxsnM\"\n                      >\n                        Tracing\n                      </span>\n                    </div>\n                    <div\n                      class=\"sc-caSCKo jXBojK\"\n                    >\n                      <div\n                        class=\"sc-kjoXOD bJwwoz\"\n                      >\n                        This GraphQL server doesn’t support tracing. See the following page for instructions:\n                        <br />\n                        https://github.com/apollographql/apollo-tracing\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n            <div\n              class=\"sc-kgAjT hyCFBj\"\n              style=\"width:0\"\n            >\n              <div\n                class=\"sc-hmzhuo ckIQDP\"\n              >\n                <div\n                  class=\"sc-TOsTZ iRmVrA\"\n                >\n                  Docs\n                </div>\n                <div\n                  class=\"sc-TOsTZ FJeHV\"\n                >\n                  Schema\n                </div>\n              </div>\n              <div\n                class=\"sc-ksYbfQ jvrrBm\"\n              />\n              <div\n                class=\"sc-frDJqD esEVLt\"\n              />\n              <div\n                class=\"sc-cJSrbW hLWfWH\"\n              />\n            </div>\n          </div>\n        </div>\n      </div>\n      <div\n        class=\"sc-dTdPqK emFIyf\"\n      >\n        <div\n          class=\"sc-itybZL hAFQvt\"\n        >\n          <svg\n            height=\"23\"\n            viewBox=\"0 0 50 50\"\n            width=\"23\"\n          >\n            <title>\n              Settings\n            </title>\n            <path\n              d=\"M48,21h-5.71c-0.4-1.58-0.91-3.33-1.56-4.66l4.06-4.06c0.19-0.19,0.29-0.44,0.29-0.71\n\t\tc0-0.27-0.11-0.52-0.29-0.71L39.14,5.2c-0.39-0.39-1.02-0.39-1.41,0l-4.06,4.06C32.33,8.62,30.58,8.11,29,7.71V2c0-0.55-0.45-1-1-1\n\t\th-6c-0.55,0-1,0.45-1,1v5.71c-1.58,0.4-3.33,0.91-4.66,1.55L12.27,5.2c-0.39-0.39-1.02-0.39-1.41,0L5.2,10.86\n\t\tc-0.39,0.39-0.39,1.02,0,1.41l4.07,4.07C8.62,17.66,8.11,19.42,7.71,21H2c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h5.71\n\t\tc0.4,1.58,0.91,3.34,1.56,4.66L5.2,37.73c-0.19,0.19-0.29,0.44-0.29,0.71s0.11,0.52,0.29,0.71l5.66,5.66c0.38,0.38,1.04,0.38,1.41,0\n\t\tl4.07-4.06c1.32,0.65,3.08,1.15,4.66,1.56V48c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-5.71c1.58-0.4,3.34-0.91,4.66-1.56l4.07,4.06\n\t\tc0.39,0.39,1.02,0.39,1.41,0l5.66-5.66c0.39-0.39,0.39-1.02,0-1.41l-4.06-4.07c0.65-1.33,1.16-3.08,1.56-4.66H48c0.55,0,1-0.45,1-1\n\t\tv-6C49,21.45,48.55,21,48,21 M25,33c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S29.41,33,25,33\"\n            />\n          </svg>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`test MiddleWareApp with tabs 1`] = `\n<div>\n  <div\n    class=\"sc-jtggT lbSfdq\"\n  >\n    <div\n      class=\"sc-fONwsr jNppkf playground\"\n    >\n      <div\n        class=\"sc-daURTG dROqMf\"\n      >\n        <div\n          class=\"sc-bXGyLb dDuAEY\"\n        >\n          <div\n            class=\"sc-cmthru bfVYLy\"\n          >\n            <div\n              class=\"sc-gqPbQI SEbZC\"\n            >\n              <div\n                class=\"sc-hORach fyhdOf\"\n              />\n            </div>\n            <div\n              class=\"sc-hMFtBS gtvAeD\"\n            >\n              New Tab\n            </div>\n            <div\n              class=\"sc-gojNiO izjFJN close\"\n            >\n              <svg\n                height=\"11\"\n                stroke-width=\"7\"\n                viewBox=\"0 0 50 50\"\n                width=\"12\"\n              >\n                <title>\n                  Close Tab\n                </title>\n                <line\n                  x1=\"4\"\n                  x2=\"46\"\n                  y1=\"4\"\n                  y2=\"46\"\n                />\n                <line\n                  x1=\"46\"\n                  x2=\"4\"\n                  y1=\"4\"\n                  y2=\"46\"\n                />\n              </svg>\n            </div>\n          </div>\n          <div\n            class=\"sc-lkqHmb hrrKPQ\"\n          >\n            <svg\n              height=\"34\"\n              stroke-width=\"4\"\n              viewBox=\"0 0 50 50\"\n              width=\"34\"\n            >\n              <title>\n                Opens a New Tab\n              </title>\n              <line\n                x1=\"25\"\n                x2=\"25\"\n                y1=\"13.1\"\n                y2=\"36.9\"\n              />\n              <line\n                x1=\"36.9\"\n                x2=\"13.1\"\n                y1=\"25\"\n                y2=\"25\"\n              />\n            </svg>\n          </div>\n        </div>\n      </div>\n      <div\n        class=\"sc-VJcYb jsBJIl\"\n      >\n        <div\n          class=\"sc-ipXKqB iPMBQr graphiql-wrapper active\"\n        >\n          <div\n            class=\"sc-EHOje cIypmL\"\n          >\n            <div\n              class=\"sc-ifAKCX cEPVvT\"\n            >\n              <div\n                class=\"sc-cvbbAY kOflzg\"\n              >\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  Prettify\n                </button>\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  History\n                </button>\n                <div\n                  class=\"sc-brqgnP kOowTR\"\n                >\n                  <input\n                    class=\"sc-jWBwVP cljqcK\"\n                    value=\"https://localhost/\"\n                  />\n                  <div\n                    style=\"display:flex;flex-direction:row;align-items:center;position:absolute;left:6px\"\n                  >\n                    <div\n                      class=\"sc-jKJlTe sc-iAyFgw cVhxIQ\"\n                      title=\"Polling Schema\"\n                    >\n                      <div\n                        class=\"sc-hSdWYo vFglF\"\n                      />\n                    </div>\n                  </div>\n                </div>\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  Copy CURL\n                </button>\n              </div>\n              <div\n                class=\"sc-ibxdXY biDfcz\"\n              >\n                <div\n                  class=\"sc-cMhqgX dUUizb\"\n                >\n                  <div\n                    class=\"sc-ifAKCX cEPVvT\"\n                  >\n                    <div\n                      class=\"sc-bZQynM imcoIY\"\n                    />\n                  </div>\n                  <div\n                    class=\"sc-eTuwsz sc-hXRMBi bihGhC\"\n                    height=\"200\"\n                  >\n                    <div\n                      class=\"sc-gwVKww jmsfqV sc-epnACN cATAit\"\n                    >\n                      <span\n                        class=\"sc-iQNlJl bpxsnM\"\n                      >\n                        Query Variables\n                      </span>\n                      <span\n                        class=\"sc-iQNlJl gArUSm\"\n                      >\n                        HTTP Headers \n                      </span>\n                    </div>\n                    <div\n                      class=\"sc-gPEVay ihtVGC\"\n                    />\n                  </div>\n                  <div\n                    class=\"sc-iQKALj sc-bwCtUz hLmxzl\"\n                  />\n                </div>\n                <div\n                  class=\"sc-RefOD iqiKGG\"\n                >\n                  <div\n                    class=\"sc-iQKALj sc-hrWEMg fHZBGP\"\n                  />\n                  <div\n                    class=\"sc-bdVaJa bFURGJ\"\n                  >\n                    <div\n                      class=\"sc-bwzfXH kJytub\"\n                      title=\"Execute Query (Ctrl-Enter)\"\n                    >\n                      <svg\n                        height=\"35\"\n                        viewBox=\"3.5,4.5,24,24\"\n                        width=\"35\"\n                      >\n                        <path\n                          d=\"M 11 9 L 24 16 L 11 23 z\"\n                        />\n                      </svg>\n                    </div>\n                  </div>\n                  <div\n                    class=\"sc-csuQGl jqqEqQ\"\n                  >\n                    <div\n                      class=\"sc-Rmtcm izeTTo\"\n                    >\n                      <div\n                        class=\"sc-jhAzac czBwBS\"\n                      >\n                        <div\n                          class=\"sc-gipzik jWCgLV\"\n                        />\n                      </div>\n                    </div>\n                  </div>\n                  <div\n                    class=\"sc-iuJeZd PkTkM\"\n                  >\n                    Press the Play Button to get a response here\n                  </div>\n                  <div\n                    class=\"sc-eTuwsz sc-bsbRJL jvVfGJ\"\n                    height=\"300\"\n                  >\n                    <div\n                      class=\"sc-gwVKww jmsfqV sc-hZSUBg hQHJtw\"\n                    >\n                      <span\n                        class=\"sc-iQNlJl bpxsnM\"\n                      >\n                        Tracing\n                      </span>\n                    </div>\n                    <div\n                      class=\"sc-caSCKo jXBojK\"\n                    >\n                      <div\n                        class=\"sc-kjoXOD bJwwoz\"\n                      >\n                        This GraphQL server doesn’t support tracing. See the following page for instructions:\n                        <br />\n                        https://github.com/apollographql/apollo-tracing\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n            <div\n              class=\"sc-kgAjT hyCFBj\"\n              style=\"width:0\"\n            >\n              <div\n                class=\"sc-hmzhuo ckIQDP\"\n              >\n                <div\n                  class=\"sc-TOsTZ iRmVrA\"\n                >\n                  Docs\n                </div>\n                <div\n                  class=\"sc-TOsTZ FJeHV\"\n                >\n                  Schema\n                </div>\n              </div>\n              <div\n                class=\"sc-ksYbfQ jvrrBm\"\n              />\n              <div\n                class=\"sc-frDJqD esEVLt\"\n              />\n              <div\n                class=\"sc-cJSrbW hLWfWH\"\n              />\n            </div>\n          </div>\n        </div>\n      </div>\n      <div\n        class=\"sc-dTdPqK emFIyf\"\n      >\n        <div\n          class=\"sc-itybZL hAFQvt\"\n        >\n          <svg\n            height=\"23\"\n            viewBox=\"0 0 50 50\"\n            width=\"23\"\n          >\n            <title>\n              Settings\n            </title>\n            <path\n              d=\"M48,21h-5.71c-0.4-1.58-0.91-3.33-1.56-4.66l4.06-4.06c0.19-0.19,0.29-0.44,0.29-0.71\n\t\tc0-0.27-0.11-0.52-0.29-0.71L39.14,5.2c-0.39-0.39-1.02-0.39-1.41,0l-4.06,4.06C32.33,8.62,30.58,8.11,29,7.71V2c0-0.55-0.45-1-1-1\n\t\th-6c-0.55,0-1,0.45-1,1v5.71c-1.58,0.4-3.33,0.91-4.66,1.55L12.27,5.2c-0.39-0.39-1.02-0.39-1.41,0L5.2,10.86\n\t\tc-0.39,0.39-0.39,1.02,0,1.41l4.07,4.07C8.62,17.66,8.11,19.42,7.71,21H2c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h5.71\n\t\tc0.4,1.58,0.91,3.34,1.56,4.66L5.2,37.73c-0.19,0.19-0.29,0.44-0.29,0.71s0.11,0.52,0.29,0.71l5.66,5.66c0.38,0.38,1.04,0.38,1.41,0\n\t\tl4.07-4.06c1.32,0.65,3.08,1.15,4.66,1.56V48c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-5.71c1.58-0.4,3.34-0.91,4.66-1.56l4.07,4.06\n\t\tc0.39,0.39,1.02,0.39,1.41,0l5.66-5.66c0.39-0.39,0.39-1.02,0-1.41l-4.06-4.07c0.65-1.33,1.16-3.08,1.56-4.66H48c0.55,0,1-0.45,1-1\n\t\tv-6C49,21.45,48.55,21,48,21 M25,33c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S29.41,33,25,33\"\n            />\n          </svg>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n\nexports[`test MiddleWareApp without tabs 1`] = `\n<div>\n  <div\n    class=\"sc-jtggT lbSfdq\"\n  >\n    <div\n      class=\"sc-fONwsr jNppkf playground\"\n    >\n      <div\n        class=\"sc-daURTG dROqMf\"\n      >\n        <div\n          class=\"sc-bXGyLb dDuAEY\"\n        >\n          <div\n            class=\"sc-cmthru bfVYLy\"\n          >\n            <div\n              class=\"sc-gqPbQI SEbZC\"\n            >\n              <div\n                class=\"sc-hORach fyhdOf\"\n              />\n            </div>\n            <div\n              class=\"sc-hMFtBS gtvAeD\"\n            >\n              New Tab\n            </div>\n            <div\n              class=\"sc-gojNiO izjFJN close\"\n            >\n              <svg\n                height=\"11\"\n                stroke-width=\"7\"\n                viewBox=\"0 0 50 50\"\n                width=\"12\"\n              >\n                <title>\n                  Close Tab\n                </title>\n                <line\n                  x1=\"4\"\n                  x2=\"46\"\n                  y1=\"4\"\n                  y2=\"46\"\n                />\n                <line\n                  x1=\"46\"\n                  x2=\"4\"\n                  y1=\"4\"\n                  y2=\"46\"\n                />\n              </svg>\n            </div>\n          </div>\n          <div\n            class=\"sc-lkqHmb hrrKPQ\"\n          >\n            <svg\n              height=\"34\"\n              stroke-width=\"4\"\n              viewBox=\"0 0 50 50\"\n              width=\"34\"\n            >\n              <title>\n                Opens a New Tab\n              </title>\n              <line\n                x1=\"25\"\n                x2=\"25\"\n                y1=\"13.1\"\n                y2=\"36.9\"\n              />\n              <line\n                x1=\"36.9\"\n                x2=\"13.1\"\n                y1=\"25\"\n                y2=\"25\"\n              />\n            </svg>\n          </div>\n        </div>\n      </div>\n      <div\n        class=\"sc-VJcYb jsBJIl\"\n      >\n        <div\n          class=\"sc-ipXKqB iPMBQr graphiql-wrapper active\"\n        >\n          <div\n            class=\"sc-EHOje cIypmL\"\n          >\n            <div\n              class=\"sc-ifAKCX cEPVvT\"\n            >\n              <div\n                class=\"sc-cvbbAY kOflzg\"\n              >\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  Prettify\n                </button>\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  History\n                </button>\n                <div\n                  class=\"sc-brqgnP kOowTR\"\n                >\n                  <input\n                    class=\"sc-jWBwVP cljqcK\"\n                    value=\"https://localhost/\"\n                  />\n                  <div\n                    style=\"display:flex;flex-direction:row;align-items:center;position:absolute;left:6px\"\n                  >\n                    <div\n                      class=\"sc-jKJlTe sc-iAyFgw cVhxIQ\"\n                      title=\"Polling Schema\"\n                    >\n                      <div\n                        class=\"sc-hSdWYo vFglF\"\n                      />\n                    </div>\n                  </div>\n                </div>\n                <button\n                  class=\"sc-eHgmQL dvmgwq\"\n                >\n                  Copy CURL\n                </button>\n              </div>\n              <div\n                class=\"sc-ibxdXY biDfcz\"\n              >\n                <div\n                  class=\"sc-cMhqgX dUUizb\"\n                >\n                  <div\n                    class=\"sc-ifAKCX cEPVvT\"\n                  >\n                    <div\n                      class=\"sc-bZQynM imcoIY\"\n                    />\n                  </div>\n                  <div\n                    class=\"sc-eTuwsz sc-hXRMBi bihGhC\"\n                    height=\"200\"\n                  >\n                    <div\n                      class=\"sc-gwVKww jmsfqV sc-epnACN cATAit\"\n                    >\n                      <span\n                        class=\"sc-iQNlJl bpxsnM\"\n                      >\n                        Query Variables\n                      </span>\n                      <span\n                        class=\"sc-iQNlJl gArUSm\"\n                      >\n                        HTTP Headers \n                      </span>\n                    </div>\n                    <div\n                      class=\"sc-gPEVay ihtVGC\"\n                    />\n                  </div>\n                  <div\n                    class=\"sc-iQKALj sc-bwCtUz hLmxzl\"\n                  />\n                </div>\n                <div\n                  class=\"sc-RefOD iqiKGG\"\n                >\n                  <div\n                    class=\"sc-iQKALj sc-hrWEMg fHZBGP\"\n                  />\n                  <div\n                    class=\"sc-bdVaJa bFURGJ\"\n                  >\n                    <div\n                      class=\"sc-bwzfXH kJytub\"\n                      title=\"Execute Query (Ctrl-Enter)\"\n                    >\n                      <svg\n                        height=\"35\"\n                        viewBox=\"3.5,4.5,24,24\"\n                        width=\"35\"\n                      >\n                        <path\n                          d=\"M 11 9 L 24 16 L 11 23 z\"\n                        />\n                      </svg>\n                    </div>\n                  </div>\n                  <div\n                    class=\"sc-csuQGl jqqEqQ\"\n                  >\n                    <div\n                      class=\"sc-Rmtcm izeTTo\"\n                    >\n                      <div\n                        class=\"sc-jhAzac czBwBS\"\n                      >\n                        <div\n                          class=\"sc-gipzik jWCgLV\"\n                        />\n                      </div>\n                    </div>\n                  </div>\n                  <div\n                    class=\"sc-iuJeZd PkTkM\"\n                  >\n                    Press the Play Button to get a response here\n                  </div>\n                  <div\n                    class=\"sc-eTuwsz sc-bsbRJL jvVfGJ\"\n                    height=\"300\"\n                  >\n                    <div\n                      class=\"sc-gwVKww jmsfqV sc-hZSUBg hQHJtw\"\n                    >\n                      <span\n                        class=\"sc-iQNlJl bpxsnM\"\n                      >\n                        Tracing\n                      </span>\n                    </div>\n                    <div\n                      class=\"sc-caSCKo jXBojK\"\n                    >\n                      <div\n                        class=\"sc-kjoXOD bJwwoz\"\n                      >\n                        This GraphQL server doesn’t support tracing. See the following page for instructions:\n                        <br />\n                        https://github.com/apollographql/apollo-tracing\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n            <div\n              class=\"sc-kgAjT hyCFBj\"\n              style=\"width:0\"\n            >\n              <div\n                class=\"sc-hmzhuo ckIQDP\"\n              >\n                <div\n                  class=\"sc-TOsTZ iRmVrA\"\n                >\n                  Docs\n                </div>\n                <div\n                  class=\"sc-TOsTZ FJeHV\"\n                >\n                  Schema\n                </div>\n              </div>\n              <div\n                class=\"sc-ksYbfQ jvrrBm\"\n              />\n              <div\n                class=\"sc-frDJqD esEVLt\"\n              />\n              <div\n                class=\"sc-cJSrbW hLWfWH\"\n              />\n            </div>\n          </div>\n        </div>\n      </div>\n      <div\n        class=\"sc-dTdPqK emFIyf\"\n      >\n        <div\n          class=\"sc-itybZL hAFQvt\"\n        >\n          <svg\n            height=\"23\"\n            viewBox=\"0 0 50 50\"\n            width=\"23\"\n          >\n            <title>\n              Settings\n            </title>\n            <path\n              d=\"M48,21h-5.71c-0.4-1.58-0.91-3.33-1.56-4.66l4.06-4.06c0.19-0.19,0.29-0.44,0.29-0.71\n\t\tc0-0.27-0.11-0.52-0.29-0.71L39.14,5.2c-0.39-0.39-1.02-0.39-1.41,0l-4.06,4.06C32.33,8.62,30.58,8.11,29,7.71V2c0-0.55-0.45-1-1-1\n\t\th-6c-0.55,0-1,0.45-1,1v5.71c-1.58,0.4-3.33,0.91-4.66,1.55L12.27,5.2c-0.39-0.39-1.02-0.39-1.41,0L5.2,10.86\n\t\tc-0.39,0.39-0.39,1.02,0,1.41l4.07,4.07C8.62,17.66,8.11,19.42,7.71,21H2c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h5.71\n\t\tc0.4,1.58,0.91,3.34,1.56,4.66L5.2,37.73c-0.19,0.19-0.29,0.44-0.29,0.71s0.11,0.52,0.29,0.71l5.66,5.66c0.38,0.38,1.04,0.38,1.41,0\n\t\tl4.07-4.06c1.32,0.65,3.08,1.15,4.66,1.56V48c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-5.71c1.58-0.4,3.34-0.91,4.66-1.56l4.07,4.06\n\t\tc0.39,0.39,1.02,0.39,1.41,0l5.66-5.66c0.39-0.39,0.39-1.02,0-1.41l-4.06-4.07c0.65-1.33,1.16-3.08,1.56-4.66H48c0.55,0,1-0.45,1-1\n\t\tv-6C49,21.45,48.55,21,48,21 M25,33c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S29.41,33,25,33\"\n            />\n          </svg>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n`;\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Button.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../styled'\nimport { FullArrowRightIcon } from './Icons'\n\nexport interface Props {\n  purple?: boolean\n  hideArrow?: boolean\n  children?: any\n  onClick?: (e?: any) => void\n}\n\nexport const Button = ({ purple, hideArrow, children, onClick }: Props) => (\n  <ButtonBox purple={purple} onClick={onClick}>\n    {children ? children : 'Learn more'}\n    {!hideArrow && <FullArrowRightIcon color={'red'} width={14} height={11} />}\n  </ButtonBox>\n)\n\ninterface ButtonProps {\n  purple?: boolean\n}\n\nexport const ButtonBox = styled<ButtonProps, 'div'>('div')`\n  display: flex;\n  align-items: center;\n\n  padding: 6px 16px;\n  border-radius: 2px;\n  background: ${p => (p.purple ? 'rgb(218, 27, 127)' : '#2a7ed2')};\n  color: ${p => p.theme.colours.white};\n  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2);\n  text-transform: uppercase;\n  font-weight: 600;\n  font-size: 14px;\n  letter-spacing: 1px;\n  white-space: nowrap;\n\n  transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;\n  cursor: pointer;\n  &:hover {\n    background: ${p => (p.purple ? 'rgb(164, 3, 111)' : '#3f8ad7')};\n    transform: ${p =>\n      p.purple ? 'translate3D(0, 0, 0)' : 'translate3D(0, -1px, 0)'};\n    svg {\n      animation: move 1s ease infinite;\n    }\n  }\n\n  svg {\n    margin-left: 10px;\n    fill: ${p => p.theme.colours.white};\n  }\n\n  @keyframes move {\n    0% {\n      transform: translate3D(0, 0, 0);\n    }\n\n    50% {\n      transform: translate3D(3px, 0, 0);\n    }\n\n    100% {\n      transform: translate3D(0, 0, 0);\n    }\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Copy.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../styled'\nimport * as CopyToClipboard from 'react-copy-to-clipboard'\n\nexport interface Props {\n  text: string\n  color?: string\n  className?: string\n}\n\nexport interface State {\n  copied: boolean\n}\n\nexport default class Copy extends React.Component<Props, State> {\n  private copyTimer: any\n\n  constructor(props) {\n    super(props)\n\n    this.state = {\n      copied: false,\n    }\n  }\n\n  componentWillUnmount() {\n    clearTimeout(this.copyTimer)\n  }\n\n  render() {\n    const { text, color } = this.props\n\n    return (\n      <CopyToClipboard text={text} onCopy={this.onCopy}>\n        <CopyBox>\n          {this.state.copied && <Indicator color={color}>Copied</Indicator>}\n          {this.props.children}\n        </CopyBox>\n      </CopyToClipboard>\n    )\n  }\n\n  private onCopy = () => {\n    this.setState({ copied: true } as State)\n    this.copyTimer = window.setTimeout(\n      () => this.setState({ copied: false } as State),\n      500,\n    )\n  }\n}\n\nconst CopyBox = styled.div`\n  position: relative;\n`\n\nconst Indicator = styled.div`\n  position: absolute;\n  top: -20px;\n  left: 50%;\n  transform: translate(-50%, 0);\n  animation: copying 700ms linear;\n  color: ${p => (p.color ? p.color : p.theme.colours.darkBlue30)};\n\n  @keyframes copying {\n    0% {\n      opacity: 0;\n      transform: translate(-50%, 0);\n    }\n\n    50% {\n      opacity: 1;\n    }\n\n    100% {\n      opacity: 0;\n      transform: translate(-50%, -50px);\n    }\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/EndpointPopup.tsx",
    "content": "import * as React from 'react'\nimport * as fetch from 'isomorphic-fetch'\nimport Popup from './Popup'\nimport { throttle } from 'lodash'\nimport { Button } from './Button'\nimport { styled, css } from '../styled'\nimport { createClient } from 'graphql-ws';\n\n\n// @ts-ignore\nimport imageSource from '../assets/logo.png'\n\nexport interface Props {\n  onRequestClose: (endpoint: string) => void\n  endpoint: string\n}\n\nexport interface State {\n  endpoint: string\n  valid?: boolean\n}\n\nexport default class EndpointPopup extends React.Component<Props, State> {\n  checkEndpoint = throttle(() => {\n    if (this.state.endpoint.match(/^(https?|wss?):\\/\\/\\w+(\\.\\w+)*(:[0-9]+)?\\/?.*$/)) {\n      if (this.state.endpoint.match(/^(wss?)/)) {\n        const client = createClient({\n          url: this.state.endpoint,\n          retryAttempts:0\n        });\n        const unsubscribe = client.subscribe(\n          {\n            query: `{\n              __schema {\n                queryType {\n                  kind\n                }\n              }\n            }`,\n          },\n          {\n            next: () => {\n              this.setState({ valid: true })\n              unsubscribe()\n            },\n            error: () => {\n              this.setState({ valid: false });\n              unsubscribe()\n            },\n            complete: () =>  {},\n          },\n        );  \n        return;\n      }\n      \n      fetch(this.state.endpoint, {\n        method: 'post',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          query: `{\n        __schema {\n          queryType {\n            kind\n          }\n        }\n      }`,\n        }),\n      })\n        .then(res => {\n          this.setState({ valid: res.status < 400 })\n        })\n        .catch(err => {\n          this.setState({ valid: false })\n        })\n    }\n  }, 500) as any\n\n  constructor(props) {\n    super(props)\n    this.state = {\n      endpoint: props.endpoint,\n    }\n  }\n\n  componentDidMount() {\n    this.checkEndpoint()\n  }\n\n  render() {\n    const { valid } = this.state\n    return (\n      <Popup onRequestClose={this.close} darkBg={true}>\n        <Wrapper>\n          <LogoWrapper>\n            <Logo>\n              <img src={imageSource} alt=\"\" />\n              <Heading>GraphQL Playground</Heading>\n            </Logo>\n          </LogoWrapper>\n          <Form action=\"\" onSubmit={this.submit}>\n            <Input\n              type=\"text\"\n              placeholder=\"Enter an endpoint url...\"\n              value={this.state.endpoint}\n              onChange={this.onChangeEndpoint}\n              valid={typeof valid === 'boolean' && valid}\n              invalid={typeof valid === 'boolean' && !valid}\n              autoFocus={true}\n            />\n\n            {valid && (\n              <Button purple={true} onClick={this.close}>\n                Use Endpoint\n              </Button>\n            )}\n          </Form>\n        </Wrapper>\n      </Popup>\n    )\n  }\n\n  private onChangeEndpoint = e => {\n    this.setState({ endpoint: e.target.value }, this.checkEndpoint)\n  }\n\n  private submit = e => {\n    e.preventDefault()\n    this.close()\n  }\n\n  private close = () => {\n    if (this.state.valid) {\n      this.props.onRequestClose(this.state.endpoint)\n    }\n  }\n}\n\nconst Wrapper = styled.div`\n  box-sizing: border-box;\n`\n\nconst Form = styled.form`\n  width: 100%;\n  display: flex;\n  flex: 1 1 auto;\n\n  .button.button {\n    padding-right: ${p => p.theme.sizes.small16};\n    padding-left: ${p => p.theme.sizes.small16};\n    background: #da1b7f;\n\n    &:hover {\n      background: ${p => p.theme.colours.purple};\n    }\n  }\n`\n\ninterface InputProps {\n  valid: boolean\n  invalid: boolean\n}\n\n// prettier-ignore\nconst Input = styled<InputProps, 'input'>('input')`\n  background: ${p => p.theme.colours.white10};\n  border-radius: ${p => p.theme.sizes.smallRadius};\n  padding: ${p => `${p.theme.sizes.small16} ${p.theme.sizes.medium25}`};\n  font-weight: ${p => p.theme.sizes.fontSemiBold};\n  color: white;\n  font-size: 16px;\n  display: block;\n  width: 100%;\n  text-align: center;\n  flex: 1 1 auto;\n  display: flex;\n\n  transition: 250ms color;\n\n  ${(p: any) =>\n    p.valid ? css`\n      color: ${k => k.theme.colours.green};\n    `\n    : p.invalid ? css`\n      color: ${k => k.theme.colours.red};\n    `\n    : ``\n  }\n`\n\nconst Heading = styled.h1`\n  margin-left: 38px;\n  font-weight: 400;\n  color: ${p => p.theme.colours.white80};\n`\n\nconst LogoWrapper = styled.div`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\n\nconst Logo = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  margin-bottom: 60px;\n\n  img {\n    width: 78px;\n    height: 78px;\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/FileEditor.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../styled'\nimport { QueryEditor } from './Playground/QueryEditor'\nimport { createStructuredSelector } from 'reselect'\nimport { getFile } from '../state/sessions/selectors'\nimport { editFile } from '../state/sessions/actions'\nimport EditorWrapper, { Container } from './Playground/EditorWrapper'\nimport { connect } from 'react-redux'\n\nexport interface Props {\n  value: string\n  onChange: (value: string) => void\n}\n\nclass FileEditor extends React.Component<Props, {}> {\n  render() {\n    return (\n      <Container>\n        <Wrapper>\n          <EditorWrapper>\n            <QueryWrap>\n              <QueryEditor\n                value={this.props.value}\n                onChange={this.props.onChange}\n              />\n            </QueryWrap>\n          </EditorWrapper>\n        </Wrapper>\n      </Container>\n    )\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  value: getFile,\n})\n\nexport default connect(\n  mapStateToProps,\n  { onChange: editFile },\n)(FileEditor)\n\nconst Wrapper = styled.div`\n  background: ${p => p.theme.editorColours.resultBackground};\n  position: relative;\n  .variable-editor {\n    height: 100% !important;\n  }\n  .CodeMirror {\n    background: none !important;\n    .CodeMirror-code {\n      color: rgba(255, 255, 255, 0.7);\n    }\n    .cm-atom {\n      color: rgba(42, 126, 210, 1);\n    }\n  }\n`\n\nconst QueryWrap = styled.div`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/GraphQLBinApp.tsx",
    "content": "import * as React from 'react'\nimport { Provider, connect } from 'react-redux'\nimport createStore from '../state/createStore'\nimport 'isomorphic-fetch'\nimport EndpointPopup from './EndpointPopup'\nimport { styled, ThemeProvider, theme as styledTheme } from '../styled'\nimport { Store } from 'redux'\nimport PlaygroundWrapper from './PlaygroundWrapper'\nimport { injectState } from '../state/workspace/actions'\n\nexport const store: Store<any> = createStore()\n\nfunction getParameterByName(name: string): string {\n  const url = window.location.href\n  name = name.replace(/[\\[\\]]/g, '\\\\$&')\n  const regexa = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')\n  const results = regexa.exec(url)\n  if (!results || !results[2]) {\n    return ''\n  }\n  return decodeURIComponent(results[2].replace(/\\+/g, ' '))\n}\n\nexport interface Props {\n  endpoint?: string\n  subscriptionEndpoint?: string\n  history?: any\n  match?: any\n  headers?: any\n}\n\nexport interface State {\n  endpoint?: string\n  subscriptionEndpoint?: string\n  shareUrl?: string\n  loading: boolean\n  headers: any\n}\n\nexport interface ReduxProps {\n  injectState: (state: any) => void\n}\n\nclass GraphQLBinApp extends React.Component<Props & ReduxProps, State> {\n  constructor(props: Props & ReduxProps) {\n    super(props)\n\n    this.state = {\n      endpoint: props.endpoint,\n      subscriptionEndpoint: props.subscriptionEndpoint,\n      loading: false,\n      headers: props.headers || {},\n    }\n  }\n\n  UNSAFE_componentWillMount() {\n    if (this.props.match.params.id) {\n      if (this.props.match.params.id === 'new') {\n        return\n      }\n      this.setState({ loading: true })\n\n      // DOM side-effect:\n      // #loading-wrapper is a hardcoded DOM element in the HTML entrypoint\n      const loadingWrapper = document.getElementById('loading-wrapper')\n\n      if (loadingWrapper) {\n        loadingWrapper.classList.remove('fadeOut')\n      }\n\n      setTimeout(() => {\n        if (loadingWrapper) {\n          loadingWrapper.remove()\n        }\n      }, 1000)\n\n      fetch('https://api.graphqlbin.com', {\n        method: 'post',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify({\n          query: `\n            query ($id: String!) {\n              session(id: $id) {\n                data\n                endpoint\n              }\n            }\n          `,\n          variables: { id: this.props.match.params.id },\n        }),\n      })\n        .then(res => res.json())\n        .then(res => {\n          if (loadingWrapper) {\n            loadingWrapper.classList.add('fadeOut')\n          }\n\n          if (!res.data || res.data.session === null) {\n            location.href = `${location.origin}/v2/new`\n          }\n          const state = JSON.parse(res.data.session.data)\n          this.props.injectState(state)\n          this.setState({\n            endpoint: res.data.session.endpoint,\n            loading: false,\n          })\n        })\n    }\n  }\n\n  render() {\n    let { endpoint, subscriptionEndpoint } = this.state\n    // If no  endpoint passed tries to get one from url\n    if (!endpoint) {\n      endpoint = getParameterByName('endpoint')\n    }\n    if (!subscriptionEndpoint) {\n      subscriptionEndpoint = getParameterByName('subscription')\n    }\n\n    return (\n      <Wrapper>\n        {this.state.loading ? null : !this.state.endpoint ||\n        this.state.endpoint.length === 0 ? (\n          <ThemeProvider theme={styledTheme}>\n            <EndpointPopup\n              onRequestClose={this.handleChangeEndpoint}\n              endpoint={this.state.endpoint || ''}\n            />\n          </ThemeProvider>\n        ) : (\n          <PlaygroundWrapper\n            endpoint={endpoint}\n            headers={this.state.headers}\n            subscriptionEndpoint={subscriptionEndpoint}\n          />\n        )}\n      </Wrapper>\n    )\n  }\n\n  private handleChangeEndpoint = endpoint => {\n    this.setState({ endpoint })\n    localStorage.setItem('last-endpoint', endpoint)\n  }\n}\n\nconst ConnectedGraphQLBinApp = connect(\n  null,\n  { injectState },\n)(GraphQLBinApp)\n\n// tslint:disable\nexport default class GraphQLBinAppHOC extends React.Component<Props> {\n  render() {\n    return (\n      <Provider store={store}>\n        <ConnectedGraphQLBinApp {...this.props} />\n      </Provider>\n    )\n  }\n}\n\nconst Wrapper = styled.div`\n  width: 100%;\n  height: 100%;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup/HistoryChooser.tsx",
    "content": "import * as React from 'react'\nimport { HistoryFilter } from '../../types'\nimport { styled, withTheme, ThemeInterface } from '../../styled'\nimport { Star, History } from '../Icons'\n\ninterface Props {\n  theme: ThemeInterface\n  selectedFilter: HistoryFilter\n  onSelectFilter: (filter: any) => void\n}\n\n/* tslint:disable */\n\nconst HistoryChooser = ({ selectedFilter, onSelectFilter, theme }: Props) => (\n  <Chooser>\n    <Filter\n      active={selectedFilter === 'HISTORY'}\n      onClick={() => onSelectFilter('HISTORY')}\n    >\n      <History\n        color={\n          selectedFilter === 'HISTORY'\n            ? theme.colours.white\n            : theme.colours.black30\n        }\n        strokeWidth={3}\n        width={25}\n        height={25}\n      />\n      <FilterText>History</FilterText>\n    </Filter>\n    <Filter\n      active={selectedFilter === 'STARRED'}\n      onClick={() => onSelectFilter('STARRED')}\n    >\n      <Star\n        color={\n          selectedFilter === 'STARRED'\n            ? theme.colours.white\n            : theme.colours.black30\n        }\n        width={16}\n        height={16}\n      />\n      <FilterText>Starred</FilterText>\n    </Filter>\n  </Chooser>\n)\n\nexport default withTheme(HistoryChooser)\n\nconst Chooser = styled.div`\n  display: flex;\n  align-items: center;\n`\n\ninterface FilterProps {\n  active: boolean\n}\n\nconst Filter = styled<FilterProps, 'div'>('div')`\n  box-sizing: content-box;\n  height: 24px;\n  z-index: ${p => (p.active ? 2 : 0)};\n  display: flex;\n  align-items: center;\n  margin: 0 -2px;\n  padding: ${p => (p.active ? '7px 9px 8px 9px' : '5px 13px 6px 13px')};\n  background: ${p =>\n    p.active ? p.theme.colours.green : p.theme.colours.black07};\n\n  color: ${p => (p.active ? p.theme.colours.white : p.theme.colours.black30)};\n  font-size: 14px;\n  font-weight: 600;\n  text-transform: uppercase;\n  border-radius: 2px;\n  cursor: pointer;\n`\n\nconst FilterText = styled.p`\n  margin-left: 6px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup/HistoryHeader.tsx",
    "content": "import * as React from 'react'\nimport HistoryChooser from './HistoryChooser'\nimport { HistoryFilter } from '../../types'\nimport { styled } from '../../styled'\nimport SearchBox from '../Playground/DocExplorer/SearchBox'\n\nexport interface Props {\n  selectedFilter: HistoryFilter\n  onSelectFilter: (filter: any) => void\n  onSearch: (value: string) => void\n}\n\nexport default (props: Props) => (\n  <HistoryHeader>\n    <HistoryChooser\n      onSelectFilter={props.onSelectFilter}\n      selectedFilter={props.selectedFilter}\n    />\n    <SearchBox\n      placeholder=\"Search the history...\"\n      onSearch={props.onSearch}\n      clean={true}\n    />\n  </HistoryHeader>\n)\n\nconst HistoryHeader = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  padding: 16px;\n  background: ${p => p.theme.colours.black02};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup/HistoryItems.tsx",
    "content": "import * as React from 'react'\nimport { Session } from '../../state/sessions/reducers'\nimport { OrderedMap } from 'immutable'\nimport { Star } from '../Icons'\nimport { styled, withTheme, ThemeInterface } from '../../styled'\n\nexport interface Props {\n  items: OrderedMap<string, Session>\n  selectedItemIndex: string\n  onItemSelect: (index: string) => void\n  onItemStarToggled: (sessionId: string) => void\n  searchTerm: string\n  theme: ThemeInterface\n}\n\n/* tslint:disable */\nexport default withTheme(\n  ({\n    items,\n    onItemSelect,\n    selectedItemIndex,\n    onItemStarToggled,\n    theme,\n  }: Props) => (\n    <HistoryItems>\n      {items\n        .map((item, index) => (\n          <HistoryItem\n            key={item.id}\n            active={selectedItemIndex === index}\n            onClick={() => onItemSelect(index)}\n          >\n            <OperationSide>\n              <Star\n                onClick={() => onItemStarToggled(item.id)}\n                stroke={!item.starred ? 'rgb(221,171,0)' : undefined}\n                fill={item.starred ? 'rgb(221,171,0)' : undefined}\n                strokeWidth={0.5}\n                width={25}\n                height={25}\n              />\n              <Operation>\n                <OperationText>\n                  {item.operationName ||\n                    item.queryTypes.firstOperationName ||\n                    'New Session'}\n                </OperationText>\n                {item.queryTypes.query && <QueryIcon>Q</QueryIcon>}\n                {item.queryTypes.mutation && <MutationIcon>M</MutationIcon>}\n                {item.queryTypes.subscription && (\n                  <SubscriptionIcon>S</SubscriptionIcon>\n                )}\n              </Operation>\n            </OperationSide>\n            <OperationSide>\n              {item.date && (\n                <Time>\n                  {typeof item.date.getMonth === 'function' &&\n                    item.date.getMonth() + 1}/{item.date.getDate()}/{item.date\n                    .getFullYear()\n                    .toString()\n                    .slice(2, 4)}\n                </Time>\n              )}\n            </OperationSide>\n          </HistoryItem>\n        ))\n        .toArray()\n        .map(x => x[1])}\n    </HistoryItems>\n  ),\n)\n\nconst HistoryItems = styled.div`\n  overflow-y: scroll;\n  max-height: calc(100vh - 121px);\n`\n\ninterface ItemProps {\n  active: boolean\n}\n\nconst HistoryItem = styled<ItemProps, 'div'>('div')`\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 25px 20px;\n  cursor: pointer;\n  border-bottom: 1px solid;\n  border-color: ${p => p.theme.colours.black10};\n  background: ${p =>\n    p.active ? p.theme.colours.black04 : p.theme.colours.white};\n`\n\nconst Operation = styled.div`\n  display: flex;\n  align-items: center;\n  margin-left: 20px;\n`\n\nconst OperationSide = styled.div`\n  display: flex;\n  align-items: center;\n`\n\nconst OperationText = styled.p`\n  font-weight: 300;\n  font-size: 20px;\n  margin-right: 16px;\n`\n\nconst OperationIcon = styled.div`\n  height: 21px;\n  width: 21px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  margin-right: 4px;\n  border-radius: 2px;\n  font-weight: 700;\n  font-size: 12px;\n  color: ${p => p.theme.colours.white};\n`\n\nconst QueryIcon = styled(OperationIcon)`\n  background: ${p => p.theme.colours.blue};\n`\n\nconst MutationIcon = styled(OperationIcon)`\n  background: ${p => p.theme.colours.orange};\n`\n\nconst SubscriptionIcon = styled(OperationIcon)`\n  background: ${p => p.theme.colours.purple};\n`\n\nconst Time = styled.time`\n  color: ${p => p.theme.colours.black40};\n  font-size: 14px;\n  margin-left: 16px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup.tsx",
    "content": "import * as React from 'react'\nimport * as Modal from 'react-modal'\nimport HistoryHeader from './HistoryPopup/HistoryHeader'\nimport { HistoryFilter } from '../types'\nimport HistoryItems from './HistoryPopup/HistoryItems'\nimport { modalStyle } from '../constants'\nimport { QueryEditor } from './Playground/QueryEditor'\nimport { styled } from '../styled'\nimport { connect } from 'react-redux'\nimport { createStructuredSelector } from 'reselect'\nimport { getHistory } from '../state/history/selectors'\nimport { getHistoryOpen } from '../state/general/selectors'\nimport { closeHistory, openHistory } from '../state/general/actions'\nimport { duplicateSession } from '../state/sessions/actions'\nimport { toggleHistoryItemStarring } from '../state/history/actions'\nimport { Session } from '../state/sessions/reducers'\nimport { OrderedMap } from 'immutable'\nimport { Container } from './Playground/EditorWrapper'\nimport { ArrowRight } from './Icons'\n\nexport interface ReduxProps {\n  isOpen: boolean\n  closeHistory: () => void\n  items: OrderedMap<string, Session>\n  toggleHistoryItemStarring: (sessionId: string) => void\n  duplicateSession: (session: Session) => void\n}\n\nexport interface State {\n  selectedFilter: HistoryFilter\n  selectedItemIndex: string\n  searchTerm: string\n}\n\nclass HistoryPopup extends React.Component<ReduxProps, State> {\n  constructor(props: ReduxProps) {\n    super(props)\n    const selectedItemIndex: any = props.items.keySeq().first() || ''\n    this.state = {\n      selectedFilter: 'HISTORY',\n      selectedItemIndex,\n      searchTerm: '',\n    }\n  }\n  render() {\n    const { searchTerm, selectedFilter } = this.state\n    const items = this.props.items.filter(item => {\n      return selectedFilter === 'STARRED'\n        ? item.starred\n        : true &&\n            (searchTerm && searchTerm.length > 0\n              ? item.query.toLowerCase().includes(searchTerm.toLowerCase())\n              : true)\n    })\n\n    let selectedItem = this.props.items.get(\n      this.state.selectedItemIndex!,\n    ) as any\n    selectedItem =\n      selectedItem && selectedItem.toJS ? selectedItem.toJS() : undefined\n\n    return (\n      <Modal\n        isOpen={this.props.isOpen}\n        onRequestClose={this.props.closeHistory}\n        contentLabel=\"GraphiQL Session History\"\n        style={modalStyle}\n        ariaHideApp={false}\n      >\n        <Wrapper>\n          <Left>\n            <HistoryHeader\n              onSelectFilter={this.handleSelectFilter}\n              selectedFilter={this.state.selectedFilter}\n              onSearch={this.handleSearch}\n            />\n            <HistoryItems\n              items={items}\n              selectedItemIndex={this.state.selectedItemIndex}\n              searchTerm={this.state.searchTerm}\n              onItemSelect={this.handleItemSelect}\n              onItemStarToggled={this.props.toggleHistoryItemStarring}\n            />\n          </Left>\n          {Boolean(selectedItem) ? (\n            <Right>\n              <RightHeader>\n                <View />\n                <Use onClick={this.handleClickUse}>\n                  <UseText>Use</UseText>\n                  <ArrowRight color=\"white\" width={13} height={13} />\n                </Use>\n              </RightHeader>\n              <Big>\n                <GraphiqlWrapper>\n                  <Container>\n                    <QueryWrap>\n                      <QueryEditor value={selectedItem.query} />\n                    </QueryWrap>\n                  </Container>\n                </GraphiqlWrapper>\n              </Big>\n            </Right>\n          ) : (\n            <Right>\n              <RightEmpty>\n                <RightEmptyText>No History yet</RightEmptyText>\n              </RightEmpty>\n            </Right>\n          )}\n        </Wrapper>\n      </Modal>\n    )\n  }\n\n  private handleClickUse = () => {\n    const { items } = this.props\n    const selectedItem = items.get(this.state.selectedItemIndex)!\n    this.props.duplicateSession(selectedItem)\n    this.props.closeHistory()\n  }\n\n  private handleItemSelect = (index: string) => {\n    this.setState({ selectedItemIndex: index } as State)\n  }\n\n  private handleSelectFilter = (filter: HistoryFilter) => {\n    this.setState({ selectedFilter: filter } as State)\n  }\n\n  private handleSearch = (term: string) => {\n    this.setState({ searchTerm: term } as State)\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  items: getHistory,\n  isOpen: getHistoryOpen,\n})\n\nexport default connect(\n  mapStateToProps,\n  {\n    closeHistory,\n    openHistory,\n    duplicateSession,\n    toggleHistoryItemStarring,\n  },\n)(HistoryPopup)\n\nconst Wrapper = styled.div`\n  display: flex;\n  min-height: 500px;\n`\n\nconst Left = styled.div`\n  flex: 1;\n\n  background: white;\n`\n\nconst Right = styled.div`\n  flex: 0 0 464px;\n  z-index: 2;\n`\n\nconst RightHeader = styled.div`\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n\n  padding-left: ${p => p.theme.sizes.medium25};\n  padding-right: ${p => p.theme.sizes.medium25};\n  padding-top: 20px;\n  padding-bottom: 20px;\n\n  background: ${p => p.theme.editorColours.resultBackground};\n`\n\nconst RightEmpty = styled.div`\n  height: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n\n  background: ${p => p.theme.editorColours.resultBackground};\n`\n\nconst RightEmptyText = styled.div`\n  font-size: 16px;\n  color: ${p => p.theme.editorColours.text};\n`\n\nconst View = styled.div`\n  font-size: ${p => p.theme.sizes.fontSmall};\n  font-weight: ${p => p.theme.sizes.fontSemiBold};\n  text-transform: uppercase;\n  color: rgba(255, 255, 255, 0.4);\n`\n\nconst Use = styled.div`\n  display: flex;\n  align-items: center;\n\n  padding-top: ${p => p.theme.sizes.small10};\n  padding-bottom: ${p => p.theme.sizes.small10};\n  padding-left: ${p => p.theme.sizes.small16};\n  padding-right: ${p => p.theme.sizes.small16};\n\n  font-size: ${p => p.theme.sizes.fontSmall};\n  font-weight: ${p => p.theme.sizes.fontSemiBold};\n\n  border-radius: ${p => p.theme.sizes.smallRadius};\n  background: ${p => p.theme.colours.green};\n  cursor: pointer;\n`\n\nconst UseText = styled.div`\n  margin-right: ${p => p.theme.sizes.small6};\n  color: white;\n`\n\nconst Big = styled.div`\n  height: calc(100% - 81px);\n  display: flex;\n  flex: 1 1 auto;\n`\n\nconst GraphiqlWrapper = styled(Big)`\n  width: 100%;\n  height: 100%;\n  position: relative;\n  display: flex;\n  flex: 1 1 auto;\n`\n\nconst QueryWrap = styled.div`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Icons/index.tsx",
    "content": "import * as React from 'react'\n\ninterface IProps {\n  title?: string\n  color?: string\n  width?: number\n  height?: number\n  stroke?: string\n  fill?: string\n  strokeWidth?: number\n  className?: string\n  children?: any\n  viewBox?: string\n  y?: string\n  x?: string\n  onClick?: () => void\n}\n\nconst Svg = ({ title, children, ...props }: IProps) => (\n  <svg {...props}>\n    {title ? <title>{title}</title> : undefined}\n    {children}\n  </svg>\n)\n\nexport const AddIcon = (props: IProps) => (\n  <Svg {...props} viewBox=\"0 0 50 50\">\n    <line x1=\"25\" y1=\"13.1\" x2=\"25\" y2=\"36.9\" />\n    <line x1=\"36.9\" y1=\"25\" x2=\"13.1\" y2=\"25\" />\n  </Svg>\n)\n\nexport const AddFullIcon = (props: IProps) => (\n  <Svg x=\"0px\" y=\"0px\" viewBox=\"-1 3 50 50\" {...props}>\n    <line x1=\"24\" y1=\"7.27\" x2=\"24\" y2=\"48.73\" />\n    <line x1=\"44.73\" y1=\"28\" x2=\"3.27\" y2=\"28\" />\n  </Svg>\n)\n\nexport const FullArrowRightIcon = (props: IProps) => (\n  <Svg {...props} viewBox=\"0 0 14 11\">\n    <path\n      d=\"M13.32,4.97L8.99,0.64c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06l2.97,2.97H1.21\n\tC0.8,4.67,0.46,5,0.46,5.42S0.8,6.17,1.21,6.17h9.85L7.93,9.3c-0.29,0.29-0.29,0.77,0,1.06c0.15,0.15,0.34,0.22,0.53,0.22\n\ts0.38-0.07,0.53-0.22l4.33-4.33C13.61,5.74,13.61,5.26,13.32,4.97z\"\n    />\n  </Svg>\n)\n\n// export const ArrowRight = ({ width, height, color }: IProps) => (\n//   <Svg width=\"30px\" height=\"50px\" viewBox=\"0 0 30 50\" stroke={color}>\n//     <polyline points=\"5,5 25,25 5,45 \" />\n//   </Svg>\n// )\n\nexport const SettingsIcon = (props: IProps) => (\n  <Svg {...props} viewBox=\"0 0 50 50\">\n    <path\n      d=\"M48,21h-5.71c-0.4-1.58-0.91-3.33-1.56-4.66l4.06-4.06c0.19-0.19,0.29-0.44,0.29-0.71\n\t\tc0-0.27-0.11-0.52-0.29-0.71L39.14,5.2c-0.39-0.39-1.02-0.39-1.41,0l-4.06,4.06C32.33,8.62,30.58,8.11,29,7.71V2c0-0.55-0.45-1-1-1\n\t\th-6c-0.55,0-1,0.45-1,1v5.71c-1.58,0.4-3.33,0.91-4.66,1.55L12.27,5.2c-0.39-0.39-1.02-0.39-1.41,0L5.2,10.86\n\t\tc-0.39,0.39-0.39,1.02,0,1.41l4.07,4.07C8.62,17.66,8.11,19.42,7.71,21H2c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h5.71\n\t\tc0.4,1.58,0.91,3.34,1.56,4.66L5.2,37.73c-0.19,0.19-0.29,0.44-0.29,0.71s0.11,0.52,0.29,0.71l5.66,5.66c0.38,0.38,1.04,0.38,1.41,0\n\t\tl4.07-4.06c1.32,0.65,3.08,1.15,4.66,1.56V48c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-5.71c1.58-0.4,3.34-0.91,4.66-1.56l4.07,4.06\n\t\tc0.39,0.39,1.02,0.39,1.41,0l5.66-5.66c0.39-0.39,0.39-1.02,0-1.41l-4.06-4.07c0.65-1.33,1.16-3.08,1.56-4.66H48c0.55,0,1-0.45,1-1\n\t\tv-6C49,21.45,48.55,21,48,21 M25,33c-4.41,0-8-3.59-8-8s3.59-8,8-8s8,3.59,8,8S29.41,33,25,33\"\n    />\n  </Svg>\n)\n\nexport const CrossIcon = (props: IProps) => (\n  <Svg {...props} viewBox=\"0 0 50 50\">\n    <line x1=\"4\" y1=\"4\" x2=\"46\" y2=\"46\" />\n    <line x1=\"46\" y1=\"4\" x2=\"4\" y2=\"46\" />\n  </Svg>\n)\n\nexport const ArrowRight = (props: IProps) => (\n  <Svg width={14} height={11} {...props} viewBox=\"-1 -1 14 11\">\n    <path\n      d=\"M5,8.79825579 L5,-1.79402089\"\n      id=\"Stroke-3\"\n      stroke=\"#FFFFFF\"\n      strokeWidth=\"1.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      fill=\"none\"\n      transform=\"translate(5.750000, 3.502117) rotate(-90.000000) translate(-5.750000, -3.502117) \"\n    />\n    <polyline\n      id=\"Stroke-5\"\n      stroke=\"#FFFFFF\"\n      strokeWidth=\"1.5\"\n      strokeLinecap=\"round\"\n      strokeLinejoin=\"round\"\n      fill=\"none\"\n      transform=\"translate(9.868295, 4.333992) rotate(-90.000000) translate(-9.868295, -4.333992) \"\n      points=\"14.2022868 2.16699605 9.86829475 6.50098814 5.53430265 2.16699605\"\n    />\n  </Svg>\n)\n\nexport const History = (props: IProps) => (\n  <Svg {...props} viewBox=\"0 0 50 50\" fill=\"none\">\n    <polyline points=\"4.33,19.64 9.7,27.69 15.95,20.54 \" />\n    <path\n      d=\"M9.71,27.69C8.36,16.81,16.68,8.38,26.06,8.03c9.37-0.35,17.25,6.97,17.6,16.35\n\tc0.35,9.38-6.97,17.26-16.35,17.6\"\n    />\n    <polyline points=\"26.68,16.06 26.68,25.89 35.62,25.89 \" />\n  </Svg>\n)\n\nexport const Star = ({\n  height,\n  width,\n  stroke,\n  fill,\n  strokeWidth,\n  onClick,\n  ...props\n}: IProps) => (\n  <Svg\n    width={width}\n    height={height}\n    fill={fill ? fill : 'none'}\n    stroke={stroke ? stroke : 'none'}\n    strokeWidth={strokeWidth}\n    viewBox=\"118 12 16 16\"\n    onClick={onClick}\n    {...props}\n  >\n    <polygon points=\"126 24 121.297718 26.472136 122.195774 21.236068 118.391548 17.527864 123.648859 16.763932 126 12 128.351141 16.763932 133.608452 17.527864 129.804226 21.236068 130.702282 26.472136\" />\n  </Svg>\n)\n\nexport const Search = ({\n  height,\n  width,\n  strokeWidth,\n  color,\n  ...props\n}: IProps) => (\n  <Svg\n    width={width}\n    height={height}\n    viewBox=\"0 0 50 50\"\n    strokeWidth={strokeWidth}\n    stroke={color}\n    fill=\"none\"\n    {...props}\n  >\n    <circle cx=\"17.82\" cy=\"18.11\" r=\"16.21\" />\n    <line x1=\"29.28\" y1=\"29.57\" x2=\"48.21\" y2=\"48.5\" />\n  </Svg>\n)\n\nexport const ShareIcon = ({ width, height, color, ...props }: IProps) => (\n  <Svg\n    width={width}\n    height={height}\n    viewBox=\"0 0 50 50\"\n    stroke={color}\n    {...props}\n  >\n    <path d=\"M16.47 15.56c-.36 0-.65.3-.65.67v20.22c0 .37.29.67.65.67h9.06c.36 0 .65-.3.65-.67s-.29-.67-.65-.67h-8.41V16.91h1.29v.67c0 .37.29.67.65.67h10.35c.36 0 .65-.3.65-.67v-.67h1.29v6.07c0 .37.29.67.65.67.36 0 .65-.3.65-.67v-6.74a.66.66 0 0 0-.65-.67h-1.94v-1.35h3.88v8.76c0 .37.29.67.65.67.36 0 .65-.3.65-.67v-9.44a.66.66 0 0 0-.65-.67h-4.53v-.67a.66.66 0 0 0-.65-.67H27.4c-.3-1.54-1.61-2.7-3.17-2.7-1.56 0-2.87 1.16-3.17 2.7h-2.01c-.36 0-.65.3-.65.67v.67h-4.53c-.36 0-.65.3-.65.67V40.5c0 .37.29.67.65.67h11.65c.36 0 .65-.3.65-.67s-.29-.67-.65-.67h-11V14.22h3.88v1.35h-1.93zm3.24-2.69h1.94c.36 0 .65-.3.65-.67 0-1.11.87-2.02 1.94-2.02 1.07 0 1.94.91 1.94 2.02 0 .37.29.67.65.67h1.94v4.04h-9.06v-4.04z\" />\n    <path d=\"M28.71 20.96h-9.06c-.36 0-.65.3-.65.67 0 .37.29.67.65.67h9.06c.36 0 .65-.3.65-.67a.66.66 0 0 0-.65-.67M28.71 23.65h-9.06c-.36 0-.65.3-.65.67s.3.68.66.68h9.06c.36 0 .65-.3.65-.67s-.3-.68-.66-.68M28.71 26.35h-9.06c-.36 0-.65.3-.65.67s.29.67.65.67h9.06c.36 0 .65-.3.65-.67s-.29-.67-.65-.67M26.13 29.04h-6.47c-.36 0-.65.3-.65.67 0 .37.29.67.65.67h6.47c.36 0 .65-.3.65-.67-.01-.36-.3-.67-.65-.67M37.77 33.21h-6.13l1.43-1.38c.26-.25.28-.68.03-.95a.62.62 0 0 0-.91-.04l-2.63 2.54c-.13.13-.21.3-.21.49v.02c0 .2.09.38.23.5l2.6 2.56c.12.12.28.18.44.18.17 0 .34-.07.47-.21.25-.27.23-.7-.03-.95l-1.43-1.41h6.13c.36 0 .65-.3.65-.67s-.28-.68-.64-.68\" />\n  </Svg>\n)\n\nexport const Triangle = (props: IProps) => (\n  <Svg width={6} height={7} viewBox=\"40 0 6 7\" {...props}>\n    <polygon\n      stroke=\"none\"\n      fill=\"rgba(0, 0, 0, .2)\"\n      fillRule=\"evenodd\"\n      points=\"40 7 40 0 46 3.5\"\n    />\n  </Svg>\n)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/MiddlewareApp.tsx",
    "content": "import * as React from 'react'\nimport { Provider } from 'react-redux'\nimport createStore from '../state/createStore'\nimport { getSettings } from '../state/workspace/reducers'\nimport { setSettingsString } from '../state/general/actions'\nimport PlaygroundWrapper, { PlaygroundWrapperProps } from './PlaygroundWrapper'\n\nconst store = createStore()\n\nexport default class MiddlewareApp extends React.Component<\n  PlaygroundWrapperProps\n> {\n  componentDidMount() {\n    const initialSettings = getSettings(store.getState())\n    const mergedSettings = { ...initialSettings, ...this.props.settings }\n    const settingsString = JSON.stringify(mergedSettings, null, 2)\n    store.dispatch(setSettingsString(settingsString))\n  }\n  render() {\n    return (\n      <Provider store={store}>\n        <PlaygroundWrapper {...this.props} />\n      </Provider>\n    )\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Modal.tsx",
    "content": "import * as React from 'react'\nimport * as Modal from 'react-modal'\nimport { modalStyle } from '../constants'\n\nexport interface Props {\n  isOpen: boolean\n  contentLabel: string\n  onRequestClose: () => void\n  children: JSX.Element\n}\n\nconst ModalComponent = ({\n  isOpen,\n  onRequestClose,\n  contentLabel,\n  children,\n}: Props) => {\n  return (\n    <Modal\n      isOpen={isOpen}\n      onRequestClose={onRequestClose}\n      contentLabel={contentLabel}\n      style={modalStyle}\n      ariaHideApp={false}\n    >\n      {children}\n    </Modal>\n  )\n}\n\nexport default ModalComponent\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ConfigEditor.tsx",
    "content": "import * as React from 'react'\nimport EditorWrapper from './EditorWrapper'\nimport { styled } from '../../styled'\n\nexport interface Props {\n  value?: string\n  onEdit?: (value: string) => void\n  onPrettifyQuery?: () => void\n  onRunQuery?: () => void\n  editorTheme?: string\n  readOnly?: boolean\n  isYaml?: boolean\n}\n\n/**\n * The editor to edit json and yaml\n */\nexport class ConfigEditor extends React.Component<Props, {}> {\n  editor: any\n  cachedValue: any\n  node: HTMLDivElement\n  ignoreChangeEvent: boolean\n\n  constructor(props) {\n    super(props)\n\n    // Keep a cached version of the value, this cache will be updated when the\n    // editor is updated, which can later be used to protect the editor from\n    // unnecessary updates during the update lifecycle.\n    this.cachedValue = props.value || ''\n  }\n\n  componentDidMount() {\n    // Lazily require to ensure requiring GraphiQL outside of a Browser context\n    // does not produce an error.\n    const CodeMirror = require('codemirror')\n    require('codemirror/addon/hint/show-hint')\n    require('codemirror/addon/edit/matchbrackets')\n    require('codemirror/addon/edit/closebrackets')\n    require('codemirror/addon/fold/brace-fold')\n    require('codemirror/addon/fold/foldgutter')\n    require('codemirror/addon/lint/lint')\n    require('codemirror/addon/search/searchcursor')\n    require('codemirror/addon/search/jump-to-line')\n    require('codemirror/addon/dialog/dialog')\n    require('codemirror/keymap/sublime')\n    require('codemirror/mode/yaml/yaml')\n    require('codemirror-graphql/variables/hint')\n    require('codemirror-graphql/variables/lint')\n    require('codemirror-graphql/variables/mode')\n\n    this.editor = CodeMirror(this.node, {\n      value: this.props.value || '',\n      lineNumbers: true,\n      tabSize: 2,\n      mode: this.props.isYaml ? 'yaml' : 'graphql-variables',\n      theme: this.props.editorTheme || 'graphiql',\n      keyMap: 'sublime',\n      autoCloseBrackets: true,\n      matchBrackets: true,\n      showCursorWhenSelecting: true,\n      readOnly: this.props.readOnly ? 'nocursor' : false,\n      foldGutter: {\n        minFoldSize: 4,\n      },\n      gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],\n      extraKeys: {\n        'Cmd-Space': () => this.editor.showHint({ completeSingle: false }),\n        'Ctrl-Space': () => this.editor.showHint({ completeSingle: false }),\n        'Alt-Space': () => this.editor.showHint({ completeSingle: false }),\n        'Shift-Space': () => this.editor.showHint({ completeSingle: false }),\n\n        'Cmd-Enter': () => {\n          if (this.props.onRunQuery) {\n            this.props.onRunQuery()\n          }\n        },\n        'Ctrl-Enter': () => {\n          if (this.props.onRunQuery) {\n            this.props.onRunQuery()\n          }\n        },\n\n        'Shift-Ctrl-P': () => {\n          if (this.props.onPrettifyQuery) {\n            this.props.onPrettifyQuery()\n          }\n        },\n\n        // Persistent search box in Query Editor\n        'Cmd-F': 'findPersistent',\n        'Ctrl-F': 'findPersistent',\n\n        // Editor improvements\n        'Ctrl-Left': 'goSubwordLeft',\n        'Ctrl-Right': 'goSubwordRight',\n        'Alt-Left': 'goGroupLeft',\n        'Alt-Right': 'goGroupRight',\n      },\n    })\n\n    this.editor.on('change', this.onEdit)\n    this.editor.on('keyup', this.onKeyUp)\n  }\n\n  componentDidUpdate(prevProps) {\n    // Ensure the changes caused by this update are not interpretted as\n    // user-input changes which could otherwise result in an infinite\n    // event loop.\n    this.ignoreChangeEvent = true\n    if (\n      this.props.value !== prevProps.value &&\n      this.props.value !== this.cachedValue\n    ) {\n      this.cachedValue = this.props.value\n      this.editor.setValue(this.props.value)\n    }\n    this.ignoreChangeEvent = false\n  }\n\n  componentWillUnmount() {\n    this.editor.off('change', this.onEdit)\n    this.editor.off('keyup', this.onKeyUp)\n    this.editor = null\n  }\n\n  render() {\n    return (\n      <EditorWrapper>\n        <Editor ref={this.setNode} />\n      </EditorWrapper>\n    )\n  }\n\n  setNode = node => {\n    this.node = node\n  }\n\n  /**\n   * Public API for retrieving the CodeMirror instance from this\n   * React component.\n   */\n  getCodeMirror() {\n    return this.editor\n  }\n\n  /**\n   * Public API for retrieving the DOM client height for this component.\n   */\n  getClientHeight() {\n    return this.node && this.node.clientHeight\n  }\n\n  private onKeyUp = (cm, event) => {\n    const code = event.keyCode\n    if (\n      (code >= 65 && code <= 90) || // letters\n      (!event.shiftKey && code >= 48 && code <= 57) || // numbers\n      (event.shiftKey && code === 189) || // underscore\n      (event.shiftKey && code === 222) // \"\n    ) {\n      this.editor.execCommand('autocomplete')\n    }\n  }\n\n  private onEdit = () => {\n    if (!this.ignoreChangeEvent) {\n      this.cachedValue = this.editor.getValue()\n      if (this.props.onEdit) {\n        this.props.onEdit(this.cachedValue)\n      }\n    }\n  }\n}\n\nconst Editor = styled.div`\n  flex: 1;\n  height: 100%;\n  position: relative;\n  .CodeMirror-linenumbers {\n    background: ${p => p.theme.editorColours.resultBackground};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/Argument.tsx",
    "content": "import * as React from 'react'\nimport { astFromValue, print } from 'graphql'\nimport TypeLink from './TypeLink'\n\nexport interface Props {\n  arg: any\n  x: number\n  y: number\n  showDefaultValue?: boolean\n  sessionId: string\n}\n\nexport default function Argument({\n  arg,\n  showDefaultValue,\n  x,\n  y,\n}: // sessionId,\nProps) {\n  return (\n    <span>\n      <TypeLink\n        type={arg}\n        x={x}\n        y={y}\n        lastActive={false}\n        afterNode={\n          arg.defaultValue !== undefined &&\n          showDefaultValue !== false && (\n            <span>\n              {' = '}\n              <span className=\"arg-default-value\">\n                {print(astFromValue(arg.defaultValue, arg.type))}\n              </span>\n            </span>\n          )\n        }\n      />\n    </span>\n  )\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/ArgumentInline.tsx",
    "content": "import * as React from 'react'\nimport { astFromValue, print, GraphQLList, GraphQLNonNull } from 'graphql'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  arg: any\n  showDefaultValue?: boolean\n}\n\nexport default function Argument({ arg, showDefaultValue }: Props) {\n  return (\n    <ArgumentLine>\n      <span className=\"arg-name\">{arg.name}</span>\n      {': '}\n      <span className=\"type-name\">{renderType(arg.type)}</span>\n      {arg.defaultValue !== undefined &&\n        showDefaultValue !== false && (\n          <span>\n            {' = '}\n            <span className=\"arg-default-value\">\n              {print(astFromValue(arg.defaultValue, arg.type))}\n            </span>\n          </span>\n        )}\n    </ArgumentLine>\n  )\n}\n\nfunction renderType(type) {\n  if (type instanceof GraphQLNonNull) {\n    return (\n      <span>\n        {renderType(type.ofType)}\n        {'!'}\n      </span>\n    )\n  }\n  if (type instanceof GraphQLList) {\n    return (\n      <span>\n        {'['}\n        {renderType(type.ofType)}\n        {']'}\n      </span>\n    )\n  }\n  return <span>{type.name}</span>\n}\n\nconst ArgumentLine = styled.div`\n  margin-left: 16px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/ColumnDoc.tsx",
    "content": "import * as React from 'react'\nimport { columnWidth } from '../../../constants'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  children: any\n  overflow?: boolean\n  width?: number\n}\n\nconst ColumnDoc = ({\n  children,\n  overflow = true,\n  width = columnWidth,\n}: Props) => {\n  return (\n    <Column style={{ width }} verticalScroll={overflow}>\n      {children}\n    </Column>\n  )\n}\n\nexport default ColumnDoc\n\ninterface ColumnProps {\n  verticalScroll: boolean\n}\n\nconst Column = styled<ColumnProps, 'div'>('div')`\n  display: flex;\n  flex: 0 0 auto;\n  flex-flow: column;\n  padding-bottom: 20px;\n  border-right: 1px solid ${p => p.theme.colours.black10};\n  overflow-x: ${p => (p.verticalScroll ? 'hidden' : 'auto')}\n  overflow-y: ${p => (p.verticalScroll ? 'scroll' : 'auto')}\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocTypeSchema.tsx",
    "content": "import { GraphQLInterfaceType } from 'graphql'\nimport * as React from 'react'\nimport TypeLink from './TypeLink'\nimport { styled } from '../../../styled'\n\nexport interface DocTypeSchemaProps {\n  type: any\n  fields: any[]\n  interfaces: any[]\n  level: number\n  sessionId: string\n}\n\nexport default ({ type, fields, interfaces, level }: DocTypeSchemaProps) => {\n  const nonDeprecatedFields = fields.filter(data => !data.isDeprecated)\n  const deprecatedFields = fields.filter(data => data.isDeprecated)\n\n  const typeInstance =\n    type instanceof GraphQLInterfaceType ? 'interface ' : 'type'\n\n  return (\n    <DocTypeSchema>\n      <DocTypeLine>\n        <span className=\"field-name\">{typeInstance}</span>{' '}\n        <DocsTypeName>{type.name}</DocsTypeName>{' '}\n        {interfaces.length === 0 && <Brace>{`{`}</Brace>}\n      </DocTypeLine>\n      {interfaces.map((data, index) => (\n        <DocsTypeInferface\n          key={data.name}\n          type={data}\n          x={level}\n          y={index}\n          collapsable={true}\n          beforeNode={<span className=\"field-name\">implements</span>}\n          afterNode={\n            index === interfaces.length - 1 ? <Brace>{'{'}</Brace> : null\n          }\n          lastActive={false}\n        />\n      ))}\n      {nonDeprecatedFields.map((data, index) => (\n        <TypeLink\n          key={data.name}\n          type={data}\n          x={level}\n          y={index + interfaces.length}\n          collapsable={true}\n          lastActive={false}\n        />\n      ))}\n      {deprecatedFields.length > 0 && <br />}\n      {deprecatedFields.map((data, index) => (\n        <div key={data.name}>\n          <DocsValueComment>\n            # Deprecated: {data.deprecationReason}\n          </DocsValueComment>\n          <TypeLink\n            type={data}\n            x={level}\n            y={index + nonDeprecatedFields.length + interfaces.length}\n            collapsable={true}\n            lastActive={false}\n          />\n        </div>\n      ))}\n      <DocTypeLine>\n        <Brace>{'}'}</Brace>\n      </DocTypeLine>\n    </DocTypeSchema>\n  )\n}\n\nconst DocTypeSchema = styled.div`\n  font-size: 14px;\n  overflow: auto;\n  .doc-category-item {\n    padding-left: 32px;\n  }\n`\n\nconst DocTypeLine = styled.div`\n  padding: 6px 16px;\n  white-space: nowrap;\n`\n\nconst DocsTypeName = styled.span`\n  color: #f25c54;\n`\n\nconst DocsTypeInferface = styled(TypeLink)`\n  padding-left: 16px;\n  .field-name {\n    color: rgb(245, 160, 0);\n  }\n  .type-name {\n    color: #f25c54;\n  }\n`\n\nconst DocsValueComment = styled.p`\n  color: ${p => p.theme.colours.black50};\n  padding-right: 16px;\n  padding-left: 32px;\n`\n\nconst Brace = styled.span`\n  font-weight: 600;\n  color: ${p => p.theme.colours.darkBlue50};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsStyles.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../styled'\n\nconst Title = styled.div`\n  color: rgba(0, 0, 0, 0.3);\n  cursor: default;\n  font-size: 14px;\n  font-weight: 600;\n  text-transform: uppercase !important;\n  letter-spacing: 1px;\n  padding: 16px;\n  user-select: none;\n`\nexport const CategoryTitle = ({ children }) => <Title>{children}</Title>\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/DocType.tsx",
    "content": "import { styled } from '../../../../styled'\n\nexport const DocType = styled.div`\n  padding: 20px 16px 0 16px;\n  overflow: auto;\n  font-size: 14px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/EnumTypeSchema.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../../styled'\nimport { DocType } from './DocType'\n\nexport interface EnumTypeSchemaProps {\n  type: any\n  sdlType?: boolean\n}\n\nconst EnumTypeSchema = ({ type, sdlType }: EnumTypeSchemaProps) => {\n  const values = sdlType ? type._values : type.getValues()\n  const deprecatedValues = values.filter((value: any) => value.isDeprecated)\n  return (\n    <DocType className=\"doc-type-schema\">\n      <span className=\"field-name\">enum</span>{' '}\n      <span className=\"type-name\">{type.name}</span>{' '}\n      <span className=\"brace\">{'{'}</span>\n      {values\n        .filter((value: any) => !value.isDeprecated)\n        .map((value, index) => (\n          <Value key={value.name} first={index === 0} value={value} />\n        ))}\n      {deprecatedValues.length > 0 && <br />}\n      {deprecatedValues.map((value, index) => (\n        <Value\n          first={index === 0}\n          key={value.name}\n          value={value}\n          isDeprecated={true}\n        />\n      ))}\n      <span className=\"brace\">{'}'}</span>\n    </DocType>\n  )\n}\n\nexport default EnumTypeSchema\n\ninterface ValueProps {\n  value: any\n  isDeprecated?: boolean\n  first: boolean\n}\n\nconst Value = ({ value, isDeprecated, first }: ValueProps) => (\n  <DocsValue first={first}>\n    <div className=\"field-name\">{value.name}</div>\n    {value.description && (\n      <DocsValueComment>{value.description}</DocsValueComment>\n    )}\n    {isDeprecated && (\n      <DocsValueComment>Deprecated: {value.deprecationReason}</DocsValueComment>\n    )}\n  </DocsValue>\n)\n\ninterface DocsValueProps {\n  first: boolean\n}\n\nconst DocsValue = styled<DocsValueProps, 'div'>('div')`\n  margin-top: ${p => (p.first ? 0 : 6)}px;\n  .field-name {\n    padding: 0 16px;\n    color: red;\n  }\n`\n\nconst DocsValueComment = styled.div`\n  padding: 0 16px;\n  color: ${p => p.theme.colours.black50};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/ScalarType.tsx",
    "content": "import * as React from 'react'\nimport { DocType } from './DocType'\n\nexport interface ScalarTypeSchemaProps {\n  type: any\n}\n\nconst ScalarTypeSchema = ({ type }: ScalarTypeSchemaProps) => {\n  return (\n    <DocType className=\"doc-type-schema\">\n      <span className=\"field-name\">scalar</span>{' '}\n      <span className=\"type-name\">{type.name}</span>\n    </DocType>\n  )\n}\n\nexport default ScalarTypeSchema\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/UnionTypeSchema.tsx",
    "content": "import TypeLink from '../TypeLink'\nimport * as React from 'react'\nimport { DocType } from './DocType'\n\nexport interface EnumTypeSchemaProps {\n  schema: any\n  type: any\n  level: number\n  sessionId: string\n}\n\nconst UnionTypeSchema = ({\n  schema,\n  type,\n  level,\n  sessionId,\n}: EnumTypeSchemaProps) => {\n  const types = schema.getPossibleTypes(type)\n  return (\n    <DocType className=\"doc-type-schema\">\n      <span className=\"field-name\">union</span>{' '}\n      <span className=\"type-name\">{type.name}</span>\n      {' = '}\n      {types.map((value, index) => (\n        <TypeLink\n          key={value.name}\n          type={value}\n          x={level}\n          y={index + 1}\n          collapsable={true}\n          sessionId={sessionId}\n          lastActive={false}\n        />\n      ))}\n    </DocType>\n  )\n}\n\nexport default UnionTypeSchema\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/ErrorContainer.tsx",
    "content": "import { styled } from '../../../styled'\nexport const ErrorContainer = styled.div`\n  font-weight: bold;\n  left: 0;\n  letter-spacing: 1px;\n  opacity: 0.5;\n  position: absolute;\n  right: 0;\n  text-align: center;\n  text-transform: uppercase;\n  top: 50%;\n  transform: translate(0, -50%);\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/FieldDoc.tsx",
    "content": "import * as React from 'react'\nimport Argument from './Argument'\nimport {\n  GraphQLInterfaceType,\n  GraphQLEnumType,\n  GraphQLUnionType,\n  GraphQLScalarType,\n} from 'graphql'\nimport MarkdownContent from 'graphiql/dist/components/DocExplorer/MarkdownContent'\nimport TypeLink from './TypeLink'\nimport DocTypeSchema from './DocTypeSchema'\nimport ScalarTypeSchema from './DocsTypes/ScalarType'\nimport EnumTypeSchema from './DocsTypes/EnumTypeSchema'\nimport UnionTypeSchema from './DocsTypes/UnionTypeSchema'\nimport { getDeeperType, serialize } from '../util/stack'\nimport { CategoryTitle } from './DocsStyles'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  schema: any\n  field: any\n  level: number\n  sessionId: string\n}\n\nexport interface State {\n  showDeprecated: boolean\n}\n\nexport default class FieldDoc extends React.Component<Props, State> {\n  state = { showDeprecated: false }\n  ref\n\n  componentDidMount() {\n    this.scrollToRight()\n  }\n\n  shouldComponentUpdate(nextProps) {\n    if (this.props.field !== nextProps.field) {\n      this.scrollToRight()\n      return true\n    }\n    return false\n  }\n\n  scrollToRight() {\n    const explorer = this.ref\n    const explorerDoc: any =\n      explorer.parentNode && explorer.parentNode.parentNode\n    // TODO see browser compatibility scrollWidth && scrollLeft\n    scrollToRight(explorerDoc, explorerDoc.scrollWidth, 50)\n  }\n\n  setRef = ref => {\n    this.ref = ref\n  }\n\n  render() {\n    const { schema, field, level } = this.props\n    let type = field.type || field\n    const obj = serialize(schema, field)\n    type = getDeeperType(type)\n    const argsOffset = obj.fields.length + obj.interfaces.length\n    const implementationsOffset =\n      obj.fields.length + obj.interfaces.length + obj.args.length\n\n    let typeInstance\n\n    if (type instanceof GraphQLInterfaceType) {\n      typeInstance = 'interface'\n    } else if (type instanceof GraphQLUnionType) {\n      typeInstance = 'union'\n    } else if (type instanceof GraphQLEnumType) {\n      typeInstance = 'enum'\n    } else {\n      typeInstance = 'type'\n    }\n\n    return (\n      <div ref={this.setRef}>\n        <DocsHeader>\n          <TypeLink\n            type={field}\n            x={level}\n            y={-1}\n            clickable={false}\n            lastActive={false}\n          />\n        </DocsHeader>\n        <DocsDescription\n          className=\"doc-type-description\"\n          markdown={field.description || ''}\n        />\n\n        <CategoryTitle>{`${typeInstance} details`}</CategoryTitle>\n        {type.description &&\n          type.description.length > 0 && (\n            <DocsDescription markdown={type.description || ''} />\n          )}\n        {type instanceof GraphQLScalarType && <ScalarTypeSchema type={type} />}\n        {type instanceof GraphQLEnumType && <EnumTypeSchema type={type} />}\n        {type instanceof GraphQLUnionType && (\n          <UnionTypeSchema\n            type={type}\n            schema={schema}\n            level={level}\n            sessionId={this.props.sessionId}\n          />\n        )}\n\n        {obj.fields &&\n          obj.fields.length > 0 && (\n            <DocTypeSchema\n              type={type}\n              fields={obj.fields}\n              interfaces={obj.interfaces}\n              level={level}\n              sessionId={this.props.sessionId}\n            />\n          )}\n\n        {obj.args &&\n          obj.args.length > 0 && (\n            <div>\n              <CategoryTitle>arguments</CategoryTitle>\n              {obj.args.map((arg, index) => (\n                <div key={arg.name}>\n                  <div>\n                    <Argument\n                      arg={arg}\n                      x={level}\n                      y={index + argsOffset}\n                      sessionId={this.props.sessionId}\n                    />\n                  </div>\n                </div>\n              ))}\n            </div>\n          )}\n\n        {obj.implementations &&\n          obj.implementations.length > 0 && (\n            <div>\n              <CategoryTitle>implementations</CategoryTitle>\n              {obj.implementations.map((data, index) => (\n                <TypeLink\n                  key={data.name}\n                  type={data}\n                  x={level}\n                  y={index + implementationsOffset}\n                  collapsable={true}\n                  lastActive={false}\n                />\n              ))}\n            </div>\n          )}\n      </div>\n    )\n  }\n}\n\nconst scrollToRight = (element: Element, to: number, duration: number) => {\n  if (duration <= 0) {\n    return\n  }\n  const difference = to - element.scrollLeft\n  const perTick = (difference / duration) * 10\n  setTimeout(() => {\n    element.scrollLeft = element.scrollLeft + perTick\n    if (element.scrollLeft === to) {\n      return\n    }\n    scrollToRight(element, to, duration - 10)\n  }, 10)\n}\n\nconst DocsHeader = styled.div`\n  background: ${p => p.theme.colours.black02};\n  padding-top: 20px;\n  padding-bottom: 10px;\n\n  .doc-category-item {\n    font-size: 14px;\n    font-weight: 600;\n    word-wrap: break-word;\n  }\n  .doc-category-item .field-name {\n    color: #f25c54;\n  }\n  div {\n    background: transparent;\n    pointer-events: none;\n  }\n`\n\nconst DocsDescription = styled(MarkdownContent)`\n  font-size: 14px;\n  padding: 0 16px 20px 16px;\n  color: rgba(0, 0, 0, 0.5);\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/GraphDocs.tsx",
    "content": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport * as keycode from 'keycode'\nimport FieldDoc from './FieldDoc'\nimport ColumnDoc from './ColumnDoc'\nimport {\n  addStack,\n  toggleDocs,\n  changeWidthDocs,\n  changeKeyMove,\n  setDocsVisible,\n} from '../../../state/docs/actions'\nimport Spinner from '../../Spinner'\nimport { columnWidth } from '../../../constants'\nimport RootColumn from './RootColumn'\nimport {\n  serialize,\n  getElementRoot,\n  serializeRoot,\n  getElement,\n} from '../util/stack'\nimport { getSessionDocs } from '../../../state/docs/selectors'\nimport { getSelectedSessionIdFromRoot } from '../../../state/sessions/selectors'\nimport { createStructuredSelector } from 'reselect'\nimport { SideTabContentProps } from '../ExplorerTabs/SideTabs'\nimport { ErrorContainer } from './ErrorContainer'\nimport { styled } from '../../../styled'\n\ninterface StateFromProps {\n  docs: {\n    navStack: any[]\n    docsOpen: boolean\n    docsWidth: number\n    keyMove: boolean\n  }\n}\n\ninterface DispatchFromProps {\n  addStack: (sessionId: string, field: any, x: number, y: number) => any\n  toggleDocs: (sessionId: string) => any\n  setDocsVisible: (sessionId: string, open: boolean) => any\n  changeWidthDocs: (sessionId: string, width: number) => any\n  changeKeyMove: (sessionId: string, move: boolean) => any\n}\n\nexport interface State {\n  searchValue: string\n  widthMap: any\n}\n\nclass GraphDocs extends React.Component<\n  SideTabContentProps & StateFromProps & DispatchFromProps,\n  State\n> {\n  ref\n  // private refDocExplorer: any;\n\n  constructor(props) {\n    super(props)\n    this.state = {\n      searchValue: '',\n      widthMap: {},\n    }\n    ;(window as any).d = this\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps: SideTabContentProps & StateFromProps) {\n    // If user use default column size % columnWidth\n    // Make the column follow the clicks\n    if (\n      this.props.docs.navStack.length !== nextProps.docs.navStack.length ||\n      this.props.docs.navStack.slice(-1)[0] !==\n        nextProps.docs.navStack.slice(-1)[0] ||\n      (!this.props.schema && nextProps.schema)\n    ) {\n      this.setWidth(nextProps)\n    }\n  }\n\n  setWidth(props: any = this.props) {\n    this.props.setWidth(props)\n  }\n\n  getWidth(props: any = this.props) {\n    const rootWidth = this.state.widthMap.root || columnWidth\n    const stackWidths = props.docs.navStack.map(\n      stack => this.state.widthMap[stack.field.path] || columnWidth,\n    )\n\n    return [rootWidth].concat(stackWidths).reduce((acc, curr) => acc + curr, 0)\n  }\n\n  componentDidMount() {\n    this.setWidth()\n  }\n\n  render() {\n    const { navStack } = this.props.docs\n    const { schema } = this.props\n    let emptySchema\n    if (schema === undefined) {\n      // Schema is undefined when it is being loaded via introspection.\n      emptySchema = <Spinner />\n    } else if (schema === null) {\n      // Schema is null when it explicitly does not exist, typically due to\n      // an error during introspection.\n      emptySchema = <ErrorContainer>{'No Schema Available'}</ErrorContainer>\n    }\n\n    return (\n      <DocsExplorerContainer\n        onKeyDown={this.handleKeyDown}\n        tabIndex={0}\n        ref={this.setRef}\n      >\n        {emptySchema && <ColumnDoc>{emptySchema}</ColumnDoc>}\n        {!emptySchema &&\n          schema && (\n            <RootColumn\n              schema={schema}\n              width={this.state.widthMap.root || columnWidth - 1}\n              searchValue={this.state.searchValue}\n              handleSearch={this.handleSearch}\n              sessionId={this.props.sessionId}\n            />\n          )}\n        {navStack.map((stack, index) => (\n          <ColumnDoc\n            key={index}\n            width={this.state.widthMap[stack.field.path] || columnWidth}\n          >\n            <FieldDoc\n              schema={schema}\n              field={stack.field}\n              level={index + 1}\n              sessionId={this.props.sessionId}\n            />\n          </ColumnDoc>\n        ))}\n      </DocsExplorerContainer>\n    )\n  }\n\n  setRef = ref => {\n    this.ref = ref\n  }\n\n  public showDocFromType = type => {\n    this.props.addStack(this.props.sessionId, type, 0, 0)\n  }\n\n  private handleSearch = (value: string) => {\n    this.setState({ searchValue: value })\n  }\n\n  private handleKeyDown = e => {\n    // we don't want to interfere with inputs\n    if (\n      e.target instanceof HTMLInputElement ||\n      e.metaKey ||\n      e.shiftKey ||\n      e.altKey ||\n      e.ctrlKey\n    ) {\n      return\n    }\n    e.preventDefault()\n    this.props.changeKeyMove(this.props.sessionId, true)\n    const lastNavStack =\n      this.props.docs.navStack.length > 0 &&\n      this.props.docs.navStack[this.props.docs.navStack.length - 1]\n    const beforeLastNavStack =\n      this.props.docs.navStack.length > 0 &&\n      this.props.docs.navStack[this.props.docs.navStack.length - 2]\n    const keyPressed = keycode(e)\n    switch (keyPressed) {\n      case 'esc':\n        this.props.setDocsVisible(this.props.sessionId, false)\n        break\n      case 'left':\n        if (beforeLastNavStack) {\n          this.props.addStack(\n            this.props.sessionId,\n            beforeLastNavStack.field,\n            beforeLastNavStack.x,\n            beforeLastNavStack.y,\n          )\n        }\n        break\n      case 'right':\n        if (lastNavStack) {\n          const obj = serialize(this.props.schema, lastNavStack.field)\n          const firstElement = getElement(obj, 0)\n          if (firstElement) {\n            this.props.addStack(\n              this.props.sessionId,\n              firstElement,\n              lastNavStack.x + 1,\n              0,\n            )\n          }\n        } else {\n          const obj = serializeRoot(this.props.schema)\n          const element = getElementRoot(obj, 0)\n          if (element) {\n            this.props.addStack(this.props.sessionId, element, 0, 0)\n          }\n        }\n        break\n      case 'up':\n      case 'down':\n        if (beforeLastNavStack) {\n          const obj = serialize(this.props.schema, beforeLastNavStack.field)\n          const element = getElement(\n            obj,\n            keyPressed === 'up' ? lastNavStack.y - 1 : lastNavStack.y + 1,\n          )\n          if (element) {\n            this.props.addStack(\n              this.props.sessionId,\n              element,\n              lastNavStack.x,\n              keyPressed === 'up' ? lastNavStack.y - 1 : lastNavStack.y + 1,\n            )\n          }\n        } else {\n          const obj = serializeRoot(this.props.schema)\n          const y = lastNavStack ? lastNavStack.y : 0\n          const element = getElementRoot(\n            obj,\n            keyPressed === 'up' ? y - 1 : y + 1,\n          )\n          if (element) {\n            this.props.addStack(\n              this.props.sessionId,\n              element,\n              0,\n              keyPressed === 'up' ? y - 1 : y + 1,\n            )\n          }\n        }\n        break\n    }\n  }\n}\n\nconst mapDispatchToProps = dispatch =>\n  bindActionCreators(\n    {\n      addStack,\n      toggleDocs,\n      changeWidthDocs,\n      changeKeyMove,\n      setDocsVisible,\n    },\n    dispatch,\n  )\n\nconst mapStateToProps = createStructuredSelector({\n  docs: getSessionDocs,\n  sessionId: getSelectedSessionIdFromRoot,\n})\n\nexport default connect<StateFromProps, DispatchFromProps, SideTabContentProps>(\n  mapStateToProps,\n  mapDispatchToProps,\n  null,\n  { forwardRef: true },\n)(GraphDocs)\n\nconst DocsExplorerContainer = styled.div`\n  display: flex;\n  position: relative;\n  height: 100%;\n  width: 100%;\n  overflow-x: auto;\n  overflow-y: hidden;\n  outline: none !important;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/GraphDocsRoot.tsx",
    "content": "import * as React from 'react'\nimport TypeLink from './TypeLink'\nimport { serializeRoot } from '../util/stack'\nimport { CategoryTitle } from './DocsStyles'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  schema: any\n  sessionId: string\n}\n\nexport default class GraphDocsRoot extends React.PureComponent<Props, {}> {\n  render() {\n    const { schema, sessionId } = this.props\n    const obj = serializeRoot(schema)\n    return (\n      <DocsRoot className=\"doc-root\">\n        <ShowRootType\n          name=\"Queries\"\n          fields={obj.queries}\n          offset={0}\n          sessionId={sessionId}\n        />\n        {obj.mutations.length > 0 && (\n          <ShowRootType\n            name=\"Mutations\"\n            fields={obj.mutations}\n            offset={obj.queries.length}\n            sessionId={sessionId}\n          />\n        )}\n        {obj.subscriptions.length > 0 && (\n          <ShowRootType\n            name=\"Subscriptions\"\n            fields={obj.subscriptions}\n            offset={obj.queries.length + obj.mutations.length}\n            sessionId={sessionId}\n          />\n        )}\n      </DocsRoot>\n    )\n  }\n}\n\ninterface ShowRootTypeProps {\n  name: string\n  fields: any[]\n  offset: number\n  sessionId: string\n}\n\nfunction ShowRootType({ name, fields, offset }: ShowRootTypeProps) {\n  const nonDeprecatedFields = fields.filter(data => !data.isDeprecated)\n  const deprecatedFields = fields.filter(data => data.isDeprecated)\n\n  return (\n    <div>\n      <CategoryTitle>{name}</CategoryTitle>\n      {nonDeprecatedFields.map((field, index) => (\n        <TypeLink\n          key={field.name}\n          type={field}\n          x={0}\n          y={offset + index}\n          collapsable={true}\n          lastActive={false}\n        />\n      ))}\n      {deprecatedFields.length > 0 && <br />}\n      {deprecatedFields.map((field, index) => (\n        <div key={field.name}>\n          <DocsValueComment>\n            # Deprecated: {field.deprecationReason}\n          </DocsValueComment>\n          <TypeLink\n            type={field}\n            x={0}\n            y={offset + index + nonDeprecatedFields.length}\n            collapsable={true}\n            lastActive={false}\n          />\n        </div>\n      ))}\n    </div>\n  )\n}\n\nconst DocsRoot = styled.div`\n  padding-left: 6px;\n\n  .doc-category-item .field-name {\n    color: #f25c54;\n  }\n`\n\nconst DocsValueComment = styled.p`\n  color: ${p => p.theme.colours.black50};\n  padding-right: 16px;\n  padding-left: 16px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/RootColumn.tsx",
    "content": "import * as React from 'react'\nimport ColumnDoc from './ColumnDoc'\nimport SearchResults from './SearchResults'\nimport GraphDocsRoot from './GraphDocsRoot'\nimport SearchBox from './SearchBox'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  searchValue: string\n  schema: any\n  width: number\n  handleSearch: (value: string) => void\n  sessionId: string\n}\n\nexport default class RootColumn extends React.PureComponent<Props, {}> {\n  render() {\n    const { searchValue, schema, width, sessionId, handleSearch } = this.props\n    return (\n      <ColumnDoc width={width} overflow={false}>\n        <SearchBox onSearch={handleSearch} />\n        <Column>\n          {searchValue && (\n            <SearchResults\n              searchValue={searchValue}\n              schema={schema}\n              level={0}\n              sessionId={sessionId}\n            />\n          )}\n          {!searchValue && (\n            <GraphDocsRoot schema={schema} sessionId={sessionId} />\n          )}\n        </Column>\n      </ColumnDoc>\n    )\n  }\n}\n\nconst Column = styled.div`\n  overflow: auto;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/SchemaDoc.tsx",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nimport * as React from 'react'\n\nimport TypeLink from 'graphiql/dist/components/DocExplorer/TypeLink'\nimport MarkdownContent from 'graphiql/dist/components/DocExplorer/MarkdownContent'\n\nexport interface Props {\n  schema: any\n  onClickType: any\n}\n\n// Render the top level Schema\nexport default class SchemaDoc extends React.Component<Props, {}> {\n  shouldComponentUpdate(nextProps) {\n    return this.props.schema !== nextProps.schema\n  }\n\n  render() {\n    const schema = this.props.schema\n    const queryType = schema.getQueryType()\n    const mutationType = schema.getMutationType && schema.getMutationType()\n    const subscriptionType =\n      schema.getSubscriptionType && schema.getSubscriptionType()\n\n    return (\n      <div className=\"root\">\n        <MarkdownContent\n          className=\"doc-type-description\"\n          markdown={\n            'A GraphQL schema provides a root type for each kind of operation.'\n          }\n        />\n        <div className=\"doc-category\">\n          <div className=\"doc-category-title\">{'root types'}</div>\n          <div className=\"doc-category-item\">\n            <span className=\"keyword\">{'query'}</span>\n            {': '}\n            <TypeLink type={queryType} onClick={this.props.onClickType} />\n          </div>\n          {mutationType && (\n            <div className=\"doc-category-item\">\n              <span className=\"keyword\">{'mutation'}</span>\n              {': '}\n              <TypeLink type={mutationType} onClick={this.props.onClickType} />\n            </div>\n          )}\n          {subscriptionType && (\n            <div className=\"doc-category-item\">\n              <span className=\"keyword\">{'subscription'}</span>\n              {': '}\n              <TypeLink\n                type={subscriptionType}\n                onClick={this.props.onClickType}\n              />\n            </div>\n          )}\n        </div>\n      </div>\n    )\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/SearchBox.tsx",
    "content": "import * as React from 'react'\nimport debounce from 'graphiql/dist/utility/debounce'\nimport { Search } from '../../Icons'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  onSearch: (value: string) => void\n  placeholder?: string\n  clean?: boolean\n}\n\nexport interface State {\n  value: string\n}\n\nexport default class SearchBox extends React.Component<Props, State> {\n  private debouncedOnSearch: any\n\n  constructor(props) {\n    super(props)\n\n    this.state = { value: '' }\n\n    this.debouncedOnSearch = debounce(200, () => {\n      this.props.onSearch(this.state.value)\n    })\n  }\n\n  shouldComponentUpdate(nextProps, nextState) {\n    return nextState.value !== this.state.value\n  }\n\n  render() {\n    const LabelComponent = (\n      <Label>\n        <Search\n          height={16}\n          width={16}\n          strokeWidth={3}\n          color={'rgba(0, 0, 0, 0.3)'}\n        />\n        <Input\n          onChange={this.handleChange}\n          type=\"text\"\n          value={this.state.value}\n          placeholder={this.props.placeholder || 'Search the docs ...'}\n        />\n      </Label>\n    )\n    if (this.props.clean) {\n      return LabelComponent\n    }\n\n    return <SearchContainer>{LabelComponent}</SearchContainer>\n  }\n\n  handleChange = event => {\n    this.setState({ value: event.target.value })\n    this.debouncedOnSearch()\n  }\n}\n\nconst SearchContainer = styled.div`\n  position: relative;\n  flex: 0 0 auto;\n  z-index: 1;\n  display: flex;\n  margin-left: 6px;\n  padding: 25px;\n  background: ${p => p.theme.colours.black02};\n  border-bottom: 1px solid ${p => p.theme.colours.black10};\n  div {\n    width: 100%;\n  }\n`\n\nconst Label = styled.div`\n  box-sizing: border-box;\n  display: flex;\n  align-items: center;\n  padding: 12px 14px 13px 15px;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n  background: ${p => p.theme.colours.white};\n`\n\nconst Input = styled.input`\n  font-size: 16px;\n  margin-left: 10px;\n  &::placeholder {\n    color: ${p => p.theme.colours.black30};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/SearchResults.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../styled'\nimport TypeLink from './TypeLink'\n\nexport interface Props {\n  schema: any\n  withinType?: any\n  searchValue: string\n  level: number\n  sessionId: string\n}\n\nexport default class SearchResults extends React.Component<Props, {}> {\n  shouldComponentUpdate(nextProps) {\n    return (\n      this.props.schema !== nextProps.schema ||\n      this.props.searchValue !== nextProps.searchValue\n    )\n  }\n\n  render() {\n    const { level } = this.props\n    const searchValue = this.props.searchValue\n    const withinType = this.props.withinType\n    const schema = this.props.schema\n\n    const matchedWithin: any[] = []\n    const matchedTypes: any[] = []\n    const matchedFields: any[] = []\n\n    const typeMap = schema.getTypeMap()\n    let typeNames = Object.keys(typeMap)\n\n    // Move the within type name to be the first searched.\n    if (withinType) {\n      typeNames = typeNames.filter(n => n !== withinType.name)\n      typeNames.unshift(withinType.name)\n    }\n\n    let count = 0\n    for (const typeName of typeNames) {\n      if (\n        matchedWithin.length + matchedTypes.length + matchedFields.length >=\n        100\n      ) {\n        break\n      }\n\n      const type = typeMap[typeName]\n      if (withinType !== type && isMatch(typeName, searchValue)) {\n        matchedTypes.push(\n          <div className=\"doc-category-item\" key={typeName}>\n            <TypeLink type={type} x={level} y={count++} lastActive={false} />\n          </div>,\n        )\n      }\n\n      if (type.getFields) {\n        const fields = type.getFields()\n        Object.keys(fields).forEach(fieldName => {\n          const field = fields[fieldName]\n          field.parent = type\n          let matchingArgs\n\n          if (!isMatch(fieldName, searchValue)) {\n            if (field.args && field.args.length) {\n              matchingArgs = field.args.filter(arg =>\n                isMatch(arg.name, searchValue),\n              )\n              if (matchingArgs.length === 0) {\n                return\n              }\n            } else {\n              return\n            }\n          }\n\n          const match = (\n            <div className=\"doc-category-item\" key={typeName + '.' + fieldName}>\n              <TypeLink\n                key=\"type\"\n                type={field}\n                x={level}\n                y={count++}\n                showParentName={true}\n                lastActive={false}\n              />\n            </div>\n          )\n\n          if (withinType === type) {\n            matchedWithin.push(match)\n          } else {\n            matchedFields.push(match)\n          }\n        })\n      }\n    }\n\n    if (\n      matchedWithin.length + matchedTypes.length + matchedFields.length ===\n      0\n    ) {\n      return <NoResult>No results found.</NoResult>\n    }\n\n    if (withinType && matchedTypes.length + matchedFields.length > 0) {\n      return (\n        <div>\n          {matchedWithin}\n          <div className=\"doc-category\">\n            <div className=\"doc-category-title\">{'other results'}</div>\n            {matchedTypes}\n            {matchedFields}\n          </div>\n        </div>\n      )\n    }\n\n    return (\n      <div>\n        {matchedWithin}\n        {matchedTypes}\n        {matchedFields}\n      </div>\n    )\n  }\n}\n\nfunction isMatch(sourceText, searchValue) {\n  try {\n    const escaped = searchValue.replace(/[^_0-9A-Za-z]/g, ch => '\\\\' + ch)\n    return sourceText.search(new RegExp(escaped, 'i')) !== -1\n  } catch (e) {\n    return sourceText.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1\n  }\n}\n\nconst NoResult = styled.span`\n  display: block;\n  margin-top: 16px;\n  margin-left: 16px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/TypeLink.tsx",
    "content": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport { GraphQLList, GraphQLNonNull, isType } from 'graphql'\nimport ArgumentInline from './ArgumentInline'\nimport { Triangle } from '../../Icons'\nimport { toJS } from '../util/toJS'\nimport { addStack } from '../../../state/docs/actions'\nimport { getSessionDocsState } from '../../../state/docs/selectors'\nimport {\n  // getSelectedSessionId,\n  getSelectedSessionIdFromRoot,\n} from '../../../state/sessions/selectors'\nimport { createSelector } from 'reselect'\nimport { styled } from '../../../styled'\n\ninterface ReduxProps {\n  keyMove: boolean\n  isActive: boolean\n}\n\ninterface DispatchFromProps {\n  addStack: (sessionId: string, field: any, x: number, y: number) => any\n}\n\nexport interface Props {\n  type: any\n  // X position in the list\n  x: number\n  // Y position in the list\n  y: number\n  clickable?: boolean\n  className?: string\n  beforeNode?: JSX.Element | null | false\n  afterNode?: JSX.Element | null | false\n  onSetWidth?: (width: number) => void\n  showParentName?: boolean\n  collapsable?: boolean\n  lastActive: boolean\n  sessionId?: string\n}\n\ninterface State {\n  collapsed: boolean\n}\n\nclass TypeLink extends React.Component<\n  Props & ReduxProps & DispatchFromProps,\n  State\n> {\n  static defaultProps: Partial<Props> = {\n    clickable: true,\n    collapsable: false,\n  }\n  private ref: any\n\n  constructor(props) {\n    super(props)\n    this.state = {\n      collapsed: false,\n    }\n  }\n\n  shouldComponentUpdate(nextProps: Props & ReduxProps, nextState: State) {\n    return (\n      this.props.type !== nextProps.type ||\n      this.props.keyMove !== nextProps.keyMove ||\n      this.props.isActive !== nextProps.isActive ||\n      this.state.collapsed !== nextState.collapsed\n    )\n  }\n\n  onClick = () => {\n    if (this.props.clickable) {\n      this.props.addStack(\n        this.props.sessionId,\n        this.props.type,\n        this.props.x,\n        this.props.y,\n      )\n    }\n  }\n\n  componentDidMount() {\n    this.updateSize()\n  }\n\n  componentDidUpdate() {\n    this.updateSize()\n  }\n\n  updateSize() {\n    if (this.ref) {\n      if (typeof this.props.onSetWidth === 'function') {\n        this.props.onSetWidth(this.ref.scrollWidth)\n      }\n\n      const LINE_HEIGHT = 31\n\n      if (\n        this.ref.scrollHeight > LINE_HEIGHT &&\n        !this.state.collapsed &&\n        this.props.collapsable\n      ) {\n        this.setState({ collapsed: true })\n      }\n    }\n  }\n\n  setRef = ref => {\n    this.ref = ref\n  }\n\n  render() {\n    const {\n      type,\n      clickable,\n      className,\n      beforeNode,\n      afterNode,\n      showParentName,\n      isActive,\n    } = this.props\n    const isGraphqlType = isType(type)\n\n    const fieldName =\n      showParentName && type.parent ? (\n        <span>\n          {type.parent.name}.<b>{type.name}</b>\n        </span>\n      ) : (\n        type.name\n      )\n\n    return (\n      <DocsCategoryItem\n        active={isActive}\n        clickable={clickable}\n        className={`doc-category-item${className ? className : ''}`}\n        onClick={this.onClick}\n        ref={this.setRef}\n      >\n        {beforeNode}\n        {beforeNode && ' '}\n        {!isGraphqlType && (\n          <span>\n            <span className=\"field-name\">{fieldName}</span>\n            {type.args &&\n              type.args.length > 0 && [\n                '(',\n                <span key=\"args\">\n                  {this.state.collapsed ? (\n                    <Dots>...</Dots>\n                  ) : (\n                    type.args.map(arg => (\n                      <ArgumentInline key={arg.name} arg={arg} />\n                    ))\n                  )}\n                </span>,\n                ')',\n              ]}\n            {': '}\n          </span>\n        )}\n        <span className=\"type-name\">{renderType(type.type || type)}</span>\n        {type.defaultValue !== undefined ? (\n          <DefaultValue>\n            {' '}\n            = <span>{`${JSON.stringify(type.defaultValue, null, 2)}`}</span>\n          </DefaultValue>\n        ) : (\n          undefined\n        )}\n        {clickable && (\n          <IconBox>\n            <Triangle />\n          </IconBox>\n        )}\n        {afterNode && ' '}\n        {afterNode}\n      </DocsCategoryItem>\n    )\n  }\n}\n\nfunction renderType(type) {\n  if (type instanceof GraphQLNonNull) {\n    return (\n      <span>\n        {renderType(type.ofType)}\n        {'!'}\n      </span>\n    )\n  }\n  if (type instanceof GraphQLList) {\n    return (\n      <span>\n        {'['}\n        {renderType(type.ofType)}\n        {']'}\n      </span>\n    )\n  }\n  return <span>{type.name}</span>\n}\n\nconst mapStateToProps = (state, { x, y }) => {\n  const docs = getSessionDocsState(state)\n  const sessionId = getSelectedSessionIdFromRoot(state)\n  if (docs) {\n    const nav = docs.navStack.get(x)\n    if (nav) {\n      const isActive = nav.get('x') === x && nav.get('y') === y\n      return {\n        isActive,\n        keyMove: docs.keyMove,\n        lastActive: isActive && x === docs.navStack.length - 1,\n        sessionId,\n      }\n    }\n  }\n  return {\n    isActive: false,\n    keyMove: false,\n    lastActive: false,\n    sessionId,\n  }\n}\n\nconst selector = createSelector([mapStateToProps], s => s)\n\nconst mapDispatchToProps = dispatch =>\n  bindActionCreators(\n    {\n      addStack,\n    },\n    dispatch,\n  )\n\nexport default connect<ReduxProps, DispatchFromProps, Props>(\n  selector,\n  mapDispatchToProps,\n)(toJS(TypeLink))\n\ninterface DocsCategoryItemProps {\n  clickable?: boolean\n  active?: boolean\n}\n\nconst DocsCategoryItem = styled<DocsCategoryItemProps, 'div'>('div')`\n  position: relative;\n  padding: 6px 16px;\n  overflow: auto;\n  font-size: 14px;\n  transition: 0.1s background-color;\n  background: ${p =>\n    p.active ? p.theme.colours.black07 : p.theme.colours.white};\n\n  cursor: ${p => (p.clickable ? 'pointer' : 'select')};\n\n  &:hover {\n    color: ${p => p.theme.colours.white};\n    background: #2a7ed3;\n    .field-name,\n    .type-name,\n    .arg-name,\n    span {\n      color: ${p => p.theme.colours.white} !important;\n    }\n  }\n  b {\n    font-weight: 600;\n  }\n`\n\nconst Dots = styled.span`\n  font-weight: 600;\n`\n\nconst IconBox = styled.div`\n  position: absolute;\n  right: 10px;\n  top: 50%;\n  transform: translateY(-50%);\n`\n\nconst DefaultValue = styled.span`\n  color: ${p => p.theme.colours.black30};\n  span {\n    color: #1f61a9;\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/EditorWrapper.tsx",
    "content": "import * as React from 'react'\nimport { styled, createGlobalStyle } from '../../styled'\n\nconst EditorWrapper = styled.div`\n  /* Comment */\n  .cm-comment {\n    color: ${p => p.theme.editorColours.comment};\n  }\n\n  /* Punctuation */\n  .cm-punctuation {\n    color: ${p => p.theme.editorColours.punctuation};\n  }\n\n  /* Proppery */\n  .cm-property {\n    color: ${p => p.theme.editorColours.property};\n  }\n\n  /* Keyword */\n  .cm-keyword {\n    color: ${p => p.theme.editorColours.keyword};\n  }\n\n  /* OperationName, FragmentName */\n  .cm-def {\n    color: ${p => p.theme.editorColours.def};\n  }\n\n  /* FieldAlias */\n  .cm-qualifier {\n    color: ${p => p.theme.editorColours.def};\n  }\n\n  /* ArgumentName and ObjectFieldName */\n  .cm-attribute {\n    color: ${p => p.theme.editorColours.attribute};\n  }\n\n  /* Number */\n  .cm-number {\n    color: ${p => p.theme.editorColours.number};\n  }\n\n  /* String */\n  .cm-string {\n    color: ${p => p.theme.editorColours.string};\n  }\n\n  /* Boolean */\n  .cm-builtin {\n    color: ${p => p.theme.editorColours.builtin};\n  }\n\n  /* EnumValue */\n  .cm-string-2 {\n    color: ${p => p.theme.editorColours.string2};\n  }\n\n  /* Variable */\n  .cm-variable {\n    color: ${p => p.theme.editorColours.variable};\n  }\n\n  /* Directive */\n  .cm-meta {\n    color: ${p => p.theme.editorColours.meta};\n  }\n\n  /* Type */\n  .cm-atom {\n    color: ${p => p.theme.editorColours.atom};\n  }\n\n  /* Comma */\n  .cm-ws {\n    color: ${p => p.theme.editorColours.ws};\n  }\n  position: relative;\n  display: flex;\n  flex: 1 1 0%;\n  flex-flow: column;\n\n  .CodeMirror {\n    color: rgba(255, 255, 255, 0.3);\n    font-family: ${p => p.theme.settings['editor.fontFamily']};\n    font-size: ${p => `${p.theme.settings['editor.fontSize']}px`};\n    height: 100%;\n    left: 0;\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  .CodeMirror-lines {\n    padding: 20px 0;\n  }\n\n  .CodeMirror-gutters {\n    border-right: none;\n  }\n\n  .CodeMirror span[role='presentation'] {\n    color: ${p => p.theme.colours.text};\n  }\n\n  /* CURSOR */\n\n  .CodeMirror div.CodeMirror-cursor {\n    background: ${p =>\n      p.theme.settings['editor.cursorShape'] === 'block'\n        ? p.theme.editorColours.cursorColor\n        : 'transparent'};\n    border-left: ${p =>\n      p.theme.settings['editor.cursorShape'] === 'line'\n        ? `1px solid ${p.theme.editorColours.cursorColor}`\n        : 0};\n    border-bottom: ${p =>\n      p.theme.settings['editor.cursorShape'] === 'underline'\n        ? `1px solid ${p.theme.editorColours.cursorColor}`\n        : 0};\n  }\n  /* Shown when moving in bi-directional text */\n  .CodeMirror div.CodeMirror-secondarycursor {\n    border-left: 1px solid silver;\n  }\n  .CodeMirror.cm-fat-cursor div.CodeMirror-cursor {\n    background: rgba(255, 255, 255, 0.6);\n    color: white;\n    border: 0;\n    width: auto;\n  }\n  .CodeMirror.cm-fat-cursor div.CodeMirror-cursors {\n    z-index: 1;\n  }\n\n  .cm-animate-fat-cursor {\n    -webkit-animation: blink 1.06s steps(1) infinite;\n    animation: blink 1.06s steps(1) infinite;\n    border: 0;\n    width: auto;\n  }\n  @-webkit-keyframes blink {\n    0% {\n      background: #7e7;\n    }\n    50% {\n      background: none;\n    }\n    100% {\n      background: #7e7;\n    }\n  }\n  @keyframes blink {\n    0% {\n      background: #7e7;\n    }\n    50% {\n      background: none;\n    }\n    100% {\n      background: #7e7;\n    }\n  }\n\n  .CodeMirror-foldmarker {\n    border-radius: 4px;\n    background: #08f;\n    background: linear-gradient(#43a8ff, #0f83e8);\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 0 0 1px rgba(0, 0, 0, 0.1);\n    color: white;\n    font-family: arial;\n    font-size: 12px;\n    line-height: 0;\n    margin: 0 3px;\n    padding: 0px 4px 1px;\n    text-shadow: 0 -1px rgba(0, 0, 0, 0.1);\n  }\n\n  div.CodeMirror span.CodeMirror-matchingbracket {\n    /* color: rgba(255, 255, 255, 0.4); */\n    text-decoration: underline;\n  }\n\n  div.CodeMirror span.CodeMirror-nonmatchingbracket {\n    color: rgb(242, 92, 84);\n  }\n\n  .toolbar-button {\n    background: #fdfdfd;\n    background: linear-gradient(#fbfbfb, #f8f8f8);\n    border-color: #d3d3d3 #d0d0d0 #bababa;\n    border-radius: 4px;\n    border-style: solid;\n    border-width: 0.5px;\n    box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.13), inset 0 1px #fff;\n    color: #444;\n    cursor: pointer;\n    display: inline-block;\n    margin: 0 5px 0;\n    padding: 2px 8px 4px;\n    text-decoration: none;\n  }\n  .toolbar-button:active {\n    background: linear-gradient(#ececec, #d8d8d8);\n    border-color: #cacaca #c9c9c9 #b0b0b0;\n    box-shadow: 0 1px 0 #fff, inset 0 1px rgba(255, 255, 255, 0.2),\n      inset 0 1px 1px rgba(0, 0, 0, 0.08);\n  }\n  .toolbar-button.error {\n    background: linear-gradient(#fdf3f3, #e6d6d7);\n    color: #b00;\n  }\n\n  .autoInsertedLeaf.cm-property {\n    -webkit-animation-duration: 6s;\n    animation-duration: 6s;\n    -webkit-animation-name: insertionFade;\n    animation-name: insertionFade;\n    border-bottom: 2px solid rgba(255, 255, 255, 0);\n    border-radius: 2px;\n    margin: -2px -4px -1px;\n    padding: 2px 4px 1px;\n  }\n\n  @-webkit-keyframes insertionFade {\n    from,\n    to {\n      background: rgba(255, 255, 255, 0);\n      border-color: rgba(255, 255, 255, 0);\n    }\n\n    15%,\n    85% {\n      background: #fbffc9;\n      border-color: #f0f3c0;\n    }\n  }\n\n  @keyframes insertionFade {\n    from,\n    to {\n      background: rgba(255, 255, 255, 0);\n      border-color: rgba(255, 255, 255, 0);\n    }\n\n    15%,\n    85% {\n      background: #fbffc9;\n      border-color: #f0f3c0;\n    }\n  }\n\n  .CodeMirror pre {\n    padding: 0 4px; /* Horizontal padding of content */\n  }\n\n  .CodeMirror-scrollbar-filler,\n  .CodeMirror-gutter-filler {\n    background-color: white; /* The little square between H and V scrollbars */\n  }\n\n  /* GUTTER */\n\n  .CodeMirror-gutters {\n    background-color: transparent;\n    border: none;\n    white-space: nowrap;\n  }\n  .CodeMirror-linenumbers {\n    background: ${p => p.theme.editorColours.editorBackground};\n  }\n  .CodeMirror-linenumber {\n    font-family: Open Sans, sans-serif;\n    font-weight: 600;\n    font-size: ${p => `${p.theme.settings['editor.fontSize'] - 2}px`};\n    color: ${p => p.theme.colours.textInactive};\n    min-width: 20px;\n    padding: 0 3px 0 5px;\n    text-align: right;\n    white-space: nowrap;\n  }\n\n  .CodeMirror-guttermarker {\n    color: black;\n  }\n  .CodeMirror-guttermarker-subtle {\n    color: #999;\n  }\n\n  .cm-tab {\n    display: inline-block;\n    text-decoration: inherit;\n  }\n\n  .CodeMirror-ruler {\n    border-left: 1px solid #ccc;\n    position: absolute;\n  }\n  .cm-negative {\n    color: #d44;\n  }\n  .cm-positive {\n    color: #292;\n  }\n  .cm-header,\n  .cm-strong {\n    font-weight: bold;\n  }\n  .cm-em {\n    font-style: italic;\n  }\n  .cm-link {\n    text-decoration: underline;\n  }\n  .cm-strikethrough {\n    text-decoration: line-through;\n  }\n\n  .cm-s-default .cm-error {\n    color: #f00;\n  }\n  .cm-invalidchar {\n    color: #f00;\n  }\n\n  .CodeMirror-composing {\n    border-bottom: 2px solid;\n  }\n  .CodeMirror-matchingtag {\n    background: rgba(255, 150, 0, 0.3);\n  }\n  .CodeMirror-activeline-background {\n    background: #e8f2ff;\n  }\n\n  /* The rest of this file contains styles related to the mechanics of\n   the editor. You probably shouldn't touch them. */\n\n  .CodeMirror {\n    background: white;\n    overflow: hidden;\n    line-height: 1.6;\n  }\n\n  .CodeMirror-scroll {\n    height: 100%;\n    /* 30px is the magic margin used to hide the element's real scrollbars */\n    /* See overflow: hidden in .CodeMirror */\n    /* margin-bottom: -30px;\n    margin-right: -30px; */\n    outline: none; /* Prevent dragging from highlighting the element */\n    overflow: hidden;\n    /* padding-bottom: 30px; */\n    position: relative;\n    &:hover {\n      overflow: scroll !important;\n    }\n  }\n  .CodeMirror-sizer {\n    border-right: 30px solid transparent;\n    position: relative;\n  }\n\n  /* The fake, visible scrollbars. Used to force redraw during scrolling\n   before actual scrolling happens, thus preventing shaking and\n   flickering artifacts. */\n  .CodeMirror-vscrollbar,\n  .CodeMirror-hscrollbar,\n  .CodeMirror-scrollbar-filler,\n  .CodeMirror-gutter-filler {\n    display: none !important;\n    position: absolute;\n    z-index: 6;\n  }\n  .CodeMirror-vscrollbar {\n    overflow-x: hidden;\n    overflow-y: scroll;\n    right: 0;\n    top: 0;\n  }\n  .CodeMirror-hscrollbar {\n    bottom: 0;\n    left: 0;\n    overflow-x: scroll;\n    overflow-y: hidden;\n  }\n  .CodeMirror-scrollbar-filler {\n    right: 0;\n    bottom: 0;\n  }\n  .CodeMirror-gutter-filler {\n    left: 0;\n    bottom: 0;\n  }\n\n  .CodeMirror-gutters {\n    min-height: 100%;\n    position: absolute;\n    left: 0;\n    top: 0;\n    z-index: 3;\n    margin-left: 3px;\n  }\n  .CodeMirror-gutter {\n    display: inline-block;\n    height: 100%;\n    margin-bottom: -30px;\n    vertical-align: top;\n    white-space: normal;\n    /* Hack to make IE7 behave */\n    *zoom: 1;\n    *display: inline;\n  }\n  .CodeMirror-gutter-wrapper {\n    background: none !important;\n    border: none !important;\n    position: absolute;\n    z-index: 4;\n  }\n  .CodeMirror-gutter-background {\n    position: absolute;\n    top: 0;\n    bottom: 0;\n    z-index: 4;\n  }\n  .CodeMirror-gutter-elt {\n    cursor: default;\n    position: absolute;\n    z-index: 4;\n  }\n  .CodeMirror-gutter-wrapper {\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n  }\n\n  .CodeMirror-lines {\n    cursor: text;\n    min-height: 1px; /* prevents collapsing before first draw */\n  }\n  .CodeMirror pre {\n    -webkit-tap-highlight-color: transparent;\n    /* Reset some styles that the rest of the page might have set */\n    background: transparent;\n    border-radius: 0;\n    border-width: 0;\n    color: inherit;\n    font-family: inherit;\n    font-size: inherit;\n    -webkit-font-variant-ligatures: none;\n    font-variant-ligatures: none;\n    line-height: inherit;\n    margin: 0;\n    overflow: visible;\n    position: relative;\n    white-space: pre;\n    word-wrap: normal;\n    z-index: 2;\n  }\n  .CodeMirror-wrap pre {\n    word-wrap: break-word;\n    white-space: pre-wrap;\n    word-break: normal;\n  }\n\n  .CodeMirror-linebackground {\n    position: absolute;\n    left: 0;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    z-index: 0;\n  }\n\n  .CodeMirror-linewidget {\n    overflow: auto;\n    position: relative;\n    z-index: 2;\n  }\n\n  .CodeMirror-widget {\n  }\n\n  .CodeMirror-code {\n    outline: none;\n  }\n\n  /* Force content-box sizing for the elements where we expect it */\n  .CodeMirror-scroll,\n  .CodeMirror-sizer,\n  .CodeMirror-gutter,\n  .CodeMirror-gutters,\n  .CodeMirror-linenumber {\n    box-sizing: content-box;\n  }\n\n  .CodeMirror-measure {\n    height: 0;\n    overflow: hidden;\n    position: absolute;\n    visibility: hidden;\n    width: 100%;\n  }\n\n  .CodeMirror-cursor {\n    position: absolute;\n  }\n  .CodeMirror-measure pre {\n    position: static;\n  }\n\n  div.CodeMirror-cursors {\n    position: relative;\n    visibility: hidden;\n    z-index: 3;\n  }\n  div.CodeMirror-dragcursors {\n    visibility: visible;\n  }\n\n  .CodeMirror-focused div.CodeMirror-cursors {\n    visibility: visible;\n  }\n\n  .CodeMirror-selected {\n    background: ${p => p.theme.editorColours.selection};\n  }\n  .CodeMirror-focused .CodeMirror-selected {\n    background: ${p => p.theme.editorColours.selection};\n  }\n  .CodeMirror-crosshair {\n    cursor: crosshair;\n  }\n  .CodeMirror-line::-moz-selection,\n  .CodeMirror-line > span::-moz-selection,\n  .CodeMirror-line > span > span::-moz-selection {\n    background: ${p => p.theme.editorColours.selection};\n  }\n  .CodeMirror-line::selection,\n  .CodeMirror-line > span::selection,\n  .CodeMirror-line > span > span::selection {\n    background: ${p => p.theme.editorColours.selection};\n  }\n  .CodeMirror-line::-moz-selection,\n  .CodeMirror-line > span::-moz-selection,\n  .CodeMirror-line > span > span::-moz-selection {\n    background: ${p => p.theme.editorColours.selection};\n  }\n\n  .cm-searching {\n    background: #ffa;\n    background: rgba(255, 255, 0, 0.4);\n  }\n\n  /* IE7 hack to prevent it from returning funny offsetTops on the spans */\n  .CodeMirror span {\n    *vertical-align: text-bottom;\n  }\n\n  /* Used to force a border model for a node */\n  .cm-force-border {\n    padding-right: 0.1px;\n  }\n\n  @media print {\n    /* Hide the cursor when printing */\n    .CodeMirror div.CodeMirror-cursors {\n      visibility: hidden;\n    }\n  }\n\n  /* See issue #2901 */\n  .cm-tab-wrap-hack:after {\n    content: '';\n  }\n\n  /* Help users use markselection to safely style text background */\n  span.CodeMirror-selectedtext {\n    background: none;\n  }\n\n  .CodeMirror-dialog {\n    background: inherit;\n    color: inherit;\n    left: 0;\n    right: 0;\n    overflow: hidden;\n    padding: 0.1em 0.8em;\n    position: absolute;\n    z-index: 15;\n  }\n\n  .CodeMirror-dialog-top {\n    border-bottom: 1px solid #eee;\n    top: 0;\n  }\n\n  .CodeMirror-dialog-bottom {\n    border-top: 1px solid #eee;\n    bottom: 0;\n  }\n\n  .CodeMirror-dialog input {\n    background: transparent;\n    border: 1px solid #d3d6db;\n    color: inherit;\n    font-family: monospace;\n    outline: none;\n    width: 20em;\n  }\n\n  .CodeMirror-dialog span.CodeMirror-search-label {\n    color: ${p => p.theme.colours.text};\n  }\n\n  .CodeMirror-dialog input.CodeMirror-search-field {\n    color: ${p => p.theme.colours.text};\n    background: ${p => p.theme.colours.background};\n  }\n\n  .CodeMirror-dialog button {\n    font-size: 70%;\n  }\n\n  .CodeMirror-foldgutter {\n    width: 0.7em;\n  }\n  .CodeMirror-foldgutter-open,\n  .CodeMirror-foldgutter-folded {\n    cursor: pointer;\n  }\n  .CodeMirror-foldgutter-open:after {\n    content: '▾';\n  }\n  .CodeMirror-foldgutter-folded:after {\n    content: '▸';\n  }\n  /* The lint marker gutter */\n  .CodeMirror-lint-markers {\n    width: 16px;\n  }\n\n  .CodeMirror-jump-token {\n    cursor: pointer;\n    text-decoration: underline;\n  }\n`\n\n// Styling of portal for hints\n// .CodeMirror-info info for types breaks stack trace\n// tslint:disable-next-line\nconst GlobalStyle = createGlobalStyle`\n  *::-webkit-scrollbar {\n    -webkit-appearance: none;\n    width: 7px;\n    height: 7px;\n  }\n  *::-webkit-scrollbar-track-piece {\n    background-color: rgba(255, 255, 255, 0);\n  }\n  *::-webkit-scrollbar-track {\n    background-color: inherit;\n  }\n  *::-webkit-scrollbar-thumb {\n    max-height: 100px;\n    border-radius: 3px;\n    background-color: rgba(1, 1, 1, 0.23);\n  }\n  *::-webkit-scrollbar-thumb:hover {\n    background-color: rgba(1, 1, 1, 0.35);\n  }\n  *::-webkit-scrollbar-thumb:active {\n    background-color: rgba(1, 1, 1, 0.48);\n  }\n  *::-webkit-scrollbar-corner {\n    background: rgba(0,0,0,0);\n  }\n\n\n  .CodeMirror-lint-tooltip, .CodeMirror-info {\n    background-color: white;\n    border-radius: 4px 4px 4px 4px;\n    border: 1px solid black;\n    color: #09141C;\n    font-family: Open Sans, monospace;\n    font-size: 14px;\n    max-width: 600px;\n    opacity: 0;\n    overflow: hidden;\n    padding: 12px 14px;\n    position: fixed;\n    -webkit-transition: opacity 0.4s;\n    transition: opacity 0.4s;\n    z-index: 100;\n  }\n\n  .CodeMirror-lint-message-error,\n  .CodeMirror-lint-message-warning {\n    padding-left: 18px;\n  }\n\n  .CodeMirror-lint-mark-error,\n  .CodeMirror-lint-mark-warning {\n    background-position: left bottom;\n    background-repeat: repeat-x;\n  }\n\n  .CodeMirror-lint-mark-error {\n    background-image: url('data:image/svg+xml;utf8,<svg width=\"5\" height=\"4\" viewBox=\"0 0 5 4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n    <path d=\"M5 1.00954C4.87191 1.03474 4.75219 1.10989 4.674 1.235L3.87 2.52141C3.28249 3.46141 1.9135 3.46141 1.326 2.52141L0.521998 1.235C0.404356 1.04677 0.19271 0.971619 0 1.00954V0.00314821C0.0325855 0.00105209 0.0652291 2.68503e-06 0.0978728 5.14592e-09C0.0977892 -1.71531e-09 0.0979564 -1.71531e-09 0.0978728 5.14592e-09C0.586954 4.01563e-05 1.07627 0.235041 1.37 0.705002L2.174 1.99141C2.36983 2.30474 2.82616 2.30474 3.022 1.99141L3.826 0.705002C4.10012 0.266408 4.54438 0.0324569 5 0.00314818V1.00954Z\" fill=\"#FF4F56\"/>\n    </svg>\n    ');\n  }\n\n  .CodeMirror-lint-mark-warning {\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=');\n  }\n\n  .CodeMirror-lint-marker-error,\n  .CodeMirror-lint-marker-warning {\n    background-position: center center;\n    background-repeat: no-repeat;\n    cursor: pointer;\n    display: inline-block;\n    height: 16px;\n    position: relative;\n    vertical-align: middle;\n    width: 16px;\n  }\n\n  .CodeMirror-lint-message-error,\n  .CodeMirror-lint-message-warning {\n    background-position: top left;\n    background-repeat: no-repeat;\n    padding-left: 22px;\n  }\n\n  .CodeMirror-lint-marker-error,\n  .CodeMirror-lint-message-error {\n    background-image: url('data:image/svg+xml;utf8,<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n    <circle cx=\"8\" cy=\"8\" r=\"8\" fill=\"#FF4F56\"/>\n    <path d=\"M4.2929 10.2928C3.90237 10.6833 3.90237 11.3164 4.29289 11.707C4.68341 12.0975 5.31657 12.0975 5.7071 11.707L4.2929 10.2928ZM11.7071 5.70711C12.0976 5.31659 12.0976 4.68343 11.7071 4.2929C11.3166 3.90237 10.6834 3.90237 10.2929 4.29289L11.7071 5.70711ZM5.7071 4.29301C5.31657 3.90249 4.68341 3.9025 4.29289 4.29302C3.90237 4.68355 3.90237 5.31672 4.2929 5.70724L5.7071 4.29301ZM10.2929 11.7071C10.6834 12.0976 11.3166 12.0976 11.7071 11.7071C12.0976 11.3166 12.0976 10.6834 11.7071 10.2929L10.2929 11.7071ZM5.7071 11.707L11.7071 5.70711L10.2929 4.29289L4.2929 10.2928L5.7071 11.707ZM4.2929 5.70724L10.2929 11.7071L11.7071 10.2929L5.7071 4.29301L4.2929 5.70724Z\" fill=\"white\"/>\n    </svg>\n    ');\n    background-position: 0 50%;\n  }\n\n  .CodeMirror-lint-marker-warning,\n  .CodeMirror-lint-message-warning {\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=');\n  }\n\n  .CodeMirror-lint-marker-multiple {\n    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC');\n    background-position: right bottom;\n    background-repeat: no-repeat;\n    width: 100%;\n    height: 100%;\n  }\n\n  .CodeMirror-lint-mark-error {\n    &:before {\n      content: '';\n      width: 50px;\n      height: 14px;\n      position: absolute;\n      background: #FF4F56;\n      left: -80px;\n      top: 50%;\n      transform: translateY(-50%);\n      z-index: 10;\n    }\n  }\n\n  .CodeMirror-lint-message-error span {\n    color: white;\n    background: #FF4F56;\n    font-family: 'Source Code Pro', monospace;\n    font-weight: 600;\n    border-radius: 2px;\n    padding: 0 4px;\n  }\n\n  .CodeMirror-hints {\n    background: white;\n    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);\n    font-size: 14px;\n    list-style: none;\n    margin-left: -6px;\n    margin: 0;\n    max-height: 20em;\n    overflow: hidden;\n    padding: 0;\n    position: absolute;\n    z-index: 10;\n    border-radius: 2px;\n    top: 0;\n    left: 0;\n    &:hover {\n      overflow-y: overlay;\n    }\n  }\n\n  .CodeMirror-hints-wrapper {\n    font-family: 'Open Sans', sans-serif;\n    background: white;\n    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);\n    margin-left: -6px;\n    position: absolute;\n    z-index: 10;\n  }\n\n  .CodeMirror-hints-wrapper .CodeMirror-hints {\n    box-shadow: none;\n    margin-left: 0;\n    position: relative;\n    z-index: 0;\n  }\n\n  .CodeMirror-hint {\n    color: rgba(15, 32, 45, 0.6);\n    cursor: pointer;\n    margin: 0;\n    max-width: 300px;\n    overflow: hidden;\n    padding: 6px 12px;\n    white-space: pre;\n  }\n\n  li.CodeMirror-hint-active {\n    background-color: #2a7ed3;\n    border-top-color: white;\n    color: white;\n  }\n\n  .CodeMirror-hint-information {\n    border-top: solid 1px rgba(0, 0, 0, 0.1);\n    max-width: 300px;\n    padding: 10px 12px;\n    position: relative;\n    z-index: 1;\n    background-color: rgba(15, 32, 45, 0.03);\n    font-size: 14px;\n  }\n\n  .CodeMirror-hint-information:first-child {\n    border-bottom: solid 1px #c0c0c0;\n    border-top: none;\n    margin-bottom: -1px;\n  }\n\n  .CodeMirror-hint-information .content {\n    color: rgba(15, 32, 45, 0.6);\n    box-orient: vertical;\n    display: -webkit-box;\n    display: -ms-flexbox;\n    display: flex;\n    line-clamp: 3;\n    line-height: 1.36;\n    max-height: 59px;\n    overflow: hidden;\n    text-overflow: -o-ellipsis-lastline;\n  }\n\n  .CodeMirror-hint-information .content p:first-child {\n    margin-top: 0;\n  }\n\n  .CodeMirror-hint-information .content p:last-child {\n    margin-bottom: 0;\n  }\n\n  .CodeMirror-hint-information .infoType {\n    color: rgb(241, 143, 1);\n    cursor: pointer;\n    display: inline;\n    margin-right: 0.5em;\n  }\n`\n\nconst Wrapper = ({ children }) => {\n  function lintMessage(e) {\n    if (e.target.classList.contains('CodeMirror-lint-mark-error')) {\n      const items = document.getElementsByClassName(\n        'CodeMirror-lint-message-error',\n      )\n      for (const item of Array.from(items)) {\n        item.innerHTML = item.innerHTML.replace(/\"(.*?)\"/g, '<span>$1</span>')\n      }\n    }\n  }\n  return (\n    <EditorWrapper onMouseMove={lintMessage}>\n      {children}\n      <GlobalStyle />\n    </EditorWrapper>\n  )\n}\n\nconst GraphqlContainer = styled.div`\n  color: #141823;\n  display: flex;\n  flex-direction: row;\n  font-family: system, -apple-system, 'San Francisco', '.SFNSDisplay-Regular',\n    'Segoe UI', Segoe, 'Segoe WP', 'Helvetica Neue', helvetica, 'Lucida Grande',\n    arial, sans-serif;\n  font-size: 14px;\n  height: 100%;\n  margin: 0;\n  overflow: hidden;\n  width: 100%;\n`\n\nexport class Container extends React.PureComponent {\n  private graphqlContainer\n\n  render() {\n    return (\n      <GraphqlContainer ref={this.setGraphqlContainer}>\n        {this.props.children}\n      </GraphqlContainer>\n    )\n  }\n\n  getWidth = () => {\n    return this.graphqlContainer.offsetWidth\n  }\n\n  private setGraphqlContainer = ref => {\n    this.graphqlContainer = ref\n  }\n}\n\nexport default Wrapper\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExecuteButton.tsx",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nimport * as React from 'react'\nimport ExecuteButtonOperation from './ExecuteButtonOperation'\nimport { styled } from '../../styled'\nimport { connect } from 'react-redux'\nimport { runQuery, stopQuery } from '../../state/sessions/actions'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getQueryRunning,\n  getOperations,\n  getSelectedSessionIdFromRoot,\n} from '../../state/sessions/selectors'\nimport { toJS } from './util/toJS'\n\nexport interface ReduxProps {\n  runQuery: (operationName?: string) => void\n  stopQuery: (sessionId: string) => void\n  queryRunning: boolean\n  operations: any[]\n  sessionId: string\n}\n\nexport interface State {\n  optionsOpen: boolean\n  highlight: any\n}\n\nlet firstTime = true\n\n/**\n * ExecuteButton\n *\n * What a nice round shiny button. Shows a drop-down when there are multiple\n * queries to run.\n */\nclass ExecuteButton extends React.Component<ReduxProps, State> {\n  constructor(props) {\n    super(props)\n\n    this.state = {\n      optionsOpen: false,\n      highlight: null,\n    }\n  }\n\n  render() {\n    const { operations } = this.props\n    const optionsOpen = this.state.optionsOpen\n    const hasOptions = operations && operations.length > 1\n\n    let options: any = null\n    if (hasOptions && optionsOpen) {\n      const highlight = this.state.highlight\n      options = (\n        <ExecuteBox>\n          <ExecuteOptions>\n            {operations.map(operation => (\n              <ExecuteButtonOperation\n                operation={operation}\n                onMouseOver={this.handleMouseOver}\n                onMouseOut={this.handleMouseOut}\n                onMouseUp={this.handleMouseUp}\n                highlight={highlight}\n                key={operation.name ? operation.name.value : '*'}\n              />\n            ))}\n          </ExecuteOptions>\n        </ExecuteBox>\n      )\n    }\n\n    // Allow click event if there is a running query or if there are not options\n    // for which operation to run.\n    let onClick\n    if (this.props.queryRunning || !hasOptions) {\n      onClick = this.onClick\n    }\n\n    // Allow mouse down if there is no running query, there are options for\n    // which operation to run, and the dropdown is currently closed.\n    let onMouseDown\n    if (!this.props.queryRunning && hasOptions && !optionsOpen) {\n      onMouseDown = this.onOptionsOpen\n    }\n\n    const pathJSX = this.props.queryRunning ? (\n      <rect fill=\"#FFFFFF\" x=\"10\" y=\"10\" width=\"13\" height=\"13\" rx=\"1\" />\n    ) : (\n      <path d=\"M 11 9 L 24 16 L 11 23 z\" />\n    )\n\n    return (\n      <Wrapper>\n        <Button\n          isRunning={this.props.queryRunning}\n          onMouseDown={onMouseDown}\n          onClick={onClick}\n          title=\"Execute Query (Ctrl-Enter)\"\n        >\n          <svg\n            width=\"35\"\n            height=\"35\"\n            viewBox={`${this.props.queryRunning ? 4 : 3}.5,4.5,24,24`}\n          >\n            {pathJSX}\n          </svg>\n        </Button>\n        {options}\n      </Wrapper>\n    )\n  }\n\n  private handleMouseOver = (operation: any) => {\n    this.setState({ highlight: operation })\n  }\n\n  private handleMouseOut = () => {\n    this.setState({ highlight: null })\n  }\n\n  private handleMouseUp = (operation: any) => {\n    this.onOptionSelected(operation)\n  }\n\n  private onClick = () => {\n    if (this.props.queryRunning) {\n      this.props.stopQuery(this.props.sessionId)\n    } else {\n      this.props.runQuery()\n    }\n  }\n\n  private onOptionSelected = operation => {\n    this.setState({ optionsOpen: false } as State)\n    if (!operation) {\n      return\n    }\n    this.props.runQuery(operation.name && operation.name.value)\n  }\n\n  private onOptionsOpen = downEvent => {\n    let initialPress = true\n    const downTarget = downEvent.target\n    this.setState({ highlight: null, optionsOpen: true })\n\n    let onMouseUp: any = upEvent => {\n      if (initialPress && upEvent.target === downTarget) {\n        initialPress = false\n      } else {\n        document.removeEventListener('mouseup', onMouseUp)\n        onMouseUp = null\n        if (downTarget.parentNode) {\n          const isOptionsMenuClicked =\n            // tslint:disable-next-line\n            downTarget.parentNode.compareDocumentPosition(upEvent.target) &\n            Node.DOCUMENT_POSITION_CONTAINED_BY\n          if (!isOptionsMenuClicked) {\n            // menu calls setState if it was clicked\n            this.setState({ optionsOpen: false } as State)\n          }\n          if (firstTime) {\n            this.onOptionSelected(\n              this.props.operations.find(\n                op => op.name.value === upEvent.target.textContent,\n              ) || this.props.operations[0],\n            )\n            firstTime = false\n          }\n        }\n      }\n    }\n\n    document.addEventListener('mouseup', onMouseUp)\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  queryRunning: getQueryRunning,\n  operations: getOperations,\n  sessionId: getSelectedSessionIdFromRoot,\n})\n\nexport default connect(\n  mapStateToProps,\n  { runQuery, stopQuery },\n)(toJS(ExecuteButton))\n\nconst Wrapper = styled.div`\n  position: absolute;\n  left: -62px;\n  z-index: 5;\n  top: 15px;\n  margin: 0 14px 0 28px;\n`\n\ninterface ButtonProps {\n  isRunning: boolean\n}\n\nconst Button = styled<ButtonProps, 'div'>('div')`\n  width: 60px;\n  height: 60px;\n\n  display: flex;\n  align-items: center;\n  justify-content: center;\n\n  border-radius: 100%;\n  transition: background-color 100ms;\n  background-color: ${p =>\n    p.isRunning\n      ? p.theme.editorColours.executeButtonSubscription\n      : p.theme.editorColours.executeButton};\n  border: 6px solid ${p => p.theme.editorColours.executeButtonBorder};\n  cursor: pointer;\n  user-select: none;\n\n  svg {\n    fill: ${p => (p.theme.mode === 'light' ? 'white' : 'inherit')};\n  }\n\n  &:hover {\n    background-color: ${p =>\n      p.isRunning\n        ? p.theme.editorColours.executeButtonSubscriptionHover\n        : p.theme.editorColours.executeButtonHover};\n  }\n`\n\nconst ExecuteBox = styled.div`\n  background: #fff;\n  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.25);\n  padding: 8px 0;\n  left: -1px;\n  margin: 0;\n  position: absolute;\n  top: 78px;\n  z-index: 100;\n  user-select: none;\n\n  &:before {\n    position: absolute;\n    background: white;\n    content: '';\n    top: -4px;\n    left: 34px;\n    transform: rotate(45deg);\n    width: 8px;\n    height: 8px;\n  }\n`\n\nconst ExecuteOptions = styled.ul`\n  max-height: 270px;\n  overflow: scroll;\n\n  li {\n    cursor: pointer;\n    list-style: none;\n    min-width: 100px;\n    padding: 2px 30px 4px 10px;\n  }\n\n  li.selected {\n    background: rgb(39, 174, 96);\n    color: white;\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExecuteButtonOperation.tsx",
    "content": "import * as React from 'react'\n\nexport interface Props {\n  operation: any\n  onMouseOver: (operation: any) => void\n  onMouseOut: () => void\n  onMouseUp: (operation: any) => void\n  highlight: any\n}\n\nclass ExecuteButtonOperation extends React.PureComponent<Props> {\n  render() {\n    return (\n      <li\n        key={this.props.operation.name ? this.props.operation.name.value : '*'}\n        className={\n          this.props.operation === this.props.highlight ? 'selected' : ''\n        }\n        onMouseOver={this.onMouseOver}\n        onMouseOut={this.props.onMouseOut}\n        onMouseUp={this.onMouseUp}\n      >\n        {this.props.operation.name\n          ? this.props.operation.name.value\n          : '<Unnamed>'}\n      </li>\n    )\n  }\n  private onMouseOver = () => {\n    this.props.onMouseOver(this.props.operation)\n  }\n\n  private onMouseUp = () => {\n    this.props.onMouseUp(this.props.operation)\n  }\n}\n\nexport default ExecuteButtonOperation\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExplorerTabs/SideTab.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  label: string\n  activeColor: string\n  children: any\n  active?: boolean\n  tabWidth?: string\n  onClick?: () => any\n}\n\nexport default class SideTab extends React.PureComponent<Props> {\n  render() {\n    const { label, activeColor, active, onClick, tabWidth } = this.props\n    return (\n      <Tab\n        onClick={onClick}\n        activeColor={activeColor}\n        active={active}\n        tabWidth={tabWidth}\n      >\n        {label}\n      </Tab>\n    )\n  }\n}\n\nexport interface TabProps {\n  active: boolean\n  activeColor: string\n}\n\nconst Tab = styled<TabProps, 'div'>('div')`\n  z-index: ${p => (p.active ? 10 : 2)};\n  padding: 8px 8px 8px 8px;\n  border-radius: 2px 2px 0px 0px;\n  color: ${p =>\n    p.theme.mode === 'dark'\n      ? p.theme.colours.white\n      : p.theme.colours[p.active ? 'white' : 'darkBlue']};\n  background: ${p =>\n    p.active && p.activeColor\n      ? p.theme.colours[p.activeColor]\n      : p.theme.mode === 'dark'\n        ? '#3D5866'\n        : '#DBDEE0'};\n  box-shadow: -1px 1px 6px 0 rgba(0, 0, 0, 0.3);\n  text-transform: uppercase;\n  text-align: center;\n  font-weight: 600;\n  font-size: 12px;\n  line-height: 12px;\n  letter-spacing: 0.45px;\n  cursor: pointer;\n  transform: rotate(-90deg);\n  transform-origin: bottom left;\n  margin-top: 65px;\n  width: ${p => p.tabWidth || '100%'};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExplorerTabs/SideTabs.tsx",
    "content": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport * as keycode from 'keycode'\nimport { getLeft } from 'graphiql/dist/utility/elementPosition'\nimport {\n  addStack,\n  toggleDocs,\n  changeKeyMove,\n  setDocsVisible,\n  changeWidthDocs\n} from '../../../state/docs/actions'\nimport { GraphQLSchema } from 'graphql'\nimport { getSessionDocs } from '../../../state/docs/selectors'\nimport { getSelectedSessionIdFromRoot } from '../../../state/sessions/selectors'\nimport { createStructuredSelector } from 'reselect'\nimport { styled } from '../../../styled'\nimport SideTab from './SideTab'\n\ninterface StateFromProps {\n  docs: {\n    navStack: any[]\n    docsOpen: boolean\n    docsWidth: number\n    keyMove: boolean\n    activeTabIdx: number\n  }\n}\n\ninterface DispatchFromProps {\n  addStack: (sessionId: string, field: any, x: number, y: number) => any\n  toggleDocs: (sessionId: string, activeTabIdx?: number | null) => any\n  setDocsVisible: (sessionId: string, open: boolean, idx?: number | null) => any\n  changeWidthDocs: (sessionId: string, width: number) => any\n  changeKeyMove: (sessionId: string, move: boolean) => any\n}\n\nexport interface Props {\n  schema: GraphQLSchema\n  sessionId: string\n  children: Array<React.ReactElement<any>>\n  maxWidth: number\n  setWidth: (props?: any) => any\n  setActiveContentRef: (ref: any) => void\n}\n\nexport interface SideTabContentProps {\n  schema: GraphQLSchema\n  sessionId?: string\n  ref?: any\n  setWidth?: (props?: any) => any\n}\n\nexport interface State {\n  searchValue: string\n  widthMap: any\n}\n\nclass SideTabs extends React.Component<\n  Props & StateFromProps & DispatchFromProps,\n  State\n> {\n  ref\n  private refContentContainer: any\n  private clientX: number = 0\n  private clientY: number = 0\n  constructor(props) {\n    super(props)\n    ;(window as any).d = this\n  }\n\n  componentDidUpdate(prevProps) {\n    if (!prevProps.docs.activeTabIdx && this.props.docs.activeTabIdx) {\n      this.props.setDocsVisible(\n        this.props.sessionId,\n        true,\n        this.props.docs.activeTabIdx,\n      )\n    }\n    if (prevProps.activeTabIdx && !this.props.docs.activeTabIdx) {\n      this.props.setDocsVisible(this.props.sessionId, false)\n    }\n    this.props.setWidth()\n    if (\n      this.props.docs.activeTabIdx !== prevProps.docs.activeTabIdx &&\n      this.refContentContainer\n    ) {\n      this.refContentContainer.focus()\n    }\n  }\n\n  componentDidMount() {\n    if (!this.props.docs.activeTabIdx) {\n      this.props.setDocsVisible(this.props.sessionId, false)\n    }\n    return this.props.setWidth()\n  }\n\n  render() {\n    const { docsOpen, docsWidth, activeTabIdx } = this.props.docs\n    const docsStyle = { width: docsOpen ? docsWidth : 0 }\n    const activeTab =\n      docsOpen &&\n      (React.Children.toArray(this.props.children)[\n        activeTabIdx\n      ] as React.ReactElement<any>)\n    return (\n      <Tabs open={docsOpen} style={docsStyle} ref={this.setRef}>\n        <TabsContainer>\n          {React.Children.toArray(this.props.children).map(\n            (child: React.ReactElement<any>, index) => {\n              return React.cloneElement(child, {\n                ...child.props,\n                key: index,\n                onClick: this.handleTabClick(index),\n                active: index === activeTabIdx,\n              })\n            },\n          )}\n        </TabsContainer>\n        <TabContentResizer onMouseDown={this.handleDocsResizeStart} />\n        <TabsGradient index={activeTabIdx} />\n        <TabContentContainer\n          onKeyDown={this.handleKeyDown}\n          onMouseMove={this.handleMouseMove}\n          tabIndex={activeTabIdx}\n          color={activeTab ? activeTab.props.activeColor : undefined}\n          ref={this.setContentContainerRef}\n        >\n          {activeTab &&\n            React.cloneElement(activeTab.props.children, {\n              ...activeTab.props,\n              ref: this.props.setActiveContentRef,\n              setWidth: this.props.setWidth,\n            })}\n        </TabContentContainer>\n      </Tabs>\n    )\n  }\n\n  setRef = ref => {\n    this.ref = ref\n  }\n\n  private setContentContainerRef = ref => {\n    this.refContentContainer = ref\n  }\n\n  private handleTabClick = idx => () => {\n    if (this.props.docs.activeTabIdx === idx) {\n      this.props.setDocsVisible(this.props.sessionId, false)\n      return this.props.setWidth()\n    }\n    if (this.props.docs.activeTabIdx !== idx) {\n      this.props.setDocsVisible(\n        this.props.sessionId,\n        false,\n        this.props.docs.activeTabIdx,\n      )\n      this.props.setDocsVisible(this.props.sessionId, true, idx)\n      return this.props.setWidth()\n    } else {\n      this.props.setDocsVisible(this.props.sessionId, true, idx)\n      return this.props.setWidth()\n    }\n  }\n\n  private handleKeyDown = e => {\n    // we don't want to interfere with inputs\n    if (\n      e.target instanceof HTMLInputElement ||\n      e.metaKey ||\n      e.shiftKey ||\n      e.altKey ||\n      e.ctrlKey\n    ) {\n      return\n    }\n    const keyPressed = keycode(e)\n    switch (keyPressed) {\n      case 'esc':\n        this.props.changeKeyMove(this.props.sessionId, true)\n        e.preventDefault()\n        this.props.setDocsVisible(this.props.sessionId, false)\n        break\n    }\n  }\n\n  private handleDocsResizeStart = downEvent => {\n    downEvent.preventDefault()\n\n    const hadWidth = this.props.docs.docsWidth\n    const offset = downEvent.clientX - getLeft(downEvent.target)\n\n    let onMouseMove: any = moveEvent => {\n      if (moveEvent.buttons === 0) {\n        return onMouseUp()\n      }\n\n      const app = this.ref\n      const cursorPos = moveEvent.clientX - getLeft(app) - offset\n      const newSize = app.clientWidth - cursorPos\n      const maxSize = window.innerWidth - 50\n      const docsSize = maxSize < newSize ? maxSize : newSize\n\n      if (docsSize < 100) {\n        this.props.setDocsVisible(\n          this.props.sessionId,\n          false,\n          this.props.docs.activeTabIdx,\n        )\n      } else {\n        this.props.setDocsVisible(\n          this.props.sessionId,\n          true,\n          this.props.docs.activeTabIdx,\n        )\n        this.props.changeWidthDocs(this.props.sessionId, docsSize)\n      }\n    }\n\n    let onMouseUp: any = () => {\n      if (!this.props.docs.docsOpen) {\n        this.props.changeWidthDocs(this.props.sessionId, hadWidth)\n      }\n\n      document.removeEventListener('mousemove', onMouseMove)\n      document.removeEventListener('mouseup', onMouseUp)\n      onMouseMove = null\n      onMouseUp = null\n    }\n\n    document.addEventListener('mousemove', onMouseMove)\n    document.addEventListener('mouseup', onMouseUp)\n  }\n  private handleMouseMove = e => {\n    this.clientX = e.clientX\n    this.clientY = e.clientY\n    if (\n      this.props.docs.keyMove &&\n      this.clientX !== e.clientX &&\n      this.clientY !== e.clientY\n    ) {\n      this.props.changeKeyMove(this.props.sessionId, false)\n    }\n  }\n}\n\nconst mapDispatchToProps = dispatch =>\n  bindActionCreators(\n    {\n      addStack,\n      toggleDocs,\n      changeKeyMove,\n      setDocsVisible,\n      changeWidthDocs\n    },\n    dispatch,\n  )\n\nconst mapStateToProps = createStructuredSelector({\n  docs: getSessionDocs,\n  sessionId: getSelectedSessionIdFromRoot,\n})\n\nconst ConnectedGraphDocs = connect<StateFromProps, DispatchFromProps, Props>(\n  mapStateToProps,\n  // @ts-ignore\n  mapDispatchToProps,\n  null,\n  { forwardRef: true },\n)(SideTabs)\n\n// @ts-ignore\nConnectedGraphDocs.Tab = SideTab\n\nexport default ConnectedGraphDocs\n\ninterface TabsProps {\n  open: boolean\n}\n\nconst Tabs = styled<TabsProps, 'div'>('div')`\n  background: white;\n  outline: none;\n  box-shadow: 0 0 8px rgba(0, 0, 0, 0.15);\n  position: absolute;\n  right: 0px;\n  z-index: ${p => (p.open ? 2000 : 3)};\n  height: 100%;\n  font-family: 'Open Sans', sans-serif;\n  -webkit-font-smoothing: antialiased;\n  .doc-type-description p {\n    padding: 16px;\n    font-size: 14px;\n  }\n  .field-name {\n    color: #1f61a0;\n  }\n  .type-name {\n    color: rgb(245, 160, 0);\n  }\n  .arg-name {\n    color: #1f61a9;\n  }\n  code {\n    font-family: 'Source Code Pro', monospace;\n    border-radius: 2px;\n    padding: 1px 2px;\n    background: rgba(0, 0, 0, 0.06);\n  }\n`\n\nconst TabContentContainer = styled.div`\n  background: white;\n  display: flex;\n  position: relative;\n  height: 100%;\n  letter-spacing: 0.3px;\n  box-shadow: -1px 1px 6px 0 rgba(0, 0, 0, 0.3);\n  outline: none;\n  &::before {\n    top: 0;\n    bottom: 0;\n    background: ${props =>\n      props.color ? props.theme.colours[props.color] : '#3D5866'};\n    position: absolute;\n    z-index: 3;\n    left: 0px;\n    content: '';\n    width: 6px;\n  }\n`\n\nconst TabContentResizer = styled.div`\n  cursor: col-resize;\n  outline: none !important;\n  height: 100%;\n  left: -5px;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  width: 10px;\n  z-index: 10;\n`\n\nconst TabsContainer = styled.div`\n  position: absolute;\n  outline: none !important;\n  z-index: 2;\n  height: 0;\n  top: 129px;\n`\n\nconst TabsGradient = styled.div`\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 20px;\n  z-index: 1;\n  pointer-events: none;\n  content: '';\n  background: ${p =>\n    p.index === 0\n      ? `linear-gradient(\n\t\tto right,\n\t\trgba(255, 255, 255, 1) 30%,\n\t\trgba(255, 255, 255, 0))`\n      : `transparent`};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/GraphQLEditor.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport { isNamedType, GraphQLSchema } from 'graphql'\nimport { List } from 'immutable'\n\n// Query & Response Components\nimport ExecuteButton from './ExecuteButton'\nimport QueryEditor from './QueryEditor'\nimport EditorWrapper, { Container } from './EditorWrapper'\nimport CodeMirrorSizer from 'graphiql/dist/utility/CodeMirrorSizer'\nimport TopBar from './TopBar/TopBar'\nimport {\n  VariableEditorComponent,\n  HeadersEditorComponent,\n} from './VariableEditor'\nimport Spinner from '../Spinner'\nimport Results from './Results'\nimport ResponseTracing from './ResponseTracing'\nimport { fillLeafs } from 'graphiql/dist/utility/fillLeafs'\nimport { getLeft, getTop } from 'graphiql/dist/utility/elementPosition'\n\n// Explorer Components\nimport SideTab from './ExplorerTabs/SideTab'\nimport SideTabs from './ExplorerTabs/SideTabs'\nimport SDLView from './SchemaExplorer/SDLView'\nimport GraphDocs from './DocExplorer/GraphDocs'\n\nimport { styled } from '../../styled/index'\n\n// Redux Dependencies\nimport { connect } from 'react-redux'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getQueryRunning,\n  getResponses,\n  getSubscriptionActive,\n  getVariableEditorOpen,\n  getVariableEditorHeight,\n  getResponseTracingOpen,\n  getResponseTracingHeight,\n  getResponseExtensions,\n  getCurrentQueryStartTime,\n  getCurrentQueryEndTime,\n  getTracingSupported,\n  getEditorFlex,\n  getQueryVariablesActive,\n  getHeaders,\n  getOperations,\n  getOperationName,\n  getHeadersCount,\n  getSelectedSessionIdFromRoot,\n} from '../../state/sessions/selectors'\nimport {\n  updateQueryFacts,\n  stopQuery,\n  runQueryAtPosition,\n  closeQueryVariables,\n  openQueryVariables,\n  openVariables,\n  closeVariables,\n  openTracing,\n  closeTracing,\n  toggleTracing,\n  setEditorFlex,\n  toggleVariables,\n  fetchSchema,\n} from '../../state/sessions/actions'\nimport { ResponseRecord } from '../../state/sessions/reducers'\nimport { getDocsOpen } from '../../state/docs/selectors'\nimport { changeWidthDocs } from '../../state/docs/actions'\n\n/**\n * The top-level React component for GraphQLEditor, intended to encompass the entire\n * browser viewport.\n */\n\nexport interface Props {\n  onRef?: any\n  shareEnabled?: boolean\n  fixedEndpoint?: boolean\n  schema?: GraphQLSchema\n}\n\nexport interface ReduxProps {\n  setStacks: (sessionId: string, stack: any[]) => void\n  updateQueryFacts: () => void\n  runQueryAtPosition: (position: number) => void\n  fetchSchema: () => void\n  openQueryVariables: () => void\n  closeQueryVariables: () => void\n  openVariables: (height: number) => void\n  closeVariables: (height: number) => void\n  openTracing: (height: number) => void\n  closeTracing: (height: number) => void\n  toggleTracing: () => void\n  toggleVariables: () => void\n  setEditorFlex: (flex: number) => void\n  stopQuery: (sessionId: string) => void\n  changeWidthDocs: (sessionId: string, width: number) => void\n  navStack: any[]\n  docsOpen: boolean\n  // sesion props\n  queryRunning: boolean\n  responses: List<ResponseRecord>\n  subscriptionActive: boolean\n  variableEditorOpen: boolean\n  variableEditorHeight: number\n  currentQueryStartTime?: Date\n  currentQueryEndTime?: Date\n  responseTracingOpen: boolean\n  responseTracingHeight: number\n  responseExtensions: any\n  tracingSupported?: boolean\n  editorFlex: number\n  headers: string\n  headersCount: number\n  queryVariablesActive: boolean\n  operationName: string\n  query: string\n  sessionId: string\n}\n\nexport interface SimpleProps {\n  children?: any\n}\n\nexport interface ToolbarButtonProps extends SimpleProps {\n  onClick: (e: any) => void\n  title: string\n  label: string\n}\n\nclass GraphQLEditor extends React.PureComponent<Props & ReduxProps> {\n  public codeMirrorSizer\n  public queryEditorComponent\n  public variableEditorComponent\n  public resultComponent\n  public editorBarComponent\n  public docExplorerComponent: any // later React.Component<...>\n  public graphExplorerComponent: any\n  public schemaExplorerComponent: any\n  private queryResizer: any\n  private responseResizer: any\n  private queryVariablesRef\n  private httpHeadersRef\n  private containerComponent\n  private activeSideTabContent\n\n  componentDidMount() {\n    // Ensure a form of a schema exists (including `null`) and\n    // if not, fetch one using an introspection query.\n    // this.props.fetchSchema()\n\n    // Utility for keeping CodeMirror correctly sized.\n    this.codeMirrorSizer = new CodeMirrorSizer()\n    ;(global as any).g = this\n  }\n\n  componentDidUpdate() {\n    // If this update caused DOM nodes to have changed sizes, update the\n    // corresponding CodeMirror instance sizes to match.\n    // const components = [\n    // this.queryEditorComponent,\n    // this.variableEditorComponent,\n    // this.resultComponent,\n    // ]\n    // this.codeMirrorSizer.updateSizes(components)\n    if (this.resultComponent && Boolean(this.props.subscriptionActive)) {\n      this.resultComponent.scrollTop = this.resultComponent.scrollHeight\n    }\n  }\n\n  render() {\n    return (\n      <Container ref={this.setContainerComponent}>\n        <EditorWrapper>\n          <TopBar\n            shareEnabled={this.props.shareEnabled}\n          />\n          <EditorBar\n            ref={this.setEditorBarComponent}\n            onMouseDown={this.handleResizeStart}\n          >\n            <QueryWrap flex={this.props.editorFlex}>\n              <QueryEditor\n                getRef={this.setQueryEditorComponent}\n                schema={this.props.schema}\n                onHintInformationRender={this.handleHintInformationRender}\n                onRunQuery={this.runQueryAtCursor}\n                onClickReference={this.handleClickReference}\n              />\n              <VariableEditor\n                isOpen={this.props.variableEditorOpen}\n                height={this.props.variableEditorHeight}\n              >\n                <VariableEditorTitle\n                  isOpen={this.props.variableEditorOpen}\n                  onMouseDown={this.handleVariableResizeStart}\n                >\n                  <VariableEditorSubtitle\n                    isOpen={this.props.queryVariablesActive}\n                    ref={this.setQueryVariablesRef}\n                    onClick={this.props.openQueryVariables}\n                  >\n                    Query Variables\n                  </VariableEditorSubtitle>\n                  <VariableEditorSubtitle\n                    isOpen={!this.props.queryVariablesActive}\n                    ref={this.setHttpHeadersRef}\n                    onClick={this.props.closeQueryVariables}\n                  >\n                    {'HTTP Headers ' +\n                      (this.props.headersCount && this.props.headersCount > 0\n                        ? `(${this.props.headersCount})`\n                        : '')}\n                  </VariableEditorSubtitle>\n                </VariableEditorTitle>\n                {this.props.queryVariablesActive ? (\n                  <VariableEditorComponent\n                    getRef={this.setVariableEditorComponent}\n                    onHintInformationRender={\n                      this.props.queryVariablesActive\n                        ? this.handleHintInformationRender\n                        : undefined\n                    }\n                    onRunQuery={this.runQueryAtCursor}\n                  />\n                ) : (\n                  <HeadersEditorComponent\n                    getRef={this.setVariableEditorComponent}\n                    onHintInformationRender={\n                      this.props.queryVariablesActive\n                        ? this.handleHintInformationRender\n                        : undefined\n                    }\n                    onRunQuery={this.runQueryAtCursor}\n                  />\n                )}\n              </VariableEditor>\n              <QueryDragBar ref={this.setQueryResizer} />\n            </QueryWrap>\n            <ResultWrap>\n              <ResultDragBar ref={this.setResponseResizer} />\n              <ExecuteButton />\n              {this.props.queryRunning &&\n                this.props.responses.size === 0 && <Spinner />}\n              <Results setRef={this.setResultComponent} />\n              {!this.props.queryRunning &&\n                (!this.props.responses || this.props.responses.size === 0) && (\n                  <Intro>Press the Play Button to get a response here</Intro>\n                )}\n              {this.props.subscriptionActive && (\n                <Listening>Listening &hellip;</Listening>\n              )}\n              <ResponseTracking\n                isOpen={this.props.responseTracingOpen}\n                height={this.props.responseTracingHeight}\n              >\n                <ResponseTrackingTitle\n                  isOpen={this.props.responseTracingOpen}\n                  onMouseDown={this.handleTracingResizeStart}\n                >\n                  <VariableEditorSubtitle isOpen={false}>\n                    Tracing\n                  </VariableEditorSubtitle>\n                </ResponseTrackingTitle>\n                <ResponseTracing open={this.props.responseTracingOpen} />\n              </ResponseTracking>\n            </ResultWrap>\n          </EditorBar>\n        </EditorWrapper>\n        <SideTabs\n          sessionId={this.props.sessionId}\n          schema={this.props.schema}\n          setActiveContentRef={this.setSideTabActiveContentRef}\n          setWidth={this.setDocsWidth}\n          maxWidth={10000}\n        >\n          <SideTab label=\"Docs\" activeColor=\"green\" tabWidth=\"49px\">\n            <GraphDocs\n              schema={this.props.schema}\n              ref={this.setDocExplorerRef}\n            />\n          </SideTab>\n          <SideTab label=\"Schema\" activeColor=\"blue\" tabWidth=\"65px\">\n            <SDLView\n              schema={this.props.schema}\n              ref={this.setSchemaExplorerRef}\n              sessionId={this.props.sessionId}\n              setWidth={this.setDocsWidth}\n            />\n          </SideTab>\n        </SideTabs>\n      </Container>\n    )\n  }\n\n  setQueryVariablesRef = ref => {\n    this.queryVariablesRef = ref\n  }\n\n  setHttpHeadersRef = ref => {\n    this.httpHeadersRef = ref\n  }\n\n  setQueryResizer = ref => {\n    this.queryResizer = ReactDOM.findDOMNode(ref)\n  }\n\n  setResponseResizer = ref => {\n    this.responseResizer = ReactDOM.findDOMNode(ref)\n  }\n\n  setEditorBarComponent = ref => {\n    this.editorBarComponent = ref\n  }\n\n  setQueryEditorComponent = ref => {\n    this.queryEditorComponent = ref\n  }\n\n  setVariableEditorComponent = ref => {\n    this.variableEditorComponent = ref\n  }\n\n  setResultComponent = ref => {\n    this.resultComponent = ref\n  }\n\n  setDocExplorerRef = ref => {\n    if (ref) {\n      this.docExplorerComponent = ref.getWrappedInstance()\n    }\n  }\n  setGraphExplorerRef = ref => {\n    if (ref) {\n      this.graphExplorerComponent = ref.getWrappedInstance()\n    }\n  }\n  setSchemaExplorerRef = ref => {\n    if (ref) {\n      this.schemaExplorerComponent = ref\n    }\n  }\n  setContainerComponent = ref => {\n    this.containerComponent = ref\n  }\n\n  handleClickReference = reference => {\n    if (this.docExplorerComponent) {\n      this.docExplorerComponent.showDocFromType(reference.field || reference)\n    }\n  }\n\n  setSideTabActiveContentRef = ref => {\n    if (ref) {\n      this.activeSideTabContent = ref\n    }\n  }\n\n  /**\n   * Inspect the query, automatically filling in selection sets for non-leaf\n   * fields which do not yet have them.\n   *\n   * @public\n   */\n  autoCompleteLeafs() {\n    const { insertions, result } = fillLeafs(\n      this.props.schema,\n      this.props.query,\n    ) as {\n      insertions: Array<{ index: number; string: string }>\n      result: string\n    }\n    if (insertions && insertions.length > 0) {\n      const editor = this.queryEditorComponent.getCodeMirror()\n      editor.operation(() => {\n        const cursor = editor.getCursor()\n        const cursorIndex = editor.indexFromPos(cursor)\n        editor.setValue(result)\n        let added = 0\n        try {\n          /* tslint:disable-next-line */\n          const markers = insertions.map(({ index, string }) =>\n            editor.markText(\n              editor.posFromIndex(index + added),\n              editor.posFromIndex(index + (added += string.length)),\n              {\n                className: 'autoInsertedLeaf',\n                clearOnEnter: true,\n                title: 'Automatically added leaf fields',\n              },\n            ),\n          )\n          setTimeout(() => markers.forEach(marker => marker.clear()), 7000)\n        } catch (e) {\n          //\n        }\n        let newCursorIndex = cursorIndex\n        /* tslint:disable-next-line */\n        insertions.forEach(({ index, string }) => {\n          if (index < cursorIndex && string) {\n            newCursorIndex += string.length\n          }\n        })\n        editor.setCursor(editor.posFromIndex(newCursorIndex))\n      })\n    }\n\n    return result\n  }\n\n  private runQueryAtCursor = () => {\n    if (this.props.queryRunning) {\n      this.props.stopQuery(this.props.sessionId)\n      return\n    }\n\n    const editor = this.queryEditorComponent.getCodeMirror()\n    const cursor = editor.getCursor()\n    const cursorIndex = editor.indexFromPos(cursor)\n    this.props.runQueryAtPosition(cursorIndex)\n  }\n\n  private handleHintInformationRender = elem => {\n    elem.addEventListener('click', this.onClickHintInformation)\n\n    let onRemoveFn\n    elem.addEventListener(\n      'DOMNodeRemoved',\n      (onRemoveFn = () => {\n        elem.removeEventListener('DOMNodeRemoved', onRemoveFn)\n        elem.removeEventListener('click', this.onClickHintInformation)\n      }),\n    )\n  }\n\n  private handleResizeStart = downEvent => {\n    if (!this.didClickDragBar(downEvent)) {\n      return\n    }\n\n    downEvent.preventDefault()\n\n    const offset = downEvent.clientX - getLeft(downEvent.target)\n\n    let onMouseMove: any = moveEvent => {\n      if (moveEvent.buttons === 0) {\n        return onMouseUp()\n      }\n\n      const editorBar = ReactDOM.findDOMNode(this.editorBarComponent) as Element\n      const leftSize = moveEvent.clientX - getLeft(editorBar) - offset\n      const rightSize = editorBar.clientWidth - leftSize\n      this.props.setEditorFlex(leftSize / rightSize)\n    }\n\n    let onMouseUp: any = () => {\n      document.removeEventListener('mousemove', onMouseMove)\n      document.removeEventListener('mouseup', onMouseUp)\n      onMouseMove = null\n      onMouseUp = null\n    }\n\n    document.addEventListener('mousemove', onMouseMove)\n    document.addEventListener('mouseup', onMouseUp)\n  }\n\n  private didClickDragBar(event) {\n    // Only for primary unmodified clicks\n    return (\n      event.target === this.queryResizer ||\n      event.target === this.responseResizer\n    )\n  }\n\n  private handleTracingResizeStart = downEvent => {\n    downEvent.preventDefault()\n\n    let didMove = false\n    const hadHeight = this.props.responseTracingHeight\n    const offset = downEvent.clientY - getTop(downEvent.target)\n\n    let onMouseMove: any = moveEvent => {\n      if (moveEvent.buttons === 0) {\n        return onMouseUp()\n      }\n\n      didMove = true\n\n      const editorBar = ReactDOM.findDOMNode(this.editorBarComponent) as Element\n      const topSize = moveEvent.clientY - getTop(editorBar) - offset\n      const bottomSize = editorBar.clientHeight - topSize\n      if (bottomSize < 60) {\n        this.props.closeTracing(hadHeight)\n      } else {\n        this.props.openTracing(hadHeight)\n      }\n    }\n\n    let onMouseUp: any = () => {\n      if (!didMove) {\n        this.props.toggleTracing()\n      }\n\n      document.removeEventListener('mousemove', onMouseMove)\n      document.removeEventListener('mouseup', onMouseUp)\n      onMouseMove = null\n      onMouseUp = null\n    }\n\n    document.addEventListener('mousemove', onMouseMove)\n    document.addEventListener('mouseup', onMouseUp)\n  }\n\n  private handleVariableResizeStart = downEvent => {\n    downEvent.preventDefault()\n\n    let didMove = false\n    const wasOpen = this.props.variableEditorOpen\n    const hadHeight = this.props.variableEditorHeight\n    const offset = downEvent.clientY - getTop(downEvent.target)\n\n    if (\n      wasOpen &&\n      (downEvent.target === this.queryVariablesRef ||\n        downEvent.target === this.httpHeadersRef)\n    ) {\n      return\n    }\n\n    let onMouseMove: any = moveEvent => {\n      if (moveEvent.buttons === 0) {\n        return onMouseUp()\n      }\n\n      didMove = true\n\n      const editorBar = ReactDOM.findDOMNode(this.editorBarComponent) as Element\n      const topSize = moveEvent.clientY - getTop(editorBar) - offset\n      const bottomSize = editorBar.clientHeight - topSize\n      if (bottomSize < 60) {\n        this.props.closeVariables(hadHeight)\n      } else {\n        this.props.openVariables(bottomSize)\n      }\n    }\n\n    let onMouseUp: any = () => {\n      if (!didMove) {\n        this.props.toggleVariables()\n      }\n\n      document.removeEventListener('mousemove', onMouseMove)\n      document.removeEventListener('mouseup', onMouseUp)\n      onMouseMove = null\n      onMouseUp = null\n    }\n\n    document.addEventListener('mousemove', onMouseMove)\n    document.addEventListener('mouseup', onMouseUp)\n  }\n\n  private onClickHintInformation = event => {\n    if (event.target.className === 'typeName') {\n      const typeName = event.target.innerHTML\n      const schema = this.props.schema\n      if (schema) {\n        // TODO: There is no way as of now to retrieve the NAMED_TYPE of a GraphQLList(Type).\n        // We're therefore removing any '[' or '!' characters, to properly find its NAMED_TYPE. (eg. [Type!]! => Type)\n        // This should be removed as soon as there's a safer way to do that.\n        const namedTypeName = typeName.replace(/[\\]\\[!]/g, '')\n        const type = schema.getType(namedTypeName)\n\n        if (isNamedType(type)) {\n          this.docExplorerComponent.showDocFromType(type)\n        }\n      }\n    }\n  }\n\n  private setDocsWidth = (props: any = this.props) => {\n    if (!this.activeSideTabContent) {\n      return\n    }\n    if (!this.props.docsOpen) {\n      return\n    }\n    requestAnimationFrame(() => {\n      const width = this.activeSideTabContent.getWidth()\n      const maxWidth = this.containerComponent.getWidth() - 86\n      this.props.changeWidthDocs(props.sessionId, Math.min(width, maxWidth))\n    })\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  queryRunning: getQueryRunning,\n  responses: getResponses,\n  subscriptionActive: getSubscriptionActive,\n  variableEditorOpen: getVariableEditorOpen,\n  variableEditorHeight: getVariableEditorHeight,\n  responseTracingOpen: getResponseTracingOpen,\n  responseTracingHeight: getResponseTracingHeight,\n  responseExtensions: getResponseExtensions,\n  currentQueryStartTime: getCurrentQueryStartTime,\n  currentQueryEndTime: getCurrentQueryEndTime,\n  tracingSupported: getTracingSupported,\n  editorFlex: getEditorFlex,\n  queryVariablesActive: getQueryVariablesActive,\n  headers: getHeaders,\n  operations: getOperations,\n  operationName: getOperationName,\n  headersCount: getHeadersCount,\n  sessionId: getSelectedSessionIdFromRoot,\n  docsOpen: getDocsOpen,\n})\n\nexport default // TODO fix redux types\nconnect<any, any, any>(\n  mapStateToProps,\n  {\n    updateQueryFacts,\n    stopQuery,\n    runQueryAtPosition,\n    openQueryVariables,\n    closeQueryVariables,\n    openVariables,\n    closeVariables,\n    openTracing,\n    closeTracing,\n    toggleTracing,\n    setEditorFlex,\n    toggleVariables,\n    fetchSchema,\n    changeWidthDocs,\n  },\n  null,\n  {\n    forwardRef: true,\n  },\n)(GraphQLEditor)\n\nconst EditorBar = styled.div`\n  display: flex;\n  flex-direction: row;\n  flex: 1;\n  height: 100%;\n`\n\nconst ResultWrap = styled.div`\n  display: flex;\n  flex-direction: column;\n  flex: 1;\n  height: 100%;\n  position: relative;\n  border-left: none;\n  background: ${p => p.theme.editorColours.resultBackground};\n  overflow-anchor: auto;\n`\n\nconst DragBar = styled.div`\n  width: 15px;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  cursor: col-resize;\n`\n\nconst QueryDragBar = styled(DragBar)`\n  right: 0px;\n`\n\nconst ResultDragBar = styled(DragBar)`\n  left: 0px;\n  z-index: 1;\n`\n\ninterface DrawerProps {\n  isOpen: boolean\n  height: number\n}\n\nconst BottomDrawer = styled<DrawerProps, 'div'>('div')`\n  display: flex;\n  background: #0b1924;\n  flex-direction: column;\n  position: relative;\n  height: ${props => (props.isOpen ? `${props.height}px` : '43px')};\n`\n\ninterface TitleProps {\n  isOpen: boolean\n  onMouseDown?: any\n  onClick?: any\n  ref?: any\n}\n\nconst BottomDrawerTitle = styled.div`\n  background: #0b1924;\n  text-transform: uppercase;\n  font-weight: 600;\n  letter-spacing: 0.53px;\n  line-height: 14px;\n  font-size: 14px;\n  padding: 14px 14px 15px 21px;\n  user-select: none;\n`\n\nconst VariableEditor = styled(BottomDrawer)`\n  .CodeMirror {\n    padding-left: 4px;\n    width: calc(100% - 4px);\n    background: ${p => p.theme.editorColours.leftDrawerBackground};\n  }\n  .CodeMirror-lines {\n    padding: 10px 0 20px 0;\n  }\n  .CodeMirror-linenumbers {\n    background: ${p => p.theme.editorColours.leftDrawerBackground};\n  }\n`\n\nconst VariableEditorTitle = styled<TitleProps>(({ isOpen, ...rest }) => (\n  <BottomDrawerTitle {...rest} />\n))`\n  cursor: ${p => (p.isOpen ? 'row-resize' : 'n-resize')};\n  background: ${p => p.theme.editorColours.leftDrawerBackground};\n`\n\nconst VariableEditorSubtitle = styled<TitleProps, 'span'>('span')`\n  margin-right: 10px;\n  cursor: pointer;\n  color: ${p =>\n    p.isOpen\n      ? p.theme.editorColours.drawerText\n      : p.theme.editorColours.drawerTextInactive};\n  &:last-child {\n    margin-right: 0;\n  }\n`\n\nconst ResponseTracking = styled(BottomDrawer)`\n  background: ${p => p.theme.editorColours.rightDrawerBackground};\n`\n\nconst ResponseTrackingTitle = styled<TitleProps>(({ isOpen, ...rest }) => (\n  <BottomDrawerTitle {...rest} />\n))`\n  text-align: right;\n  background: ${p => p.theme.editorColours.rightDrawerBackground};\n  cursor: ${props => (props.isOpen ? 's-resize' : 'n-resize')};\n  color: ${p => p.theme.editorColours.drawerTextInactive};\n`\n\ninterface QueryProps {\n  flex: number\n}\n\nconst QueryWrap = styled<QueryProps, 'div'>('div')`\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  flex: ${props => props.flex} 1 0%;\n  border-top: 8px solid ${props => props.theme.editorColours.resultBackground};\n`\n\nconst Intro = styled.div`\n  width: 235px;\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  color: ${p => p.theme.colours.textInactive};\n  font-size: ${p => p.theme.sizes.small16};\n  font-family: 'Source Code Pro', 'Consolas', 'Inconsolata', 'Droid Sans Mono',\n    'Monaco', monospace;\n  text-align: center;\n  letter-spacing: 0.6px;\n`\n\nconst Listening = styled.div`\n  position: absolute;\n  bottom: 0;\n  color: ${p => p.theme.editorColours.text};\n  background: ${p => p.theme.editorColours.resultBackground};\n  font-size: ${p => p.theme.sizes.small16};\n  font-family: ${p => p.theme.settings['editor.fontFamily']};\n  letter-spacing: 0.6px;\n  padding-left: 24px;\n  padding-bottom: 60px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/QueryEditor.tsx",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nimport * as React from 'react'\nimport { GraphQLSchema } from 'graphql'\nimport * as MD from 'markdown-it'\nimport { connect } from 'react-redux'\nimport onHasCompletion from './onHasCompletion'\nimport { editQuery, setScrollTop } from '../../state/sessions/actions'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getQuery,\n  getSelectedSessionIdFromRoot,\n  getScrollTop,\n  getTabWidth,\n  getUseTabs,\n} from '../../state/sessions/selectors'\nimport EditorWrapper from './EditorWrapper'\nimport { styled } from '../../styled'\nimport { isIframe } from '../../utils'\n/**\n * QueryEditor\n *\n * Maintains an instance of CodeMirror responsible for editing a GraphQL query.\n *\n * Props:\n *\n *   - schema: A GraphQLSchema instance enabling editor linting and hinting.\n *   - value: The text of the editor.\n *   - onEdit: A function called when the editor changes, given the edited text.\n *\n */\nexport interface Props {\n  schema?: GraphQLSchema | null\n  onHintInformationRender?: (elem: any) => void\n  onRunQuery?: () => void\n  onClickReference?: (reference: any) => void\n  getRef?: (ref: QueryEditor) => void\n}\n\nexport interface ReduxProps {\n  showDocForReference?: (reference: any) => void\n  onChange?: (query: string) => void\n  setScrollTop?: (sessionId: string, value: number) => void\n  value: string\n  sessionId?: string\n  scrollTop?: number\n  tabWidth?: number\n  useTabs?: boolean\n}\n\nconst md = new MD()\n// const AUTO_COMPLETE_AFTER_KEY = /^[a-zA-Z0-9_@(]$/\n\nexport class QueryEditor extends React.PureComponent<Props & ReduxProps, {}> {\n  private cachedValue: string\n  private editor: any\n  private ignoreChangeEvent: boolean\n  private node: any\n\n  constructor(props) {\n    super(props)\n\n    // Keep a cached version of the value, this cache will be updated when the\n    // editor is updated, which can later be used to protect the editor from\n    // unnecessary updates during the update lifecycle.\n    this.cachedValue = props.value || ''\n    if (this.props.getRef) {\n      this.props.getRef(this)\n    }\n  }\n\n  componentDidMount() {\n    // Lazily require to ensure requiring GraphiQL outside of a Browser context\n    // does not produce an error.\n    const CodeMirror = require('codemirror')\n    require('codemirror/addon/hint/show-hint')\n    require('codemirror/addon/comment/comment')\n    require('codemirror/addon/edit/matchbrackets')\n    require('codemirror/addon/edit/closebrackets')\n    require('codemirror/addon/fold/foldgutter')\n    require('codemirror/addon/fold/brace-fold')\n    require('codemirror/addon/search/search')\n    require('codemirror/addon/search/searchcursor')\n    require('codemirror/addon/search/jump-to-line')\n    require('codemirror/addon/dialog/dialog')\n    require('codemirror/addon/lint/lint')\n    require('codemirror/keymap/sublime')\n    require('codemirror/keymap/vim')\n    require('codemirror-graphql/hint')\n    require('codemirror-graphql/lint')\n    require('codemirror-graphql/info')\n    require('codemirror-graphql/jump')\n    require('codemirror-graphql/mode')\n\n    const gutters: any[] = []\n    gutters.push('CodeMirror-linenumbers')\n    gutters.push('CodeMirror-foldgutter')\n\n    this.editor = CodeMirror(this.node, {\n      autofocus: !isIframe() ? true : false,\n      value: this.props.value || '',\n      lineNumbers: true,\n      tabSize: this.props.tabWidth || 2,\n      indentWithTabs: this.props.useTabs || false,\n      mode: 'graphql',\n      theme: 'graphiql',\n      keyMap: 'sublime',\n      autoCloseBrackets: true,\n      matchBrackets: true,\n      showCursorWhenSelecting: true,\n      readOnly: false,\n      foldGutter: {\n        minFoldSize: 4,\n      },\n      lint: {\n        schema: this.props.schema,\n      },\n      hintOptions: {\n        schema: this.props.schema,\n        closeOnUnfocus: true,\n        completeSingle: false,\n      },\n      info: {\n        schema: this.props.schema,\n        renderDescription: text => md.render(text),\n        onClick: this.props.onClickReference,\n      },\n      jump: {\n        schema: this.props.schema,\n        onClick: this.props.onClickReference,\n      },\n      gutters,\n      extraKeys: {\n        'Cmd-Space': () => this.editor.showHint({ completeSingle: true }),\n        'Ctrl-Space': () => this.editor.showHint({ completeSingle: true }),\n        'Alt-Space': () => this.editor.showHint({ completeSingle: true }),\n        'Shift-Space': () => this.editor.showHint({ completeSingle: true }),\n\n        'Cmd-Enter': () => {\n          if (this.props.onRunQuery) {\n            this.props.onRunQuery()\n          }\n        },\n        'Ctrl-Enter': () => {\n          if (this.props.onRunQuery) {\n            this.props.onRunQuery()\n          }\n        },\n\n        // Editor improvements\n        'Ctrl-Left': 'goSubwordLeft',\n        'Ctrl-Right': 'goSubwordRight',\n        'Alt-Left': 'goGroupLeft',\n        'Alt-Right': 'goGroupRight',\n\n        'Cmd-F': 'findPersistent',\n        'Ctrl-F': 'findPersistent',\n      },\n    })\n\n    this.editor.on('change', this.onEdit)\n    this.editor.on('keyup', this.onKeyUp)\n    this.editor.on('hasCompletion', this.onHasCompletion)\n    ;(global as any).editor = this.editor\n\n    if (this.props.scrollTop) {\n      this.scrollTo(this.props.scrollTop)\n    }\n  }\n\n  componentDidUpdate(prevProps) {\n    const CodeMirror = require('codemirror')\n\n    // Ensure the changes caused by this update are not interpretted as\n    // user-input changes which could otherwise result in an infinite\n    // event loop.\n\n    this.ignoreChangeEvent = true\n    if (this.props.schema !== prevProps.schema) {\n      this.editor.options.lint.schema = this.props.schema\n      this.editor.options.hintOptions.schema = this.props.schema\n      this.editor.options.info.schema = this.props.schema\n      this.editor.options.jump.schema = this.props.schema\n      CodeMirror.signal(this.editor, 'change', this.editor)\n    }\n    if (\n      this.props.value !== prevProps.value &&\n      this.props.value !== this.cachedValue\n    ) {\n      this.cachedValue = this.props.value\n      this.editor.setValue(this.props.value)\n    }\n    this.ignoreChangeEvent = false\n\n    setTimeout(() => {\n      if (this.props.sessionId !== prevProps.sessionId) {\n        if (this.props.scrollTop) {\n          this.scrollTo(this.props.scrollTop)\n        }\n      }\n    })\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    if (this.props.sessionId !== nextProps.sessionId) {\n      this.closeCompletion()\n      this.updateSessionScrollTop()\n      if (!isIframe()) {\n        this.editor.focus()\n      }\n    }\n  }\n\n  scrollTo(y) {\n    this.node.querySelector('.CodeMirror-scroll').scrollTop = y\n  }\n\n  updateSessionScrollTop() {\n    if (this.props.setScrollTop && this.props.sessionId) {\n      this.props.setScrollTop(\n        this.props.sessionId!,\n        this.node.querySelector('.CodeMirror-scroll').scrollTop,\n      )\n    }\n  }\n\n  componentWillUnmount() {\n    this.updateSessionScrollTop()\n    this.editor.off('change', this.onEdit)\n    this.editor.off('keyup', this.onKeyUp)\n    this.editor.off('hasCompletion', this.onHasCompletion)\n    this.editor = null\n  }\n\n  render() {\n    return (\n      <EditorWrapper>\n        <Editor ref={this.setRef} />\n      </EditorWrapper>\n    )\n  }\n\n  setRef = ref => {\n    this.node = ref\n  }\n\n  /**\n   * Public API for retrieving the CodeMirror instance from this\n   * React component.\n   */\n  getCodeMirror() {\n    return this.editor\n  }\n\n  /**\n   * Public API for retrieving the DOM client height for this component.\n   */\n  getClientHeight() {\n    return this.node && this.node.clientHeight\n  }\n\n  private onKeyUp = (_, event) => {\n    const code = event.keyCode\n    if (code === 86) {\n      return\n    }\n    if (\n      (code >= 65 && code <= 90) || // letters\n      (!event.shiftKey && code >= 48 && code <= 57) || // numbers\n      (event.shiftKey && code === 189) || // underscore\n      (event.shiftKey && code === 50) || // @\n      (event.shiftKey && code === 57) // (\n    ) {\n      this.editor.execCommand('autocomplete')\n    }\n  }\n\n  private onEdit = () => {\n    if (!this.ignoreChangeEvent && this.props.onChange) {\n      this.cachedValue = this.editor.getValue()\n      this.props.onChange(this.cachedValue)\n    }\n  }\n\n  /**\n   * Render a custom UI for CodeMirror's hint which includes additional info\n   * about the type and description for the selected context.\n   */\n  private onHasCompletion = (cm, data) => {\n    onHasCompletion(cm, data, this.props.onHintInformationRender)\n  }\n\n  private closeCompletion = () => {\n    if (\n      this.editor.state.completionActive &&\n      typeof this.editor.state.completionActive.close === 'function'\n    ) {\n      this.editor.state.completionActive.close()\n    }\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  value: getQuery,\n  sessionId: getSelectedSessionIdFromRoot,\n  scrollTop: getScrollTop,\n  tabWidth: getTabWidth,\n  useTabs: getUseTabs,\n})\n\nexport default connect(\n  mapStateToProps,\n  { onChange: editQuery, setScrollTop },\n)(QueryEditor)\n\nconst Editor = styled.div`\n  flex: 1 1 0%;\n  position: relative;\n\n  .CodeMirror {\n    width: 100%;\n    background: ${p => p.theme.editorColours.editorBackground};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ResponseTracing.tsx",
    "content": "import * as React from 'react'\nimport TracingRow from './TracingRow'\nimport styled from '../../styled/styled'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getTracing,\n  getCurrentQueryStartTime,\n  getCurrentQueryEndTime,\n  getTracingSupported,\n  getQueryRunning,\n} from '../../state/sessions/selectors'\nimport { connect } from 'react-redux'\n\nexport interface TracingFormat {\n  version: 1\n  startTime: string\n  endTime: string\n  duration: number\n  execution: {\n    resolvers: Array<{\n      path: Array<string | number>\n      parentType: string\n      fieldName: string\n      returnType: string\n      startOffset: number\n      duration: number\n    }>\n  }\n}\n\nexport interface ReduxProps {\n  tracing?: TracingFormat\n  tracingSupported?: boolean\n  startTime?: Date\n  endTime?: Date\n  queryRunning: boolean\n}\n\nconst TracingWrapper = styled.div`\n  padding-top: 6px;\n  padding-left: 25px;\n  padding-right: 25px;\n  color: ${p => p.theme.editorColours.text};\n  overflow: auto;\n  position: relative;\n  height: 100%;\n`\n\nconst ReRun = styled.div`\n  font-size: 14px;\n`\nconst NotSupported = styled.div`\n  font-size: 14px;\n  color: rgba(241, 143, 1, 1);\n`\n\nconst TracingRows = styled.div`\n  padding-left: 100px;\n  padding-bottom: 100px;\n  padding-top: 16px;\n  position: absolute;\n  overflow: auto;\n  top: 0;\n  left: 0;\n  width: calc(100% + 100px);\n  height: calc(100% + 116px);\n`\n\ninterface Props {\n  open: boolean\n}\n\nclass ResponseTracing extends React.PureComponent<ReduxProps & Props> {\n  render() {\n    const { tracing, tracingSupported, startTime, endTime, open } = this.props\n    const requestMs =\n      tracing && startTime\n        ? Math.abs(new Date(tracing.startTime).getTime() - startTime.getTime())\n        : 0\n    const responseMs =\n      tracing && endTime\n        ? Math.abs(endTime.getTime() - new Date(tracing.endTime).getTime())\n        : 0\n    const requestDuration = 1000 * 1000 * requestMs\n\n    return (\n      <TracingWrapper>\n        {tracing && open ? (\n          <TracingRows>\n            <TracingRow\n              path={['Request']}\n              startOffset={0}\n              duration={requestDuration}\n            />\n            {tracing.execution.resolvers.map(res => (\n              <TracingRow\n                key={res.path.join('.')}\n                path={res.path}\n                startOffset={res.startOffset + requestDuration}\n                duration={res.duration}\n              />\n            ))}\n            <TracingRow\n              path={['Response']}\n              startOffset={tracing.duration + requestDuration}\n              duration={1000 * 1000 * responseMs}\n            />\n          </TracingRows>\n        ) : tracingSupported ? (\n          <ReRun>\n            {this.props.queryRunning\n              ? 'Running query ...'\n              : 'Please re-run the query to show tracing results.'}\n          </ReRun>\n        ) : (\n          <NotSupported>\n            This GraphQL server doesn’t support tracing. See the following page\n            for instructions:<br />\n            https://github.com/apollographql/apollo-tracing\n          </NotSupported>\n        )}\n      </TracingWrapper>\n    )\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  tracing: getTracing,\n  startTime: getCurrentQueryStartTime,\n  endTime: getCurrentQueryEndTime,\n  tracingSupported: getTracingSupported,\n  queryRunning: getQueryRunning,\n})\n\nexport default connect(mapStateToProps)(ResponseTracing)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ResultViewer.tsx",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nimport * as React from 'react'\nimport { styled } from '../../styled'\n\nexport interface Props {\n  value: string\n  isSubscription: boolean\n  hideGutters?: boolean\n}\n\n/**\n * ResultViewer\n *\n * Maintains an instance of CodeMirror for viewing a GraphQL response.\n *\n * Props:\n *\n *   - value: The text of the editor.\n *\n */\nexport class ResultViewer extends React.Component<Props, {}> {\n  private node: any\n  private viewer: any\n\n  componentDidMount() {\n    const CodeMirror = require('codemirror')\n    require('codemirror/addon/fold/foldgutter')\n    require('codemirror/addon/fold/brace-fold')\n    require('codemirror/addon/dialog/dialog')\n    require('codemirror/addon/search/search')\n    require('codemirror/addon/search/searchcursor')\n    require('codemirror/addon/search/jump-to-line')\n    require('codemirror/keymap/sublime')\n    require('codemirror-graphql/results/mode')\n\n    const gutters: any[] = []\n    if (!this.props.hideGutters) {\n      gutters.push('CodeMirror-foldgutter')\n    }\n    let foldGutter: any = {}\n    if (!this.props.hideGutters) {\n      foldGutter = {\n        minFoldSize: 4,\n      }\n    }\n\n    const value = this.props.value || ''\n\n    this.viewer = CodeMirror(this.node, {\n      lineWrapping: true,\n      value,\n      readOnly: true,\n      theme: 'graphiql',\n      mode: 'graphql-results',\n      keyMap: 'sublime',\n      foldGutter,\n      gutters,\n      extraKeys: {\n        // Persistent search box in Query Editor\n        'Cmd-F': 'findPersistent',\n        'Ctrl-F': 'findPersistent',\n\n        // Editor improvements\n        'Ctrl-Left': 'goSubwordLeft',\n        'Ctrl-Right': 'goSubwordRight',\n        'Alt-Left': 'goGroupLeft',\n        'Alt-Right': 'goGroupRight',\n      },\n    })\n  }\n\n  shouldComponentUpdate(nextProps) {\n    return this.props.value !== nextProps.value\n  }\n\n  componentDidUpdate() {\n    const value = this.props.value || ''\n    this.viewer.setValue(value)\n  }\n\n  componentWillUnmount() {\n    this.viewer = null\n  }\n\n  render() {\n    return (\n      <Result ref={this.setRef} isSubscription={this.props.isSubscription} />\n    )\n  }\n\n  setRef = ref => {\n    this.node = ref\n  }\n\n  /**\n   * Public API for retrieving the CodeMirror instance from this\n   * React component.\n   */\n  getCodeMirror() {\n    return this.viewer\n  }\n\n  /**\n   * Public API for retrieving the DOM client height for this component.\n   */\n  getClientHeight() {\n    return this.node && this.node.clientHeight\n  }\n}\n\ninterface ResultProps {\n  isSubscription: boolean\n}\n\nconst Result = styled<ResultProps, 'div'>('div')`\n  position: relative;\n  display: flex;\n  flex: 1;\n  height: ${props => (props.isSubscription ? 'auto' : '100%')};\n  .CodeMirror {\n    height: ${props => (props.isSubscription ? 'auto' : '100%')};\n    position: ${props => (props.isSubscription ? 'relative' : 'absolute%')};\n    box-sizing: border-box;\n    background: none;\n    padding-left: 38px;\n  }\n  .CodeMirror-cursor {\n    display: none !important;\n  }\n  .CodeMirror-scroll {\n    overflow: scroll !important;\n    margin-right: 10px;\n  }\n  .CodeMirror-sizer {\n    margin-bottom: 0 !important;\n  }\n  .CodeMirror-lines {\n    margin: 20px 0;\n    padding: 0;\n  }\n  .cm-string {\n    color: ${p => p.theme.editorColours.property} !important;\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/Results.tsx",
    "content": "import * as React from 'react'\nimport ageOfDate from './util/ageOfDate'\nimport { ResultViewer } from './ResultViewer'\nimport { connect } from 'react-redux'\nimport { createStructuredSelector } from 'reselect'\nimport { getResponses } from '../../state/sessions/selectors'\nimport { List } from 'immutable'\nimport { styled } from '../../styled'\nimport { ResponseRecord } from '../../state/sessions/reducers'\n\nexport interface Props {\n  setRef: (ref: any) => void\n}\n\nexport interface ReduxProps {\n  responses: List<ResponseRecord>\n}\n\nconst defaultResponseRecord = new ResponseRecord({\n  date: '',\n  time: new Date(),\n  resultID: 'default-id',\n})\n\nconst Results: React.SFC<Props & ReduxProps> = ({ setRef, responses }) => {\n  const response1 = responses.get(0) || defaultResponseRecord\n  const isSubscription = responses.size > 1\n  return (\n    <ResultWindow ref={setRef} isSubscription={isSubscription}>\n      {responses.size <= 1 ? (\n        <Response key={'first'} isSubscription={isSubscription}>\n          {responses.size > 1 &&\n            response1.time && (\n              <SubscriptionTime>\n                <SubscriptionTimeText>\n                  {ageOfDate(response1.time)}\n                </SubscriptionTimeText>\n              </SubscriptionTime>\n            )}\n          <ResultWrapper isSubscription={isSubscription}>\n            <ResultViewer\n              value={response1.date}\n              isSubscription={isSubscription}\n            />\n          </ResultWrapper>\n        </Response>\n      ) : (\n        responses.map(response => (\n          <Response\n            key={response.resultID || String(response.time)}\n            isSubscription={isSubscription}\n          >\n            {responses.size > 1 &&\n              response.time && (\n                <SubscriptionTime>\n                  <SubscriptionTimeText>\n                    {ageOfDate(response.time)}\n                  </SubscriptionTimeText>\n                </SubscriptionTime>\n              )}\n            <ResultWrapper isSubscription={responses.size > 1}>\n              <ResultViewer\n                value={response.date}\n                isSubscription={isSubscription}\n              />\n            </ResultWrapper>\n          </Response>\n        ))\n      )}\n    </ResultWindow>\n  )\n}\n\nconst mapStateToProps = createStructuredSelector({\n  responses: getResponses,\n})\n\nexport default connect(mapStateToProps)(Results)\n\nconst ResultWindow = styled<ResultWrapperProps, 'div'>('div')`\n  flex: 1;\n  height: ${props => (props.isSubscription ? 'auto' : '100%')};\n  position: relative;\n  overflow: ${props => (props.isSubscription ? 'auto' : 'visible')};\n  max-height: none !important;\n\n  .cm-string {\n    color: rgb(41, 185, 115);\n  }\n\n  .cm-def {\n    color: rgb(241, 143, 1);\n  }\n\n  .cm-property {\n    color: rgb(51, 147, 220);\n  }\n\n  &::-webkit-scrollbar {\n    display: none;\n  }\n\n  .CodeMirror {\n    background: ${p => p.theme.editorColours.resultBackground};\n  }\n  .CodeMirror-gutters {\n    cursor: col-resize;\n  }\n  .CodeMirror-foldgutter,\n  .CodeMirror-foldgutter-open:after,\n  .CodeMirror-foldgutter-folded:after {\n    padding-left: 3px;\n  }\n`\n\nconst Response = styled<ResultWrapperProps, 'div'>('div')`\n  position: relative;\n  display: flex;\n  flex: 1;\n  height: ${props => (props.isSubscription ? `auto` : '100%')};\n  flex-direction: column;\n  &:not(:first-child):last-of-type {\n    margin-bottom: 48px;\n  }\n`\n\nconst SubscriptionTime = styled.div`\n  position: relative;\n  height: 17px;\n  margin-top: 12px;\n  margin-bottom: 4px;\n  &:before {\n    position: absolute;\n    width: 100%;\n    content: '';\n    top: 9px;\n    left: 95px;\n    border-top: 1px solid\n      ${p => p.theme.editorColours.subscriptionTimeBoaderTop};\n  }\n`\n\nconst SubscriptionTimeText = styled.div`\n  font-size: 12px;\n  color: ${p => p.theme.editorColours.subscriptionTimeText};\n  padding-left: 15px;\n`\n\ninterface ResultWrapperProps {\n  isSubscription: boolean\n}\n\nconst ResultWrapper = styled<ResultWrapperProps, 'div'>('div')`\n  display: flex;\n  flex: 1;\n  height: ${props => (props.isSubscription ? `auto` : '100%')};\n  position: ${props => (props.isSubscription ? `relative` : 'static')};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLEditor.tsx",
    "content": "import * as React from 'react'\nimport { GraphQLSchema, printSchema } from 'graphql'\nimport EditorWrapper from '../EditorWrapper'\nimport { styled } from '../../../styled'\nimport { getSDL } from '../util/createSDL'\nimport { ISettings } from '../../../types'\n\nexport interface Props {\n  schema?: GraphQLSchema | null\n  isPollingSchema: boolean\n  getRef?: (ref: SDLEditor) => void\n  width?: number\n  sessionId?: string\n  settings: ISettings\n}\n\nclass SDLEditor extends React.PureComponent<Props, { overflowY: boolean }> {\n  cachedValue: string\n  private editor: any\n  private node: any\n\n  constructor(props) {\n    super(props)\n    this.state = {\n      overflowY: false,\n    }\n    // Keep a cached version of the value, this cache will be updated when the\n    // editor is updated, which can later be used to protect the editor from\n    // unnecessary updates during the update lifecycle.\n    this.cachedValue = props.value || ''\n    if (this.props.getRef) {\n      this.props.getRef(this)\n    }\n  }\n\n  componentDidMount() {\n    // Lazily require to ensure requiring GraphiQL outside of a Browser context\n    // does not produce an error.\n    const CodeMirror = require('codemirror')\n    require('codemirror/addon/fold/brace-fold')\n    require('codemirror/addon/comment/comment')\n    require('codemirror-graphql/mode')\n\n    const gutters: any[] = []\n    gutters.push('CodeMirror-linenumbers')\n\n    this.editor = CodeMirror(this.node, {\n      autofocus: false,\n      value:\n        getSDL(\n          this.props.schema,\n          this.props.settings['schema.disableComments'],\n        ) || '',\n      lineNumbers: false,\n      showCursorWhenSelecting: false,\n      tabSize: 1,\n      mode: 'graphql',\n      theme: 'graphiql',\n      // lineWrapping: true,\n      keyMap: 'sublime',\n      readOnly: true,\n      gutters,\n    })\n    ;(global as any).editor = this.editor\n    this.editor.on('scroll', this.handleScroll)\n    this.editor.refresh()\n  }\n  componentDidUpdate(prevProps: Props) {\n    const CodeMirror = require('codemirror')\n    const currentSchemaStr = this.props.schema && printSchema(this.props.schema)\n    const prevSchemaStr = prevProps.schema && printSchema(prevProps.schema)\n    if (currentSchemaStr !== prevSchemaStr) {\n      const initialScroll = this.editor.getScrollInfo()\n      this.cachedValue =\n        getSDL(\n          this.props.schema,\n          this.props.settings['schema.disableComments'],\n        ) || ''\n      this.editor.setValue(\n        getSDL(\n          this.props.schema,\n          this.props.settings['schema.disableComments'],\n        ),\n      )\n      if (this.props.isPollingSchema) {\n        this.editor.scrollTo(initialScroll.left, initialScroll.top)\n      }\n      CodeMirror.signal(this.editor, 'change', this.editor)\n    }\n    if (this.props.width !== prevProps.width) {\n      this.editor.refresh()\n    }\n    if (\n      this.props.settings['schema.disableComments'] !==\n      prevProps.settings['schema.disableComments']\n    ) {\n      this.editor.refresh()\n    }\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    if (this.props.sessionId !== nextProps.sessionId) {\n      this.editor.scrollTo(0, 0)\n    }\n  }\n\n  componentWillUnmount() {\n    if(this.editor) {\n      this.editor.off('scroll')\n      this.editor = null\n    }\n  }\n\n  handleScroll = e => {\n    if (e.doc.scrollTop > 0) {\n      return this.setState({\n        overflowY: true,\n      })\n    }\n    return this.setState({\n      overflowY: false,\n    })\n  }\n\n  render() {\n    const { overflowY } = this.state\n    return (\n      <EditorWrapper>\n        {overflowY && <OverflowShadow />}\n        <Editor ref={this.setRef} />\n      </EditorWrapper>\n    )\n  }\n\n  setRef = ref => {\n    this.node = ref\n  }\n\n  getCodeMirror() {\n    return this.editor\n  }\n  getClientHeight() {\n    return this.node && this.node.clientHeight\n  }\n}\n\nexport default SDLEditor\n\nconst Editor = styled.div`\n  flex: 1;\n  height: auto;\n  overflow-x: hidden;\n  overflow-y: scroll;\n  .CodeMirror {\n    background: ${p =>\n      p.theme.mode === 'dark'\n        ? p.theme.editorColours.editorBackground\n        : 'white'};\n    padding-left: 20px;\n  }\n`\nconst OverflowShadow = styled.div`\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  height: 1px;\n  box-shadow: 0px 1px 3px rgba(17, 17, 17, 0.1);\n  z-index: 1000;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLHeader.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../styled'\nimport { Button } from '../TopBar/TopBar'\nimport { GraphQLSchema } from 'graphql'\nimport { downloadSchema } from '../util/createSDL'\n\ninterface SDLHeaderProps {\n  schema: GraphQLSchema\n}\n\ninterface State {\n  open: boolean\n}\n\nexport default class SDLHeader extends React.Component<SDLHeaderProps, State> {\n  ref\n  private node: any\n  constructor(props) {\n    super(props)\n    this.state = {\n      open: false,\n    }\n  }\n\n  UNSAFE_componentWillMount() {\n    document.addEventListener('mousedown', this.handleClick, false)\n  }\n\n  componentWillUnmount() {\n    document.removeEventListener('mousedown', this.handleClick, false)\n  }\n\n  handleClick = e => {\n    if (this.node.contains(e.target)) {\n      return\n    }\n    return this.setState({\n      open: false,\n    })\n  }\n\n  showOptions = () => {\n    this.setState({\n      open: !this.state.open,\n    })\n  }\n\n  printSDL = () => {\n    return downloadSchema(this.props.schema, 'sdl')\n  }\n\n  printIntrospection = () => {\n    return downloadSchema(this.props.schema, 'json')\n  }\n\n  setRef = ref => {\n    this.node = ref\n  }\n\n  render() {\n    const { open } = this.state\n    return (\n      <SchemaHeader ref={this.setRef}>\n        <Title>Schema</Title>\n        <Box>\n          <Download onClick={this.showOptions} open={open}>\n            Download\n          </Download>\n          {open && (\n            <React.Fragment>\n              <Option onClick={this.printIntrospection}>JSON</Option>\n              <Option onClick={this.printSDL}>SDL</Option>\n            </React.Fragment>\n          )}\n        </Box>\n      </SchemaHeader>\n    )\n  }\n}\n\nconst SchemaHeader = styled.div`\n  display: flex;\n  flex-direction: row;\n  height: 64px;\n  width: 100%;\n  margin-right: 108px;\n  align-items: center;\n  justify-content: flex-start;\n  outline: none;\n  user-select: none;\n`\n\nconst Box = styled.div`\n  position: absolute;\n  top: 16px;\n  right: 2em;\n  width: 108px;\n  display: flex;\n  flex-wrap: wrap;\n  flex-direction: column;\n`\n\nconst Title = styled.div`\n  color: ${p => styleHelper(p).title};\n  cursor: default;\n  font-size: 14px;\n  font-weight: 600;\n  text-transform: uppercase !important;\n  font-family: 'Open Sans', sans-serif !important;\n  letter-spacing: 1px;\n  user-select: none !important;\n  padding: 16px;\n  padding-right: 5px;\n`\n\nconst Download = styled(Button)`\n  flex: 1;\n  color: ${p => styleHelper(p).download['text']};\n  background: ${p => styleHelper(p).download['button']};\n  height: 32px;\n  border-radius: 2px;\n  &:hover {\n    color: ${p => styleHelper(p).buttonTextHover};\n    background-color: ${p => styleHelper(p).buttonHover};\n  }\n`\n\nconst Option = styled(Download)`\n  text-align: left;\n  width: 100%;\n  margin-left: 0px;\n  border-radius: 0px;\n  z-index: 2000;\n  background: ${p => styleHelper(p).button};\n`\n\nconst styleHelper = p => {\n  if (p.theme.mode === 'dark') {\n    return {\n      title: 'white',\n      subtitle: '#8B959C',\n      download: {\n        text: p.open ? '#8B959C' : 'white',\n        button: p.theme.colours.darkBlue,\n      },\n      buttonText: 'white',\n      button: p.theme.colours.darkBlue,\n      buttonHover: '#2B3C48',\n      buttonTextHover: 'white',\n    }\n  }\n  return {\n    title: p.theme.colours.darkBlue,\n    subtitle: 'rgba(61, 88, 102, 0.5)',\n    download: {\n      text: p.open ? 'rgba(61, 88, 102, 0.5)' : p.theme.colours.darkBlue,\n      button: '#f6f6f6',\n    },\n    buttonText: p.theme.colours.darkBlue,\n    button: '#f6f6f6',\n    buttonHover: '#EDEDED',\n    buttonTextHover: p.theme.colours.darkBlue,\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLDocType.tsx",
    "content": "import * as React from 'react'\nimport SDLType from './SDLType'\nimport { styled } from '../../../../styled'\n\nexport interface DocTypeSchemaProps {\n  type: any\n  fields: any[]\n  interfaces: any[]\n}\n\nexport default ({ type, fields, interfaces }: DocTypeSchemaProps) => {\n  const nonDeprecatedFields = fields.filter(data => !data.isDeprecated)\n  const deprecatedFields = fields.filter(data => data.isDeprecated)\n  return (\n    <DocTypeSchema>\n      <DocTypeLine>\n        <span className=\"field-name\">{type.instanceOf}</span>{' '}\n        <DocsTypeName>{type.name}</DocsTypeName>{' '}\n        {interfaces.length === 0 && <Brace>{`{`}</Brace>}\n      </DocTypeLine>\n      {interfaces.map((data, index) => (\n        <DocsTypeInferface\n          key={data.name}\n          type={data}\n          beforeNode={<span className=\"field-name\">implements</span>}\n          afterNode={\n            index === interfaces.length - 1 ? <Brace>{'{'}</Brace> : null\n          }\n        />\n      ))}\n      {nonDeprecatedFields.map(data => (\n        <SDLType key={data.name} type={data} collapsable={true} />\n      ))}\n      {deprecatedFields.length > 0 && <br />}\n      {deprecatedFields.map((data, index) => (\n        <div key={data.name}>\n          <DocsValueComment>\n            # Deprecated: {data.deprecationReason}\n          </DocsValueComment>\n          <SDLType type={data} />\n        </div>\n      ))}\n      <DocTypeLine>\n        <Brace>{'}'}</Brace>\n      </DocTypeLine>\n    </DocTypeSchema>\n  )\n}\n\nconst DocTypeSchema = styled.div`\n  font-size: 14px;\n  flex: 1;\n  .doc-category-item {\n    padding-left: 32px;\n  }\n`\n\nconst DocTypeLine = styled.div`\n  padding: 6px 16px;\n  white-space: nowrap;\n`\n\nconst DocsTypeName = styled.span`\n  color: #f25c54;\n`\n\nconst DocsTypeInferface = styled(SDLType)`\n  padding-left: 16px;\n  .field-name {\n    color: rgb(245, 160, 0);\n  }\n  .type-name {\n    color: #f25c54;\n  }\n`\n\nconst DocsValueComment = styled.span`\n  color: ${p => p.theme.colours.black50};\n  padding-right: 16px;\n  padding-left: 32px;\n`\n\nconst Brace = styled.span`\n  font-weight: 600;\n  color: ${p => p.theme.colours.darkBlue50};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLFieldDoc.tsx",
    "content": "import * as React from 'react'\nimport MarkdownContent from 'graphiql/dist/components/DocExplorer/MarkdownContent'\nimport SDLDocType from './SDLDocType'\nimport ScalarTypeSchema from '../../DocExplorer/DocsTypes/ScalarType'\nimport EnumTypeSchema from '../../DocExplorer/DocsTypes/EnumTypeSchema'\nimport SDLUnionType from './SDLUnionType'\nimport { CategoryTitle } from '../../DocExplorer/DocsStyles'\nimport { styled } from '../../../../styled'\n\nexport interface Props {\n  schema: any\n  type: any\n}\n\nexport interface State {\n  showDeprecated: boolean\n}\n\nexport default class FieldDoc extends React.Component<Props, State> {\n  state = { showDeprecated: false }\n\n  render() {\n    const { type, schema } = this.props\n    return (\n      <div>\n        <CategoryTitle>{`${type.name} details`}</CategoryTitle>\n        {type.description &&\n          type.description.length > 0 && (\n            <DocsDescription markdown={type.description || ''} />\n          )}\n        {type.instanceOf === 'scalar' && <ScalarTypeSchema type={type} />}\n        {type.instanceOf === 'enum' && (\n          <EnumTypeSchema sdlType={true} type={type} />\n        )}\n        {type.instanceOf === 'union' && (\n          <SDLUnionType type={type} schema={schema} />\n        )}\n        {type.fields.length > 0 && (\n          <SDLDocType\n            type={type}\n            fields={type.fields}\n            interfaces={type.interfaces}\n          />\n        )}\n      </div>\n    )\n  }\n}\n\nconst DocsDescription = styled(MarkdownContent)`\n  font-size: 14px;\n  padding: 0 16px 20px 16px;\n  color: rgba(0, 0, 0, 0.5);\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLStyles.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../../styled'\nimport { columnWidth } from '../../../../constants'\n\nexport const SchemaExplorerContainer = styled.div`\n  position: relative;\n  height: 100%;\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  flex-wrap: wrap;\n  align-items: stretch;\n  padding: 0px 8px 8px 8px;\n  background: ${p =>\n    p.theme.mode === 'dark' ? p.theme.editorColours.editorBackground : 'white'};\n  font-family: ${p => p.theme.settings['editor.fontFamily']};\n  font-size: ${p => `${p.theme.settings['editor.fontSize']}px`};\n  outline: none !important;\n`\n\nexport interface SDLColumnProps {\n  children: any\n  width?: number\n}\n\nconst SDLColumn = ({ children, width = columnWidth }: SDLColumnProps) => {\n  return <Column style={{ width }}>{children}</Column>\n}\n\nexport { SDLColumn }\n\nconst Column = styled<SDLColumnProps, 'div'>('div')`\n  display: flex;\n  flex: 1 0 auto;\n  flex-flow: column;\n  padding-bottom: 20px;\n  border-right: 1px solid ${p => p.theme.colours.black10};\n  overflow: hidden;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLType.tsx",
    "content": "import * as React from 'react'\nimport { GraphQLList, GraphQLNonNull, isType } from 'graphql'\nimport ArgumentInline from '../../DocExplorer/ArgumentInline'\nimport { styled } from '../../../../styled'\n\nexport interface Props {\n  type: any\n  className?: string\n  beforeNode?: JSX.Element | null | false\n  afterNode?: JSX.Element | null | false\n  showParentName?: boolean\n  collapsable?: boolean\n}\n\nexport default class SDLType extends React.Component<Props> {\n  render() {\n    const {\n      type,\n      className,\n      beforeNode,\n      afterNode,\n      showParentName,\n    } = this.props\n    const isGraphqlType = isType(type)\n\n    const fieldName =\n      showParentName && type.parent ? (\n        <span>\n          {type.parent.name}.<b>{type.name}</b>\n        </span>\n      ) : (\n        type.name\n      )\n\n    return (\n      <DocsCategoryItem\n        className={`doc-category-item${className ? className : ''}`}\n      >\n        {beforeNode}\n        {beforeNode && ' '}\n        {!isGraphqlType && (\n          <span>\n            <span className=\"field-name\">{fieldName}</span>\n            {type.args &&\n              type.args.length > 0 && [\n                '(',\n                <span key=\"args\">\n                  {type.args.map(arg => (\n                    <ArgumentInline key={arg.name} arg={arg} />\n                  ))}\n                </span>,\n                ')',\n              ]}\n            {': '}\n          </span>\n        )}\n        <span className=\"type-name\">{renderType(type.type || type)}</span>\n        {type.defaultValue !== undefined ? (\n          <DefaultValue>\n            {' '}\n            = <span>{`${type.defaultValue}`}</span>\n          </DefaultValue>\n        ) : (\n          undefined\n        )}\n        {afterNode && ' '}\n        {afterNode}\n      </DocsCategoryItem>\n    )\n  }\n}\n\nfunction renderType(type) {\n  if (type instanceof GraphQLNonNull) {\n    return (\n      <span>\n        {renderType(type.ofType)}\n        {'!'}\n      </span>\n    )\n  }\n  if (type instanceof GraphQLList) {\n    return (\n      <span>\n        {'['}\n        {renderType(type.ofType)}\n        {']'}\n      </span>\n    )\n  }\n  return <span>{type.name}</span>\n}\n\ninterface DocsCategoryItemProps {\n  clickable?: boolean\n  active?: boolean\n}\n\nconst DocsCategoryItem = styled<DocsCategoryItemProps, 'div'>('div')`\n\tposition: relative;\n\tpadding: 6px 16px;\n\toverflow: auto;\n\tfont-size: 14px;\n\ttransition: 0.1s background-color;\n\tbackground: ${p =>\n    p.active ? p.theme.colours.black07 : p.theme.colours.white};\n\n\tcursor: ${p => (p.clickable ? 'pointer' : 'select')};\n\n\t// &:hover {\n\t// \tcolor: ${p => p.theme.colours.white};\n\t// \tbackground: #2a7ed3;\n\t// \t.field-name,\n\t// \t.type-name,\n\t// \t.arg-name,\n\t// \tspan {\n\t// \t\tcolor: ${p => p.theme.colours.white} !important;\n\t// \t}\n\t// }\n\tb {\n\t\tfont-weight: 600;\n\t}\n`\n\nconst DefaultValue = styled.span`\n  color: ${p => p.theme.colours.black30};\n  span {\n    color: #1f61a9;\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLUnionType.tsx",
    "content": "import SDLType from './SDLType'\nimport * as React from 'react'\nimport { DocType } from '../../DocExplorer/DocsTypes/DocType'\n\nexport interface EnumTypeSchemaProps {\n  schema: any\n  type: any\n}\n\nconst UnionTypeSchema = ({ schema, type }: EnumTypeSchemaProps) => {\n  const types = schema.getPossibleTypes(type)\n  return (\n    <DocType className=\"doc-type-schema\">\n      <span className=\"field-name\">union</span>{' '}\n      <span className=\"type-name\">{type.name}</span>\n      {' = '}\n      {types.map(value => <SDLType key={value.name} type={value} />)}\n    </DocType>\n  )\n}\n\nexport default UnionTypeSchema\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLView.tsx",
    "content": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport {\n  toggleDocs,\n  changeWidthDocs,\n  setDocsVisible,\n} from '../../../state/docs/actions'\nimport Spinner from '../../Spinner'\nimport { columnWidth } from '../../../constants'\nimport { SideTabContentProps } from '../ExplorerTabs/SideTabs'\nimport {\n  getSelectedSessionIdFromRoot,\n  getIsPollingSchema,\n} from '../../../state/sessions/selectors'\nimport { getSessionDocs } from '../../../state/docs/selectors'\nimport { createStructuredSelector } from 'reselect'\nimport { ErrorContainer } from '../DocExplorer/ErrorContainer'\nimport { SchemaExplorerContainer, SDLColumn } from './SDLTypes/SDLStyles'\nimport SDLHeader from './SDLHeader'\nimport SDLEditor from './SDLEditor'\nimport { getSettings } from '../../../state/workspace/reducers'\nimport { ISettings } from '../../../types'\n\ninterface StateFromProps {\n  docs: {\n    navStack: any[]\n    docsOpen: boolean\n    docsWidth: number\n    keyMove: boolean\n  }\n  isPollingSchema: boolean\n  settings: ISettings\n}\n\ninterface DispatchFromProps {\n  toggleDocs: (sessionId: string) => any\n  setDocsVisible: (sessionId: string, open: boolean) => any\n  changeWidthDocs: (sessionId: string, width: number) => any\n  setSchemaUpdated: () => void\n}\n\nclass SDLView extends React.Component<\n  SideTabContentProps & StateFromProps\n> {\n  ref\n  constructor(props) {\n    super(props)\n    ;(window as any).d = this\n  }\n  UNSAFE_componentWillReceiveProps(nextProps: SideTabContentProps & StateFromProps) {\n    // If user use default column size % columnWidth\n    // Make the column follow the clicks\n    if (!this.props.schema && nextProps.schema) {\n      this.setWidth(nextProps)\n    }\n  }\n\n  setWidth(props: any = this.props) {\n    this.props.setWidth(props)\n  }\n\n  getWidth(props: any = this.props) {\n    const rootWidth = props.docs.docsWidth || columnWidth\n    return rootWidth\n  }\n  componentDidMount() {\n    this.setWidth()\n  }\n\n  render() {\n    const { schema, settings, isPollingSchema } = this.props\n    let emptySchema\n    if (schema === undefined) {\n      // Schema is undefined when it is being loaded via introspection.\n      emptySchema = <Spinner />\n    } else if (schema === null) {\n      // Schema is null when it explicitly does not exist, typically due to\n      // an error during introspection.\n      emptySchema = <ErrorContainer>{'No Schema Available'}</ErrorContainer>\n    }\n    // let types\n    // if (schema instanceof GraphQLSchema) {\n    // \ttypes = sdlArray(schema)\n    // }\n    return (\n      <SchemaExplorerContainer ref={this.setRef}>\n        {emptySchema ? (\n          <SDLColumn>{emptySchema}</SDLColumn>\n        ) : (\n          <SDLColumn width={this.props.docs.docsWidth || columnWidth - 1}>\n            <SDLHeader schema={schema} />\n            <SDLEditor\n              schema={schema}\n              settings={settings}\n              isPollingSchema={isPollingSchema}\n              width={this.props.docs.docsWidth || columnWidth}\n            />\n          </SDLColumn>\n        )}\n      </SchemaExplorerContainer>\n    )\n  }\n  setRef = ref => {\n    this.ref = ref\n  }\n}\n\nconst mapDispatchToProps = dispatch =>\n  bindActionCreators(\n    {\n      toggleDocs,\n      changeWidthDocs,\n      setDocsVisible,\n    },\n    dispatch,\n  )\n\nconst mapStateToProps = createStructuredSelector({\n  settings: getSettings,\n  docs: getSessionDocs,\n  sessionId: getSelectedSessionIdFromRoot,\n  isPollingSchema: getIsPollingSchema,\n})\n\nexport default connect<StateFromProps, DispatchFromProps, SideTabContentProps>(\n  mapStateToProps,\n  // @ts-ignore\n  mapDispatchToProps,\n  null,\n  { forwardRef: true },\n)(SDLView)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/SchemaFetcher.ts",
    "content": "import {\n  GraphQLSchema,\n  getIntrospectionQuery,\n  buildClientSchema,\n  validateSchema,\n  IntrospectionQuery,\n} from 'graphql'\nimport { NoSchemaError } from './util/NoSchemaError'\nimport { InvalidSchemaError } from './util/InvalidSchemaError'\nimport { ApolloLink, execute, toPromise } from 'apollo-link'\nimport { Map, set } from 'immutable'\nimport { makeOperation } from './util/makeOperation'\nimport { parseHeaders } from './util/parseHeaders'\nimport { LinkCreatorProps } from '../../state/sessions/fetchingSagas'\nimport * as LRU from 'lru-cache'\n\nexport interface TracingSchemaTuple {\n  schema: GraphQLSchema\n  tracingSupported: boolean\n}\n\nexport interface SchemaFetchProps {\n  endpoint: string\n  headers?: string\n  useTracingHeader?: boolean\n}\n\nexport type LinkGetter = (session: LinkCreatorProps) => { link: ApolloLink }\n\n/**\n * The SchemaFetcher class servers the purpose of providing the GraphQLSchema.\n * All sagas and every part of the UI is using this as a singleton to prevent\n * unnecessary calls to the server. We're not storing this information in Redux,\n * as it's a good practice to only store serializable data in Redux.\n * GraphQLSchema objects are serializable, but can easily exceed the localStorage\n * max. Another reason to keep this in a separate class is, that we have more\n * advanced requirements like caching.\n */\nexport class SchemaFetcher {\n  /**\n   * The `sessionCache` property is used for UI components, that need fast access to the current schema.\n   * If the relevant information of the session didn't change (endpoint and headers),\n   * the cached schema will be returned.\n   */\n  sessionCache: LRU.Cache<string, TracingSchemaTuple>\n  /**\n   * The `schemaInstanceCache` property is used to prevent unnecessary buildClientSchema calls.\n   * It's tested by stringifying the introspection result, which is orders of magnitude\n   * faster than rebuilding the schema.\n   */\n  schemaInstanceCache: LRU.Cache<string, GraphQLSchema>\n  /**\n   * The `linkGetter` property is a callback that provides an ApolloLink instance.\n   * This can be overriden by the user.\n   */\n  linkGetter: LinkGetter\n  /**\n   * In order to prevent duplicate fetching of the same schema, we keep track\n   * of all subsequent calls to `.fetch` with the `fetching` property.\n   */\n  fetching: Map<string, Promise<any>>\n  /**\n   * Other parts of the application can subscribe to change of a schema for a\n   * particular session. These subscribers are being kept track of in the\n   * `subscriptions` property\n   */\n  subscriptions: Map<string, (schema: GraphQLSchema) => void> = Map()\n  constructor(linkGetter: LinkGetter) {\n    this.sessionCache = new LRU<string, TracingSchemaTuple>({ max: 10 })\n    this.schemaInstanceCache = new LRU({ max: 10 })\n    this.fetching = Map()\n    this.linkGetter = linkGetter\n  }\n  async fetch(session: SchemaFetchProps) {\n    const hash = this.hash(session)\n    const cachedSchema = this.sessionCache.get(hash)\n    if (cachedSchema) {\n      return cachedSchema\n    }\n    const fetching = this.fetching.get(hash)\n    if (fetching) {\n      return fetching\n    }\n    const promise = this.fetchSchema(session)\n    this.fetching = this.fetching.set(hash, promise)\n    return promise\n  }\n  subscribe(session: SchemaFetchProps, cb: (schema: GraphQLSchema) => void) {\n    const hash = this.hash(session)\n    this.subscriptions = this.subscriptions.set(hash, cb)\n  }\n  refetch(session: SchemaFetchProps) {\n    return this.fetchSchema(session)\n  }\n  hash(session: SchemaFetchProps) {\n    return `${session.endpoint}~${session.headers || ''}`\n  }\n  private getSchema(data: IntrospectionQuery) {\n    const schemaString = JSON.stringify(data)\n    const cachedSchema = this.schemaInstanceCache.get(schemaString)\n    if (cachedSchema) {\n      return cachedSchema\n    }\n\n    const schema = buildClientSchema(data)\n\n    const validationErrors = validateSchema(schema)\n    if (validationErrors && validationErrors.length > 0) {\n      throw new InvalidSchemaError(validationErrors)\n    }\n    this.schemaInstanceCache.set(schemaString, schema)\n\n    return schema\n  }\n  private async fetchSchema(\n    session: SchemaFetchProps,\n  ): Promise<{ schema: GraphQLSchema; tracingSupported: boolean } | null> {\n    const hash = this.hash(session)\n    try {\n      const { endpoint } = session\n      const headersTracing = {\n        ...parseHeaders(session.headers),\n        'X-Apollo-Tracing': '1',\n      }\n      const headersNoTracing = {\n        ...parseHeaders(session.headers),\n      }\n      const headers = session.useTracingHeader\n        ? headersTracing\n        : headersNoTracing\n\n      const options = set(session, 'headers', headers) as any\n\n      const { link } = this.linkGetter(options)\n\n      const operation = makeOperation({ query: getIntrospectionQuery() })\n\n      const schemaData = await toPromise(execute(link, operation))\n      if (\n        schemaData &&\n        ((schemaData.errors && schemaData.errors.length > 0) ||\n          !schemaData.data)\n      ) {\n        throw new Error(JSON.stringify(schemaData, null, 2))\n      }\n\n      if (!schemaData) {\n        throw new NoSchemaError(endpoint)\n      }\n\n      const schema = this.getSchema(schemaData.data as IntrospectionQuery)\n\n      const tracingSupported =\n        (schemaData.extensions && Boolean(schemaData.extensions.tracing)) ||\n        false\n      const result: TracingSchemaTuple = {\n        schema,\n        tracingSupported,\n      }\n      this.sessionCache.set(this.hash(session), result)\n      const subscription = this.subscriptions.get(hash)\n      if (subscription) {\n        subscription(result.schema)\n      }\n      return result\n    } finally {\n      this.fetching.remove(hash)\n    }\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/Tab.tsx",
    "content": "import * as React from 'react'\nimport { SettingsIcon, CrossIcon } from '../Icons'\nimport { connect } from 'react-redux'\nimport { closeTab, selectTab, editName } from '../../state/sessions/actions'\nimport { styled } from '../../styled'\nimport { Session } from '../../state/sessions/reducers'\nimport AutosizeInput from 'react-input-autosize'\n\nexport interface Props {\n  session: Session\n  selectedSessionId: string\n}\n\nexport interface ReduxProps {\n  selectTab: (sessionId: string) => void\n  closeTab: (sessionId: string) => void\n  editName: (name: string) => void\n}\n\nexport interface State {\n  overCross: boolean\n  editingName: boolean\n}\n\nclass Tab extends React.PureComponent<Props & ReduxProps, State> {\n  constructor(props) {\n    super(props)\n\n    this.state = {\n      overCross: false,\n      editingName: false,\n    }\n  }\n\n  render() {\n    const { session, selectedSessionId } = this.props\n    const { queryTypes } = session\n\n    const active = session.id === selectedSessionId\n\n    const name =\n      session.name ||\n      session.operationName ||\n      queryTypes.firstOperationName ||\n      'New Tab'\n\n    return (\n      <TabItem active={active} onMouseDown={this.handleSelectSession}>\n        <Icons active={active}>\n          {session.subscriptionActive && <RedDot />}\n          <QueryTypes>\n            {queryTypes.query && <Query>Q</Query>}\n            {(session.isSettingsTab || session.isConfigTab) && (\n              <Query>\n                <SettingsIcon width={12} height={12} fill=\"white\" />\n              </Query>\n            )}\n            {queryTypes.mutation && <Mutation>M</Mutation>}\n            {queryTypes.subscription && <Subscription>S</Subscription>}\n          </QueryTypes>\n        </Icons>\n        {this.state.editingName ? (\n          <OperationNameInput\n            value={session.name || ''}\n            onChange={this.handleEditName}\n            onBlur={this.stopEditName}\n            onKeyDown={this.handleKeyDown}\n            autoFocus={true}\n          />\n        ) : (\n          <OperationName active={active} onDoubleClick={this.startEditName}>\n            {name}\n          </OperationName>\n        )}\n        <Close\n          className=\"close\"\n          active={active}\n          hasCircle={session.isFile && session.changed && !this.state.overCross}\n          onClick={this.handleCloseSession}\n          onMouseEnter={this.handleMouseOverCross}\n          onMouseLeave={this.handleMouseOutCross}\n        >\n          {session.isFile && session.changed && !this.state.overCross ? (\n            <Circle>⬤</Circle>\n          ) : (\n            <CrossIcon\n              width={12}\n              height={11}\n              strokeWidth={7}\n              title=\"Close Tab\"\n            />\n          )}\n        </Close>\n      </TabItem>\n    )\n  }\n\n  private startEditName = () => {\n    this.setState({ editingName: true })\n  }\n\n  private stopEditName = () => {\n    this.setState({ editingName: false })\n  }\n\n  private handleKeyDown = e => {\n    if (e.keyCode === 13) {\n      this.setState({ editingName: false })\n    }\n  }\n\n  private handleMouseOverCross = () => {\n    this.setState({ overCross: true })\n  }\n\n  private handleMouseOutCross = () => {\n    this.setState({ overCross: false })\n  }\n\n  private handleSelectSession = () => {\n    this.props.selectTab(this.props.session.id)\n  }\n\n  private handleCloseSession = (e: any) => {\n    e.stopPropagation()\n    this.props.closeTab(this.props.session.id)\n  }\n\n  private handleEditName = e => {\n    this.props.editName(e.target.value)\n  }\n}\n\nexport default connect(\n  null,\n  { closeTab, selectTab, editName },\n)(Tab)\n\ninterface TabItemProps {\n  active: boolean\n  hasCircle?: boolean\n}\n\nconst TabItem = styled<TabItemProps, 'div'>('div')`\n  -webkit-app-region: no-drag;\n  flex: 0 0 auto;\n  display: flex;\n  align-items: center;\n  height: 43px;\n  padding: 10px;\n  padding-top: 9px;\n  margin-right: 10px;\n  font-size: 14px;\n  border-radius: 2px;\n  border-bottom: 2px solid ${p => p.theme.editorColours.navigationBar};\n  box-sizing: border-box;\n  cursor: pointer;\n  user-select: none;\n  background: ${p =>\n    p.active ? p.theme.editorColours.tab : p.theme.editorColours.tabInactive};\n  &:hover {\n    background: ${p => p.theme.editorColours.tab};\n    .close {\n      opacity: 1;\n    }\n  }\n`\n\nconst OperationName = styled<TabItemProps, 'div'>('div')`\n  opacity: ${p => (p.active ? 1 : 0.5)};\n  background: transparent;\n  color: ${p => p.theme.editorColours.tabText};\n  font-size: 14px;\n  margin-left: 2px;\n  display: inline;\n  letter-spacing: 0.53px;\n`\n\nconst OperationNameInput = styled(AutosizeInput)`\n  input {\n    background: transparent;\n    color: ${p => p.theme.editorColours.tabText};\n    font-size: 14px;\n    margin-left: 2px;\n    display: inline;\n    letter-spacing: 0.53px;\n  }\n`\n\nconst Icons = styled<TabItemProps, 'div'>('div')`\n  display: flex;\n  align-items: center;\n  opacity: ${p => (p.active ? 1 : 0.5)};\n`\n\nconst QueryTypes = styled.div`\n  display: flex;\n  color: white;\n`\n\nconst QueryType = styled.div`\n  height: 22px;\n  width: 22px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  margin-right: 4px;\n  font-size: 12px;\n  font-weight: 700;\n  border-radius: 2px;\n`\n\nconst Query = styled(QueryType)`\n  background: ${p => p.theme.colours.blue};\n`\n\nconst Mutation = styled(QueryType)`\n  background: ${p => p.theme.colours.orange};\n`\n\nconst Subscription = styled(QueryType)`\n  background: ${p => p.theme.colours.purple};\n`\n\nconst RedDot = styled.div`\n  width: 7px;\n  height: 7px;\n  background: rgba(242, 92, 84, 1);\n  border-radius: 100%;\n  margin-right: 10px;\n`\n\nconst Circle = styled.div`\n  position: relative;\n  top: -2px;\n  font-size: 9px;\n  background: ${p => p.theme.editorColours.circle};\n`\n\nconst Close = styled<TabItemProps, 'div'>('div')`\n  position: relative;\n  display: flex;\n  margin-left: 10px;\n  top: 1px;\n  height: 13px;\n  width: 13px;\n  opacity: ${p => (p.active || p.hasCircle ? 1 : 0)};\n  svg {\n    stroke: ${p => p.theme.editorColours.icon};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TabBar.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../styled'\nimport { AddIcon } from '../Icons'\nimport Tab, { Props as TabProps } from './Tab'\nimport { connect } from 'react-redux'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getSessionsArray,\n  getSelectedSessionIdFromRoot,\n} from '../../state/sessions/selectors'\nimport { Session } from '../../state/sessions/reducers'\nimport { reorderTabs } from '../../state/sessions/actions'\nimport {\n  SortableContainer,\n  SortableElement,\n  SortStart,\n  SortEnd,\n} from 'react-sortable-hoc'\n\nexport interface Props {\n  onNewSession: any\n  isApp?: boolean\n}\n\nexport interface ReduxProps {\n  sessions: Session[]\n  selectedSessionId: string\n  reorderTabs: (src: number, dest: number) => void\n}\n\ninterface State {\n  sorting: boolean\n}\n\nconst SortableTab = SortableElement<TabProps>(Tab)\n\nclass TabBar extends React.PureComponent<Props & ReduxProps, State> {\n  state = { sorting: false }\n\n  render() {\n    const { sessions, isApp, selectedSessionId, onNewSession } = this.props\n    const { sorting } = this.state\n    return (\n      <SortableTabBar\n        onSortStart={this.onSortStart}\n        onSortEnd={this.onSortEnd}\n        getHelperDimensions={this.getHelperDimensions}\n        axis=\"x\"\n        lockAxis=\"x\"\n        lockToContainerEdges={true}\n        distance={10}\n        transitionDuration={200}\n      >\n        <Tabs isApp={isApp}>\n          {sessions.map((session, ndx) => (\n            <SortableTab\n              key={session.id}\n              session={session}\n              selectedSessionId={selectedSessionId}\n              index={ndx}\n            />\n          ))}\n          <Plus onClick={onNewSession} sorting={sorting}>\n            <AddIcon\n              width={34}\n              height={34}\n              strokeWidth={4}\n              title=\"Opens a New Tab\"\n            />\n          </Plus>\n        </Tabs>\n      </SortableTabBar>\n    )\n  }\n\n  private onSortStart = ({ index }: SortStart) => {\n    this.setState({ sorting: true })\n  }\n\n  private onSortEnd = ({ oldIndex, newIndex }: SortEnd) => {\n    this.props.reorderTabs(oldIndex, newIndex)\n    this.setState({ sorting: false })\n  }\n\n  private getHelperDimensions = ({ node }: SortStart) => {\n    const { width, height } = node.getBoundingClientRect()\n    return { width, height }\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  sessions: getSessionsArray,\n  selectedSessionId: getSelectedSessionIdFromRoot,\n})\n\nexport default connect(\n  mapStateToProps,\n  { reorderTabs },\n)(TabBar)\n\nconst StyledTabBar = styled.div`\n  color: white;\n  height: 57px;\n  background: ${p => p.theme.editorColours.background};\n  overflow: hidden;\n  -webkit-app-region: drag;\n  &:hover {\n    overflow-x: overlay;\n  }\n`\n\nconst SortableTabBar = SortableContainer(StyledTabBar)\n\ninterface TabsProps {\n  isApp?: boolean\n}\n\nconst Tabs = styled<TabsProps, 'div'>('div')`\n  display: flex;\n  align-items: center;\n  margin-top: 16px;\n  padding-left: ${p => (p.isApp ? '43px' : '0')};\n`\n\ninterface PlusProps {\n  sorting: boolean\n}\n\nconst Plus = styled<PlusProps, 'div'>('div')`\n  -webkit-app-region: no-drag;\n  box-sizing: border-box;\n  display: flex;\n  visibility: ${p => (p.sorting ? 'hidden' : 'visible')}\n  height: 43px;\n  width: 43px;\n  border-radius: 2px;\n  border-bottom: 2px solid ${p => p.theme.editorColours.navigationBar};\n  background: ${p => p.theme.editorColours.tabInactive};\n  justify-content: center;\n  align-items: center;\n  svg {\n    stroke: ${p => p.theme.editorColours.icon};\n  }\n  &:hover {\n    background: ${p => p.theme.editorColours.tab};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/Polling.tsx",
    "content": "import * as React from 'react'\nimport PollingIcon from './PollingIcon'\n\nexport interface Props {\n  interval: number\n  onReloadSchema: () => void\n}\n\ninterface State {\n  windowVisible: boolean\n}\n\nclass SchemaPolling extends React.Component<Props, State> {\n  timer: any\n  constructor(props) {\n    super(props)\n\n    this.state = {\n      windowVisible: true,\n    }\n  }\n  componentDidMount() {\n    this.updatePolling()\n    document.addEventListener('visibilitychange', this.setWindowVisibility)\n  }\n  componentWillUnmount() {\n    this.clearTimer()\n    document.removeEventListener('visibilitychange', this.setWindowVisibility)\n  }\n  setWindowVisibility = () => {\n    if (document.visibilityState === 'visible') {\n      this.setState(\n        {\n          windowVisible: true,\n        },\n        this.updatePolling,\n      )\n    }\n    if (document.visibilityState === 'hidden') {\n      this.setState(\n        {\n          windowVisible: false,\n        },\n        this.updatePolling,\n      )\n    }\n  }\n  UNSAFE_componentWillReceiveProps(nextProps: Props) {\n    this.updatePolling(nextProps)\n  }\n\n  render() {\n    return <PollingIcon animate={this.state.windowVisible} />\n  }\n  private updatePolling = (props: Props = this.props) => {\n    this.clearTimer()\n    if (this.state.windowVisible) {\n      // timer starts only when introspection not in flight\n      this.timer = setInterval(() => props.onReloadSchema(), props.interval)\n    }\n  }\n\n  private clearTimer() {\n    if (this.timer) {\n      clearInterval(this.timer)\n      this.timer = null\n    }\n  }\n}\n\nexport default SchemaPolling\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/PollingIcon.tsx",
    "content": "import * as React from 'react'\nimport { styled, keyframes, css } from '../../../styled/index'\nimport BasePositioner from './Positioner'\n\nexport interface Props {\n  animate: boolean\n  disabled?: boolean\n  onClick?: () => void\n}\n\nconst PollingIcon: React.SFC<Props> = props => (\n  <Positioner onClick={props.onClick} title=\"Polling Schema\">\n    <Icon animate={props.animate} />\n  </Positioner>\n)\n\nexport default PollingIcon\n\nconst pulse = keyframes`\n0% {\n  box-shadow: 0 0 0 0 rgba(139, 149, 156, 0.4);\n}\n70% {\n  box-shadow: 0 0 0 10px rgba(139, 149, 156, 0);\n}\n100% {\n  box-shadow: 0 0 0 0 rgba(139, 149, 156, 0);\n}\n`\n\nconst Positioner = styled(BasePositioner)`\n  display: flex;\n  justify-content: center;\n  align-items: center;\n`\nconst Icon = styled.div`\n  display: block;\n  width: 8px;\n  height: 8px;\n  border-radius: 50%;\n  background: ${p => p.theme.editorColours.pollingIcon};\n  box-shadow: 0 0 0 ${p => p.theme.editorColours.pollingIconShadow};\n  ${p =>\n    p.animate\n      ? css`\n          animation: ${pulse} 2s infinite;\n        `\n      : undefined};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/Positioner.tsx",
    "content": "import { styled } from '../../../styled/index'\n\nexport default styled.div`\n  width: 20px;\n  height: 20px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/Reload.tsx",
    "content": "import * as React from 'react'\nimport ReloadIcon from './ReloadIcon'\n\nexport interface Props {\n  isReloadingSchema: boolean\n  onReloadSchema?: () => void\n}\n\nconst Reload: React.SFC<Props> = props => (\n  <ReloadIcon\n    animate={props.isReloadingSchema}\n    onClick={props.onReloadSchema}\n  />\n)\n\nexport default Reload\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/ReloadIcon.tsx",
    "content": "import * as React from 'react'\nimport { styled, keyframes, css } from '../../../styled/index'\nimport BasePositioner from './Positioner'\n\nexport interface Props {\n  animate: boolean\n  disabled?: boolean\n  onClick?: () => void\n}\n\nconst ReloadIcon: React.SFC<Props> = props => (\n  <Positioner\n    onClick={props.onClick}\n    title=\"Reload Schema\"\n    disabled={props.disabled}\n  >\n    <Svg viewBox=\"0 0 20 20\" disabled={props.disabled}>\n      <Circle\n        cx=\"9.5\"\n        cy=\"10\"\n        r=\"6\"\n        strokeWidth=\"1.5\"\n        fill=\"none\"\n        strokeLinecap=\"round\"\n        animate={props.animate}\n      />\n      <Icon\n        d=\"M4.83 4.86a6.92 6.92 0 0 1 11.3 2.97l.41-1.23c.13-.4.56-.6.95-.47.4.13.6.56.47.95l-1.13 3.33a.76.76 0 0 1-.7.5.72.72 0 0 1-.43-.12l-2.88-1.92a.76.76 0 0 1-.2-1.04.75.75 0 0 1 1.03-.2l1.06.7A5.34 5.34 0 0 0 9.75 4.5a5.44 5.44 0 0 0-5.64 5.22 5.42 5.42 0 0 0 5.24 5.62c.41 0 .74.36.72.78a.75.75 0 0 1-.75.72H9.3a6.9 6.9 0 0 1-6.68-7.18 6.88 6.88 0 0 1 2.22-4.81z\"\n        animate={props.animate}\n      />\n    </Svg>\n  </Positioner>\n)\n\nexport default ReloadIcon\n\nconst refreshFrames = keyframes`\n0% {\n  transform: rotate(0deg);\n  stroke-dashoffset: 7.92;\n}\n\n50% {\n  transform: rotate(720deg);\n  stroke-dashoffset: 37.68;\n}\n\n100% {\n  transform: rotate(1080deg);\n  stroke-dashoffset: 7.92;\n}\n`\n\n// same result for these 2 keyframes, however when the props change\n// it makes the element animated with these keyframes to trigger\n// again the animation\nconst reloadAction = props => keyframes`\n0% {\n  transform: rotate(${props.animate ? 0 : 360}deg);\n}\n\n100% {\n  transform: rotate(${props.animate ? 360 : 720}deg);\n}`\n\nconst Svg = styled.svg`\n  fill: ${p => p.theme.editorColours.icon};\n  transition: 0.1s linear all;\n  ${p =>\n    p.disabled\n      ? undefined\n      : css`\n          &:hover {\n            fill: ${p => p.theme.editorColours.iconHover};\n          }\n        `};\n`\nconst Positioner = styled(BasePositioner)`\n  cursor: ${({ disabled = false }) => (disabled ? 'auto' : 'pointer')};\n  transform: rotateY(180deg);\n`\nconst Circle = styled<Props, 'circle'>('circle')`\n  fill: none;\n  stroke: ${p => p.theme.editorColours.icon};\n  stroke-dasharray: 37.68;\n  transition: opacity 0.3s ease-in-out;\n  opacity: ${p => (p.animate ? 1 : 0)};\n  transform-origin: 9.5px 10px;\n  animation: ${refreshFrames} 2s linear ${p => (p.animate ? 'infinite' : '')};\n`\n\nconst Icon = styled<Props, 'path'>('path')`\n  transition: opacity 0.3s ease-in-out;\n  opacity: ${p => (p.animate ? 0 : 1)};\n  transform-origin: 9.5px 10px;\n  animation: ${reloadAction} 0.5s linear;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/SchemaReload.tsx",
    "content": "import * as React from 'react'\nimport ReloadIcon from './Reload'\nimport Polling from './Polling'\nimport { ISettings } from '../../../types'\nimport { createStructuredSelector } from 'reselect'\nimport { getIsReloadingSchema } from '../../../state/sessions/selectors'\nimport { connect } from 'react-redux'\n\nexport interface Props {\n  isPollingSchema: boolean\n  isReloadingSchema: boolean\n  onReloadSchema: () => any\n  settings: ISettings\n}\n\nconst SchemaReload = (props: Props) => {\n  if (props.isPollingSchema) {\n    return (\n      <Polling\n        interval={props.settings['schema.polling.interval']}\n        onReloadSchema={props.onReloadSchema}\n      />\n    )\n  }\n  return (\n    <ReloadIcon\n      isReloadingSchema={props.isReloadingSchema}\n      onReloadSchema={props.onReloadSchema}\n    />\n  )\n}\n\nconst mapStateToProps = createStructuredSelector({\n  isReloadingSchema: getIsReloadingSchema,\n})\n\nexport default connect(mapStateToProps)(SchemaReload)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TopBar/TopBar.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../../../styled/index'\nimport * as copy from 'copy-to-clipboard'\n\nimport Share from '../../Share'\nimport SchemaReload from './SchemaReload'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getEndpoint,\n  getSelectedSession,\n  getEndpointUnreachable,\n  getIsPollingSchema,\n} from '../../../state/sessions/selectors'\nimport { connect } from 'react-redux'\nimport { getFixedEndpoint } from '../../../state/general/selectors'\nimport * as PropTypes from 'prop-types'\nimport {\n  editEndpoint,\n  prettifyQuery,\n  refetchSchema,\n} from '../../../state/sessions/actions'\nimport { share } from '../../../state/sharing/actions'\nimport { openHistory } from '../../../state/general/actions'\nimport { getSettings } from '../../../state/workspace/reducers'\nimport { Session } from '../../../state/sessions/reducers'\nimport { ISettings } from '../../../types'\n\nexport interface Props {\n  endpoint: string\n  shareEnabled?: boolean\n  fixedEndpoint?: boolean\n  isPollingSchema: boolean\n  endpointUnreachable: boolean\n  session: Session\n\n  editEndpoint: (value: string) => void\n  prettifyQuery: () => void\n  openHistory: () => void\n  share: () => void\n  refetchSchema: () => void\n\n  settings: ISettings\n}\n\nclass TopBar extends React.Component<Props, {}> {\n  static contextTypes = {\n    store: PropTypes.shape({\n      subscribe: PropTypes.func.isRequired,\n      dispatch: PropTypes.func.isRequired,\n      getState: PropTypes.func.isRequired,\n    }),\n  }\n  render() {\n    const { endpointUnreachable, settings } = this.props\n    return (\n      <TopBarWrapper>\n        <Button onClick={this.props.prettifyQuery}>Prettify</Button>\n        <Button onClick={this.openHistory}>History</Button>\n        <UrlBarWrapper>\n          <UrlBar\n            value={this.props.endpoint}\n            onChange={this.onChange}\n            onKeyDown={this.onKeyDown}\n            onBlur={this.props.refetchSchema}\n            disabled={this.props.fixedEndpoint}\n            active={!this.props.fixedEndpoint}\n          />\n          {endpointUnreachable ? (\n            <ReachError>\n              <span>Server cannot be reached</span>\n              <Spinner />\n            </ReachError>\n          ) : (\n            <div\n              style={{\n                display: 'flex',\n                flexDirection: 'row',\n                alignItems: 'center',\n                position: 'absolute',\n                left: '6px',\n              }}\n            >\n              <SchemaReload\n                settings={settings}\n                isPollingSchema={this.props.isPollingSchema}\n                onReloadSchema={this.props.refetchSchema}\n              />\n            </div>\n          )}\n        </UrlBarWrapper>\n        <Button onClick={this.copyCurlToClipboard}>Copy CURL</Button>\n        {this.props.shareEnabled && (\n          <Share>\n            <Button>Share Playground</Button>\n          </Share>\n        )}\n      </TopBarWrapper>\n    )\n  }\n  copyCurlToClipboard = () => {\n    const curl = this.getCurl()\n    copy(curl)\n  }\n  onChange = e => {\n    this.props.editEndpoint(e.target.value)\n  }\n  onKeyDown = e => {\n    if (e.keyCode === 13) {\n      this.props.refetchSchema()\n    }\n  }\n  openHistory = () => {\n    this.props.openHistory()\n  }\n  getCurl = () => {\n    const session = this.props.session\n    let variables\n    try {\n      variables = JSON.parse(session.variables)\n    } catch (e) {\n      //\n    }\n    const data = JSON.stringify({\n      query: session.query,\n      variables,\n      operationName: session.operationName,\n    })\n    let sessionHeaders\n    try {\n      sessionHeaders = JSON.parse(session.headers!)\n    } catch (e) {\n      //\n    }\n    const globalHeaders = this.props.settings['request.globalHeaders']\n    const headers = {\n      'Accept-Encoding': 'gzip, deflate, br',\n      'Content-Type': 'application/json',\n      Accept: 'application/json',\n      Connection: 'keep-alive',\n      DNT: '1',\n      Origin: location.origin || session.endpoint,\n      ...globalHeaders,\n      ...sessionHeaders,\n    }\n    const headersString = Object.keys(headers)\n      .map(key => {\n        const value = headers[key]\n        return `-H '${key}: ${value}'`\n      })\n      .join(' ')\n    return `curl '${\n      session.endpoint\n    }' ${headersString} --data-binary '${data}' --compressed`\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  endpoint: getEndpoint,\n  fixedEndpoint: getFixedEndpoint,\n  isPollingSchema: getIsPollingSchema,\n  endpointUnreachable: getEndpointUnreachable,\n  settings: getSettings,\n  session: getSelectedSession,\n})\n\nexport default connect(\n  mapStateToProps,\n  {\n    editEndpoint,\n    prettifyQuery,\n    openHistory,\n    share,\n    refetchSchema,\n  },\n)(TopBar)\n\nexport const Button = styled.button`\n  text-transform: uppercase;\n  font-weight: 600;\n  color: ${p => p.theme.editorColours.buttonText};\n  background: ${p => p.theme.editorColours.button};\n  border-radius: 2px;\n  flex: 0 0 auto;\n  letter-spacing: 0.53px;\n  font-size: 14px;\n  padding: 6px 9px 7px 10px;\n  margin-left: 6px;\n\n  cursor: pointer;\n  transition: 0.1s linear background-color;\n  &:first-child {\n    margin-left: 0;\n  }\n  &:hover {\n    background-color: ${p => p.theme.editorColours.buttonHover};\n  }\n`\n\nconst TopBarWrapper = styled.div`\n  display: flex;\n  background: ${p => p.theme.editorColours.navigationBar};\n  padding: 10px 10px 4px;\n  align-items: center;\n`\n\ninterface UrlBarProps {\n  active: boolean\n}\n\nconst UrlBar = styled<UrlBarProps, 'input'>('input')`\n  background: ${p => p.theme.editorColours.button};\n  border-radius: 4px;\n  color: ${p =>\n    p.active\n      ? p.theme.editorColours.navigationBarText\n      : p.theme.editorColours.textInactive};\n  border: 1px solid ${p => p.theme.editorColours.background};\n  padding: 6px 12px;\n  padding-left: 30px;\n  font-size: 13px;\n  flex: 1;\n`\n\nconst UrlBarWrapper = styled.div`\n  flex: 1;\n  margin-left: 6px;\n  position: relative;\n  display: flex;\n  align-items: center;\n`\n\nconst ReachError = styled.div`\n  position: absolute;\n  right: 5px;\n  display: flex;\n  align-items: center;\n  color: #f25c54;\n`\n\nconst Pulse = styled.div`\n  width: 16px;\n  height: 16px;\n  background-color: ${p => p.theme.editorColours.icon};\n  border-radius: 100%;\n`\n\nconst SpinnerWrapper = styled.div`\n  position: relative;\n  margin: 6px;\n`\n\nconst Spinner = () => (\n  <SpinnerWrapper>\n    <Pulse />\n  </SpinnerWrapper>\n)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/TracingRow.tsx",
    "content": "import * as React from 'react'\nimport styled from '../../styled/styled'\n\nconst Row = styled.div`\n  position: relative;\n  font-size: 12px;\n  display: table;\n  padding-right: 25px;\n\n  color: ${p => p.theme.editorColours.text};\n`\n\nconst Bar = styled.span`\n  display: inline-block;\n  position: relative;\n  margin: 0 10px;\n  height: 1.5px;\n  bottom: 4px;\n\n  background: ${p => p.theme.editorColours.text};\n`\n\nconst Duration = styled.span`\n  font-size: 10px;\n  color: ${p => p.theme.editorColours.textInactive};\n`\n\nconst NameWrapper = styled.span`\n  position: absolute;\n  left: 0;\n  transform: translateX(-100%);\n  display: inline-flex;\n  align-items: center;\n\n  text-align: right;\n`\n\nconst Name = styled.span`\n  margin-left: 10px;\n`\n\nexport interface TracingRowProps {\n  path: Array<string | number>\n  startOffset: number\n  duration: number\n}\n\nexport interface TracingRowState {\n  collapsed: boolean\n}\n\nexport default class TracingRow extends React.Component<\n  TracingRowProps,\n  TracingRowState\n> {\n  state = {\n    collapsed: false,\n  }\n  render() {\n    const { path, startOffset, duration } = this.props\n    const factor = 1000 * 1000\n    const offsetLeft = startOffset / factor\n    const barWidth = duration / factor\n    return (\n      <Row style={{ transform: `translateX(${offsetLeft}px)` }}>\n        <NameWrapper>\n          <Name>\n            {path.slice(-2).map((p, index) => (\n              <span\n                style={{\n                  opacity: index === path.slice(-2).length - 1 ? 1 : 0.6,\n                }}\n                key={p}\n              >\n                {`${index > 0 ? '.' : ''}${p}`}\n              </span>\n            ))}\n          </Name>\n        </NameWrapper>\n        <Bar style={{ width: Math.max(barWidth, 3) }} />\n        <Duration>{this.printDuration(duration)}</Duration>\n      </Row>\n    )\n  }\n  private printDuration(nanoSeconds) {\n    const microSeconds = Math.round(nanoSeconds / 1000)\n    if (microSeconds > 1000) {\n      const ms = Math.round(microSeconds / 1000)\n      return `${ms} ms`\n    }\n\n    return `${microSeconds} µs`\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/VariableEditor.tsx",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nimport * as React from 'react'\nimport onHasCompletion from './onHasCompletion'\nimport { connect } from 'react-redux'\nimport { editVariables, editHeaders } from '../../state/sessions/actions'\nimport {\n  getVariables,\n  getVariableToType,\n  getHeaders,\n} from '../../state/sessions/selectors'\nimport { createStructuredSelector } from 'reselect'\nimport { VariableToType } from '../../state/sessions/reducers'\nimport { styled } from '../../styled'\n\n/* tslint:disable */\n\ninterface Props {\n  onHintInformationRender: (elem) => void\n  onRunQuery: () => void\n  prettifyQuery?: () => void\n  getRef?: (editor: VariableEditor) => void\n}\n\ninterface ReduxProps {\n  value: string\n  variableToType?: VariableToType\n  onChange: (variable: string) => void\n}\n\n/**\n * VariableEditor\n *\n * An instance of CodeMirror for editing variables defined in QueryEditor.\n *\n * Props:\n *\n *   - variableToType: A mapping of variable name to GraphQLType.\n *   - value: The text of the editor.\n *   - onEdit: A function called when the editor changes, given the edited text.\n *   - readOnly: Turns the editor to read-only mode.\n *\n */\n\nclass VariableEditor extends React.PureComponent<Props & ReduxProps> {\n  cachedValue: any\n  editor: any\n  ignoreChangeEvent: boolean\n  _node: any\n  constructor(props) {\n    super(props)\n\n    // Keep a cached version of the value, this cache will be updated when the\n    // editor is updated, which can later be used to protect the editor from\n    // unnecessary updates during the update lifecycle.\n    this.cachedValue = props.value || ''\n    if (this.props.getRef) {\n      this.props.getRef(this)\n    }\n  }\n\n  componentDidMount() {\n    // Lazily require to ensure requiring GraphiQL outside of a Browser context\n    // does not produce an error.\n    const CodeMirror = require('codemirror')\n    require('codemirror/addon/hint/show-hint')\n    require('codemirror/addon/edit/matchbrackets')\n    require('codemirror/addon/edit/closebrackets')\n    require('codemirror/addon/fold/brace-fold')\n    require('codemirror/addon/fold/foldgutter')\n    require('codemirror/addon/lint/lint')\n    require('codemirror/addon/search/searchcursor')\n    require('codemirror/addon/search/jump-to-line')\n    require('codemirror/addon/dialog/dialog')\n    require('codemirror/keymap/sublime')\n    require('codemirror-graphql/variables/hint')\n    require('codemirror-graphql/variables/lint')\n    require('codemirror-graphql/variables/mode')\n\n    this.editor = CodeMirror(this._node, {\n      value: this.props.value || '',\n      lineNumbers: true,\n      tabSize: 2,\n      mode: 'graphql-variables',\n      theme: 'graphiql',\n      keyMap: 'sublime',\n      autoCloseBrackets: true,\n      matchBrackets: true,\n      showCursorWhenSelecting: true,\n      readOnly: false,\n      foldGutter: {\n        minFoldSize: 4,\n      },\n      lint: {\n        variableToType: this.props.variableToType\n          ? this.props.variableToType.toJS()\n          : undefined,\n      },\n      hintOptions: {\n        variableToType: this.props.variableToType\n          ? this.props.variableToType.toJS()\n          : undefined,\n        closeOnUnfocus: false,\n        completeSingle: false,\n      },\n      gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],\n      extraKeys: {\n        'Cmd-Space': () => this.editor.showHint({ completeSingle: false }),\n        'Ctrl-Space': () => this.editor.showHint({ completeSingle: false }),\n        'Alt-Space': () => this.editor.showHint({ completeSingle: false }),\n        'Shift-Space': () => this.editor.showHint({ completeSingle: false }),\n\n        'Cmd-Enter': () => {\n          if (this.props.onRunQuery) {\n            this.props.onRunQuery()\n          }\n        },\n        'Ctrl-Enter': () => {\n          if (this.props.onRunQuery) {\n            this.props.onRunQuery()\n          }\n        },\n\n        'Shift-Ctrl-P': () => {\n          if (this.props.prettifyQuery) {\n            this.props.prettifyQuery()\n          }\n        },\n\n        // Persistent search box in Query Editor\n        'Cmd-F': 'findPersistent',\n        'Ctrl-F': 'findPersistent',\n\n        // Editor improvements\n        'Ctrl-Left': 'goSubwordLeft',\n        'Ctrl-Right': 'goSubwordRight',\n        'Alt-Left': 'goGroupLeft',\n        'Alt-Right': 'goGroupRight',\n      },\n    })\n\n    this.editor.on('change', this._onEdit)\n    this.editor.on('keyup', this._onKeyUp)\n    this.editor.on('hasCompletion', this._onHasCompletion)\n  }\n\n  componentDidUpdate(prevProps) {\n    const CodeMirror = require('codemirror')\n\n    // Ensure the changes caused by this update are not interpretted as\n    // user-input changes which could otherwise result in an infinite\n    // event loop.\n    this.ignoreChangeEvent = true\n    if (this.props.variableToType !== prevProps.variableToType) {\n      this.editor.options.lint.variableToType = this.props.variableToType\n        ? this.props.variableToType.toJS()\n        : undefined\n      this.editor.options.hintOptions.variableToType = this.props.variableToType\n        ? this.props.variableToType.toJS()\n        : undefined\n      CodeMirror.signal(this.editor, 'change', this.editor)\n    }\n    if (\n      this.props.value !== prevProps.value &&\n      this.props.value !== this.cachedValue\n    ) {\n      this.cachedValue = this.props.value\n      this.editor.setValue(this.props.value)\n    }\n    this.ignoreChangeEvent = false\n  }\n\n  componentWillUnmount() {\n    this.editor.off('change', this._onEdit)\n    this.editor.off('keyup', this._onKeyUp)\n    this.editor.off('hasCompletion', this._onHasCompletion)\n    this.editor = null\n  }\n\n  render() {\n    return (\n      <Editor\n        ref={node => {\n          this._node = node\n        }}\n      />\n    )\n  }\n\n  /**\n   * Public API for retrieving the CodeMirror instance from this\n   * React component.\n   */\n  getCodeMirror() {\n    return this.editor\n  }\n\n  /**\n   * Public API for retrieving the DOM client height for this component.\n   */\n  getClientHeight() {\n    return this._node && this._node.clientHeight\n  }\n\n  _onKeyUp = (cm, event) => {\n    const code = event.keyCode\n    if (\n      (code >= 65 && code <= 90) || // letters\n      (!event.shiftKey && code >= 48 && code <= 57) || // numbers\n      (event.shiftKey && code === 189) || // underscore\n      (event.shiftKey && code === 222) // \"\n    ) {\n      this.editor.execCommand('autocomplete')\n    }\n  }\n\n  _onEdit = () => {\n    if (!this.ignoreChangeEvent) {\n      this.cachedValue = this.editor.getValue()\n      this.props.onChange(this.cachedValue)\n    }\n  }\n\n  _onHasCompletion = (cm, data) => {\n    onHasCompletion(cm, data, this.props.onHintInformationRender)\n  }\n}\n\nconst mapStateToVariablesProps = createStructuredSelector({\n  value: getVariables,\n  variableToType: getVariableToType,\n})\n\nexport const VariableEditorComponent = connect(\n  mapStateToVariablesProps,\n  {\n    onChange: editVariables,\n  },\n)(VariableEditor)\n\nconst mapStateToHeadersProps = createStructuredSelector({\n  value: getHeaders,\n})\n\nexport const HeadersEditorComponent = connect(\n  mapStateToHeadersProps,\n  {\n    onChange: editHeaders,\n  },\n)(VariableEditor)\n\nconst Editor = styled.div`\n  flex: 1;\n  height: 100%;\n  position: relative;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/onHasCompletion.tsx",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nconst escapeHTML = require('escape-html');\nimport * as MD from 'markdown-it';\n\nconst md = new MD();\n\n/**\n * Render a custom UI for CodeMirror's hint which includes additional info\n * about the type and description for the selected context.\n */\nexport default function onHasCompletion(cm, data, onHintInformationRender) {\n  const CodeMirror = require('codemirror')\n\n  let wrapper\n  let information\n  let deprecation\n\n  // When a hint result is selected, we touch the UI.\n  CodeMirror.on(data, 'select', (ctx, el) => {\n    // Only the first time (usually when the hint UI is first displayed)\n    // do we create the wrapping node.\n    if (!wrapper) {\n      // Wrap the existing hint UI, so we have a place to put information.\n      const hintsUl = el.parentNode\n      const container = hintsUl.parentNode\n      wrapper = document.createElement('div')\n      container.appendChild(wrapper)\n\n      // CodeMirror vertically inverts the hint UI if there is not enough\n      // space below the cursor. Since this modified UI appends to the bottom\n      // of CodeMirror's existing UI, it could cover the cursor. This adjusts\n      // the positioning of the hint UI to accomodate.\n      let top = hintsUl.style.top\n      let bottom = ''\n      const cursorTop = cm.cursorCoords().top\n      if (parseInt(top, 10) < cursorTop) {\n        top = ''\n        bottom = window.innerHeight - cursorTop + 3 + 'px'\n      }\n\n      // Style the wrapper, remove positioning from hints. Note that usage\n      // of this option will need to specify CSS to remove some styles from\n      // the existing hint UI.\n      wrapper.className = 'CodeMirror-hints-wrapper'\n      wrapper.style.left = hintsUl.style.left\n      wrapper.style.top = top\n      wrapper.style.bottom = bottom\n      hintsUl.style.left = ''\n      hintsUl.style.top = ''\n\n      // This \"information\" node will contain the additional info about the\n      // highlighted typeahead option.\n      information = document.createElement('div')\n      information.className = 'CodeMirror-hint-information'\n\n      // This \"deprecation\" node will contain info about deprecated usage.\n      deprecation = document.createElement('div')\n      deprecation.className = 'CodeMirror-hint-deprecation'\n\n      if (bottom) {\n        wrapper.appendChild(deprecation)\n        wrapper.appendChild(information)\n        wrapper.appendChild(hintsUl)\n      } else {\n        wrapper.appendChild(hintsUl)\n        wrapper.appendChild(information)\n        wrapper.appendChild(deprecation)\n      }\n\n      const wrapperHeight = wrapper.clientHeight\n      const currentTop = parseFloat(String(top).replace('px', ''))\n      let newTop = currentTop\n      if (wrapperHeight + currentTop > window.innerHeight) {\n        newTop = window.innerHeight - 40 - wrapperHeight\n      }\n\n      wrapper.style.top = `${newTop}px`\n      ;(global as any).wrapper = wrapper\n\n      // When CodeMirror attempts to remove the hint UI, we detect that it was\n      // removed from our wrapper and in turn remove the wrapper from the\n      // original container.\n      let onRemoveFn\n      wrapper.addEventListener(\n        'DOMNodeRemoved',\n        (onRemoveFn = event => {\n          if (event.target === hintsUl) {\n            wrapper.removeEventListener('DOMNodeRemoved', onRemoveFn)\n            wrapper.parentNode.removeChild(wrapper)\n            wrapper = null\n            information = null\n            onRemoveFn = null\n          }\n        }),\n      )\n    }\n\n    // Now that the UI has been set up, add info to information.\n    const description = ctx.description\n      ? md.render(ctx.description)\n      : ''\n    const type =\n      ctx.type && ctx.type !== 'undefined'\n        ? '<span class=\"infoType\">' + renderType(ctx.type) + '</span>'\n        : ''\n\n    information.innerHTML =\n      '<div class=\"content\">' +\n      (description.slice(0, 3) === '<p>'\n        ? '<p>' + type + description.slice(3)\n        : type + description) +\n      '</div>'\n\n    if (ctx.isDeprecated) {\n      const reason = ctx.deprecationReason\n        ? md.render(ctx.deprecationReason)\n        : ''\n      deprecation.innerHTML =\n        '<span class=\"deprecation-label\">Deprecated</span>' + reason\n      deprecation.style.display = 'block'\n    } else {\n      deprecation.style.display = 'none'\n    }\n\n    // Additional rendering?\n    if (onHintInformationRender) {\n      onHintInformationRender(information)\n    }\n  })\n}\n\nfunction renderType(type) {\n  return `<a class=\"typeName\">${escapeHTML(type.toString())}</a>`\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/InvalidSchemaError.ts",
    "content": "import type { GraphQLError } from \"graphql\";\n\nexport class InvalidSchemaError extends Error {\n  constructor(validationErrors: readonly GraphQLError[]) {\n    super(\n      `Invalid schema Error:\\n${validationErrors.join('\\n')}`,\n    )\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/NoSchemaError.ts",
    "content": "export class NoSchemaError extends Error {\n  constructor(endpoint: string) {\n    super(\n      `Schema could not be fetched.\\nPlease check if the endpoint '${endpoint}' is a valid GraphQL Endpoint.`,\n    )\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/ageOfDate.ts",
    "content": "export default function ageOfDate(date: Date) {\n  const now = new Date()\n  const diffMs = Math.abs(date.getTime() - now.getTime())\n  const diffDays = Math.floor(diffMs / 86400000)\n  const diffHrs = Math.floor((diffMs % 86400000) / 3600000)\n  const diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000)\n\n  if (diffDays > 0) {\n    return `${diffDays} days ago`\n  }\n\n  if (diffHrs > 0) {\n    return `${diffHrs} h ago`\n  }\n\n  if (diffMins > 0) {\n    return `${diffMins} min ago`\n  }\n\n  const sec = Math.round(diffMs / 1000)\n\n  return `${sec} sec${sec > 1 ? 's' : ''} ago`\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/createSDL.ts",
    "content": "import {\n  GraphQLEnumType,\n  GraphQLUnionType,\n  GraphQLInterfaceType,\n  GraphQLInputObjectType,\n  GraphQLSchema,\n  printSchema,\n} from 'graphql'\nimport { serialize } from './stack'\nimport { prettify } from '../../../utils'\n// import { getRootMap } from './stack'\n\ninterface Options {\n  commentDescriptions?: boolean\n}\n\nconst defaultTypes = [\n  '__Schema',\n  '__Directive',\n  '__DirectiveLocation',\n  '__Type',\n  '__Field',\n  '__InputValue',\n  '__EnumValue',\n  '__TypeKind',\n  'String',\n  'ID',\n  'Boolean',\n  'Int',\n  'Float',\n]\n\n/* Creates an array of SchemaTypes for the SDLFieldDocs \n(A component that is similar to the DocsExplorer) to consume */\nexport function sdlArray(schema: GraphQLSchema, options?: Options) {\n  const objectValues =\n    Object.values || (obj => Object.keys(obj).map(key => obj[key]))\n  const typeMap = schema.getTypeMap()\n  const types = objectValues(typeMap)\n    .sort((type1, type2) => type1.name.localeCompare(type2.name))\n    .filter(type => !defaultTypes.includes(type.name))\n    .map(type => ({\n      ...type,\n      ...serialize(schema, type),\n      instanceOf: getTypeInstance(type),\n    }))\n  return types\n}\n\nfunction getTypeInstance(type) {\n  if (type instanceof GraphQLInterfaceType) {\n    return 'interface'\n  } else if (type instanceof GraphQLUnionType) {\n    return 'union'\n  } else if (type instanceof GraphQLEnumType) {\n    return 'enum'\n  } else if (type instanceof GraphQLInputObjectType) {\n    return 'input'\n  } else {\n    return 'type'\n  }\n}\n\n\n// Returns a prettified schema\nexport function getSDL(\n  schema: GraphQLSchema | null | undefined,\n  commentsDisabled: boolean = true,\n) {\n  if (schema instanceof GraphQLSchema) {\n    const rawSdl = printSchema(schema, { commentDescriptions: true })\n    if (commentsDisabled) {\n      // Removes Comments but still has new lines\n      // Removes newlines left behind by Comments\n      return prettify(rawSdl, {\n        printWidth: 80,\n        tabWidth: 2,\n        useTabs: false,\n      })\n    }\n    return prettify(rawSdl, {\n      printWidth: 80,\n      tabWidth: 2,\n      useTabs: false,\n    })\n  }\n  return ''\n}\n\n// Downloads the schema in either .json or .graphql format\nexport function downloadSchema(schema: GraphQLSchema, type: string) {\n  if (type === 'sdl') {\n    const data = getSDL(schema, false)\n    const filename = 'schema.graphql'\n    return download(data, filename)\n  } else {\n    const data = JSON.stringify(schema)\n    const filename = 'introspectionSchema.json'\n    return download(data, filename)\n  }\n}\n\n// Performant option for downloading files\nfunction download(data: any, filename: string, mime?: string) {\n  const blob = new Blob([data], { type: mime || 'application/octet-stream' })\n  if (typeof window.navigator.msSaveBlob !== 'undefined') {\n    window.navigator.msSaveBlob(blob, filename)\n  } else {\n    const blobURL = window.URL.createObjectURL(blob)\n    const tempLink = document.createElement('a')\n    tempLink.style.display = 'none'\n    tempLink.href = blobURL\n    tempLink.setAttribute('download', filename)\n    if (typeof tempLink.download === 'undefined') {\n      tempLink.setAttribute('target', '_blank')\n    }\n    document.body.appendChild(tempLink)\n    tempLink.click()\n    document.body.removeChild(tempLink)\n    window.URL.revokeObjectURL(blobURL)\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/fibonacci-backoff.ts",
    "content": "import { memoize } from 'lodash'\nconst fibonacci = memoize(num => {\n  if (num <= 1) {\n    return 1\n  }\n\n  return fibonacci(num - 1) + fibonacci(num - 2)\n})\n\nexport class Backoff {\n  cb\n  count = 1\n  running = true\n  timeout\n  maxRetries = 20\n  constructor(cb) {\n    this.cb = cb\n  }\n  async start() {\n    const fn = async () => {\n      await this.cb()\n      this.count++\n      // The first 5 attempts are fast, then fibonacci starts with n = 3\n      if (this.running && this.count < this.maxRetries) {\n        this.timeout = setTimeout(\n          fn,\n          (this.count < 3 ? 5 : fibonacci(this.count - 5)) * 1000,\n        )\n      }\n    }\n    fn()\n  }\n  stop = () => {\n    this.running = false\n    clearTimeout(this.timeout)\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/getQueryFacts.ts",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\nimport { typeFromAST, DocumentNode } from 'graphql'\n\n/**\n * Provided previous \"queryFacts\", a GraphQL schema, and a query document\n * string, return a set of facts about that query useful for GraphiQL features.\n *\n * If the query cannot be parsed, returns undefined.\n */\nexport function getQueryFacts(schema, documentAST: DocumentNode): any {\n  const variableToType = schema ? collectVariables(schema, documentAST) : null\n\n  // Collect operations by their names.\n  const operations: any[] = []\n  documentAST.definitions.forEach(def => {\n    if (def.kind === 'OperationDefinition') {\n      operations.push(def)\n    }\n  })\n\n  return { variableToType, operations }\n}\n\n/**\n * Provided a schema and a document, produces a `variableToType` Object.\n */\nexport function collectVariables(schema, documentAST) {\n  const variableToType = Object.create(null)\n  documentAST.definitions.forEach(definition => {\n    if (definition.kind === 'OperationDefinition') {\n      const variableDefinitions = definition.variableDefinitions\n      if (variableDefinitions) {\n        variableDefinitions.forEach(({ variable, type }) => {\n          const inputType = typeFromAST(schema, type)\n          if (inputType) {\n            variableToType[variable.name.value] = inputType\n          }\n        })\n      }\n    }\n  })\n  return variableToType\n}\n\n// function getDeepType(type) {\n//   if (type.type) {\n//     return getDeepType(type.type)\n//   }\n//   return type\n// }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/getQueryTypes.ts",
    "content": "import { QueryTypes } from '../../../state/sessions/reducers'\n\nexport const getQueryTypes = (ast): QueryTypes => {\n  let hasSubscription = false\n  let hasQuery = false\n  let hasMutation = false\n  let firstOperationName = null\n  // let operations: OperationDefinition[] = []\n\n  if (ast && ast.definitions) {\n    ast.definitions.forEach(definition => {\n      if (!firstOperationName) {\n        firstOperationName = definition.name && definition.name.value\n      }\n\n      if (!firstOperationName) {\n        firstOperationName =\n          definition.selectionSet &&\n          definition.selectionSet.selections &&\n          definition.selectionSet.selections.length > 0 &&\n          definition.selectionSet.selections[0].name.value\n      }\n      if (definition.operation === 'subscription') {\n        hasSubscription = true\n      }\n      if (definition.operation === 'query') {\n        hasQuery = true\n      }\n      if (definition.operation === 'mutation') {\n        hasMutation = true\n      }\n      // if (definition.name) {\n      //   operations.push({\n      //     name: definition.name.value,\n      //     startLine: definition.loc.startToken.line,\n      //     endLine: definition.loc.endToken.line,\n      //   })\n      // }\n    })\n  }\n\n  return {\n    firstOperationName,\n    subscription: hasSubscription,\n    query: hasQuery,\n    mutation: hasMutation,\n    // operations,\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/getSelectedOperationName.ts",
    "content": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n */\n\n/**\n * Provided optional previous operations and selected name, and a next list of\n * operations, determine what the next selected operation should be.\n */\nexport default function getSelectedOperationName(\n  prevOperations,\n  prevSelectedOperationName,\n  operations,\n) {\n  // If there are not enough operations to bother with, return nothing.\n  if (!operations || operations.length < 1) {\n    return\n  }\n\n  // If a previous selection still exists, continue to use it.\n  const names = operations.map(op => op.name && op.name.value)\n  if (\n    prevSelectedOperationName &&\n    names.indexOf(prevSelectedOperationName) !== -1\n  ) {\n    return prevSelectedOperationName\n  }\n\n  // If a previous selection was the Nth operation, use the same Nth.\n  if (prevSelectedOperationName && prevOperations) {\n    const prevNames = prevOperations.map(op => op.name && op.name.value)\n    const prevIndex = prevNames.indexOf(prevSelectedOperationName)\n    if (prevIndex !== -1 && prevIndex < names.length) {\n      return names[prevIndex]\n    }\n  }\n\n  // Use the first operation.\n  return names[0]\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/getWorkspaceId.ts",
    "content": "export function getWorkspaceId(props: {\n  configPath?: string\n  workspaceName?: string\n  endpoint?: string\n}) {\n  const configPathString = props.configPath ? `${props.configPath}~` : ''\n  const workspaceNameString = props.workspaceName\n    ? `${props.workspaceName}~`\n    : ''\n  return `${configPathString}${workspaceNameString}${props.endpoint}`\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/hasSubscription.ts",
    "content": "import { Operation } from 'apollo-link'\nimport { OperationDefinitionNode } from 'graphql'\n\nexport function isSubscription(operation: Operation): boolean {\n  const selectedOperation = getSelectedOperation(operation)\n  if (selectedOperation) {\n    return selectedOperation.operation === 'subscription'\n  }\n  return false\n}\n\nfunction getSelectedOperation(\n  operation: Operation,\n): OperationDefinitionNode | undefined {\n  if (operation.query.definitions.length === 1) {\n    return operation.query.definitions[0] as OperationDefinitionNode\n  }\n\n  return operation.query.definitions.find(\n    d =>\n      d.kind === 'OperationDefinition' &&\n      !!d.name &&\n      d.name.value === operation.operationName,\n  ) as OperationDefinitionNode\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/immutableMemoize.ts",
    "content": "import { is } from 'immutable'\n\nexport function immutableMemoize(fn) {\n  let lastValue\n  return arg => {\n    const newValue = fn(arg)\n    if (!is(lastValue, newValue)) {\n      lastValue = newValue\n    }\n    return lastValue\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/makeOperation.ts",
    "content": "import { setIn } from 'immutable'\nimport { parse } from 'graphql'\nimport { Operation } from 'apollo-link'\n\nexport interface GraphQLRequestData {\n  query: string\n  variables?: any\n  operationName?: string\n  extensions?: any\n}\n\nexport function makeOperation(request: GraphQLRequestData): Operation {\n  return setIn(request, ['query'], parse(request.query)) as any\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/parseHeaders.ts",
    "content": "export function parseHeaders(headers?: string) {\n  if (!headers) {\n    return {}\n  }\n  try {\n    return JSON.parse(headers)\n  } catch (e) {\n    return {}\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/session.ts",
    "content": "import { Session } from '../../../state/sessions/reducers'\n\nexport function isSharingAuthorization(sharableSessions: Session[]): boolean {\n  // If user's gonna share an Authorization header,\n  // let's warn her\n\n  // Check all sessions\n  for (const session of sharableSessions) {\n    // Check every header of each session\n    for (const header of Object.keys(session.headers || {})) {\n      // If there's a Authorization header present,\n      // set the flag to `true` and stop the loop\n      if (header.toLowerCase() === 'authorization') {\n        // break\n        return true\n      }\n    }\n  }\n\n  return false\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/shallowEqual.ts",
    "content": "const hasOwn = Object.prototype.hasOwnProperty\n\nfunction is(x, y) {\n  if (x === y) {\n    return x !== 0 || y !== 0 || 1 / x === 1 / y\n  } else {\n    return x !== x && y !== y\n  }\n}\n\nexport default function shallowEqual(objA, objB) {\n  if (is(objA, objB)) {\n    return true\n  }\n\n  if (\n    typeof objA !== 'object' ||\n    objA === null ||\n    typeof objB !== 'object' ||\n    objB === null\n  ) {\n    return false\n  }\n\n  const keysA = Object.keys(objA)\n  const keysB = Object.keys(objB)\n\n  if (keysA.length !== keysB.length) {\n    return false\n  }\n\n  /* tslint:disable-next-line */\n  for (let i = 0; i < keysA.length; i++) {\n    if (!hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {\n      return false\n    }\n  }\n\n  return true\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/shouldUpdate.ts",
    "content": "// import { pick } from 'lodash'\n//\n// const cache: any = {}\n//\n// // TODO remove\n// export default function shouldUpdate(\n//   name: string | null,\n//   instance,\n//   nextProps,\n//   nextState,\n// ) {\n//   const { props } = instance\n//   let fields: any[] = []\n//\n//   if (name && cache[name]) {\n//     fields = cache[name]\n//   }\n//\n//   if ((name && !cache[name]) || !name) {\n//     fields = Object.keys(props).filter(k => typeof props[k] !== 'function')\n//\n//     if (name) {\n//       cache[name] = fields\n//     }\n//   }\n//\n//   const oldProps = pick(props, fields)\n//   const newProps = pick(nextProps, fields)\n//\n//   const propsEqual = shallowEqual(oldProps, newProps)\n//   const stateEqual = shallowEqual(instance.state, nextState)\n//\n//   return !propsEqual && !stateEqual\n// }\n//\n// const hasOwnProperty = Object.prototype.hasOwnProperty\n//\n// function is(x, y) {\n//   // SameValue algorithm\n//   if (x === y) {\n//     // Steps 1-5, 7-10\n//     // Steps 6.b-6.e: +0 != -0\n//     // Added the nonzero y check to make Flow happy, but it is redundant\n//     return x !== 0 || y !== 0 || 1 / x === 1 / y\n//   } else {\n//     // Step 6.a: NaN == NaN\n//     return x !== x && y !== y\n//   }\n// }\n//\n// /**\n//  * Performs equality by iterating through keys on an object and returning false\n//  * when any key has values which are not strictly equal between the arguments.\n//  * Returns true when the values of all keys are strictly equal.\n//  */\n// function shallowEqual(objA, objB) {\n//   if (is(objA, objB)) {\n//     return true\n//   }\n//\n//   if (\n//     typeof objA !== 'object' ||\n//     objA === null ||\n//     typeof objB !== 'object' ||\n//     objB === null\n//   ) {\n//     return false\n//   }\n//\n//   const keysA = Object.keys(objA)\n//   const keysB = Object.keys(objB)\n//\n//   if (keysA.length !== keysB.length) {\n//     return false\n//   }\n//\n//   // Test for A's keys different from B.\n//   for (const key of keysA) {\n//     if (!hasOwnProperty.call(objB, key) || !is(objA[key], objB[key])) {\n//       return false\n//     }\n//   }\n//\n//   return true\n// }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/stack.ts",
    "content": "import { isType, GraphQLInterfaceType, GraphQLObjectType } from 'graphql'\nimport { Map } from 'immutable'\n\nexport function getNewStack(root, schema, stack: Map<any, any>) {\n  const path = stack.getIn(['field', 'path'])\n  const splittedPath = path.split('/')\n  let pointer: any = null\n  let count = 0\n  let lastPointer: any = null\n  let y = -1\n  while (splittedPath.length > 0) {\n    const currentPath: string = splittedPath.shift()!\n    if (count === 0) {\n      pointer = root[currentPath]\n      y = Object.keys(root).indexOf(currentPath)\n    } else {\n      const argFound = pointer.args.find(arg => arg.name === currentPath)\n      lastPointer = pointer\n      if (argFound) {\n        pointer = argFound\n      } else {\n        if (pointer.type.ofType) {\n          pointer = getDeeperType(pointer.type.ofType)\n        }\n        if (pointer.type) {\n          pointer = pointer.type\n        }\n        pointer =\n          pointer.getFields()[currentPath] ||\n          pointer.getInterfaces().find(i => i.name === currentPath)\n      }\n    }\n    if (lastPointer) {\n      y = getElementIndex(schema, lastPointer, pointer)\n    }\n    count++\n  }\n\n  if (!pointer) {\n    return null\n  }\n\n  pointer.path = path\n  pointer.parent = lastPointer\n\n  return stack.merge({\n    y,\n    field: pointer,\n  })\n}\n\n// Return the deeper type found on object\n// For example [[[Company]!]!]! will return only Company\nexport function getDeeperType(type: any, depth: number = 0): any {\n  if (type.ofType && depth < 5) {\n    return getDeeperType(type.ofType, depth + 1)\n  }\n  return type\n}\n\nexport interface SerializedRoot {\n  queries: any[]\n  mutations: any[]\n  subscriptions: any[]\n}\n\nexport function getRootMap(schema): any {\n  return {\n    ...schema.getQueryType().getFields(),\n    ...(schema.getMutationType &&\n      schema.getMutationType() &&\n      schema.getMutationType().getFields()),\n    ...(schema.getSubscriptionType &&\n      schema.getSubscriptionType() &&\n      schema.getSubscriptionType().getFields()),\n  }\n}\n\n// Serialize schema to get root object\nexport function serializeRoot(schema): SerializedRoot {\n  const obj: SerializedRoot = {\n    queries: [],\n    mutations: [],\n    subscriptions: [],\n  }\n  const queryType = schema.getQueryType()\n  const queryFieldMap = queryType.getFields()\n  obj.queries = Object.keys(queryFieldMap).map(fieldName => {\n    const field = queryFieldMap[fieldName]\n    field.path = fieldName\n    field.parent = null\n    return field\n  })\n  const mutationType = schema.getMutationType && schema.getMutationType()\n  if (mutationType) {\n    const mutationFieldMap = mutationType.getFields()\n    obj.mutations = Object.keys(mutationFieldMap).map(fieldName => {\n      const field = mutationFieldMap[fieldName]\n      field.path = fieldName\n      field.parent = null\n      return field\n    })\n  }\n  ;(window as any).ss = schema\n  const subscriptionType =\n    schema.getSubscriptionType && schema.getSubscriptionType()\n  if (subscriptionType) {\n    const subscriptionFieldMap = subscriptionType.getFields()\n    obj.subscriptions = Object.keys(subscriptionFieldMap).map(fieldName => {\n      const field = subscriptionFieldMap[fieldName]\n      field.path = fieldName\n      field.parent = null\n      return field\n    })\n  }\n  return obj\n}\n\n// Return element that match index on root object\nexport function getElementRoot(obj: any, index: number) {\n  let i = 0\n  if (obj.queries[index + i]) {\n    return obj.queries[index + i]\n  }\n  i += obj.queries.length\n  if (obj.mutations[index - i]) {\n    return obj.mutations[index - i]\n  }\n  i += obj.mutations.length\n  if (obj.subscriptions[index - i]) {\n    return obj.subscriptions[index - i]\n  }\n}\n\nexport interface SerializedObj {\n  fields: any[]\n  interfaces: any[]\n  args: any[]\n  implementations: any[]\n}\n// Serialize field\nexport function serialize(schema, field) {\n  const obj: SerializedObj = {\n    fields: [],\n    interfaces: [],\n    args: [],\n    implementations: [],\n  }\n  let type = field.type || field\n  const isVarType = isType(type)\n  if (type.ofType) {\n    type = getDeeperType(type.ofType)\n  }\n  // Get fields\n  if (type.getFields) {\n    const fieldMap = type.getFields()\n    obj.fields = Object.keys(fieldMap).map(name => {\n      const f = fieldMap[name]\n      f.parent = field\n      f.path = field.path + `/${name}`\n      return f\n    })\n  }\n  // Get interfaces\n  if (type instanceof GraphQLObjectType) {\n    obj.interfaces = type.getInterfaces()\n  }\n  // Get args\n  obj.args = field.args ? field.args : []\n  // Get implementations\n  if (isVarType && type instanceof GraphQLInterfaceType) {\n    obj.implementations = schema.getPossibleTypes(type)\n  }\n  return obj\n}\n\n// Return element that match index on object\nexport function getElement(obj: any, index: number) {\n  let i = 0\n  if (obj.interfaces[index + i]) {\n    return obj.interfaces[index + i]\n  }\n  i += obj.interfaces.length\n  if (obj.fields[index - i]) {\n    return obj.fields[index - i]\n  }\n  i += obj.fields.length\n  if (obj.args[index - i]) {\n    return obj.args[index - i]\n  }\n  i += obj.args.length\n  if (obj.implementations[index - i]) {\n    return obj.implementations[index - i]\n  }\n}\n\nexport function getElementIndex(schema: any, main: any, element: any) {\n  const obj = serialize(schema, main)\n  const interfaceIndex = obj.interfaces.indexOf(element)\n  if (interfaceIndex > -1) {\n    return interfaceIndex\n  }\n\n  const fieldsIndex = obj.fields.indexOf(element)\n  if (fieldsIndex > -1) {\n    return obj.interfaces.length + fieldsIndex\n  }\n\n  const argsIndex = obj.args.indexOf(element)\n  if (argsIndex > -1) {\n    return obj.interfaces.length + obj.fields.length + argsIndex\n  }\n\n  const implementationIndex = obj.implementations.indexOf(element)\n  if (implementationIndex > -1) {\n    return (\n      obj.interfaces.length +\n      obj.fields.length +\n      obj.args.length +\n      implementationIndex\n    )\n  }\n\n  return 0\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/toJS.tsx",
    "content": "import * as React from 'react'\nimport { isImmutable } from 'immutable'\nexport const toJS = WrappedComponent => wrappedComponentProps => {\n  const KEY = 0\n  const VALUE = 1\n  const propsJS = Object.entries(wrappedComponentProps).reduce(\n    (newProps, wrappedComponentProp: any) => {\n      newProps[wrappedComponentProp[KEY]] = isImmutable(\n        wrappedComponentProp[VALUE],\n      )\n        ? wrappedComponentProp[VALUE].toJS()\n        : wrappedComponentProp[VALUE]\n      return newProps\n    },\n    {},\n  )\n  return <WrappedComponent {...propsJS} />\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/util/whatChanged.ts",
    "content": "export function whatChanged(\n  oldProps,\n  newProps,\n  oldState?: any,\n  newState?: any,\n) {\n  return {\n    props: getUnequalProps(oldProps, newProps),\n    state: oldState && newState ? getUnequalProps(oldState, newState) : null,\n  }\n}\n\nfunction getUnequalProps(obj1, obj2) {\n  return Object.keys(obj1).filter(key => {\n    return obj1[key] !== obj2[key]\n  })\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground.tsx",
    "content": "import * as React from 'react'\nimport GraphQLEditor from './Playground/GraphQLEditor'\nimport TabBar from './Playground/TabBar'\nimport { ISettings } from '../types'\nimport HistoryPopup from './HistoryPopup'\nimport { styled } from '../styled'\nimport Settings from './Settings'\nimport { PlaygroundSettingsEditor, GraphQLConfigEditor } from './SettingsEditor'\nimport { GraphQLConfig } from '../graphqlConfig'\nimport FileEditor from './FileEditor'\nimport { ApolloLink } from 'apollo-link'\n\nimport * as app from '../../package.json'\nimport { connect } from 'react-redux'\nimport {\n  selectTabIndex,\n  selectNextTab,\n  selectPrevTab,\n  newSession,\n  closeSelectedTab,\n  saveSettings,\n  saveConfig,\n  setTracingSupported,\n  injectHeaders,\n  schemaFetchingError,\n  schemaFetchingSuccess,\n} from '../state/sessions/actions'\nimport { setConfigString } from '../state/general/actions'\nimport { initState } from '../state/workspace/actions'\nimport { GraphQLSchema, validateSchema } from 'graphql'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getIsConfigTab,\n  getIsSettingsTab,\n  getIsFile,\n  getFile,\n  getHeaders,\n  getIsReloadingSchema,\n  getEndpoint,\n  getIsPollingSchema,\n} from '../state/sessions/selectors'\nimport { getHistoryOpen } from '../state/general/selectors'\nimport {\n  setLinkCreator,\n  schemaFetcher,\n  setSubscriptionEndpoint,\n} from '../state/sessions/fetchingSagas'\nimport { Session } from '../state/sessions/reducers'\nimport { getWorkspaceId } from './Playground/util/getWorkspaceId'\nimport { getSettings, getSettingsString } from '../state/workspace/reducers'\nimport { Backoff } from './Playground/util/fibonacci-backoff'\nimport { debounce } from 'lodash'\nimport { cachedPrintSchema } from './util'\nimport { InvalidSchemaError } from './Playground/util/InvalidSchemaError'\n\nexport interface Response {\n  resultID: string\n  date: string\n  time: Date\n}\n\nexport interface Props {\n  endpoint: string\n  sessionEndpoint: string\n  subscriptionEndpoint?: string\n  projectId?: string\n  shareEnabled?: boolean\n  fixedEndpoint?: boolean\n  onSuccess?: (graphQLParams: any, response: any) => void\n  isEndpoint?: boolean\n  isApp?: boolean\n  onChangeEndpoint?: (endpoint: string) => void\n  share?: (state: any) => void\n  shareUrl?: string\n  onChangeSubscriptionsEndpoint?: (endpoint: string) => void\n  getRef?: (ref: Playground) => void\n  graphqlConfig?: any\n  onSaveSettings?: () => void\n  onChangeSettings?: (settingsString: string) => void\n  onSaveConfig: () => void\n  onChangeConfig: (configString: string) => void\n  onUpdateSessionCount?: () => void\n  config: GraphQLConfig\n  configString: string\n  configIsYaml: boolean\n  canSaveConfig: boolean\n  fixedEndpoints: boolean\n  headers?: { [key: string]: string }\n  configPath?: string\n  createApolloLink?: (\n    session: Session,\n    subscriptionEndpoint?: string,\n  ) => ApolloLink\n  workspaceName?: string\n  schema?: GraphQLSchema\n}\n\nexport interface ReduxProps {\n  selectTabIndex: (index: number) => void\n  selectNextTab: () => void\n  selectPrevTab: () => void\n  closeSelectedTab: () => void\n  newSession: (endpoint: string, reuseHeaders: boolean) => void\n  initState: (workspaceId: string, endpoint: string) => void\n  saveConfig: () => void\n  saveSettings: () => void\n  setTracingSupported: (value: boolean) => void\n  injectHeaders: (\n    headers: string | { [key: string]: string } | void,\n    endpoint: string,\n  ) => void\n  setConfigString: (str: string) => void\n  schemaFetchingError: (endpoint: string, error: string) => void\n  schemaFetchingSuccess: (\n    endpoint: string,\n    tracingSupported: boolean,\n    isPollingSchema: boolean,\n  ) => void\n  isReloadingSchema: boolean\n  isPollingSchema: boolean\n  isConfigTab: boolean\n  isSettingsTab: boolean\n  isFile: boolean\n  historyOpen: boolean\n  file: string\n  sessionHeaders?: any\n  settings: ISettings\n  settingsString: string\n}\n\nexport interface State {\n  schema?: GraphQLSchema\n}\n\nexport interface CursorPosition {\n  line: number\n  ch: number\n}\n\nexport { GraphQLEditor }\n\nexport class Playground extends React.PureComponent<Props & ReduxProps, State> {\n  static defaultProps = {\n    shareEnabled: false,\n  }\n\n  apolloLinks: { [sessionId: string]: any } = {}\n  observers: { [sessionId: string]: any } = {}\n  graphiqlComponents: any[] = []\n\n  // debounce as we call this on each http header or endpoint edit\n  getSchema = debounce(\n    async (props: Props & ReduxProps = this.props) => {\n      if (props.schema) {\n        return\n      }\n      if (this.mounted && this.state.schema && !props.isPollingSchema) {\n        this.setState({ schema: undefined })\n      }\n      let first = true\n      if (this.backoff) {\n        this.backoff.stop()\n      }\n      this.backoff = new Backoff(async () => {\n        if (first) {\n          await this.schemaGetter(props)\n          first = false\n        } else {\n          await this.schemaGetter()\n        }\n      })\n      this.backoff.start()\n    },\n    600,\n    { trailing: true }, // important to not miss the last call\n  ) as any\n\n  private backoff: Backoff\n  private initialIndex: number = -1\n  private mounted = false\n  private initialSchemaFetch = true\n\n  constructor(props: Props & ReduxProps) {\n    super(props)\n\n    if (props.schema) {\n      const validationErrors = validateSchema(props.schema)\n      if (validationErrors && validationErrors.length > 0) {\n        throw new InvalidSchemaError(validationErrors);\n      }  \n    }\n\n    this.state = {\n      schema: props.schema,\n    }\n    ;(global as any).p = this\n\n    if (typeof this.props.getRef === 'function') {\n      this.props.getRef(this)\n    }\n\n    setLinkCreator(props.createApolloLink)\n    this.getSchema()\n    setSubscriptionEndpoint(props.subscriptionEndpoint)\n  }\n\n  UNSAFE_componentWillMount() {\n    // init redux\n    this.props.initState(getWorkspaceId(this.props), this.props.endpoint)\n    this.props.setConfigString(this.props.configString)\n    this.props.injectHeaders(this.props.headers, this.props.endpoint)\n  }\n\n  componentDidMount() {\n    if (this.initialIndex > -1) {\n      this.setState({\n        selectedSessionIndex: this.initialIndex,\n      } as State)\n    }\n    this.mounted = true\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps: Props & ReduxProps) {\n    if (this.props.createApolloLink !== nextProps.createApolloLink) {\n      setLinkCreator(nextProps.createApolloLink)\n    }\n    if (\n      nextProps.headers !== this.props.headers ||\n      nextProps.endpoint !== this.props.endpoint ||\n      nextProps.workspaceName !== this.props.workspaceName ||\n      nextProps.sessionHeaders !== this.props.sessionHeaders ||\n      nextProps.sessionEndpoint !== this.props.sessionEndpoint\n    ) {\n      this.getSchema(nextProps)\n    }\n    if (this.props.isReloadingSchema && !nextProps.isReloadingSchema) {\n      setTimeout(() => {\n        this.getSchema(nextProps)\n      })\n    }\n    if (\n      this.props.endpoint !== nextProps.endpoint ||\n      this.props.configPath !== nextProps.configPath ||\n      nextProps.workspaceName !== this.props.workspaceName\n    ) {\n      this.props.initState(getWorkspaceId(nextProps), nextProps.endpoint)\n    }\n    if (this.props.subscriptionEndpoint !== nextProps.subscriptionEndpoint) {\n      setSubscriptionEndpoint(nextProps.subscriptionEndpoint)\n    }\n    if (nextProps.headers !== this.props.headers) {\n      this.props.injectHeaders(nextProps.headers, nextProps.endpoint)\n    }\n    if (nextProps.configString !== this.props.configString) {\n      this.props.setConfigString(nextProps.configString)\n    }\n    if (nextProps.schema !== this.props.schema) {\n      const validationErrors = validateSchema(nextProps.schema)\n      if (validationErrors && validationErrors.length > 0) {\n        throw new InvalidSchemaError(validationErrors);\n      }  \n      this.setState({ schema: nextProps.schema })\n    }\n  }\n\n  async schemaGetter(propsInput?: Props & ReduxProps) {\n    const props = propsInput || this.props\n    const endpoint = props.sessionEndpoint || props.endpoint\n    const currentSchema = this.state.schema\n    const globalHeaders = props.settings['request.globalHeaders']\n\n    try {\n      const data = {\n        endpoint,\n        headers:\n          props.sessionHeaders && props.sessionHeaders.length > 0\n            ? JSON.stringify({\n                ...globalHeaders,\n                ...JSON.parse(props.sessionHeaders),\n              })\n            : JSON.stringify({\n                ...globalHeaders,\n                ...props.headers,\n              }),\n        credentials: props.settings['request.credentials'],\n        useTracingHeader:\n          !this.initialSchemaFetch &&\n          props.settings['tracing.tracingSupported'],\n      }\n      const schema = await schemaFetcher.fetch(data)\n      schemaFetcher.subscribe(data, newSchema => {\n        if (\n          data.endpoint === this.props.endpoint ||\n          data.endpoint === this.props.sessionEndpoint\n        ) {\n          this.updateSchema(currentSchema, newSchema, props)\n        }\n      })\n      if (schema) {\n        this.updateSchema(currentSchema, schema.schema, props)\n        if (this.initialSchemaFetch) {\n          this.props.schemaFetchingSuccess(\n            data.endpoint,\n            schema.tracingSupported,\n            props.isPollingSchema,\n          )\n          this.initialSchemaFetch = false\n        }\n        this.backoff.stop()\n      }\n    } catch (e) {\n      // tslint:disable-next-line\n      console.error(e)\n      this.props.schemaFetchingError(endpoint, e.message)\n    }\n  }\n\n  render() {\n    const { version }: any = app\n\n    window.version = version\n\n    return (\n      <PlaygroundContainer className=\"playground\">\n        <TabBar onNewSession={this.createSession} isApp={this.props.isApp} />\n        <GraphiqlsContainer>\n          <GraphiqlWrapper className=\"graphiql-wrapper active\">\n            {this.props.isConfigTab ? (\n              <GraphQLConfigEditor\n                onSave={this.handleSaveConfig}\n                isYaml={this.props.configIsYaml}\n                isConfig={true}\n                readOnly={!this.props.canSaveConfig}\n              />\n            ) : this.props.isSettingsTab ? (\n              <PlaygroundSettingsEditor onSave={this.handleSaveSettings} />\n            ) : this.props.isFile && this.props.file ? (\n              <FileEditor />\n            ) : (\n              <GraphQLEditor\n                shareEnabled={this.props.shareEnabled}\n                fixedEndpoint={this.props.fixedEndpoint}\n                schema={this.state.schema}\n              />\n            )}\n          </GraphiqlWrapper>\n        </GraphiqlsContainer>\n        <Settings />\n        {this.props.historyOpen && this.renderHistoryPopup()}\n      </PlaygroundContainer>\n    )\n  }\n\n  renderHistoryPopup() {\n    return <HistoryPopup />\n  }\n\n  setRef = (index: number, ref: any) => {\n    this.graphiqlComponents[index] = ref ? ref.getWrappedInstance() : ref\n  }\n\n  public closeTab = () => {\n    this.props.closeSelectedTab()\n  }\n\n  public nextTab = () => {\n    this.props.selectNextTab()\n  }\n\n  public prevTab = () => {\n    this.props.selectPrevTab()\n  }\n\n  public switchTab = (index: number) => {\n    this.props.selectTabIndex(index)\n  }\n\n  handleSaveConfig = () => {\n    this.props.saveConfig()\n    this.props.onSaveConfig()\n  }\n\n  handleSaveSettings = () => {\n    this.props.saveSettings()\n    this.props.onSaveSettings()\n  }\n\n  private createSession = () => {\n    this.props.newSession(\n      this.props.endpoint,\n      this.props.settings['editor.reuseHeaders'],\n    )\n  }\n\n  private updateSchema(\n    currentSchema: GraphQLSchema | undefined,\n    newSchema: GraphQLSchema,\n    props: Readonly<{ children?: React.ReactNode }> &\n      Readonly<Props & ReduxProps>,\n  ) {\n    // first check for reference equality\n    if (currentSchema !== newSchema) {\n      // if references are not equal, do an equality check on the printed schema\n      const currentSchemaStr = currentSchema\n        ? cachedPrintSchema(currentSchema)\n        : null\n      const newSchemaStr = cachedPrintSchema(newSchema)\n\n      if (newSchemaStr !== currentSchemaStr || !props.isPollingSchema) {\n        this.setState({ schema: newSchema })\n      }\n    }\n  }\n\n  get httpApiPrefix() {\n    return this.props.endpoint.match(/(https?:\\/\\/.*?)\\/?/)![1]\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  isConfigTab: getIsConfigTab,\n  isSettingsTab: getIsSettingsTab,\n  isFile: getIsFile,\n  historyOpen: getHistoryOpen,\n  file: getFile,\n  sessionHeaders: getHeaders,\n  settings: getSettings,\n  settingsString: getSettingsString,\n  isReloadingSchema: getIsReloadingSchema,\n  isPollingSchema: getIsPollingSchema,\n  sessionEndpoint: getEndpoint,\n})\n\nexport default connect(\n  mapStateToProps,\n  {\n    selectTabIndex,\n    selectNextTab,\n    selectPrevTab,\n    newSession,\n    closeSelectedTab,\n    initState,\n    saveSettings,\n    saveConfig,\n    setTracingSupported,\n    injectHeaders,\n    setConfigString,\n    schemaFetchingError,\n    schemaFetchingSuccess,\n  },\n)(Playground)\n\nconst PlaygroundContainer = styled.div`\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n\n  height: 100%;\n  margin: 0;\n  padding: 0;\n  overflow: hidden;\n  margin-right: -1px !important;\n\n  line-height: 1.5;\n  font-family: 'Open Sans', sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  letter-spacing: 0.53px;\n  color: rgba(0, 0, 0, 0.8);\n\n  a:active,\n  a:focus,\n  button:focus,\n  input:focus {\n    outline: none;\n  }\n`\n\nconst GraphiqlsContainer = styled.div`\n  height: calc(100vh - 57px);\n  position: relative;\n  overflow: hidden;\n`\n\nconst GraphiqlWrapper = styled.div`\n  width: 100%;\n  height: 100%;\n  position: relative;\n  overflow: hidden;\n  visibility: hidden;\n  &.active {\n    visibility: visible;\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/PlaygroundWrapper.tsx",
    "content": "import * as React from 'react'\nimport Playground, { Playground as IPlayground } from './Playground'\nimport { Helmet } from 'react-helmet'\nimport { GraphQLConfig } from '../graphqlConfig'\nimport * as yaml from 'js-yaml'\nimport ProjectsSideNav from './ProjectsSideNav'\nimport {\n  styled,\n  ThemeProvider,\n  theme as styledTheme,\n  keyframes,\n} from '../styled'\nimport {\n  darkColours,\n  lightColours,\n  darkEditorColours,\n  lightEditorColours,\n  EditorColours,\n} from '../styled/theme'\n// import OldThemeProvider from './Theme/ThemeProvider'\nimport { getActiveEndpoints } from './util'\nimport { ISettings } from '../types'\nimport { connect } from 'react-redux'\nimport { getTheme, getSettings } from '../state/workspace/reducers'\nimport { Session, Tab } from '../state/sessions/reducers'\nimport { ApolloLink } from 'apollo-link'\nimport { injectTabs } from '../state/workspace/actions'\nimport { buildSchema, buildClientSchema, GraphQLSchema } from 'graphql'\n\nfunction getParameterByName(name: string, uri?: string): string | null {\n  const url = uri || window.location.href\n  name = name.replace(/[\\[\\]]/g, '\\\\$&')\n  const regexa = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')\n  const results = regexa.exec(url)\n  if (!results || !results[2]) {\n    return null\n  }\n  return decodeURIComponent(results[2].replace(/\\+/g, ' '))\n}\n\nexport interface PlaygroundWrapperProps {\n  endpoint?: string\n  endpointUrl?: string\n  subscriptionEndpoint?: string\n  setTitle?: boolean\n  settings?: ISettings\n  shareEnabled?: boolean\n  fixedEndpoint?: boolean\n  folderName?: string\n  configString?: string\n  showNewWorkspace?: boolean\n  isElectron?: boolean\n  canSaveConfig?: boolean\n  onSaveConfig?: (configString: string) => void\n  onNewWorkspace?: () => void\n  getRef?: (ref: any) => void\n  platformToken?: string\n  env?: any\n  config?: GraphQLConfig\n  configPath?: string\n  injectedState?: any\n  createApolloLink?: (\n    session: Session,\n    subscriptionEndpoint?: string,\n  ) => ApolloLink\n  tabs?: Tab[]\n  schema?: { __schema: any } // introspection result\n  codeTheme?: EditorColours\n  workspaceName?: string\n  headers?: any\n}\n\nexport interface ReduxProps {\n  theme: string\n  injectTabs: (tabs: Tab[]) => void\n}\n\nexport interface State {\n  endpoint: string\n  subscriptionPrefix?: string\n  subscriptionEndpoint?: string\n  shareUrl?: string\n  platformToken?: string\n  configIsYaml?: boolean\n  configString?: string\n  activeProjectName?: string\n  activeEnv?: string\n  headers?: any\n  schema?: GraphQLSchema\n}\n\nclass PlaygroundWrapper extends React.Component<\n  PlaygroundWrapperProps & ReduxProps,\n  State\n> {\n  playground: IPlayground\n  constructor(props: PlaygroundWrapperProps & ReduxProps) {\n    super(props)\n    ;(global as any).m = this\n\n    this.state = this.mapPropsToState(props)\n    this.removeLoader()\n  }\n\n  mapPropsToState(props: PlaygroundWrapperProps): State {\n    const configIsYaml = props.configString\n      ? this.isConfigYaml(props.configString)\n      : false\n\n    const { activeEnv, projectName } = this.getInitialActiveEnv(props.config)\n\n    let endpoint =\n      props.endpoint ||\n      props.endpointUrl ||\n      getParameterByName('endpoint') ||\n      location.href\n\n    const result = this.extractEndpointAndHeaders(endpoint)\n    endpoint = result.endpoint\n    let headers = result.headers\n\n    let subscriptionEndpoint: any =\n      props.subscriptionEndpoint || getParameterByName('subscriptionEndpoint')\n\n    if (props.configString && props.config && activeEnv) {\n      const endpoints = getActiveEndpoints(props.config, activeEnv, projectName)\n      endpoint = endpoints.endpoint\n      subscriptionEndpoint = endpoints.subscriptionEndpoint\n      headers = endpoints.headers\n    }\n\n    subscriptionEndpoint =\n      this.normalizeSubscriptionUrl(endpoint, subscriptionEndpoint) || undefined\n\n    return {\n      endpoint: this.absolutizeUrl(endpoint),\n      platformToken:\n        props.platformToken ||\n        localStorage.getItem('platform-token') ||\n        undefined,\n      subscriptionEndpoint,\n      configIsYaml,\n      configString: props.configString,\n      activeEnv,\n      activeProjectName: projectName,\n      headers,\n    }\n  }\n\n  extractEndpointAndHeaders(endpoint) {\n    const splitted = endpoint.split('?')\n    if (splitted.length === 1) {\n      return { endpoint }\n    }\n    try {\n      const headers = getParameterByName('headers', endpoint)\n      if (headers) {\n        return { headers: JSON.parse(headers), endpoint: splitted[0] }\n      }\n    } catch (e) {\n      //\n    }\n    return { endpoint: splitted[0] }\n  }\n\n  removeLoader() {\n    const loadingWrapper = document.getElementById('loading-wrapper')\n    if (loadingWrapper) {\n      loadingWrapper.remove()\n    }\n  }\n\n  normalizeSubscriptionUrl(endpoint, subscriptionEndpoint) {\n    if (subscriptionEndpoint) {\n      if (subscriptionEndpoint.startsWith('/')) {\n        const secure =\n          endpoint.includes('https') || location.href.includes('https')\n            ? 's'\n            : ''\n        return `ws${secure}://${location.host}${subscriptionEndpoint}`\n      } else {\n        return subscriptionEndpoint.replace(/^http/, 'ws')\n      }\n    }\n\n    return this.getGraphcoolSubscriptionEndpoint(endpoint).replace(\n      /^http/,\n      'ws',\n    )\n  }\n\n  getGraphcoolSubscriptionEndpoint(endpoint) {\n    if (endpoint.includes('api.graph.cool')) {\n      return `wss://subscriptions.graph.cool/v1/${\n        endpoint.split('/').slice(-1)[0]\n      }`\n    }\n\n    return endpoint.replace(/^http/, 'ws')\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps: PlaygroundWrapperProps & ReduxProps) {\n    // Reactive props (props that cause a state change upon being changed)\n    if (\n      nextProps.endpoint !== this.props.endpoint ||\n      nextProps.endpointUrl !== this.props.endpointUrl ||\n      nextProps.subscriptionEndpoint !== this.props.subscriptionEndpoint ||\n      nextProps.configString !== this.props.configString ||\n      nextProps.platformToken !== this.props.platformToken ||\n      nextProps.config !== this.props.config\n    ) {\n      this.setState(this.mapPropsToState(nextProps))\n      this.setInitialWorkspace(nextProps)\n    }\n  }\n\n  getInitialActiveEnv(\n    config?: GraphQLConfig,\n  ): { projectName?: string; activeEnv?: string } {\n    if (config) {\n      if (config.extensions && config.extensions.endpoints) {\n        return {\n          activeEnv: Object.keys(config.extensions.endpoints)[0],\n        }\n      }\n      if (config.projects) {\n        const projectName = Object.keys(config.projects)[0]\n        const project = config.projects[projectName]\n        if (project.extensions && project.extensions.endpoints) {\n          return {\n            activeEnv: Object.keys(project.extensions.endpoints)[0],\n            projectName,\n          }\n        }\n      }\n    }\n\n    return {}\n  }\n\n  isConfigYaml(configString: string) {\n    try {\n      yaml.safeLoad(configString)\n      return true\n    } catch (e) {\n      //\n    }\n    return false\n  }\n\n  absolutizeUrl(url) {\n    if (url.startsWith('/')) {\n      return location.origin + url\n    }\n\n    return url\n  }\n\n  UNSAFE_componentWillMount() {\n    const platformToken = getParameterByName('platform-token')\n    if (platformToken && platformToken.length > 0) {\n      localStorage.setItem('platform-token', platformToken)\n      window.location.replace(window.location.origin + window.location.pathname)\n    }\n  }\n\n  componentDidMount() {\n    if (this.state.subscriptionEndpoint === '') {\n      this.updateSubscriptionsUrl()\n    }\n    setTimeout(() => {\n      this.removePlaygroundInClass()\n    }, 5000)\n    this.setInitialWorkspace()\n    if (this.props.tabs) {\n      this.props.injectTabs(this.props.tabs)\n    } else {\n      const query = getParameterByName('query')\n      if (query) {\n        const endpoint = getParameterByName('endpoint') || this.state.endpoint\n        this.props.injectTabs([{ query, endpoint }])\n      } else {\n        const tabsString = getParameterByName('tabs')\n        if (tabsString) {\n          try {\n            const tabs = JSON.parse(tabsString)\n            this.props.injectTabs(tabs)\n          } catch (e) {\n            //\n          }\n        }\n      }\n    }\n\n    if (this.props.schema) {\n      // in this case it's sdl\n      if (typeof this.props.schema === 'string') {\n        this.setState({ schema: buildSchema(this.props.schema) })\n        // if it's an object, it must be an introspection query\n      } else {\n        this.setState({ schema: buildClientSchema(this.props.schema) })\n      }\n    }\n  }\n\n  setInitialWorkspace(props = this.props) {\n    if (props.config) {\n      const activeEnv = this.getInitialActiveEnv(props.config)\n      const endpoints = getActiveEndpoints(\n        props.config,\n        activeEnv.activeEnv!,\n        activeEnv.projectName,\n      )\n      const endpoint = endpoints.endpoint\n      const subscriptionEndpoint =\n        endpoints.subscriptionEndpoint ||\n        this.normalizeSubscriptionUrl(endpoint, endpoints.subscriptionEndpoint)\n      const headers = endpoints.headers\n      this.setState({\n        endpoint,\n        subscriptionEndpoint,\n        headers,\n        activeEnv: activeEnv.activeEnv,\n        activeProjectName: activeEnv.projectName,\n      })\n    }\n  }\n\n  removePlaygroundInClass() {\n    const root = document.getElementById('root')\n    if (root) {\n      root.classList.remove('playgroundIn')\n    }\n  }\n\n  render() {\n    const title = this.props.setTitle ? (\n      <Helmet>\n        <title>{this.getTitle()}</title>\n      </Helmet>\n    ) : null\n\n    const defaultHeaders = this.props.headers || {}\n    const stateHeaders = this.state.headers || {}\n    const combinedHeaders = { ...defaultHeaders, ...stateHeaders }\n\n    const { theme } = this.props\n    return (\n      <div>\n        {title}\n        <ThemeProvider\n          theme={{\n            ...styledTheme,\n            mode: theme,\n            colours: theme === 'dark' ? darkColours : lightColours,\n            editorColours: {\n              ...(theme === 'dark' ? darkEditorColours : lightEditorColours),\n              ...this.props.codeTheme,\n            },\n            settings: this.props.settings,\n          }}\n        >\n          <App>\n            {this.props.config &&\n              this.state.activeEnv && (\n                <ProjectsSideNav\n                  config={this.props.config}\n                  folderName={this.props.folderName || 'GraphQL App'}\n                  theme={theme}\n                  activeEnv={this.state.activeEnv}\n                  onSelectEnv={this.handleSelectEnv}\n                  onNewWorkspace={this.props.onNewWorkspace}\n                  showNewWorkspace={Boolean(this.props.showNewWorkspace)}\n                  isElectron={Boolean(this.props.isElectron)}\n                  activeProjectName={this.state.activeProjectName}\n                  configPath={this.props.configPath}\n                />\n              )}\n            <Playground\n              endpoint={this.state.endpoint}\n              shareEnabled={this.props.shareEnabled}\n              subscriptionEndpoint={this.state.subscriptionEndpoint}\n              shareUrl={this.state.shareUrl}\n              onChangeEndpoint={this.handleChangeEndpoint}\n              onChangeSubscriptionsEndpoint={\n                this.handleChangeSubscriptionsEndpoint\n              }\n              getRef={this.getPlaygroundRef}\n              config={this.props.config!}\n              configString={this.state.configString!}\n              configIsYaml={this.state.configIsYaml!}\n              canSaveConfig={Boolean(this.props.canSaveConfig)}\n              onChangeConfig={this.handleChangeConfig}\n              onSaveConfig={this.handleSaveConfig}\n              onUpdateSessionCount={this.handleUpdateSessionCount}\n              fixedEndpoints={Boolean(this.state.configString)}\n              fixedEndpoint={this.props.fixedEndpoint}\n              headers={combinedHeaders}\n              configPath={this.props.configPath}\n              workspaceName={\n                this.props.workspaceName || this.state.activeProjectName\n              }\n              createApolloLink={this.props.createApolloLink}\n              schema={this.state.schema}\n            />\n          </App>\n        </ThemeProvider>\n      </div>\n    )\n  }\n\n  handleUpdateSessionCount = () => {\n    this.forceUpdate()\n  }\n\n  getPlaygroundRef = ref => {\n    this.playground = ref\n    if (typeof this.props.getRef === 'function') {\n      this.props.getRef(ref)\n    }\n  }\n\n  handleChangeConfig = (configString: string) => {\n    this.setState({ configString })\n  }\n\n  handleSaveConfig = () => {\n    /* tslint:disable-next-line */\n    if (typeof this.props.onSaveConfig === 'function') {\n      /* tslint:disable-next-line */\n      this.props.onSaveConfig(this.state.configString!)\n    }\n  }\n\n  handleSelectEnv = (env: string, projectName?: string) => {\n    const { endpoint, subscriptionEndpoint, headers } = getActiveEndpoints(\n      this.props.config!,\n      env,\n      projectName,\n    )!\n    this.setState({\n      activeEnv: env,\n      endpoint,\n      headers,\n      subscriptionEndpoint: this.normalizeSubscriptionUrl(\n        endpoint,\n        subscriptionEndpoint,\n      ),\n      activeProjectName: projectName,\n    })\n  }\n\n  private handleChangeEndpoint = endpoint => {\n    this.setState({ endpoint })\n  }\n\n  private handleChangeSubscriptionsEndpoint = subscriptionEndpoint => {\n    this.setState({ subscriptionEndpoint })\n  }\n\n  private getTitle() {\n    if (\n      this.state.platformToken ||\n      this.state.endpoint.includes('api.graph.cool')\n    ) {\n      const projectId = this.getProjectId(this.state.endpoint)\n      const cluster = this.state.endpoint.includes('api.graph.cool')\n        ? 'shared'\n        : 'local'\n      return `${cluster}/${projectId} - Playground`\n    }\n\n    return `Playground - ${this.state.endpoint}`\n  }\n\n  private async updateSubscriptionsUrl() {\n    const candidates = this.getSubscriptionsUrlCandidated(this.state.endpoint)\n    const validCandidate = await find(candidates, candidate =>\n      this.wsEndpointValid(candidate),\n    )\n    if (validCandidate) {\n      this.setState({ subscriptionEndpoint: validCandidate })\n    }\n  }\n\n  private getSubscriptionsUrlCandidated(endpoint): string[] {\n    const candidates: string[] = []\n    candidates.push(endpoint.replace('https', 'wss').replace('http', 'ws'))\n    if (endpoint.includes('graph.cool')) {\n      candidates.push(\n        `wss://subscriptions.graph.cool/v1/${this.getProjectId(endpoint)}`,\n      )\n    }\n    if (endpoint.includes('/simple/v1/')) {\n      // it's a graphcool local endpoint\n      const host = endpoint.match(/https?:\\/\\/(.*?)\\//)\n      candidates.push(\n        `ws://${host![1]}/subscriptions/v1/${this.getProjectId(endpoint)}`,\n      )\n    }\n    return candidates\n  }\n\n  private wsEndpointValid(url): Promise<boolean> {\n    return new Promise(resolve => {\n      const socket = new WebSocket(url, 'graphql-ws')\n      socket.addEventListener('open', event => {\n        socket.send(JSON.stringify({ type: 'connection_init' }))\n      })\n      socket.addEventListener('message', event => {\n        const data = JSON.parse(event.data)\n        if (data.type === 'connection_ack') {\n          resolve(true)\n        }\n      })\n      socket.addEventListener('error', event => {\n        resolve(false)\n      })\n      setTimeout(() => {\n        resolve(false)\n      }, 1000)\n    })\n  }\n\n  private getProjectId(endpoint) {\n    return endpoint.split('/').slice(-1)[0]\n  }\n}\n\nconst mapStateToProps = (state, ownProps) => {\n  const theme = ownProps.theme || getTheme(state, ownProps.settings)\n  const settings = getSettings(state)\n  return { theme, settings }\n}\n\nexport default connect(\n  mapStateToProps,\n  { injectTabs },\n)(PlaygroundWrapper)\n\nasync function find(\n  iterable: any[],\n  predicate: (item?: any, index?: number) => Promise<boolean>,\n): Promise<any | null> {\n  for (let i = 0; i < iterable.length; i++) {\n    const element = iterable[i]\n    const result = await predicate(element, i)\n    if (result) {\n      return element\n    }\n  }\n  return null\n}\n\nconst appearIn = keyframes`\n  from { \n    opacity: 0;\n    transform: translateY(10px);\n  }\n  to { \n    opacity: 1;\n    transform: translateY(0);\n  }\n`\n\nconst App = styled.div`\n  display: flex;\n  width: 100%;\n  opacity: 0;\n  transform: translateY(10px);\n  animation: ${appearIn} 0.5s ease-out forwards 0.2s;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Popup.tsx",
    "content": "import * as React from 'react'\nimport * as Modal from 'react-modal'\nimport { styled } from '../styled'\n\nexport interface Props {\n  onRequestClose: () => void\n  width?: number\n  closeInside?: boolean\n  darkBg?: boolean\n}\n\nexport const fieldModalStyle = {\n  overlay: {\n    zIndex: 100,\n    backgroundColor: 'rgba(255,255,255,.9)',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  content: {\n    position: 'relative',\n    width: 554,\n    height: 'auto',\n    top: 'initial',\n    left: 'initial',\n    right: 'initial',\n    bottom: 'initial',\n    borderRadius: 2,\n    padding: 0,\n    border: 'none',\n    background: 'none',\n    // boxShadow: '0 1px 7px rgba(0,0,0,.2)',\n    overflow: 'visible',\n  },\n}\n\nexport default class Popup extends React.Component<Props, {}> {\n  render() {\n    const { darkBg } = this.props\n    const modalStyle = {\n      overlay: {\n        ...fieldModalStyle.overlay,\n        background: darkBg ? 'rgba(23,42,58,1.0)' : 'rgba(255,255,255,.9)',\n      },\n      content: {\n        ...fieldModalStyle.content,\n        width: this.props.width || 560,\n      },\n    }\n    return (\n      <Modal\n        isOpen={true}\n        onRequestClose={this.props.onRequestClose}\n        style={modalStyle}\n        ariaHideApp={false}\n        contentLabel=\"Popup\"\n      >\n        <ContentWrapper>{this.props.children}</ContentWrapper>\n      </Modal>\n    )\n  }\n}\n\nconst ContentWrapper = styled.div``\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/ProjectsSideNav.tsx",
    "content": "import * as React from 'react'\nimport { GraphQLConfig, GraphQLConfigEnpointsMapData } from '../graphqlConfig'\nimport ProjectsSideNavItem from './ProjectsSideNavItem'\nimport { SettingsIcon, AddFullIcon } from './Icons'\nimport { styled } from '../styled/index'\nimport { getEndpointFromEndpointConfig } from './util'\nimport { createStructuredSelector } from 'reselect'\nimport { connect } from 'react-redux'\nimport { getSessionCounts } from '../state/workspace/reducers'\nimport { Map } from 'immutable'\nimport { getWorkspaceId } from './Playground/util/getWorkspaceId'\nimport { openConfigTab } from '../state/sessions/actions'\n\nexport interface Props {\n  config: GraphQLConfig\n  folderName: string\n  theme: string\n  activeEnv: string\n  onSelectEnv: (endpoint: string, projectName?: string) => void\n  onNewWorkspace?: () => void\n  showNewWorkspace: boolean\n  isElectron: boolean\n  activeProjectName?: string\n  configPath?: string\n}\n\nexport interface ReduxProps {\n  counts: Map<string, number>\n  openConfigTab: () => void\n}\n\nclass ProjectsSideNav extends React.Component<Props & ReduxProps, {}> {\n  render() {\n    const { config, folderName, onNewWorkspace, isElectron } = this.props\n    const endpoints = config.extensions && config.extensions.endpoints\n    const projects = config.projects\n    return (\n      <SideNav>\n        <List isElectron={isElectron}>\n          <TitleRow>\n            <Title>{folderName}</Title>\n            <SettingsIcon\n              width={18}\n              height={18}\n              onClick={this.props.openConfigTab}\n              title=\"Project settings\"\n            />\n          </TitleRow>\n          {endpoints && this.renderEndpoints(endpoints)}\n          {projects &&\n            Object.keys(projects).map(projectName => {\n              const project = projects[projectName]\n              const projectEndpoints =\n                project.extensions && project.extensions.endpoints\n              if (!projectEndpoints) {\n                return null\n              }\n\n              return (\n                <Project key={projectName}>\n                  <ProjectName>{projectName}</ProjectName>\n                  {this.renderEndpoints(projectEndpoints, projectName)}\n                </Project>\n              )\n            })}\n        </List>\n        {isElectron && (\n          <Footer>\n            <WorkspaceButton onClick={onNewWorkspace}>\n              <AddFullIcon width={14} height={14} strokeWidth={6} />\n              NEW WORKSPACE\n            </WorkspaceButton>\n          </Footer>\n        )}\n      </SideNav>\n    )\n  }\n\n  private renderEndpoints(\n    endpoints: GraphQLConfigEnpointsMapData,\n    projectName?: string,\n  ) {\n    return Object.keys(endpoints).map(env => {\n      const { endpoint } = getEndpointFromEndpointConfig(endpoints[env])\n      const count =\n        this.props.counts.get(\n          getWorkspaceId({\n            endpoint,\n            configPath: this.props.configPath,\n            workspaceName: projectName,\n          }),\n        ) || 1\n      return (\n        <ProjectsSideNavItem\n          key={env}\n          env={env}\n          onSelectEnv={this.props.onSelectEnv}\n          activeEnv={this.props.activeEnv}\n          count={count}\n          deep={Boolean(projectName)}\n          projectName={projectName}\n          activeProjectName={this.props.activeProjectName}\n        />\n      )\n    })\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  counts: getSessionCounts,\n})\n\nexport default connect(\n  mapStateToProps,\n  { openConfigTab },\n)(ProjectsSideNav)\n\nconst SideNav = styled.div`\n  display: flex;\n  flex-direction: column;\n  justify-content: space-between;\n  background: ${p => p.theme.editorColours.sidebar};\n  flex-basis: 222px;\n  color: ${p => p.theme.editorColours.text};\n  border-right: 6px solid ${p => p.theme.editorColours.background};\n`\n\nconst List = styled.div`\n  -webkit-app-region: drag;\n  padding-top: ${(p: any) => (p.isElectron ? 48 : 20)}px;\n  display: flex;\n  flex-direction: column;\n  background: ${p => p.theme.editorColours.sidebarTop};\n`\n\nconst Title = styled.div`\n  font-size: 16px;\n  font-weight: 600;\n  color: ${p => p.theme.editorColours.text};\n  word-break: break-word;\n`\n\nconst TitleRow = styled.div`\n  display: flex;\n  align-items: center;\n  justify-content: space-evenly;\n  margin: 0 15px 20px 15px;\n  svg {\n    -webkit-app-region: no-drag;\n    min-width: 18px;\n    min-height: 18px;\n    cursor: pointer;\n    fill: ${p => p.theme.editorColours.icon};\n    transition: 0.1s linear fill;\n  }\n  &:hover {\n    svg {\n      fill: ${p => p.theme.editorColours.iconHover};\n    }\n  }\n`\n\nconst Project = styled.div`\n  display: flex;\n  flex-direction: column;\n  & + & {\n    margin-top: 12px;\n  }\n  &:last-child {\n    margin-bottom: 32px;\n  }\n`\n\nconst ProjectName = styled.div`\n  font-size: 14px;\n  color: ${p => p.theme.editorColours.text};\n  font-weight: 600;\n  letter-spacing: 0.53px;\n  margin: 0 10px 6px 30px;\n  word-break: break-word;\n`\n\nconst Footer = styled.div`\n  display: flex;\n  justify-content: center;\n  margin: 32px 0;\n  background: ${p => p.theme.editorColours.sidebarBottom};\n`\n\nconst WorkspaceButton = styled.button`\n  padding: 10px;\n  display: flex;\n  align-items: center;\n  border-radius: 2px;\n  cursor: pointer;\n  font-size: 14px;\n  font-weight: 600;\n  letter-spacing: 0.53px;\n  color: ${p => p.theme.editorColours.buttonWorkspaceText};\n  background-color: ${p => p.theme.editorColours.buttonWorkspace};\n  transition: 0.1s linear all;\n  &:hover {\n    background-color: ${p => p.theme.editorColours.buttonWorkspaceHover};\n  }\n  i {\n    margin-right: 6px;\n  }\n  svg {\n    min-width: 18px;\n    min-height: 18px;\n    stroke: ${p => p.theme.editorColours.buttonWorkspaceText};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/ProjectsSideNavItem.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../styled/index'\n\nexport interface Props {\n  env: string\n  onSelectEnv: (env: string, projectName?: string) => void\n  activeEnv: string\n  count: number\n  deep: boolean\n  projectName?: string\n  activeProjectName?: string\n}\n\nexport default class ProjectsSideNavItem extends React.Component<Props, {}> {\n  render() {\n    const {\n      env,\n      activeEnv,\n      count,\n      deep,\n      activeProjectName,\n      projectName,\n    } = this.props\n    const active = activeEnv === env && activeProjectName === projectName\n\n    return (\n      <ListItem active={active} deep={deep} onClick={this.selectEndpoint}>\n        <span>{env}</span>\n        <Count active={active}>{count}</Count>\n      </ListItem>\n    )\n  }\n\n  private selectEndpoint = () => {\n    this.props.onSelectEnv(this.props.env, this.props.projectName)\n  }\n}\n\ninterface SidebarItemProps {\n  active: boolean\n  deep?: boolean\n}\n\nconst ListItem = styled<SidebarItemProps, 'div'>('div')`\n  padding: 10px 10px 10px ${p => (p.deep ? '43px' : '38px')};\n  word-break: break-word;\n  font-weight: 600;\n  cursor: pointer;\n  font-size: 12px;\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  background: ${p =>\n    p.active ? p.theme.editorColours.sidebarItemActive : 'transparent'};\n  border-left: 4px solid\n    ${p => (p.active ? p.theme.editorColours.sidebarItemSide : 'transparent')};\n  border-radius: 2px;\n\n  &:hover {\n    background: ${p => p.theme.editorColours.sidebarItemActive};\n  }\n`\n\nconst Count = styled<SidebarItemProps, 'div'>('div')`\n  border-radius: 6px;\n  min-width: 18px;\n  min-height: 18px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-size: 11px;\n  font-weight: bold;\n  background: ${p => p.theme.editorColours.sidebarItemSessions};\n  color: ${p => p.theme.editorColours.text};\n  opacity: ${p => (p.active ? 1 : 0.6)};\n  transition: 0.1s linear all;\n` as any\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Root.tsx",
    "content": "import * as React from 'react'\nimport { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom'\nimport GraphQLBinApp from './GraphQLBinApp'\n\nexport default class Root extends React.Component<{}, {}> {\n  render() {\n    return (\n      <BrowserRouter>\n        <Switch>\n          <Route path=\"/v2/:id\" component={GraphQLBinApp} />\n          <Redirect\n            exact={true}\n            from=\"/\"\n            to=\"/v2/new\"\n            component={GraphQLBinApp}\n          />\n          <Route path=\"*\" component={RedirectToOldPlayground} />\n        </Switch>\n      </BrowserRouter>\n    )\n  }\n}\n\nconst RedirectToOldPlayground = props => {\n  location.href = `https://legacy.graphqlbin.com${location.pathname}${\n    location.search\n  }`\n  return null\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Settings.tsx",
    "content": "import * as React from 'react'\nimport { SettingsIcon } from './Icons'\nimport { styled } from '../styled'\nimport { openSettingsTab } from '../state/sessions/actions'\nimport { connect } from 'react-redux'\n\nexport interface Props {\n  onClick: () => void\n}\n\nclass Settings extends React.Component<Props, {}> {\n  render() {\n    return (\n      <Wrapper>\n        <IconWrapper>\n          <SettingsIcon\n            width={23}\n            height={23}\n            onClick={this.props.onClick}\n            title=\"Settings\"\n          />\n        </IconWrapper>\n      </Wrapper>\n    )\n  }\n}\n\nexport default connect(\n  null,\n  { onClick: openSettingsTab },\n)(Settings)\n\nconst Wrapper = styled.div`\n  position: absolute;\n  z-index: 1005;\n  right: 20px;\n  top: 17px;\n`\n\nconst IconWrapper = styled.div`\n  position: relative;\n  cursor: pointer;\n\n  svg {\n    fill: ${p => p.theme.editorColours.icon};\n    transition: 0.1s linear fill;\n  }\n\n  &:hover {\n    svg {\n      fill: ${p => p.theme.editorColours.iconHover};\n    }\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/SettingsEditor.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../styled'\nimport { Button } from './Playground/TopBar/TopBar'\nimport { ConfigEditor } from './Playground/ConfigEditor'\nimport { connect } from 'react-redux'\nimport { createStructuredSelector } from 'reselect'\nimport { getConfigString } from '../state/general/selectors'\nimport { setSettingsString, setConfigString } from '../state/general/actions'\nimport { editSettings, saveSettings } from '../state/sessions/actions'\nimport { getSettingsString } from '../state/workspace/reducers'\nimport EditorWrapper, { Container } from './Playground/EditorWrapper'\n\nexport interface Props {\n  value: string\n  onChange: (value: string) => void\n  onSave: () => void\n  isYaml?: boolean\n  isConfig?: boolean\n  readOnly?: boolean\n}\n\n// TODO: Trigger onSave on CMD+S or CTRL+S\n\nexport class SettingsEditor extends React.Component<Props, {}> {\n  componentDidMount() {\n    window.addEventListener('keydown', this.handleKeydown, true)\n  }\n\n  render() {\n    const { isConfig } = this.props\n    return (\n      <Container>\n        <Wrapper>\n          <EditorWrapper>\n            <ConfigEditor\n              value={this.props.value}\n              onEdit={this.props.onChange}\n              onRunQuery={this.props.onSave}\n              isYaml={this.props.isYaml}\n              readOnly={this.props.readOnly}\n            />\n            <PlaygroundVersion>{window.version}</PlaygroundVersion>\n          </EditorWrapper>\n          {!this.props.readOnly && (\n            <ButtonWrapper>\n              <Button onClick={this.props.onSave}>\n                Save {isConfig ? `Config` : `Settings`}\n              </Button>\n            </ButtonWrapper>\n          )}\n        </Wrapper>\n      </Container>\n    )\n  }\n\n  private handleKeydown = (e: KeyboardEvent) => {\n    if (e.key === 's' && e.metaKey) {\n      e.preventDefault()\n      this.props.onSave()\n    }\n  }\n}\nconst playgroundSettingsSelector = createStructuredSelector({\n  value: getSettingsString,\n})\n\ninterface HOCProps {\n  editSettings: () => void\n  saveSettings: () => void\n  onSave: (value: string) => void\n}\n\n// tslint:disable\nclass SettingsEditorHOC extends React.Component<\n  Props & HOCProps,\n  { value: string }\n> {\n  constructor(props) {\n    super(props)\n    this.state = { value: props.value }\n  }\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    if (nextProps.value !== this.props.value) {\n      this.setState({ value: nextProps.value })\n    }\n  }\n  render() {\n    return (\n      <SettingsEditor\n        value={this.state.value}\n        onChange={this.handleChange}\n        onSave={this.handleSave}\n      />\n    )\n  }\n  handleChange = value => {\n    this.setState({ value })\n    this.props.editSettings()\n  }\n  handleSave = () => {\n    this.props.onChange(this.state.value)\n    this.props.saveSettings()\n  }\n}\n\nexport const PlaygroundSettingsEditor = connect(\n  playgroundSettingsSelector,\n  {\n    onChange: setSettingsString,\n    editSettings,\n    saveSettings,\n  },\n)(SettingsEditorHOC)\n\nconst configSelector = createStructuredSelector({\n  value: getConfigString,\n})\n\nexport const GraphQLConfigEditor = connect(\n  configSelector,\n  {\n    onChange: setConfigString,\n  },\n)(SettingsEditor)\n\nconst Wrapper = styled.div`\n  background: ${p => p.theme.editorColours.resultBackground};\n  position: relative;\n  display: flex;\n  flex-flow: column;\n  flex: 1 1 0;\n\n  .CodeMirror {\n    background: ${p => p.theme.editorColours.resultBackground};\n    .CodeMirror-code {\n      color: rgba(255, 255, 255, 0.7);\n    }\n    .cm-atom {\n      color: rgba(42, 126, 210, 1);\n    }\n  }\n`\n\nconst ButtonWrapper = styled.div`\n  position: absolute;\n  top: 16px;\n  right: 16px;\n  z-index: 2;\n`\n\nconst PlaygroundVersion = styled.span`\n  position: absolute;\n  right: 20px;\n  bottom: 17px;\n  color: ${p => p.theme.editorColours.textInactive};\n  font-weight: 700;\n  margin-right: 14px;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Share.tsx",
    "content": "import * as React from 'react'\nimport { ShareIcon } from './Icons'\nimport ToggleButton from './ToggleButton'\nimport Tooltip from './Tooltip'\nimport { Button } from './Button'\nimport Copy from './Copy'\nimport { keyframes, styled, ThemeInterface, withTheme } from '../styled'\nimport { connect } from 'react-redux'\nimport { createStructuredSelector } from 'reselect'\nimport {\n  getSharingHistory,\n  getSharingHeaders,\n  getSharingAllTabs,\n  getShareUrl,\n} from '../state/sharing/selectors'\nimport {\n  toggleShareHistory,\n  toggleShareHeaders,\n  toggleShareAllTabs,\n  share,\n} from '../state/sharing/actions'\n\nexport interface SharingProps {\n  allTabs: boolean\n  headers: boolean\n  history: boolean\n  theme: ThemeInterface\n\n  toggleShareHistory: () => void\n  toggleShareHeaders: () => void\n  toggleShareAllTabs: () => void\n  share: () => void\n\n  shareUrl?: string\n  reshare: boolean\n  isSharingAuthorization: boolean\n  children?: any\n}\n\nexport interface State {\n  open: boolean\n}\n\nclass Share extends React.Component<SharingProps, State> {\n  constructor(props) {\n    super(props)\n    this.state = {\n      open: false,\n    }\n  }\n  render() {\n    const { open } = this.state\n    const { allTabs, headers, history, shareUrl, reshare, theme } = this.props\n    return (\n      <Wrapper>\n        <IconWrapper>\n          <div onClick={this.toggleTooltip}>{this.props.children}</div>\n          {open && (\n            <TooltipWrapper>\n              <Tooltip\n                open={open}\n                onClose={this.toggleTooltip}\n                anchorOrigin={{\n                  horizontal: 'right',\n                  vertical: 'bottom',\n                }}\n                renderAfterContent={this.renderAuthSharingWarning}\n              >\n                <div>\n                  <Row>\n                    <TooltipText onClick={this.props.toggleShareAllTabs}>\n                      Share all tabs{' '}\n                    </TooltipText>\n                    <ToggleButton\n                      checked={allTabs}\n                      onChange={this.props.toggleShareAllTabs}\n                    />\n                  </Row>\n                  <Row>\n                    <TooltipText onClick={this.props.toggleShareHeaders}>\n                      HTTP headers{' '}\n                    </TooltipText>\n                    <ToggleButton\n                      checked={headers}\n                      onChange={this.props.toggleShareHeaders}\n                    />\n                  </Row>\n                  <Row>\n                    <TooltipText onClick={this.props.toggleShareHistory}>\n                      History{' '}\n                    </TooltipText>\n                    <ToggleButton\n                      checked={history}\n                      onChange={this.props.toggleShareHistory}\n                    />\n                  </Row>\n                  {shareUrl && (\n                    <Row>\n                      <Input value={shareUrl} disabled={true} />\n                      <CopyWrapper>\n                        <Copy text={shareUrl}>\n                          <ShareIcon\n                            color={theme.colours.darkBlue30}\n                            width={25}\n                            height={25}\n                            title=\"Copy URL to Clipboard\"\n                          />\n                        </Copy>\n                      </CopyWrapper>\n                    </Row>\n                  )}\n                  <Row>\n                    <div />\n                    <Button hideArrow={true} onClick={this.share}>\n                      {reshare && shareUrl ? 'Reshare' : 'Share'}\n                    </Button>\n                  </Row>\n                </div>\n              </Tooltip>\n            </TooltipWrapper>\n          )}\n        </IconWrapper>\n      </Wrapper>\n    )\n  }\n\n  private share = () => {\n    this.props.share()\n  }\n\n  private renderAuthSharingWarning = () => {\n    if (!this.props.isSharingAuthorization) {\n      return null\n    }\n\n    return <AuthSharingWarning />\n  }\n\n  private toggleTooltip = () => {\n    this.setState(state => ({ open: !state.open }))\n  }\n}\n\nconst mapStateToProps = createStructuredSelector({\n  history: getSharingHistory,\n  headers: getSharingHeaders,\n  allTabs: getSharingAllTabs,\n  shareUrl: getShareUrl,\n})\n\nexport default withTheme(\n  connect(\n    mapStateToProps,\n    {\n      toggleShareAllTabs,\n      toggleShareHeaders,\n      toggleShareHistory,\n      share,\n    },\n  )(Share),\n)\n\nconst AuthSharingWarning = () => (\n  <Message>\n    <MessageTitle>Watch out!</MessageTitle>\n    You’re sharing your <code>Authorization</code> header with the world!\n  </Message>\n)\n\n// TODO: use theme\n\nconst pulse = keyframes`\n  0% {\n    transform: scale(1.04);\n  }\n\n  100% {\n    transform: scale(1);\n  }\n`\n\nconst Message = styled.div`\n  padding: 12px 16px;\n  margin-top: 10px;\n\n  font-size: 14px;\n  letter-spacing: normal;\n\n  cursor: default;\n  border-radius: 2px;\n  background: #f3f4f4;\n  box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.15);\n\n  animation: ${pulse} 0.7s ease-in-out infinite alternate;\n`\n\nconst MessageTitle = styled.div`\n  margin-right: 3px;\n  margin-bottom: 2px;\n  font-weight: bold;\n  color: #2a7ed2;\n`\n\n// Main styled components\nconst Wrapper = styled.div`\n  z-index: 1005;\n  height: 100%;\n  margin-left: 6px;\n`\n\nconst TooltipText = styled.div`\n  margin-right: 10px;\n\n  font-size: ${p => p.theme.sizes.fontSmall};\n  font-weight: ${p => p.theme.sizes.fontSemiBold};\n  text-transform: uppercase;\n  letter-spacing: 0.53px;\n\n  color: ${p => p.theme.colours.darkBlue50};\n`\n\nconst IconWrapper = styled.div`\n  position: relative;\n  cursor: pointer;\n`\n\nconst TooltipWrapper = styled.div`\n  position: absolute;\n  right: 0px;\n`\n\nconst Row = styled.div`\n  position: relative;\n  min-width: 245px;\n  margin-top: ${p => p.theme.sizes.small16};\n\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n\n  &:first-child {\n    margin-top: 0;\n  }\n`\n\nconst CopyWrapper = styled.div`\n  position: absolute;\n  right: 0;\n\n  &:hover {\n    svg {\n      fill: ${p => p.theme.colours.darkBlue60};\n    }\n  }\n`\n\nconst Input = styled.input`\n  display: block;\n  width: 100%;\n  padding: ${p => p.theme.sizes.small6} ${p => p.theme.sizes.small10};\n  padding-right: 25px;\n\n  font-weight: ${p => p.theme.sizes.fontSemiBold};\n  font-size: ${p => p.theme.sizes.fontTiny};\n\n  border-radius: ${p => p.theme.sizes.smallRadius};\n  background: ${p => p.theme.colours.darkBlue10};\n  color: ${p => p.theme.colours.darkBlue};\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Spinner.tsx",
    "content": "import * as React from 'react'\nimport { keyframes, styled } from '../styled'\n\nconst Spinner = () => (\n  <Wrapper>\n    <SpinnerNode />\n  </Wrapper>\n)\n\nconst rotation = keyframes`\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(359deg);\n  }\n`\n\nconst Wrapper = styled.div`\n  height: 36px;\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  width: 36px;\n  z-index: 10;\n`\n\nconst SpinnerNode = styled.div`\n  position: absolute;\n  display: inline-block;\n  height: 24px;\n  width: 24px;\n  vertical-align: middle;\n\n  animation: ${rotation} 0.6s infinite linear;\n\n  border-radius: 100%;\n  border-bottom: 6px solid rgba(150, 150, 150, 0.15);\n  border-left: 6px solid rgba(150, 150, 150, 0.15);\n  border-right: 6px solid rgba(150, 150, 150, 0.15);\n  border-top: 6px solid rgba(150, 150, 150, 0.8);\n`\n\nexport default Spinner\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Toggle.tsx",
    "content": "import * as React from 'react'\nimport { css, styled } from '../styled'\n\nexport interface ToggleProps {\n  choices: string[]\n  onChange: (choice: string, i: number) => void\n  activeChoice: string\n}\n\nconst Toggle: React.SFC<ToggleProps> = ({\n  choices,\n  onChange,\n  activeChoice,\n}) => (\n  <Wrapper>\n    {choices.map((choice, i) => (\n      <Choice\n        active={choice === activeChoice}\n        key={choice}\n        // tslint:disable-next-line\n        onClick={() => onChange(choice, i)}\n      >\n        {choice}\n      </Choice>\n    ))}\n  </Wrapper>\n)\n\nconst Wrapper = styled.div`\n  display: flex;\n`\n\ninterface ChoiceProps {\n  active: boolean\n}\n\n// prettier-ignore\nconst Choice = styled.div`\n  padding: 4px 8px;\n  margin-right: ${p => p.theme.sizes.small6};\n\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.2px;\n\n  cursor: pointer;\n  border-radius: ${p => p.theme.sizes.smallRadius};\n  color: ${p => p.theme.colours.black40};\n\n  ${(p: ChoiceProps) => p.active ? css`\n    color: rgba(0, 0, 0, 0.7);\n    background: #b8bfc4;\n  ` : css`\n    /* hover state when it's not active */\n    &:hover {\n      color: rgba(0, 0, 0, 0.7);\n    }\n  `}\n`\n\nexport default Toggle\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/ToggleButton.tsx",
    "content": "import * as React from 'react'\nimport { styled } from '../styled'\n\nexport interface Props {\n  checked: boolean\n  onChange: (e: any) => void\n  className?: string\n}\n\nconst ToggleButton = ({ checked, onChange, className }: Props) => {\n  return (\n    <Wrapper className={className} onClick={onChange}>\n      <Input type=\"checkbox\" checked={checked} readOnly={true} />\n      <Slider checked={checked} />\n    </Wrapper>\n  )\n}\n\nexport default ToggleButton\n\nconst Wrapper = styled.div`\n  position: relative;\n  display: inline-block;\n\n  width: 39px;\n  height: 21px;\n`\n\nconst Input = styled.input`\n  display: none;\n`\n\ninterface SliderProps {\n  checked: boolean\n}\n\nconst Slider = styled<SliderProps, 'div'>('div')`\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n\n  transition: transform 70ms linear;\n  border-radius: 23px;\n  cursor: pointer;\n\n  background: ${p =>\n    p.checked ? p.theme.colours.green : p.theme.colours.black40};\n\n  &:before {\n    position: absolute;\n    content: '';\n    height: 23px;\n    width: 23px;\n    left: -1px;\n    bottom: -1px;\n    background-color: white;\n    border-radius: 50%;\n    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);\n    transition: transform 70ms linear;\n\n    transform: ${p => (p.checked ? 'translateX(19px)' : '')};\n  }\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Tooltip.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport { css, styled } from '../styled'\n\nexport interface Props {\n  open: boolean\n  children: any\n  anchorOrigin?: {\n    vertical?: 'bottom' | 'top'\n    horizontal?: 'left' | 'right' | 'center'\n  }\n  renderAfterContent?: () => any\n  onClick?: () => void\n  onClose?: (e?: any) => void\n}\n\nclass Tooltip extends React.PureComponent<Props, {}> {\n  static defaultProps: Partial<Props> = {\n    anchorOrigin: {\n      vertical: 'top',\n      horizontal: 'center',\n    },\n  }\n\n  componentDidMount() {\n    document.addEventListener('click', this.handleClickOutside, true)\n  }\n\n  componentWillUnmount() {\n    document.removeEventListener(\n      'click',\n      this.handleClickOutside.bind(this),\n      true,\n    )\n  }\n\n  handleClickOutside = event => {\n    if (!this.props.open) {\n      return\n    }\n\n    try {\n      const domNode = ReactDOM.findDOMNode(this as any)\n\n      if (\n        (!domNode || !domNode.contains(event.target)) &&\n        typeof this.props.onClose !== 'undefined'\n      ) {\n        this.props.onClose(event)\n      }\n    } catch (e) {\n      //\n    }\n  }\n\n  render() {\n    const { open, children, renderAfterContent, onClick } = this.props\n    const anchorOrigin = this.props.anchorOrigin!\n    return (\n      <Wrapper\n        visible={open}\n        anchorTop={anchorOrigin.vertical === 'top'}\n        anchorBottom={anchorOrigin.vertical === 'bottom'}\n        anchorLeft={anchorOrigin.horizontal === 'left'}\n        anchorRight={anchorOrigin.horizontal === 'right'}\n        anchorCenter={anchorOrigin.horizontal === 'center'}\n      >\n        <Content onClick={onClick}>\n          <BigTriangle />\n          {children}\n        </Content>\n\n        {renderAfterContent && renderAfterContent()}\n      </Wrapper>\n    )\n  }\n}\n\nexport default Tooltip\n\ninterface WrapperProps {\n  visible?: boolean\n  anchorTop?: boolean\n  anchorBottom?: boolean\n  anchorLeft?: boolean\n  anchorRight?: boolean\n  anchorCenter?: boolean\n}\n\nconst Wrapper = styled.div`\n  position: absolute;\n  z-index: 9999;\n\n  text-align: left;\n  transform: translateX(-50%);\n\n  transition: opacity ease-out 0.2s;\n\n  ${(p: WrapperProps) =>\n    p.visible\n      ? css`\n          visibility: visible;\n          opacity: 1;\n        `\n      : css`\n          visibility: hidden;\n          opacity: 0;\n        `} ${(p: WrapperProps) =>\n  p.anchorTop\n    ? css`\n        bottom: 100%;\n        margin-bottom: 16px;\n\n        ${BigTriangle} {\n          bottom: -10px;\n        }\n      `\n    : ''} ${(p: WrapperProps) =>\n  p.anchorBottom\n    ? css`\n        top: 100%;\n        margin-top: 16px;\n\n        ${BigTriangle} {\n          top: -10px;\n          border-width: 0 10px 10px 10px;\n          border-color: ${k => k.theme.colours.paleGrey} transparent\n            ${k => k.theme.colours.paleGrey} transparent;\n        }\n      `\n    : ''} ${(p: WrapperProps) =>\n  p.anchorLeft\n    ? css`\n        left: 0;\n        transform: none;\n\n        ${BigTriangle} {\n          left: 25px;\n        }\n      `\n    : ''} ${(p: WrapperProps) =>\n  p.anchorRight\n    ? css`\n        right: 0;\n        transform: none;\n\n        ${BigTriangle} {\n          right: 25px;\n        }\n      `\n    : ''} ${(p: WrapperProps) =>\n  p.anchorCenter\n    ? css`\n        left: 50%;\n\n        ${BigTriangle} {\n          left: calc(50% - 10px);\n        }\n      `\n    : ''};\n`\n\nconst Content = styled.div`\n  display: flex;\n  align-items: center;\n\n  padding: ${p => p.theme.sizes.small12} ${p => p.theme.sizes.small16};\n  white-space: nowrap;\n\n  box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.15);\n  background-color: ${p => p.theme.colours.paleGrey};\n  border-radius: ${p => p.theme.sizes.smallRadius};\n  color: ${p => p.theme.colours.paleText};\n`\n\nconst BigTriangle = styled.div`\n  position: absolute;\n  width: 0;\n  height: 0;\n\n  border-style: solid;\n  border-width: 10px 10px 0 10px;\n  border-color: ${p => p.theme.colours.paleGrey} transparent transparent\n    transparent;\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/asyncComponent.tsx",
    "content": "import * as React from 'react'\nimport Spinner from './Spinner'\n\nexport interface State {\n  component?: any\n}\n\nconst asyncComponent = importComponent => {\n  return class extends React.Component<any, State> {\n    state: State = {\n      component: null,\n    }\n    componentDidMount() {\n      importComponent().then(cmp => {\n        this.setState({ component: cmp.default })\n      })\n    }\n\n    render() {\n      const C = this.state.component as any\n      return C ? <C {...this.props} /> : <Spinner />\n    }\n  }\n}\n\nexport default asyncComponent\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/resolveRefStrings.ts",
    "content": "export function resolveRefString(str: string, values?: object): string {\n  const { strings, rawRefs } = parse(str)\n  const refValues = rawRefs.map(ref => resolveRef(ref, values))\n\n  let res = ''\n  for (let i = 0; i < refValues.length; i++) {\n    res += strings[i]\n    res += refValues[i]\n  }\n  res += strings.pop()\n  return res\n}\n\nexport function resolveEnvsInValues<T extends any>(\n  inputConfig: T,\n  env: { [name: string]: string | undefined },\n): T {\n  const config = { ...(inputConfig as any) }\n  Object.keys(config).forEach(key => {\n    const value = config[key]\n    if (typeof value === 'string') {\n      config[key] = resolveRefString(value, { env })\n    } else if (typeof value === 'object') {\n      config[key] = resolveEnvsInValues(value, env)\n    }\n  })\n  return config\n}\n\nexport function getUsedEnvs(config: any): { [name: string]: string } {\n  const result = {}\n\n  const traverse = val => {\n    if (typeof val === 'string') {\n      const rawRefs = parse(val).rawRefs\n      for (const ref of rawRefs) {\n        result[parseRef(ref).ref] = resolveRef(ref, {}, false)\n      }\n    } else if (typeof val === 'object') {\n      Object.keys(config).forEach(key => {\n        traverse(config[key])\n      })\n    }\n  }\n  traverse(config)\n  return result\n}\n\nfunction parseRef(rawRef: string): { type: string; ref: string } {\n  const [type, ref] = rawRef.split(/\\s*:\\s*/)\n  return { type, ref }\n}\n\nfunction resolveRef(\n  rawRef: string,\n  values: any = {},\n  throwIfUndef: boolean = true,\n): string | null {\n  const { type, ref } = parseRef(rawRef)\n\n  if (type === 'env') {\n    if (!ref) {\n      throw new Error(`Reference value is not present for ${type}: ${rawRef}`)\n    }\n\n    const refValue = (values.env && values.env[ref]) || process.env[ref]\n    if (!refValue) {\n      if (throwIfUndef) {\n        throw new Error(`Environment variable ${ref} is not set`)\n      } else {\n        return null\n      }\n    }\n    return refValue\n  } else {\n    // support only 'env' for now\n    throw new Error(\n      'Undefined reference type \\\\$\\\\{refType}. Only \"env\" is supported',\n    )\n  }\n}\n\nfunction parse(str: string): { strings: string[]; rawRefs: string[] } {\n  const regex = /\\${([^}]*)}/g\n  const strings: string[] = []\n  const rawRefs: string[] = []\n\n  let prevIdx = 0\n  let match\n  // tslint:disable-next-line:no-conditional-assignment\n  while ((match = regex.exec(str)) !== null) {\n    if (match.index > 0 && str[match.index - 1] === '\\\\') {\n      continue\n    }\n\n    strings.push(str.substring(prevIdx, match.index))\n    rawRefs.push(match[1])\n    prevIdx = match.index + match[0].length\n  }\n  strings.push(str.substring(prevIdx))\n  return { strings, rawRefs }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/util.ts",
    "content": "import { GraphQLConfig, GraphQLConfigEnpointConfig } from '../graphqlConfig'\nimport { GraphQLSchema, printSchema } from 'graphql'\nimport * as LRU from 'lru-cache'\n\nexport function getActiveEndpoints(\n  config: GraphQLConfig,\n  envName: string,\n  projectName?: string,\n): { endpoint: string; subscriptionEndpoint?: string; headers?: any } {\n  if (projectName) {\n    const env = config.projects![projectName].extensions!.endpoints![envName]!\n    return getEndpointFromEndpointConfig(env)\n  } else {\n    const env = config.extensions!.endpoints![envName]!\n    return getEndpointFromEndpointConfig(env)\n  }\n}\n\nexport function getEndpointFromEndpointConfig(\n  env: GraphQLConfigEnpointConfig | string,\n) {\n  if (typeof env === 'string') {\n    return {\n      endpoint: env,\n      subscriptionEndpoint: undefined,\n    }\n  } else {\n    return {\n      endpoint: env.url,\n      subscriptionEndpoint: env.subscription\n        ? env.subscription!.url\n        : undefined,\n      headers: env.headers,\n    }\n  }\n}\n\nconst printSchemaCache: LRU.Cache<GraphQLSchema, string> = new LRU({ max: 10 })\n/**\n * A cached version of `printSchema`\n * @param schema GraphQLSchema instance\n */\nexport function cachedPrintSchema(schema: GraphQLSchema) {\n  const cachedString = printSchemaCache.get(schema)\n  if (cachedString) {\n    return cachedString\n  }\n\n  const schemaString = printSchema(schema)\n  printSchemaCache.set(schema, schemaString)\n\n  return schemaString\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/constants.ts",
    "content": "import * as cuid from 'cuid'\nimport { getIntrospectionQuery } from 'graphql'\nimport { getQueryTypes } from './components/Playground/util/getQueryTypes'\nimport { List, Map } from 'immutable'\n\nexport const columnWidth = 300\n\nexport const introspectionQuery = getIntrospectionQuery()\n\nexport const defaultQuery = '# Write your query or mutation here\\n'\n\nexport const modalStyle = {\n  overlay: {\n    zIndex: 99999,\n    backgroundColor: 'rgba(15,32,46,.9)',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n  },\n  content: {\n    position: 'relative',\n    width: 976,\n    height: 'auto',\n    top: 'initial',\n    left: 'initial',\n    right: 'initial',\n    bottom: 'initial',\n    borderRadius: 2,\n    padding: 0,\n    border: 'none',\n    background: 'none',\n    boxShadow: '0 1px 7px rgba(0,0,0,.2)',\n  },\n}\n\nexport function getDefaultSession(endpoint: string) {\n  return {\n    id: cuid(),\n    query: defaultQuery,\n    variables: '',\n    responses: List([]),\n    endpoint,\n    operationName: undefined,\n    hasMutation: false,\n    hasSubscription: false,\n    hasQuery: false,\n    queryTypes: getQueryTypes(defaultQuery),\n    subscriptionActive: false,\n    date: new Date(),\n    starred: false,\n    queryRunning: false,\n    operations: List([]),\n    isReloadingSchema: false,\n    isSchemaPendingUpdate: false,\n    responseExtensions: {},\n    queryVariablesActive: false,\n    endpointUnreachable: false,\n    editorFlex: 1,\n    variableEditorOpen: false,\n    variableEditorHeight: 200,\n    responseTracingOpen: false,\n    responseTracingHeight: 300,\n    docExplorerWidth: 350,\n    variableToType: Map({}),\n    headers: '',\n    file: undefined,\n    isFile: false,\n    name: undefined,\n    filePath: undefined,\n    selectedUserToken: undefined,\n    hasChanged: undefined,\n    absolutePath: undefined,\n    isSettingsTab: undefined,\n    isConfigTab: undefined,\n    currentQueryStartTime: undefined,\n    currentQueryEndTime: undefined,\n    nextQueryStartTime: undefined,\n    tracingSupported: undefined,\n    changed: undefined,\n    scrollTop: undefined,\n  } as any\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/fixtures/exampleSchema.ts",
    "content": "export const exampleSchema = {\n  __schema: {\n    directives: [\n      {\n        name: 'include',\n        description:\n          'Directs the executor to include this field or fragment only when the `if` argument is true.',\n        locations: ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'],\n        args: [\n          {\n            name: 'if',\n            description: 'Included when true.',\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n            defaultValue: null,\n          },\n        ],\n      },\n      {\n        name: 'skip',\n        description:\n          'Directs the executor to skip this field or fragment when the `if` argument is true.',\n        locations: ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'],\n        args: [\n          {\n            name: 'if',\n            description: 'Included when true.',\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n            defaultValue: null,\n          },\n        ],\n      },\n      {\n        name: 'deprecated',\n        description:\n          'Marks an element of a GraphQL schema as no longer supported.',\n        locations: ['ENUM_VALUE', 'FIELD_DEFINITION'],\n        args: [\n          {\n            name: 'reason',\n            description:\n              'Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in [Markdown](https://daringfireball.net/projects/markdown/).',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: '\"No longer supported\"',\n          },\n        ],\n      },\n    ],\n    mutationType: { name: 'Mutation' },\n    subscriptionType: { name: 'Subscription' },\n    queryType: { name: 'Query' },\n    types: [\n      {\n        inputFields: null,\n        name: 'BatchPayload',\n        description: '',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'count',\n            description:\n              'The number of nodes that have been affected by the Batch operation.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Long', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Mutation',\n        description: null,\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'createUser',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'data',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserCreateInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'User', ofType: null },\n            },\n          },\n          {\n            name: 'updateUser',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'data',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserUpdateInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n              {\n                name: 'where',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserWhereUniqueInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n            ],\n            type: { kind: 'OBJECT', name: 'User', ofType: null },\n          },\n          {\n            name: 'deleteUser',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserWhereUniqueInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n            ],\n            type: { kind: 'OBJECT', name: 'User', ofType: null },\n          },\n          {\n            name: 'upsertUser',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserWhereUniqueInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n              {\n                name: 'create',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserCreateInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n              {\n                name: 'update',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserUpdateInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'User', ofType: null },\n            },\n          },\n          {\n            name: 'updateManyUsers',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'data',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserUpdateInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n              {\n                name: 'where',\n                description: '',\n                type: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'BatchPayload', ofType: null },\n            },\n          },\n          {\n            name: 'deleteManyUsers',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: '',\n                type: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'BatchPayload', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'MutationType',\n        description: null,\n        interfaces: null,\n        enumValues: [\n          {\n            name: 'CREATED',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'UPDATED',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'DELETED',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n        ],\n        fields: null,\n        kind: 'ENUM',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Subscription',\n        description: null,\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'user',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: '',\n                type: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserSubscriptionWhereInput',\n                  ofType: null,\n                },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'OBJECT',\n              name: 'UserSubscriptionPayload',\n              ofType: null,\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: [\n          {\n            name: 'name',\n            description: null,\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'email',\n            description: null,\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n            defaultValue: null,\n          },\n        ],\n        name: 'UserCreateInput',\n        description: null,\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'INPUT_OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'UserPreviousValues',\n        description: null,\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'id',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'ID', ofType: null },\n            },\n          },\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n          {\n            name: 'email',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'UserSubscriptionPayload',\n        description: null,\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'mutation',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'ENUM', name: 'MutationType', ofType: null },\n            },\n          },\n          {\n            name: 'node',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'OBJECT', name: 'User', ofType: null },\n          },\n          {\n            name: 'updatedFields',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'previousValues',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'OBJECT', name: 'UserPreviousValues', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: [\n          {\n            name: 'AND',\n            description: 'Logical AND on all given filters.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserSubscriptionWhereInput',\n                  ofType: null,\n                },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'OR',\n            description: 'Logical OR on all given filters.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserSubscriptionWhereInput',\n                  ofType: null,\n                },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'NOT',\n            description: 'Logical NOT on all given filters combined by AND.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserSubscriptionWhereInput',\n                  ofType: null,\n                },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'mutation_in',\n            description:\n              \"The subscription event gets dispatched when it's listed in mutation_in\",\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'ENUM', name: 'MutationType', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'updatedFields_contains',\n            description:\n              'The subscription event gets only dispatched when one of the updated fields names is included in this list',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'updatedFields_contains_every',\n            description:\n              'The subscription event gets only dispatched when all of the field names included in this list have been updated',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'updatedFields_contains_some',\n            description:\n              'The subscription event gets only dispatched when some of the field names included in this list have been updated',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'node',\n            description: null,\n            type: {\n              kind: 'INPUT_OBJECT',\n              name: 'UserWhereInput',\n              ofType: null,\n            },\n            defaultValue: null,\n          },\n        ],\n        name: 'UserSubscriptionWhereInput',\n        description: null,\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'INPUT_OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: [\n          {\n            name: 'name',\n            description: null,\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email',\n            description: null,\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n        ],\n        name: 'UserUpdateInput',\n        description: null,\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'INPUT_OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'AggregateUser',\n        description: null,\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'count',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Int', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Node',\n        description: 'An object with an ID',\n        interfaces: null,\n        enumValues: null,\n        fields: [\n          {\n            name: 'id',\n            description: 'The id of the object.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'ID', ofType: null },\n            },\n          },\n        ],\n        kind: 'INTERFACE',\n        possibleTypes: [{ kind: 'OBJECT', name: 'User', ofType: null }],\n      },\n      {\n        inputFields: null,\n        name: 'PageInfo',\n        description: 'Information about pagination in a connection.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'hasNextPage',\n            description: 'When paginating forwards, are there more items?',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n          {\n            name: 'hasPreviousPage',\n            description: 'When paginating backwards, are there more items?',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n          {\n            name: 'startCursor',\n            description: 'When paginating backwards, the cursor to continue.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'endCursor',\n            description: 'When paginating forwards, the cursor to continue.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Query',\n        description: null,\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'users',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: '',\n                type: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n                defaultValue: null,\n              },\n              {\n                name: 'orderBy',\n                description: null,\n                type: { kind: 'ENUM', name: 'UserOrderByInput', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'skip',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Int', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'after',\n                description: null,\n                type: { kind: 'SCALAR', name: 'String', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'before',\n                description: null,\n                type: { kind: 'SCALAR', name: 'String', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'first',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Int', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'last',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Int', ofType: null },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: { kind: 'OBJECT', name: 'User', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'user',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: null,\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'INPUT_OBJECT',\n                    name: 'UserWhereUniqueInput',\n                    ofType: null,\n                  },\n                },\n                defaultValue: null,\n              },\n            ],\n            type: { kind: 'OBJECT', name: 'User', ofType: null },\n          },\n          {\n            name: 'usersConnection',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'where',\n                description: '',\n                type: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n                defaultValue: null,\n              },\n              {\n                name: 'orderBy',\n                description: null,\n                type: { kind: 'ENUM', name: 'UserOrderByInput', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'skip',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Int', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'after',\n                description: null,\n                type: { kind: 'SCALAR', name: 'String', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'before',\n                description: null,\n                type: { kind: 'SCALAR', name: 'String', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'first',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Int', ofType: null },\n                defaultValue: null,\n              },\n              {\n                name: 'last',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Int', ofType: null },\n                defaultValue: null,\n              },\n            ],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'UserConnection', ofType: null },\n            },\n          },\n          {\n            name: 'node',\n            description: 'Fetches an object given its ID',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'id',\n                description: 'The ID of an object',\n                type: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: { kind: 'SCALAR', name: 'ID', ofType: null },\n                },\n                defaultValue: null,\n              },\n            ],\n            type: { kind: 'INTERFACE', name: 'Node', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'User',\n        description: null,\n        interfaces: [{ kind: 'INTERFACE', name: 'Node', ofType: null }],\n        enumValues: null,\n        fields: [\n          {\n            name: 'id',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'ID', ofType: null },\n            },\n          },\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n          {\n            name: 'email',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'UserConnection',\n        description: 'A connection to a list of items.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'pageInfo',\n            description: 'Information to aid in pagination.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'PageInfo', ofType: null },\n            },\n          },\n          {\n            name: 'edges',\n            description: 'A list of edges.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: { kind: 'OBJECT', name: 'UserEdge', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'aggregate',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'AggregateUser', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'UserEdge',\n        description: 'An edge in a connection.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'node',\n            description: 'The item at the end of the edge.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: 'User', ofType: null },\n            },\n          },\n          {\n            name: 'cursor',\n            description: 'A cursor for use in pagination.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'UserOrderByInput',\n        description: null,\n        interfaces: null,\n        enumValues: [\n          {\n            name: 'id_ASC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'id_DESC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'name_ASC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'name_DESC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'email_ASC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'email_DESC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'updatedAt_ASC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'updatedAt_DESC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'createdAt_ASC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'createdAt_DESC',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n        ],\n        fields: null,\n        kind: 'ENUM',\n        possibleTypes: null,\n      },\n      {\n        inputFields: [\n          {\n            name: 'AND',\n            description: 'Logical AND on all given filters.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'OR',\n            description: 'Logical OR on all given filters.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'NOT',\n            description: 'Logical NOT on all given filters combined by AND.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: {\n                  kind: 'INPUT_OBJECT',\n                  name: 'UserWhereInput',\n                  ofType: null,\n                },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'id',\n            description: '',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_not',\n            description: 'All values that are not equal to given value.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_in',\n            description: 'All values that are contained in given list.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'ID', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'id_not_in',\n            description: 'All values that are not contained in given list.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'ID', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'id_lt',\n            description: 'All values less than the given value.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_lte',\n            description: 'All values less than or equal the given value.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_gt',\n            description: 'All values greater than the given value.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_gte',\n            description: 'All values greater than or equal the given value.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_contains',\n            description: 'All values containing the given string.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_not_contains',\n            description: 'All values not containing the given string.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_starts_with',\n            description: 'All values starting with the given string.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_not_starts_with',\n            description: 'All values not starting with the given string.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_ends_with',\n            description: 'All values ending with the given string.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'id_not_ends_with',\n            description: 'All values not ending with the given string.',\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name',\n            description: '',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_not',\n            description: 'All values that are not equal to given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_in',\n            description: 'All values that are contained in given list.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'name_not_in',\n            description: 'All values that are not contained in given list.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'name_lt',\n            description: 'All values less than the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_lte',\n            description: 'All values less than or equal the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_gt',\n            description: 'All values greater than the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_gte',\n            description: 'All values greater than or equal the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_contains',\n            description: 'All values containing the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_not_contains',\n            description: 'All values not containing the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_starts_with',\n            description: 'All values starting with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_not_starts_with',\n            description: 'All values not starting with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_ends_with',\n            description: 'All values ending with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'name_not_ends_with',\n            description: 'All values not ending with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email',\n            description: '',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_not',\n            description: 'All values that are not equal to given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_in',\n            description: 'All values that are contained in given list.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'email_not_in',\n            description: 'All values that are not contained in given list.',\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n              },\n            },\n            defaultValue: null,\n          },\n          {\n            name: 'email_lt',\n            description: 'All values less than the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_lte',\n            description: 'All values less than or equal the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_gt',\n            description: 'All values greater than the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_gte',\n            description: 'All values greater than or equal the given value.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_contains',\n            description: 'All values containing the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_not_contains',\n            description: 'All values not containing the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_starts_with',\n            description: 'All values starting with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_not_starts_with',\n            description: 'All values not starting with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_ends_with',\n            description: 'All values ending with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email_not_ends_with',\n            description: 'All values not ending with the given string.',\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n        ],\n        name: 'UserWhereInput',\n        description: null,\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'INPUT_OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: [\n          {\n            name: 'id',\n            description: null,\n            type: { kind: 'SCALAR', name: 'ID', ofType: null },\n            defaultValue: null,\n          },\n          {\n            name: 'email',\n            description: null,\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n            defaultValue: null,\n          },\n        ],\n        name: 'UserWhereUniqueInput',\n        description: null,\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'INPUT_OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__Directive',\n        description:\n          'A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\\n\\nIn some cases, you need to provide options to alter GraphQL’s execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n          {\n            name: 'description',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'locations',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'ENUM',\n                    name: '__DirectiveLocation',\n                    ofType: null,\n                  },\n                },\n              },\n            },\n          },\n          {\n            name: 'args',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'OBJECT',\n                    name: '__InputValue',\n                    ofType: null,\n                  },\n                },\n              },\n            },\n          },\n          {\n            name: 'onOperation',\n            description: null,\n            isDeprecated: true,\n            deprecationReason: 'Use `locations`.',\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n          {\n            name: 'onFragment',\n            description: null,\n            isDeprecated: true,\n            deprecationReason: 'Use `locations`.',\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n          {\n            name: 'onField',\n            description: null,\n            isDeprecated: true,\n            deprecationReason: 'Use `locations`.',\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__DirectiveLocation',\n        description:\n          'A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.',\n        interfaces: null,\n        enumValues: [\n          {\n            name: 'QUERY',\n            description: 'Location adjacent to a query operation.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'MUTATION',\n            description: 'Location adjacent to a mutation operation.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'SUBSCRIPTION',\n            description: 'Location adjacent to a subscription operation.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'FIELD',\n            description: 'Location adjacent to a field.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'FRAGMENT_DEFINITION',\n            description: 'Location adjacent to a fragment definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'FRAGMENT_SPREAD',\n            description: 'Location adjacent to a fragment spread.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'INLINE_FRAGMENT',\n            description: 'Location adjacent to an inline fragment.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'SCHEMA',\n            description: 'Location adjacent to a schema definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'SCALAR',\n            description: 'Location adjacent to a scalar definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'OBJECT',\n            description: 'Location adjacent to an object type definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'FIELD_DEFINITION',\n            description: 'Location adjacent to a field definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'ARGUMENT_DEFINITION',\n            description: 'Location adjacent to an argument definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'INTERFACE',\n            description: 'Location adjacent to an interface definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'UNION',\n            description: 'Location adjacent to a union definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'ENUM',\n            description: 'Location adjacent to an enum definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'ENUM_VALUE',\n            description: 'Location adjacent to an enum value definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'INPUT_OBJECT',\n            description: 'INPUT_OBJECT',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'INPUT_FIELD_DEFINITION',\n            description:\n              'Location adjacent to an input object field definition.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n        ],\n        fields: null,\n        kind: 'ENUM',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__EnumValue',\n        description:\n          'One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n          {\n            name: 'description',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'isDeprecated',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n          {\n            name: 'deprecationReason',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__Field',\n        description:\n          'Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n          {\n            name: 'description',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'args',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: {\n                    kind: 'OBJECT',\n                    name: '__InputValue',\n                    ofType: null,\n                  },\n                },\n              },\n            },\n          },\n          {\n            name: 'type',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: '__Type', ofType: null },\n            },\n          },\n          {\n            name: 'isDeprecated',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n            },\n          },\n          {\n            name: 'deprecationReason',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__InputValue',\n        description:\n          'Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'SCALAR', name: 'String', ofType: null },\n            },\n          },\n          {\n            name: 'description',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'type',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: '__Type', ofType: null },\n            },\n          },\n          {\n            name: 'defaultValue',\n            description:\n              'A GraphQL-formatted string representing the default value for this input value.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__Schema',\n        description:\n          'A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'types',\n            description: 'A list of all types supported by this server.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: { kind: 'OBJECT', name: '__Type', ofType: null },\n                },\n              },\n            },\n          },\n          {\n            name: 'queryType',\n            description: 'The type that query operations will be rooted at.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'OBJECT', name: '__Type', ofType: null },\n            },\n          },\n          {\n            name: 'mutationType',\n            description:\n              'If this server supports mutation, the type that mutation operations will be rooted at.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'OBJECT', name: '__Type', ofType: null },\n          },\n          {\n            name: 'subscriptionType',\n            description:\n              'If this server support subscription, the type that subscription operations will be rooted at.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'OBJECT', name: '__Type', ofType: null },\n          },\n          {\n            name: 'directives',\n            description: 'A list of all directives supported by this server.',\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: {\n                kind: 'LIST',\n                name: null,\n                ofType: {\n                  kind: 'NON_NULL',\n                  name: null,\n                  ofType: { kind: 'OBJECT', name: '__Directive', ofType: null },\n                },\n              },\n            },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__Type',\n        description:\n          'The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\\n\\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.',\n        interfaces: [],\n        enumValues: null,\n        fields: [\n          {\n            name: 'kind',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'NON_NULL',\n              name: null,\n              ofType: { kind: 'ENUM', name: '__TypeKind', ofType: null },\n            },\n          },\n          {\n            name: 'name',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'description',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'SCALAR', name: 'String', ofType: null },\n          },\n          {\n            name: 'fields',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'includeDeprecated',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n                defaultValue: 'false',\n              },\n            ],\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'OBJECT', name: '__Field', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'interfaces',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'OBJECT', name: '__Type', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'possibleTypes',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'OBJECT', name: '__Type', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'enumValues',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [\n              {\n                name: 'includeDeprecated',\n                description: null,\n                type: { kind: 'SCALAR', name: 'Boolean', ofType: null },\n                defaultValue: 'false',\n              },\n            ],\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'OBJECT', name: '__EnumValue', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'inputFields',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: {\n              kind: 'LIST',\n              name: null,\n              ofType: {\n                kind: 'NON_NULL',\n                name: null,\n                ofType: { kind: 'OBJECT', name: '__InputValue', ofType: null },\n              },\n            },\n          },\n          {\n            name: 'ofType',\n            description: null,\n            isDeprecated: false,\n            deprecationReason: null,\n            args: [],\n            type: { kind: 'OBJECT', name: '__Type', ofType: null },\n          },\n        ],\n        kind: 'OBJECT',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: '__TypeKind',\n        description:\n          'An enum describing what kind of type a given `__Type` is.',\n        interfaces: null,\n        enumValues: [\n          {\n            name: 'SCALAR',\n            description: 'Indicates this type is a scalar.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'OBJECT',\n            description:\n              'Indicates this type is an object. `fields` and `interfaces` are valid fields.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'INTERFACE',\n            description:\n              'Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'UNION',\n            description:\n              'Indicates this type is a union. `possibleTypes` is a valid field.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'ENUM',\n            description:\n              'Indicates this type is an enum. `enumValues` is a valid field.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'INPUT_OBJECT',\n            description:\n              'Indicates this type is an input object. `inputFields` is a valid field.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'LIST',\n            description:\n              'Indicates this type is a list. `ofType` is a valid field.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n          {\n            name: 'NON_NULL',\n            description:\n              'Indicates this type is a non-null. `ofType` is a valid field.',\n            isDeprecated: false,\n            deprecationReason: null,\n          },\n        ],\n        fields: null,\n        kind: 'ENUM',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Boolean',\n        description: 'The `Boolean` scalar type represents `true` or `false`.',\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'SCALAR',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'ID',\n        description:\n          'The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID.',\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'SCALAR',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Int',\n        description:\n          'The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.',\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'SCALAR',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'Long',\n        description:\n          'The `Long` scalar type represents non-fractional signed whole numeric values. Long can represent values between -(2^63) and 2^63 - 1.',\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'SCALAR',\n        possibleTypes: null,\n      },\n      {\n        inputFields: null,\n        name: 'String',\n        description:\n          'The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.',\n        interfaces: null,\n        enumValues: null,\n        fields: null,\n        kind: 'SCALAR',\n        possibleTypes: null,\n      },\n    ],\n  },\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/fixtures/sdl.ts",
    "content": "export const exampleSdl = `type A implements Node {\n  id: ID!\n  name: String!\n}\n\n\"\"\"A connection to a list of items.\"\"\"\ntype AConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n\n  \"\"\"A list of edges.\"\"\"\n  edges: [AEdge]!\n  aggregate: AggregateA!\n}\n\ninput ACreateInput {\n  name: String!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype AEdge {\n  \"\"\"The item at the end of the edge.\"\"\"\n  node: A!\n\n  \"\"\"A cursor for use in pagination.\"\"\"\n  cursor: String!\n}\n\ntype AggregateA {\n  count: Int!\n}\n\ntype AggregateB {\n  count: Int!\n}\n\ntype AggregateUser {\n  count: Int!\n}\n\nenum AOrderByInput {\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  createdAt_ASC\n  createdAt_DESC\n}\n\ntype APreviousValues {\n  id: ID!\n  name: String!\n}\n\ntype ASubscriptionPayload {\n  mutation: MutationType!\n  node: A\n  updatedFields: [String!]\n  previousValues: APreviousValues\n}\n\ninput ASubscriptionWhereInput {\n  \"\"\"Logical AND on all given filters.\"\"\"\n  AND: [ASubscriptionWhereInput!]\n\n  \"\"\"Logical OR on all given filters.\"\"\"\n  OR: [ASubscriptionWhereInput!]\n\n  \"\"\"Logical NOT on all given filters combined by AND.\"\"\"\n  NOT: [ASubscriptionWhereInput!]\n\n  \"\"\"\n  The subscription event gets dispatched when it's listed in mutation_in\n  \"\"\"\n  mutation_in: [MutationType!]\n\n  \"\"\"\n  The subscription event gets only dispatched when one of the updated fields names is included in this list\n  \"\"\"\n  updatedFields_contains: String\n\n  \"\"\"\n  The subscription event gets only dispatched when all of the field names included in this list have been updated\n  \"\"\"\n  updatedFields_contains_every: [String!]\n\n  \"\"\"\n  The subscription event gets only dispatched when some of the field names included in this list have been updated\n  \"\"\"\n  updatedFields_contains_some: [String!]\n  node: AWhereInput\n}\n\ninput AUpdateInput {\n  name: String\n}\n\ninput AWhereInput {\n  \"\"\"Logical AND on all given filters.\"\"\"\n  AND: [AWhereInput!]\n\n  \"\"\"Logical OR on all given filters.\"\"\"\n  OR: [AWhereInput!]\n\n  \"\"\"Logical NOT on all given filters combined by AND.\"\"\"\n  NOT: [AWhereInput!]\n  id: ID\n\n  \"\"\"All values that are not equal to given value.\"\"\"\n  id_not: ID\n\n  \"\"\"All values that are contained in given list.\"\"\"\n  id_in: [ID!]\n\n  \"\"\"All values that are not contained in given list.\"\"\"\n  id_not_in: [ID!]\n\n  \"\"\"All values less than the given value.\"\"\"\n  id_lt: ID\n\n  \"\"\"All values less than or equal the given value.\"\"\"\n  id_lte: ID\n\n  \"\"\"All values greater than the given value.\"\"\"\n  id_gt: ID\n\n  \"\"\"All values greater than or equal the given value.\"\"\"\n  id_gte: ID\n\n  \"\"\"All values containing the given string.\"\"\"\n  id_contains: ID\n\n  \"\"\"All values not containing the given string.\"\"\"\n  id_not_contains: ID\n\n  \"\"\"All values starting with the given string.\"\"\"\n  id_starts_with: ID\n\n  \"\"\"All values not starting with the given string.\"\"\"\n  id_not_starts_with: ID\n\n  \"\"\"All values ending with the given string.\"\"\"\n  id_ends_with: ID\n\n  \"\"\"All values not ending with the given string.\"\"\"\n  id_not_ends_with: ID\n  name: String\n\n  \"\"\"All values that are not equal to given value.\"\"\"\n  name_not: String\n\n  \"\"\"All values that are contained in given list.\"\"\"\n  name_in: [String!]\n\n  \"\"\"All values that are not contained in given list.\"\"\"\n  name_not_in: [String!]\n\n  \"\"\"All values less than the given value.\"\"\"\n  name_lt: String\n\n  \"\"\"All values less than or equal the given value.\"\"\"\n  name_lte: String\n\n  \"\"\"All values greater than the given value.\"\"\"\n  name_gt: String\n\n  \"\"\"All values greater than or equal the given value.\"\"\"\n  name_gte: String\n\n  \"\"\"All values containing the given string.\"\"\"\n  name_contains: String\n\n  \"\"\"All values not containing the given string.\"\"\"\n  name_not_contains: String\n\n  \"\"\"All values starting with the given string.\"\"\"\n  name_starts_with: String\n\n  \"\"\"All values not starting with the given string.\"\"\"\n  name_not_starts_with: String\n\n  \"\"\"All values ending with the given string.\"\"\"\n  name_ends_with: String\n\n  \"\"\"All values not ending with the given string.\"\"\"\n  name_not_ends_with: String\n}\n\ninput AWhereUniqueInput {\n  id: ID\n}\n\ntype B implements Node {\n  id: ID!\n  name: String!\n}\n\ntype BatchPayload {\n  \"\"\"The number of nodes that have been affected by the Batch operation.\"\"\"\n  count: Long!\n}\n\n\"\"\"A connection to a list of items.\"\"\"\ntype BConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n\n  \"\"\"A list of edges.\"\"\"\n  edges: [BEdge]!\n  aggregate: AggregateB!\n}\n\ninput BCreateInput {\n  name: String!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype BEdge {\n  \"\"\"The item at the end of the edge.\"\"\"\n  node: B!\n\n  \"\"\"A cursor for use in pagination.\"\"\"\n  cursor: String!\n}\n\nenum BOrderByInput {\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  createdAt_ASC\n  createdAt_DESC\n}\n\ntype BPreviousValues {\n  id: ID!\n  name: String!\n}\n\ntype BSubscriptionPayload {\n  mutation: MutationType!\n  node: B\n  updatedFields: [String!]\n  previousValues: BPreviousValues\n}\n\ninput BSubscriptionWhereInput {\n  \"\"\"Logical AND on all given filters.\"\"\"\n  AND: [BSubscriptionWhereInput!]\n\n  \"\"\"Logical OR on all given filters.\"\"\"\n  OR: [BSubscriptionWhereInput!]\n\n  \"\"\"Logical NOT on all given filters combined by AND.\"\"\"\n  NOT: [BSubscriptionWhereInput!]\n\n  \"\"\"\n  The subscription event gets dispatched when it's listed in mutation_in\n  \"\"\"\n  mutation_in: [MutationType!]\n\n  \"\"\"\n  The subscription event gets only dispatched when one of the updated fields names is included in this list\n  \"\"\"\n  updatedFields_contains: String\n\n  \"\"\"\n  The subscription event gets only dispatched when all of the field names included in this list have been updated\n  \"\"\"\n  updatedFields_contains_every: [String!]\n\n  \"\"\"\n  The subscription event gets only dispatched when some of the field names included in this list have been updated\n  \"\"\"\n  updatedFields_contains_some: [String!]\n  node: BWhereInput\n}\n\ninput BUpdateInput {\n  name: String\n}\n\ninput BWhereInput {\n  \"\"\"Logical AND on all given filters.\"\"\"\n  AND: [BWhereInput!]\n\n  \"\"\"Logical OR on all given filters.\"\"\"\n  OR: [BWhereInput!]\n\n  \"\"\"Logical NOT on all given filters combined by AND.\"\"\"\n  NOT: [BWhereInput!]\n  id: ID\n\n  \"\"\"All values that are not equal to given value.\"\"\"\n  id_not: ID\n\n  \"\"\"All values that are contained in given list.\"\"\"\n  id_in: [ID!]\n\n  \"\"\"All values that are not contained in given list.\"\"\"\n  id_not_in: [ID!]\n\n  \"\"\"All values less than the given value.\"\"\"\n  id_lt: ID\n\n  \"\"\"All values less than or equal the given value.\"\"\"\n  id_lte: ID\n\n  \"\"\"All values greater than the given value.\"\"\"\n  id_gt: ID\n\n  \"\"\"All values greater than or equal the given value.\"\"\"\n  id_gte: ID\n\n  \"\"\"All values containing the given string.\"\"\"\n  id_contains: ID\n\n  \"\"\"All values not containing the given string.\"\"\"\n  id_not_contains: ID\n\n  \"\"\"All values starting with the given string.\"\"\"\n  id_starts_with: ID\n\n  \"\"\"All values not starting with the given string.\"\"\"\n  id_not_starts_with: ID\n\n  \"\"\"All values ending with the given string.\"\"\"\n  id_ends_with: ID\n\n  \"\"\"All values not ending with the given string.\"\"\"\n  id_not_ends_with: ID\n  name: String\n\n  \"\"\"All values that are not equal to given value.\"\"\"\n  name_not: String\n\n  \"\"\"All values that are contained in given list.\"\"\"\n  name_in: [String!]\n\n  \"\"\"All values that are not contained in given list.\"\"\"\n  name_not_in: [String!]\n\n  \"\"\"All values less than the given value.\"\"\"\n  name_lt: String\n\n  \"\"\"All values less than or equal the given value.\"\"\"\n  name_lte: String\n\n  \"\"\"All values greater than the given value.\"\"\"\n  name_gt: String\n\n  \"\"\"All values greater than or equal the given value.\"\"\"\n  name_gte: String\n\n  \"\"\"All values containing the given string.\"\"\"\n  name_contains: String\n\n  \"\"\"All values not containing the given string.\"\"\"\n  name_not_contains: String\n\n  \"\"\"All values starting with the given string.\"\"\"\n  name_starts_with: String\n\n  \"\"\"All values not starting with the given string.\"\"\"\n  name_not_starts_with: String\n\n  \"\"\"All values ending with the given string.\"\"\"\n  name_ends_with: String\n\n  \"\"\"All values not ending with the given string.\"\"\"\n  name_not_ends_with: String\n}\n\ninput BWhereUniqueInput {\n  id: ID\n}\n\n\"\"\"\nThe \\`Long\\` scalar type represents non-fractional signed whole numeric values.\nLong can represent values between -(2^63) and 2^63 - 1.\n\"\"\"\nscalar Long\n\ntype Mutation {\n  createUser(data: UserCreateInput!): User!\n  createA(data: ACreateInput!): A!\n  createB(data: BCreateInput!): B!\n  updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User\n  updateA(data: AUpdateInput!, where: AWhereUniqueInput!): A\n  updateB(data: BUpdateInput!, where: BWhereUniqueInput!): B\n  deleteUser(where: UserWhereUniqueInput!): User\n  deleteA(where: AWhereUniqueInput!): A\n  deleteB(where: BWhereUniqueInput!): B\n  upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User!\n  upsertA(where: AWhereUniqueInput!, create: ACreateInput!, update: AUpdateInput!): A!\n  upsertB(where: BWhereUniqueInput!, create: BCreateInput!, update: BUpdateInput!): B!\n  updateManyUsers(data: UserUpdateInput!, where: UserWhereInput): BatchPayload!\n  updateManyAs(data: AUpdateInput!, where: AWhereInput): BatchPayload!\n  updateManyBs(data: BUpdateInput!, where: BWhereInput): BatchPayload!\n  deleteManyUsers(where: UserWhereInput): BatchPayload!\n  deleteManyAs(where: AWhereInput): BatchPayload!\n  deleteManyBs(where: BWhereInput): BatchPayload!\n}\n\nenum MutationType {\n  CREATED\n  UPDATED\n  DELETED\n}\n\n\"\"\"An object with an ID\"\"\"\ninterface Node {\n  \"\"\"The id of the object.\"\"\"\n  id: ID!\n}\n\n\"\"\"Information about pagination in a connection.\"\"\"\ntype PageInfo {\n  \"\"\"When paginating forwards, are there more items?\"\"\"\n  hasNextPage: Boolean!\n\n  \"\"\"When paginating backwards, are there more items?\"\"\"\n  hasPreviousPage: Boolean!\n\n  \"\"\"When paginating backwards, the cursor to continue.\"\"\"\n  startCursor: String\n\n  \"\"\"When paginating forwards, the cursor to continue.\"\"\"\n  endCursor: String\n}\n\ntype Query {\n  users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]!\n  as(where: AWhereInput, orderBy: AOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [A]!\n  bs(where: BWhereInput, orderBy: BOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [B]!\n  user(where: UserWhereUniqueInput!): User\n  a(where: AWhereUniqueInput!): A\n  b(where: BWhereUniqueInput!): B\n  usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection!\n  asConnection(where: AWhereInput, orderBy: AOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): AConnection!\n  bsConnection(where: BWhereInput, orderBy: BOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): BConnection!\n\n  \"\"\"Fetches an object given its ID\"\"\"\n  node(\n    \"\"\"The ID of an object\"\"\"\n    id: ID!\n  ): Node\n}\n\ntype Subscription {\n  user(where: UserSubscriptionWhereInput): UserSubscriptionPayload\n  a(where: ASubscriptionWhereInput): ASubscriptionPayload\n  b(where: BSubscriptionWhereInput): BSubscriptionPayload\n}\n\ntype User implements Node {\n  id: ID!\n  name: String!\n}\n\n\"\"\"A connection to a list of items.\"\"\"\ntype UserConnection {\n  \"\"\"Information to aid in pagination.\"\"\"\n  pageInfo: PageInfo!\n\n  \"\"\"A list of edges.\"\"\"\n  edges: [UserEdge]!\n  aggregate: AggregateUser!\n}\n\ninput UserCreateInput {\n  name: String!\n}\n\n\"\"\"An edge in a connection.\"\"\"\ntype UserEdge {\n  \"\"\"The item at the end of the edge.\"\"\"\n  node: User!\n\n  \"\"\"A cursor for use in pagination.\"\"\"\n  cursor: String!\n}\n\nenum UserOrderByInput {\n  id_ASC\n  id_DESC\n  name_ASC\n  name_DESC\n  updatedAt_ASC\n  updatedAt_DESC\n  createdAt_ASC\n  createdAt_DESC\n}\n\ntype UserPreviousValues {\n  id: ID!\n  name: String!\n}\n\ntype UserSubscriptionPayload {\n  mutation: MutationType!\n  node: User\n  updatedFields: [String!]\n  previousValues: UserPreviousValues\n}\n\ninput UserSubscriptionWhereInput {\n  \"\"\"Logical AND on all given filters.\"\"\"\n  AND: [UserSubscriptionWhereInput!]\n\n  \"\"\"Logical OR on all given filters.\"\"\"\n  OR: [UserSubscriptionWhereInput!]\n\n  \"\"\"Logical NOT on all given filters combined by AND.\"\"\"\n  NOT: [UserSubscriptionWhereInput!]\n\n  \"\"\"\n  The subscription event gets dispatched when it's listed in mutation_in\n  \"\"\"\n  mutation_in: [MutationType!]\n\n  \"\"\"\n  The subscription event gets only dispatched when one of the updated fields names is included in this list\n  \"\"\"\n  updatedFields_contains: String\n\n  \"\"\"\n  The subscription event gets only dispatched when all of the field names included in this list have been updated\n  \"\"\"\n  updatedFields_contains_every: [String!]\n\n  \"\"\"\n  The subscription event gets only dispatched when some of the field names included in this list have been updated\n  \"\"\"\n  updatedFields_contains_some: [String!]\n  node: UserWhereInput\n}\n\ninput UserUpdateInput {\n  name: String\n}\n\ninput UserWhereInput {\n  \"\"\"Logical AND on all given filters.\"\"\"\n  AND: [UserWhereInput!]\n\n  \"\"\"Logical OR on all given filters.\"\"\"\n  OR: [UserWhereInput!]\n\n  \"\"\"Logical NOT on all given filters combined by AND.\"\"\"\n  NOT: [UserWhereInput!]\n  id: ID\n\n  \"\"\"All values that are not equal to given value.\"\"\"\n  id_not: ID\n\n  \"\"\"All values that are contained in given list.\"\"\"\n  id_in: [ID!]\n\n  \"\"\"All values that are not contained in given list.\"\"\"\n  id_not_in: [ID!]\n\n  \"\"\"All values less than the given value.\"\"\"\n  id_lt: ID\n\n  \"\"\"All values less than or equal the given value.\"\"\"\n  id_lte: ID\n\n  \"\"\"All values greater than the given value.\"\"\"\n  id_gt: ID\n\n  \"\"\"All values greater than or equal the given value.\"\"\"\n  id_gte: ID\n\n  \"\"\"All values containing the given string.\"\"\"\n  id_contains: ID\n\n  \"\"\"All values not containing the given string.\"\"\"\n  id_not_contains: ID\n\n  \"\"\"All values starting with the given string.\"\"\"\n  id_starts_with: ID\n\n  \"\"\"All values not starting with the given string.\"\"\"\n  id_not_starts_with: ID\n\n  \"\"\"All values ending with the given string.\"\"\"\n  id_ends_with: ID\n\n  \"\"\"All values not ending with the given string.\"\"\"\n  id_not_ends_with: ID\n  name: String\n\n  \"\"\"All values that are not equal to given value.\"\"\"\n  name_not: String\n\n  \"\"\"All values that are contained in given list.\"\"\"\n  name_in: [String!]\n\n  \"\"\"All values that are not contained in given list.\"\"\"\n  name_not_in: [String!]\n\n  \"\"\"All values less than the given value.\"\"\"\n  name_lt: String\n\n  \"\"\"All values less than or equal the given value.\"\"\"\n  name_lte: String\n\n  \"\"\"All values greater than the given value.\"\"\"\n  name_gt: String\n\n  \"\"\"All values greater than or equal the given value.\"\"\"\n  name_gte: String\n\n  \"\"\"All values containing the given string.\"\"\"\n  name_contains: String\n\n  \"\"\"All values not containing the given string.\"\"\"\n  name_not_contains: String\n\n  \"\"\"All values starting with the given string.\"\"\"\n  name_starts_with: String\n\n  \"\"\"All values not starting with the given string.\"\"\"\n  name_not_starts_with: String\n\n  \"\"\"All values ending with the given string.\"\"\"\n  name_ends_with: String\n\n  \"\"\"All values not ending with the given string.\"\"\"\n  name_not_ends_with: String\n}\n\ninput UserWhereUniqueInput {\n  id: ID\n}\n`\n"
  },
  {
    "path": "packages/graphql-playground-react/src/graphqlConfig.ts",
    "content": "export interface GraphQLConfigExtensions {\n  endpoints?: GraphQLConfigEnpointsData\n  [name: string]: any\n}\n\nexport interface GraphQLResolvedConfigData {\n  schemaPath: string\n\n  includes?: string[]\n  excludes?: string[]\n\n  extensions?: GraphQLConfigExtensions\n}\n\nexport type GraphQLConfig = GraphQLResolvedConfigData & {\n  projects?: { [projectName: string]: GraphQLResolvedConfigData }\n}\n\nexport interface GraphQLConfigEnpointsSubscription {\n  url: string\n  connectionParams?: { [name: string]: string | undefined }\n}\n\nexport interface GraphQLConfigEnpointConfig {\n  url: string\n  headers?: { [name: string]: string }\n  subscription?: GraphQLConfigEnpointsSubscription\n}\n\nexport interface GraphQLConfigEnpointsMapData {\n  [env: string]: GraphQLConfigEnpointConfig | string\n}\n\nexport interface GraphQLConfigEnpointsMap {\n  [env: string]: GraphQLConfigEnpointConfig\n}\n\nexport type GraphQLConfigEnpointsData = GraphQLConfigEnpointsMapData\n"
  },
  {
    "path": "packages/graphql-playground-react/src/index.css",
    "content": "body {\n  margin: 0;\n  padding: 0;\n  font-family: sans-serif;\n  overflow: hidden;\n}\n\n#root {\n  height: 100%;\n}\n\nbody {\n  font-family: 'Open Sans', sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  color: rgba(0,0,0,.8);\n  line-height: 1.5;\n  height: 100vh;\n  letter-spacing: 0.53px;\n  margin-right: -1px !important;\n}\n\nhtml, body, p, a, h1, h2, h3, h4, ul, pre, code {\n  margin: 0;\n  padding: 0;\n  color: inherit;\n}\n\na:active, a:focus, button:focus, input:focus {\n  outline: none;\n}\n\ninput, button, submit {\n  border: none;\n}\n\ninput, button, pre {\n  font-family: 'Open Sans', sans-serif;\n}\n\ncode {\n  font-family: Consolas, monospace;\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/index.test.tsx",
    "content": "import * as React from 'react'\nimport { render, mount } from 'enzyme'\nimport MiddlewareApp from './components/MiddlewareApp'\n\ntest('test MiddleWareApp without tabs', () => {\n  const wrapper = render(\n    <MiddlewareApp setTitle={true} showNewWorkspace={false} />,\n  )\n  expect(wrapper).toMatchSnapshot()\n})\n\ntest('test MiddleWareApp with tabs', () => {\n  const wrapper = render(\n    <MiddlewareApp\n      setTitle={true}\n      showNewWorkspace={false}\n      tabs={[\n        {\n          name: 'Tab 1',\n          query: '{ users { id } }',\n          endpoint: 'https://eu1.prisma.sh/public-asdf/session65/dev',\n          responses: ['{}'],\n        },\n        {\n          name: 'Tab 2',\n          query: '{ users { id } }',\n          endpoint: 'https://eu1.prisma.sh/public-asdf/session65/dev',\n        },\n      ]}\n    />,\n  )\n  expect(wrapper).toMatchSnapshot()\n})\n\ntest('test MiddleWareApp with one tab and click execute', () => {\n  const wrapper = mount(\n    <MiddlewareApp\n      setTitle={true}\n      showNewWorkspace={false}\n      tabs={[\n        {\n          name: 'Tab 1',\n          query: '{ users { id } }',\n          endpoint: 'http://localhost:4000',\n        },\n      ]}\n    />,\n  )\n  const executeButtons = wrapper.find('[title=\"Execute Query (Ctrl-Enter)\"]')\n  const executeButtonElement = {\n    ...executeButtons.get(0),\n    props: {\n      onClick: jest.fn(),\n    },\n  }\n  const executeButton = wrapper.wrap(executeButtonElement)\n  expect(executeButton.length).toBe(1)\n})\n\ntest('test MiddleWareApp passed default headers', () => {\n  const wrapper = render(\n    <MiddlewareApp\n      setTitle={true}\n      showNewWorkspace={false}\n      headers={{ test: 'test' }}\n    />,\n  )\n  expect(wrapper).toMatchSnapshot()\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/index.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport Root from './components/Root'\nimport './index.css'\n\nif (process.env.NODE_ENV !== 'production') {\n  /* tslint:disable-next-line */\n  // const { whyDidYouUpdate } = require('why-did-you-update')\n  // whyDidYouUpdate(React)\n}\n\n/* tslint:disable-next-line */\n;(window as any)['GraphQLPlayground'] = {\n  init(element: HTMLElement, options) {\n    ReactDOM.render(<Root {...options} />, element)\n  },\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/lib.tsx",
    "content": "import PlaygroundWrapper from './components/PlaygroundWrapper'\nimport GraphQLEditor from './components/Playground/GraphQLEditor'\nimport { store } from './components/GraphQLBinApp'\n\nexport { PlaygroundWrapper as Playground, GraphQLEditor }\n\nexport default PlaygroundWrapper\n\nexport { store }\n\nexport * from './state/sessions/actions'\nexport * from './state/sessions/selectors'\n\nexport * from './state/sharing/actions'\nexport * from './state/sharing/selectors'\n\nexport * from './state/workspace/actions'\nexport * from './state/workspace/reducers'\n\nexport * from './state/history/actions'\nexport * from './state/history/selectors'\n\nexport * from './state/docs/actions'\nexport * from './state/docs/selectors'\n\nexport * from './state/general/actions'\nexport * from './state/general/selectors'\n\nexport * from './state/appHistory/actions'\nexport * from './state/appHistory/reducers'\n"
  },
  {
    "path": "packages/graphql-playground-react/src/localDevIndex.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport MiddlewareApp from './components/MiddlewareApp'\nimport './index.css'\n// import { Tab } from './state/sessions/reducers'\nimport { LinkCreatorProps } from './state/sessions/fetchingSagas'\nimport { ApolloLink } from 'apollo-link'\nimport { HttpLink } from 'apollo-link-http'\n// import { exampleSchema } from './fixtures/exampleSchema'\n\nif (process.env.NODE_ENV !== 'production') {\n  /* tslint:disable-next-line */\n  // const { whyDidYouUpdate } = require('why-did-you-update')\n  // whyDidYouUpdate(React)\n}\n\n/* tslint:disable-next-line */\n;(window as any)['GraphQLPlayground'] = {\n  init(element: HTMLElement, options) {\n    ReactDOM.render(\n      <MiddlewareApp\n        setTitle={true}\n        showNewWorkspace={false}\n        {...options}\n        // config={config}\n        // configString={configString}\n        // codeTheme={lightEditorColours}\n        // tabs={tabs}\n        createApolloLink={customLinkCreator}\n        // schema={exampleSchema}\n      />,\n      element,\n    )\n  },\n}\n\n// const configString = `projects:\n// app:\n//   schemaPath: \"src/schema.graphql\"\n//   extensions:\n//     endpoints:\n//       default: \"http://localhost:4000\"\n// database:\n//   schemaPath: \"src/generated/prisma.graphql\"\n//   extensions:\n//     prisma: database/prisma.yml`\n\n// const config = {\n//   projects: {\n//     prisma: {\n//       schemaPath: 'src/generated/prisma.graphql',\n//       includes: ['database/seed.graphql'],\n//       extensions: {\n//         prisma: 'database/prisma.yml',\n//         'prepare-binding': {\n//           output: 'src/generated/prisma.ts',\n//           generator: 'prisma-ts',\n//         },\n//         endpoints: {\n//           dev2: {\n//             url: 'https://eu1.prisma.sh/public-asdf/session65/dev',\n//             // headers: {\n//             //   Authorization:\n//             //     'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InNlcnZpY2UiOiJhc2RmQGRldiIsInJvbGVzIjpbImFkbWluIl19LCJpYXQiOjE1MjM1MTg3NTYsImV4cCI6MTUyNDEyMzU1Nn0.fzKhXa1JpN9M1UGTbS6p2KMUWDrKLxYD3i3a9eVfOQQ',\n//             // },\n//           },\n//         },\n//       },\n//     },\n//     app: {\n//       schemaPath: 'src/schema.graphql',\n//       includes: ['queries/{booking,queries}.graphql'],\n//       extensions: {\n//         endpoints: {\n//           default: 'http://localhost:4000',\n//         },\n//       },\n//     },\n//   },\n// }\n\n// const tabs: Tab[] = [\n//   {\n//     query: '{ users { id } }',\n//     endpoint: 'https://eu1.prisma.sh/public-asdf/session65/dev',\n//     responses: ['{}'],\n//   },\n//   {\n//     query: '{ users { id } }',\n//     endpoint: 'https://eu1.prisma.sh/public-asdf/session65/dev',\n//   },\n// ]\n\nconst customLinkCreator = (\n  session: LinkCreatorProps,\n  wsEndpoint?: string,\n): { link: ApolloLink } => {\n  const { headers, credentials } = session\n\n  const link = new HttpLink({\n    uri: session.endpoint,\n    fetch,\n    headers,\n    credentials,\n  })\n\n  return { link }\n}\n\n// const lightEditorColours = {\n//   property: '#328c8c',\n//   comment: 'rgba(0, 0, 0, 0.3)',\n//   punctuation: 'rgba(23,42,58,.8)',\n//   keyword: '#366b6b',\n//   def: 'rgb(56, 189, 193)',\n//   qualifier: '#1c92a9',\n//   attribute: '#b56531',\n//   number: '#1f6ed6;',\n//   string: '#d64292',\n//   builtin: '#d47509',\n//   string2: '#0b7fc7',\n//   variable: 'rgb(236, 95, 103)',\n//   meta: '#b33086',\n//   atom: 'rgb(245, 160, 0)',\n//   ws: 'rgba(23, 42, 58, 0.8)',\n//   selection: '#d1e9fd',\n//   cursorColor: 'rgba(0, 0, 0, 0.4)',\n\n//   editorBackground: '#f6f7f7',\n//   resultBackground: '#eeeff0',\n//   leftDrawerBackground: '#e9eaea',\n//   rightDrawerBackground: '#e5e7e7',\n// }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/middlewareIndex.tsx",
    "content": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport MiddlewareApp from './components/MiddlewareApp'\nimport './index.css'\n\nif (process.env.NODE_ENV !== 'production') {\n  /* tslint:disable-next-line */\n  // const { whyDidYouUpdate } = require('why-did-you-update')\n  // whyDidYouUpdate(React)\n}\n\n/* tslint:disable-next-line */\n;(window as any)['GraphQLPlayground'] = {\n  init(element: HTMLElement, options) {\n    ReactDOM.render(\n      <MiddlewareApp setTitle={true} showNewWorkspace={false} {...options} />,\n      element,\n    )\n  },\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/setupEnzyme.ts",
    "content": "import { configure } from 'enzyme'\nimport * as EnzymeAdapter from 'enzyme-adapter-react-16'\nimport { JSDOM } from 'jsdom'\n\nconfigure({ adapter: new EnzymeAdapter() })\n\n// TODO: Fix/document this hack\n// https://github.com/jsdom/jsdom#intervening-before-parsing\nconst jsdom = new JSDOM('<!doctype html><html><body></body></html>', {\n  beforeParse(window) {\n    window.focus = jest.fn()\n  },\n})\nconst { window } = jsdom\n\nfunction copyProps(src, target) {\n  const props = Object.getOwnPropertyNames(src)\n    .filter((prop) => typeof target[prop] === 'undefined')\n    .reduce(\n      (result, prop) => ({\n        ...result,\n        [prop]: Object.getOwnPropertyDescriptor(src, prop),\n      }),\n      {},\n    )\n  Object.defineProperties(target, props)\n}\n\n;(global as any).window = window as any\n;(global as any).document = window.document as any\n;(global as any).navigator = {\n  userAgent: 'node.js',\n}\ncopyProps(window, global)\n\n// TODO: Fix/document this hack\n;(global as any).document.createRange = () => {\n  return {\n    setEnd: () => {},\n    setStart: () => {},\n    getBoundingClientRect: () => {\n      return {\n        right: 0,\n      }\n    },\n    getClientRects: () => {\n      return {\n        length: 0,\n        left: 0,\n        right: 0,\n      }\n    },\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/appHistory/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const { selectAppHistoryItem } = createActions({\n  SELECT_APP_HISTORY_ITEM: item => ({ item }),\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/appHistory/reducers.ts",
    "content": "import { Record, OrderedMap } from 'immutable'\nimport { handleActions } from 'redux-actions'\n\n// tslint:disable\n\nexport class AppHistory extends Record({\n  items: OrderedMap(),\n}) {\n  items: OrderedMap<string, AppHistoryItem>\n}\n\nexport class AppHistoryItem extends Record({\n  type: 'local',\n  configString: undefined,\n  configPath: undefined,\n  endpoint: undefined,\n  folderName: undefined,\n  env: undefined,\n  platformToken: undefined,\n  lastOpened: new Date(),\n  config: undefined,\n} as any) {\n  type: 'local' | 'endpoint'\n  configString?: string\n  configPath?: string\n  endpoint?: string\n  folderName?: string\n  env?: any\n  platformToken?: string\n  lastOpened: Date\n  config?: any\n}\n\nexport default handleActions(\n  {\n    SELECT_APP_HISTORY_ITEM: (state, { payload }) =>\n      state.setIn(['items', payload.item.path], payload.item),\n  },\n  new AppHistory(),\n)\n\nexport const getAppHistory = state => state.appHistory\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/createStore.ts",
    "content": "import { compose, createStore, Store, applyMiddleware } from 'redux'\nimport createSagaMiddleware from 'redux-saga'\nimport rootSaga from './rootSaga'\nimport rootReducer from './workspace/reducers'\nimport { getSelectedSession } from './sessions/selectors'\nimport { serializeState, deserializeState } from './localStorage'\n\nconst sagaMiddleware = createSagaMiddleware()\nconst functions = [applyMiddleware(sagaMiddleware)]\n\nconst composeEnhancers =\n  (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose\n\nconst initialState = deserializeState()\n\nexport default (): Store<any> => {\n  const store = createStore(\n    rootReducer,\n    initialState,\n    composeEnhancers.apply(null, functions),\n  )\n\n  store.subscribe(serializeState(store))\n  ;(window as any).s = store\n  ;(window as any).session = () => {\n    return getSelectedSession(store.getState())\n  }\n\n  sagaMiddleware.run(rootSaga)\n  return store\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/docs/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const {\n  setStacks,\n  addStack,\n  toggleDocs,\n  setDocsVisible,\n  changeWidthDocs,\n  changeKeyMove,\n  showDocForReference,\n} = createActions({\n  SET_STACKS: (sessionId, stacks) => ({ sessionId, stacks }),\n  ADD_STACK: (sessionId, field, x, y) => ({ sessionId, field, x, y }),\n  TOGGLE_DOCS: (sessionId, activeTabIdx) => ({ sessionId, activeTabIdx }),\n  SET_DOCS_VISIBLE: (sessionId, open, activeTabIdx?) => ({\n    sessionId,\n    open,\n    activeTabIdx,\n  }),\n  CHANGE_WIDTH_DOCS: (sessionId, width) => ({ sessionId, width }),\n  CHANGE_KEY_MOVE: (sessionId, move) => ({ sessionId, move }),\n  SHOW_DOC_FOR_REFERENCE: reference => ({ reference }),\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/docs/reducers.ts",
    "content": "import { GraphQLField } from 'graphql'\nimport { Map, List, Record, set } from 'immutable'\nimport { handleActions } from 'redux-actions'\nimport { columnWidth } from '../../constants'\n\nexport type DocsState = Map<string, DocsSessionState>\n\nexport interface NavItem {\n  x: number\n  y: number\n  field: GraphQLField<any, any>\n}\n\nexport interface DocsSessionState {\n  readonly navStack: List<Map<string, NavItem>>\n  readonly docsOpen: boolean\n  readonly docsWidth: number\n  readonly keyMove: boolean\n  readonly activeTabIdx: number | null\n}\n\nexport class DocsSession extends Record({\n  navStack: List([]),\n  docsOpen: false,\n  docsWidth: columnWidth,\n  activeTabIdx: null,\n  keyMove: false,\n}) {\n  toJSON() {\n    const obj = this.toObject()\n    // don't serialize navStack, as it could contain circular references in the type definitions\n    return set(obj, 'navStack', List([]))\n  }\n}\n\nconst defaultState: DocsState = Map({ '': new DocsSession() })\n\nexport default handleActions(\n  {\n    SET_STACKS: (state, { payload: { sessionId, stacks } }) => {\n      let session = getSession(state, sessionId)\n      session = session.set('navStack', stacks)\n      return state.set(sessionId, session)\n    },\n    ADD_STACK: (state, { payload: { sessionId, field, x, y } }) => {\n      if (!field.path) {\n        field.path = field.name\n      }\n      let session = getSession(state, sessionId)\n      session = session.update('navStack', navStack => {\n        let newNavStack = navStack\n        if (x < newNavStack.count()) {\n          newNavStack = newNavStack.slice(0, x)\n        }\n        return newNavStack.push(\n          Map({\n            x,\n            y,\n            field,\n          }),\n        )\n      })\n      return state.set(sessionId, session)\n    },\n    TOGGLE_DOCS: (state, { payload: { sessionId, activeTabIdx } }) => {\n      let session = getSession(state, sessionId)\n      session = session.set('docsOpen', !session.docsOpen)\n      if (typeof activeTabIdx === 'number') {\n        session = session.set(\n          'activeTabIdx',\n          session.docsOpen ? activeTabIdx : null,\n        )\n      }\n      return state.set(sessionId, session)\n    },\n    SET_DOCS_VISIBLE: (\n      state,\n      { payload: { sessionId, open, activeTabIdx } },\n    ) => {\n      let session = getSession(state, sessionId)\n      session = session.set('docsOpen', !!open)\n      if (!session.docsOpen) {\n        session = session.set('activeTabIdx', null)\n      } else if (typeof activeTabIdx === 'number') {\n        session = session.set('activeTabIdx', activeTabIdx)\n      }\n      return state.set(sessionId, session)\n    },\n    CHANGE_WIDTH_DOCS: (state, { payload: { sessionId, width } }) => {\n      let session = getSession(state, sessionId)\n      session = session.set('docsWidth', width)\n      return state.set(sessionId, session)\n    },\n    CHANGE_KEY_MOVE: (state, { payload: { sessionId, keyMove } }) => {\n      let session = getSession(state, sessionId)\n      session = session.set('keyMove', keyMove)\n      return state.set(sessionId, session)\n    },\n  },\n  defaultState,\n)\n\nfunction getSession(state, sessionId) {\n  if (!sessionId) {\n    throw new Error('sessionId cant be null')\n  }\n  return state.get(sessionId) || new DocsSession()\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/docs/selectors.ts",
    "content": "import { createSelector } from 'reselect'\nimport { DocsSession } from './reducers'\nimport { getSelectedWorkspace } from '../workspace/reducers'\n\nexport const getSessionDocsState = createSelector(\n  [getSelectedWorkspace],\n  state => {\n    const sessionId = state.sessions.selectedSessionId\n    return state.docs.get(sessionId) || new DocsSession()\n  },\n)\n\nexport const getSessionDocs = createSelector([getSessionDocsState], state => {\n  return state.toJS()\n})\nexport const getDocsOpen = createSelector([getSessionDocsState], state => {\n  return state.get('docsOpen')\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/general/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const {\n  setSettingsString,\n  setConfigString,\n  openHistory,\n  closeHistory,\n} = createActions({\n  SET_SETTINGS_STRING: settingsString => ({ settingsString }),\n  SET_CONFIG_STRING: configString => ({ configString }),\n  OPEN_HISTORY: () => ({}),\n  CLOSE_HISTORY: () => ({}),\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/general/reducers.ts",
    "content": "import { Record } from 'immutable'\nimport { handleActions } from 'redux-actions'\n\nexport class GeneralState extends Record({\n  historyOpen: false,\n  fixedEndpoint: false,\n  endpoint: '',\n  configString: '',\n  envVars: {},\n}) {\n  historyOpen: boolean\n  fixedEndpoint: boolean\n  endpoint: string\n  configString: string\n  envVars: any\n}\n\nexport default handleActions(\n  {\n    OPEN_HISTORY: state => state.set('historyOpen', true),\n    CLOSE_HISTORY: state => state.set('historyOpen', false),\n    SET_ENDPOINT_DISABLED: (state, { payload: { value } }) =>\n      state.set('endpointDisabled', value),\n    SET_CONFIG_STRING: (state, { payload: { configString } }) =>\n      state.set('configString', configString),\n  },\n  new GeneralState(),\n)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/general/selectors.ts",
    "content": "const makeGeneralSelector = key => state => {\n  return state.general.get(key)\n}\n\nexport const getFixedEndpoint = makeGeneralSelector('fixedEndpoint')\nexport const getHistoryOpen = makeGeneralSelector('historyOpen')\nexport const getConfigString = makeGeneralSelector('configString')\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/history/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const { toggleHistoryItemStarring, addHistoryItem } = createActions({\n  TOGGLE_HISTORY_ITEM_STARRING: sessionId => ({ sessionId }),\n  ADD_HISTORY_ITEM: session => ({ session }),\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/history/reducers.ts",
    "content": "import { OrderedMap, List } from 'immutable'\nimport { handleActions } from 'redux-actions'\nimport * as cuid from 'cuid'\nimport { SessionStateProps } from '../sessions/reducers'\n\nexport type HistoryState = OrderedMap<string, SessionStateProps>\n\nexport const defaultHistoryState: HistoryState = OrderedMap({})\n\nexport default handleActions(\n  {\n    TOGGLE_HISTORY_ITEM_STARRING: (state, { payload: { sessionId } }) =>\n      state.setIn([sessionId, 'starred'], !state.getIn([sessionId, 'starred'])),\n    ADD_HISTORY_ITEM: (state, { payload: { session } }) => {\n      const id = cuid()\n      return state.slice(-40).set(\n        id,\n        session.merge({\n          id,\n          date: new Date(),\n          responses: List(),\n        }),\n      )\n    },\n  },\n  defaultHistoryState,\n)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/history/selectors.ts",
    "content": "import { createSelector } from 'reselect'\nimport { getSelectedWorkspace } from '../workspace/reducers'\n\nexport const getHistory = createSelector(\n  [getSelectedWorkspace],\n  state => state.history,\n)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/localStorage.ts",
    "content": "import { debounce } from 'lodash'\nimport { deserializePersistedState } from './workspace/deserialize'\n\nexport function serializeState(store) {\n  return debounce(\n    () => {\n      const state = store.getState()\n      if (!state.stateInjected) {\n        localStorage.setItem('graphql-playground', JSON.stringify(state))\n      }\n    },\n    300,\n    { trailing: true },\n  ) as any\n}\n\nexport function deserializeState() {\n  try {\n    // let before = performance.now()\n    const state = localStorage.getItem('graphql-playground')\n    if (state) {\n      // console.log(\n      //   `Needed ${performance.now() - before}ms to get ${\n      //     state.length\n      //   } bytes from localstorage`,\n      // )\n      // before = performance.now()\n      const json = JSON.parse(state)\n      // console.log(`Needed ${performance.now() - before}ms to parse state`)\n      // before = performance.now()\n      const result = deserializePersistedState(json) as any\n      // console.log(\n      //   `Needed ${performance.now() - before}ms to deserialize the parsed json`,\n      // )\n      return result\n    }\n  } catch (e) {\n    //\n  }\n  return undefined\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/rootSaga.ts",
    "content": "import { fecthingSagas } from './sessions/fetchingSagas'\nimport { sessionsSagas } from './sessions/sagas'\nimport { all, AllEffect } from 'redux-saga/effects'\nimport { sharingSagas } from './sharing/sharingSaga'\n\nexport default function* rootSaga() {\n  yield all([...sessionsSagas, ...fecthingSagas, ...sharingSagas])\n}\n\nexport { AllEffect }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts",
    "content": "import { ApolloLink, Operation, FetchResult, Observable } from 'apollo-link';\nimport { print, GraphQLError } from 'graphql';\nimport { Client } from 'graphql-ws';\n\nexport class WebSocketLink extends ApolloLink {\n\n    constructor(private client: Client) {\n        super();\n    }\n\n    public request(operation: Operation): Observable<FetchResult> {\n        return new Observable((sink) => {\n            return this.client.subscribe<FetchResult>(\n                { ...operation, query: print(operation.query) },\n                {\n                    next: sink.next.bind(sink),\n                    complete: sink.complete.bind(sink),\n                    error: (err) => {\n                        if (err instanceof Error) {\n                            sink.error(err);\n                        } else if (err instanceof CloseEvent) {\n                            sink.error(\n                                new Error(\n                                    `Socket closed with event ${err.code}` + err.reason\n                                        ? `: ${err.reason}` // reason will be available on clean closes\n                                        : '',\n                                ),\n                            );\n                        } else {\n                            sink.error(\n                                new Error(\n                                    (err as GraphQLError[])\n                                        .map(({ message }) => message)\n                                        .join(', '),\n                                ),\n                            );\n                        }\n                    },\n                },\n            );\n        });\n    }\n} \n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sessions/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const {\n  editQuery,\n  editVariables,\n  setOperationName,\n  editHeaders,\n  editEndpoint,\n  setVariableToType,\n  setOperations,\n  startQuery,\n  stopQuery,\n  setEditorFlex,\n  openQueryVariables,\n  closeQueryVariables,\n  setVariableEditorHeight,\n  setResponseTracingHeight,\n  setTracingSupported,\n  closeTracing,\n  openTracing,\n  closeVariables,\n  openVariables,\n  addResponse,\n  setResponse,\n  clearResponses,\n  openSettingsTab,\n  schemaFetchingSuccess,\n  schemaFetchingError,\n  setEndpointUnreachable,\n  renewStacks,\n  runQuery,\n  prettifyQuery,\n  fetchSchema,\n  updateQueryFacts,\n  runQueryAtPosition,\n  toggleTracing,\n  toggleVariables,\n  newSession,\n  newSessionFromQuery,\n  newFileTab,\n  closeTab,\n  closeSelectedTab,\n  editSettings,\n  saveSettings,\n  editConfig,\n  saveConfig,\n  editFile,\n  saveFile,\n  selectTab,\n  selectTabIndex,\n  selectNextTab,\n  selectPrevTab,\n  duplicateSession,\n  querySuccess,\n  queryError,\n  setSubscriptionActive,\n  setQueryTypes,\n  injectHeaders,\n  openConfigTab,\n  editName,\n  setResponseExtensions,\n  setCurrentQueryStartTime,\n  setCurrentQueryEndTime,\n  refetchSchema,\n  setScrollTop,\n  reorderTabs,\n} = createActions({\n  // simple property setting\n  EDIT_QUERY: query => ({ query }),\n  EDIT_HEADERS: simpleAction('headers'),\n  EDIT_ENDPOINT: simpleAction('endpoint'),\n  EDIT_VARIABLES: simpleAction('variables'),\n  SET_OPERATION_NAME: simpleAction('operationName'),\n  SET_VARIABLE_TO_TYPE: simpleAction('variableToType'),\n  SET_OPERATIONS: simpleAction('operations'),\n  SET_EDITOR_FLEX: simpleAction('editorFlex'),\n  EDIT_NAME: simpleAction('name'),\n\n  OPEN_QUERY_VARIABLES: () => ({ queryVariablesActive: true }),\n  CLOSE_QUERY_VARIABLES: () => ({ queryVariablesActive: false }),\n  SET_VARIABLE_EDITOR_HEIGHT: simpleAction('variableEditorHeight'),\n  SET_RESPONSE_TRACING_HEIGHT: simpleAction('responceTracingHeight'),\n  SET_TRACING_SUPPORTED: simpleAction('tracingSupported'),\n  SET_SUBSCRIPTION_ACTIVE: simpleAction('subscriptionActive'),\n  SET_QUERY_TYPES: simpleAction('queryTypes'),\n  SET_RESPONSE_EXTENSIONS: simpleAction('responseExtensions'),\n  SET_CURRENT_QUERY_START_TIME: simpleAction('currentQueryStartTime'),\n  SET_CURRENT_QUERY_END_TIME: simpleAction('currentQueryEndTime'),\n\n  UPDATE_QUERY_FACTS: simpleAction(),\n  PRETTIFY_QUERY: simpleAction(),\n  INJECT_HEADERS: (headers, endpoint) => ({ headers, endpoint }),\n\n  // setting multiple props\n  /*\n    this.setState({\n      responseTracingOpen: false,\n      responseTracingHeight: hadHeight,\n    } as State)\n  */\n  CLOSE_TRACING: simpleAction('responseTracingHeight'),\n  OPEN_TRACING: simpleAction('responseTracingHeight'),\n  TOGGLE_TRACING: simpleAction(),\n  // setting multiple props\n  /*\n    this.setState({\n      responseTracingOpen: false,\n      responseTracingHeight: hadHeight,\n    } as State)\n  */\n  CLOSE_VARIABLES: simpleAction('variableEditorHeight'),\n  OPEN_VARIABLES: simpleAction('variableEditorHeight'),\n  TOGGLE_VARIABLES: simpleAction(),\n\n  /*\n    a littlebit more complex state mutations\n  */\n  ADD_RESPONSE: (workspaceId, sessionId, response) => ({\n    workspaceId,\n    sessionId,\n    response,\n  }),\n  SET_RESPONSE: (workspaceId, sessionId, response) => ({\n    workspaceId,\n    sessionId,\n    response,\n  }),\n  CLEAR_RESPONSES: simpleAction(),\n\n  FETCH_SCHEMA: simpleAction(),\n  REFETCH_SCHEMA: simpleAction(),\n  SET_ENDPOINT_UNREACHABLE: simpleAction('endpoint'),\n  SET_SCROLL_TOP: (sessionId, scrollTop) => ({ sessionId, scrollTop }),\n  SCHEMA_FETCHING_SUCCESS: (endpoint, tracingSupported, isPollingSchema) => ({\n    endpoint,\n    tracingSupported,\n    isPollingSchema,\n  }),\n  /*\n        this.setState({\n          schema,\n          isReloadingSchema: false,\n          endpointUnreachable: false,\n          + tracingSupported\n        })\n  */\n  SCHEMA_FETCHING_ERROR: (endpoint, error) => ({ endpoint, error }),\n  /*\n\n      this.setState({\n        isReloadingSchema: false,\n        endpointUnreachable: true,\n      })\n  */\n\n  RENEW_STACKS: simpleAction(),\n  /*\n  GraphQLEditor.renewStacks()\n  */\n\n  RUN_QUERY: operationName => ({ operationName }),\n  QUERY_SUCCESS: simpleAction(),\n  QUERY_ERROR: simpleAction(),\n  RUN_QUERY_AT_POSITION: position => ({ position }),\n  START_QUERY: simpleAction('queryRunning', true),\n  STOP_QUERY: (sessionId, workspaceId) => ({ workspaceId, sessionId }),\n  /* GraphQLEditor.handleRunQuery */\n  OPEN_SETTINGS_TAB: () => ({}),\n  OPEN_CONFIG_TAB: () => ({}),\n  NEW_SESSION: (endpoint, reuseHeaders) => ({ endpoint, reuseHeaders }),\n  NEW_SESSION_FROM_QUERY: (query: string) => ({ query }),\n  NEW_FILE_TAB: (fileName: string, filePath: string, file: string) => ({\n    fileName,\n    filePath,\n    file,\n  }),\n  DUPLICATE_SESSION: simpleAction('session'),\n  CLOSE_SELECTED_TAB: () => ({}),\n  SELECT_NEXT_TAB: () => ({}),\n  SELECT_PREV_TAB: () => ({}),\n  SELECT_TAB: simpleAction('sessionId'),\n  SELECT_TAB_INDEX: simpleAction('index'),\n  CLOSE_TAB: simpleAction('sessionId'),\n  REORDER_TABS: (src, dest) => ({ src, dest }),\n\n  // files, settings, config\n  EDIT_SETTINGS: simpleAction(),\n  SAVE_SETTINGS: simpleAction(),\n  EDIT_CONFIG: simpleAction(),\n  SAVE_CONFIG: simpleAction(),\n  EDIT_FILE: simpleAction(),\n  SAVE_FILE: simpleAction(),\n})\n\nfunction simpleAction(key?: any, defaultValue?: any) {\n  return value => ({ [key]: value || defaultValue })\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts",
    "content": "import { ApolloLink, execute } from 'apollo-link'\nimport { parseHeaders } from '../../components/Playground/util/parseHeaders'\nimport { HttpLink } from 'apollo-link-http'\nimport { isSubscription } from '../../components/Playground/util/hasSubscription'\nimport {\n  takeLatest,\n  ForkEffect,\n  put,\n  select,\n  takeEvery,\n  take,\n} from 'redux-saga/effects'\nimport { eventChannel, END } from 'redux-saga'\nimport { makeOperation } from '../../components/Playground/util/makeOperation'\nimport {\n  setSubscriptionActive,\n  stopQuery,\n  startQuery,\n  addResponse,\n  setResponseExtensions,\n  setCurrentQueryStartTime,\n  setCurrentQueryEndTime,\n  setEndpointUnreachable,\n  clearResponses,\n  setResponse,\n} from './actions'\nimport {\n  getSelectedSession,\n  getSessionsState,\n  getParsedVariablesFromSession,\n} from './selectors'\nimport { SchemaFetcher } from '../../components/Playground/SchemaFetcher'\nimport { getSelectedWorkspaceId, getSettings } from '../workspace/reducers'\nimport * as cuid from 'cuid'\nimport { Session, ResponseRecord } from './reducers'\nimport { addHistoryItem } from '../history/actions'\nimport { safely } from '../../utils'\nimport { set } from 'immutable'\nimport { SubscriptionClient as SubscriptionClientSTWS } from 'subscriptions-transport-ws'\nimport { WebSocketLink as WebSocketLinkALW } from 'apollo-link-ws'\nimport { createClient as createSubscriptionClient, Client as SubscriptionClientGWS } from 'graphql-ws'\nimport { WebSocketLink as WebSocketLinkGW } from './WebSocketLink'\n\n// tslint:disable\nlet subscriptionEndpoint\n\nexport function setSubscriptionEndpoint(endpoint) {\n  subscriptionEndpoint = endpoint\n}\n\nexport interface LinkCreatorProps {\n  endpoint: string\n  headers?: Headers\n  credentials?: string\n  subscriptionTransport?: string\n}\n\nexport interface Headers {\n  [key: string]: string | number | null\n}\n\nconst isWSEndpoint = (endpoint: string): boolean => !!endpoint.match(/wss?/);\n\nexport const defaultLinkCreator = (\n  session: LinkCreatorProps,\n  subscriptionEndpoint?: string,\n): { link: ApolloLink; subscriptionClient?: SubscriptionClientGWS | SubscriptionClientSTWS } => {\n  \n  let connectionParams = {}\n  const { headers, credentials, subscriptionTransport } = session\n\n  if (headers) {\n    connectionParams = { ...headers }\n  }\n\n  const httpLink = new HttpLink({\n    uri: session.endpoint,\n    headers,\n    credentials,\n  })\n\n  // ws endpoint => graphql-ws default link\n  if (isWSEndpoint(session.endpoint)) {\n    const subscriptionClient = createSubscriptionClient({\n      retryAttempts: 1000,\n      retryWait: () => new Promise(resolve => setTimeout(resolve, 20000)),\n      lazy: true,\n      connectionParams,\n      url: session.endpoint,\n    })\n\n    return {\n      link: new WebSocketLinkGW(subscriptionClient),\n      subscriptionClient,\n    }\n  } \n\n  // http endpoint & graphql-ws => default link = http + graphql-ws subscriptions\n  if (subscriptionTransport === 'graphql-ws') {\n    const subscriptionClient = createSubscriptionClient({\n      retryWait: () => new Promise(resolve => setTimeout(resolve, 20000)),\n      lazy: true,\n      connectionParams,\n      url: subscriptionEndpoint || session.endpoint.replace('http', 'ws'),\n    })\n  \n    return {\n      subscriptionClient,\n      link: new WebSocketLinkGW(subscriptionClient)\n    }\n  }\n\n  // http endpoint => default link = http + subscriptions-transport-ws subscriptions\n  const subscriptionClient = new SubscriptionClientSTWS(\n    subscriptionEndpoint || session.endpoint.replace('http', 'ws'),\n    {\n      timeout: 20000,\n      lazy: true,\n      connectionParams,\n    }\n  )\n\n  const webSocketLink = new WebSocketLinkALW(subscriptionClient);\n\n  return {\n    link: ApolloLink.split(\n      operation => isSubscription(operation),\n      webSocketLink,\n      httpLink,\n    ),\n    subscriptionClient,\n  }\n}\n\nlet linkCreator = defaultLinkCreator\nexport let schemaFetcher: SchemaFetcher = new SchemaFetcher(linkCreator)\n;(window as any).schemaFetcher = schemaFetcher\n\nexport function setLinkCreator(newLinkCreator) {\n  if (newLinkCreator) {\n    linkCreator = newLinkCreator\n    schemaFetcher = new SchemaFetcher(newLinkCreator)\n  }\n}\n\nconst subscriptions = {}\n\nconst isSubscriptionClientSTWS = (\n  client: SubscriptionClientGWS | SubscriptionClientSTWS\n  ): client is SubscriptionClientSTWS => {\n  return !!(client as SubscriptionClientSTWS).onDisconnected\n}\n\nfunction* runQuerySaga(action) {\n  // run the query\n  const { operationName } = action.payload\n  const selectedWorkspaceId = yield select(getSelectedWorkspaceId)\n  const session: Session = yield select(getSelectedSession)\n  const request = {\n    query: session.query,\n    operationName,\n    variables: getParsedVariablesFromSession(session),\n  }\n  const operation = makeOperation(request)\n  const operationIsSubscription = isSubscription(operation)\n  const workspace = yield select(getSelectedWorkspaceId)\n  const settings = yield select(getSettings)\n  yield put(setSubscriptionActive(isSubscription(operation)))\n  yield put(startQuery())\n  let headers = parseHeaders(session.headers)\n  if (session.tracingSupported && session.responseTracingOpen) {\n    headers = set(headers, 'X-Apollo-Tracing', '1')\n  }\n  \n  const lol = {\n    endpoint: session.endpoint,\n    headers: {\n      ...settings['request.globalHeaders'],\n      ...headers,\n    },\n    subscriptionTransport: settings['subscriptions.protocol'],\n    credentials: settings['request.credentials'],\n  }\n\n  const { link, subscriptionClient } = linkCreator(lol, subscriptionEndpoint)\n  yield put(setCurrentQueryStartTime(new Date()))\n\n  let firstResponse = false\n  const channel = eventChannel(emitter => {\n    let closed = false\n    if (subscriptionClient && operationIsSubscription) {\n      const onDisconnect = () => {\n        closed = true\n        emitter({\n          error: new Error(\n            `Could not connect to websocket endpoint ${subscriptionEndpoint}. Please check if the endpoint url is correct.`,\n          ),\n        })\n        emitter(END)\n      }\n      if (isSubscriptionClientSTWS(subscriptionClient)) {\n        subscriptionClient.onDisconnected(onDisconnect)\n      } else {\n        subscriptionClient.on('closed', onDisconnect)\n      }\n    }\n    const subscription = execute(link, operation).subscribe({\n      next: function(value) {\n        emitter({ value })\n      },\n      error: error => {\n        emitter({ error })\n        emitter(END)\n      },\n      complete: () => {\n        emitter(END)\n      },\n    })\n\n    const unsubscribe = () => {\n      if (!closed) {\n        try {\n          subscription.unsubscribe()\n        } catch (e) {\n          console.error(e)\n        }\n      }\n    }\n\n    const key = `${workspace}~${session.id}`\n    subscriptions[key] = { unsubscribe }\n\n    return unsubscribe\n  })\n\n  try {\n    while (true) {\n      const { value, error } = yield take(channel)\n      if (value && value.extensions) {\n        const extensions = value.extensions\n        yield put(setResponseExtensions(extensions))\n        if (\n          value.extensions.tracing &&\n          settings['tracing.hideTracingResponse']\n        ) {\n          delete value.extensions.tracing\n        }\n      }\n      const response = new ResponseRecord({\n        date: JSON.stringify(value ? value : formatError(error), null, 2),\n        time: new Date(),\n        resultID: cuid(),\n      })\n      const errorMessage = extractMessage(error)\n      if (errorMessage === 'Failed to fetch') {\n        yield put(setEndpointUnreachable(session.endpoint))\n      }\n      if (operationIsSubscription) {\n        if (firstResponse) {\n          yield put(clearResponses())\n          firstResponse = false\n        }\n        yield put(addResponse(selectedWorkspaceId, session.id, response))\n      } else {\n        yield put(setResponse(selectedWorkspaceId, session.id, response))\n      }\n      yield put(addHistoryItem(session))\n    }\n  } finally {\n    yield put(setCurrentQueryEndTime(new Date()))\n    yield put(stopQuery(session.id, selectedWorkspaceId))\n  }\n}\n\nexport function formatError(error, fetchingSchema: boolean = false) {\n  const message = extractMessage(error)\n  if (message === 'Failed to fetch') {\n    const schemaMessage = fetchingSchema ? ' schema' : ''\n    return { error: `${message}${schemaMessage}. Please check your connection` }\n  }\n\n  try {\n    const ee = JSON.parse(message)\n    return ee\n  } catch (e) {\n    //\n  }\n\n  return { error: message }\n}\n\nfunction extractMessage(error) {\n  if (error instanceof Error) {\n    // Errors from apollo-link-http may include a \"result\" object, which is a JSON response from\n    // the server. We should surface that to the client\n    if (!!error['result'] && typeof error['result'] === 'object') {\n      return (error as any).result\n    }\n    return error.message\n  }\n\n  if (typeof error === 'string') {\n    return error\n  }\n\n  return error\n}\n\nfunction* stopQuerySaga(action) {\n  const { sessionId, workspaceId } = action.payload\n  const { sessions } = yield select(getSessionsState)\n  const session = sessions.get(sessionId)\n  const workspace = yield workspaceId || select(getSelectedWorkspaceId)\n\n  const key = `${workspace}~${session.id}`\n  const subscription = subscriptions[key]\n  if (subscription && subscription.unsubscribe) {\n    subscription.unsubscribe()\n  }\n  delete subscriptions[key]\n}\n\nexport const fecthingSagas = [\n  takeEvery('RUN_QUERY', safely(runQuerySaga)),\n  takeLatest('STOP_QUERY', safely(stopQuerySaga)),\n]\n\n// needed to fix typescript\nexport { ForkEffect }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sessions/reducers.ts",
    "content": "import { OrderedMap, Map, List, Record, merge } from 'immutable'\nimport { handleActions, combineActions } from 'redux-actions'\nimport {\n  editQuery,\n  editVariables,\n  editHeaders,\n  editEndpoint,\n  setEditorFlex,\n  openQueryVariables,\n  closeQueryVariables,\n  setVariableEditorHeight,\n  setResponseTracingHeight,\n  setTracingSupported,\n  setVariableToType,\n  setOperations,\n  setOperationName,\n  setSubscriptionActive,\n  startQuery,\n  setQueryTypes,\n  editName,\n  setResponseExtensions,\n  setCurrentQueryStartTime,\n  setCurrentQueryEndTime,\n} from './actions'\nimport { getSelectedSessionId } from './selectors'\nimport { getDefaultSession, defaultQuery } from '../../constants'\nimport * as cuid from 'cuid'\nimport { formatError } from './fetchingSagas'\nimport { arrayMove } from 'react-sortable-hoc'\n\nexport interface SessionStateProps {\n  sessions: OrderedMap<string, Session>\n  selectedSessionId: string\n  sessionCount: number\n  headers?: string\n}\n\nexport interface Tab {\n  endpoint: string\n  query: string\n  name?: string\n  variables?: string\n  responses?: string[]\n  headers?: { [key: string]: string }\n}\n\n// tslint:disable\nexport class Session extends Record(getDefaultSession('')) {\n  id: string\n  endpoint: string\n\n  query: string\n  file?: string\n  variables: string\n  responses?: List<ResponseRecord>\n  operationName?: string\n  queryRunning: boolean\n  subscriptionActive: boolean\n\n  // query facts\n  operations: List<OperationDefinition>\n  variableToType: VariableToType\n\n  // additional props that are interactive in graphiql, these are not represented in graphiqls state\n  queryTypes: QueryTypes\n  date: Date\n  hasMutation: boolean\n  hasSubscription: boolean\n  hasQuery: boolean\n\n  isFile?: boolean\n  starred?: boolean\n  name?: string\n  filePath?: string\n  selectedUserToken?: string\n  headers?: string\n  absolutePath?: string\n  isSettingsTab?: boolean\n  isConfigTab?: boolean\n\n  currentQueryStartTime?: Date\n  currentQueryEndTime?: Date\n\n  isReloadingSchema: boolean\n  isSchemaPendingUpdate: boolean\n\n  responseExtensions: any\n  queryVariablesActive: boolean\n  endpointUnreachable: boolean\n\n  // editor settings\n  editorFlex: number\n  variableEditorOpen: boolean\n  variableEditorHeight: number\n  responseTracingOpen: boolean\n  responseTracingHeight: number\n  nextQueryStartTime?: Date\n  tracingSupported?: boolean\n  docExplorerWidth: number\n  changed?: boolean\n  scrollTop?: number\n\n  toJSON() {\n    const obj = this.toObject()\n    const override: any = {\n      queryRunning: false,\n      subscriptionActive: false,\n      responseExtensions: {},\n    }\n    // dont serialize very big responses as the localStorage size is limited\n    if (\n      obj.responses &&\n      obj.responses.size > 0 &&\n      (obj.responses.size > 20 || obj.responses.get(0).date.length > 2000)\n    ) {\n      override.responses = List()\n    }\n    return merge(obj, override)\n  }\n}\nexport type VariableToType = Map<string, any>\n\nexport interface QueryTypes {\n  firstOperationName: string | null\n  subscription: boolean\n  query: boolean\n  mutation: boolean\n}\n\nexport interface OperationDefinition {\n  startLine: number\n  endLine: number\n  name: string\n}\nexport interface ResponseType {\n  resultID: string\n  date: string\n  time: Date\n}\n\nexport class ResponseRecord extends Record({\n  resultID: '',\n  date: '',\n  time: new Date(),\n  isSchemaError: false,\n}) {\n  resultID: string\n  date: string\n  time: Date\n  isSchemaError: boolean\n}\n\nfunction makeSession(endpoint = '') {\n  return new Session({ endpoint }).set('id', cuid())\n}\n\nexport function sessionFromTab(tab: Tab): Session {\n  return new Session({\n    ...tab,\n    headers: tab.headers ? JSON.stringify(tab.headers, null, 2) : '',\n    responses:\n      tab.responses && tab.responses.length > 0\n        ? List(tab.responses.map(r => new ResponseRecord({ date: r })))\n        : List(),\n  }).set('id', cuid())\n}\n\nexport class SessionState extends Record({\n  sessions: OrderedMap({}),\n  selectedSessionId: '',\n  sessionCount: 0,\n  headers: '',\n}) {\n  sessions: OrderedMap<string, Session>\n  selectedSessionId: string\n  sessionCount: number\n  headers: string\n}\n\nexport function makeSessionState(endpoint) {\n  const session = new Session({ endpoint: endpoint || '' })\n\n  return new SessionState({\n    sessions: OrderedMap({ [session.id]: session }),\n    selectedSessionId: session.id,\n    sessionCount: 1,\n  })\n}\n\nconst reducer = handleActions(\n  {\n    [combineActions(\n      editQuery,\n      editVariables,\n      editHeaders,\n      editEndpoint,\n      setEditorFlex,\n      openQueryVariables,\n      closeQueryVariables,\n      setVariableEditorHeight,\n      setResponseTracingHeight,\n      setTracingSupported,\n      setVariableToType,\n      setOperations,\n      setOperationName,\n      setSubscriptionActive,\n      startQuery,\n      setQueryTypes,\n      editName,\n      setResponseExtensions,\n      setCurrentQueryStartTime,\n      setCurrentQueryEndTime,\n    )]: (state, { payload }) => {\n      const keys = Object.keys(payload)\n      const keyName = keys.length === 1 ? keys[0] : keys[1]\n      const path = ['sessions', getSelectedSessionId(state), keyName]\n      return state.setIn(path, payload[keyName])\n    },\n    START_QUERY: state => {\n      return state\n        .setIn(['sessions', getSelectedSessionId(state), 'queryRunning'], true)\n        .setIn(\n          ['sessions', getSelectedSessionId(state), 'responseExtensions'],\n          undefined,\n        )\n    },\n    CLOSE_TRACING: (state, { payload: { responseTracingHeight } }) => {\n      return state.mergeDeepIn(\n        ['sessions', getSelectedSessionId(state)],\n        Map({ responseTracingHeight, responseTracingOpen: false }),\n      )\n    },\n    TOGGLE_TRACING: state => {\n      const path = [\n        'sessions',\n        getSelectedSessionId(state),\n        'responseTracingOpen',\n      ]\n      return state.setIn(path, !state.getIn(path))\n    },\n    OPEN_TRACING: (state, { payload: { responseTracingHeight } }) => {\n      return state.mergeDeepIn(\n        ['sessions', getSelectedSessionId(state)],\n        Map({ responseTracingHeight, responseTracingOpen: true }),\n      )\n    },\n    CLOSE_VARIABLES: (state, { payload: { variableEditorHeight } }) => {\n      return state.mergeDeepIn(\n        ['sessions', getSelectedSessionId(state)],\n        Map({ variableEditorHeight, variableEditorOpen: false }),\n      )\n    },\n    OPEN_VARIABLES: (state, { payload: { variableEditorHeight } }) => {\n      return state.mergeDeepIn(\n        ['sessions', getSelectedSessionId(state)],\n        Map({ variableEditorHeight, variableEditorOpen: true }),\n      )\n    },\n    TOGGLE_VARIABLES: state => {\n      const path = [\n        'sessions',\n        getSelectedSessionId(state),\n        'variableEditorOpen',\n      ]\n      return state.setIn(path, !state.getIn(path))\n    },\n    ADD_RESPONSE: (state, { payload: { response, sessionId } }) => {\n      return state.updateIn(['sessions', sessionId, 'responses'], responses =>\n        responses.push(response),\n      )\n    },\n    SET_RESPONSE: (state, { payload: { response, sessionId } }) => {\n      return state.setIn(['sessions', sessionId, 'responses'], List([response]))\n    },\n    CLEAR_RESPONSES: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'responses'],\n        List(),\n      )\n    },\n    FETCH_SCHEMA: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'isReloadingSchema'],\n        true,\n      )\n    },\n    REFETCH_SCHEMA: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'isReloadingSchema'],\n        true,\n      )\n    },\n    STOP_QUERY: (state, { payload: { sessionId } }) => {\n      return state.mergeIn(['sessions', sessionId], {\n        queryRunning: false,\n        subscriptionActive: false,\n      })\n    },\n    SET_SCROLL_TOP: (state, { payload: { sessionId, scrollTop } }) => {\n      if (state.sessions.get(sessionId)) {\n        return state.setIn(['sessions', sessionId, 'scrollTop'], scrollTop)\n      }\n      return state\n    },\n    SCHEMA_FETCHING_SUCCESS: (state, { payload }) => {\n      const newSessions = state.get('sessions').map((session: Session) => {\n        if (session.endpoint === payload.endpoint) {\n          // if there was an error, clear it away\n          const data: any = {\n            tracingSupported: payload.tracingSupported,\n            isReloadingSchema: false,\n            endpointUnreachable: false,\n          }\n          const response = session.responses ? session.responses!.first() : null\n          if (\n            response &&\n            session.responses!.size === 1 &&\n            // @ts-ignore\n            response.isSchemaError\n          ) {\n            data.responses = List([])\n          }\n          return session.merge(Map(data))\n        }\n        return session\n      })\n      return state.set('sessions', newSessions)\n    },\n    SET_ENDPOINT_UNREACHABLE: (state, { payload }) => {\n      const newSessions = state.get('sessions').map((session, sessionId) => {\n        if (session.get('endpoint') === payload.endpoint) {\n          return session.merge(\n            Map({\n              endpointUnreachable: true,\n            }),\n          )\n        }\n        return session\n      })\n      return state.set('sessions', newSessions)\n    },\n    SCHEMA_FETCHING_ERROR: (state, { payload }) => {\n      const newSessions = state.get('sessions').map((session, sessionId) => {\n        if (session.get('endpoint') === payload.endpoint) {\n          let { responses } = session\n\n          // Only override the responses if there is one or zero and that one is a schemaError\n          // Don't override user's responses!\n          if (responses.size <= 1) {\n            let response = session.responses ? session.responses!.first() : null\n            if (!response || response.isSchemaError) {\n              response = new ResponseRecord({\n                resultID: cuid(),\n                isSchemaError: true,\n                date: JSON.stringify(formatError(payload.error, true), null, 2),\n                time: new Date(),\n              })\n            }\n            responses = List([response])\n          }\n\n          return session.merge(\n            Map({\n              isReloadingSchema: false,\n              endpointUnreachable: true,\n              responses,\n            }),\n          )\n        }\n        return session\n      })\n      return state.set('sessions', newSessions)\n    },\n    SET_SELECTED_SESSION_ID: (state, { payload: { sessionId } }) =>\n      state.set('selectedSessionId', sessionId),\n    OPEN_SETTINGS_TAB: (state: any) => {\n      let newState = state\n      let settingsTab = state.sessions.find(value =>\n        value.get('isSettingsTab', false),\n      )\n      if (!settingsTab) {\n        settingsTab = makeSession().merge({\n          isSettingsTab: true,\n          isFile: true,\n          name: 'Settings',\n          changed: false,\n        })\n        newState = newState.setIn(['sessions', settingsTab.id], settingsTab)\n      }\n      return newState.set('selectedSessionId', settingsTab.id)\n    },\n    OPEN_CONFIG_TAB: state => {\n      let newState = state\n      let configTab = state.sessions.find(value =>\n        value.get('isConfigTab', false),\n      )\n      if (!configTab) {\n        configTab = makeSession().merge({\n          isConfigTab: true,\n          isFile: true,\n          name: 'GraphQL Config',\n          changed: false,\n        })\n        newState = newState.setIn(['sessions', configTab.id], configTab)\n      }\n      return newState.set('selectedSessionId', configTab.id)\n    },\n    NEW_FILE_TAB: (state, { payload: { fileName, filePath, file } }) => {\n      let newState = state\n      let fileTab = state.sessions.find(\n        value => value.get('name', '') === fileName,\n      )\n      if (!fileTab) {\n        fileTab = makeSession().merge({\n          isFile: true,\n          name: fileName,\n          changed: false,\n          file,\n          filePath,\n        })\n        newState = newState.setIn(['sessions', fileTab.id], fileTab)\n      }\n      return newState\n        .set('selectedSessionId', fileTab.id)\n        .set('sessionCount', newState.sessions.size)\n    },\n    NEW_SESSION: (state, { payload: { reuseHeaders, endpoint } }) => {\n      const currentSession = state.sessions.first()\n      const newSession: any = {\n        query: '',\n        isReloadingSchema: currentSession.isReloadingSchema,\n        endpointUnreachable: currentSession.endpointUnreachable,\n      }\n      if (currentSession.endpointUnreachable) {\n        newSession.responses = currentSession.responses\n      }\n      let session = makeSession(endpoint || currentSession.endpoint).merge(\n        newSession,\n      )\n      if (reuseHeaders) {\n        const selectedSessionId = getSelectedSessionId(state)\n        const currentSession = state.sessions.get(selectedSessionId)\n        session = session.set('headers', currentSession.headers)\n      } else {\n        session = session.set('headers', state.headers)\n      }\n      return state\n        .setIn(['sessions', session.id], session)\n        .set('selectedSessionId', session.id)\n        .set('sessionCount', state.sessions.size + 1)\n    },\n    // inject headers is used for graphql config\n    // it makes sure, that there definitely is a tab open with the correct header\n    INJECT_HEADERS: (state, { payload: { headers, endpoint } }) => {\n      // if there are no headers to inject, there's nothing to do\n      if (!headers || headers === '' || Object.keys(headers).length === 0) {\n        return state\n      }\n      const headersString =\n        typeof headers === 'string' ? headers : JSON.stringify(headers, null, 2)\n      const selectedSessionId = getSelectedSessionId(state)\n      let newState = state.set('headers', headersString)\n      const currentSession = state.sessions.get(selectedSessionId)\n\n      if (currentSession.headers === headersString) {\n        return newState\n      }\n\n      if (currentSession.query === defaultQuery) {\n        return newState.setIn(\n          ['sessions', selectedSessionId, 'headers'],\n          headersString,\n        )\n      }\n\n      const session = makeSession(endpoint).set('headers', headersString)\n\n      return newState\n        .setIn(['sessions', session.id], session)\n        .set('selectedSessionId', session.id)\n        .set('sessionCount', state.sessions.size + 1)\n    },\n    DUPLICATE_SESSION: (state, { payload: { session } }) => {\n      const newSession = session.set('id', cuid())\n      return state\n        .setIn(['sessions', newSession.id], newSession)\n        .set('selectedSessionId', newSession.id)\n        .set('sessionCount', state.sessions.size + 1)\n    },\n    NEW_SESSION_FROM_QUERY: (state, { payload: { query } }) => {\n      const session = makeSession().set('query', query)\n      return state\n        .setIn(['sessions', session.id], session)\n        .set('sessionCount', state.sessions.size + 1)\n    },\n    CLOSE_SELECTED_TAB: state => {\n      const selectedSessionId = getSelectedSessionId(state)\n      return closeTab(state, selectedSessionId).set(\n        'sessionCount',\n        state.sessions.size - 1,\n      )\n    },\n    SELECT_NEXT_TAB: state => {\n      const selectedSessionId = getSelectedSessionId(state)\n      const count = state.sessions.size\n      const keys = state.sessions.keySeq()\n      const index = keys.indexOf(selectedSessionId)\n      if (index + 1 < count) {\n        return state.set('selectedSessionId', keys.get(index + 1))\n      }\n      return state.set('selectedSessionId', keys.get(0))\n    },\n    SELECT_PREV_TAB: state => {\n      const selectedSessionId = getSelectedSessionId(state)\n      const count = state.sessions.size\n      const keys = state.sessions.keySeq()\n      const index = keys.indexOf(selectedSessionId)\n      if (index - 1 >= 0) {\n        return state.set('selectedSessionId', keys.get(index - 1))\n      }\n      return state.set('selectedSessionId', keys.get(count - 1))\n    },\n    SELECT_TAB_INDEX: (state, { payload: { index } }) => {\n      const keys = state.sessions.keySeq()\n      return state.set('selectedSessionId', keys.get(index))\n    },\n    SELECT_TAB: (state, { payload: { sessionId } }) => {\n      return state.set('selectedSessionId', sessionId)\n    },\n    CLOSE_TAB: (state, { payload: { sessionId } }) => {\n      return closeTab(state, sessionId).set(\n        'sessionCount',\n        state.sessions.size - 1,\n      )\n    },\n    REORDER_TABS: (state, { payload: { src, dest } }) => {\n      const seq = state.sessions.toIndexedSeq()\n\n      const indexes: number[] = []\n      for (let i = 0; i < seq.size; i++) indexes.push(i)\n      const newIndexes = arrayMove(indexes, src, dest)\n\n      let newSessions = OrderedMap()\n      for (let i = 0; i < seq.size; i++) {\n        const ndx = newIndexes[i]\n        const val = seq.get(ndx)\n        newSessions = newSessions.set(val.id, val)\n      }\n      return state.set('sessions', newSessions)\n    },\n    EDIT_SETTINGS: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'changed'],\n        true,\n      )\n    },\n    SAVE_SETTINGS: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'changed'],\n        false,\n      )\n    },\n    EDIT_CONFIG: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'changed'],\n        true,\n      )\n    },\n    SAVE_CONFIG: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'changed'],\n        false,\n      )\n    },\n    EDIT_FILE: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'changed'],\n        true,\n      )\n    },\n    SAVE_FILE: state => {\n      return state.setIn(\n        ['sessions', getSelectedSessionId(state), 'changed'],\n        false,\n      )\n    },\n  },\n  makeSessionState(''),\n)\n\n// add a self-healing wrapper to clean up broken states\nexport default (state, action) => {\n  const newState: SessionState = reducer(state, action)\n  if (newState.selectedSessionId === '' && state.sessions.size > 0) {\n    return newState.set('selectedSessionId', state.sessions.first().id)\n  }\n  return newState\n}\n\nfunction closeTab(state, sessionId) {\n  const length = state.sessions.size\n  const keys = state.sessions.keySeq()\n  let newState = state.removeIn(['sessions', sessionId])\n  const session = state.sessions.get(sessionId)\n  // if there is only one session, delete it and replace it by a new one\n  // and keep the endpoint & headers of the last one\n  if (length === 1) {\n    const newSessionData: any = {\n      query: '',\n      headers: session.headers,\n      isReloadingSchema: session.isReloadingSchema,\n      endpointUnreachable: session.endpointUnreachable,\n    }\n    if (session.endpointUnreachable) {\n      newSessionData.responses = session.responses\n    }\n    const newSession = makeSession(session.endpoint).merge(newSessionData)\n    newState = newState.set('selectedSessionId', newSession.id)\n    return newState.setIn(['sessions', newSession.id], newSession)\n  }\n  const selectedSessionId = getSelectedSessionId(state)\n  const sessionIndex = keys.indexOf(sessionId)\n  // if the session to be closed is selected, unselect it\n  if (selectedSessionId === sessionId) {\n    const leftNeighbour = sessionIndex - 1\n    // if its the first session on the left, take the right neighbour\n    if (leftNeighbour < 0) {\n      return newState.set('selectedSessionId', keys.get(1))\n    }\n    return newState.set('selectedSessionId', keys.get(leftNeighbour))\n  } else {\n    // otherwise the old selected session still can be selected, only the session has to be removed\n    return newState\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sessions/sagas.ts",
    "content": "import {\n  takeLatest,\n  ForkEffect,\n  delay,\n  select,\n  takeEvery,\n  put,\n} from 'redux-saga/effects'\nimport { getSelectedSession, getIsPollingSchema } from './selectors'\nimport getSelectedOperationName from '../../components/Playground/util/getSelectedOperationName'\nimport { getQueryFacts } from '../../components/Playground/util/getQueryFacts'\nimport { fromJS, is } from 'immutable'\nimport {\n  editQuery,\n  setVariableToType,\n  setOperations,\n  setOperationName,\n  schemaFetchingSuccess,\n  schemaFetchingError,\n  // fetchSchema,\n  runQuery,\n  setTracingSupported,\n  setQueryTypes,\n  refetchSchema,\n  fetchSchema,\n} from './actions'\nimport { getRootMap, getNewStack } from '../../components/Playground/util/stack'\nimport { DocsSessionState } from '../docs/reducers'\nimport { setStacks } from '../docs/actions'\nimport { HistoryState } from '../history/reducers'\nimport { addHistoryItem } from '../history/actions'\nimport { schemaFetcher } from './fetchingSagas'\nimport { getSelectedWorkspace, getSettings } from '../workspace/reducers'\nimport { getSessionDocsState } from '../docs/selectors'\nimport { getQueryTypes } from '../../components/Playground/util/getQueryTypes'\nimport { parse } from 'graphql'\nimport { Session } from './reducers'\nimport { safely, prettify } from '../../utils'\nimport * as queryString from 'query-string'\nimport { parseHeaders } from '../../components/Playground/util/parseHeaders'\n\nfunction* setQueryFacts() {\n  // debounce by 100 ms\n  yield delay(100)\n  const session: Session = yield select(getSelectedSession)\n  const { schema } = yield schemaFetcher.fetch(session)\n  try {\n    const ast = parse(session.query)\n    const queryFacts = getQueryFacts(schema, ast)\n\n    if (queryFacts) {\n      const immutableQueryFacts = fromJS(queryFacts)\n      const operationName = getSelectedOperationName(\n        session.operations,\n        session.operationName,\n        immutableQueryFacts.operations,\n      )\n      if (\n        !is(immutableQueryFacts.get('variableToType'), session.variableToType)\n      ) {\n        // set variableToType\n        yield put(setVariableToType(immutableQueryFacts.get('variableToType')))\n      }\n      if (!is(immutableQueryFacts.get('operations'), session.operations)) {\n        // set operations\n        yield put(setOperations(immutableQueryFacts.get('operations')))\n      }\n      if (operationName !== session.operationName) {\n        yield put(setOperationName(operationName))\n      }\n    }\n\n    const queryTypes = getQueryTypes(ast)\n    yield put(setQueryTypes(queryTypes))\n  } catch (e) {\n    const queryTypes = getQueryTypes(null)\n    yield put(setQueryTypes(queryTypes))\n  }\n}\n\nfunction* reflectQueryToUrl({ payload }) {\n  // debounce by 100 ms\n  yield delay(100)\n  if (!location.search.includes('query')) {\n    return\n  }\n\n  const params = queryString.parse(location.search)\n  if (typeof params.query !== 'undefined') {\n    const newSearch = queryString.stringify({\n      ...params,\n      query: payload.query,\n    })\n    const url = `${location.origin}${location.pathname}?${newSearch}`\n    window.history.replaceState(\n      {},\n      document.getElementsByTagName('title')[0].innerHTML,\n      url,\n    )\n  }\n}\n\nfunction* runQueryAtPosition(action) {\n  const { position } = action.payload\n  const session: Session = yield select(getSelectedSession)\n  if (session.operations) {\n    let operationName\n    const operations = session.operations.toJS()\n    operations.forEach((operation: any) => {\n      if (\n        operation.loc &&\n        operation.loc.start <= position &&\n        operation.loc.end >= position\n      ) {\n        operationName = operation.name && operation.name.value\n      }\n    })\n    if (operationName) {\n      yield put(runQuery(operationName))\n    } else {\n      yield put(runQuery())\n    }\n  } else {\n    yield put(runQuery())\n  }\n}\n\nfunction* getSessionWithCredentials() {\n  const session = yield select(getSelectedSession)\n  const settings = yield select(getSettings)\n  const combinedHeaders = {\n    ...settings['request.globalHeaders'],\n    ...parseHeaders(session.headers),\n  }\n\n  return {\n    endpoint: session.endpoint,\n    headers: JSON.stringify(combinedHeaders),\n    credentials: settings['request.credentials'],\n  }\n}\n\nfunction* fetchSchemaSaga() {\n  const session: Session = yield getSessionWithCredentials()\n  try {\n    yield schemaFetcher.fetch(session)\n    yield put(\n      schemaFetchingSuccess(\n        session.endpoint,\n        null,\n        yield select(getIsPollingSchema),\n      ),\n    )\n  } catch (e) {\n    yield put(schemaFetchingError(session.endpoint))\n    yield delay(5000)\n    yield put(fetchSchema())\n  }\n}\n\nfunction* refetchSchemaSaga() {\n  const session: Session = yield getSessionWithCredentials()\n  try {\n    yield schemaFetcher.refetch(session)\n    yield put(\n      schemaFetchingSuccess(\n        session.endpoint,\n        null,\n        yield select(getIsPollingSchema),\n      ),\n    )\n  } catch (e) {\n    yield put(schemaFetchingError(session.endpoint))\n    yield delay(5000)\n    yield put(refetchSchema())\n  }\n}\n\nlet lastSchema\n\nfunction* renewStacks() {\n  const session: Session = yield select(getSelectedSession)\n  const fetchSession = yield getSessionWithCredentials()\n  const docs: DocsSessionState = yield select(getSessionDocsState)\n  const result = yield schemaFetcher.fetch(fetchSession)\n  const { schema, tracingSupported } = result\n  if (schema && (!lastSchema || lastSchema !== schema)) {\n    const rootMap = getRootMap(schema)\n    const stacks = docs.navStack\n      .map(stack => getNewStack(rootMap, schema, stack))\n      .filter(s => s)\n    yield put(setStacks(session.id, stacks))\n    yield put(setTracingSupported(tracingSupported))\n    lastSchema = schema\n  }\n}\n\nfunction* addToHistory({ payload }) {\n  const { sessionId } = payload\n  const workspace = yield select(getSelectedWorkspace)\n  const session = workspace.getIn(['sessions', sessionId])\n\n  const history: HistoryState = workspace.get('history')\n\n  const exists = history.toKeyedSeq().find(item => is(item, session))\n  if (!exists) {\n    yield put(addHistoryItem(session))\n  }\n}\n\nfunction* prettifyQuery() {\n  const { query } = yield select(getSelectedSession)\n  const settings = yield select(getSettings)\n  try {\n    const prettyQuery = prettify(query, {\n      printWidth: settings['prettier.printWidth'],\n      tabWidth: settings['prettier.tabWidth'],\n      useTabs: settings['prettier.useTabs'],\n    })\n    yield put(editQuery(prettyQuery))\n  } catch (e) {\n    // TODO show errors somewhere\n    // tslint:disable-next-line\n    console.log(e)\n  }\n}\n\nexport const sessionsSagas = [\n  takeLatest('GET_QUERY_FACTS', safely(setQueryFacts)),\n  takeLatest('SET_OPERATION_NAME', safely(setQueryFacts)),\n  takeEvery('EDIT_QUERY', safely(setQueryFacts)),\n  takeEvery('EDIT_QUERY', safely(reflectQueryToUrl)),\n  takeEvery('RUN_QUERY_AT_POSITION', safely(runQueryAtPosition)),\n  takeLatest('FETCH_SCHEMA', safely(fetchSchemaSaga)),\n  takeLatest('REFETCH_SCHEMA', safely(refetchSchemaSaga)),\n  takeLatest('SCHEMA_FETCHING_SUCCESS', safely(renewStacks)),\n  takeEvery('QUERY_SUCCESS' as any, safely(addToHistory)),\n  takeLatest('PRETTIFY_QUERY', safely(prettifyQuery)),\n]\n\n// needed to fix typescript\nexport { ForkEffect }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sessions/selectors.ts",
    "content": "import { createSelector } from 'reselect'\nimport { makeWorkspace } from '../workspace/reducers'\n\nfunction getSelectedWorkspaceId(state) {\n  return state.get('selectedWorkspace')\n}\nfunction getSelectedWorkspace(state) {\n  return (\n    state.getIn(['workspaces', getSelectedWorkspaceId(state)]) ||\n    makeWorkspace('')\n  )\n}\n\nexport const getSessionsState = createSelector(\n  [getSelectedWorkspace],\n  workspace => workspace.get('sessions'),\n)\n\nexport const getSelectedSession = createSelector([getSessionsState], state => {\n  const id = getSelectedSessionId(state)\n  const session = state.getIn(['sessions', id])\n  return session\n})\n\nexport const getSelectedSessionId = state =>\n  state.selectedSessionId && state.selectedSessionId !== ''\n    ? state.selectedSessionId\n    : state.sessions.first().id\n\nexport const getSelectedSessionIdFromRoot = createSelector(\n  [getSelectedSession],\n  state => state.get('id'),\n)\n\nconst makeSessionSelector = prop => {\n  return createSelector([getSelectedSession], session => session.get(prop))\n}\n\nexport const getScrollTop = makeSessionSelector('scrollTop')\nexport const getEndpoint = makeSessionSelector('endpoint')\nexport const getQuery = makeSessionSelector('query')\nexport const getFile = makeSessionSelector('file')\nexport const getVariables = makeSessionSelector('variables')\nexport const getResponses = makeSessionSelector('responses')\nexport const getOperationName = makeSessionSelector('operationName')\nexport const getQueryRunning = makeSessionSelector('queryRunning')\nexport const getSubscriptionActive = makeSessionSelector('subscriptionActive')\nexport const getOperations = makeSessionSelector('operations')\nexport const getVariableToType = makeSessionSelector('variableToType')\nexport const getQueryTypes = makeSessionSelector('queryTypes')\nexport const getDate = makeSessionSelector('date')\nexport const getHasMutation = makeSessionSelector('hasMutation')\nexport const getHasSubscription = makeSessionSelector('hasSubscription')\nexport const getHasQuery = makeSessionSelector('hasQuery')\nexport const getIsFile = makeSessionSelector('isFile')\nexport const getStarred = makeSessionSelector('starred')\nexport const getName = makeSessionSelector('name')\nexport const getFilePath = makeSessionSelector('filePath')\nexport const getSelectedUserToken = makeSessionSelector('selectedUserToken')\nexport const getHeaders = makeSessionSelector('headers')\nexport const getHasChanged = makeSessionSelector('hasChanged')\nexport const getAbsolutePath = makeSessionSelector('absolutePath')\nexport const getIsSettingsTab = makeSessionSelector('isSettingsTab')\nexport const getIsConfigTab = makeSessionSelector('isConfigTab')\nexport const getCurrentQueryStartTime = makeSessionSelector(\n  'currentQueryStartTime',\n)\nexport const getCurrentQueryEndTime = makeSessionSelector('currentQueryEndTime')\nexport const getIsReloadingSchema = makeSessionSelector('isReloadingSchema')\nexport const getIsPollingSchema = createSelector(\n  [getEndpoint, getSettings],\n  (endpoint, settings) => {\n    const json = JSON.parse(settings)\n    try {\n      const isPolling =\n        json['schema.polling.enable'] &&\n        endpoint.match(`/${json['schema.polling.endpointFilter']}`) &&\n        true\n      return isPolling\n    } catch (e) {\n      return false\n    }\n  },\n)\n\nexport const getResponseExtensions = makeSessionSelector('responseExtensions')\nexport const getQueryVariablesActive = makeSessionSelector(\n  'queryVariablesActive',\n)\nexport const getEndpointUnreachable = makeSessionSelector('endpointUnreachable')\nexport const getEditorFlex = makeSessionSelector('editorFlex')\nexport const getVariableEditorOpen = makeSessionSelector('variableEditorOpen')\nexport const getVariableEditorHeight = makeSessionSelector(\n  'variableEditorHeight',\n)\nexport const getResponseTracingOpen = makeSessionSelector('responseTracingOpen')\nexport const getResponseTracingHeight = makeSessionSelector(\n  'responseTracingHeight',\n)\nexport const getDocExplorerWidth = makeSessionSelector('docExplorerWidth')\nexport const getNextQueryStartTime = makeSessionSelector('nextQueryStartTime')\nexport const getTracingSupported = makeSessionSelector('tracingSupported')\n\nfunction getSettings(state) {\n  return state.getIn(['settingsString'])\n}\n\nexport const getTabWidth = createSelector([getSettings], settings => {\n  try {\n    const json = JSON.parse(settings)\n    return json['prettier.tabWidth'] || 2\n  } catch (e) {\n    //\n  }\n\n  return 2\n})\n\nexport const getUseTabs = createSelector([getSettings], settings => {\n  try {\n    const json = JSON.parse(settings)\n    return json['prettier.useTabs'] || false\n  } catch (e) {\n    //\n  }\n\n  return false\n})\n\nexport const getHeadersCount = createSelector([getHeaders], headers => {\n  try {\n    const json = JSON.parse(headers)\n    return Object.keys(json).length\n  } catch (e) {\n    //\n  }\n\n  return 0\n})\n\nexport const getParsedHeaders = createSelector(\n  [getSelectedSession],\n  getParsedHeadersFromSession,\n)\n\nexport function getParsedHeadersFromSession(headers) {\n  try {\n    const json = JSON.parse(headers)\n    return json\n  } catch (e) {\n    //\n  }\n\n  return {}\n}\n\nexport const getParsedVariables = createSelector(\n  [getSelectedSession],\n  getParsedVariablesFromSession,\n)\n\nexport function getParsedVariablesFromSession(session) {\n  const variables = session.variables\n\n  try {\n    const json = JSON.parse(variables)\n    return json\n  } catch (e) {\n    //\n  }\n\n  return {}\n}\n\nexport const getTracing = createSelector(\n  [getResponseExtensions],\n  extensions => extensions && extensions.tracing,\n)\n\nexport const getSessionsArray = createSelector([getSessionsState], state => {\n  const array = state\n    .get('sessions')\n    .toArray()\n    .map(arr => arr[1])\n\n  return array\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sharing/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const {\n  share,\n  toggleShareHistory,\n  toggleShareHeaders,\n  toggleShareAllTabs,\n  setShareUrl,\n} = createActions({\n  TOGGLE_SHARE_HISTORY: () => ({}),\n  TOGGLE_SHARE_HEADERS: () => ({}),\n  TOGGLE_SHARE_ALL_TABS: () => ({}),\n  SHARE: () => ({}),\n  SET_SHARE_URL: shareUrl => ({ shareUrl }),\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sharing/reducers.ts",
    "content": "import { Record } from 'immutable'\nimport { handleActions } from 'redux-actions'\n\nexport class SharingState extends Record({\n  history: false,\n  headers: true,\n  allTabs: true,\n  shareUrl: null,\n}) {\n  history: boolean\n  headers: boolean\n  allTabs: boolean\n  shareUrl: any // go away typescript\n}\n\nexport default handleActions(\n  {\n    TOGGLE_SHARE_HISTORY: state => state.set('history', !state.history),\n    TOGGLE_SHARE_HEADERS: state => state.set('headers', !state.headers),\n    TOGGLE_SHARE_ALL_TABS: state => state.set('allTabs', !state.allTabs),\n    SET_SHARE_URL: (state, { payload: { shareUrl } }) =>\n      state.set('shareUrl', shareUrl),\n  },\n  new SharingState(),\n)\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sharing/selectors.ts",
    "content": "import { createSelector } from 'reselect'\nimport { getSelectedWorkspace } from '../workspace/reducers'\n\nexport const getSharingState = createSelector([getSelectedWorkspace], state => {\n  return state.sharing\n})\n\nconst makeSharingSelector = key =>\n  createSelector([getSharingState], state => {\n    return state.get(key)\n  })\n\nexport const getSharingHistory = makeSharingSelector('history')\nexport const getSharingHeaders = makeSharingSelector('headers')\nexport const getSharingAllTabs = makeSharingSelector('allTabs')\nexport const getShareUrl = makeSharingSelector('shareUrl')\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/sharing/sharingSaga.ts",
    "content": "import { takeEvery, ForkEffect, select, put } from 'redux-saga/effects'\nimport { getEndpoint } from '../sessions/selectors'\nimport { setShareUrl } from './actions'\nimport * as cuid from 'cuid'\nimport { getSharingState } from './selectors'\nimport { Map } from 'immutable'\nimport { safely } from '../../utils'\n\nfunction* share() {\n  const state = yield makeSharingState()\n  const endpoint = yield select(getEndpoint)\n  const res = yield fetch('https://api.graphqlbin.com/', {\n    method: 'post',\n    headers: {\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({\n      query: `\n        mutation ($session: String! $endpoint: String!) {\n          addSession(session: $session endpoint: $endpoint) {\n            id\n          }\n        }\n      `,\n      variables: {\n        session: JSON.stringify(state),\n        endpoint,\n      },\n    }),\n  }).then(data => data.json())\n\n  const shareUrl = `https://graphqlbin.com/v2/${res.data.addSession.id}`\n  yield put(setShareUrl(shareUrl))\n}\n\nfunction* makeSharingState() {\n  let state = yield select()\n  const sharing = yield select(getSharingState)\n\n  const id = cuid()\n  state = state\n    .update('workspaces', w =>\n      w.filter((workspace, key) => key === state.selectedWorkspace),\n    )\n    .set('selectedWorkspace', `${id}~${state.selectedWorkspace}`)\n    .update('workspaces', w => w.mapKeys(k => `${id}~${k}`))\n\n  const selectedSessionId = state.workspaces.get(state.selectedWorkspace)\n    .sessions.selectedSessionId\n\n  if (!sharing.allTabs) {\n    state = state\n      .updateIn(\n        ['workspaces', state.selectedWorkspace, 'sessions', 'sessions'],\n        sessions => sessions.filter((value, key) => key === selectedSessionId),\n      )\n      .setIn(\n        ['workspaces', state.selectedWorkspace, 'sessions', 'sessionCount'],\n        1,\n      )\n  }\n\n  if (!sharing.headers) {\n    state = state.updateIn(\n      ['workspaces', state.selectedWorkspace, 'sessions', 'sessions'],\n      sessions => sessions.map(session => session.set('headers', '')),\n    )\n  }\n\n  if (!sharing.history) {\n    state = state.setIn(\n      ['workspaces', state.selectedWorkspace, 'history'],\n      Map(),\n    )\n  }\n\n  return state\n}\n\nexport const sharingSagas = [takeEvery('SHARE', safely(share))]\n\n// needed to fix typescript\nexport { ForkEffect }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/workspace/actions.ts",
    "content": "import { createActions } from 'redux-actions'\n\nexport const {\n  selectWorkspace,\n  initState,\n  injectState,\n  injectTabs,\n} = createActions({\n  SELECT_WORKSPACE: workspace => ({ workspace }),\n  INIT_STATE: (workspaceId, endpoint) => ({ workspaceId, endpoint }),\n  INJECT_STATE: state => ({ state }),\n  INJECT_TABS: tabs => ({ tabs }),\n})\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/workspace/deserialize.ts",
    "content": "import { DocsSession } from '../docs/reducers'\nimport { Session, SessionState, ResponseRecord } from '../sessions/reducers'\nimport { SharingState } from '../sharing/reducers'\nimport { Map, OrderedMap, List, fromJS } from 'immutable'\nimport { GeneralState } from '../general/reducers'\nimport { mapValues } from 'lodash'\nimport { RootState, Workspace, normalizeSettingsString } from './reducers'\nimport { AppHistory, AppHistoryItem } from '../appHistory/reducers'\n\nexport function deserializePersistedState(state) {\n  return new RootState({\n    workspaces: deserializeWorkspaces(state.workspaces),\n    selectedWorkspace: state.selectedWorkspace,\n    settingsString: normalizeSettingsString(state.settingsString),\n    appHistory: deserializeAppHistory(state.appHistory),\n    general: deserializeGeneral(state.general),\n  }) as any\n}\n\nfunction deserializeWorkspaces(workspaces): Map<string, any> {\n  return Map(\n    mapValues(workspaces, (workspace, workspaceId) => {\n      return new Workspace({\n        docs: deserializeDocs(workspace.docs),\n        sessions: deserializeSessionsState(workspace.sessions),\n        sharing: deserializeSharing(workspace.sharing),\n        history: deserializeHistory(workspace.history),\n      })\n    }),\n  )\n}\n\nfunction deserializeAppHistory(state) {\n  return new AppHistory({\n    items: OrderedMap(mapValues(state.items, item => new AppHistoryItem(item))),\n  })\n}\n\nfunction deserializeDocs(state): Map<string, any> {\n  return Map(\n    mapValues(state, docsSession => {\n      return new DocsSession({\n        docsOpen: docsSession.docsOpen,\n        keyMove: docsSession.keyMove,\n        docsWidth: docsSession.docsWidth,\n        navStack: deserializeNavstack(docsSession.navStack),\n      })\n    }),\n  )\n}\n\nfunction deserializeNavstack(navStack) {\n  // note that stacks are plain objects. could be refactored to Map later\n  return List(navStack.map(s => Map(s))) as any\n}\n\nfunction deserializeSessionsState(state) {\n  const sessions: any = deserializeSessions(state.sessions)\n  const selectedSessionId =\n    state.selectedSessionId && state.selectedSessionId !== ''\n      ? state.selectedSessionId\n      : // @ts-ignore\n        sessions.first()!.id\n  return new SessionState({\n    selectedSessionId,\n    // @ts-ignore\n    sessions,\n    sessionCount: sessions.size,\n    headers: state.headers,\n  })\n}\n\nfunction deserializeSessions(state) {\n  return OrderedMap(mapValues(state, session => deserializeSession(session)))\n}\n\nfunction deserializeSession(session) {\n  return new Session({\n    ...session,\n    responses: deserializeResponses(session.responses),\n    operations: fromJS(session.operations),\n    variableToType: Map(session.variableToType),\n    date: session.date ? new Date(session.date) : undefined,\n    currentQueryStartTime: session.currentQueryStartTime\n      ? new Date(session.currentQueryStartTime)\n      : undefined,\n    currentQueryEndTime: session.currentQueryEndTime\n      ? new Date(session.currentQueryEndTime)\n      : undefined,\n    nextQueryStartTime: session.nextQueryStartTime\n      ? new Date(session.nextQueryStartTime)\n      : undefined,\n  })\n}\n\nfunction deserializeResponses(responses) {\n  return List(\n    responses\n      .filter(r => r.isSchemaError)\n      .map(response => deserializeResponse(response)),\n  )\n}\n\nfunction deserializeResponse(response) {\n  return new ResponseRecord({\n    resultID: response.resultID,\n    date: response.date,\n    time: new Date(response.time),\n    isSchemaError: response.isSchemaError || false,\n  })\n}\n\nfunction deserializeSharing({ shareUrl, ...state }) {\n  // dont deserialize the shareUrl\n  return new SharingState(state)\n}\n\nfunction deserializeHistory(state) {\n  return deserializeSessions(state)\n}\n\nfunction deserializeGeneral(state) {\n  return new GeneralState(state)\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/state/workspace/reducers.ts",
    "content": "import { Reducer } from 'redux'\nimport { combineReducers } from 'redux-immutable'\nimport docs, { DocsSession, DocsState } from '../docs/reducers'\nimport sessions, {\n  makeSessionState,\n  SessionState,\n  Tab,\n  sessionFromTab,\n  Session,\n} from '../sessions/reducers'\nimport sharing, { SharingState } from '../sharing/reducers'\nimport history, { HistoryState } from '../history/reducers'\nimport { Map, Record, OrderedMap } from 'immutable'\nimport general, { GeneralState } from '../general/reducers'\nimport { immutableMemoize } from '../../components/Playground/util/immutableMemoize'\nimport { createSelector } from 'reselect'\nimport { deserializePersistedState } from './deserialize'\nimport appHistory, { AppHistory } from '../appHistory/reducers'\n// import { createSelector } from 'reselect'\n\nimport { ISettings } from '../../types'\n\nexport function getSelectedWorkspaceId(state) {\n  return state.get('selectedWorkspace')\n}\n\nexport function getSelectedWorkspace(state) {\n  return state.getIn(['workspaces', getSelectedWorkspaceId(state)])\n}\n\nexport class Workspace extends Record({\n  docs: Map({}),\n  sessions: makeSessionState(''),\n  sharing: new SharingState(),\n  history: OrderedMap(),\n}) {\n  docs: DocsState\n  sessions: SessionState\n  sharing: SharingState\n  history: HistoryState\n}\n\nexport const defaultSettings: ISettings = {\n  'editor.cursorShape': 'line',\n  'editor.fontFamily': `'Source Code Pro', 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace`,\n  'editor.fontSize': 14,\n  'editor.reuseHeaders': true,\n  'editor.theme': 'dark',\n  'general.betaUpdates': false,\n  'prettier.printWidth': 80,\n  'prettier.tabWidth': 2,\n  'prettier.useTabs': false,\n  'request.credentials': 'omit',\n  'request.globalHeaders': {},\n  'schema.disableComments': true,\n  'schema.polling.enable': true,\n  'schema.polling.endpointFilter': '*localhost*',\n  'schema.polling.interval': 2000,\n  'tracing.hideTracingResponse': true,\n  'tracing.tracingSupported': true,\n  'subscriptions.protocol': 'subscription-transport-ws',\n}\n\n// tslint:disable-next-line:max-classes-per-file\nexport class RootState extends Record({\n  workspaces: Map({ '': makeWorkspace('') }),\n  selectedWorkspace: '',\n  settingsString: JSON.stringify(defaultSettings, null, 2),\n  stateInjected: false,\n  appHistory: new AppHistory(),\n  general: new GeneralState(),\n}) {\n  workspaces: Map<string, Workspace>\n  selectedWorkspace: string\n  settingsString: string\n  stateInjected: false\n  appHistory: AppHistory\n  general: GeneralState\n}\n\nconst workspaceReducers: Reducer<any> = combineReducers({\n  docs,\n  sessions,\n  sharing,\n  history,\n  general,\n  appHistory,\n})\n\n// todo: add lru-cache later when the localStorage is full\nexport const rootReducer = (state = new RootState(), action) => {\n  if (action.type === 'SELECT_WORKSPACE') {\n    return state.set('selectedWorkspace', action.payload.workspace)\n  }\n\n  if (action.type === 'SET_SETTINGS_STRING') {\n    return state.set('settingsString', action.payload.settingsString)\n  }\n\n  if (action.type === 'INIT_STATE' && !state.stateInjected) {\n    const { workspaceId, endpoint } = action.payload\n    if (!state.workspaces.get(workspaceId)) {\n      const newState = state.setIn(\n        ['workspaces', workspaceId],\n        makeWorkspace(endpoint),\n      )\n      return newState.set('selectedWorkspace', workspaceId)\n    }\n    return state.set('selectedWorkspace', workspaceId)\n  }\n\n  if (action.type === 'INJECT_STATE') {\n    return deserializePersistedState(action.payload.state).set(\n      'stateInjected',\n      true,\n    )\n  }\n\n  if (action.type === 'INJECT_TABS') {\n    return makeStateFromTabs(action.payload.tabs)\n  }\n\n  if (action.type === 'SELECT_APP_HISTORY_ITEM') {\n    return state.set('appHistory', appHistory(state.appHistory, action))\n  }\n\n  const generalActions = {\n    OPEN_HISTORY: true,\n    CLOSE_HISTORY: true,\n    SET_ENDPOINT_DISABLED: true,\n    SET_CONFIG_STRING: true,\n  }\n\n  if (generalActions[action.type]) {\n    return state.set('general', general(state.general, action))\n  }\n\n  const selectedWorkspaceId =\n    action.payload && action.payload.workspaceId\n      ? action.payload.workspaceId\n      : getSelectedWorkspaceId(state)\n\n  const path = ['workspaces', selectedWorkspaceId]\n\n  return state.setIn(path, workspaceReducers(state.getIn(path), action))\n}\n\nfunction makeStateFromTabs(tabs: Tab[]): RootState {\n  const endpoint = tabs[0].endpoint\n  const tabSessions = OrderedMap(\n    tabs.map(sessionFromTab).reduce(\n      (acc, curr) => {\n        return { ...acc, [curr.id]: curr }\n      },\n      {} as OrderedMap<string, Session>,\n    ),\n  )\n  // @ts-ignore\n  const selectedSessionId = tabSessions.first()!.id\n  const workspace = makeWorkspace(endpoint)\n    .setIn(['sessions', 'sessions'], tabSessions)\n    .setIn(['sessions', 'selectedSessionId'], selectedSessionId)\n  return new RootState()\n    .setIn(['workspaces', endpoint], workspace)\n    .set('selectedWorkspace', endpoint)\n}\n\nexport function makeWorkspace(endpoint) {\n  const sessionState = makeSessionState(endpoint)\n\n  // weird typescript error\n  return new Workspace({\n    docs: Map({\n      [sessionState.selectedSessionId]: new DocsSession(),\n    }),\n    sessions: sessionState,\n    sharing: new SharingState(),\n    history: OrderedMap(),\n  }) as any\n}\n\nexport default rootReducer\n\nexport const getSessionCounts = immutableMemoize(state => {\n  return state.workspaces.map(w => w.sessions.sessionCount)\n})\n\nexport const getSettingsString = state => state.settingsString\nexport const getSettings = createSelector(\n  [getSettingsString],\n  parseSettingsString,\n)\n\nfunction normalizeSettings(settings) {\n  const theme = settings['editor.theme']\n  if (theme !== 'dark' && theme !== 'light') {\n    settings['editor.theme'] = 'dark'\n  }\n\n  return {\n    ...defaultSettings,\n    ...settings,\n  }\n}\n\nfunction parseSettingsString(settingsString) {\n  try {\n    return normalizeSettings(JSON.parse(settingsString))\n  } catch (e) {\n    return defaultSettings\n  }\n}\n\nexport function normalizeSettingsString(settingsString) {\n  return JSON.stringify(parseSettingsString(settingsString), null, 2)\n}\n\nexport const getTheme = (state, customSettings) => {\n  const settings = customSettings || getSettings(state)\n  return settings['editor.theme'] || 'dark'\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/styled/index.ts",
    "content": "export * from './styled'\nexport { default as styled } from './styled'\n"
  },
  {
    "path": "packages/graphql-playground-react/src/styled/styled.ts",
    "content": "import * as styledComponents from 'styled-components'\nimport { ThemedStyledComponentsModule } from 'styled-components' // tslint:disable-line\nimport { ComponentClass } from 'react' // tslint:disable-line\n\nimport { ThemeInterface, theme } from './theme'\n\nconst {\n  default: styled,\n  css,\n  injectGlobal,\n  keyframes,\n  ThemeProvider,\n  withTheme,\n  createGlobalStyle,\n} = styledComponents as ThemedStyledComponentsModule<ThemeInterface>\n\nexport {\n  css,\n  injectGlobal,\n  keyframes,\n  ThemeProvider,\n  theme,\n  withTheme,\n  createGlobalStyle,\n  ThemeInterface,\n}\nexport default styled\n\nexport { ComponentClass }\n"
  },
  {
    "path": "packages/graphql-playground-react/src/styled/theme.ts",
    "content": "import { ISettings } from '../types'\nimport { defaultSettings } from '../state/workspace/reducers'\n\nexport interface Colours {\n  green: string\n  darkBlue: string\n  darkBlue50: string\n  darkBlue60: string\n  darkBlue80: string\n  darkBlue30: string\n  darkBlue20: string\n  darkBlue10: string\n  darkerBlue: string\n  darkestBlue: string\n  white80: string\n  white70: string\n  white60: string\n  white30: string\n  white20: string\n  white10: string\n  white: string\n  black02: string\n  black04: string\n  black07: string\n  black10: string\n  black30: string\n  black40: string\n  black50: string\n  paleText: string\n  paleGrey: string\n  red: string\n  blue: string\n  orange: string\n  purple: string\n  lightGrey: string\n  lighterGrey: string\n  // New dynamic styles\n  text: string\n  textInactive: string\n}\n\nexport interface EditorColours {\n  property: string\n  comment: string\n  punctuation: string\n  keyword: string\n  def: string\n  qualifier: string\n  attribute: string\n  number: string\n  string: string\n  builtin: string\n  string2: string\n  variable: string\n  meta: string\n  atom: string\n  ws: string\n  selection: string\n  cursorColor: string\n\n  text: string\n  textInactive: string\n  background: string\n  sidebarTop: string\n  sidebar: string\n  sidebarBottom: string\n  sidebarItemActive: string\n  sidebarItemSide: string\n  sidebarItemSessions: string\n  tab: string\n  tabInactive: string\n  tabText: string\n  navigationBar: string\n  navigationBarText: string\n  editorBackground: string\n  resultBackground: string\n  leftDrawerBackground: string\n  rightDrawerBackground: string\n  drawerText: string\n  drawerTextInactive: string\n  executeButton: string\n  executeButtonBorder: string\n  executeButtonHover: string\n  executeButtonSubscription: string\n  executeButtonSubscriptionHover: string\n  icon: string\n  iconHover: string\n  pollingIcon: string\n  pollingIconShadow: string\n  button: string\n  buttonHover: string\n  buttonText: string\n  buttonWorkspace: string\n  buttonWorkspaceHover: string\n  buttonWorkspaceText: string\n  circle: string\n  subscriptionTimeBoaderTop: string\n  subscriptionTimeText: string\n}\n\nexport const darkColours: Colours = {\n  green: '#27ae60',\n  darkBlue: 'rgb(23, 42, 58)',\n  darkBlue50: 'rgba(23, 42, 58, 0.5)',\n  darkBlue80: 'rgba(23, 42, 58, 0.8)',\n  darkBlue60: 'rgba(23, 42, 58, 0.6)',\n  darkBlue30: 'rgba(23, 42, 58, 0.3)',\n  darkBlue20: 'rgba(23, 42, 58, 0.2)',\n  darkBlue10: 'rgba(23, 42, 58, 0.1)',\n  darkerBlue: '#0F202D',\n  darkestBlue: 'rgb(11,20,28)',\n  white10: 'rgba(255, 255, 255, 0.1)',\n  white20: 'rgba(255, 255, 255, 0.2)',\n  white30: 'rgba(255, 255, 255, 0.3)',\n  white60: 'rgba(255, 255, 255, 0.6)',\n  white70: 'rgba(255, 255, 255, 0.7)',\n  white80: 'rgba(255, 255, 255, 0.8)',\n  white: 'rgba(255, 255, 255, 1)',\n  black02: 'rgba(0, 0, 0, 0.02)',\n  black07: 'rgba(0, 0, 0, 0.07)',\n  black04: 'rgba(0, 0, 0, 0.04)',\n  black10: 'rgba(0, 0, 0, 0.1)',\n  black30: 'rgba(0, 0, 0, 0.3)',\n  black40: 'rgba(0, 0, 0, 0.4)',\n  black50: 'rgba(0, 0, 0, 0.5)',\n  red: '#f25c54',\n  orange: 'rgba(241, 143, 1, 1)',\n  blue: 'rgba(42, 126, 210, 1)',\n  purple: 'rgb(164, 3, 111)',\n\n  paleText: 'rgba(0, 0, 0, 0.5)',\n  paleGrey: '#f3f4f4', // use for bgs, borders, etc\n  lightGrey: '#eeeff0',\n  lighterGrey: '#f6f7f7',\n  // New colors\n  text: 'rgba(255,255,255,0.6)',\n  textInactive: '#555e66',\n}\n\nexport const lightColours: Colours = {\n  green: '#27ae60',\n  darkBlue: 'rgb(23, 42, 58)',\n  darkBlue50: 'rgba(23, 42, 58, 0.5)',\n  darkBlue80: 'rgba(23, 42, 58, 0.8)',\n  darkBlue60: 'rgba(23, 42, 58, 0.6)',\n  darkBlue30: 'rgba(23, 42, 58, 0.3)',\n  darkBlue20: 'rgba(23, 42, 58, 0.2)',\n  darkBlue10: 'rgba(23, 42, 58, 0.1)',\n  darkerBlue: '#0F202D',\n  darkestBlue: 'rgb(11,20,28)',\n  white10: 'rgba(255, 255, 255, 0.1)',\n  white20: 'rgba(255, 255, 255, 0.2)',\n  white30: 'rgba(255, 255, 255, 0.3)',\n  white60: 'rgba(255, 255, 255, 0.6)',\n  white70: 'rgba(255, 255, 255, 0.7)',\n  white80: 'rgba(255, 255, 255, 0.8)',\n  white: 'rgba(255, 255, 255, 1)',\n  black02: 'rgba(0, 0, 0, 0.02)',\n  black04: 'rgba(0, 0, 0, 0.04)',\n  black10: 'rgba(0, 0, 0, 0.1)',\n  black07: 'rgba(0, 0, 0, 0.07)',\n  black30: 'rgba(0, 0, 0, 0.3)',\n  black40: 'rgba(0, 0, 0, 0.4)',\n  black50: 'rgba(0, 0, 0, 0.5)',\n  red: '#f25c54',\n  orange: 'rgba(241, 143, 1, 1)',\n  blue: 'rgba(42, 126, 210, 1)',\n  purple: 'rgb(164, 3, 111)',\n  paleText: 'rgba(0, 0, 0, 0.5)',\n  paleGrey: '#f3f4f4', // use for bgs, borders, etc\n  lightGrey: '#eeeff0',\n  lighterGrey: '#f6f7f7',\n  // New colors\n  text: 'rgba(0,0,0,.7)',\n  textInactive: 'rgba(0,0,0,.3)',\n}\n\nexport const darkEditorColours: EditorColours = {\n  property: 'rgb(41, 185, 115)',\n  comment: 'rgba(255, 255, 255, 0.3)',\n  punctuation: 'rgba(255, 255, 255, 0.4)',\n  keyword: 'rgb(42, 126, 211)',\n  def: 'rgb(56, 189, 193)',\n  qualifier: '#1c92a9',\n  attribute: 'rgb(247, 116, 102)',\n  number: '#2882f9',\n  string: '#d64292',\n  builtin: '#d47509',\n  string2: '#0b7fc7',\n  variable: 'rgb(181, 34, 130)',\n  meta: '#b33086',\n  atom: 'rgb(249, 233, 34)',\n  ws: 'rgba(255, 255, 255, 0.4)',\n  selection: 'rgba(255, 255, 255, 0.1)',\n  cursorColor: 'rgba(255, 255, 255, 0.4)',\n  text: '#fff',\n  textInactive: 'rgba(255, 255, 255, 0.6)',\n  background: '#09141c',\n  sidebarTop: '#0f202d',\n  sidebar: '#172b3a',\n  sidebarBottom: '#172b3a',\n  sidebarItemActive: 'rgb(23, 42, 58)',\n  sidebarItemSide: '#27ae60',\n  sidebarItemSessions: 'rgba(255, 255, 255, 0.05)',\n  tab: '#172b3a',\n  tabInactive: '#0f202d',\n  tabText: '#fff',\n  navigationBar: '#172b3a',\n  navigationBarText: 'rgba(255, 255, 255, 0.6)',\n  editorBackground: '#0f202d',\n  resultBackground: '#172b3a',\n  leftDrawerBackground: '#0b1924',\n  rightDrawerBackground: '#0b1924',\n  drawerText: 'rgba(255,255,255,0.6)',\n  drawerTextInactive: '#555e66',\n  executeButton: 'rgb(185, 191, 196)',\n  executeButtonBorder: 'rgb(11, 20, 28)',\n  executeButtonHover: 'rgb(195, 201, 206)',\n  executeButtonSubscription: '#f25c54',\n  executeButtonSubscriptionHover: '#f36c65',\n  icon: 'rgb(74, 85, 95)',\n  iconHover: 'rgba(255, 255, 255, 0.6)',\n  pollingIcon: 'rgba(139, 149, 156, 1)',\n  pollingIconShadow: 'rgba(139, 149, 156, 0.4)',\n  button: '#0F202D',\n  buttonHover: '#122535',\n  buttonText: 'rgba(255,255,255,0.6)',\n  buttonWorkspace: '#b9bfc4',\n  buttonWorkspaceHover: '#a4acb2',\n  buttonWorkspaceText: 'rgb(23, 42, 58)',\n  circle: 'rgba(255, 255, 255, 0.4)',\n  subscriptionTimeBoaderTop: 'rgba(255, 255, 255, 0.2)',\n  subscriptionTimeText: 'rgba(255, 255, 255, 0.5)',\n}\n\nexport const lightEditorColours: EditorColours = {\n  property: '#328c8c', //\n  comment: 'rgba(0, 0, 0, 0.3)', //\n  punctuation: 'rgba(23,42,58,.8)', //\n  keyword: '#366b6b', //\n  def: 'rgb(56, 189, 193)', //\n  qualifier: '#1c92a9', //\n  attribute: '#b56531', //\n  number: '#1f6ed6;', //\n  string: '#d64292', //\n  builtin: '#d47509', //\n  string2: '#0b7fc7', //\n  variable: 'rgb(236, 95, 103)', //\n  meta: '#b33086', //\n  atom: 'rgb(245, 160, 0)', //\n  ws: 'rgba(23, 42, 58, 0.8)', //\n  selection: '#d1e9fd',\n  cursorColor: 'rgba(0, 0, 0, 0.4)',\n  text: 'rgba(0, 0, 0, 0.7)',\n  textInactive: 'rgba(0, 0, 0, 0.3)',\n  background: '#dbdee0',\n  sidebarTop: '#eeeff0',\n  sidebar: '#eeeff0',\n  sidebarBottom: '#f6f7f7',\n  sidebarItemActive: '#f6f7f7',\n  sidebarItemSide: '#27ae60',\n  sidebarItemSessions: '#dbdee0',\n  tab: '#eeeff0',\n  tabInactive: '#e7eaec',\n  tabText: 'rgba(23, 42, 58, .8)',\n  navigationBar: '#eeeff0',\n  navigationBarText: 'rgba(23, 42, 58, 0.8)',\n  editorBackground: '#f6f7f7',\n  resultBackground: '#eeeff0',\n  leftDrawerBackground: '#e9eaea',\n  rightDrawerBackground: '#e5e7e7',\n  drawerText: 'rgba(0, 0, 0, 0.7)',\n  drawerTextInactive: 'rgba(0, 0, 0, 0.3)',\n  executeButton: 'rgb(115, 127, 136)',\n  executeButtonBorder: '#eeeff0',\n  executeButtonHover: '',\n  executeButtonSubscription: '#f25c54',\n  executeButtonSubscriptionHover: '#f36c65',\n  icon: 'rgb(194, 200, 203)',\n  iconHover: 'rgba(23, 42, 58, 0.6)',\n  pollingIcon: 'rgba(139, 149, 156, 1)',\n  pollingIconShadow: 'rgba(139, 149, 156, 0.4)',\n  button: '#d8dbde',\n  buttonHover: 'rgba(20, 37, 51, 0.2)',\n  buttonText: 'rgba(23, 42, 58, 0.8)',\n  buttonWorkspace: 'rgb(185, 191, 196)',\n  buttonWorkspaceHover: 'rgb(157, 166, 173)',\n  buttonWorkspaceText: 'rgb(238, 239, 240)',\n  circle: 'rgba(23,42,58,.4)',\n  subscriptionTimeBoaderTop: 'rgba(23, 42, 58, 0.2)',\n  subscriptionTimeText: 'rgba(23, 42, 58, 0.5)',\n}\n\nexport interface Sizes {\n  small6: string\n  small10: string\n  small12: string\n  small16: string\n  medium25: string\n  smallRadius: string\n  fontLight: string\n  fontSemiBold: string\n  fontTiny: string\n  fontSmall: string\n  fontMedium: string\n}\n\nexport const sizes: Sizes = {\n  small6: '6px',\n  small10: '10px',\n  small12: '12px',\n  small16: '16px',\n  medium25: '25px',\n\n  // font weights\n  fontLight: '300',\n  fontSemiBold: '600',\n\n  // font sizes\n  fontTiny: '12px',\n  fontSmall: '14px',\n  fontMedium: '20px',\n\n  // others\n  smallRadius: '2px',\n}\n\nexport interface Shorthands {\n  [x: string]: any\n}\n\nexport const shorthands: Shorthands = {}\n\nexport interface ThemeInterface {\n  mode: 'light' | 'dark'\n  colours: Colours\n  sizes: Sizes\n  shorthands: Shorthands\n  editorColours: EditorColours\n  settings: ISettings\n}\n\nexport const theme: any = {\n  mode: 'dark',\n  colours: darkColours,\n  sizes,\n  shorthands,\n  editorColours: darkEditorColours,\n  settings: defaultSettings,\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/types.ts",
    "content": "import { Observable, FetchResult } from 'apollo-link'\n\nexport type ApolloLinkExecuteResponse = Observable<FetchResult>\n\nexport type HistoryFilter = 'HISTORY' | 'STARRED'\n\nexport type Environment = 'Node' | 'Browser' | 'Cli'\nexport type GraphQLClient =\n  | 'fetch'\n  | 'relay'\n  | 'apollo'\n  | 'graphql-request'\n  | 'curl'\n\nexport type Theme = 'dark' | 'light'\n\nexport type CursorShape = 'line' | 'block' | 'underline'\n\nexport interface ISettings {\n  ['editor.cursorShape']: CursorShape\n  ['editor.fontFamily']: string\n  ['editor.fontSize']: number\n  ['editor.reuseHeaders']: boolean\n  ['editor.theme']: Theme\n  ['general.betaUpdates']: boolean\n  ['prettier.printWidth']: number\n  ['prettier.tabWidth']: number\n  ['prettier.useTabs']: boolean\n  ['request.credentials']: 'omit' | 'include' | 'same-origin'\n  ['request.globalHeaders']: { [key: string]: string }\n  ['schema.disableComments']: boolean\n  ['schema.polling.enable']: boolean\n  ['schema.polling.endpointFilter']: string\n  ['schema.polling.interval']: number\n  ['tracing.hideTracingResponse']: boolean\n  ['tracing.tracingSupported']: boolean\n  ['subscriptions.protocol']: 'subscription-transport-ws' | 'graphql-ws'\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/utils/performance.ts",
    "content": "let last: number | null = null\n// tslint:disable\nexport function log(...messages) {\n  if (messages.length === 0) {\n    last = null\n  }\n  if (last) {\n    console.log(...messages, `${performance.now() - last}ms`)\n  } else {\n    console.log(...messages)\n  }\n  last = performance.now()\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/src/utils.ts",
    "content": "import * as prettier from 'prettier/standalone'\nimport * as graphql from 'prettier/parser-graphql'\n// tslint:disable\n\nexport function safely(cb: any) {\n  return function*(...args) {\n    try {\n      yield cb(...args)\n    } catch (e) {\n      console.error(e)\n    }\n  }\n}\n\ninterface PrettierOptions {\n  printWidth: number\n  tabWidth: number\n  useTabs: boolean\n}\n\nexport function prettify(query: string, options: PrettierOptions) {\n  return prettier.format(query, {\n    ...options,\n    parser: 'graphql',\n    plugins: [graphql],\n  })\n}\n\nexport function isIframe() {\n  try {\n    return window.self !== window.top\n  } catch (e) {\n    return true\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/tests/schema.faker.graphql",
    "content": "type Company {\n  name: String @fake(type:companyName)\n  industry: String @examples(values: [\"IT\", \"Manufacturing\", \"Medicine\", \"Media\"])\n  employees: [Employee!]\n}\n\n# Employee type\ntype Employee {\n  firstName: String @fake(type: firstName, locale:en_CA)\n  lastName: String @fake(type: lastName, locale:en_CA)\n  address: String @fake(type:streetAddress, options: { useFullAddress: true })\n  subordinates: [Employee!]!\n  company: Company\n}\n\ninterface Node {\n  id: ID!\n}\n\ninterface Character {\n  id: ID!\n  name: String!\n}\n\ntype Human implements Character, Node {\n  id: ID!\n  name: String!\n  totalCredits: Int\n}\n\nunion UNIONMASTER = Employee | User | Company\n\nenum Role {\n  # Adimn role\n  ADMIN\n  USER @deprecated(reason: \"not cool\")\n  # Jedi\n  JEDI\n  NO_DESCRIPTION\n  DEP_NO_REASON @deprecated\n}\n\ntype User {\n  # User role lorem ipsum\n  role: Role\n  union: UNIONMASTER\n  dep: String @deprecated(reason: \"hey\")\n  hey: String!\n  id: ID\n}\n\ntype Query {\n  # get first user\n  user(\n    # Hey i am the id\n    id: ID\n  ): User!\n  human: Human\n  employee(id: ID, name: String, lorem: String, Ipsum: Int): Employee\n  company(id: ID): Company\n  allCompanies: [Company!]\n}\n\ntype Mutation {\n  user: User\n}\n\n"
  },
  {
    "path": "packages/graphql-playground-react/tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"lib\",\n    \"noUnusedLocals\": false\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/tsconfig.jest.json",
    "content": "{\n  \"extends\": \"./tsconfig\",\n  \"compilerOptions\": {\n    \"jsx\": \"react\"\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\n      \"esnext\",\n      \"dom\"\n    ],\n    \"sourceMap\": true,\n    \"jsx\": \"preserve\",\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": false,\n    \"skipLibCheck\": true,\n    \"strictNullChecks\": false,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"declaration\": true,\n    \"plugins\": [\n      {\n        \"name\": \"typescript-styled-plugin\"\n      }\n    ]\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"lib\",\n    \"dist\",\n    \"examples\",\n    \"build\"\n  ]\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/tslint.json",
    "content": "{\n  \"extends\": [\"tslint-graphcool-frontend\"],\n  \"rules\": {\n    \"forin\": false,\n    \"no-submodule-imports\": false,\n    \"prefer-conditional-expression\": false,\n    \"no-implicit-dependencies\": false,\n    \"no-empty\": false,\n    \"no-shadowed-variable\": false,\n    \"prefer-for-of\": false,\n    \"no-string-literal\": false\n  }\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/typings/custom.d.ts",
    "content": "interface Window {\n  GraphQLPlayground: any\n  version: string\n}\n\ndeclare module '*.json' {\n  const value: any\n  export default value\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/typings/styled-jsx.d.ts",
    "content": "import 'react'\n\ndeclare module 'react' {\n  interface HTMLProps<T> {\n    jsx?: boolean\n    global?: boolean\n  }\n}\n\ndeclare module 'react' {\n  interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {\n    jsx?: boolean\n    global?: boolean\n  }\n}\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\n    \"config:base\",\n    \"docker:disable\"\n  ],\n  \"ignoreDeps\": [\n    \"hapi\"\n  ]\n}\n"
  },
  {
    "path": "scripts/build.sh",
    "content": "#!/bin/bash\n\nset -e\n\ncd packages\n\npackages=(\n  graphql-playground-html\n  graphql-playground-react\n  # graphql-playground-electron\n  graphql-playground-middleware-express\n  graphql-playground-middleware-hapi\n  graphql-playground-middleware-koa\n  graphql-playground-middleware-lambda\n)\n\nfor pkg in \"${packages[@]}\"\ndo\n  cd $pkg\n  echo \"Building ${pkg}\"\n  yarn build\n  cd ..\ndone\n"
  },
  {
    "path": "scripts/release-html.sh",
    "content": "#!/bin/bash\n\nif ! [ -x \"$(command -v jq)\" ]; then\n  echo 'Error: jq is not installed.' >&2\n  exit 1\nfi\n\nset -e\n\ncd packages\n\nmiddlewares=(\n  graphql-playground-middleware-express\n  graphql-playground-middleware-hapi\n  graphql-playground-middleware-koa\n  graphql-playground-middleware-lambda\n)\n\ncd graphql-playground-html\necho \"Releasing graphql-playground-html...\"\nyarn version --no-git-tag-version --new-version patch\nyarn publish --non-interactive\nversion=$(cat package.json | jq -r '.version')\ncd ..\n\nfor middleware in \"${middlewares[@]}\"\ndo\n  cd $middleware\n  echo \"Releasing ${middleware}...\"\n  yarn add graphql-playground-html@$version\n  yarn version --no-git-tag-version --new-version patch\n  yarn publish --non-interactive\n  cd ..\ndone\n"
  },
  {
    "path": "scripts/release-react.sh",
    "content": "#!/bin/bash\n\nif ! [ -x \"$(command -v jq)\" ]; then\n  echo 'Error: jq is not installed.' >&2\n  exit 1\nfi\n\nset -e\n\ncd packages\n\nmiddlewares=(\n  graphql-playground-middleware-express\n  graphql-playground-middleware-hapi\n  graphql-playground-middleware-koa\n  graphql-playground-middleware-lambda\n)\n\ncd graphql-playground-react\nyarn install\necho \"Releasing graphql-playground-react...\"\nyarn version --no-git-tag-version --new-version patch\nyarn publish --non-interactive\nexport version=$(cat package.json | jq -r '.version')\ncd ..\n\necho \"Updating JSDeliver cache...\"\ncurl -X POST \\\n  http://purge.jsdelivr.net/ \\\n  -H 'cache-control: no-cache' \\\n  -H 'content-type: application/json' \\\n  -d '{\n\t\"path\": [\n\t\t\"/npm/graphql-playground-react/build/static/css/middleware.css\",\n\t\t\"/npm/graphql-playground-react/build/static/js/middleware.js\"\n\t]\n}'\n\nfor middleware in \"${middlewares[@]}\"\ndo\n  cd $middleware\n  yarn install\n  echo \"Releasing ${middleware}...\"\n  cat package.json | jq \".playgroundVersion = \\\"$version\\\"\" > package.tmp.json\n  mv package.tmp.json package.json\n  npm version patch --no-git-tag-version\n  npm publish\n  cd ..\ndone\n\ncd graphql-playground-electron\necho \"Updating dependency & version in graphql-playground-electron...\"\nyarn add graphql-playground-react@$version\nyarn version --no-git-tag-version --new-version patch\ncd ..\n"
  },
  {
    "path": "scripts/versions.sh",
    "content": "#!/bin/bash\n\nset -e\n\ncd packages\n\npackages=(\n  graphql-playground-react\n  graphql-playground-html\n  graphql-playground-electron\n  graphql-playground-middleware-express\n  graphql-playground-middleware-hapi\n  graphql-playground-middleware-koa\n  graphql-playground-middleware-lambda\n)\n\nfor pkg in \"${packages[@]}\"\ndo\n  cd $pkg\n  version=$(cat package.json | jq -r '.version')\n  echo \"$pkg: $version\"\n  cd ..\ndone"
  }
]