[
  {
    "path": ".eslintignore",
    "content": "npm-package/lib/\n*.tmpl.js\n*.bundle.js\ndist/\nrelease/\nnode_modules/\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"parser\": \"@babel/eslint-parser\",\n  \"extends\": [\"airbnb\", \"prettier\"],\n  \"env\": {\n    \"browser\": true,\n    \"node\": true,\n    \"jest\": true\n  },\n  \"settings\": {\n    \"import/core-modules\": [\"electron\"]\n  },\n  \"rules\": {\n    \"linebreak-style\": 0,\n    \"react/prefer-stateless-function\": 0,\n    \"consistent-return\": 0,\n    \"strict\": 0,\n    \"no-console\": 0,\n    \"no-param-reassign\": [\"error\", { \"props\": false }],\n    \"no-underscore-dangle\": [\n      \"error\",\n      {\n        \"allow\": [\n          \"__IS_REDUX_NATIVE_MESSAGE__\",\n          \"__AVAILABLE_METHODS_CAN_CALL_BY_RNDEBUGGER__\",\n          \"__PLATFORM__\",\n          \"__REPORT_REACT_DEVTOOLS_PORT__\",\n          \"__FETCH_SUPPORT__\",\n          \"__NETWORK_INSPECT__\",\n          \"__FROM_DEBUGGER_WORKER__\"\n        ]\n      }\n    ],\n    \"react/jsx-filename-extension\": [1, { \"extensions\": [\".js\", \".jsx\"] }],\n    \"import/prefer-default-export\": 0,\n    \"import/no-extraneous-dependencies\": [\"error\", { \"optionalDependencies\": true }],\n    \"semi\": [\"error\", \"never\"]\n  }\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: jhen0409\nopen_collective: react-native-debugger\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\nBefore submitting the issue:\n\n- You're using the latest version of react-native-debugger\n- You have read the documentation\n- For the feature requests / issues of devtools integration like React / Redux / Apollo, you should submit an issue to that repo\n  - https://github.com/facebook/react-devtools/issues\n  - https://github.com/reduxjs/redux-devtools/issues\n  - https://github.com/apollographql/apollo-client-devtools/issues\n-->\n\n<!--\nPlease provide the following information for bug report or question, if you can provide a minimal example project or screenshot or even video would be helpful for reproduce the problem. You can just removed these if you want to submit a feature request:\n-->\n\nReact Native Debugger app version: [FILL THIS OUT]\nReact Native version: [FILL THIS OUT]\nPlatform: [FILL THIS OUT: iOS, Android, ...]\nIs real device of platform: [Yes or No]\nOperating System: [FILL THIS OUT: macOS, Linux, Windows]\n\n<!-- Love react-native-debugger? Please consider supporting our collective:\n👉  https://opencollective.com/react-native-debugger/donate -->\n"
  },
  {
    "path": ".github/settings.yml",
    "content": "repository:\n  name: react-native-debugger\n  has_issues: true\n  has_wiki: true\n  has_downloads: true\n  default_branch: master\n  allow_squash_merge: true\n  allow_merge_commit: true\n  allow_rebase_merge: true\n\nlabels:\n  - name: bug\n    color: CC0000\n  - name: help wanted\n    color: 33aa3f\n  - name: duplicate\n    color: cfd3d7\n  - name: enhancement\n    color: a2eeef\n  - name: question\n    color: d876e3\n  - name: invalid\n    color: e4e669\n  - name: wontfix\n    color: ffffff\n  - name: feature\n    color: 336699\n  - name: trivial\n    oldname: good first issue\n    color: afffb2\n  - name: has PR\n    color: 3100ad\n  - name: documentation\n    color: a1ed95\n  - name: RFC\n    color: 3100ad\n  - name: WIP\n    color: e4e669\n  - name: don't merge\n    color: CC0000\n  - name: stale\n    color: ffffff\n  - name: cannot-reproduce\n    color: bfdadc\n  - name: more-information-needed\n    color: c2e0c6\n  - name: upstream\n    color: 5319e7\n  - name: waiting-for-response\n    color: 3100ad\n\n  # Integrations\n  - name: integration/react-devtools\n    color: 1b307c\n  - name: integration/redux-devtools\n    color: 7c2d9e\n  - name: integration/apollo-client-devtools\n    color: 7066e8\n\n  # Features\n  - name: feature/network-inspect\n    color: fce885\n\n  # Packages\n  - name: package/react-native-debugger-open\n    color: f7e78f\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\n\non: [push, pull_request]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  build-test-linux:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3.7.0\n        with:\n          node-version: 18.x\n          cache: 'yarn'\n      - name: Setup\n        run: sudo apt-get install -y libgbm-dev\n      - name: Test\n        id: test\n        run: |\n          yarn\n          cd npm-package && yarn && cd ..\n          yarn test\n          yarn build\n          xvfb-run --auto-servernum yarn test-e2e\n      - name: Upload artifacts on failure\n        if: ${{ failure() && steps.test.conclusion == 'failure' }}\n        uses: actions/upload-artifact@v3\n        with:\n          name: artifacts\n          path: artifacts\n          retention-days: 1\n  build-test-macos:\n    runs-on: macOS-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3.7.0\n        with:\n          node-version: 18.x\n          cache: 'yarn'\n      - name: Test\n        id: test\n        run: |\n          yarn\n          cd npm-package && yarn && cd ..\n          yarn test\n          yarn build\n          yarn test-e2e\n      - name: Upload artifacts on failure\n        if: ${{ failure() && steps.test.conclusion == 'failure' }}\n        uses: actions/upload-artifact@v3\n        with:\n          name: artifacts\n          path: artifacts\n          retention-days: 1\n  build-test-windows:\n    runs-on: windows-2022\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3.7.0\n        with:\n          node-version: 18.x\n          cache: 'yarn'\n      - name: Test\n        id: test\n        shell: bash\n        run: |\n          yarn config set network-timeout 500000 -g\n          yarn\n          cd npm-package && yarn && cd ..\n          yarn build\n          yarn test\n          yarn test-e2e\n      - name: Upload artifacts on failure\n        if: ${{ failure() && steps.test.conclusion == 'failure' }}\n        uses: actions/upload-artifact@v3\n        with:\n          name: artifacts\n          path: artifacts\n          retention-days: 1"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  release:\n    types: [published]\n\njobs:\n  release-linux:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3.7.0\n        with:\n          node-version: 18.x\n          cache: 'yarn'\n      - name: Package\n        run: |\n          yarn\n          yarn build\n          yarn pack-linux\n      - name: Upload assets to release\n        uses: jhen0409/release-asset-action@master\n        with:\n          file: release/rn-debugger-linux-x64.zip\n          pattern: release/react-native-debugger*\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n  release-windows:\n    runs-on: windows-2022\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3.7.0\n        with:\n          node-version: 18.x\n          cache: 'yarn'\n      - name: Package\n        shell: bash\n        run: |\n          yarn config set network-timeout 500000 -g\n          yarn\n          yarn build\n          yarn pack-windows\n      - name: Upload assets to release\n        uses: jhen0409/release-asset-action@master\n        with:\n          file: release/rn-debugger-windows-x64.zip\n          pattern: release/react_native_debugger*.exe\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\nnpm-debug.log\nyarn-error.log\n.DS_Store\ndist/js\ndist/main.js*\nrelease/\n*.bundle.js\ntmp/\nconfig_test\n.idea/\nartifacts/\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"trailingComma\": \"all\",\n  \"tabWidth\": 2,\n  \"semi\": false,\n  \"singleQuote\": true,\n  \"printWidth\": 80\n}\n"
  },
  {
    "path": "LICENSE.md",
    "content": "\nThe MIT License (MIT)\n\nCopyright (c) 2016 Jhen-Jie Hong\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": "# React Native Debugger\n\n[![Backers on Open Collective](https://opencollective.com/react-native-debugger/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/react-native-debugger/sponsors/badge.svg)](#sponsors) [![CI Status](https://github.com/jhen0409/react-native-debugger/workflows/CI/badge.svg)](https://github.com/jhen0409/react-native-debugger)\n\n⚠️ This app is currently only supported old [Remote Debugger](https://reactnative.dev/docs/debugging#chrome-developer-tools), if you're looking for new debugger support (e.g. Hermes / JSI / New Architecture) of React Native Debugger, please follow [discussion#774](https://github.com/jhen0409/react-native-debugger/discussions/774).\n\n![React Native Debugger](https://user-images.githubusercontent.com/3001525/29451479-6621bf1a-83c8-11e7-8ebb-b4e98b1af91c.png)\n\n> Run the redux example of [react-navigation](https://github.com/react-navigation/react-navigation/tree/master/example) with Redux DevTools setup\n\nThis is a standalone app for debugging React Native apps:\n\n- Based on official [Remote Debugger](https://reactnative.dev/docs/debugging#chrome-developer-tools) and provide more functionality.\n- Includes [React Inspector](docs/react-devtools-integration.md) from [`react-devtools-core`](https://github.com/facebook/react/tree/master/packages/react-devtools-core).\n- Includes Redux DevTools, made [the same API](docs/redux-devtools-integration.md) with [`redux-devtools-extension`](https://github.com/reduxjs/redux-devtools/tree/main/extension).\n- Includes [Apollo Client DevTools](docs/apollo-client-devtools-integration.md) ([`apollographql/apollo-client-devtools`](https://github.com/apollographql/apollo-client-devtools)) as devtools extension.\n\n## Installation\n\nTo install the app, you can download a prebuilt binary from the [release page](https://github.com/jhen0409/react-native-debugger/releases).\n\nFor **macOS**, you can use [Homebrew Cask](https://caskroom.github.io) to install:\n\n### < Homebrew 2.6.0\n\n```bash\nbrew update && brew install --cask react-native-debugger\n```\n\n### >= Homebrew 2.6.0\n\n```bash\nbrew install --cask react-native-debugger\n```\n\nThis puts `React Native Debugger.app` in your `/applications/` folder.\n\n### NOTICE: React Native Compatibility\n\nTo use this app you need to ensure you are using the correct version of React Native Debugger and react-native:\n\n| React Native Debugger | react-native |\n| --------------------- | ------------ |\n| >= 0.11               | >= 0.62      |\n| <= 0.10               | <= 0.61      |\n\nWe used different auto-update feed for `v0.10` and `v0.11`, so you won't see update tips of `v0.11` from `v0.10`.\n\nInstall last release of v0.10 (0.10.7)\n\n### < Homebrew 2.6.0\n\n`brew update && brew cask install https://raw.githubusercontent.com/Homebrew/homebrew-cask/b6ac3795c1df9f97242481c0817b1165e3e6306a/Casks/react-native-debugger.rb`\n\n### >= Homebrew 2.6.0\n\n`brew install --cask https://raw.githubusercontent.com/Homebrew/homebrew-cask/b6ac3795c1df9f97242481c0817b1165e3e6306a/Casks/react-native-debugger.rb`\n\n### Arch-based distributions\n\nYou can install [react-native-debugger-bin][1] from Arch User Repository:\n\n```shell\ngit clone https://aur.archlinux.org/react-native-debugger-bin.git\ncd react-native-debugger-bin\nmakepkg -si\n\n# or using AUR helper\nparu -S react-native-debugger-bin\n```\n\n## Build from source\n\nPlease read [Development section](docs/contributing.md#development) in docs/contributing.md for how to build the app from source.\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Debugger Integration](docs/debugger-integration.md)\n- [React DevTools Integration](docs/react-devtools-integration.md)\n- [Redux DevTools Integration](docs/redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](docs/apollo-client-devtools-integration.md)\n- [Shortcut references](docs/shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](docs/network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](docs/enable-open-in-editor-in-console.md)\n- [Config file in home directory](docs/config-file-in-home-directory.md)\n- [Troubleshooting](docs/troubleshooting.md)\n- [Contributing](docs/contributing.md)\n\n## Documentation (v0.10)\n\nPlease visit [`v0.10 branch`](https://github.com/jhen0409/react-native-debugger/tree/v0.10).\n\n## Credits\n\n- Great work of [React DevTools](https://github.com/facebook/react/tree/master/packages/react-devtools)\n- Great work of [Redux DevTools](https://github.com/gaearon/redux-devtools) / [Remote Redux DevTools](https://github.com/zalmoxisus/remote-redux-devtools) and all third-party monitors.\n- Great work of [Apollo Client DevTools](https://github.com/apollographql/apollo-client-devtools)). (Special thanks to [@Gongreg](https://github.com/Gongreg) for integrating this!)\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/react-native-debugger#backer)]\n\n<a href=\"https://opencollective.com/react-native-debugger#backers\" target=\"_blank\"><img src=\"https://opencollective.com/react-native-debugger/backers.svg?width=890\"></a>\n\n## Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/react-native-debugger#sponsor)]\n\n<a href=\"https://opencollective.com/react-native-debugger#backers\" target=\"_blank\"><img src=\"https://opencollective.com/react-native-debugger/sponsors.svg?width=890\"></a>\n\n## LICENSE\n\n[MIT](LICENSE.md)\n\n[1]: https://aur.archlinux.org/packages/react-native-debugger-bin\n"
  },
  {
    "path": "__e2e__/app.spec.js",
    "content": "import fs from 'fs'\nimport path from 'path'\nimport net from 'net'\nimport http from 'http'\nimport executablePath from 'electron'\nimport { _electron as electron } from 'playwright-core'\nimport waitForExpect from 'wait-for-expect'\nimport buildTestBundle, { bundlePath } from './buildTestBundle'\nimport createMockRNServer from './mockRNServer'\n\nconst delay = (time) =>\n  new Promise((resolve) => {\n    setTimeout(resolve, time)\n  })\n\njest.setTimeout(6e4)\n\ndescribe('Application launch', () => {\n  let electronApp\n  let mainWindow\n  const logs = []\n\n  beforeAll(async () => {\n    await buildTestBundle()\n    process.env.PACKAGE = 'no'\n    electronApp = await electron.launch({\n      executablePath,\n      args: ['--user-dir=__e2e__/tmp', './main.js'],\n      cwd: path.join(__dirname, '../dist'),\n    })\n    mainWindow = await electronApp.firstWindow()\n    mainWindow.on('console', (msg) => logs.push(msg))\n    await mainWindow.waitForLoadState()\n  })\n\n  afterEach(async () => {\n    const state = expect.getState()\n    await mainWindow.screenshot({\n      path: `./artifacts/${state.currentTestName}.png`,\n    })\n    const devtoolsWindow = electronApp.windows()[2]\n    if (devtoolsWindow) {\n      try {\n        await delay(100)\n        await devtoolsWindow.screenshot({\n          path: `./artifacts/devtools:${state.currentTestName}.png`,\n        })\n      } catch (e) {\n        console.error(e)\n      }\n    }\n  })\n\n  afterAll(async () => {\n    await electronApp.close()\n  })\n\n  it('should show an initial window', async () => {\n    expect(await mainWindow.title()).toBe(\n      'React Native Debugger - Attempting reconnection (port 8081)',\n    )\n  })\n\n  it('should portfile (for debugger-open usage) always exists in home dir', async () => {\n    const portFile = path.join(\n      process.env.USERPROFILE || process.env.HOME,\n      '.rndebugger_port',\n    )\n\n    expect(fs.existsSync(portFile)).toBe(true)\n    fs.unlinkSync(portFile)\n\n    await waitForExpect(async () => {\n      expect(fs.existsSync(portFile)).toBeTruthy()\n    })\n  })\n\n  it(\"should contain Inspector monitor's component on Redux DevTools\", async () => {\n    const val = await mainWindow.textContent(\n      '//div[contains(@class, \"inspector-\")]',\n    )\n    expect(val).not.toBeNull()\n  })\n\n  it('should contain an empty actions list on Redux DevTools', async () => {\n    const val = await mainWindow.textContent(\n      '//div[contains(@class, \"actionListRows-\")]',\n    )\n    expect(val).toBe('')\n  })\n\n  it('should show waiting message on React DevTools', async () => {\n    const el = await mainWindow.locator(\n      '//h2[text()=\"Waiting for React to connect…\"]',\n    )\n    expect(await el.isVisible()).toBe(true)\n  })\n\n  const customRNServerPort = 8098\n  const getURLFromConnection = (server) =>\n    new Promise((resolve) => {\n      server.on('connection', (socket, req) => {\n        resolve(req.url)\n      })\n    })\n\n  it('should connect to fake RN server', async () => {\n    const { wss, server } = createMockRNServer()\n\n    const url = await getURLFromConnection(wss)\n    expect(url).toBe('/debugger-proxy?role=debugger&name=Chrome')\n\n    await waitForExpect(async () => {\n      expect(await mainWindow.title()).toBe(\n        'React Native Debugger - Waiting for client connection (port 8081)',\n      )\n    })\n    server.close()\n    wss.close()\n  })\n\n  it('should connect to fake RN server (port 8088) with send set-debugger-loc after', async () => {\n    const { wss, server } = createMockRNServer(customRNServerPort)\n\n    const rndPath = `rndebugger://set-debugger-loc?host=localhost&port=${customRNServerPort}`\n    const homeEnv = process.platform === 'win32' ? 'USERPROFILE' : 'HOME'\n    const portFile = path.join(process.env[homeEnv], '.rndebugger_port')\n    const rndPort = fs.readFileSync(portFile, 'utf-8')\n\n    const sendSuccess = await new Promise((resolve) => {\n      const socket = net.createConnection(\n        { host: '127.0.0.1', port: rndPort },\n        () => {\n          let pass\n          socket.setEncoding('utf-8')\n          socket.write(JSON.stringify({ path: rndPath }))\n          socket.on('data', (data) => {\n            pass = data === 'success'\n            socket.end()\n          })\n          socket.on('end', () => resolve(pass))\n          setTimeout(() => socket.end(), 1000)\n        },\n      )\n    })\n    expect(sendSuccess).toBe(true)\n\n    const url = await getURLFromConnection(wss)\n    expect(url).toBe('/debugger-proxy?role=debugger&name=Chrome')\n\n    await waitForExpect(async () => {\n      expect(await mainWindow.title()).toBe(\n        `React Native Debugger - Waiting for client connection (port ${customRNServerPort})`,\n      )\n    })\n    server.close()\n    wss.close()\n  })\n\n  describe('Import fake script after', () => {\n    const getOneRequestHeaders = (port) =>\n      new Promise((resolve) => {\n        const server = http.createServer((req, res) => {\n          res.writeHead(200, { 'Content-Type': 'text/plain' })\n          res.end('')\n          resolve(req.headers)\n          server.close()\n        })\n        server.listen(port)\n      })\n\n    let headersPromise\n    let server\n    let wss\n    beforeAll(async () => {\n      const info = createMockRNServer(customRNServerPort)\n      server = info.server\n      wss = info.wss\n\n      headersPromise = getOneRequestHeaders(8099)\n\n      await new Promise((resolve) => {\n        wss.on('connection', (socket) => {\n          socket.on('message', (message) => {\n            const data = JSON.parse(message)\n            switch (data.replyID) {\n              case 'createJSRuntime':\n                socket.send(\n                  JSON.stringify({\n                    id: 'sendFakeScript',\n                    method: 'executeApplicationScript',\n                    inject: [],\n                    url: `../../${bundlePath}`,\n                  }),\n                )\n                break\n              case 'sendFakeScript':\n                return resolve()\n              default:\n                console.error(`Unexperted id ${data.replyID}, data:`, data)\n            }\n          })\n          socket.send(\n            JSON.stringify({\n              id: 'createJSRuntime',\n              method: 'prepareJSRuntime',\n            }),\n          )\n        })\n      })\n      expect(await mainWindow.title()).toBe(\n        `React Native Debugger - Connected (port ${customRNServerPort})`,\n      )\n    })\n\n    afterAll(() => {\n      server.close()\n      wss.close()\n    })\n\n    it('should received forbidden header names from xhr-test', async () => {\n      const headers = await headersPromise\n\n      expect(headers.origin).toBe('custom_origin_here')\n      expect(headers['user-agent']).toBe('react-native')\n    })\n\n    it('should have @@INIT action on Redux DevTools', async () => {\n      const el = await mainWindow\n        .locator('div')\n        .filter({ hasText: '@@redux/INIT' })\n        .first()\n      expect(await el.isVisible()).toBeTruthy() // Last store is `RemoteDev store instance 1`\n    })\n\n    let currentInstance = 'Autoselect instances' // Default instance\n    const wait = () => delay(750)\n    const selectInstance = async (instance) => {\n      let el = mainWindow.locator(`//div[text()=\"${currentInstance}\"]`)\n      expect(await el.isVisible()).toBeTruthy()\n      await el.click({ force: true })\n      await wait()\n      currentInstance = instance\n      el = mainWindow.locator(`//div[text()=\"${instance}\"]`)\n      expect(await el.isVisible()).toBeTruthy()\n      await el.click({ force: true })\n      await wait()\n    }\n    const commit = async () => {\n      await mainWindow.click('//button[text()=\"Commit\"]', { force: true })\n      await wait()\n    }\n\n    const expectActions = {\n      'Redux store instance 1': {\n        expt: [\n          '@@INIT',\n          'TEST_PASS_FOR_REDUX_STORE_1',\n          'SHOW_FOR_REDUX_STORE_1',\n        ],\n        notExpt: ['NOT_SHOW_FOR_REDUX_STORE_1', 'TEST_PASS_FOR_REDUX_STORE_2'],\n      },\n      'Redux store instance 2': {\n        expt: ['@@INIT', 'TEST_PASS_FOR_REDUX_STORE_2'],\n        notExpt: [\n          'TEST_PASS_FOR_REDUX_STORE_1',\n          'NOT_SHOW_1_FOR_REDUX_STORE_2',\n          'NOT_SHOW_2_FOR_REDUX_STORE_2',\n          'NOT_SHOW_3_FOR_REDUX_STORE_2',\n        ],\n      },\n      'MobX store instance 1': {\n        expt: ['@@INIT', 'testPassForMobXStore1'],\n        notExpt: ['TEST_PASS_FOR_REDUX_STORE_2'],\n      },\n      'MobX store instance 2': {\n        expt: ['@@INIT', 'testPassForMobXStore2'],\n        notExpt: ['testPassForMobXStore1'],\n      },\n      'RemoteDev store instance 1': {\n        expt: ['@@redux/INIT', 'TEST_PASS_FOR_REMOTEDEV_STORE_1'],\n        notExpt: ['testPassForMobXStore2'],\n      },\n    }\n\n    const eachAsync = (entries, fn) =>\n      entries.reduce(\n        (promise, entry, index) => promise.then(() => fn(entry, index)),\n        Promise.resolve(),\n      )\n\n    const runExpectActions = async (name) => {\n      const { expt, notExpt } = expectActions[name]\n\n      await eachAsync(expt, async (action) => {\n        const el = await mainWindow\n          .locator('div')\n          .filter({ hasText: action })\n          .first()\n        expect(await el.isVisible()).toBeTruthy()\n      })\n\n      await eachAsync(notExpt, async (action) => {\n        const el = await mainWindow\n          .locator('div')\n          .filter({ hasText: action })\n          .first()\n        expect(await el.isVisible()).toBeFalsy()\n      })\n    }\n\n    const checkInstance = async (name) => {\n      await selectInstance(name)\n      await runExpectActions(name)\n      await commit()\n    }\n\n    it('should have two Redux store instances on Redux DevTools', async () => {\n      await checkInstance('Redux store instance 1')\n      await checkInstance('Redux store instance 2')\n    })\n\n    it('should have two MobX store instances on Redux DevTools', async () => {\n      await checkInstance('MobX store instance 1')\n      await checkInstance('MobX store instance 2')\n    })\n\n    it('should have one RemoteDev store instances on Redux DevTools', async () => {\n      await checkInstance('RemoteDev store instance 1')\n    })\n\n    it('should have only specific logs in console of main window', async () => {\n      // Print renderer process logs\n      logs.forEach((log) =>\n        console.log(`Message: ${log.text()}\\nType: ${log.type()}`),\n      )\n      expect(logs.length).toEqual(3) // clear + clear + warning\n      const [, , formDataWarning] = logs\n      expect(formDataWarning.type()).toBe('warning')\n      expect(\n        formDataWarning\n          .text()\n          .indexOf(\"Detected you're enabled Network Inspect\") > 0,\n      ).toBeTruthy()\n    })\n\n    it('should show apollo devtools panel', async () => {\n      const devtoolsWindow = electronApp.windows()[2]\n      expect(\n        await devtoolsWindow.evaluate(() =>\n          // eslint-disable-next-line no-undef\n          Object.keys(UI.panels).some(\n            (key) =>\n              key.startsWith('chrome-extension://') && key.endsWith('Apollo'),\n          ),\n        ),\n      ).toBeTruthy()\n    })\n  })\n})\n"
  },
  {
    "path": "__e2e__/buildTestBundle.js",
    "content": "import path from 'path'\nimport webpack from 'webpack'\n\nconst outputPath = '__e2e__/fixture'\nconst filename = 'app.bundle.js'\n\nexport const bundlePath = path.join(outputPath, filename)\n\n// Build a bundle for simulate RNDebugger worker run react-native bundle,\n// it included redux, mobx, remotedev tests\nexport default function buildTestBundle() {\n  return new Promise((resolve) => {\n    webpack({\n      mode: 'development',\n      entry: './__e2e__/fixture/app',\n      output: {\n        path: path.resolve(__dirname, '..', outputPath),\n        filename,\n      },\n      resolve: {\n        mainFields: ['react-native', 'main', 'browser'],\n      },\n    }).run(resolve)\n  })\n}\n"
  },
  {
    "path": "__e2e__/fixture/apollo.js",
    "content": "/* eslint-disable import/no-extraneous-dependencies */\n/*\n * Create an Apollo Client to test the bridge messages sent\n * wouldn't break the debugger proxy.\n */\n\nimport { ApolloClient, InMemoryCache } from '@apollo/client'\nimport gql from 'graphql-tag'\n\nconst client = new ApolloClient({\n  uri: 'https://spacex-production.up.railway.app/',\n  cache: new InMemoryCache(),\n})\n\nexport default async function run() {\n  return client.query({\n    query: gql`\n      query ExampleQuery {\n        company {\n          name\n          ceo\n          employees\n        }\n      }\n    `,\n  })\n}\n"
  },
  {
    "path": "__e2e__/fixture/app.js",
    "content": "import './setup'\n\nimport runXHRTest from './xhr-test' // Install fetch polyfill before initial apollo-client\nimport runApolloTest from './apollo'\nimport runReduxTest from './redux'\nimport runMobXTest from './mobx'\nimport runRemoteDevTest from './remotedev'\n\nrunReduxTest()\nrunMobXTest()\nrunRemoteDevTest()\nrunApolloTest().catch((e) => console.error(e))\nrunXHRTest().catch((e) => console.error(e))\n"
  },
  {
    "path": "__e2e__/fixture/mobx.js",
    "content": "/* eslint prefer-arrow-callback: 0 */\nimport { observable, action, useStrict } from 'mobx'\nimport remotedev from 'mobx-remotedev/lib/dev'\n\nuseStrict(true)\n\nexport default function run() {\n  const store = observable({ value: 0 })\n  store.testPassForMobXStore1 = action(function testPassForMobXStore1() {})\n\n  remotedev(store, { name: 'MobX store instance 1' }).testPassForMobXStore1()\n\n  const store2 = observable({ value: 1 })\n  store2.testPassForMobXStore2 = action(function testPassForMobXStore2() {})\n\n  remotedev(store2, { name: 'MobX store instance 2' }).testPassForMobXStore2()\n}\n"
  },
  {
    "path": "__e2e__/fixture/redux.js",
    "content": "/* eslint no-underscore-dangle: 0 */\n\nimport { createStore } from 'redux'\n\nexport default function run() {\n  // Enhancer\n  const store1 = createStore(\n    (state) => state,\n    { value: 0 },\n    window.__REDUX_DEVTOOLS_EXTENSION__({\n      name: 'Redux store instance 1',\n      actionsWhitelist: ['@@INIT', 'TEST_PASS_FOR_REDUX_STORE_1', '^SHOW_FOR_REDUX_STORE_1$'],\n    }),\n  )\n\n  // Compose enhancers\n  const store2 = createStore(\n    (state) => state,\n    { value: 1 },\n    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({\n      name: 'Redux store instance 2',\n      actionsBlacklist: ['NOT_SHOW_1_FOR_REDUX_STORE_2', 'NOT_SHOW_2_FOR_REDUX_STORE_2'],\n      predicate: (state, action) => action.type !== 'NOT_SHOW_3_FOR_REDUX_STORE_2',\n    })(/* No enhancers */),\n  )\n\n  store1.dispatch({ type: 'TEST_PASS_FOR_REDUX_STORE_1' })\n  store1.dispatch({ type: 'SHOW_FOR_REDUX_STORE_1' })\n  store1.dispatch({ type: 'NOT_SHOW_FOR_REDUX_STORE_1' })\n\n  store2.dispatch({ type: 'TEST_PASS_FOR_REDUX_STORE_2' })\n  store2.dispatch({ type: 'NOT_SHOW_1_FOR_REDUX_STORE_2' })\n  store2.dispatch({ type: 'NOT_SHOW_2_FOR_REDUX_STORE_2' })\n  store2.dispatch({ type: 'NOT_SHOW_3_FOR_REDUX_STORE_2' })\n}\n"
  },
  {
    "path": "__e2e__/fixture/remotedev.js",
    "content": "import { createStore } from 'redux'\n\nconst connectViaExtension = window.devToolsExtension.connect\n\nconst logReducer = (reducer) => {\n  const remotedev = connectViaExtension({\n    name: 'RemoteDev store instance 1',\n    actionCreators: {\n      test: () => {},\n    },\n  })\n  return (state, action) => {\n    const reducedState = reducer(state, action)\n    remotedev.send(action, reducedState)\n    return reducedState\n  }\n}\n\nconst logRemotely = (next) => (reducer, initialState) => next(logReducer(reducer), initialState)\n\nexport default function run() {\n  const store = logRemotely(createStore)((state) => state, { value: 0 })\n\n  store.dispatch({ type: 'TEST_PASS_FOR_REMOTEDEV_STORE_1' })\n}\n"
  },
  {
    "path": "__e2e__/fixture/setup.js",
    "content": "/* eslint-disable no-restricted-globals */\n/* eslint no-underscore-dangle: 0 */\n\nself.window = global\n\n// Remove native fetch as react-native use whatwg-fetch polyfill\nself.fetch = undefined\n\nconst MessageQueue = function MessageQueue() {}\nMessageQueue.spy = () => {}\nMessageQueue.prototype.__spy = null\n\nconst requiredModules = {\n  NativeModules: {},\n  Platform: {},\n  setupDevtools: undefined,\n  AsyncStorage: {},\n  MessageQueue,\n}\n// Simulate React Native's window.require polyfill\nwindow.require = (moduleName) => {\n  if (typeof moduleName !== 'number') {\n    // From https://github.com/facebook/react-native/blob/5403946f098cc72c3d33ea5cee263fb3dd03891d/packager/src/Resolver/polyfills/require.js#L97\n    console.warn(\n      `Requiring module '${moduleName}' by name is only supported for `\n        + 'debugging purposes and will BREAK IN PRODUCTION!',\n    )\n  }\n  return requiredModules[moduleName]\n}\nwindow.__DEV__ = true\nwindow.__fbBatchedBridge = new MessageQueue()\n"
  },
  {
    "path": "__e2e__/fixture/xhr-test.js",
    "content": "import 'whatwg-fetch'\n\nexport default async function run() {\n  // Fetch with forbidden header names\n  await fetch('http://localhost:8099', {\n    headers: {\n      Origin: 'custom_origin_here',\n      'User-Agent': 'react-native',\n    },\n  })\n\n  // It will log warning\n  // because we can't use worker's FormData for upload file\n  const data = { uri: 'uri' }\n  const form = new FormData()\n  form.append('file', data)\n}\n"
  },
  {
    "path": "__e2e__/mockRNServer.js",
    "content": "import http from 'http'\nimport WebSocket from 'ws'\n\nexport default function createMockRNServer(port = 8081) {\n  const server = http.createServer((req, res) => {\n    if (req.method === 'GET' && req.url === '/debugger-ui') {\n      res.writeHead(200, { 'Content-Type': 'text/html' })\n      res.end('<html></html>')\n    }\n  })\n  const wss = new WebSocket.Server({ server })\n  server.listen(port)\n  return { server, wss }\n}\n"
  },
  {
    "path": "app/actions/debugger.js",
    "content": "export const SET_DEBUGGER_LOCATION = 'SET_DEBUGGER_LOCATION'\nexport const SET_DEBUGGER_STATUS = 'SET_DEBUGGER_STATUS'\nexport const SET_DEBUGGER_WORKER = 'SET_DEBUGGER_WORKER'\nexport const SYNC_STATE = 'SYNC_STATE'\nexport const BEFORE_WINDOW_CLOSE = 'BEFORE_WINDOW_CLOSE'\n\nexport const setDebuggerLocation = (loc) => ({\n  type: SET_DEBUGGER_LOCATION,\n  loc,\n})\n\nexport const setDebuggerStatus = (status) => ({\n  type: SET_DEBUGGER_STATUS,\n  status,\n})\n\nexport const setDebuggerWorker = (worker, status) => ({\n  type: SET_DEBUGGER_WORKER,\n  worker,\n  status,\n})\n\nexport const syncState = (payload) => ({\n  type: SYNC_STATE,\n  payload,\n})\n\nexport const beforeWindowClose = () => ({\n  type: BEFORE_WINDOW_CLOSE,\n})\n"
  },
  {
    "path": "app/actions/setting.js",
    "content": "export const TOGGLE_DEVTOOLS = 'TOGGLE_DEVTOOLS'\nexport const RESIZE_DEVTOOLS = 'RESIZE_DEVTOOLS'\nexport const CHANGE_DEFAULT_THEME = 'CHANGE_DEFAULT_THEME'\n\nexport const toggleDevTools = (name) => ({\n  type: TOGGLE_DEVTOOLS,\n  name,\n})\n\nexport const resizeDevTools = (size) => ({\n  type: RESIZE_DEVTOOLS,\n  size,\n})\n\nexport const changeDefaultTheme = (themeName) => ({\n  type: CHANGE_DEFAULT_THEME,\n  themeName,\n})\n"
  },
  {
    "path": "app/components/Draggable.js",
    "content": "import React, { PureComponent } from 'react'\nimport PropTypes from 'prop-types'\n\nconst styles = {\n  draggable: {\n    position: 'relative',\n    zIndex: 1,\n    cursor: 'ns-resize',\n    padding: '3px 0',\n    margin: '-3px 0',\n    width: '100%',\n  },\n}\n\nexport default class Draggable extends PureComponent {\n  onMove = (evt) => {\n    evt.preventDefault()\n    const { onMove } = this.props\n    onMove?.(evt.pageX, evt.pageY)\n  }\n\n  onUp = (evt) => {\n    evt.preventDefault()\n    document.removeEventListener('mousemove', this.onMove)\n    document.removeEventListener('mouseup', this.onUp)\n    const { onStop } = this.props\n    onStop?.()\n  }\n\n  startDragging = (evt) => {\n    evt.preventDefault()\n    document.addEventListener('mousemove', this.onMove)\n    document.addEventListener('mouseup', this.onUp)\n    const { onStart } = this.props\n    onStart?.()\n  }\n\n  render() {\n    return (\n      <div\n        role=\"button\"\n        tabIndex=\"0\"\n        aria-label=\"Draggable\"\n        style={styles.draggable}\n        onMouseDown={this.startDragging}\n      />\n    )\n  }\n}\n\nDraggable.propTypes = {\n  onStart: PropTypes.func,\n  onMove: PropTypes.func.isRequired,\n  onStop: PropTypes.func,\n}\n\nDraggable.defaultProps = {\n  onStart: undefined,\n  onStop: undefined,\n}\n"
  },
  {
    "path": "app/components/FormInput.js",
    "content": "import React, { PureComponent } from 'react'\nimport PropTypes from 'prop-types'\n\nconst styles = {\n  title: { textAlign: 'center' },\n  form: {\n    display: 'flex',\n    flexDirection: 'row',\n    justifyContent: 'center',\n    alignItems: 'center',\n    margin: 8,\n  },\n  input: {\n    appearance: 'none',\n    fontSize: '16px',\n    margin: 2,\n    padding: '8px',\n    border: 0,\n    borderRadius: 2,\n  },\n  button: {\n    fontSize: '16px',\n    margin: 2,\n    padding: '8px',\n    border: 0,\n    borderRadius: 2,\n  },\n}\n\nexport default class FormInput extends PureComponent {\n  constructor(props) {\n    super(props)\n    this.state = { value: undefined }\n  }\n\n  handleOnChange = (evt) => {\n    const { onInputChange } = this.props\n    let { value } = evt.target\n    if (onInputChange) {\n      value = onInputChange(value)\n    }\n    this.setState({ value })\n  }\n\n  handleClick = (evt) => {\n    const { inputProps, onSubmit } = this.props\n    const { value } = this.state\n    onSubmit(evt, value || inputProps.value)\n  }\n\n  render() {\n    const { title, inputProps, button } = this.props\n    const { value } = this.state\n    const val = typeof value !== 'undefined' ? value : inputProps.value\n    return (\n      <div>\n        <div style={styles.title}>{title}</div>\n        <div style={styles.form}>\n          <input\n            onKeyDown={(e) => {\n              // Enter/Return key pressed\n              if (e.key === 'Enter') this.handleClick()\n            }}\n            type={inputProps.type}\n            value={val}\n            style={styles.input}\n            onChange={this.handleOnChange}\n          />\n          <button type=\"button\" style={styles.button} onClick={this.handleClick}>\n            {button}\n          </button>\n        </div>\n      </div>\n    )\n  }\n}\n\nFormInput.propTypes = {\n  title: PropTypes.string.isRequired,\n  inputProps: PropTypes.shape({\n    type: PropTypes.string,\n    value: PropTypes.string,\n  }),\n  button: PropTypes.string,\n  onInputChange: PropTypes.func,\n  onSubmit: PropTypes.func.isRequired,\n}\n\nFormInput.defaultProps = {\n  inputProps: { type: 'input' },\n  button: 'Confirm',\n  onInputChange: null,\n}\n"
  },
  {
    "path": "app/containers/App.js",
    "content": "import { ipcRenderer } from 'electron'\nimport { getCurrentWindow } from '@electron/remote'\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport * as debuggerActionCreators from '../actions/debugger'\nimport * as settingActionCreators from '../actions/setting'\nimport ReduxDevTools from './redux/DevTools'\nimport ReactInspector from './ReactInspector'\nimport FormInput from '../components/FormInput'\nimport Draggable from '../components/Draggable'\nimport { catchConsoleLogLink } from '../../electron/devtools'\n\nconst currentWindow = getCurrentWindow()\n\nconst styles = {\n  container: {\n    height: '100%',\n  },\n  wrapBackground: {\n    display: 'flex',\n    height: '100%',\n    flexDirection: 'column',\n    justifyContent: 'center',\n    alignItems: 'center',\n    color: '#ccc',\n    fontSize: '25px',\n    WebkitUserSelect: 'none',\n  },\n  text: {\n    textAlign: 'center',\n    margin: '7px',\n  },\n  shortcut: {\n    fontFamily: 'Monaco, monospace',\n    color: '#ddd',\n    backgroundColor: '#555',\n    padding: '4px',\n    borderRadius: '4px',\n    letterSpacing: '3px',\n  },\n}\n\nconst shortcutPrefix = process.platform === 'darwin' ? '⌥⌘' : 'Ctrl+Alt+'\n\nconst background = (\n  <div style={styles.wrapBackground}>\n    <div style={styles.text}>\n      <kbd style={styles.shortcut}>{`${shortcutPrefix}K`}</kbd>\n      {' to toggle Redux DevTools'}\n    </div>\n    <div style={styles.text}>\n      <kbd style={styles.shortcut}>{`${shortcutPrefix}J`}</kbd>\n      {' to toggle React DevTools'}\n    </div>\n  </div>\n)\n\nconst removeAllIPCListeners = () => {\n  ipcRenderer.removeAllListeners('toggle-devtools')\n  ipcRenderer.removeAllListeners('set-debugger-loc')\n  ipcRenderer.removeAllListeners('sync-state')\n}\n\nclass App extends Component {\n  componentDidMount() {\n    const { settingActions, debuggerActions } = this.props\n    ipcRenderer.on('toggle-devtools', (e, name) => settingActions.toggleDevTools(name))\n    ipcRenderer.on('sync-state', (event, arg) => debuggerActions.syncState(arg))\n    ipcRenderer.on('set-debugger-loc', (e, payload) => {\n      const location = JSON.parse(payload)\n      this.setDebuggerLocation(location)\n      catchConsoleLogLink(currentWindow, location.host || 'localhost', location.port)\n    })\n    const { debuggerState } = this.props\n    if (!debuggerState.isPortSettingRequired) {\n      this.setDebuggerLocation(JSON.parse(process.env.DEBUGGER_SETTING || '{}'))\n    }\n    window.onbeforeunload = removeAllIPCListeners\n    window.notifyDevToolsThemeChange = settingActions.changeDefaultTheme\n  }\n\n  componentWillUnmount() {\n    removeAllIPCListeners()\n    window.notifyDevToolsThemeChange = null\n  }\n\n  onResize = (x, y) => {\n    const { settingActions } = this.props\n    settingActions.resizeDevTools(y / window.innerHeight)\n  }\n\n  setDebuggerLocation({ projectRoots, ...location }) {\n    const { debuggerActions } = this.props\n    debuggerActions.setDebuggerLocation(location)\n    if (projectRoots) {\n      ReactInspector.setProjectRoots(projectRoots)\n    }\n  }\n\n  getReactBackgroundColor = () => {\n    const { settingState } = this.props\n    const { themeName } = settingState\n    switch (themeName) {\n      case 'dark':\n        return '#242424'\n      case 'default':\n        return 'white'\n      default:\n        return 'transparent'\n    }\n  }\n\n  getLayoutStyle = (size) => ({\n    width: '100%',\n    height: `${size * 100}%`,\n    display: size ? 'inline-block' : 'none',\n    backgroundColor: this.getReactBackgroundColor(),\n  })\n\n  getDevToolsSize() {\n    const { settingState } = this.props\n    const { redux, react, size } = settingState\n    if (!redux || !react) {\n      return {\n        redux: redux ? 1 : 0,\n        react: react ? 1 : 0,\n      }\n    }\n    return { redux: size, react: 1 - size }\n  }\n\n  handlePortOnSubmit = (evt, port) => {\n    ipcRenderer.once('check-port-available-reply', (event, available) => {\n      if (!available) {\n        window.alert(`The port ${port} is already used by another window.`)\n        return\n      }\n      const { debuggerActions } = this.props\n      debuggerActions.setDebuggerLocation({\n        ...JSON.parse(process.env.DEBUGGER_SETTING || '{}'),\n        port,\n      })\n      currentWindow.openDevTools()\n    })\n    ipcRenderer.send('check-port-available', port)\n  }\n\n  renderPortSetting() {\n    return (\n      <div style={styles.wrapBackground}>\n        <FormInput\n          title=\"Type in another React Native packager port\"\n          button=\"Confirm\"\n          inputProps={{\n            type: 'input',\n            value: 19000,\n          }}\n          onInputChange={(value) => Number(value.replace(/\\D/g, '').substr(0, 5)) || ''}\n          onSubmit={this.handlePortOnSubmit}\n        />\n      </div>\n    )\n  }\n\n  renderReduxDevTools(size) {\n    return (\n      <div style={this.getLayoutStyle(size)}>\n        <ReduxDevTools />\n        <Draggable onMove={this.onResize} />\n      </div>\n    )\n  }\n\n  renderReactInspector(size) {\n    return (\n      <div style={this.getLayoutStyle(size)}>\n        <ReactInspector />\n      </div>\n    )\n  }\n\n  render() {\n    const { debuggerState } = this.props\n    const { isPortSettingRequired } = debuggerState\n    if (isPortSettingRequired) {\n      return this.renderPortSetting()\n    }\n    const { redux, react } = this.getDevToolsSize()\n    return (\n      <div style={styles.container}>\n        {this.renderReduxDevTools(redux)}\n        {this.renderReactInspector(react)}\n        {!react && !redux && background}\n      </div>\n    )\n  }\n}\n\nApp.propTypes = {\n  settingState: PropTypes.shape({\n    redux: PropTypes.bool.isRequired,\n    react: PropTypes.bool.isRequired,\n    size: PropTypes.number.isRequired,\n    themeName: PropTypes.string.isRequired,\n  }).isRequired,\n  settingActions: PropTypes.shape({\n    toggleDevTools: PropTypes.func.isRequired,\n    resizeDevTools: PropTypes.func.isRequired,\n    changeDefaultTheme: PropTypes.func.isRequired,\n  }).isRequired,\n  debuggerState: PropTypes.shape({\n    isPortSettingRequired: PropTypes.bool.isRequired,\n  }).isRequired,\n  debuggerActions: PropTypes.shape({\n    setDebuggerLocation: PropTypes.func.isRequired,\n    syncState: PropTypes.func.isRequired,\n  }).isRequired,\n}\n\nexport default connect(\n  (state) => ({\n    debuggerState: state.debugger,\n    settingState: state.setting,\n  }),\n  (dispatch) => ({\n    debuggerActions: bindActionCreators(debuggerActionCreators, dispatch),\n    settingActions: bindActionCreators(settingActionCreators, dispatch),\n  }),\n)(App)\n"
  },
  {
    "path": "app/containers/ReactInspector.js",
    "content": "import { connect } from 'react-redux'\nimport React, { Component } from 'react'\nimport PropTypes from 'prop-types'\nimport { tryADBReverse } from '../utils/adb'\n\nlet ReactServer\nconst getReactInspector = () => {\n  if (ReactServer) return ReactServer\n  // eslint-disable-next-line\n  ReactServer = ReactServer || require('react-devtools-core/standalone').default;\n\n  return ReactServer\n}\nconst containerId = 'react-devtools-container'\n\nconst styles = {\n  container: {\n    display: 'flex',\n    height: '100%',\n    justifyContent: 'center',\n    position: 'relative',\n  },\n  waiting: {\n    height: '100%',\n    display: 'flex',\n    WebkitUserSelect: 'none',\n    textAlign: 'center',\n    color: '#aaa',\n    justifyContent: 'center',\n    alignItems: 'center',\n    position: 'absolute',\n    top: 0,\n    left: 0,\n    right: 0,\n    bottom: 0,\n  },\n}\n\nconst isReactPanelOpen = (props) => props.settingState.react\n\nclass ReactInspector extends Component {\n  static setProjectRoots(projectRoots) {\n    getReactInspector().setProjectRoots(projectRoots)\n  }\n\n  listeningPort = window.reactDevToolsPort\n\n  componentDidMount() {\n    const { debuggerState } = this.props\n    const { worker } = debuggerState\n    if (worker) {\n      this.server = this.startServer()\n      worker.addEventListener('message', this.workerOnMessage)\n    }\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    const { debuggerState } = this.props\n    const { worker } = debuggerState\n    const { worker: nextWorker } = nextProps.debuggerState\n    if (nextWorker && nextWorker !== worker) {\n      this.closeServerIfExists()\n      if (isReactPanelOpen(this.props)) {\n        this.server = this.startServer()\n      }\n      nextWorker.addEventListener('message', this.workerOnMessage)\n    } else if (!nextWorker) {\n      this.closeServerIfExists()\n    }\n    // Open / Close server when react panel opened / hidden\n    if (!worker && !nextWorker) return\n    if (isReactPanelOpen(this.props) && !isReactPanelOpen(nextProps)) {\n      this.closeServerIfExists()\n    } else if (!isReactPanelOpen(this.props) && isReactPanelOpen(nextProps)) {\n      this.closeServerIfExists()\n      this.server = this.startServer()\n    }\n  }\n\n  shouldComponentUpdate() {\n    return false\n  }\n\n  componentWillUnmount() {\n    this.closeServerIfExists()\n  }\n\n  workerOnMessage = (message) => {\n    const { data } = message\n    if (!data || !data.__REPORT_REACT_DEVTOOLS_PORT__) return\n\n    const port = Number(data.__REPORT_REACT_DEVTOOLS_PORT__)\n    const { platform } = data\n    if (port && port !== this.listeningPort) {\n      this.listeningPort = port\n      this.closeServerIfExists()\n      if (isReactPanelOpen(this.props)) {\n        this.server = this.startServer(port)\n      }\n      if (platform === 'android') tryADBReverse(port).catch(() => {})\n    }\n  }\n\n  closeServerIfExists = () => {\n    if (this.server) {\n      this.server.close()\n      this.server = null\n    }\n  }\n\n  startServer(port = this.listeningPort) {\n    let loggedWarn = false\n\n    return getReactInspector()\n      .setStatusListener((status) => {\n        if (!loggedWarn && status === 'Failed to start the server.') {\n          const message = port !== 8097\n            ? 're-open the debugger window might be helpful.'\n            : 'we recommended to upgrade React Native version to 0.39+ for random port support.'\n          console.error(\n            '[RNDebugger]',\n            `Failed to start React DevTools server with port \\`${port}\\`,`,\n            'because another server is listening,',\n            message,\n          )\n          loggedWarn = true\n        }\n      })\n      .setContentDOMNode(document.getElementById(containerId))\n      .startServer(port)\n  }\n\n  render() {\n    return (\n      <div id={containerId} style={styles.container}>\n        <div id=\"waiting\" style={styles.waiting}>\n          <h2>Waiting for React to connect…</h2>\n        </div>\n      </div>\n    )\n  }\n}\n\nReactInspector.propTypes = {\n  debuggerState: PropTypes.shape({\n    worker: PropTypes.shape({\n      addEventListener: PropTypes.func.isRequired,\n    }),\n  }).isRequired,\n}\n\nexport default connect(\n  (state) => ({\n    settingState: state.setting,\n    debuggerState: state.debugger,\n  }),\n  (dispatch) => ({ dispatch }),\n)(ReactInspector)\n"
  },
  {
    "path": "app/containers/redux/DevTools.js",
    "content": "import React from 'react'\nimport { useSelector, useDispatch } from 'react-redux'\nimport styled from 'styled-components'\nimport { Container, Notification } from '@redux-devtools/ui'\nimport { clearNotification } from '@redux-devtools/app/lib/esm/actions'\nimport Actions from '@redux-devtools/app/lib/esm/containers/Actions'\nimport Settings from './Settings'\nimport Header from './Header'\n\nconst StyledContainer = styled(Container)`overflow: hidden;`\n\nfunction App() {\n  const section = useSelector((state) => state.section)\n  const theme = useSelector((state) => state.theme)\n  const notification = useSelector((state) => state.notification)\n\n  const dispatch = useDispatch()\n\n  let body\n  switch (section) {\n    case 'Settings':\n      body = <Settings />\n      break\n    default:\n      body = <Actions />\n  }\n\n  return (\n    <StyledContainer themeData={theme}>\n      <Header section={section} />\n      {body}\n      {notification && (\n        <Notification\n          type={notification.type}\n          onClose={() => dispatch(clearNotification())}\n        >\n          {notification.message}\n        </Notification>\n      )}\n    </StyledContainer>\n  )\n}\n\nexport default App\n"
  },
  {
    "path": "app/containers/redux/Header.js",
    "content": "import React, { useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport { useDispatch } from 'react-redux'\nimport {\n  Tabs, Toolbar, Button, Divider,\n} from '@redux-devtools/ui'\nimport { GoBook } from 'react-icons/go'\nimport styled from 'styled-components'\nimport { changeSection } from '@redux-devtools/app/lib/esm/actions'\nimport { shell } from 'electron'\n\nconst WindowDraggable = styled.div`\n  display: flex;\n  flex: 1;\n  height: 100%;\n  -webkit-app-region: drag;\n  -webkit-user-select: none;\n`\n\nconst tabs = [{ name: 'Actions' }, { name: 'Settings' }]\n\nfunction Header(props) {\n  const { section } = props\n\n  const dispatch = useDispatch()\n\n  const handleChangeSection = useCallback(\n    (sec) => dispatch(changeSection(sec)),\n    [dispatch, changeSection],\n  )\n\n  const openHelp = useCallback(() => shell.openExternal('https://goo.gl/SHU4yL'), [])\n\n  return (\n    <Toolbar compact noBorder borderPosition=\"bottom\">\n      <Tabs\n        main\n        collapsible\n        tabs={tabs}\n        onClick={handleChangeSection}\n        selected={section || 'Actions'}\n        style={{ flex: 'unset' }}\n      />\n      <WindowDraggable />\n      <Divider />\n      <Button\n        title=\"Documentation\"\n        tooltipPosition=\"bottom\"\n        onClick={openHelp}\n      >\n        <GoBook />\n      </Button>\n    </Toolbar>\n  )\n}\n\nHeader.propTypes = {\n  section: PropTypes.string.isRequired,\n}\n\nexport default Header\n"
  },
  {
    "path": "app/containers/redux/Settings.js",
    "content": "/* eslint-disable import/no-named-as-default */\nimport React, { Component } from 'react'\nimport Tabs from '@redux-devtools/ui/lib/esm/Tabs/Tabs'\nimport Themes from '@redux-devtools/app/lib/esm/components/Settings/Themes'\n\nexport default class Settings extends Component {\n  tabs = [\n    { name: 'Themes', component: Themes },\n  ]\n\n  constructor(props) {\n    super(props)\n    this.state = { selected: 'Themes' }\n  }\n\n  handleSelect = (selected) => {\n    this.setState({ selected })\n  }\n\n  render() {\n    const { selected } = this.state\n    return (\n      <Tabs\n        tabs={this.tabs}\n        selected={selected}\n        onClick={this.handleSelect}\n      />\n    )\n  }\n}\n"
  },
  {
    "path": "app/globalStyles.js",
    "content": "import { css, createGlobalStyle } from 'styled-components'\n\nconst commonStyles = css``\n\nexport const GlobalStyle =\n  process.platform !== 'darwin'\n    ? createGlobalStyle`\n        ${commonStyles}\n        ::-webkit-scrollbar {\n          width: 8px;\n          height: 8px;\n          background-color: #95959588;\n        }\n        ::-webkit-scrollbar-thumb {\n          background-color: #33333366;\n        }\n      `\n    : createGlobalStyle`${commonStyles}`\n"
  },
  {
    "path": "app/index.js",
    "content": "import { findAPortNotInUse } from 'portscanner'\nimport { webFrame } from 'electron'\nimport { getCurrentWindow } from '@electron/remote'\nimport React from 'react'\nimport { createRoot } from 'react-dom/client'\nimport { Provider } from 'react-redux'\nimport launchEditor from 'react-dev-utils/launchEditor'\nimport { PersistGate } from 'redux-persist/integration/react'\nimport './setup'\nimport App from './containers/App'\nimport configureStore from './store/configureStore'\nimport { beforeWindowClose } from './actions/debugger'\nimport { invokeDevMethod } from './utils/devMenu'\nimport { client, tryADBReverse } from './utils/adb'\nimport config from './utils/config'\nimport { toggleOpenInEditor, isOpenInEditorEnabled } from './utils/devtools'\nimport { GlobalStyle } from './globalStyles'\n\nconst currentWindow = getCurrentWindow()\n\nwebFrame.setZoomFactor(1)\nwebFrame.setVisualZoomLevelLimits(1, 1)\n\n// Prevent dropped file\ndocument.addEventListener('drop', (e) => {\n  e.preventDefault()\n  e.stopPropagation()\n})\ndocument.addEventListener('dragover', (e) => {\n  e.preventDefault()\n  e.stopPropagation()\n})\n\nlet store\nlet persistor\nconst handleReady = () => {\n  const { defaultReactDevToolsPort = 19567 } = config\n  findAPortNotInUse(Number(defaultReactDevToolsPort)).then((port) => {\n    window.reactDevToolsPort = port\n    const root = createRoot(document.getElementById('root'))\n    root.render(\n      <>\n        <GlobalStyle />\n        <Provider store={store}>\n          <PersistGate loading={null} persistor={persistor}>\n            <App />\n          </PersistGate>\n        </Provider>\n      </>,\n    )\n  })\n}\n\n;({ store, persistor } = configureStore(handleReady))\n\n// Provide for user\nwindow.adb = client\nwindow.adb.reverseAll = tryADBReverse\nwindow.adb.reversePackager = () =>\n  tryADBReverse(store.getState().debugger.location.port)\n\nwindow.checkWindowInfo = () => {\n  const debuggerState = store.getState().debugger\n  return {\n    isWorkerRunning: !!debuggerState.worker,\n    location: debuggerState.location,\n    isPortSettingRequired: debuggerState.isPortSettingRequired,\n  }\n}\n\nwindow.beforeWindowClose = () =>\n  new Promise((resolve) => {\n    if (store.dispatch(beforeWindowClose())) {\n      setTimeout(resolve, 200)\n    } else {\n      resolve()\n    }\n  })\n\n// For security, we should disable nodeIntegration when user use this open a website\nconst originWindowOpen = window.open\nwindow.open = (url, frameName, features = '') => {\n  const featureList = features.split(',')\n  featureList.push('nodeIntegration=0')\n  return originWindowOpen.call(window, url, frameName, featureList.join(','))\n}\n\nwindow.openInEditor = (file, lineNumber) => launchEditor(file, lineNumber)\nwindow.toggleOpenInEditor = () => {\n  const { port } = store.getState().debugger.location\n  return toggleOpenInEditor(currentWindow, port)\n}\nwindow.isOpenInEditorEnabled = () => isOpenInEditorEnabled(currentWindow)\n\nwindow.invokeDevMethod = (name) => invokeDevMethod(name)()\n\n// Package will missing /usr/local/bin,\n// we need fix it for ensure child process work\n// (like launchEditor of react-devtools)\nif (\n  process.env.NODE_ENV === 'production' &&\n  process.platform === 'darwin' &&\n  process.env.PATH.indexOf('/usr/local/bin') === -1\n) {\n  process.env.PATH = `${process.env.PATH}:/usr/local/bin`\n}\n"
  },
  {
    "path": "app/middlewares/debuggerAPI.js",
    "content": "/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\n// Take from https://github.com/facebook/react-native/blob/master/local-cli/server/util/debugger.html\n\nimport { getCurrentWindow } from '@electron/remote'\nimport { bindActionCreators } from 'redux'\nimport { checkPortStatus } from 'portscanner'\nimport * as debuggerActions from '../actions/debugger'\nimport { setDevMenuMethods, networkInspect } from '../utils/devMenu'\nimport { tryADBReverse } from '../utils/adb'\nimport { clearNetworkLogs, selectRNDebuggerWorkerContext } from '../utils/devtools'\nimport config from '../utils/config'\n\nconst currentWindow = getCurrentWindow()\nconst { SET_DEBUGGER_LOCATION, BEFORE_WINDOW_CLOSE } = debuggerActions\n\nlet worker\nlet queuedMessages = []\nlet scriptExecuted = false\nlet actions\nlet host\nlet port\nlet socket\n\nconst APOLLO_MESSAGE_PREFIX = 'ac-devtools:'\n\nconst workerOnMessage = (message) => {\n  const { data } = message\n\n  if (data && data.message?.startsWith(APOLLO_MESSAGE_PREFIX)) {\n    data.__FROM_DEBUGGER_WORKER__ = true\n    postMessage(data, '*')\n    return false\n  }\n\n  if (data && (data.__IS_REDUX_NATIVE_MESSAGE__ || data.__REPORT_REACT_DEVTOOLS_PORT__)) {\n    return true\n  }\n  const list = data && data.__AVAILABLE_METHODS_CAN_CALL_BY_RNDEBUGGER__\n  if (list) {\n    setDevMenuMethods(list, worker)\n    return false\n  }\n  socket.send(JSON.stringify(data))\n}\n\nconst onWindowMessage = (e) => {\n  const { data } = e\n  if (\n    !data?.__FROM_DEBUGGER_WORKER__ &&\n    data?.message?.startsWith(APOLLO_MESSAGE_PREFIX)\n  ) {\n    worker.postMessage({\n      method: 'emitApolloMessage',\n      ...data,\n    })\n    return false\n  }\n}\n\nconst createJSRuntime = () => {\n  // This worker will run the application javascript code,\n  // making sure that it's run in an environment without a global\n  // document, to make it consistent with the JSC executor environment.\n  // eslint-disable-next-line\n  worker = new Worker(`${__webpack_public_path__}RNDebuggerWorker.js`);\n  worker.addEventListener('message', workerOnMessage)\n  window.addEventListener('message', onWindowMessage)\n  actions.setDebuggerWorker(worker, 'connected')\n}\n\nconst shutdownJSRuntime = () => {\n  const { setDebuggerWorker } = actions\n  scriptExecuted = false\n  if (worker) {\n    worker.terminate()\n    window.removeEventListener('message', onWindowMessage)\n    setDevMenuMethods([])\n  }\n  worker = null\n  setDebuggerWorker(null, 'disconnected')\n}\n\nconst isScriptBuildForAndroid = (url) => url && (url.indexOf('.android.bundle') > -1 || url.indexOf('platform=android') > -1)\n\nlet preconnectTimeout\nconst preconnect = async (fn, firstTimeout) => {\n  if (firstTimeout || (await checkPortStatus(port, host)) !== 'open') {\n    preconnectTimeout = setTimeout(() => preconnect(fn), 500)\n    return\n  }\n  socket = await fn()\n}\n\nconst clearLogs = () => {\n  if (process.env.NODE_ENV !== 'development') {\n    console.clear()\n    clearNetworkLogs(currentWindow)\n  }\n}\n\nconst flushQueuedMessages = () => {\n  if (!worker) return\n  // Flush any messages queued up and clear them\n  queuedMessages.forEach((message) => worker.postMessage(message))\n  queuedMessages = []\n}\n\nlet loadCount = 0\nconst checkJSLoadCount = () => {\n  loadCount += 1\n  if (\n    currentWindow.webContents.isDevToolsOpened()\n    && config.timesJSLoadToRefreshDevTools >= 0\n    && loadCount > 0\n    && loadCount % config.timesJSLoadToRefreshDevTools === 0\n  ) {\n    currentWindow.webContents.closeDevTools()\n    currentWindow.webContents.openDevTools()\n    console.warn(\n      '[RNDebugger]',\n      `Refreshed the devtools panel as React Native app was reloaded ${loadCount} times.`,\n      'If you want to update or disable this,',\n      'Open `Debugger` -> `Open Config File` to change `timesJSLoadToRefreshDevTools` field.',\n    )\n    loadCount = 0\n  }\n}\n\nconst connectToDebuggerProxy = async () => {\n  const ws = new WebSocket(`ws://${host}:${port}/debugger-proxy?role=debugger&name=Chrome`)\n\n  const { setDebuggerStatus } = actions\n  ws.onopen = () => setDebuggerStatus('waiting')\n  ws.onmessage = async (message) => {\n    if (!message.data) return\n\n    const object = JSON.parse(message.data)\n    if (object.$event === 'client-disconnected') {\n      shutdownJSRuntime()\n      return\n    }\n    if (!object.method) return\n\n    // Special message that asks for a new JS runtime\n    if (object.method === 'prepareJSRuntime') {\n      shutdownJSRuntime()\n      createJSRuntime()\n      clearLogs()\n      selectRNDebuggerWorkerContext(currentWindow)\n      ws.send(JSON.stringify({ replyID: object.id }))\n    } else if (object.method === '$disconnected') {\n      shutdownJSRuntime()\n    } else {\n      if (!worker) return\n      if (object.method === 'executeApplicationScript') {\n        object.networkInspect = networkInspect.isEnabled()\n        object.reactDevToolsPort = window.reactDevToolsPort\n        if (isScriptBuildForAndroid(object.url)) {\n          // Reserve React Inspector port for debug via USB on Android real device\n          tryADBReverse(window.reactDevToolsPort).catch(() => {})\n        }\n        // Clear logs even if no error catched\n        clearLogs()\n        scriptExecuted = true\n        checkJSLoadCount()\n      }\n      if (scriptExecuted) {\n        // Otherwise, pass through to the worker provided the\n        // application script has been executed. If not add\n        // it to a queue until it has been executed.\n        worker.postMessage(object)\n        flushQueuedMessages()\n      } else {\n        queuedMessages.push(object)\n      }\n    }\n  }\n\n  ws.onerror = () => {}\n  ws.onclose = (e) => {\n    shutdownJSRuntime()\n    if (e.reason) {\n      console.warn(e.reason)\n    }\n    preconnect(connectToDebuggerProxy, true)\n  }\n  return ws\n}\n\nconst setDebuggerLoc = ({ host: packagerHost, port: packagerPort }) => {\n  if (host === packagerHost && port === Number(packagerPort)) return\n\n  host = packagerHost || 'localhost'\n  port = packagerPort || config.port || 8081\n  if (socket) {\n    shutdownJSRuntime()\n    socket.close()\n  } else {\n    // Should ensure cleared timeout if called preconnect twice\n    clearTimeout(preconnectTimeout)\n    preconnect(connectToDebuggerProxy)\n  }\n}\n\nexport default ({ dispatch }) => {\n  actions = bindActionCreators(debuggerActions, dispatch)\n\n  return (next) => (action) => {\n    if (action.type === SET_DEBUGGER_LOCATION) {\n      setDebuggerLoc(action.loc)\n    }\n    if (action.type === BEFORE_WINDOW_CLOSE) {\n      // Return boolean instead of handle reducer\n      if (!worker) return false\n      worker.postMessage({ method: 'beforeTerminate' })\n      return true\n    }\n    return next(action)\n  }\n}\n"
  },
  {
    "path": "app/middlewares/reduxAPI.js",
    "content": "import { bindActionCreators } from 'redux'\nimport { ipcRenderer } from 'electron'\nimport { getGlobal } from '@electron/remote'\n\nimport { UPDATE_STATE, LIFTED_ACTION } from '@redux-devtools/app/lib/esm/constants/actionTypes'\nimport { DISCONNECTED } from '@redux-devtools/app/lib/esm/constants/socketActionTypes'\nimport { nonReduxDispatch } from '@redux-devtools/app/lib/esm/utils/monitorActions'\nimport { showNotification, liftedDispatch } from '@redux-devtools/app/lib/esm/actions'\nimport { getActiveInstance } from '@redux-devtools/app/lib/esm/reducers/instances'\n\nimport { SET_DEBUGGER_WORKER, SYNC_STATE } from '../actions/debugger'\nimport { setReduxDevToolsMethods, updateSliderContent } from '../utils/devMenu'\n\nconst unboundActions = {\n  showNotification,\n  updateState: (request) => ({\n    type: UPDATE_STATE,\n    request: request.data ? { ...request.data, id: request.id } : request,\n  }),\n  liftedDispatch,\n}\nlet actions\nlet worker\nlet store\n\nconst toWorker = ({\n  message, action, state, toAll,\n}) => {\n  if (!worker) return\n\n  const { instances } = store.getState()\n  const instanceId = getActiveInstance(instances)\n  const id = instances.options[instanceId].connectionId\n  worker.postMessage({\n    method: 'emitReduxMessage',\n    content: {\n      type: message,\n      action,\n      state: nonReduxDispatch(store, message, instanceId, action, state, instances),\n      instanceId,\n      id,\n      toAll,\n    },\n  })\n}\n\nconst postImportMessage = (state) => {\n  if (!worker) return\n\n  const { instances } = store.getState()\n  const instanceId = getActiveInstance(instances)\n  const id = instances.options[instanceId].connectionId\n  worker.postMessage({\n    method: 'emitReduxMessage',\n    content: {\n      type: 'IMPORT',\n      state,\n      instanceId,\n      id,\n    },\n  })\n}\n\n// Receive messages from worker\nconst messaging = (message) => {\n  const { data } = message\n  if (!data || !data.__IS_REDUX_NATIVE_MESSAGE__) return\n\n  const { content: request } = data\n  if (request.type === 'ERROR') {\n    actions.showNotification(request.payload)\n    return\n  }\n  actions.updateState(request)\n}\n\nconst initWorker = (wkr) => {\n  wkr.addEventListener('message', messaging)\n  worker = wkr\n}\n\nconst removeWorker = () => {\n  worker = null\n}\n\nconst syncLiftedState = (liftedState) => {\n  if (!getGlobal('isSyncState')()) return\n\n  const { actionsById } = liftedState\n  const payload = []\n  liftedState.stagedActionIds.slice(1).forEach((id) => {\n    payload.push(actionsById[id].action)\n  })\n  const serialized = JSON.stringify({ payload: JSON.stringify(payload) })\n  ipcRenderer.send('sync-state', serialized)\n}\n\nexport default (inStore) => {\n  store = inStore\n  actions = bindActionCreators(unboundActions, store.dispatch)\n  return (next) => (action) => {\n    if (action.type === SET_DEBUGGER_WORKER) {\n      if (action.worker) {\n        initWorker(action.worker)\n      } else {\n        removeWorker(action.worker)\n        setReduxDevToolsMethods(false)\n        next({ type: DISCONNECTED })\n      }\n    }\n    if (action.type === LIFTED_ACTION) {\n      toWorker(action)\n    }\n    if (\n      action.type === UPDATE_STATE\n      || action.type === LIFTED_ACTION\n      || action.type === SYNC_STATE\n    ) {\n      next(action)\n      const state = store.getState()\n      const { instances } = state\n      const id = getActiveInstance(instances)\n      const liftedState = instances.states[id]\n      if (liftedState && liftedState.computedStates.length > 1) {\n        setReduxDevToolsMethods(true, actions.liftedDispatch)\n      } else if (liftedState && liftedState.computedStates.length <= 1) {\n        setReduxDevToolsMethods(false)\n      }\n      updateSliderContent(liftedState, action.action && action.action.dontUpdateTouchBarSlider)\n      if (action.request && action.request.type === 'ACTION') {\n        syncLiftedState(liftedState)\n      }\n      if (action.type === SYNC_STATE) {\n        postImportMessage(action.payload)\n      }\n      return\n    }\n    return next(action)\n  }\n}\n"
  },
  {
    "path": "app/reducers/debugger.js",
    "content": "import {\n  SET_DEBUGGER_STATUS,\n  SET_DEBUGGER_WORKER,\n  SET_DEBUGGER_LOCATION,\n} from '../actions/debugger'\nimport config from '../utils/config'\n\nfunction getStatusMessage(status, port) {\n  let message\n  switch (status) {\n    case 'new':\n      message = 'New Window'\n      break\n    case 'waiting':\n      message = 'Waiting for client connection'\n      break\n    case 'connected':\n      message = 'Connected'\n      break\n    case 'disconnected':\n    default:\n      message = 'Attempting reconnection'\n  }\n  if (status !== 'new') {\n    message += ` (port ${port})`\n  }\n  const title = `React Native Debugger - ${message}`\n  if (title !== document.title) {\n    document.title = title\n  }\n  return message\n}\n\nconst initialState = {\n  worker: null,\n  status: 'disconnected',\n  statusMessage: getStatusMessage(config.isPortSettingRequired ? 'new' : 'disconnected', 8081),\n  location: {\n    host: 'localhost',\n    port: config.port || 8081,\n  },\n  isPortSettingRequired: config.isPortSettingRequired,\n}\n\nconst actionsMap = {\n  [SET_DEBUGGER_STATUS]: (state, action) => {\n    const status = action.status || initialState.status\n    const newState = {\n      ...state,\n      status,\n      statusMessage: getStatusMessage(status, state.location.port),\n    }\n    return newState\n  },\n  [SET_DEBUGGER_WORKER]: (state, action) => {\n    const status = action.status || initialState.status\n    const newState = {\n      ...state,\n      worker: action.worker,\n      status,\n      statusMessage: getStatusMessage(status, state.location.port),\n    }\n    return newState\n  },\n  [SET_DEBUGGER_LOCATION]: (state, action) => {\n    const location = { ...state.location, ...action.loc }\n    const newState = {\n      ...state,\n      location,\n      statusMessage: getStatusMessage(state.status, location.port),\n      isPortSettingRequired: false,\n    }\n    return newState\n  },\n}\n\nexport default (state = initialState, action = {}) => {\n  const reduceFn = actionsMap[action.type]\n  if (!reduceFn) return state\n  return reduceFn(state, action)\n}\n"
  },
  {
    "path": "app/reducers/index.js",
    "content": "import { combineReducers } from 'redux'\nimport { section } from '@redux-devtools/app/lib/esm/reducers/section'\n// import { connection } from '@redux-devtools/app/lib/esm/reducers/connection';\n// import { socket } from '@redux-devtools/app/lib/esm/reducers/socket';\nimport { monitor } from '@redux-devtools/app/lib/esm/reducers/monitor'\nimport { notification } from '@redux-devtools/app/lib/esm/reducers/notification'\nimport { instances } from '@redux-devtools/app/lib/esm/reducers/instances'\nimport { reports } from '@redux-devtools/app/lib/esm/reducers/reports'\nimport { theme } from '@redux-devtools/app/lib/esm/reducers/theme'\n\nimport setting from './setting'\nimport debuggerReducer from './debugger'\n\nexport default combineReducers({\n  section,\n  instances,\n  reports,\n  theme,\n  monitor,\n  notification,\n\n  setting,\n  debugger: debuggerReducer,\n})\n"
  },
  {
    "path": "app/reducers/setting.js",
    "content": "import { TOGGLE_DEVTOOLS, RESIZE_DEVTOOLS, CHANGE_DEFAULT_THEME } from '../actions/setting'\n\nconst initialState = {\n  react: true,\n  redux: true,\n  size: 0.6,\n  themeName: null,\n}\n\nconst actionsMap = {\n  [TOGGLE_DEVTOOLS]: (state, action) => ({\n    ...state,\n    [action.name]: !state[action.name],\n  }),\n  [RESIZE_DEVTOOLS]: (state, action) => {\n    if (!state.redux || !state.react) {\n      return state\n    }\n    const { size } = action\n    if (size < 0.2) return { ...state, size: 0.2 }\n    if (size > 0.8) return { ...state, size: 0.8 }\n    return { ...state, size }\n  },\n  [CHANGE_DEFAULT_THEME]: (state, action) => ({\n    ...state,\n    themeName: action.themeName,\n  }),\n}\n\nexport default (state = initialState, action = {}) => {\n  const reduceFn = actionsMap[action.type]\n  if (!reduceFn) return state\n  return reduceFn(state, action)\n}\n"
  },
  {
    "path": "app/setup.js",
    "content": "import config from './utils/config'\n\nif (config.editor) {\n  process.env.EDITOR = config.editor\n}\n\nif (config.fontFamily) {\n  const styleEl = document.createElement('style')\n  document.head.appendChild(styleEl)\n  styleEl.sheet.insertRule(\n    `div *, span * { font-family: ${config.fontFamily} !important; }`,\n    0,\n  )\n}\n"
  },
  {
    "path": "app/store/configureStore.js",
    "content": "import { createStore, applyMiddleware, compose } from 'redux'\nimport { persistReducer, persistStore } from 'redux-persist'\nimport localForage from 'localforage'\nimport { exportStateMiddleware } from '@redux-devtools/app/lib/cjs/middlewares/exportState'\nimport { instancesInitialState } from '@redux-devtools/app/lib/esm/reducers/instances'\nimport debuggerAPI from '../middlewares/debuggerAPI'\nimport reduxAPI from '../middlewares/reduxAPI'\nimport rootReducer from '../reducers'\n\nconst persistConfig = {\n  key: 'redux-devtools',\n  blacklist: ['instances', 'debugger'],\n  storage: localForage,\n}\n\nconst persistedReducer = persistReducer(persistConfig, rootReducer)\n\nconst middlewares = applyMiddleware(\n  debuggerAPI,\n  exportStateMiddleware,\n  reduxAPI,\n)\n\n// If Redux DevTools Extension is installed use it, otherwise use Redux compose\n/* eslint-disable no-underscore-dangle */\nconst composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose\n/* eslint-enable no-underscore-dangle */\nconst enhancer = composeEnhancers(middlewares)\n\nconst initialState = {\n  instances: {\n    ...instancesInitialState,\n    selected: '',\n  },\n}\n\nexport default (callback) => {\n  const store = createStore(persistedReducer, initialState, enhancer)\n  const persistor = persistStore(store, null, () => callback?.(store))\n  return { store, persistor }\n}\n"
  },
  {
    "path": "app/utils/adb.js",
    "content": "import adb from 'adbkit'\n\nexport const client = adb.createClient({ host: '127.0.0.1' })\n\nconst reverse = (device, port) => client.reverse(device, `tcp:${port}`, `tcp:${port}`)\n\nexport const tryADBReverse = async (port) => {\n  const devices = await client.listDevices().filter((device) => device.type === 'device')\n  return Promise.all(devices.map((device) => reverse(device.id, port)))\n}\n"
  },
  {
    "path": "app/utils/config.js",
    "content": "import { getCurrentWindow } from '@electron/remote'\n\nexport default getCurrentWindow().debuggerConfig || {}\n"
  },
  {
    "path": "app/utils/devMenu.js",
    "content": "import { TouchBar, nativeImage, getCurrentWindow } from '@electron/remote'\n\nimport { ipcRenderer } from 'electron'\nimport config from './config'\n\nconst { TouchBarButton, TouchBarSlider } = TouchBar || {}\nconst currentWindow = getCurrentWindow()\n\nlet worker\nlet availableMethods = []\n\n/* reload, toggleElementInspector, networkInspect */\nlet leftBar = {}\n\nlet isSliderEnabled\nlet storeLiftedState\n/* slider, prev, next */\nlet rightBar = {}\n\nconst getBarItems = (bar) => Object.keys(bar)\n  .map((key) => bar[key])\n  .filter((barItem) => !!barItem)\nconst setTouchBar = () => currentWindow.setTouchBar(\n  new TouchBar({\n    items: [\n      ...getBarItems(leftBar),\n      ...(isSliderEnabled ? getBarItems(rightBar) : []),\n    ],\n  }),\n)\n\nconst invokeDevMenuMethod = ({ name, args }) => worker && worker.postMessage({ method: 'invokeDevMenuMethod', name, args })\n\nlet networkInspectEnabled = !!config.networkInspect\nconst sendContextMenuUpdate = () => {\n  ipcRenderer.send(`context-menu-available-methods-update-${currentWindow.id}`, {\n    availableMethods,\n    networkInspectEnabled,\n  })\n}\n\nexport const networkInspect = {\n  isEnabled: () => !!networkInspectEnabled,\n  getHighlightColor: () => (networkInspectEnabled ? '#7A7A7A' : '#363636'),\n  toggle() {\n    networkInspectEnabled = !networkInspectEnabled\n    sendContextMenuUpdate()\n  },\n}\n\nconst devMenuMethods = {\n  reload: () => invokeDevMenuMethod({ name: 'reload' }),\n  toggleElementInspector: () => invokeDevMenuMethod({ name: 'toggleElementInspector' }),\n  show: () => invokeDevMenuMethod({ name: 'show' }),\n  networkInspect: () => {\n    networkInspect.toggle()\n    if (leftBar.networkInspect) {\n      leftBar.networkInspect.backgroundColor = networkInspect.getHighlightColor()\n    }\n    invokeDevMenuMethod({\n      name: 'networkInspect',\n      args: [networkInspectEnabled],\n    })\n  },\n  showAsyncStorage: () => {\n    invokeDevMenuMethod({ name: 'showAsyncStorage' })\n  },\n  clearAsyncStorage: () => {\n    if (\n      window.confirm(\n        'Call `AsyncStorage.clear()` in current React Native debug session?',\n      )\n    ) {\n      invokeDevMenuMethod({ name: 'clearAsyncStorage' })\n    }\n  },\n}\n\nexport const invokeDevMethod = (name) => () => {\n  if (availableMethods.includes(name)) {\n    return devMenuMethods[name]()\n  }\n}\n\nconst hslShift = [0.5, 0.2, 0.8]\nconst icon = (name, resizeOpts) => {\n  const image = nativeImage.createFromNamedImage(name, hslShift)\n  return image.resize(resizeOpts)\n}\n\nlet namedImages\nconst initNamedImages = () => {\n  if (process.platform !== 'darwin' || namedImages) return\n  namedImages = {\n    reload: icon('NSTouchBarRefreshTemplate', { height: 20 }),\n    toggleElementInspector: icon('NSTouchBarQuickLookTemplate', { height: 18 }),\n    networkInspect: icon('NSTouchBarRecordStartTemplate', { height: 20 }),\n    prev: icon('NSTouchBarGoBackTemplate', { height: 20 }),\n    next: icon('NSTouchBarGoForwardTemplate', { height: 20 }),\n  }\n}\n\nconst setDevMenuMethodsForTouchBar = () => {\n  if (process.platform !== 'darwin') return\n  initNamedImages()\n\n  leftBar = {\n    // Default items\n    networkInspect: new TouchBarButton({\n      icon: namedImages.networkInspect,\n      click: devMenuMethods.networkInspect,\n      backgroundColor: networkInspect.getHighlightColor(),\n    }),\n  }\n  if (availableMethods.includes('reload')) {\n    leftBar.reload = new TouchBarButton({\n      icon: namedImages.reload,\n      click: devMenuMethods.reload,\n    })\n  }\n  if (availableMethods.includes('toggleElementInspector')) {\n    leftBar.toggleElementInspector = new TouchBarButton({\n      icon: namedImages.toggleElementInspector,\n      click: devMenuMethods.toggleElementInspector,\n    })\n  }\n  setTouchBar()\n}\n\n// Reset TouchBar when reload the app\nsetDevMenuMethodsForTouchBar([])\n\nexport const setDevMenuMethods = (list, wkr) => {\n  worker = wkr\n  availableMethods = list\n  sendContextMenuUpdate()\n  setDevMenuMethodsForTouchBar()\n}\n\nexport const setReduxDevToolsMethods = (enabled, dispatch) => {\n  if (process.platform !== 'darwin') return\n  initNamedImages()\n\n  // Already setup\n  if (enabled && isSliderEnabled) return\n\n  const handleSliderChange = (nextIndex, dontUpdateTouchBarSlider = false) => dispatch({\n    type: 'JUMP_TO_STATE',\n    actionId: storeLiftedState.stagedActionIds[nextIndex],\n    index: nextIndex,\n    dontUpdateTouchBarSlider,\n  })\n\n  rightBar = {\n    slider: new TouchBarSlider({\n      value: 0,\n      minValue: 0,\n      maxValue: 0,\n      change(nextIndex) {\n        if (nextIndex !== storeLiftedState.currentStateIndex) {\n          // Set `dontUpdateTouchBarSlider` true for keep slide experience\n          handleSliderChange(nextIndex, true)\n        }\n      },\n    }),\n    prev: new TouchBarButton({\n      icon: namedImages.prev,\n      click() {\n        const nextIndex = storeLiftedState.currentStateIndex - 1\n        if (nextIndex >= 0) {\n          handleSliderChange(nextIndex)\n        }\n      },\n    }),\n    next: new TouchBarButton({\n      icon: namedImages.next,\n      click() {\n        const nextIndex = storeLiftedState.currentStateIndex + 1\n        if (nextIndex < storeLiftedState.computedStates.length) {\n          handleSliderChange(nextIndex)\n        }\n      },\n    }),\n  }\n  isSliderEnabled = enabled\n  setTouchBar()\n}\n\nexport const updateSliderContent = (liftedState, dontUpdateTouchBarSlider) => {\n  if (process.platform !== 'darwin') return\n\n  storeLiftedState = liftedState\n  if (isSliderEnabled && !dontUpdateTouchBarSlider) {\n    const { currentStateIndex, computedStates } = liftedState\n    rightBar.slider.maxValue = computedStates.length - 1\n    rightBar.slider.value = currentStateIndex\n  }\n}\n"
  },
  {
    "path": "app/utils/devtools.js",
    "content": "import { getCatchConsoleLogScript } from '../../electron/devtools'\n\nlet enabled = false\nexport const toggleOpenInEditor = (win, port) => {\n  if (win.devToolsWebContents) {\n    enabled = !enabled\n    return win.devToolsWebContents.executeJavaScript(`(() => {\n      ${getCatchConsoleLogScript(port)}\n      window.__IS_OPEN_IN_EDITOR_ENABLED__ = ${enabled};\n    })()`)\n  }\n}\n\nexport const isOpenInEditorEnabled = () => enabled\n\nexport const clearNetworkLogs = (win) => {\n  if (win.devToolsWebContents) {\n    return win.devToolsWebContents.executeJavaScript(`setTimeout(() => {\n      const { network } = UI.panels;\n      if (network && network.networkLogView && network.networkLogView.reset) {\n        network.networkLogView.reset()\n      }\n    }, 100)`)\n  }\n}\n\nexport const selectRNDebuggerWorkerContext = (win) => {\n  if (win.devToolsWebContents) {\n    return win.devToolsWebContents.executeJavaScript(`setTimeout(() => {\n      const { console } = UI.panels;\n      if (console && console.view && console.view.consoleContextSelector) {\n        const selector = console.view.consoleContextSelector;\n        const item = selector.items.items.find(\n          item => item.label() === 'RNDebuggerWorker.js'\n        );\n        if (item) {\n          selector.itemSelected(item);\n        }\n      }\n    }, 100)`)\n  }\n}\n"
  },
  {
    "path": "app/worker/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"no-restricted-globals\": \"off\"\n  }\n}"
  },
  {
    "path": "app/worker/apollo.js",
    "content": "\nexport function handleApolloClient() {\n  // eslint-disable-next-line global-require\n  require('apollo-client-devtools/build/hook')\n}\n"
  },
  {
    "path": "app/worker/asyncStorage.js",
    "content": "export const getClearAsyncStorageFn = (AsyncStorage) => {\n  if (!AsyncStorage.clear) return\n  return () => AsyncStorage.clear().catch((f) => f)\n}\n\nfunction convertError(error) {\n  if (!error) {\n    return null\n  }\n  const out = new Error(error.message)\n  out.key = error.key\n  return out\n}\n\nfunction convertErrors(errs) {\n  if (!errs) {\n    return null\n  }\n  return (Array.isArray(errs) ? errs : [errs]).map((e) => convertError(e))\n}\n\nexport const getSafeAsyncStorage = (NativeModules) => {\n  const RCTAsyncStorage = NativeModules\n    && (NativeModules.RNC_AsyncSQLiteDBStorage\n      || NativeModules.RNCAsyncStorage\n      || NativeModules.PlatformLocalStorage\n      || NativeModules.AsyncRocksDBStorage\n      || NativeModules.AsyncSQLiteDBStorage\n      || NativeModules.AsyncLocalStorage)\n\n  return {\n    getItem(key) {\n      if (!RCTAsyncStorage) return Promise.resolve(null)\n      return new Promise((resolve, reject) => {\n        RCTAsyncStorage.multiGet([key], (errors, result) => {\n          // Unpack result to get value from [[key,value]]\n          const value = result && result[0] && result[0][1] ? result[0][1] : null\n          const errs = convertErrors(errors)\n          if (errs) {\n            reject(errs[0])\n          } else {\n            resolve(value)\n          }\n        })\n      })\n    },\n    async setItem(key, value) {\n      if (!RCTAsyncStorage) return Promise.resolve(null)\n      return new Promise((resolve, reject) => {\n        RCTAsyncStorage.multiSet([[key, value]], (errors) => {\n          const errs = convertErrors(errors)\n          if (errs) {\n            reject(errs[0])\n          } else {\n            resolve(null)\n          }\n        })\n      })\n    },\n    clear() {\n      if (!RCTAsyncStorage) return Promise.resolve(null)\n      return new Promise((resolve, reject) => {\n        RCTAsyncStorage.clear((error) => {\n          if (error && convertError(error)) {\n            reject(convertError(error))\n          } else {\n            resolve(null)\n          }\n        })\n      })\n    },\n    getAllKeys() {\n      if (!RCTAsyncStorage) return Promise.resolve(null)\n      return new Promise((resolve, reject) => {\n        RCTAsyncStorage.getAllKeys((error, keys) => {\n          if (error) {\n            reject(convertError(error))\n          } else {\n            resolve(keys)\n          }\n        })\n      })\n    },\n  }\n}\n\nexport const getShowAsyncStorageFn = (AsyncStorage) => {\n  if (!AsyncStorage.getAllKeys || !AsyncStorage.getItem) return\n  return async () => {\n    const keys = await AsyncStorage.getAllKeys()\n    if (keys && keys.length) {\n      const items = await Promise.all(\n        keys.map((key) => AsyncStorage.getItem(key)),\n      )\n      const table = {}\n      keys.forEach((key, index) => {\n        table[key] = { content: items[index] }\n      })\n      console.table(table)\n    } else {\n      console.log('[RNDebugger] No AsyncStorage content.')\n    }\n  }\n}\n"
  },
  {
    "path": "app/worker/devMenu.js",
    "content": "/* eslint-disable no-underscore-dangle */\n\nimport { toggleNetworkInspect } from './networkInspect'\nimport { getClearAsyncStorageFn, getShowAsyncStorageFn, getSafeAsyncStorage } from './asyncStorage'\n\nlet availableDevMenuMethods = {}\n\nexport const checkAvailableDevMenuMethods = ({ NativeModules }) => {\n  // RN 0.43 use DevSettings, DevMenu will be deprecated\n  const DevSettings = NativeModules.DevSettings || NativeModules.DevMenu\n  // Currently `show dev menu` is only on DevMenu\n  const showDevMenu = (DevSettings && DevSettings.show)\n    || (NativeModules.DevMenu && NativeModules.DevMenu.show)\n    || undefined\n\n  const AsyncStorage = getSafeAsyncStorage(NativeModules)\n  const methods = {\n    ...DevSettings,\n    show: showDevMenu,\n    networkInspect: toggleNetworkInspect,\n    showAsyncStorage: getShowAsyncStorageFn(AsyncStorage),\n    clearAsyncStorage: getClearAsyncStorageFn(AsyncStorage),\n  }\n  if (methods.showAsyncStorage) {\n    window.showAsyncStorageContentInDev = methods.showAsyncStorage\n  }\n  const result = Object.keys(methods).filter((key) => !!methods[key])\n  availableDevMenuMethods = methods\n\n  postMessage({ __AVAILABLE_METHODS_CAN_CALL_BY_RNDEBUGGER__: result })\n}\n\nexport const invokeDevMenuMethodIfAvailable = (name, args = []) => {\n  const method = availableDevMenuMethods[name]\n  if (method) method(...args)\n}\n"
  },
  {
    "path": "app/worker/index.js",
    "content": "/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n/* global __fbBatchedBridge, importScripts: true */\n\n// Edit from https://github.com/facebook/react-native/blob/master/local-cli/server/util/debuggerWorker.js\n\nimport './setup'\nimport { checkAvailableDevMenuMethods, invokeDevMenuMethodIfAvailable } from './devMenu'\nimport { reportDefaultReactDevToolsPort } from './reactDevTools'\nimport devToolsEnhancer, { composeWithDevTools } from './reduxAPI'\nimport * as RemoteDev from './remotedev'\nimport { getRequiredModules } from './utils'\nimport { toggleNetworkInspect } from './networkInspect'\nimport { handleApolloClient } from './apollo'\n\n/* eslint-disable no-underscore-dangle */\nself.__REMOTEDEV__ = RemoteDev\n\ndevToolsEnhancer.send = RemoteDev.send\ndevToolsEnhancer.connect = RemoteDev.connect\ndevToolsEnhancer.disconnect = RemoteDev.disconnect\n\n// Deprecated API, these may removed when redux-devtools-extension 3.0 release\nself.devToolsExtension = devToolsEnhancer\nself.reduxNativeDevTools = devToolsEnhancer\nself.reduxNativeDevToolsCompose = composeWithDevTools\n\nself.__REDUX_DEVTOOLS_EXTENSION__ = devToolsEnhancer\nself.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ = composeWithDevTools\n\nconst setupRNDebuggerBeforeImportScript = (message) => {\n  self.__REACT_DEVTOOLS_PORT__ = message.reactDevToolsPort\n  if (message.networkInspect) {\n    self.__NETWORK_INSPECT__ = toggleNetworkInspect\n  }\n}\n\nconst noop = (f) => f\nconst setupRNDebugger = async (message) => {\n  // We need to regularly update JS runtime\n  // because the changes of worker message (Redux DevTools, DevMenu)\n  // doesn't notify to the remote JS runtime\n  self.__RND_INTERVAL__ = setInterval(noop, 100); // eslint-disable-line\n\n  handleApolloClient()\n  toggleNetworkInspect(message.networkInspect)\n  const modules = await getRequiredModules(message.moduleSize)\n  if (modules) {\n    checkAvailableDevMenuMethods(modules)\n    reportDefaultReactDevToolsPort(modules)\n  }\n}\n\nconst messageHandlers = {\n  executeApplicationScript(message, sendReply) {\n    setupRNDebuggerBeforeImportScript(message)\n\n    Object.keys(message.inject).forEach((key) => {\n      self[key] = JSON.parse(message.inject[key])\n    })\n    let error\n    try {\n      importScripts(message.url)\n    } catch (err) {\n      error = err.message\n    }\n\n    if (!error) {\n      setupRNDebugger(message)\n    }\n\n    sendReply(null /* result */, error)\n\n    return false\n  },\n  emitReduxMessage() {\n    // pass to other listeners\n    return true\n  },\n  emitApolloMessage() {\n    // pass to other listeners\n    return true\n  },\n  invokeDevMenuMethod({ name, args }) {\n    invokeDevMenuMethodIfAvailable(name, args)\n    return false\n  },\n  beforeTerminate() {\n    // Clean for notify native bridge\n    if (window.__RND_INTERVAL__) {\n      clearInterval(window.__RND_INTERVAL__)\n      window.__RND_INTERVAL__ = null\n    }\n    return false\n  },\n}\n\naddEventListener('message', (message) => {\n  const object = message.data\n\n  const sendReply = (result, error) => {\n    postMessage({ replyID: object.id, result, error })\n  }\n\n  const handler = messageHandlers[object.method]\n  if (handler) {\n    // Special cased handlers\n    return handler(object, sendReply)\n  }\n  // Other methods get called on the bridge\n  let returnValue = [[], [], [], 0]\n  let error\n  try {\n    if (typeof __fbBatchedBridge === 'object') {\n      returnValue = __fbBatchedBridge[object.method].apply(null, object.arguments)\n    } else {\n      error = 'Failed to call function, __fbBatchedBridge is undefined'\n    }\n  } catch (err) {\n    error = err.message\n  } finally {\n    sendReply(JSON.stringify(returnValue), error)\n  }\n  return false\n})\n"
  },
  {
    "path": "app/worker/networkInspect.js",
    "content": "import getRNDebuggerFetchPolyfills from './polyfills/fetch'\n\nconst isWorkerMethod = (fn) => String(fn).indexOf('[native code]') > -1\n\n/* eslint-disable no-underscore-dangle */\nlet networkInspect\n\nexport const toggleNetworkInspect = (enabled) => {\n  if (!enabled && networkInspect) {\n    self.fetch = networkInspect.fetch\n    self.XMLHttpRequest = networkInspect.XMLHttpRequest\n    self.FormData = networkInspect.FormData\n    self.Headers = networkInspect.Headers\n    self.Request = networkInspect.Request\n    self.Response = networkInspect.Response\n    networkInspect = null\n    return\n  }\n  if (!enabled) return\n  if (enabled && networkInspect) return\n  if (isWorkerMethod(self.XMLHttpRequest) || isWorkerMethod(self.FormData)) {\n    console.warn(\n      '[RNDebugger] '\n        + 'I tried to enable Network Inspect but XHR '\n        + \"have been replaced by worker's XHR. \"\n        + 'You can disable Network Inspect (documentation: https://goo.gl/BVvEkJ) '\n        + 'or tracking your app code if you have called '\n        + '`global.XMLHttpRequest = global.originalXMLHttpRequest`.',\n    )\n    return\n  }\n  networkInspect = {\n    fetch: self.fetch,\n    XMLHttpRequest: self.XMLHttpRequest,\n    FormData: self.FormData,\n    Headers: self.Headers,\n    Request: self.Request,\n    Response: self.Response,\n  }\n\n  self.XMLHttpRequest = self.originalXMLHttpRequest\n    ? self.originalXMLHttpRequest\n    : self.XMLHttpRequest\n  self.FormData = self.originalFormData ? self.originalFormData : self.FormData\n  const {\n    fetch, Headers, Request, Response,\n  } = getRNDebuggerFetchPolyfills()\n  self.fetch = fetch\n  self.Headers = Headers\n  self.Request = Request\n  self.Response = Response\n\n  console.log(\n    '[RNDebugger]',\n    'Network Inspect is enabled,',\n    'see the documentation (https://goo.gl/yEcRrU) for more information.',\n  )\n}\n\n/*\n * `originalXMLHttpRequest` haven't permission to set forbidden header name\n * (https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name)\n * We have to use Electron session to solve this problem (See electron/main.js)\n */\nconst forbiddenHeaderNames = [\n  'Accept-Charset',\n  'Accept-Encoding',\n  'Access-Control-Request-Headers',\n  'Access-Control-Request-Method',\n  'Connection',\n  'Content-Length',\n  'Cookie',\n  'Cookie2',\n  'Date',\n  'DNT',\n  'Expect',\n  'Host',\n  'Keep-Alive',\n  'Origin',\n  'Referer',\n  'TE',\n  'Trailer',\n  'Transfer-Encoding',\n  'Upgrade',\n  'Via',\n  // Actually it still blocked on Chrome\n  'User-Agent',\n]\nforbiddenHeaderNames.forEach((name) => forbiddenHeaderNames.push(name.toLowerCase()))\n\nconst isForbiddenHeaderName = (header) => forbiddenHeaderNames.includes(header)\n  || header.startsWith('Proxy-')\n  || header.startsWith('proxy-')\n  || header.startsWith('Sec-')\n  || header.startsWith('sec-')\n\nexport const replaceForbiddenHeadersForWorkerXHR = () => {\n  if (!isWorkerMethod(self.XMLHttpRequest)) return\n  const originalSetRequestHeader = self.XMLHttpRequest.prototype.setRequestHeader\n  self.XMLHttpRequest.prototype.setRequestHeader = function setRequestHeader(header, value) {\n    let replacedHeader = header\n    if (isForbiddenHeaderName(header)) {\n      replacedHeader = `__RN_DEBUGGER_SET_HEADER_REQUEST_${header}`\n    }\n    return originalSetRequestHeader.call(this, replacedHeader, value)\n  }\n}\n\nexport const addURIWarningForWorkerFormData = () => {\n  if (!isWorkerMethod(self.FormData)) return\n  const originAppend = FormData.prototype.append\n  self.FormData.prototype.append = function append(key, value) {\n    if (value && value.uri) {\n      console.warn(\n        '[RNDebugger] '\n          + \"Detected you're enabled Network Inspect and using `uri` in FormData, \"\n          + 'it will be a problem if you use it for upload, '\n          + 'please see the documentation (https://goo.gl/yEcRrU) for more information.',\n      )\n    }\n    return originAppend.call(this, key, value)\n  }\n}\n"
  },
  {
    "path": "app/worker/polyfills/fetch.js",
    "content": "/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-param-reassign */\n/* eslint-disable no-prototype-builtins */\n/* eslint-disable no-new */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable func-names */\n\nexport default function getRNDebuggerFetchPolyfills() {\n  const support = {\n    searchParams: 'URLSearchParams' in self,\n    iterable: 'Symbol' in self && 'iterator' in Symbol,\n    blob: false, // NOTE: Default for RNDebugger\n    formData: 'FormData' in self,\n    arrayBuffer: 'ArrayBuffer' in self,\n  }\n\n  function isDataView(obj) {\n    return obj && DataView.prototype.isPrototypeOf(obj)\n  }\n\n  let isArrayBufferView\n  if (support.arrayBuffer) {\n    const viewClasses = [\n      '[object Int8Array]',\n      '[object Uint8Array]',\n      '[object Uint8ClampedArray]',\n      '[object Int16Array]',\n      '[object Uint16Array]',\n      '[object Int32Array]',\n      '[object Uint32Array]',\n      '[object Float32Array]',\n      '[object Float64Array]',\n    ]\n\n    isArrayBufferView = ArrayBuffer.isView\n      || function (obj) {\n        return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1\n      }\n  }\n\n  function normalizeName(name) {\n    if (typeof name !== 'string') {\n      name = String(name)\n    }\n    if (/[^a-z0-9\\-#$%&'*+.^_`|~]/i.test(name) || name === '') {\n      throw new TypeError('Invalid character in header field name')\n    }\n    return name.toLowerCase()\n  }\n\n  function normalizeValue(value) {\n    if (typeof value !== 'string') {\n      value = String(value)\n    }\n    return value\n  }\n\n  // Build a destructive iterator for the value list\n  function iteratorFor(items) {\n    const iterator = {\n      next() {\n        const value = items.shift()\n        return { done: value === undefined, value }\n      },\n    }\n\n    if (support.iterable) {\n      iterator[Symbol.iterator] = function () {\n        return iterator\n      }\n    }\n\n    return iterator\n  }\n\n  function Headers(headers) {\n    this.map = {}\n\n    if (headers instanceof Headers) {\n      headers.forEach(function (value, name) {\n        this.append(name, value)\n      }, this)\n    } else if (Array.isArray(headers)) {\n      headers.forEach(function (header) {\n        this.append(header[0], header[1])\n      }, this)\n    } else if (headers) {\n      Object.getOwnPropertyNames(headers).forEach(function (name) {\n        this.append(name, headers[name])\n      }, this)\n    }\n  }\n\n  Headers.prototype.append = function (name, value) {\n    name = normalizeName(name)\n    value = normalizeValue(value)\n    const oldValue = this.map[name]\n    this.map[name] = oldValue ? `${oldValue}, ${value}` : value\n  }\n\n  Headers.prototype.delete = function (name) {\n    delete this.map[normalizeName(name)]\n  }\n\n  Headers.prototype.get = function (name) {\n    name = normalizeName(name)\n    return this.has(name) ? this.map[name] : null\n  }\n\n  Headers.prototype.has = function (name) {\n    return this.map.hasOwnProperty(normalizeName(name))\n  }\n\n  Headers.prototype.set = function (name, value) {\n    this.map[normalizeName(name)] = normalizeValue(value)\n  }\n\n  Headers.prototype.forEach = function (callback, thisArg) {\n    for (const name in this.map) {\n      if (this.map.hasOwnProperty(name)) {\n        callback.call(thisArg, this.map[name], name, this)\n      }\n    }\n  }\n\n  Headers.prototype.keys = function () {\n    const items = []\n    this.forEach((value, name) => {\n      items.push(name)\n    })\n    return iteratorFor(items)\n  }\n\n  Headers.prototype.values = function () {\n    const items = []\n    this.forEach((value) => {\n      items.push(value)\n    })\n    return iteratorFor(items)\n  }\n\n  Headers.prototype.entries = function () {\n    const items = []\n    this.forEach((value, name) => {\n      items.push([name, value])\n    })\n    return iteratorFor(items)\n  }\n\n  if (support.iterable) {\n    Headers.prototype[Symbol.iterator] = Headers.prototype.entries\n  }\n\n  function consumed(body) {\n    if (body.bodyUsed) {\n      return Promise.reject(new TypeError('Already read'))\n    }\n    body.bodyUsed = true\n  }\n\n  function fileReaderReady(reader) {\n    return new Promise((resolve, reject) => {\n      reader.onload = function () {\n        resolve(reader.result)\n      }\n      reader.onerror = function () {\n        reject(reader.error)\n      }\n    })\n  }\n\n  function readBlobAsArrayBuffer(blob) {\n    const reader = new FileReader()\n    const promise = fileReaderReady(reader)\n    reader.readAsArrayBuffer(blob)\n    return promise\n  }\n\n  function readBlobAsText(blob) {\n    const reader = new FileReader()\n    const promise = fileReaderReady(reader)\n    reader.readAsText(blob)\n    return promise\n  }\n\n  function readArrayBufferAsText(buf) {\n    const view = new Uint8Array(buf)\n    const chars = new Array(view.length)\n\n    for (let i = 0; i < view.length; i += 1) {\n      chars[i] = String.fromCharCode(view[i])\n    }\n    return chars.join('')\n  }\n\n  function bufferClone(buf) {\n    if (buf.slice) {\n      return buf.slice(0)\n    }\n    const view = new Uint8Array(buf.byteLength)\n    view.set(new Uint8Array(buf))\n    return view.buffer\n  }\n\n  function decode(body) {\n    const form = new FormData()\n    body\n      .trim()\n      .split('&')\n      .forEach((bytes) => {\n        if (bytes) {\n          const split = bytes.split('=')\n          const name = split.shift().replace(/\\+/g, ' ')\n          const value = split.join('=').replace(/\\+/g, ' ')\n          form.append(decodeURIComponent(name), decodeURIComponent(value))\n        }\n      })\n    return form\n  }\n\n  function Body() {\n    this.bodyUsed = false\n\n    this._initBody = function (body) {\n      this._bodyInit = body\n      if (!body) {\n        this._bodyText = ''\n      } else if (typeof body === 'string') {\n        this._bodyText = body\n      } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {\n        this._bodyBlob = body\n      } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {\n        this._bodyFormData = body\n      } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n        this._bodyText = body.toString()\n      } else if (support.arrayBuffer && support.blob && isDataView(body)) {\n        this._bodyArrayBuffer = bufferClone(body.buffer)\n        // IE 10-11 can't handle a DataView body.\n        this._bodyInit = new Blob([this._bodyArrayBuffer])\n      } else if (\n        support.arrayBuffer\n        && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))\n      ) {\n        this._bodyArrayBuffer = bufferClone(body)\n      } else {\n        const bodyText = Object.prototype.toString.call(body)\n        body = bodyText\n        this._bodyText = bodyText\n      }\n\n      if (!this.headers.get('content-type')) {\n        if (typeof body === 'string') {\n          this.headers.set('content-type', 'text/plain;charset=UTF-8')\n        } else if (this._bodyBlob && this._bodyBlob.type) {\n          this.headers.set('content-type', this._bodyBlob.type)\n        } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n          this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')\n        }\n      }\n    }\n\n    if (support.blob) {\n      this.blob = function () {\n        const rejected = consumed(this)\n        if (rejected) {\n          return rejected\n        }\n\n        if (this._bodyBlob) {\n          return Promise.resolve(this._bodyBlob)\n        } if (this._bodyArrayBuffer) {\n          return Promise.resolve(new Blob([this._bodyArrayBuffer]))\n        } if (this._bodyFormData) {\n          throw new Error('could not read FormData body as blob')\n        } else {\n          return Promise.resolve(new Blob([this._bodyText]))\n        }\n      }\n\n      this.arrayBuffer = function () {\n        if (this._bodyArrayBuffer) {\n          return consumed(this) || Promise.resolve(this._bodyArrayBuffer)\n        }\n        return this.blob().then(readBlobAsArrayBuffer)\n      }\n    }\n\n    this.text = function () {\n      const rejected = consumed(this)\n      if (rejected) {\n        return rejected\n      }\n\n      if (this._bodyBlob) {\n        return readBlobAsText(this._bodyBlob)\n      } if (this._bodyArrayBuffer) {\n        return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))\n      } if (this._bodyFormData) {\n        throw new Error('could not read FormData body as text')\n      } else {\n        return Promise.resolve(this._bodyText)\n      }\n    }\n\n    if (support.formData) {\n      this.formData = function () {\n        return this.text().then(decode)\n      }\n    }\n\n    this.json = function () {\n      return this.text().then(JSON.parse)\n    }\n\n    return this\n  }\n\n  // HTTP methods whose capitalization should be normalized\n  const methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']\n\n  function normalizeMethod(method) {\n    const upcased = method.toUpperCase()\n    return methods.indexOf(upcased) > -1 ? upcased : method\n  }\n\n  function Request(input, options) {\n    options = options || {}\n    let { body } = options\n\n    if (input instanceof Request) {\n      if (input.bodyUsed) {\n        throw new TypeError('Already read')\n      }\n      this.url = input.url\n      this.credentials = input.credentials\n      if (!options.headers) {\n        this.headers = new Headers(input.headers)\n      }\n      this.method = input.method\n      this.mode = input.mode\n      this.signal = input.signal\n      if (!body && input._bodyInit != null) {\n        body = input._bodyInit\n        input.bodyUsed = true\n      }\n    } else {\n      this.url = String(input)\n    }\n\n    this.credentials = options.credentials || this.credentials || 'same-origin'\n    if (options.headers || !this.headers) {\n      this.headers = new Headers(options.headers)\n    }\n    this.method = normalizeMethod(options.method || this.method || 'GET')\n    this.mode = options.mode || this.mode || null\n    this.signal = options.signal || this.signal\n    this.referrer = null\n\n    if ((this.method === 'GET' || this.method === 'HEAD') && body) {\n      throw new TypeError('Body not allowed for GET or HEAD requests')\n    }\n    this._initBody(body)\n  }\n\n  Request.prototype.clone = function () {\n    return new Request(this, { body: this._bodyInit })\n  }\n\n  function parseHeaders(rawHeaders) {\n    const headers = new Headers()\n    // Replace instances of \\r\\n and \\n followed by\n    // at least one space or horizontal tab with a space\n    // https://tools.ietf.org/html/rfc7230#section-3.2\n    const preProcessedHeaders = rawHeaders.replace(/\\r?\\n[\\t ]+/g, ' ')\n    preProcessedHeaders.split(/\\r?\\n/).forEach((line) => {\n      const parts = line.split(':')\n      const key = parts.shift().trim()\n      if (key) {\n        const value = parts.join(':').trim()\n        headers.append(key, value)\n      }\n    })\n    return headers\n  }\n\n  Body.call(Request.prototype)\n\n  function Response(bodyInit, options) {\n    if (!options) {\n      options = {}\n    }\n\n    this.type = 'default'\n    this.status = options.status === undefined ? 200 : options.status\n    this.ok = this.status >= 200 && this.status < 300\n    this.statusText = 'statusText' in options ? options.statusText : 'OK'\n    this.headers = new Headers(options.headers)\n    this.url = options.url || ''\n    this._initBody(bodyInit)\n  }\n\n  Body.call(Response.prototype)\n\n  Response.prototype.clone = function () {\n    return new Response(this._bodyInit, {\n      status: this.status,\n      statusText: this.statusText,\n      headers: new Headers(this.headers),\n      url: this.url,\n    })\n  }\n\n  Response.error = function () {\n    const response = new Response(null, { status: 0, statusText: '' })\n    response.type = 'error'\n    return response\n  }\n\n  const redirectStatuses = [301, 302, 303, 307, 308]\n\n  Response.redirect = function (url, status) {\n    if (redirectStatuses.indexOf(status) === -1) {\n      throw new RangeError('Invalid status code')\n    }\n\n    return new Response(null, { status, headers: { location: url } })\n  }\n\n  let { DOMException } = self\n  try {\n    new DOMException()\n  } catch (err) {\n    DOMException = function (message, name) {\n      this.message = message\n      this.name = name\n      const error = Error(message)\n      this.stack = error.stack\n    }\n    DOMException.prototype = Object.create(Error.prototype)\n    DOMException.prototype.constructor = DOMException\n  }\n\n  function fetch(input, init) {\n    return new Promise((resolve, reject) => {\n      const request = new Request(input, init)\n\n      if (request.signal && request.signal.aborted) {\n        reject(new DOMException('Aborted', 'AbortError'))\n        return\n      }\n\n      const xhr = new XMLHttpRequest()\n\n      function abortXhr() {\n        xhr.abort()\n      }\n\n      xhr.onload = function () {\n        const options = {\n          status: xhr.status,\n          statusText: xhr.statusText,\n          headers: parseHeaders(xhr.getAllResponseHeaders() || ''),\n        }\n        options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')\n        const body = 'response' in xhr ? xhr.response : xhr.responseText\n        resolve(new Response(body, options))\n      }\n\n      xhr.onerror = function () {\n        reject(new TypeError('Network request failed'))\n      }\n\n      xhr.ontimeout = function () {\n        reject(new TypeError('Network request failed'))\n      }\n\n      xhr.onabort = function () {\n        reject(new DOMException('Aborted', 'AbortError'))\n      }\n\n      xhr.open(request.method, request.url, true)\n\n      if (request.credentials === 'include') {\n        xhr.withCredentials = true\n      } else if (request.credentials === 'omit') {\n        xhr.withCredentials = false\n      }\n\n      if ('responseType' in xhr && support.blob) {\n        xhr.responseType = 'blob'\n      }\n\n      request.headers.forEach((value, name) => {\n        xhr.setRequestHeader(name, value)\n      })\n\n      if (request.signal) {\n        request.signal.addEventListener('abort', abortXhr)\n\n        xhr.onreadystatechange = function () {\n          // DONE (success or failure)\n          if (xhr.readyState === 4) {\n            request.signal.removeEventListener('abort', abortXhr)\n          }\n        }\n      }\n\n      xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)\n    })\n  }\n\n  fetch.polyfill = true\n\n  return {\n    fetch,\n    Headers,\n    Request,\n    Response,\n  }\n}\n"
  },
  {
    "path": "app/worker/reactDevTools.js",
    "content": "/* eslint-disable no-underscore-dangle */\n\nconst methodGlobalName = '__REPORT_REACT_DEVTOOLS_PORT__'\n\nconst reportReactDevToolsPort = (port, platform) => postMessage({\n  [methodGlobalName]: port,\n  platform,\n})\n\nexport const reportDefaultReactDevToolsPort = async ({ setupDevtools, Platform }) => {\n  if (Platform.__empty) return\n  /*\n   * [Fallback] React Native version under 0.39 can't specified the port\n   */\n  if (\n    typeof setupDevtools === 'function'\n    && setupDevtools.toString().indexOf('window.__REACT_DEVTOOLS_PORT__') === -1\n  ) {\n    reportReactDevToolsPort(8097, Platform.OS)\n  } else {\n    // React Inspector will keep the last reported port even if reload JS,\n    // because we don't want to icrease the user waiting time for reload JS.\n    // We need back to use the random port if we don't need fallback\n    reportReactDevToolsPort(window.__REACT_DEVTOOLS_PORT__, Platform.OS)\n  }\n}\n"
  },
  {
    "path": "app/worker/reduxAPI.js",
    "content": "import { instrument } from '@redux-devtools/instrument'\nimport {\n  evalAction,\n  getActionsArray,\n  generateId,\n  stringify,\n  getSeralizeParameter,\n  importState,\n  getLocalFilter,\n  isFiltered,\n  filterStagedActions,\n  filterState,\n} from '@redux-devtools/utils'\nimport { updateStackWithSourceMap } from './utils'\n\nfunction configureStore(next, subscriber, options) {\n  return instrument(subscriber, options)(next)\n}\n\nconst instances = {\n  /* [id]: { name, store, ... } */\n}\n\nlet lastAction\nlet isExcess\nlet listenerAdded\nlet locked\nlet paused\n\nfunction getStackTrace(config, toExcludeFromTrace) {\n  if (!config.trace) return undefined\n  if (typeof config.trace === 'function') return config.trace()\n\n  let stack\n  let extraFrames = 0\n  let prevStackTraceLimit\n  const { traceLimit } = config\n  const error = Error()\n  if (Error.captureStackTrace) {\n    if (Error.stackTraceLimit < traceLimit) {\n      prevStackTraceLimit = Error.stackTraceLimit\n      Error.stackTraceLimit = traceLimit\n    }\n    Error.captureStackTrace(error, toExcludeFromTrace)\n  } else {\n    extraFrames = 3\n  }\n  stack = error.stack\n  if (prevStackTraceLimit) Error.stackTraceLimit = prevStackTraceLimit\n  if (\n    extraFrames\n    || typeof Error.stackTraceLimit !== 'number'\n    || Error.stackTraceLimit > traceLimit\n  ) {\n    const frames = stack.split('\\n')\n    if (frames.length > traceLimit) {\n      stack = frames\n        .slice(0, traceLimit + extraFrames + (frames[0] === 'Error' ? 1 : 0))\n        .join('\\n')\n    }\n  }\n  return updateStackWithSourceMap(stack)\n}\n\nfunction getLiftedState(store, filters) {\n  return filterStagedActions(store.liftedStore.getState(), filters)\n}\n\nfunction relay(type, state, instance, action, nextActionId) {\n  const {\n    filters,\n    predicate,\n    stateSanitizer,\n    actionSanitizer,\n    serializeState,\n    serializeAction,\n  } = instance\n\n  const message = {\n    type,\n    id: instance.id,\n    name: instance.name,\n  }\n  if (state) {\n    message.payload = type === 'ERROR'\n      ? state\n      : stringify(\n        filterState(\n          state,\n          type,\n          filters,\n          stateSanitizer,\n          actionSanitizer,\n          nextActionId,\n          predicate,\n        ),\n        serializeState,\n      )\n  }\n  if (type === 'ACTION') {\n    action.stack = getStackTrace(instance, true)\n    message.action = stringify(\n      !actionSanitizer ? action : actionSanitizer(action.action, nextActionId - 1),\n      serializeAction,\n    )\n    message.isExcess = isExcess\n    message.nextActionId = nextActionId\n  } else if (instance) {\n    message.libConfig = {\n      type: 'redux',\n      actionCreators: stringify(instance.actionCreators),\n      serialize: !!instance.serialize,\n    }\n  }\n  postMessage({ __IS_REDUX_NATIVE_MESSAGE__: true, content: message })\n}\n\nfunction dispatchRemotely(action, instance) {\n  try {\n    const { store, actionCreators } = instance\n    const result = evalAction(action, actionCreators)\n    store.dispatch(result)\n  } catch (e) {\n    relay('ERROR', e.message, instance)\n  }\n}\n\nfunction importPayloadFrom(store, state, instance) {\n  try {\n    const nextLiftedState = importState(state, instance)\n    if (!nextLiftedState) return\n    store.liftedStore.dispatch({ type: 'IMPORT_STATE', ...nextLiftedState })\n    relay('STATE', getLiftedState(store, instance.filters), instance)\n  } catch (e) {\n    relay('ERROR', e.message, instance)\n  }\n}\n\nfunction exportState({ id: instanceId, store, serializeState }) {\n  const liftedState = store.liftedStore.getState()\n  const { actionsById } = liftedState\n  const payload = []\n  liftedState.stagedActionIds.slice(1).forEach((id) => {\n    payload.push(actionsById[id].action)\n  })\n  postMessage({\n    __IS_REDUX_NATIVE_MESSAGE__: true,\n    content: {\n      type: 'EXPORT',\n      payload: stringify(payload, serializeState),\n      committedState:\n        typeof liftedState.committedState !== 'undefined'\n          ? stringify(liftedState.committedState, serializeState)\n          : undefined,\n      instanceId,\n    },\n  })\n}\n\nfunction handleMessages(message) {\n  const {\n    id, instanceId, type, action, state, toAll,\n  } = message\n  if (toAll) {\n    Object.keys(instances).forEach((key) => {\n      handleMessages({ ...message, id: key, toAll: false })\n    })\n    return false\n  }\n\n  const instance = instances[id || instanceId]\n  if (!instance) return true\n  const { store, filters } = instance\n  if (!store) return false\n\n  switch (type) {\n    case 'DISPATCH':\n      store.liftedStore.dispatch(action)\n      break\n    case 'ACTION':\n      dispatchRemotely(action, instance)\n      break\n    case 'IMPORT':\n      importPayloadFrom(store, state, instance)\n      break\n    case 'EXPORT':\n      exportState(instance)\n      break\n    case 'UPDATE':\n      relay('STATE', getLiftedState(store, filters), instance)\n      break\n    default:\n      break\n  }\n  return false\n}\n\nfunction start(instance) {\n  if (!listenerAdded) {\n    self.addEventListener('message', (message) => {\n      const { method, content } = message.data\n      if (method === 'emitReduxMessage') {\n        handleMessages(content)\n      }\n    })\n    listenerAdded = true\n  }\n  const { store, actionCreators, filters } = instance\n  if (typeof actionCreators === 'function') {\n    instance.actionCreators = actionCreators()\n  }\n  relay('STATE', getLiftedState(store, filters), instance)\n}\n\nfunction checkForReducerErrors(liftedState, instance) {\n  if (liftedState.computedStates[liftedState.currentStateIndex].error) {\n    relay('STATE', filterStagedActions(liftedState, instance.filters), instance)\n    return true\n  }\n  return false\n}\n\nfunction monitorReducer(state = {}, action = {}) {\n  lastAction = action.type\n  return state\n}\n\nfunction handleChange(state, liftedState, maxAge, instance) {\n  if (checkForReducerErrors(liftedState, instance)) return\n\n  const { filters, predicate } = instance\n  if (lastAction === 'PERFORM_ACTION') {\n    const { nextActionId } = liftedState\n    const liftedAction = liftedState.actionsById[nextActionId - 1]\n    if (isFiltered(liftedAction.action, filters)) return\n    if (predicate && !predicate(state, liftedAction.action)) return\n    relay('ACTION', state, instance, liftedAction, nextActionId)\n    if (!isExcess && maxAge) isExcess = liftedState.stagedActionIds.length >= maxAge\n  } else {\n    if (lastAction === 'JUMP_TO_STATE') return\n    if (lastAction === 'PAUSE_RECORDING') {\n      paused = liftedState.isPaused\n    } else if (lastAction === 'LOCK_CHANGES') {\n      locked = liftedState.isLocked\n    }\n    if (paused || locked) {\n      if (lastAction) lastAction = undefined\n      else return\n    }\n    relay('STATE', filterStagedActions(liftedState, filters), instance)\n  }\n}\n\nexport default function devToolsEnhancer(options = {}) {\n  const {\n    name,\n    maxAge = 30,\n    shouldCatchErrors = !!global.shouldCatchErrors,\n    shouldHotReload,\n    shouldRecordChanges,\n    shouldStartLocked,\n    pauseActionType = '@@PAUSED',\n    actionCreators,\n    filters,\n    actionsBlacklist,\n    actionsWhitelist,\n    actionSanitizer,\n    stateSanitizer,\n    deserializeState,\n    deserializeAction,\n    serialize,\n    predicate,\n    trace,\n    traceLimit,\n  } = options\n  const id = generateId(options.instanceId)\n\n  const serializeState = getSeralizeParameter(options, 'serializeState')\n  const serializeAction = getSeralizeParameter(options, 'serializeAction')\n\n  return (next) => (reducer, initialState) => {\n    const store = configureStore(next, monitorReducer, {\n      maxAge,\n      shouldCatchErrors,\n      shouldHotReload,\n      shouldRecordChanges,\n      shouldStartLocked,\n      pauseActionType,\n    })(reducer, initialState)\n\n    instances[id] = {\n      name: name || id,\n      id,\n      store,\n      filters: getLocalFilter({\n        actionsWhitelist: (filters && filters.whitelist) || actionsWhitelist,\n        actionsBlacklist: (filters && filters.blacklist) || actionsBlacklist,\n      }),\n      actionCreators: actionCreators && (() => getActionsArray(actionCreators)),\n      stateSanitizer,\n      actionSanitizer,\n      deserializeState,\n      deserializeAction,\n      serializeState,\n      serializeAction,\n      serialize,\n      predicate,\n      trace,\n      traceLimit,\n    }\n\n    start(instances[id])\n    store.subscribe(() => {\n      handleChange(store.getState(), store.liftedStore.getState(), maxAge, instances[id])\n    })\n    return store\n  }\n}\n\nconst preEnhancer = (instanceId) => (next) => (reducer, initialState, enhancer) => {\n  const store = next(reducer, initialState, enhancer)\n\n  if (instances[instanceId]) {\n    instances[instanceId].store = store\n  }\n  return {\n    ...store,\n    dispatch: (action) => (locked ? action : store.dispatch(action)),\n  }\n}\n\ndevToolsEnhancer.updateStore = (newStore, instanceId) => {\n  console.warn(\n    '[RNDebugger]',\n    '`updateStore` is deprecated use `window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__` instead:',\n    'https://github.com/jhen0409/react-native-debugger/blob/master/docs/redux-devtools-integration.md',\n  )\n\n  const keys = Object.keys(instances)\n  if (!keys.length) return\n\n  if (keys.length > 1 && !instanceId) {\n    console.warn(\n      'You have multiple stores,',\n      'please provide `instanceId` argument (`updateStore(store, instanceId)`)',\n    )\n  }\n  if (instanceId) {\n    const instance = instances[instanceId]\n    if (!instance) return\n    instance.store = newStore\n  } else {\n    instances[keys[0]].store = newStore\n  }\n}\n\nconst compose = (options) => (...funcs) => (...args) => {\n  const instanceId = generateId(options.instanceId)\n  return [preEnhancer(instanceId), ...funcs].reduceRight(\n    (composed, f) => f(composed),\n    devToolsEnhancer({ ...options, instanceId })(...args),\n  )\n}\n\nexport function composeWithDevTools(...funcs) {\n  if (funcs.length === 0) {\n    return devToolsEnhancer()\n  }\n  if (funcs.length === 1 && typeof funcs[0] === 'object') {\n    return compose(funcs[0])\n  }\n  return compose({})(...funcs)\n}\n"
  },
  {
    "path": "app/worker/remotedev.js",
    "content": "// Edit from https://github.com/zalmoxisus/remotedev/blob/master/src/devTools.js\n\nimport { stringify, parse } from 'jsan'\nimport { generateId, getActionsArray } from '@redux-devtools/utils'\n\nlet listenerAdded\nconst listeners = {}\n\nexport function extractState(message) {\n  if (!message || !message.state) return undefined\n  if (typeof message.state === 'string') return parse(message.state)\n  return message.state\n}\n\nfunction handleMessages(message) {\n  if (!message.payload) {\n    message.payload = message.action\n  }\n  const fn = listeners[message.instanceId]\n  if (!fn) return true\n\n  if (typeof fn === 'function') {\n    fn(message)\n  } else {\n    fn.forEach((func) => func(message))\n  }\n  return false\n}\n\nexport function start() {\n  if (!listenerAdded) {\n    self.addEventListener('message', (message) => {\n      const { method, content } = message.data\n      if (method === 'emitReduxMessage') {\n        return handleMessages(content)\n      }\n    })\n    listenerAdded = true\n  }\n}\n\nfunction transformAction(action, config) {\n  if (action.action) return action\n  const liftedAction = { timestamp: Date.now() }\n  if (action) {\n    if (config.getActionType) {\n      liftedAction.action = config.getActionType(action)\n    } else if (typeof action === 'string') {\n      liftedAction.action = { type: action }\n    } else if (!action.type) {\n      liftedAction.action = { type: 'update' }\n    } else {\n      liftedAction.action = action\n    }\n  } else {\n    liftedAction.action = { type: action }\n  }\n  return liftedAction\n}\n\nexport function send(action, state, type, options) {\n  start()\n  setTimeout(() => {\n    const message = {\n      payload: state ? stringify(state) : '',\n      action: type === 'ACTION' ? stringify(transformAction(action, options)) : action,\n      type: type || 'ACTION',\n      id: options.instanceId,\n      instanceId: options.instanceId,\n      name: options.name,\n    }\n    message.libConfig = {\n      type: options.type,\n      name: options.name,\n      serialize: !!options.serialize,\n      actionCreators: options.actionCreators,\n    }\n    postMessage({ __IS_REDUX_NATIVE_MESSAGE__: true, content: message })\n  }, 0)\n}\n\nexport function connect(options = {}) {\n  const id = generateId(options.instanceId)\n  const opts = {\n    ...options,\n    instanceId: id,\n    name: options.name || id,\n    actionCreators: JSON.stringify(getActionsArray(options.actionCreators || {})),\n  }\n  start()\n  return {\n    init(state, action) {\n      send(action || {}, state, 'INIT', opts)\n    },\n    subscribe(listener) {\n      if (!listener) return undefined\n      if (!listeners[id]) listeners[id] = []\n      listeners[id].push(listener)\n\n      return function unsubscribe() {\n        const index = listeners[id].indexOf(listener)\n        listeners[id].splice(index, 1)\n      }\n    },\n    unsubscribe() {\n      delete listeners[id]\n    },\n    send(action, payload) {\n      if (action) {\n        send(action, payload, 'ACTION', opts)\n      } else {\n        send(undefined, payload, 'STATE', opts)\n      }\n    },\n    error(payload) {\n      send(undefined, payload, 'Error', opts)\n    },\n  }\n}\n\n// Not implemented\nexport function disconnect() {}\n"
  },
  {
    "path": "app/worker/setup.js",
    "content": "import {\n  replaceForbiddenHeadersForWorkerXHR,\n  addURIWarningForWorkerFormData,\n} from './networkInspect'\n\n// Add the missing `global` for WebWorker\nself.global = self\n\n/*\n * Blob is not supported for RN < 0.54,\n * we should remove it in WebWorker because\n * it will used for `whatwg-fetch` on older RN versions\n */\nif (self.Blob && self.Blob.toString() === 'function Blob() { [native code] }') {\n  /*\n   * RN > 0.54 will polyfill Blob.\n   * If it is deleted before the RN setup, RN will not add a reference to the original.\n   * We will need to be able to restore the original when running RN > 0.54 for networking tools,\n   * so add the reference here as react-native will not do it if the original is deleted\n   */\n  self.originalBlob = self.Blob\n  delete self.Blob\n}\n\nif (\n  self.XMLHttpRequest\n  && self.XMLHttpRequest.toString() === 'function XMLHttpRequest() { [native code] }'\n) {\n  self.originalXMLHttpRequest = self.XMLHttpRequest\n}\n\nif (self.FormData && self.FormData.toString() === 'function FormData() { [native code] }') {\n  self.originalFormData = self.FormData\n}\n\n// Catch native fetch\nif (self.fetch && self.fetch.toString() === 'function fetch() { [native code] }') {\n  /* eslint-disable-next-line no-underscore-dangle */\n  self.__ORIGINAL_FETCH__ = self.fetch\n}\n\nreplaceForbiddenHeadersForWorkerXHR()\naddURIWarningForWorkerFormData()\n"
  },
  {
    "path": "app/worker/utils.js",
    "content": "/* eslint-disable no-underscore-dangle */\n\n// Avoid warning of use metro require on dev mode\n// it actually unnecessary for RN >= 0.56, so it is backward compatibility\nconst avoidWarnForRequire = (moduleNames) => {\n  if (!moduleNames.length) moduleNames.push('NativeModules')\n  return new Promise((resolve) => {\n    setTimeout(() => {\n      // It's replaced console.warn of react-native\n      const originalWarn = console.warn\n      console.warn = (...args) => {\n        if (\n          args[0]\n            && moduleNames.some(\n              (name) => args[0].indexOf(`Requiring module '${name}' by name`) > -1,\n            )\n        ) {\n          return\n        }\n        return originalWarn(...args)\n      }\n      resolve(() => {\n        console.warn = originalWarn\n      })\n    })\n  })\n}\n\nlet reactNative\n\nconst getRequireMethod = () => {\n  // RN >= 0.57\n  if (typeof window.__r === 'function') return window.__r\n  // RN < 0.57\n  if (typeof window.require === 'function') return window.require\n}\n\nconst lookupForRNModules = (size = 999) => {\n  const metroRequire = getRequireMethod()\n  let actualSize = size\n  let getModule = metroRequire\n  if (metroRequire.getModules) {\n    const mods = metroRequire.getModules()\n    actualSize = Object.keys(mods).length\n    getModule = (moduleId) => {\n      const mod = mods && mods[moduleId]\n      return (mod && mod.publicModule && mod.publicModule.exports) || null\n    }\n  } else {\n    getModule = (moduleId) => metroRequire(moduleId)\n  }\n  for (let moduleId = 0; moduleId <= actualSize - 1; moduleId += 1) {\n    const rn = getModule(moduleId)\n    if (rn && rn.requireNativeComponent && rn.NativeModules) {\n      return rn\n    }\n  }\n  return null\n}\n\nconst getModule = (name, size) => {\n  let result\n  try {\n    const metroRequire = getRequireMethod()\n    // RN >= 0.56\n    if (metroRequire.name === 'metroRequire') {\n      const rn = reactNative || lookupForRNModules(size)\n      reactNative = rn\n      global.$reactNative = rn\n      result = reactNative && reactNative[name]\n    } else if (metroRequire.name === '_require') {\n      result = metroRequire(name)\n    }\n  } catch (e) {} // eslint-disable-line\n  return result || { __empty: true }\n}\n\nconst requiredModules = {\n  MessageQueue: (size) => (self.__fbBatchedBridge\n      && Object.getPrototypeOf(self.__fbBatchedBridge).constructor)\n    || getModule('MessageQueue', size),\n  NativeModules: (size) => getModule('NativeModules', size),\n  Platform: (size) => getModule('Platform', size),\n  setupDevtools: (size) => getModule('setupDevtools', size),\n}\n\nexport const getRequiredModules = async (size) => {\n  if (!window.__DEV__ || !getRequireMethod()) return\n  const done = await avoidWarnForRequire(Object.keys(requiredModules))\n  const modules = {}\n  Object.keys(requiredModules).forEach((name) => {\n    modules[name] = requiredModules[name](size)\n  })\n  done()\n  return modules\n}\n\nconst RN_DEBUGGER_URL_PART = 'RNDebuggerWorker.js'\nconst BUNDLE_URL_REGEXP = /(http[\\S]*?index\\.bundle\\?[\\S]*?)(:\\d+:?\\d?)/\n\nconst addInlineSourceMap = (_, urlGroup1, urlGroup2) => `${urlGroup1}&inlineSourceMap=true${urlGroup2}`\nconst mapStackLines = (line) => line.replace(BUNDLE_URL_REGEXP, addInlineSourceMap)\nconst filterRnDebuggerLines = (line) => !line.includes(RN_DEBUGGER_URL_PART)\n\nexport function updateStackWithSourceMap(stack) {\n  const lines = stack.split('\\n')\n  const linesWithoutRNDebugger = lines.filter(filterRnDebuggerLines)\n  const lineWithSourceMap = linesWithoutRNDebugger.map(mapStackLines)\n  return lineWithSourceMap.join('\\n')\n}\n"
  },
  {
    "path": "auto_update.json",
    "content": "{\n  \"url\": \"https://github.com/jhen0409/react-native-debugger/releases/download/v0.14.0/rn-debugger-macos-universal.zip\",\n  \"name\": \"v0.14.0\",\n  \"notes\": \"- Upgrade react-devtools-core to v4.28.0\\n- Upgrade redux-devtools to latest version\\n- Upgrade apollo-client-devtools to v4- More: https://github.com/jhen0409/react-native-debugger/releases/tag/v0.14.0\"\n}\n"
  },
  {
    "path": "auto_updater.json",
    "content": "{\n  \"url\": \"https://github.com/jhen0409/react-native-debugger/releases/download/v0.10.13/rn-debugger-macos-x64.zip\",\n  \"name\": \"v0.10.13\",\n  \"notes\": \"Update apollo-client-devtools to v2.3.5\"\n}\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = (api) => {\n  api.cache(true)\n  return {\n    presets: [['@babel/preset-env', { targets: { node: '18.5' } }], '@babel/preset-react'],\n    plugins: [],\n    env: {\n      production: {\n        plugins: [\n          '@babel/plugin-transform-react-inline-elements',\n          '@babel/plugin-transform-react-constant-elements',\n          'transform-react-remove-prop-types',\n        ],\n      },\n    },\n  }\n}\n"
  },
  {
    "path": "dist/app.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=utf-8>\n    <title>React Native Debugger</title>\n    <link href='css/style.css' rel=\"stylesheet\" />\n  </head>\n  <body>\n    <div id=\"root\">\n      <div id=\"loading\">Loading...</div>\n    </div>\n    <script src=\"js/bundle.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "dist/css/style.css",
    "content": "html,\nbody {\n  font-family: monaco, Consolas, Lucida Console, monospace;\n  overflow: hidden;\n  font-size: 100%;\n  margin: 0;\n  padding: 0;\n  width: 100%;\n  height: 100%;\n  background-color: rgb(53, 59, 70);\n}\n\n#root {\n  width: 100%;\n  height: 100%;\n}\n#logs {\n  position: fixed;\n  top: 0;\n  left: 0;\n  white-space: pre;\n}\n#loading {\n  color: #aaa;\n  font-size: 30px;\n  display: flex;\n  height: 100%;\n  justify-content: center;\n  align-items: center;\n}\n\n::-webkit-scrollbar {\n  width: 8px;\n  height: 8px;\n  background-color: #555;\n}\n::-webkit-scrollbar-thumb {\n  background-color: #333;\n}\n::-webkit-scrollbar-corner {\n  background-color: #333;\n}\n\n@media print {\n  @page {\n    size: auto;\n    margin: 0;\n  }\n  body {\n    position: static;\n  }\n}\n.CodeMirror {\n  font-family: monaco, Consolas, Lucida Console, monospace !important;\n}\n"
  },
  {
    "path": "dist/devtools-helper/main.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <script src=\"./main.js\"></script>\n  </head>\n  <body>\n  </body>\n</html>\n"
  },
  {
    "path": "dist/devtools-helper/main.js",
    "content": "const detectChromeDevToolsTheme = () => chrome.devtools.panels.themeName || 'default';\n\nconst themeName = detectChromeDevToolsTheme();\n\nchrome.devtools.inspectedWindow.eval(`\n  window.chromeDevToolsTheme = '${themeName}';\n  if (window.notifyDevToolsThemeChange) {\n    window.notifyDevToolsThemeChange(window.chromeDevToolsTheme);\n  }\n`);\n\nwindow.addEventListener('message', ({ data }) => {\n  if (data.type !== 'open-in-editor') {\n    return;\n  }\n  const arr = data.source.split(':');\n  const lineNumber = arr.pop(-1);\n  const file = arr.join(':');\n  chrome.devtools.inspectedWindow.eval(`\n    if (window.openInEditor) {\n      window.openInEditor('${file}', ${Number(lineNumber)});\n    }\n  `);\n});\n"
  },
  {
    "path": "dist/devtools-helper/manifest.json",
    "content": "{\n  \"manifest_version\": 2,\n  \"name\": \"RNDebugger devtools helper\",\n  \"version\": \"0.0.1\",\n  \"devtools_page\": \"main.html\"\n}\n"
  },
  {
    "path": "dist/package.json",
    "content": "{\n  \"name\": \"react-native-debugger\",\n  \"version\": \"0.14.0\",\n  \"productName\": \"React Native Debugger\",\n  \"description\": \"The standalone app for React Native Debugger, with React DevTools / Redux DevTools\",\n  \"main\": \"main.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/jhen0409/react-native-debugger.git\"\n  },\n  \"author\": \"Jhen <developer@jhen.me>\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"postinstall\": \"patch-package\"\n  },\n  \"dependencies\": {\n    \"adbkit\": \"^2.11.0\",\n    \"electron-store\": \"^1.2.0\",\n    \"react-devtools-core\": \"^4.28.0\"\n  },\n  \"devDependencies\": {\n    \"apollo-client-devtools\": \"^4.1.4\",\n    \"patch-package\": \"^6.2.2\"\n  }\n}\n"
  },
  {
    "path": "dist/patches/apollo-client-devtools+4.1.4.patch",
    "content": "diff --git a/node_modules/apollo-client-devtools/build/background.js b/node_modules/apollo-client-devtools/build/background.js\nindex 1b46d15..5767881 100644\n--- a/node_modules/apollo-client-devtools/build/background.js\n+++ b/node_modules/apollo-client-devtools/build/background.js\n@@ -171,21 +171,21 @@ chrome.runtime.onConnect.addListener(port => {\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ })\ndiff --git a/node_modules/apollo-client-devtools/build/devtools.js b/node_modules/apollo-client-devtools/build/devtools.js\nindex 165495f..8290715 100644\n--- a/node_modules/apollo-client-devtools/build/devtools.js\n+++ b/node_modules/apollo-client-devtools/build/devtools.js\n@@ -165,22 +165,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n-\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n /***/ }),\n \ndiff --git a/node_modules/apollo-client-devtools/build/hook.js b/node_modules/apollo-client-devtools/build/hook.js\nindex 63aa181..d6539a7 100644\n--- a/node_modules/apollo-client-devtools/build/hook.js\n+++ b/node_modules/apollo-client-devtools/build/hook.js\n@@ -4712,21 +4712,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ }),\n@@ -4859,7 +4859,7 @@ function initializeHook() {\n     });\n     const clientRelay = new Relay_1.default();\n     clientRelay.addConnection(\"tab\", (message) => {\n-        window.postMessage(message, \"*\");\n+        window.postMessage(message);\n     });\n     window.addEventListener(\"message\", ({ data }) => {\n         clientRelay.broadcast(data);\ndiff --git a/node_modules/apollo-client-devtools/build/panel.js b/node_modules/apollo-client-devtools/build/panel.js\nindex 4b3ad6e..f7e021e 100644\n--- a/node_modules/apollo-client-devtools/build/panel.js\n+++ b/node_modules/apollo-client-devtools/build/panel.js\n@@ -54713,21 +54713,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ }),\ndiff --git a/node_modules/apollo-client-devtools/build/tab.js b/node_modules/apollo-client-devtools/build/tab.js\nindex 9ed84be..702f76c 100644\n--- a/node_modules/apollo-client-devtools/build/tab.js\n+++ b/node_modules/apollo-client-devtools/build/tab.js\n@@ -135,21 +135,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ }),\n@@ -260,22 +260,22 @@ __webpack_require__(/*! ./tabRelay */ \"./src/extension/tab/tabRelay.ts\");\n   A common workaround for this issue is to inject an inlined function\n   into the inspected tab.\n */\n-if (typeof document === \"object\" && document instanceof HTMLDocument) {\n-    const script = document.createElement(\"script\");\n-    script.setAttribute(\"type\", \"module\");\n-    script.setAttribute(\"src\", chrome.extension.getURL(\"hook.js\"));\n-    document.addEventListener(\"DOMContentLoaded\", () => {\n-        var _a;\n-        const importMap = document.querySelector(\"script[type=\\\"importmap\\\"]\");\n-        if (importMap != null) {\n-            (_a = importMap.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(script, importMap.nextSibling);\n-        }\n-        else {\n-            const head = document.head || document.getElementsByTagName(\"head\")[0] || document.documentElement;\n-            head.insertBefore(script, head.lastChild);\n-        }\n-    });\n-}\n+// if (typeof document === \"object\" && document instanceof HTMLDocument) {\n+//     const script = document.createElement(\"script\");\n+//     script.setAttribute(\"type\", \"module\");\n+//     script.setAttribute(\"src\", chrome.extension.getURL(\"hook.js\"));\n+//     document.addEventListener(\"DOMContentLoaded\", () => {\n+//         var _a;\n+//         const importMap = document.querySelector(\"script[type=\\\"importmap\\\"]\");\n+//         if (importMap != null) {\n+//             (_a = importMap.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(script, importMap.nextSibling);\n+//         }\n+//         else {\n+//             const head = document.head || document.getElementsByTagName(\"head\")[0] || document.documentElement;\n+//             head.insertBefore(script, head.lastChild);\n+//         }\n+//     });\n+// }\n \n })();\n \n"
  },
  {
    "path": "docs/README.md",
    "content": "# Documentation\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcuts references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/apollo-client-devtools-integration.md",
    "content": "# Apollo Client DevTools Integration\n\nReact Native debugger has integration for the [Apollo Client DevTools](https://github.com/apollographql/apollo-client-devtools), you can see the `Apollo` tab in Developer Tools:\n\n<img width=\"547\" alt=\"screen shot 2019-02-01 at 1 51 27 pm\" src=\"https://user-images.githubusercontent.com/3001525/52105143-8006fe00-2628-11e9-8276-09bdeb23e3b2.png\">\n\nTo ensure it works, you must use Apollo Client ^2.0.\n\nIf the apollo tab doesn't appear, toggle developer tools off and on again.\n\nYou can read Apollo DevTools [documentation](https://github.com/apollographql/apollo-client-devtools#apollo-client-devtools)). \n\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/config-file-in-home-directory.md",
    "content": "# Config file in home directory\n\nWe could configure RNDebugger app in `~/.rndebuggerrc` (the config can be opened from the main menu: Debugger → Open Config File), the file used [json5](https://github.com/json5/json5) as format, see the following default template:\n\n\n```json5\n{\n  // Font family of the debugger window\n  fontFamily: 'monaco, Consolas, Lucida Console, monospace',\n\n  // Zoom level of the debugger window, it will override persited zoomLevel\n  zoomLevel: 0,\n\n  // Settings of debugger window,\n  windowBounds: {\n    // Size of the debugger window, it will override persisted size\n    width: 1024,\n    height: 750,\n\n    // Show frame for debugger window\n    // but due to https://github.com/electron/electron/issues/3647\n    // so we can't have custom title bar if no frame\n    frame: true,\n  },\n\n  // Auto check update on RNDebugger startup\n  autoUpdate: true,\n\n  // RNDebugger will open debugger window with the ports when app launched\n  defaultRNPackagerPorts: [8081],\n\n  // Env for\n  // open React DevTools source file link\n  // and enable open in editor for console log for RNDebugger\n  editor: '',\n\n  // Set default react-devtools theme (default is match Chrome DevTools theme)\n  // but the default theme doesn't change manually changed theme\n  // see https://github.com/facebook/react-devtools/blob/master/frontend/Themes/Themes.js to get more\n  defaultReactDevToolsTheme: 'RNDebugger',\n\n  // Set default react-devtools port (default is \\`19567+\\` if it is not being used).\n  // The devtools backend of React Native will use the port to connect to the devtools server.\n  // You should use that if you have some rules for binding port.\n  //   (like https://github.com/jhen0409/react-native-debugger/issues/397)\n  defaultReactDevToolsPort: 19567,\n\n  // Enable Network Inspect by default\n  // See https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md\n  defaultNetworkInspect: false,\n\n  // Refresh devtools when doing JS reload every N times. (-1 for disabled)\n  // This can effectively avoid possible memory leaks (Like\n  // https://github.com/jhen0409/react-native-debugger/issues/405) in devtools.\n  timesJSLoadToRefreshDevTools: -1,\n}\n```\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/contributing.md",
    "content": "# Contributing\n\n## Development\n\n### Fork this repo & install dependencies\n\nWe're recommended use yarn because we keep the dependencies lock of yarn.\n\n```bash\n# In react-native-debugger directory\n$ yarn\n$ cd npm-package && yarn && cd ..\n```\n\nIf you want to debug the [NPM package](../npm-package), just run `npm link <the package path>` on your React Native project.\n\n### Run on development mode\n_Please ensure the `React Native Debugger` production / distribution app is closed._\n\n```bash\n$ yarn dev:webpack  # Then open the another terminal tab\n$ yarn dev:electron\n```\n1. From here, you can open a react-native project with remote debugging enabled. \n1. To see the development build of the react-native-debugger, do x,y,z\n\n### Run on production mode\n\n```bash\n$ yarn build\n$ yarn start\n```\n\n### Run test\n\nRun lint and test, currently we just wrote E2E test for RNDebugger.\n\n```bash\n$ yarn test\n$ yarn test-e2e\n```\n\nYou need to closes all React Native packager (make sure `8081` or `8088` port not listening) when running the test.\n\n### Packaging app\n\n```bash\n$ yarn run pack-macos # Use --notarize to notarize app\n# On macOS: brew install fakeroot dpkg rpm\n$ yarn run pack-linux\n# On macOS: brew install wine mono\n$ yarn run pack-windows\n$ yarn run pack # all\n```\n\nIf you want to build binaries yourself, please remove [../electron/update.js](electron/update.js) (and [electon/main.js usage](electon/main.js)).\n\nFor macOS, note that if your app binary is not code signed, you will often get a firewall prompt from React DevTools server.\n\n### [Optional] Prerequisites for packaging Linux / Windows app on macOS\n\n```bash\n# Linux\nbrew install fakeroot dpkg rpm\n\n# Windows\nbrew tap homebrew/cask-versions\nbrew install wine-stable mono\n```\n\n## Financial contributions\n\nWe also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/react-native-debugger).\nAnyone can file an expense. If the expense makes sense for the development of the community, it will be \"merged\" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.\n\n## Credits\n\n### Contributors\n\nThank you to all the people who have already contributed to react-native-debugger!\n\n### Backers\n\nThank you to all our backers! [[Become a backer](https://opencollective.com/react-native-debugger#backer)]\n\n<a href=\"https://opencollective.com/react-native-debugger#backers\" target=\"_blank\"><img src=\"https://opencollective.com/react-native-debugger/backers.svg?width=890\"></a>\n\n### Sponsors\n\nThank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/react-native-debugger#sponsor))\n\n<a href=\"https://opencollective.com/react-native-debugger#backers\" target=\"_blank\"><img src=\"https://opencollective.com/react-native-debugger/sponsors.svg?width=890\"></a>\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n"
  },
  {
    "path": "docs/debugger-integration.md",
    "content": "# Debugger integration\n\nThe Debugger worker is referenced from [react-native](https://github.com/facebook/react-native/blob/master/local-cli/server/util/) debugger-ui, so it's only working if you're enabled `Debug JS Remotely`, you can debug your app in Chrome Developer Tools, we keep the following tabs:\n\n- `Console`\n- `Sources`\n- `Network` (Inspect Network requests if you are enabled [Network Inspect](network-inspect-of-chrome-devtools.md))\n- `Memory`\n\n## Multiple React Native packager (custom port) support\n\nWe can use [`react-native-debugger-open`](../npm-package) package to detect RN packager port, it will open an another window automatically if another debugger workers are running.\n\nIf you don't use [the npm package](../npm-package) and want to change port, click `Debugger` -> `New Window` (`Command⌘ + T` for macOS, `Ctrl + T` for Linux / Windows) in application menu, you need to type an another RN packager port. The default port is use [`Expo`](https://github.com/expo/expo) (and [`create-react-native-app`](https://github.com/react-community/create-react-native-app)) default port.\n\nFor macOS (10.12+), it used native tabs feature, see [the support page](https://support.apple.com/en-us/HT206998) for known how to use and setting.\n\n## Debugging tips\n\n#### Global variables in console\n\nWhen you enabled remote debugging, RNDebugger should switched context to `RNDebuggerWorker.js` automatically, so you can get global variables of React Native runtime in the console.\n\n- `$r`: You selected element on react-devtools.\n- `showAsyncStorageContentInDev()` - Log AsyncStorage content\n- `$reactNative.*` - Get react-native modules. For example, you can get `$reactNative.AsyncStorage`\n\n#### Enable `Debug Remotely` programmatically\n\nFor enable `Debug Remotely` without using dev menu, you can use the built-in `DevSettings` native module:\n\n```js\nimport { NativeModules } from 'react-native'\n\nif (__DEV__) {\n  NativeModules.DevSettings.setIsDebuggingRemotely(true)\n}\n```\n\nIf you're using Expo, you can still use the method, but it probably only works with `jsEngine: jsc` in `app.json`, `jsEngine: hermes` may not works.\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/enable-open-in-editor-in-console.md",
    "content": "# Enable open in editor in console\n\nYou can toggle the application menu item:\n\n<img width=\"386\" alt=\"2017-08-16 10 44 41\" src=\"https://user-images.githubusercontent.com/3001525/29369913-91f2e584-8269-11e7-8ebb-10d881aa5f0a.png\">\n\nInstead of open file in `Sources` tab, you can open file in editor by click source link in console. This feature is disabled by default.\n\n## Known issues\n\n- Currently this feature doesn't work with Haul bundler, please tracking [issue #141](https://github.com/jhen0409/react-native-debugger/issues/141).\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/getting-started.md",
    "content": "# Getting Started\n\nJust these steps will let you start RNDebugger out of box:\n\n- Install the latest version ([download page](https://github.com/jhen0409/react-native-debugger/releases)).\n- Make sure all debugger clients of React Native are closed, usually are `http://localhost:<port>/debugger-ui`\n- Make sure RNDebugger is open and wait state.\n- RNDebugger will try connect to debugger proxy, use port `8081` by default, you can create a new debugger window (macOS: `Command+T`, Linux/Windows: `Ctrl+T`) to specify the port if you want.\n- Enable `Debug JS Remotely` of [developer menu](https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu) on your app\n\n## Launch by CLI or React Native packager\n\nPlatform: macOS / Linux\n\n### The `rndebugger:` URI scheme\n\nLaunch RNDebugger by typing the following command:\n\n```bash\n$ open \"rndebugger://set-debugger-loc?host=localhost&port=8081\"\n```\n\nOr `xdg-open` for Linux:\n\n```bash\n$ xdg-open \"rndebugger://set-debugger-loc?host=localhost&port=8081\"\n```\n\nThe `host` / `port` means React Native packager. You may need to set `port` if you customize the packager port. (`8081` by default)\n\nFrom [`Debugging using a custom JavaScript debugger`](https://reactnative.dev/docs/0.71/debugging#debugging-using-a-custom-javascript-debugger) of React Native docs, you can use `REACT_DEBUGGER` env on react-native packager, it will try to launch RNDebugger when you turn on `Debug JS Remotely`:\n\n```bash\n$ REACT_DEBUGGER=\"unset ELECTRON_RUN_AS_NODE && open -g 'rndebugger://set-debugger-loc?port=19000' ||\" npm start\n```\n\nYou can use `open` on macOS or `xdg-open` on Linux, currently it is not supported for Windows.\n\n### Use [`react-native-debugger-open`](../npm-package)\n\nIf you don‘t need to add a dependency, you can use the package, it can help with:\n\n- Replace `open debugger-ui with Chrome` to `open React Native Debugger` in react-native packager, saving you from closing the debugger-ui page everytime it automatically opens :)\n- Detect react-native packager port then send to the app, if you launch packager with custom `--port` or use Expo, this will be very useful\n\n### What about Windows support?\n\nCurrently the `rndebugger:` URI scheme doesn't support for Windows.\n\nIn [`react-native-debugger-open`](../npm-package), it can be sent the `host` / `port` setting if RNDebugger opened, but can't automatically open if closed.\n\nIf you want to have the feature (`rndebugger:` or another way), you are welcome to contribute. Please read [contributing](https://github.com/jhen0409/react-native-debugger/blob/master/docs/contributing.md) to become a maintainer.\n\n## Use Redux DevTools Extension API\n\nUsing the same API as [`redux-devtools-extension`](https://github.com/zalmoxisus/redux-devtools-extension#1-with-redux) is very simple:\n\n```js\nconst store = createStore(\n  reducer /* preloadedState, */,\n  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),\n)\n```\n\nSee [`Redux DevTools Integration`](redux-devtools-integration.md) section for more information.\n\n## Platform support\n\n- [React Native](https://github.com/facebook/react-native) >= 0.43\n- [React Native for macOS](https://github.com/ptmt/react-native-macos) (formerly react-native-desktop) >= 0.14.0\n- [React Native for Windows](https://github.com/Microsoft/react-native-windows)\n\n## Auto-update RNDebugger app (Supported v0.5.0 after)\n\nCurrently auto-update is only supported for macOS. Linux and Windows will show a dialog of new versions available for download.\n\nYou can also click `React Native Debugger` (`RND` for Linux / Windows) -> `Check for Updates...` in the application menu.\n\n## Other documentations\n\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/network-inspect-of-chrome-devtools.md",
    "content": "# Network Inspect of Chrome Developer Tools\n\n**_WARNING_**: You should read [the limitations](#limitations) if you want to use this feature.\n\nWhen you have Network Inspect enabled you can inspect network requests that use `XMLHttpRequest` or `fetch` on the `Network` tab of Chrome Developer Tools.\n\nYou can enable this feature by one of these ways:\n\n- [context menu or Touch Bar](shortcut-references.md) (Network Inspect will be enabled while the RNDebugger is running, after closing it will reset to the default value);\n- by the `defaultNetworkInspect` option in the [config file](config-file-in-home-directory.md) (Network Inspect will be enabled permanently).\n\n## How it works\n\nSee [the comments of `react-native/Libraries/Utilities/PolyfillFunctions#L15-L27`](https://github.com/facebook/react-native/blob/ab97b9f6021d2b31b7155970c2be0c83f7e43f04/Libraries/Utilities/PolyfillFunctions.js#L15-L27). It uses `XMLHttpRequest` from WebWorker in Chrome, basically it can manually setup by:\n\n```js\nglobal.XMLHttpRequest = global.originalXMLHttpRequest\n  ? global.originalXMLHttpRequest\n  : global.XMLHttpRequest;\nglobal.FormData = global.originalFormData\n  ? global.originalFormData\n  : global.FormData;\n\nfetch; // Ensure to get the lazy property\n\nif (window.__FETCH_SUPPORT__) {\n  // it's RNDebugger only to have\n  window.__FETCH_SUPPORT__.blob = false;\n} else {\n  /*\n   * Set __FETCH_SUPPORT__ to false is just work for `fetch`.\n   * If you're using another way you can just use the native Blob and remove the `else` statement\n   */\n  global.Blob = global.originalBlob ? global.originalBlob : global.Blob;\n  global.FileReader = global.originalFileReader\n    ? global.originalFileReader\n    : global.FileReader;\n}\n```\n\n> Note that replace `global.Blob` will cause issue like [#56](https://github.com/jhen0409/react-native-debugger/issues/56).\n\nThis allows you can open the `Network` tab in devtools to inspect requests of `fetch` and `XMLHttpRequest`.\n\nYou can also do this on the official remote debugger, but it has two differences:\n\n- RNDebugger is based on [Electron](https://github.com/electron/electron) so it doesn't have the CORS issue\n- We support setting [`Forbidden header names`](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name), so you can use headers like `Origin` and `User-Agent`.\n\n## Limitations\n\nThere are some limitations of debugging network requests using Network Inspect:\n\n- [iOS] Requests pass `NSExceptionDomains` checks. If you forget to set a domain name, the requests will break in production. You should be clear about the difference.\n- [Android] If your network request would have caused `java.security.cert.CertPathValidatorException`, the Network Inpsect will skip that because it uses Debugger's network client.\n- React Native `FormData` supports the `uri` property. You can use files from `CameraRoll`, but `originalFormData` isn't supported.\n- It can't inspect request like `Image`s loaded from urls for `src`, so if your `Image` source has a set session, the session can't apply to `fetch` and `XMLHttpRequest`.\n\nIf you want to inspect deeper network requests (like requests made with `Image`), use tools like [Charles](https://www.charlesproxy.com) or [Flipper](https://github.com/facebook/flipper).\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/react-devtools-integration.md",
    "content": "# React DevTools Integration\n\n**_NOTE_** Supported React Native version is `>= 0.62`. Please downgrade RNDebugger version to `0.10` if you're using older versions of React Native.\n\nThe [React DevTools](https://reactnative.dev/docs/debugging#react-developer-tools) is built by [`facebook/react/packages/react-devtools-core`](https://github.com/facebook/react/tree/master/packages/react-devtools-core).\n\nIt will open a WebSocket server to waiting React Native connection. The connection is already included in React Native (see [`setUpReactDevTools.js`](https://github.com/facebook/react-native/blob/0.62-stable/Libraries/Core/setUpReactDevTools.js)), it will keep trying to connect the React DevTools server in development mode, it should work well without any specification.\n\nWe made the server listen to a random port and inject `window.__REACT_DEVTOOLS_PORT__` global variable in debugger worker.\n\nFor Android, we have the built-in `adb` util and it will reverse the port automatically.\n\n## Get `$r` global variable of React Native runtime in the console\n\nRefer to [`Debugger Integration`](debugger-integration.md#debugging-tips).\n\n## **_Question_**: I got `Unsupported` message from React DevTools\n\nIf you're using React Native version >= 0.62 and keep React Native Debugger as the latest version, here is what you can do:\n\nIn your app project, make sure the `react-devtools-core` dependency to match the React DevTools version. Add resolutions in your `package.json` for Yarn:\n\n```json\n{\n  \"resolutions\": {\n    \"react-devtools-core\": \"~4.28.0\"\n  }\n}\n```\n\nor NPM:\n\n```json\n{\n  \"overrides\": {\n    \"react-devtools-core\": \"~4.28.0\"\n  }\n}\n```\n\nReference: [Unsupported DevTools backend version - # React Native Debugger](https://gist.github.com/bvaughn/4bc90775530873fdf8e7ade4a039e579#react-native-debugger)\n\nIf the React Native version of your project doesn't support `react-devtools-core@4.25`, please consider downgrade React Native Debugger version to v0.12.\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/redux-devtools-integration.md",
    "content": "# Redux DevTools Integration\n\nWe used [@redux-devtools/app](https://github.com/reduxjs/redux-devtools/tree/main/packages/redux-devtools-app) and made the API same with [Redux DevTools Extension](https://github.com/reduxjs/redux-devtools/tree/main/extension).\n\nIf you've enabled `Debug JS remotely` with React Native Debugger, the following API is already included in global:\n\n- `window.__REDUX_DEVTOOLS_EXTENSION__`\n- `window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__`\n- `window.__REDUX_DEVTOOLS_EXTENSION__.connect`\n- You can just use [`redux-devtools-extension`](https://www.npmjs.com/package/redux-devtools-extension) npm package.\n\nSee also:\n\n- [Redux DevTools main repository]](https://github.com/reduxjs/redux-devtools/blob/main/README.md)\n- [API Reference](https://github.com/reduxjs/redux-devtools/tree/main/extension/docs/API)\n- [Troubleshooting](https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/Troubleshooting.md)\n- Other Integrations\n  - [`mobx-state-tree`](https://github.com/mobxjs/mobx-state-tree) - Use [`connectReduxDevtools`](https://github.com/mobxjs/mobx-state-tree/tree/3fc79b0b3ce7ad3e26d6bd5745fd9412d35c431c/packages/mst-middlewares#connectreduxdevtools) middleware.\n\nYou can ignore the things specified by the browser extension.\n\n## About `trace` feature\n\n- The debugger app might be slowed down if you enabled the `trace` feature and visited the `Trace` tab, because it will load and parse the source map for every selected action.\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/shortcut-references.md",
    "content": "# Shortcut references\n\nThis section will explain about the following items in RNDebugger.\n\n- [Content menu](#context-menu)\n- [Touch Bar](#touch-bar-in-macos)\n- [Keyboard shortcuts](#keyboard-shortcuts)\n\n## Context menu\n\nWe have context menu (right-click) for provides useful features:\n\n![Context menu](https://cloud.githubusercontent.com/assets/3001525/25920996/5c488966-3606-11e7-8d0c-cb564671067b.gif)\n\n- Reload\n- Toggle Elements Inspector\n- Show Developer Menu [iOS only]\n- Enable / Disable [Network Inspect](debugger-integration.md#how-network-inspect-works)\n- Log AsyncStorage content\n- Clear AsyncStorage\n\nIt includes the developer menu features, these would be useful for real device, instead of open developer menu in device manually.\n\n## Keyboard shortcuts\n\n- Reload JS (macOS: `Command+R`, Windows / Linux: `Ctrl+R`)\n- Toggle Elements Inspector (macOS: `Command+I`, Windows / Linux: `Ctrl+I`)\n- New Debugger Window (macOS: `Command+T`, Windows / Linux: `Ctrl+T`)\n- Toggle Developer Tools (macOS: `Command+Option+I`, Windows / Linux: `Ctrl+Alt+I`)\n- Toggle Redux DevTools (macOS: `Command+Option+J`, Windows / Linux: `Ctrl+Alt+J`)\n- Toggle React DevTools (macOS: `Command+Option+K`, Windows / Linux: `Ctrl+Alt+K`)\n- Quickly into search field of React DevTools (Type `/`)\n\nYou can also read [Keyboard Shortcuts Reference of Chrome Developer Tools](https://developers.google.com/web/tools/chrome-devtools/shortcuts).\n\n## Touch Bar in macOS\n\n<img alt=\"touch-bar\" src=\"https://user-images.githubusercontent.com/3001525/27730359-8565810a-5dbb-11e7-9052-9fd4feb72181.png\">\n\nThe `Redux Slider` will shown on right if you're using [`Redux API`](redux-devtools-integration.md),\n\nIf your Mac haven't TouchBar support and you still want to use the feature, you can use [Touché](https://redsweater.com/touche/).\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Troubleshooting](troubleshooting.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "docs/troubleshooting.md",
    "content": "# Troubleshooting\n\n## I got `Unsupported` meesage from React DevTools\n\nIf you're using React Native version >= 0.62 and keep React Native Debugger as the latest version, here is what you can do:\n\nIn your app project, make sure the `react-devtools-core` dependency to match the React DevTools version. Add resolutions in your `package.json` for Yarn:\n\n```json\n{\n  \"resolutions\": {\n    \"react-devtools-core\": \"~4.28.0\"\n  }\n}\n```\n\nor NPM:\n\n```json\n{\n  \"overrides\": {\n    \"react-devtools-core\": \"~4.28.0\"\n  }\n}\n```\n\nReference: [Unsupported DevTools backend version - # React Native Debugger](https://gist.github.com/bvaughn/4bc90775530873fdf8e7ade4a039e579#react-native-debugger)\n\nIf the React Native version of your project doesn't support `react-devtools-core@4.25`, please consider downgrade React Native Debugger version to v0.12.\n\n## Network fetch got issue like [`SyntaxError: Unexpected token o in JSON at position 1`](https://github.com/jhen0409/react-native-debugger/issues/382#issuecomment-544226529) if Network Inspect enabled\n\nThis may be caused by some library used / made fetch polyfills, it may used `Blob` but RNDebugger does not support it. If you got this issue, try to use global `fetch` / `XMLHttpRequest` instead, or try [#382#issuecomment-544226529](https://github.com/jhen0409/react-native-debugger/issues/382#issuecomment-544226529).\n\n## Debugger causes app to load stale JS bundle ([#423](https://github.com/jhen0409/react-native-debugger/issues/423))\n\nThis issue was fixed by [v0.10.9](https://github.com/jhen0409/react-native-debugger/releases/tag/v0.10.9) and [v0.11.1](https://github.com/jhen0409/react-native-debugger/releases/tag/v0.11.1). If you are still using the old version for some reason, you can turn off Network cache manually on devtools:\n\n![image](https://user-images.githubusercontent.com/848589/69504219-b0d46d00-0f85-11ea-99ed-de5e4e2e59c0.png)\n\n## Some shortcuts (e.g. `Reload` / `Clear AsyncStorage`) are missing on the Debugger\n\n- For Android and React Native version less than v0.60, you need to add and link [`react-native-devsettings-android`](https://github.com/jhen0409/react-native-devsettings-android) package\n- If you're not using dev bundle (dev=true) from React Native packager, it will not working as expected.\n- For some reasons, some dependencies may affected [Promise](https://github.com/jhen0409/react-native-debugger/blob/master/app/worker/utils.js#L7) behavior. It is recommended to use the initial project to find out the reason.\n- If you are sure it is caused by a new version of React Native, please file an new issue.\n\n## How to resolve problem of high memory usage on devtools?\n\nYou may have got a problem when you often reload JS, devtools process takes your RAM even more than 1G, it does not seem to clean.\n\nIn case of using [official remote debugger](https://reactnative.dev/docs/debugging#chrome-developer-tools), tested a initial project with remote debugging mode on Chrome 62 (beta), continuous reload JS 30 times:\n\nBefore:  \n<img width=\"600\" alt=\"2017-09-19 5 32 05 pm\" src=\"https://user-images.githubusercontent.com/3001525/30585922-ed1e557a-9cf3-11e7-9730-3b941618924f.png\">\n\nAfter:  \n<img width=\"600\" alt=\"2017-09-19 5 31 33 pm\" src=\"https://user-images.githubusercontent.com/3001525/30585923-ed1e3a54-9cf3-11e7-8d09-9915f8cffea6.png\">\n\nFortunately, the current versions of RNDebugger (Chromium 58) is better than Chrome (maybe >= 59?), but it still has a amount of growth:\n\nBefore:  \n<img width=\"704\" alt=\"2017-09-19 5 40 18 pm\" src=\"https://user-images.githubusercontent.com/3001525/30586300-27e0df7e-9cf5-11e7-9614-07162e86680c.png\">\n\nAfter:  \n<img width=\"704\" alt=\"2017-09-19 5 41 27 pm\" src=\"https://user-images.githubusercontent.com/3001525/30586302-29e0b268-9cf5-11e7-9206-e222bd753aa1.png\">\n\nTo avoid similar problems in the future, there is a way to restart the Chrome devtools (macOS: `CMD+OPTION+I`, Linux/Windows: `CTRL+ALT+I`), the same applies to official remote debugger on Chrome. You can also consider to use [`timesJSLoadToRefreshDevTools` option in Config file in home directory](config-file-in-home-directory.md).\n\n## [iOS] Debugger can't load bundle when I use real device\n\nIf you're getting the following error:\n\n![](https://user-images.githubusercontent.com/3001525/28763926-214df82c-75f4-11e7-98bc-1be54638f91b.png)\n\nIt may caused by [`xip.io`](http://xip.io) service (RN use it for debug on real device), it lead your machine IP doesn't resolved sometimes. It's [enabled by default](https://github.com/facebook/react-native/blob/ca9202f2385354b7a6b4d818ceb46bd96a037a7b/scripts/react-native-xcode.sh#L94), you can disable it in RN custom script on Xcode if you sure you don't need the service:\n\n<img width=\"839\" alt=\"2017-07-31 1 19 34\" src=\"https://user-images.githubusercontent.com/3001525/28763831-82811012-75f3-11e7-9675-d5ae515f4f38.png\">\n\n## React Inspector get stuck at \"Connecting to React…\" for RN ^0.43 ([#45](https://github.com/jhen0409/react-native-debugger/issues/45))\n\nIt usually on Android, the problem is related to `requestIdleCallback` API (try to check if it not work on debug mode).\n\nThis issue have been fixed in `react-devtools-core@^2.3.0`, please ensure the version is correct in your React Native project (Note that it's dependency of `react-native`).\n\nAlso, sometimes it have timer problem between host machine and device (emulator), you need make sure `date & time` setting is correct:\n\n<img width=\"300\" alt=\"2017-07-18 10 09 01\" src=\"https://user-images.githubusercontent.com/3001525/28492059-3c6957ea-6f2e-11e7-8901-8f4431f67a71.png\">\n\nOr try to restart your device (emulator).\n\n## [Windows 10] React native debugger process starts but no visible window ([#459](https://github.com/jhen0409/react-native-debugger/issues/459))\n\nThis issue is caused by Windows 10 dark mode, for a workaround please disable dark mode and enable it again after launching react-native-debugger\n\n## Other documentations\n\n- [Getting Started](getting-started.md)\n- [Debugger Integration](debugger-integration.md)\n- [React DevTools Integration](react-devtools-integration.md)\n- [Redux DevTools Integration](redux-devtools-integration.md)\n- [Apollo Client DevTools Integration](apollo-client-devtools-integration.md)\n- [Shortcut references](shortcut-references.md)\n- [Network inspect of Chrome Developer Tools](network-inspect-of-chrome-devtools.md)\n- [Enable open in editor in console](enable-open-in-editor-in-console.md)\n- [Config file in home directory](config-file-in-home-directory.md)\n- [Contributing](contributing.md)\n"
  },
  {
    "path": "electron/app.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <meta charset=utf-8>\n    <title>React Native Debugger</title>\n    <link href='../dist/css/style.css' rel=\"stylesheet\" />\n  </head>\n  <body>\n    <div id=\"root\">\n      <div id=\"loading\">Loading...</div>\n    </div>\n    <script src=\"http://localhost:3000/js/bundle.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "electron/config/__tests__/__snapshots__/index.test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`openConfigFile 1`] = `\n{\n  \"config\": {\n    \"autoUpdate\": true,\n    \"defaultNetworkInspect\": false,\n    \"defaultRNPackagerPorts\": [\n      8081,\n    ],\n    \"defaultReactDevToolsPort\": 19567,\n    \"defaultReactDevToolsTheme\": \"RNDebugger\",\n    \"editor\": \"\",\n    \"timesJSLoadToRefreshDevTools\": -1,\n    \"windowBounds\": {\n      \"frame\": true,\n    },\n  },\n}\n`;\n\nexports[`readConfig 1`] = `\n{\n  \"config\": {\n    \"autoUpdate\": true,\n    \"defaultNetworkInspect\": false,\n    \"defaultRNPackagerPorts\": [\n      8081,\n    ],\n    \"defaultReactDevToolsPort\": 19567,\n    \"defaultReactDevToolsTheme\": \"RNDebugger\",\n    \"editor\": \"\",\n    \"timesJSLoadToRefreshDevTools\": -1,\n    \"windowBounds\": {\n      \"frame\": true,\n    },\n  },\n}\n`;\n\nexports[`readConfig 2`] = `\n{\n  \"config\": {\n    \"autoUpdate\": false,\n  },\n}\n`;\n\nexports[`readConfig 3`] = `\n{\n  \"config\": {\n    \"autoUpdate\": true,\n    \"defaultNetworkInspect\": false,\n    \"defaultRNPackagerPorts\": [\n      8081,\n    ],\n    \"defaultReactDevToolsPort\": 19567,\n    \"defaultReactDevToolsTheme\": \"RNDebugger\",\n    \"editor\": \"\",\n    \"timesJSLoadToRefreshDevTools\": -1,\n    \"windowBounds\": {\n      \"frame\": true,\n    },\n  },\n  \"error\": [SyntaxError: Unexpected 'i' at line 1 column 16 of the JSON5 data. Still to read: \"is_broken, }\"],\n  \"isConfigBroken\": true,\n}\n`;\n"
  },
  {
    "path": "electron/config/__tests__/index.test.js",
    "content": "import fs from 'fs'\nimport path from 'path'\n\njest.mock('electron', () => ({\n  shell: {\n    openPath: jest.fn(),\n  },\n}))\n\nconst testFile = path.join(__dirname, 'config_test')\n\nbeforeAll(() => fs.existsSync(testFile) && fs.unlinkSync(testFile))\n\n/* eslint-disable global-require */\ntest('readConfig', () => {\n  const { readConfig } = require('..')\n\n  expect(readConfig(testFile)).toMatchSnapshot()\n\n  // User custom config\n  fs.writeFileSync(testFile, '{ autoUpdate: false, }')\n  expect(readConfig(testFile)).toMatchSnapshot()\n\n  // Broken config\n  fs.writeFileSync(testFile, '{ autoUpdate: is_broken, }')\n  expect(readConfig(testFile)).toMatchSnapshot()\n})\n\ntest('openConfigFile', () => {\n  const { readConfig, openConfigFile } = require('..')\n  const { shell } = require('electron')\n\n  openConfigFile(testFile)\n  expect(shell.openPath).toBeCalledWith(testFile)\n  shell.openPath.mockClear()\n\n  fs.unlinkSync(testFile)\n  openConfigFile(testFile)\n  expect(readConfig(testFile)).toMatchSnapshot()\n})\n"
  },
  {
    "path": "electron/config/index.js",
    "content": "import fs from 'fs'\nimport path from 'path'\nimport json5 from 'json5'\nimport { shell } from 'electron'\nimport template from './template'\n\nexport const filePath = path.join(\n  process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'],\n  '.rndebuggerrc',\n)\n\nexport const readConfig = (configFile = filePath) => {\n  if (!fs.existsSync(configFile)) {\n    // Create a new one\n    fs.writeFileSync(configFile, template)\n    return { config: json5.parse(template) }\n  }\n  try {\n    // eslint-disable-next-line\n    return { config: json5.parse(fs.readFileSync(configFile, 'utf-8')) };\n  } catch (error) {\n    // Alert parse config not successful\n    return { config: json5.parse(template), isConfigBroken: true, error }\n  }\n}\n\nexport const openConfigFile = (configFile = filePath) => {\n  readConfig()\n  shell.openPath(configFile)\n}\n"
  },
  {
    "path": "electron/config/template.js",
    "content": "// json5\nmodule.exports = `{\n  // Font family of the debugger window\n  // fontFamily: 'monaco, Consolas, Lucida Console, monospace',\n\n  // Zoom level of the debugger window, it will override persited zoomLevel\n  // zoomLevel: 0,\n\n  // Settings of debugger window, \n  windowBounds: {\n    // Size of the debugger window, it will override persisted size\n    // width: 1024,\n    // height: 750,\n\n    // Show frame for debugger window\n    // but due to https://github.com/electron/electron/issues/3647\n    // so we can't have custom title bar if no frame\n    // titleBarStyle: 'hidden',\n    frame: true,\n  },\n\n  // Auto check update on RNDebugger startup\n  autoUpdate: true,\n\n  // RNDebugger will open debugger window with the ports when app launched\n  defaultRNPackagerPorts: [8081],\n\n  // Env for\n  // open React DevTools source file link\n  // and enable open in editor for console log for RNDebugger\n  editor: '',\n\n  // Set default react-devtools theme (default is match Chrome DevTools theme)\n  // but the default theme doesn't change manually changed theme\n  // see https://github.com/facebook/react-devtools/blob/master/frontend/Themes/Themes.js to get more\n  defaultReactDevToolsTheme: 'RNDebugger',\n\n  // Set default react-devtools port (default is \\`19567+\\` if it is not being used).\n  // The devtools backend of React Native will use the port to connect to the devtools server.\n  // You should use that if you have some rules for binding port.\n  //   (like https://github.com/jhen0409/react-native-debugger/issues/397)\n  defaultReactDevToolsPort: 19567,\n\n  // Enable Network Inspect by default\n  // See https://github.com/jhen0409/react-native-debugger/blob/master/docs/network-inspect-of-chrome-devtools.md\n  defaultNetworkInspect: false,\n\n  // Refresh devtools when doing JS reload every N times. (-1 for disabled)\n  // This can effectively avoid possible memory leaks (Like\n  // https://github.com/jhen0409/react-native-debugger/issues/405) in devtools.\n  timesJSLoadToRefreshDevTools: -1,\n}\n`\n"
  },
  {
    "path": "electron/context-menu.js",
    "content": "import { ipcMain } from 'electron'\nimport contextMenu from 'electron-context-menu'\nimport { readConfig } from './config'\nimport {\n  toggleDevTools, n, item, separator,\n} from './menu/common'\n\nconst invokeDevMethod = (win, name) => win.webContents.executeJavaScript(\n  `window.invokeDevMethod && window.invokeDevMethod('${name}')`,\n)\n\nexport const registerContextMenu = (win) => {\n  const { config } = readConfig()\n  const defaultContextMenuItems = [\n    item('Toggle Developer Tools', n, () => toggleDevTools(win, 'chrome')),\n    item('Toggle React DevTools', n, () => toggleDevTools(win, 'react')),\n    item('Toggle Redux DevTools', n, () => toggleDevTools(win, 'redux')),\n  ]\n  let networkInspectEnabled = !!config.networkInspect\n  let availableMethods = []\n  contextMenu({\n    window: win,\n    showInspectElement: process.env.NODE_ENV === 'development',\n    prepend: () => [\n      availableMethods.includes('reload')\n          && item('Reload JS', n, () => invokeDevMethod(win, 'reload')),\n      availableMethods.includes('toggleElementInspector')\n          && item('Toggle Element Inspector', n, () => invokeDevMethod(win, 'toggleElementInspector')),\n      availableMethods.includes('show')\n          && item('Show Developer Menu', n, () => invokeDevMethod(win, 'show')),\n      item(\n        networkInspectEnabled\n          ? 'Disable Network Inspect'\n          : 'Enable Network Inspect',\n        n,\n        () => invokeDevMethod(win, 'networkInspect'),\n      ),\n      availableMethods.includes('showAsyncStorage')\n          && item('Log AsyncStorage content', n, () => invokeDevMethod(win, 'showAsyncStorage')),\n      availableMethods.includes('clearAsyncStorage')\n          && item('Clear AsyncStorage', n, () => invokeDevMethod(win, 'clearAsyncStorage')),\n      separator,\n    ]\n      .filter((menuItem) => !!menuItem)\n      .concat(defaultContextMenuItems),\n  })\n\n  const listener = (event, data) => {\n    availableMethods = data.availableMethods || availableMethods\n    networkInspectEnabled = typeof data.networkInspectEnabled === 'boolean'\n      ? data.networkInspectEnabled\n      : networkInspectEnabled\n  }\n\n  ipcMain.on(`context-menu-available-methods-update-${win.id}`, listener)\n  return () => {\n    ipcMain.off(`context-menu-available-methods-update-${win.id}`, listener)\n  }\n}\n"
  },
  {
    "path": "electron/debug.js",
    "content": "require('electron-debug')(); // eslint-disable-line\n"
  },
  {
    "path": "electron/devtools.js",
    "content": "export const getCatchConsoleLogScript = (port) => `\n  window.__RN_PACKAGER_MATCHER__ = /^http:\\\\/\\\\/[^:]+:${port}/;\n  if (!window.__INJECT_OPEN_IN_EDITOR_SCRIPT__) {\n    const rndHelperQuery = 'iframe[data-devtools-extension=\"RNDebugger devtools helper\"]';\n    document.addEventListener('click', event => {\n      if (!window.__IS_OPEN_IN_EDITOR_ENABLED__) {\n        return;\n      }\n      const { target } = event;\n      if (target.className === 'devtools-link') {\n        const source = target.title;\n        if (source && source.match(window.__RN_PACKAGER_MATCHER__)) {\n          const rndHelper = document.querySelector(rndHelperQuery);\n          if (rndHelper && rndHelper.contentWindow) {\n            rndHelper.contentWindow.postMessage(\n              {\n                type: 'open-in-editor',\n                source: source.replace(window.__RN_PACKAGER_MATCHER__, '')\n              },\n              '*'\n            );\n            return event.stopPropagation();\n          }\n        }\n      }\n    }, true);\n    window.__INJECT_OPEN_IN_EDITOR_SCRIPT__ = true;\n  }\n`\n\nexport const catchConsoleLogLink = (win, host = 'localhost', port = 8081) => {\n  if (win.devToolsWebContents) {\n    return win.devToolsWebContents.executeJavaScript(`(() => {\n      ${getCatchConsoleLogScript(host, port)}\n    })()`)\n  }\n}\n\nexport const removeUnecessaryTabs = (win) => {\n  if (\n    process.env.NODE_ENV === 'production'\n    && !process.env.DEBUG_RNDEBUGGER\n    && win.devToolsWebContents\n  ) {\n    return win.devToolsWebContents.executeJavaScript(`(() => {\n      const tabbedPane = UI.inspectorView.tabbedPane;\n      if (tabbedPane) {\n        tabbedPane.closeTab('elements');\n        tabbedPane.closeTab('security');\n        tabbedPane.closeTab('audits');\n        tabbedPane.closeTab('audits2');\n        tabbedPane.closeTab('lighthouse');\n\n        tabbedPane.leftToolbar().element.remove();\n      }\n    })()`)\n  }\n}\n\nexport const activeTabs = (win) => {\n  if (win.devToolsWebContents) {\n    // Active network tab so we can do clearNetworkLogs\n    return win.devToolsWebContents.executeJavaScript(`(() => {\n      DevToolsAPI.showPanel('network');\n      DevToolsAPI.showPanel('console');\n    })()`)\n  }\n}\n"
  },
  {
    "path": "electron/extensions.js",
    "content": "import path from 'path'\nimport { session } from 'electron'\n\nexport default async () => {\n  if (process.env.NODE_ENV === 'development') {\n    await session.defaultSession.loadExtension(\n      path.resolve('dist/devtools-helper/'),\n      { allowFileAccess: true },\n    )\n    await session.defaultSession.loadExtension(\n      path.join(\n        __dirname,\n        '../node_modules/apollo-client-devtools/build',\n      ),\n      { allowFileAccess: true },\n    )\n  } else if (process.env.PACKAGE === 'no') {\n    await session.defaultSession.loadExtension(\n      path.join(__dirname, 'devtools-helper/'),\n      { allowFileAccess: true },\n    )\n    await session.defaultSession.loadExtension(\n      path.join(\n        __dirname,\n        'node_modules/apollo-client-devtools/build',\n      ),\n      { allowFileAccess: true },\n    )\n  } else {\n    await session.defaultSession.loadExtension(\n      path.join(__dirname, '../devtools-helper/'),\n      { allowFileAccess: true },\n    )\n    await session.defaultSession.loadExtension(\n      path.join(\n        __dirname,\n        '../ac-devtools-ext-build/', // See package script for why\n      ),\n      { allowFileAccess: true },\n    )\n  }\n}\n"
  },
  {
    "path": "electron/main.js",
    "content": "import path from 'path'\nimport {\n  app, ipcMain, session, BrowserWindow, Menu,\n} from 'electron'\nimport { initialize } from '@electron/remote/main'\nimport normalizeHeaderCase from 'header-case-normalizer'\nimport installExtensions from './extensions'\nimport { checkWindowInfo, createWindow } from './window'\nimport { startListeningHandleURL, handleURL, parseUrl } from './url-handle'\nimport { createMenuTemplate } from './menu'\nimport { readConfig } from './config'\nimport { sendSyncState } from './sync-state'\n\ninitialize()\n\n// Uncomment if want to debug devtools backend\n// app.commandLine.appendSwitch('remote-debugging-port', '9222');\n\napp.commandLine.appendSwitch('disable-http-cache')\n\nprocess.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 1\n\nconst iconPath = path.resolve(__dirname, 'logo.png')\nconst defaultOptions = { iconPath }\n\nconst findWindow = async (_, port) => {\n  const browserWindows = BrowserWindow.getAllWindows()\n  const browserWindow = await browserWindows.reduce(async (promise, win) => {\n    const acc = await promise\n    if (acc) return acc\n\n    const { isWorkerRunning, isPortSettingRequired, location } = await checkWindowInfo(win)\n    return (!isWorkerRunning || location.port === port)\n      && !isPortSettingRequired\n      ? win\n      : null\n  }, Promise.resolve(null))\n  if (!browserWindow) createWindow(defaultOptions)\n  if (browserWindow) {\n    if (browserWindow.isMinimized()) browserWindow.restore()\n    browserWindow.focus()\n  }\n  return browserWindow\n}\n\nconst handleCommandLine = async (commandLine) => {\n  const url = commandLine.find((arg) => arg.startsWith('rndebugger://'))\n  if (!url) {\n    return\n  }\n  await handleURL(findWindow, url)\n}\n\nif (process.platform === 'linux') {\n  const singleInstanceLock = app.requestSingleInstanceLock()\n  if (!singleInstanceLock) {\n    process.exit()\n  } else {\n    app.on('second-instance', async (event, commandLine) => {\n      await handleCommandLine(commandLine)\n    })\n  }\n}\n\nstartListeningHandleURL(findWindow)\n\nipcMain.on('check-port-available', async (event, arg) => {\n  const port = Number(arg)\n  const windows = BrowserWindow.getAllWindows()\n  const isPortAvailable = await windows.reduce(async (promise, win) => {\n    const isAvailable = await promise\n    if (!isAvailable) return false\n\n    if (win.webContents !== event.sender) {\n      const { isPortSettingRequired, location } = await checkWindowInfo(win)\n      if (location.port === port && !isPortSettingRequired) {\n        return false\n      }\n    }\n    return true\n  }, Promise.resolve(true))\n  event.sender.send('check-port-available-reply', isPortAvailable)\n})\n\nipcMain.on('sync-state', sendSyncState)\n\napp.on('activate', () => {\n  if (BrowserWindow.getAllWindows().length !== 0) return\n  createWindow(defaultOptions)\n})\n\napp.on('new-window-for-tab', () => {\n  createWindow({ ...defaultOptions, isPortSettingRequired: true })\n})\n\napp.on('window-all-closed', () => {\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\nif (process.platform === 'darwin') {\n  app.on('before-quit', async (event) => {\n    event.preventDefault()\n    BrowserWindow.getAllWindows().forEach((win) => {\n      win.removeAllListeners('close')\n      win.close()\n    })\n    process.exit()\n  })\n}\n\napp.on('ready', async () => {\n  await installExtensions()\n\n  const { config } = readConfig()\n\n  let { defaultRNPackagerPorts } = config\n  if (!Array.isArray(defaultRNPackagerPorts)) {\n    defaultRNPackagerPorts = [8081]\n  }\n\n  if (process.platform === 'linux') {\n    const url = process.argv.find((arg) => arg.startsWith('rndebugger://'))\n    const query = url ? parseUrl(url) : undefined\n    if (query && query.port) {\n      defaultRNPackagerPorts = [query.port]\n    }\n  }\n\n  defaultRNPackagerPorts.forEach((port) => {\n    createWindow({ port, ...defaultOptions })\n  })\n\n  const menuTemplate = createMenuTemplate(defaultOptions)\n  const menu = Menu.buildFromTemplate(menuTemplate)\n  Menu.setApplicationMenu(menu)\n\n  const replaceHeaderPrefix = '__RN_DEBUGGER_SET_HEADER_REQUEST_'\n  session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {\n    delete details.requestHeaders.Origin\n    Object.entries(details.requestHeaders).forEach(([header, value]) => {\n      if (header.startsWith(replaceHeaderPrefix)) {\n        const originalHeader = normalizeHeaderCase(\n          header.replace(replaceHeaderPrefix, ''),\n        )\n        details.requestHeaders[originalHeader] = value\n        delete details.requestHeaders[header]\n      }\n    })\n    callback({ cancel: false, requestHeaders: details.requestHeaders })\n  })\n})\n\n// Pass all certificate errors in favor of Network Inspect feature\napp.on(\n  'certificate-error',\n  (event, webContents, url, error, certificate, callback) => {\n    event.preventDefault()\n    callback(true)\n  },\n)\n"
  },
  {
    "path": "electron/menu/common.js",
    "content": "export const toggleDevTools = (win, type) => {\n  if (!win || !type) return\n  if (type === 'chrome') {\n    win.toggleDevTools()\n    return\n  }\n  win.webContents.send('toggle-devtools', type)\n}\n\nexport const toggleFullscreen = (win) => win && win.setFullScreen(!win.isFullScreen())\nexport const setAlwaysOnTop = (win, checked) => win && win.setAlwaysOnTop(checked)\nexport const reload = (win) => win && win.webContents.reload()\nexport const close = (win) => win && win.close()\nexport const zoom = (win, val) => {\n  if (!win) return\n  const contents = win.webContents\n  contents.zoomLevel += val\n}\nexport const resetZoom = (win) => {\n  if (win) {\n    win.webContents.zoomLevel = 0\n  }\n}\nexport const toggleOpenInEditor = (win) => win && win.webContents.executeJavaScript('window.toggleOpenInEditor()')\n\nexport const menu = (label, submenu, role) => ({ label, submenu, role })\nexport const item = (label, accelerator, click, rest) => ({\n  label,\n  accelerator,\n  click,\n  ...rest,\n})\nexport const separator = { type: 'separator' }\nexport const n = undefined\n"
  },
  {
    "path": "electron/menu/darwin.js",
    "content": "import { app, shell, BrowserWindow } from 'electron'\nimport { createWindow } from '../window'\nimport checkUpdate from '../update'\nimport {\n  menu,\n  item,\n  separator,\n  n,\n  toggleDevTools,\n  toggleFullscreen,\n  setAlwaysOnTop,\n  reload,\n  zoom,\n  resetZoom,\n  toggleOpenInEditor,\n} from './common'\nimport { haveOpenedWindow, showAboutDialog } from './dialog'\nimport { openConfigFile } from '../config'\nimport { isSyncState, toggleSyncState } from '../sync-state'\n\nconst getWin = () => BrowserWindow.getFocusedWindow()\n\nconst viewItems = process.env.NODE_ENV === 'developemnt'\n  ? [item('Reload Window', 'Alt+Command+R', () => reload(getWin()))]\n  : []\n\nexport default ({ iconPath }) => [\n  menu('React Native Debugger', [\n    item('About', n, () => showAboutDialog(iconPath)),\n    item('Check for Updates...', n, () => checkUpdate(iconPath, true)),\n    separator,\n    item('Hide', 'Command+H', n, { selector: 'hide:' }),\n    item('Hide Others', 'Command+Shift+H', n, { selector: 'hideOtherApplications:' }),\n    item('Show All', n, n, { selector: 'unhideAllApplications:' }),\n    separator,\n    item('Quit', 'Command+Q', () => app.quit()),\n  ]),\n  menu(\n    'Debugger',\n    [\n      item('New Window', 'Command+T', () => createWindow({ iconPath, isPortSettingRequired: haveOpenedWindow() })),\n      item('Enable Open in Editor for Console Log', n, () => toggleOpenInEditor(getWin()), {\n        type: 'checkbox',\n        checked: false,\n      }),\n      item('Toggle Device Sync', n, toggleSyncState, {\n        type: 'checkbox',\n        checked: isSyncState(),\n      }),\n      item('Open Config File', n, () => openConfigFile()),\n      separator,\n      item('Minimize', 'Command+M', n, { selector: 'performMiniaturize:' }),\n      item('Close', 'Command+W', n, { selector: 'performClose:' }),\n      separator,\n      item('Bring All to Front', n, n, { selector: 'arrangeInFront:' }),\n      item('Stay in Front', n, ({ checked }) => setAlwaysOnTop(getWin(), checked), {\n        type: 'checkbox',\n        checked: false,\n      }),\n    ],\n    'window',\n  ),\n  menu('Edit', [\n    item('Undo', 'Command+Z', n, { selector: 'undo:' }),\n    item('Redo', 'Shift+Command+Z', n, { selector: 'redo:' }),\n    separator,\n    item('Cut', 'Command+X', n, { selector: 'cut:' }),\n    item('Copy', 'Command+C', n, { selector: 'copy:' }),\n    item('Paste', 'Command+V', n, { selector: 'paste:' }),\n    item('Select All', 'Command+A', n, { selector: 'selectAll:' }),\n  ]),\n  menu(\n    'View',\n    viewItems.concat([\n      item('Toggle Full Screen', 'F11', () => toggleFullscreen(getWin())),\n      item('Toggle Developer Tools', 'Alt+Command+I', () => toggleDevTools(getWin(), 'chrome')),\n      item('Toggle React DevTools', 'Alt+Command+J', () => toggleDevTools(getWin(), 'react')),\n      item('Toggle Redux DevTools', 'Alt+Command+K', () => toggleDevTools(getWin(), 'redux')),\n      separator,\n      item('Zoom In', 'Command+=', () => zoom(getWin(), 1)),\n      item('Zoom Out', 'Command+-', () => zoom(getWin(), -1)),\n      item('Reset Zoom', 'Command+0', () => resetZoom(getWin())),\n    ]),\n  ),\n  menu('Help', [\n    item('Documentation', n, () => shell.openExternal('https://github.com/jhen0409/react-native-debugger/tree/master/docs')),\n    item('Issues', n, () => shell.openExternal('https://github.com/jhen0409/react-native-debugger/issues')),\n    item('Open Collective', n, () => shell.openExternal('https://opencollective.com/react-native-debugger')),\n  ]),\n]\n"
  },
  {
    "path": "electron/menu/dialog.js",
    "content": "import { app, dialog, BrowserWindow } from 'electron'\nimport multiline from 'multiline-template'\n\nconst appName = app.name\nconst detail = multiline`\n  | Created by Jhen-Jie Hong\n  | (https://github.com/jhen0409)\n\n  | This software includes the following projects:\n\n  | https://github.com/facebook/react-devtools\n  | https://github.com/reduxjs/redux-devtools\n  | https://github.com/apollographql/apollo-client-devtools\n`\n\nexport const showAboutDialog = (iconPath) => dialog.showMessageBoxSync({\n  title: 'About',\n  message: `${appName} ${app.getVersion()}`,\n  detail,\n  icon: iconPath,\n  buttons: [],\n})\n\nexport const haveOpenedWindow = () => !!BrowserWindow.getAllWindows().length\n"
  },
  {
    "path": "electron/menu/index.js",
    "content": "/* eslint global-require: 0 */\n\nimport createMenuTemplateDarwin from './darwin'\nimport createMenuTemplateLinuxWin from './linux+win'\n\nconst createMenuTemplate = process.platform === 'darwin'\n  ? createMenuTemplateDarwin\n  : createMenuTemplateLinuxWin\n\nexport { createMenuTemplate }\n"
  },
  {
    "path": "electron/menu/linux+win.js",
    "content": "import { shell, BrowserWindow } from 'electron'\nimport { createWindow } from '../window'\nimport checkUpdate from '../update'\nimport {\n  menu,\n  item,\n  separator,\n  n,\n  toggleDevTools,\n  toggleFullscreen,\n  setAlwaysOnTop,\n  reload,\n  close,\n  zoom,\n  resetZoom,\n  toggleOpenInEditor,\n} from './common'\nimport {\n  showAboutDialog,\n  haveOpenedWindow,\n} from './dialog'\nimport { openConfigFile } from '../config'\nimport { toggleSyncState, isSyncState } from '../sync-state'\n\nconst getWin = () => BrowserWindow.getFocusedWindow()\nconst viewItems = process.env.NODE_ENV === 'developemnt'\n  ? [item('Reload Window', 'Alt+CTRL+R', () => reload(getWin()))]\n  : []\n\nexport default ({ iconPath }) => [\n  menu('RND', [\n    item('About', n, () => showAboutDialog(iconPath)),\n    item('Check for Updates...', n, () => checkUpdate(iconPath, true)),\n    separator,\n    item('Stay in Front', n, ({ checked }) => setAlwaysOnTop(getWin(), checked), {\n      type: 'checkbox',\n      checked: false,\n    }),\n  ]),\n  menu(\n    'Debugger',\n    [\n      item('New Window', 'Ctrl+T', () => createWindow({ iconPath, isPortSettingRequired: haveOpenedWindow() })),\n      item('Enable Open in Editor for Console Log', n, () => toggleOpenInEditor(getWin()), {\n        type: 'checkbox',\n        checked: false,\n      }),\n      item('Toggle Device Sync', n, toggleSyncState, {\n        type: 'checkbox',\n        checked: isSyncState(),\n      }),\n      item('Open Config File', n, () => openConfigFile()),\n      separator,\n      item('Close', 'Ctrl+W', () => close(getWin())),\n    ],\n    'window',\n  ),\n  menu('Edit', [\n    item('Undo', 'Ctrl+Z', n, { selector: 'undo:' }),\n    item('Redo', 'Shift+Ctrl+Z', n, { selector: 'redo:' }),\n    separator,\n    item('Cut', 'Ctrl+X', n, { selector: 'cut:' }),\n    item('Copy', 'Ctrl+C', n, { selector: 'copy:' }),\n    item('Paste', 'Ctrl+V', n, { selector: 'paste:' }),\n    item('Select All', 'Ctrl+A', n, { selector: 'selectAll:' }),\n  ]),\n  menu(\n    'View',\n    viewItems.concat([\n      item('Toggle Full Screen', 'F11', () => toggleFullscreen(getWin())),\n      item('Toggle Developer Tools', 'Alt+Ctrl+I', () => toggleDevTools(getWin(), 'chrome')),\n      item('Toggle React DevTools', 'Alt+Ctrl+J', () => toggleDevTools(getWin(), 'react')),\n      item('Toggle Redux DevTools', 'Alt+Ctrl+K', () => toggleDevTools(getWin(), 'redux')),\n      separator,\n      item('Zoom In', 'Ctrl+=', () => zoom(getWin(), 1)),\n      item('Zoom Out', 'Ctrl+-', () => zoom(getWin(), -1)),\n      item('Reset Zoom', 'Ctrl+0', () => resetZoom(getWin())),\n    ]),\n  ),\n  menu('Help', [\n    item('Documentation', n, () => shell.openExternal('https://github.com/jhen0409/react-native-debugger/tree/master/docs')),\n    item('Issues', n, () => shell.openExternal('https://github.com/jhen0409/react-native-debugger/issues')),\n    item('Open Collective', n, () => shell.openExternal('https://opencollective.com/react-native-debugger')),\n  ]),\n]\n"
  },
  {
    "path": "electron/sync-state.js",
    "content": "import { BrowserWindow } from 'electron'\n\nlet syncState = false\n\nexport const isSyncState = () => syncState\n\n// Take by renderer\nglobal.isSyncState = isSyncState\n\nexport const toggleSyncState = () => {\n  syncState = !syncState\n}\n\nexport const sendSyncState = (event, payload) => {\n  if (!isSyncState) return\n\n  BrowserWindow.getAllWindows()\n    .filter((win) => Number(win.webContents.id) !== event.sender.id)\n    .forEach((win) => {\n      win.webContents.send('sync-state', payload)\n    })\n}\n"
  },
  {
    "path": "electron/update.js",
    "content": "import { app, dialog, shell } from 'electron'\nimport GhReleases from 'electron-gh-releases'\nimport fetch from 'electron-fetch'\n\nconst repo = 'jhen0409/react-native-debugger'\n\nconst getFeed = () => fetch(`https://raw.githubusercontent.com/${repo}/master/auto_update.json`).then((res) => res.json())\n\nconst showDialog = ({\n  icon, buttons, message, detail,\n}) => dialog.showMessageBoxSync({\n  type: 'info',\n  buttons,\n  title: 'React Native Debugger',\n  icon,\n  message,\n  detail,\n})\n\nconst notifyUpdateAvailable = ({ icon, detail }) => {\n  const index = showDialog({\n    message: 'A newer version is available.',\n    buttons: ['Download', 'Later'],\n    icon,\n    detail,\n  })\n  return index === 0\n}\n\nconst notifyUpdateDownloaded = ({ icon }) => {\n  const index = showDialog({\n    message:\n      'The newer version has been downloaded. '\n      + 'Please restart the application to apply the update.',\n    buttons: ['Restart', 'Later'],\n    icon,\n  })\n  return index === 0\n}\n\nlet checking = false\n\nexport default (icon, notify) => {\n  if (checking) return\n\n  checking = true\n  const updater = new GhReleases({\n    repo,\n    currentVersion: app.getVersion(),\n  })\n\n  updater.check(async (err, status) => {\n    if (process.platform === 'linux' && err.message === 'This platform is not supported.') {\n      err = null; // eslint-disable-line\n      status = true; // eslint-disable-line\n    }\n    if (notify && err) {\n      showDialog({ message: err.message, buttons: ['OK'] })\n      checking = false\n      return\n    }\n    if (err || !status) {\n      checking = false\n      return\n    }\n    const feed = await getFeed()\n    const detail = `${feed.name}\\n\\n${feed.notes}`\n    if (notify) {\n      const open = notifyUpdateAvailable({ icon, detail })\n      if (open) shell.openExternal('https://github.com/jhen0409/react-native-debugger/releases')\n    } else if (\n      process.env.NODE_ENV === 'production'\n      && process.platform === 'darwin'\n      && notifyUpdateAvailable({ icon, detail })\n    ) {\n      updater.download()\n      console.log('[RNDebugger] Update downloading...')\n    }\n    checking = false\n  })\n\n  updater.on('update-downloaded', () => {\n    console.log('[RNDebugger] Update downloaded')\n    if (notifyUpdateDownloaded({ icon })) {\n      updater.install()\n    }\n  })\n}\n"
  },
  {
    "path": "electron/url-handle/handleURL.js",
    "content": "import { app } from 'electron'\nimport net from 'net'\nimport url from 'url'\nimport qs from 'querystring'\nimport fs from 'fs'\nimport * as portfile from './port'\n\nconst filterPaths = (list) => {\n  const filteredList = list.filter((dir) => {\n    try {\n      return fs.lstatSync(dir).isDirectory()\n    } catch (e) {\n      return false\n    }\n  })\n  if (!filteredList.length) {\n    return\n  }\n  return filteredList\n}\n\nconst resolveHost = (host) => (\n  !host || host === 'undefined' || host === 'null' ? 'localhost' : host\n)\n\nexport const parseUrl = (_url) => {\n  const route = url.parse(_url)\n  if (route.host !== 'set-debugger-loc') return\n  const { host, port, projectRoots } = qs.parse(route.query)\n  const query = {\n    host: resolveHost(host),\n    port: Number(port) || 8081,\n    projectRoots: filterPaths(Array.isArray(projectRoots) ? projectRoots : [projectRoots]),\n  }\n  return query\n}\n\nexport const handleURL = async (getWindow, path) => {\n  const query = parseUrl(path)\n  if (!query) {\n    return\n  }\n  const payload = JSON.stringify(query)\n\n  // This env will be get by new debugger window\n  process.env.DEBUGGER_SETTING = payload\n  const win = await getWindow(query.host, query.port)\n  // if we can get the exists window, it will send the IPC event\n  if (win) {\n    win.webContents.send('set-debugger-loc', payload)\n  }\n}\n\nconst listenOpenURL = (getWindow) => app.on('open-url', (e, path) => {\n  handleURL(getWindow, path)\n})\n\nconst createHandleURLServer = (getWindow) => net\n  .createServer((socket) => {\n    socket.setEncoding('utf-8')\n    socket.on('data', async (data) => {\n      try {\n        const obj = JSON.parse(data)\n        if (typeof obj.path === 'string') {\n          await handleURL(getWindow, obj.path)\n        }\n        socket.write('success')\n      } catch (e) {\n        socket.write('fail')\n      } finally {\n        socket.end()\n      }\n    })\n  })\n  .listen(0, '127.0.0.1')\n  .on('listening', function server() {\n    const { port } = this.address()\n    portfile.write(port)\n    portfile.watchExists(port)\n    process.on('exit', () => portfile.unlink())\n\n    console.log(`Starting listen set-debugger-loc request on port ${port}`)\n    console.log('Will save port to `$HOME/.rndebugger_port` file')\n  })\n\nexport default (getWindow) => {\n  // Handle set-debugger-loc for macOS\n  // It's can be automatically open the app\n  listenOpenURL(getWindow)\n  // Handle set-debugger-loc for macOS/Linux/Windows\n  createHandleURLServer(getWindow)\n}\n"
  },
  {
    "path": "electron/url-handle/index.js",
    "content": "import startListeningHandleURL, { handleURL, parseUrl } from './handleURL'\nimport * as port from './port'\n\nexport {\n  startListeningHandleURL, handleURL, parseUrl, port,\n}\n"
  },
  {
    "path": "electron/url-handle/port.js",
    "content": "import fs from 'fs'\nimport path from 'path'\n\nconst homeEnv = process.platform === 'win32' ? 'USERPROFILE' : 'HOME'\nconst portFile = path.join(process.env[homeEnv], '.rndebugger_port')\nlet isWatching = false\n\nexport const write = (port) => {\n  fs.writeFileSync(portFile, String(port))\n}\n\nexport function read() {\n  if (!fs.existsSync(portFile)) return null\n  return Number(fs.readFileSync(portFile, 'utf8'))\n}\n\nexport const unlink = () => {\n  if (fs.existsSync(portFile)) {\n    fs.unlinkSync(portFile)\n  }\n}\n\nexport const watchExists = (port) => {\n  if (isWatching) return\n  isWatching = true\n  fs.watchFile(portFile, (curr, prev) => {\n    if (curr.mtime !== prev.mtime) write(port)\n  })\n}\n"
  },
  {
    "path": "electron/window.js",
    "content": "import path from 'path'\nimport {\n  BrowserWindow, Menu, globalShortcut, dialog,\n} from 'electron'\nimport Store from 'electron-store'\nimport { enable } from '@electron/remote/main'\nimport autoUpdate from './update'\nimport { catchConsoleLogLink, removeUnecessaryTabs, activeTabs } from './devtools'\nimport { selectRNDebuggerWorkerContext } from '../app/utils/devtools'\nimport { readConfig, filePath as configFile } from './config'\nimport { registerContextMenu } from './context-menu'\n\nconst store = new Store()\n\nconst executeJavaScript = (win, script) => win.webContents.executeJavaScript(script)\n\nexport const checkWindowInfo = (win) => executeJavaScript(win, 'window.checkWindowInfo()')\n\nconst checkIsOpenInEditorEnabled = (win) => executeJavaScript(win, 'window.isOpenInEditorEnabled()')\n\nconst changeMenuItems = (menus) => {\n  const rootMenuItems = Menu.getApplicationMenu().items\n  Object.entries(menus).forEach(([key, subMenu]) => {\n    const rootMenuItem = rootMenuItems.find(({ label }) => label === key)\n    if (!rootMenuItem || !rootMenuItem.submenu) return\n\n    Object.entries(subMenu).forEach(([subKey, menuSet]) => {\n      const menuItem = rootMenuItem.submenu.items.find(\n        ({ label }) => label === subKey,\n      )\n      if (!menuItem) return\n\n      Object.assign(menuItem, menuSet)\n    })\n  })\n}\n\nconst invokeDevMethod = (win, name) => executeJavaScript(\n  win,\n  `window.invokeDevMethod && window.invokeDevMethod('${name}')`,\n)\n\nconst registerKeyboradShortcut = (win) => {\n  const prefix = process.platform === 'darwin' ? 'Command' : 'Ctrl'\n  // If another window focused, register a new shortcut\n  if (\n    globalShortcut.isRegistered(`${prefix}+R`)\n    || globalShortcut.isRegistered(`${prefix}+I`)\n  ) {\n    globalShortcut.unregisterAll()\n  }\n  globalShortcut.register(`${prefix}+R`, () => invokeDevMethod(win, 'reload'))\n  globalShortcut.register(`${prefix}+I`, () => invokeDevMethod(win, 'toggleElementInspector'))\n}\n\nconst unregisterKeyboradShortcut = () => globalShortcut.unregisterAll()\n\nconst registerShortcuts = async (win) => {\n  registerKeyboradShortcut(win)\n  changeMenuItems({\n    Debugger: {\n      'Stay in Front': {\n        checked: win.isAlwaysOnTop(),\n      },\n      'Enable Open in Editor for Console Log': {\n        checked: await checkIsOpenInEditorEnabled(win),\n      },\n    },\n  })\n}\n\nconst minSize = 100\nexport const createWindow = ({ iconPath, isPortSettingRequired, port }) => {\n  const { config, isConfigBroken, error } = readConfig()\n\n  if (isConfigBroken) {\n    dialog.showErrorBox(\n      'Root config error',\n      `Parse root config failed, please checkout \\`${configFile}\\`, the error trace:\\n\\n`\n        + `${error}\\n\\n`\n        + 'RNDebugger will load default config instead. '\n        + 'You can click `Debugger` -> `Open Config File` in application menu.',\n    )\n  }\n\n  const winBounds = store.get('winBounds') || {}\n  const increasePosition = BrowserWindow.getAllWindows().length * 10 || 0\n  const {\n    width, height, x = 0, y = 0,\n  } = winBounds\n  const win = new BrowserWindow({\n    ...winBounds,\n    width: width && width >= minSize ? width : 1024,\n    height: height && height >= minSize ? height : 750,\n    minWidth: minSize,\n    minHeight: minSize,\n    x: x + increasePosition,\n    y: y + increasePosition,\n    backgroundColor: '#272c37',\n    tabbingIdentifier: 'rndebugger',\n    webPreferences: {\n      contextIsolation: false,\n      nodeIntegration: true,\n      // experimentalFeatures: true,\n      // webSecurity: false,\n      // webviewTag: true, // Use this for new inspector in the future\n    },\n    ...config.windowBounds,\n  })\n  enable(win.webContents)\n\n  const isFirstWindow = BrowserWindow.getAllWindows().length === 1\n\n  const { timesJSLoadToRefreshDevTools = -1 } = config\n  win.debuggerConfig = {\n    port,\n    editor: config.editor,\n    fontFamily: config.fontFamily,\n    defaultReactDevToolsTheme: config.defaultReactDevToolsTheme,\n    defaultReactDevToolsPort: config.defaultReactDevToolsPort,\n    networkInspect: config.defaultNetworkInspect && 1,\n    isPortSettingRequired: isPortSettingRequired && 1,\n    timesJSLoadToRefreshDevTools,\n  }\n  win.loadURL(`file://${path.resolve(__dirname)}/app.html`)\n  let unregisterContextMenu\n  win.webContents.on('did-finish-load', () => {\n    win.webContents.zoomLevel = config.zoomLevel || store.get('zoomLevel', 0)\n    win.focus()\n    unregisterContextMenu = registerContextMenu(win)\n    registerShortcuts(win)\n    if (!isPortSettingRequired) win.openDevTools()\n    const checkUpdate = config.autoUpdate !== false\n    if (checkUpdate && isFirstWindow) {\n      autoUpdate(iconPath)\n    }\n  })\n  win.webContents.on('devtools-opened', async () => {\n    const { location } = await checkWindowInfo(win)\n    activeTabs(win)\n    catchConsoleLogLink(win, location.host, location.port)\n    if (config.showAllDevToolsTab !== true) {\n      removeUnecessaryTabs(win)\n    }\n    selectRNDebuggerWorkerContext(win)\n  })\n  win.on('show', () => {\n    if (!win.isFocused()) return\n    registerShortcuts(win)\n  })\n  win.on('focus', () => registerShortcuts(win))\n  win.on('restore', () => registerShortcuts(win))\n  win.on('hide', () => unregisterKeyboradShortcut())\n  win.on('blur', () => unregisterKeyboradShortcut())\n  win.on('minimize', () => unregisterKeyboradShortcut())\n  win.close = async () => {\n    unregisterKeyboradShortcut()\n    store.set('winBounds', win.getBounds())\n    store.set('zoomLevel', win.webContents.zoomLevel)\n    await executeJavaScript(\n      win,\n      'window.beforeWindowClose && window.beforeWindowClose()',\n    )\n    win.destroy()\n  }\n  win.on('close', (event) => {\n    event.preventDefault()\n    win.close()\n    if (unregisterContextMenu) unregisterContextMenu()\n  })\n  return win\n}\n"
  },
  {
    "path": "examples/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"import/no-extraneous-dependencies\": 0,\n    \"import/no-unresolved\": 0\n  }\n}\n"
  },
  {
    "path": "examples/test-old-bridge/.gitignore",
    "content": "node_modules/\n.expo/\ndist/\nnpm-debug.*\n*.jks\n*.p8\n*.p12\n*.key\n*.mobileprovision\n*.orig.*\nweb-build/\n\n# macOS\n.DS_Store\n\n# Temporary files created by Metro to check the health of the file watcher\n.metro-health-check*\n"
  },
  {
    "path": "examples/test-old-bridge/App.js",
    "content": "/* eslint-disable react/style-prop-object */\nimport { StatusBar } from 'expo-status-bar'\nimport React from 'react'\nimport { StyleSheet, View } from 'react-native'\nimport ReduxApp from './examples/redux/App'\nimport ApolloApp from './examples/apollo/App'\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    backgroundColor: '#fff',\n  },\n})\n\nexport default function App() {\n  return (\n    <View style={styles.container}>\n      <ReduxApp />\n      <ApolloApp />\n      <StatusBar style=\"auto\" />\n    </View>\n  )\n}\n"
  },
  {
    "path": "examples/test-old-bridge/README.md",
    "content": "# test-old-bridge\n\nThis is example created by `npx create-expo-app -t blank@48`,  `\"jsEngine\": \"jsc\"` to `app.json`.\n\nThe main purpose is for test functionality of React Native Debugger in old bridge.\n\nCurrently the examples included \n- simple counter example for Redux\n- simple query example for Apollo Client\n"
  },
  {
    "path": "examples/test-old-bridge/app.json",
    "content": "{\n  \"expo\": {\n    \"jsEngine\": \"jsc\",\n    \"name\": \"test-old-bridge\",\n    \"slug\": \"test-old-bridge\",\n    \"version\": \"1.0.0\",\n    \"orientation\": \"portrait\",\n    \"icon\": \"./assets/icon.png\",\n    \"userInterfaceStyle\": \"light\",\n    \"splash\": {\n      \"image\": \"./assets/splash.png\",\n      \"resizeMode\": \"contain\",\n      \"backgroundColor\": \"#ffffff\"\n    },\n    \"assetBundlePatterns\": [\n      \"**/*\"\n    ],\n    \"ios\": {\n      \"supportsTablet\": true\n    },\n    \"android\": {\n      \"adaptiveIcon\": {\n        \"foregroundImage\": \"./assets/adaptive-icon.png\",\n        \"backgroundColor\": \"#ffffff\"\n      }\n    },\n    \"web\": {\n      \"favicon\": \"./assets/favicon.png\"\n    }\n  }\n}\n"
  },
  {
    "path": "examples/test-old-bridge/babel.config.js",
    "content": "module.exports = (api) => {\n  api.cache(true)\n  return {\n    presets: ['babel-preset-expo'],\n  }\n}\n"
  },
  {
    "path": "examples/test-old-bridge/examples/apollo/App.js",
    "content": "import React from 'react'\nimport { StyleSheet, Text, View } from 'react-native'\nimport { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'\nimport SimpleQuery from './SimpleQuery'\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    justifyContent: 'center',\n    alignItems: 'center',\n    backgroundColor: '#F5FCFF',\n  },\n  title: {\n    marginBottom: 20,\n    fontSize: 25,\n    textAlign: 'center',\n    fontWeight: 'bold',\n  },\n})\n\nconst client = new ApolloClient({\n  uri: 'https://spacex-production.up.railway.app/',\n  cache: new InMemoryCache(),\n})\n\nexport default function App() {\n  return (\n    <ApolloProvider client={client}>\n      <View style={styles.container}>\n        <Text style={styles.title}>Apollo Client example</Text>\n        <SimpleQuery />\n      </View>\n    </ApolloProvider>\n  )\n}\n"
  },
  {
    "path": "examples/test-old-bridge/examples/apollo/SimpleQuery.js",
    "content": "import React from 'react'\nimport { StyleSheet, Text, Button } from 'react-native'\nimport { useQuery } from '@apollo/client'\nimport gql from 'graphql-tag'\n\nconst styles = StyleSheet.create({\n  text: {\n    fontSize: 20,\n    textAlign: 'center',\n    margin: 10,\n  },\n})\n\nconst GET_DATA = gql`\n  query ExampleQuery {\n    company {\n      name\n      ceo\n      employees\n    }\n  }\n`\n\nexport default function SimpleQuery() {\n  const { loading, error, data, refetch } = useQuery(GET_DATA)\n\n  if (loading) return <Text style={styles.text}>Loading...</Text>\n  if (error) return <Text style={styles.text}>Error :({error.message})</Text>\n\n  return (\n    <>\n      <Text style={styles.text}>Company: {data.company.name}</Text>\n      <Text style={styles.text}>CEO: {data.company.ceo}</Text>\n      <Text style={styles.text}>Employees: {data.company.employees}</Text>\n      <Button onPress={() => refetch()} title=\"Refetch\" />\n    </>\n  )\n}\n"
  },
  {
    "path": "examples/test-old-bridge/examples/redux/App.js",
    "content": "import React from 'react'\nimport { Provider } from 'react-redux'\nimport { Counter } from './features/counter/Counter'\nimport { store } from './app/store'\n\nexport default function () {\n  return (\n    <Provider store={store}>\n      <Counter />\n    </Provider>\n  )\n}\n"
  },
  {
    "path": "examples/test-old-bridge/examples/redux/app/store.js",
    "content": "import { configureStore } from '@reduxjs/toolkit'\nimport counterReducer from '../features/counter/counterSlice'\n\nexport const store = configureStore({\n  reducer: {\n    counter: counterReducer,\n  },\n})\n"
  },
  {
    "path": "examples/test-old-bridge/examples/redux/features/counter/Counter.js",
    "content": "import React from 'react'\nimport {\n  StyleSheet, View, Text, TouchableHighlight,\n} from 'react-native'\nimport { useSelector, useDispatch } from 'react-redux'\nimport {\n  decrement,\n  increment,\n  incrementAsync,\n  incrementIfOdd,\n  selectCount,\n} from './counterSlice'\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    justifyContent: 'center',\n    alignItems: 'center',\n    backgroundColor: '#F5FCFF',\n  },\n  title: {\n    marginBottom: 20,\n    fontSize: 25,\n    textAlign: 'center',\n    fontWeight: 'bold',\n  },\n  text: {\n    fontSize: 20,\n    textAlign: 'center',\n    margin: 10,\n  },\n})\n\nexport function Counter() {\n  const count = useSelector(selectCount)\n  const dispatch = useDispatch()\n  return (\n    <View style={styles.container}>\n      <Text style={styles.title}>Redux example</Text>\n      <Text style={styles.text}>\n        Clicked:\n        {count}\n        {' '}\n        times\n      </Text>\n      <TouchableHighlight onPress={() => dispatch(increment())}>\n        <Text style={styles.text}>+</Text>\n      </TouchableHighlight>\n      <TouchableHighlight onPress={() => dispatch(decrement())}>\n        <Text style={styles.text}>-</Text>\n      </TouchableHighlight>\n      <TouchableHighlight onPress={() => dispatch(incrementIfOdd(count))}>\n        <Text style={styles.text}>Increment if odd</Text>\n      </TouchableHighlight>\n      <TouchableHighlight onPress={() => dispatch(incrementAsync())}>\n        <Text style={styles.text}>Increment async</Text>\n      </TouchableHighlight>\n    </View>\n  )\n}\n\nexport default Counter\n"
  },
  {
    "path": "examples/test-old-bridge/examples/redux/features/counter/counterAPI.js",
    "content": "// A mock function to mimic making an async request for data\nexport function fetchCount(amount = 1) {\n  return new Promise((resolve) => {\n    setTimeout(() => resolve({ data: amount }), 500)\n  })\n}\n"
  },
  {
    "path": "examples/test-old-bridge/examples/redux/features/counter/counterSlice.js",
    "content": "import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'\nimport { fetchCount } from './counterAPI'\n\nconst initialState = {\n  value: 0,\n  status: 'idle',\n}\n\n// The function below is called a thunk and allows us to perform async logic. It\n// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This\n// will call the thunk with the `dispatch` function as the first argument. Async\n// code can then be executed and other actions can be dispatched. Thunks are\n// typically used to make async requests.\nexport const incrementAsync = createAsyncThunk(\n  'counter/fetchCount',\n  async (amount) => {\n    const response = await fetchCount(amount)\n    // The value we return becomes the `fulfilled` action payload\n    return response.data\n  },\n)\n\nexport const counterSlice = createSlice({\n  name: 'counter',\n  initialState,\n  // The `reducers` field lets us define reducers and generate associated actions\n  reducers: {\n    increment: (state) => {\n      // Redux Toolkit allows us to write \"mutating\" logic in reducers. It\n      // doesn't actually mutate the state because it uses the Immer library,\n      // which detects changes to a \"draft state\" and produces a brand new\n      // immutable state based off those changes\n      state.value += 1\n    },\n    decrement: (state) => {\n      state.value -= 1\n    },\n    // Use the PayloadAction type to declare the contents of `action.payload`\n    incrementByAmount: (state, action) => {\n      state.value += action.payload\n    },\n  },\n  // The `extraReducers` field lets the slice handle actions defined elsewhere,\n  // including actions generated by createAsyncThunk or in other slices.\n  extraReducers: (builder) => {\n    builder\n      .addCase(incrementAsync.pending, (state) => {\n        state.status = 'loading'\n      })\n      .addCase(incrementAsync.fulfilled, (state, action) => {\n        state.status = 'idle'\n        state.value += action.payload\n      })\n  },\n})\n\nexport const { increment, decrement, incrementByAmount } = counterSlice.actions\n\n// The function below is called a selector and allows us to select a value from\n// the state. Selectors can also be defined inline where they're used instead of\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\nexport const selectCount = (state) => state.counter.value\n\n// We can also write thunks by hand, which may contain both sync and async logic.\n// Here's an example of conditionally dispatching actions based on current state.\nexport const incrementIfOdd = (amount) => (dispatch, getState) => {\n  const currentValue = selectCount(getState())\n  if (currentValue % 2 === 1) {\n    dispatch(incrementByAmount(amount))\n  }\n}\n\nexport default counterSlice.reducer\n"
  },
  {
    "path": "examples/test-old-bridge/package.json",
    "content": "{\n  \"name\": \"test-old-bridge\",\n  \"version\": \"1.0.0\",\n  \"main\": \"node_modules/expo/AppEntry.js\",\n  \"scripts\": {\n    \"start\": \"expo start\",\n    \"android\": \"expo start --android\",\n    \"ios\": \"expo start --ios\",\n    \"web\": \"expo start --web\",\n    \"postinstall\": \"rndebugger-open\"\n  },\n  \"dependencies\": {\n    \"@apollo/client\": \"^3.7.17\",\n    \"@reduxjs/toolkit\": \"^1.9.5\",\n    \"expo\": \"~48.0.18\",\n    \"expo-status-bar\": \"~1.4.4\",\n    \"react\": \"18.2.0\",\n    \"react-native\": \"0.71.8\",\n    \"react-native-debugger-open\": \"^0.4.3\",\n    \"react-redux\": \"^8.1.1\",\n    \"redux\": \"^4.2.1\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.20.0\"\n  },\n  \"private\": true\n}\n"
  },
  {
    "path": "npm-package/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"global-require\": \"off\"\n  }\n}"
  },
  {
    "path": "npm-package/.gitignore",
    "content": "lib/\n"
  },
  {
    "path": "npm-package/README.md",
    "content": "# react-native-debugger-open [![NPM version](http://img.shields.io/npm/v/react-native-debugger-open.svg?style=flat)](https://www.npmjs.com/package/react-native-debugger-open)\n\n> Replace `open debugger-ui with Chrome` to `open React Native Debugger` from react-native packager\n\n__[macOS]__ If you opened the app before (registered URI scheme), you can use this patch open the app automatically.\n__[Linux / Windows]__ Currently it cannot open the app automatically, it just send `set-debugger-loc` request, so you need open the app yourself.\n\n## Screenshot\n\n![demo](https://user-images.githubusercontent.com/3001525/31390358-490eb22a-ad99-11e7-9d1a-65b4d185e261.gif)\n\n> Demo with initial project of Create React Native App (Expo)\n\n## Installation\n\nFirst, install [React Native Debugger](https://github.com/jhen0409/react-native-debugger#installation).\n\nIn your React Native project:\n\n```bash\n$ npm i --save-dev react-native-debugger-open # or -g\n```\n\n## Usage\n\n#### Inject to react-native packager\n\nAdd command to your project's package.json:\n\n```\n\"scripts\": {\n  \"postinstall\": \"rndebugger-open\"\n}\n```\n\nIt will be run after `npm install`. (You can run `npm run postinstall` first)\nThe `./node_modules/react-native/local-cli/server/middleware/getDevToolsMiddleware.js` code will be replaced.\n\n#### Use `REACT_DEBUGGER` env of react-native packager\n\nInstead of `Inject to react-native packager`, you can just do:\n\n```bash\n$ REACT_DEBUGGER=\"rndebugger-open --open --port 8081\" npm start\n\n# Windows\n$ set REACT_DEBUGGER=\"rndebugger-open --open --port 8081\" && npm start\n```\n\nIf you're using Expo <= 48, use port 19000 instead of 8081.\n\n#### Options (--option)\n\nName                  | Description\n-------------         | -------------\n`macos`               | Use [react-native-macos](https://github.com/ptmt/react-native-macos) module name instead of react-native. Default is `false`\n`revert`              | Revert rndebugger-open injection. Default is `false`\n`open`                | Run open directly instead of inject patch\n`port`                | Specified react-native packager port with `--open` option. Default is `8081`\n\nYou can also [`Launch by CLI or React Native packager`](https://github.com/jhen0409/react-native-debugger/blob/master/docs/getting-started.md#launch-by-cli-or-react-native-packager-macos-only) instead of this package.\n\n## LICENSE\n\n[MIT](https://github.com/jhen0409/react-native-debugger/blob/master/LICENSE.md)\n"
  },
  {
    "path": "npm-package/babel.config.js",
    "content": "module.exports = (api) => {\n  api.cache(true)\n  return {\n    presets: [['@babel/preset-env', { targets: { node: '12' } }]],\n  }\n}\n"
  },
  {
    "path": "npm-package/bin/rndebugger-open.js",
    "content": "#! /usr/bin/env node\n\n'use strict'\n\nconst defaultPort = 8081\n\nconst argv = require('minimist')(process.argv.slice(2), {\n  boolean: [\n    // Inject / Revert code from react-native packager\n    'inject',\n    'revert',\n    // Inject to react-native-desktop / react-native-macos package\n    'desktop',\n    'macos',\n    // Open directly instead of Inject code\n    'open',\n  ],\n  string: ['port', 'host'],\n  default: {\n    inject: true,\n  },\n})\n\nargv.port = Number(argv.port) || defaultPort\n\nlet mod\nif (argv.open && (argv.port || argv.host)) {\n  mod = require('../lib/open')\n} else {\n  mod = require('../lib/main')\n}\n\nmod.default(argv, (pass, dontError) => {\n  if (!pass && !dontError) process.exit(1)\n})\n"
  },
  {
    "path": "npm-package/package.json",
    "content": "{\n  \"name\": \"react-native-debugger-open\",\n  \"version\": \"0.4.3\",\n  \"description\": \"Replace `open debugger-ui with Chrome` to `open React Native Debugger` from react-native packager\",\n  \"bin\": {\n    \"rndebugger-open\": \"bin/rndebugger-open.js\"\n  },\n  \"main\": \"lib/open.js\",\n  \"scripts\": {\n    \"build\": \"babel src --out-dir lib --ignore **/__tests__\",\n    \"prepublish\": \"npm run build\"\n  },\n  \"files\": [\n    \"bin\",\n    \"lib\"\n  ],\n  \"homepage\": \"https://github.com/jhen0409/react-native-debugger\",\n  \"repository\": \"https://github.com/jhen0409/react-native-debugger/tree/master/npm-package\",\n  \"keywords\": [\n    \"react\",\n    \"react-native\",\n    \"debugger\",\n    \"react-devtools\",\n    \"redux-devtools\",\n    \"electron\"\n  ],\n  \"author\": \"Jhen <developer@jhen.me>\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"chalk\": \"^1.1.3\",\n    \"es6-template\": \"^1.0.4\",\n    \"minimist\": \"^1.2.0\",\n    \"semver\": \"^5.4.1\"\n  },\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.22.9\",\n    \"fs-extra\": \"^4.0.2\",\n    \"node-fetch\": \"^2.6.1\"\n  }\n}\n"
  },
  {
    "path": "npm-package/src/__tests__/__snapshots__/injectDevToolsMiddleware.test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.59.0-rc.0 - v1.5.0) 1`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nvar _launchChrome = _interopRequireDefault(require(\"../launchChrome\"));\n\nvar _logger = _interopRequireDefault(require(\"../../../tools/logger\"));\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchChromeDevTools(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _logger.default.info('Launching Dev Tools...');\n\n  (0, _launchChrome.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isChromeConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n  console.log('Starting custom debugger by executing:', command);\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      console.log('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isChromeConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`logger.info\\` and dev tools binary\n      _logger.default.info('We removed support for Safari dev-tools. ' + 'If you still need this, please let us know.');\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      _logger.default.info('The method /launch-chrome-devtools is deprecated. You are ' + ' probably using an application created with an older CLI with the ' + ' packager of a newer CLI. Please upgrade your application: ' + 'https://facebook.github.io/react-native/docs/upgrading.html');\n\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.59.0-rc.0 - v1.5.0) 2`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nvar _launchChrome = _interopRequireDefault(require(\"../launchChrome\"));\n\nvar _logger = _interopRequireDefault(require(\"../../../tools/logger\"));\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchChromeDevTools(port, args = '', skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port + '&args=' + args;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchChromeDevTools(port, args, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchChromeDevTools(port, args, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _logger.default.info('Launching Dev Tools...');\n\n  (0, _launchChrome.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isChromeConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n  console.log('Starting custom debugger by executing:', command);\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      console.log('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isChromeConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`logger.info\\` and dev tools binary\n      _logger.default.info('We removed support for Safari dev-tools. ' + 'If you still need this, please let us know.');\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      _logger.default.info('The method /launch-chrome-devtools is deprecated. You are ' + ' probably using an application created with an older CLI with the ' + ' packager of a newer CLI. Please upgrade your application: ' + 'https://facebook.github.io/react-native/docs/upgrading.html');\n\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.59.0-rc.0 - v1.5.0) 3`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nvar _launchChrome = _interopRequireDefault(require(\"../launchChrome\"));\n\nvar _logger = _interopRequireDefault(require(\"../../../tools/logger\"));\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchChromeDevTools(port, args = '') {\n\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _logger.default.info('Launching Dev Tools...');\n\n  (0, _launchChrome.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isChromeConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n  console.log('Starting custom debugger by executing:', command);\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      console.log('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isChromeConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`logger.info\\` and dev tools binary\n      _logger.default.info('We removed support for Safari dev-tools. ' + 'If you still need this, please let us know.');\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      _logger.default.info('The method /launch-chrome-devtools is deprecated. You are ' + ' probably using an application created with an older CLI with the ' + ' packager of a newer CLI. Please upgrade your application: ' + 'https://facebook.github.io/react-native/docs/upgrading.html');\n\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.60.0 - v2.8.3) 1`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nvar _launchChrome = _interopRequireDefault(require(\"../launchChrome\"));\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchChromeDevTools(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchChrome.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isChromeConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isChromeConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.60.0 - v2.8.3) 2`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nvar _launchChrome = _interopRequireDefault(require(\"../launchChrome\"));\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchChromeDevTools(port, args = '', skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port + '&args=' + args;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchChromeDevTools(port, args, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchChromeDevTools(port, args, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchChrome.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isChromeConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isChromeConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.60.0 - v2.8.3) 3`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nvar _launchChrome = _interopRequireDefault(require(\"../launchChrome\"));\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchChromeDevTools(port, args = '') {\n\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchChrome.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isChromeConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isChromeConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.60.0 - v2.9.0) 1`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchDefaultDebugger(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.60.0 - v2.9.0) 2`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchDefaultDebugger(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchDevTools({port, watchFolders}, isDebuggerConnected, skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port + '&watchFolders=' + watchFolders.map(f => \\`\"\\${f}\"\\`).join(',');\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchDevTools({port, watchFolders}, isDebuggerConnected, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchDevTools({port, watchFolders}, isDebuggerConnected, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.60.0 - v2.9.0) 3`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\nfunction launchDefaultDebugger(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error, stdout, stderr) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error);\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.61.0 - v3.0.0-alpha.7) 1`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction launchDefaultDebugger(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.61.0 - v3.0.0-alpha.7) 2`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction launchDefaultDebugger(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchDevTools({port, watchFolders}, isDebuggerConnected, skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port + '&watchFolders=' + watchFolders.map(f => \\`\"\\${f}\"\\`).join(',');\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchDevTools({port, watchFolders}, isDebuggerConnected, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchDevTools({port, watchFolders}, isDebuggerConnected, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.61.0 - v3.0.0-alpha.7) 3`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction launchDefaultDebugger(port, args = '') {\n  const debuggerURL = \\`http://localhost:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.61.0 - v3.0.1) 1`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction launchDefaultDebugger(host, port, args = '') {\n  const hostname = host || 'localhost';\n  const debuggerURL = \\`http://\\${hostname}:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  host,\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(host, port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.61.0 - v3.0.1) 2`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchDefaultDebugger(host, port, args = '', skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + host + '&port=' + port + '&args=' + args;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchDefaultDebugger(host, port, args, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchDefaultDebugger(host, port, args, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  const hostname = host || 'localhost';\n  const debuggerURL = \\`http://\\${hostname}:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  host,\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(host, port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli (0.61.0 - v3.0.1) 3`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\n\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n\n  _cliTools = function () {\n    return data;\n  };\n\n  return data;\n}\n\nfunction _child_process() {\n  const data = require(\"child_process\");\n\n  _child_process = function () {\n    return data;\n  };\n\n  return data;\n}\n\nvar _launchDebugger = _interopRequireDefault(require(\"../launchDebugger\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction launchDefaultDebugger(host, port, args = '') {\n\n  const hostname = host || 'localhost';\n  const debuggerURL = \\`http://\\${hostname}:\\${port}/debugger-ui\\${args}\\`;\n\n  _cliTools().logger.info('Launching Dev Tools...');\n\n  (0, _launchDebugger.default)(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\n\nfunction launchDevTools({\n  host,\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(host, port);\n  }\n}\n\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\n\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(req, res, next) {\n    if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isDebuggerConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n}\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli-server-api (0.71.8 - v10.1.1) 1`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n  _cliTools = function () {\n    return data;\n  };\n  return data;\n}\nfunction _child_process() {\n  const data = require(\"child_process\");\n  _child_process = function () {\n    return data;\n  };\n  return data;\n}\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nfunction launchDefaultDebugger(host, port, args = '') {\n  const hostname = host || 'localhost';\n  const debuggerURL = \\`http://\\${hostname}:\\${port}/debugger-ui\\${args}\\`;\n  _cliTools().logger.info('Launching Dev Tools...');\n  (0, _cliTools().launchDebugger)(debuggerURL);\n}\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\nfunction launchDevTools({\n  host,\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(host, port);\n  }\n}\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(_req, res) {\n    launchDevTools(options, isDebuggerConnected);\n    res.end('OK');\n  };\n}\n\n//# sourceMappingURL=devToolsMiddleware.js.map\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli-server-api (0.71.8 - v10.1.1) 2`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n  _cliTools = function () {\n    return data;\n  };\n  return data;\n}\nfunction _child_process() {\n  const data = require(\"child_process\");\n  _child_process = function () {\n    return data;\n  };\n  return data;\n}\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchDefaultDebugger(host, port, args = '', skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + (host || 'localhost') + '&port=' + port + '&projectRoots=' + process.cwd() + '&args=' + args;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchDefaultDebugger(host, port, args, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchDefaultDebugger(host, port, args, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  const hostname = host || 'localhost';\n  const debuggerURL = \\`http://\\${hostname}:\\${port}/debugger-ui\\${args}\\`;\n  _cliTools().logger.info('Launching Dev Tools...');\n  (0, _cliTools().launchDebugger)(debuggerURL);\n}\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\nfunction launchDevTools({\n  host,\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(host, port);\n  }\n}\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(_req, res) {\n    launchDevTools(options, isDebuggerConnected);\n    res.end('OK');\n  };\n}\n\n//# sourceMappingURL=devToolsMiddleware.js.map\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in @react-native-community/cli-server-api (0.71.8 - v10.1.1) 3`] = `\n\"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = getDevToolsMiddleware;\nfunction _cliTools() {\n  const data = require(\"@react-native-community/cli-tools\");\n  _cliTools = function () {\n    return data;\n  };\n  return data;\n}\nfunction _child_process() {\n  const data = require(\"child_process\");\n  _child_process = function () {\n    return data;\n  };\n  return data;\n}\n/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nfunction launchDefaultDebugger(host, port, args = '') {\n\n  const hostname = host || 'localhost';\n  const debuggerURL = \\`http://\\${hostname}:\\${port}/debugger-ui\\${args}\\`;\n  _cliTools().logger.info('Launching Dev Tools...');\n  (0, _cliTools().launchDebugger)(debuggerURL);\n}\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return \\`\"\\${pathname}\"\\`;\n}\nfunction launchDevTools({\n  host,\n  port,\n  watchFolders\n}, isDebuggerConnected) {\n  // Explicit config always wins\n  const customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    startCustomDebugger({\n      watchFolders,\n      customDebugger\n    });\n  } else if (!isDebuggerConnected()) {\n    // Debugger is not yet open; we need to open a session\n    launchDefaultDebugger(host, port);\n  }\n}\nfunction startCustomDebugger({\n  watchFolders,\n  customDebugger\n}) {\n  const folders = watchFolders.map(escapePath).join(' ');\n  const command = \\`\\${customDebugger} \\${folders}\\`;\n  _cliTools().logger.info('Starting custom debugger by executing:', command);\n  (0, _child_process().exec)(command, function (error) {\n    if (error !== null) {\n      _cliTools().logger.error('Error while starting custom debugger:', error.stack || '');\n    }\n  });\n}\nfunction getDevToolsMiddleware(options, isDebuggerConnected) {\n  return function devToolsMiddleware(_req, res) {\n    launchDevTools(options, isDebuggerConnected);\n    res.end('OK');\n  };\n}\n\n//# sourceMappingURL=devToolsMiddleware.js.map\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.49 1`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n'use strict';\n\nconst fs = require('fs');\nconst launchChrome = require('../util/launchChrome');\nconst path = require('path');\n\nconst {exec} = require('child_process');\n\nfunction launchChromeDevTools(port) {\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui';\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  return '\"' + pathname + '\"'; // \" Can escape paths with spaces in OS X, Windows, and *nix\n}\n\nfunction launchDevTools({port, projectRoots}, isChromeConnected) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function (error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/debugger-ui') {\n      var debuggerPath = path.join(__dirname, '..', 'util', 'debugger.html');\n      res.writeHead(200, {'Content-Type': 'text/html'});\n      fs.createReadStream(debuggerPath).pipe(res);\n    } else if (req.url === '/debuggerWorker.js') {\n      var workerPath = path.join(__dirname, '..', 'util', 'debuggerWorker.js');\n      res.writeHead(200, {'Content-Type': 'application/javascript'});\n      fs.createReadStream(workerPath).pipe(res);\n    } else if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n        'If you still need this, please let us know.'\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n        ' probably using an application created with an older CLI with the ' +\n        ' packager of a newer CLI. Please upgrade your application: ' +\n        'https://facebook.github.io/react-native/docs/upgrading.html');\n        launchDevTools(options, isChromeConnected);\n        res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.49 2`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n'use strict';\n\nconst fs = require('fs');\nconst launchChrome = require('../util/launchChrome');\nconst path = require('path');\n\nconst {exec} = require('child_process');\n\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchChromeDevTools(port, skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchChromeDevTools(port, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchChromeDevTools(port, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui';\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  return '\"' + pathname + '\"'; // \" Can escape paths with spaces in OS X, Windows, and *nix\n}\n\nfunction launchDevTools({port, projectRoots}, isChromeConnected) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function (error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/debugger-ui') {\n      var debuggerPath = path.join(__dirname, '..', 'util', 'debugger.html');\n      res.writeHead(200, {'Content-Type': 'text/html'});\n      fs.createReadStream(debuggerPath).pipe(res);\n    } else if (req.url === '/debuggerWorker.js') {\n      var workerPath = path.join(__dirname, '..', 'util', 'debuggerWorker.js');\n      res.writeHead(200, {'Content-Type': 'application/javascript'});\n      fs.createReadStream(workerPath).pipe(res);\n    } else if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n        'If you still need this, please let us know.'\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n        ' probably using an application created with an older CLI with the ' +\n        ' packager of a newer CLI. Please upgrade your application: ' +\n        'https://facebook.github.io/react-native/docs/upgrading.html');\n        launchDevTools(options, isChromeConnected);\n        res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.49 3`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n'use strict';\n\nconst fs = require('fs');\nconst launchChrome = require('../util/launchChrome');\nconst path = require('path');\n\nconst {exec} = require('child_process');\n\nfunction launchChromeDevTools(port) {\n\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui';\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  return '\"' + pathname + '\"'; // \" Can escape paths with spaces in OS X, Windows, and *nix\n}\n\nfunction launchDevTools({port, projectRoots}, isChromeConnected) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function (error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/debugger-ui') {\n      var debuggerPath = path.join(__dirname, '..', 'util', 'debugger.html');\n      res.writeHead(200, {'Content-Type': 'text/html'});\n      fs.createReadStream(debuggerPath).pipe(res);\n    } else if (req.url === '/debuggerWorker.js') {\n      var workerPath = path.join(__dirname, '..', 'util', 'debuggerWorker.js');\n      res.writeHead(200, {'Content-Type': 'application/javascript'});\n      fs.createReadStream(workerPath).pipe(res);\n    } else if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n        'If you still need this, please let us know.'\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n        ' probably using an application created with an older CLI with the ' +\n        ' packager of a newer CLI. Please upgrade your application: ' +\n        'https://facebook.github.io/react-native/docs/upgrading.html');\n        launchDevTools(options, isChromeConnected);\n        res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.50 1`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @format\n */\n'use strict';\n\nconst launchChrome = require('../util/launchChrome');\n\nconst {exec} = require('child_process');\n\nfunction launchChromeDevTools(port, args = '') {\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui' + args;\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return '\"' + pathname + '\"';\n}\n\nfunction launchDevTools(\n  {port, projectRoots, useDeltaBundler},\n  isChromeConnected,\n) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function(error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port, useDeltaBundler ? '#useDeltaBundler' : '');\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n          'If you still need this, please let us know.',\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n          ' probably using an application created with an older CLI with the ' +\n          ' packager of a newer CLI. Please upgrade your application: ' +\n          'https://facebook.github.io/react-native/docs/upgrading.html',\n      );\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.50 2`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @format\n */\n'use strict';\n\nconst launchChrome = require('../util/launchChrome');\n\nconst {exec} = require('child_process');\n\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchChromeDevTools(port, args = '', skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port + '&args=' + args;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchChromeDevTools(port, args, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchChromeDevTools(port, args, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui' + args;\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return '\"' + pathname + '\"';\n}\n\nfunction launchDevTools(\n  {port, projectRoots, useDeltaBundler},\n  isChromeConnected,\n) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function(error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port, useDeltaBundler ? '#useDeltaBundler' : '');\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n          'If you still need this, please let us know.',\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n          ' probably using an application created with an older CLI with the ' +\n          ' packager of a newer CLI. Please upgrade your application: ' +\n          'https://facebook.github.io/react-native/docs/upgrading.html',\n      );\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native 0.50 3`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n *\n * @format\n */\n'use strict';\n\nconst launchChrome = require('../util/launchChrome');\n\nconst {exec} = require('child_process');\n\nfunction launchChromeDevTools(port, args = '') {\n\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui' + args;\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  // \" Can escape paths with spaces in OS X, Windows, and *nix\n  return '\"' + pathname + '\"';\n}\n\nfunction launchDevTools(\n  {port, projectRoots, useDeltaBundler},\n  isChromeConnected,\n) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function(error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port, useDeltaBundler ? '#useDeltaBundler' : '');\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n          'If you still need this, please let us know.',\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n          ' probably using an application created with an older CLI with the ' +\n          ' packager of a newer CLI. Please upgrade your application: ' +\n          'https://facebook.github.io/react-native/docs/upgrading.html',\n      );\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native-macos 1`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n'use strict';\n\nconst fs = require('fs');\nconst launchChrome = require('../util/launchChrome');\nconst path = require('path');\n\nconst {exec} = require('child_process');\n\nfunction launchChromeDevTools(port) {\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui';\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  return '\"' + pathname + '\"'; // \" Can escape paths with spaces in OS X, Windows, and *nix\n}\n\nfunction launchDevTools({port, projectRoots}, isChromeConnected) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function (error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/debugger-ui') {\n      var debuggerPath = path.join(__dirname, '..', 'util', 'debugger.html');\n      res.writeHead(200, {'Content-Type': 'text/html'});\n      fs.createReadStream(debuggerPath).pipe(res);\n    } else if (req.url === '/debuggerWorker.js') {\n      var workerPath = path.join(__dirname, '..', 'util', 'debuggerWorker.js');\n      res.writeHead(200, {'Content-Type': 'application/javascript'});\n      fs.createReadStream(workerPath).pipe(res);\n    } else if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n        'If you still need this, please let us know.'\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n        ' probably using an application created with an older CLI with the ' +\n        ' packager of a newer CLI. Please upgrade your application: ' +\n        'https://facebook.github.io/react-native/docs/upgrading.html');\n        launchDevTools(options, isChromeConnected);\n        res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native-macos 2`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n'use strict';\n\nconst fs = require('fs');\nconst launchChrome = require('../util/launchChrome');\nconst path = require('path');\n\nconst {exec} = require('child_process');\n\n/* react-native-debugger-patch start */\nvar __fs = require('fs');\nvar __path = require('path');\nvar __net = require('net');\nvar __childProcess = require('child_process');\nvar __home_env = process.platform === 'win32' ? 'USERPROFILE' : 'HOME';\nvar __port_file = __path.join(process.env[__home_env], '.rndebugger_port');\n\nfunction __connectToRND(rndPath, log, cb) {\n  var __port;\n  try {\n    __port = __fs.readFileSync(__port_file, 'utf-8');\n  } catch (e) {\n    log && console.log(\n      '\\\\n[RNDebugger] The port file \\`$HOME/.rndebugger_port\\` not found\\\\n' +\n      'Maybe the React Native Debugger (^0.3) is not open?\\\\n' +\n      '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n'\n    );\n    return cb(false);\n  }\n  var __c = __net.createConnection({ host: '127.0.0.1', port: __port }, () => {\n    let pass = false;\n    __c.setEncoding('utf-8');\n    __c.write(JSON.stringify({ path: rndPath }));\n    __c.on('data', data => {\n      pass = data === 'success';\n      __c.end();\n    });\n    const __timeoutId = setTimeout(() => {\n      log && console.log(\n        '\\\\n[RNDebugger] Cannot connect to port ' + __port + '.\\\\n'\n      );\n      __c.end();\n    }, 1000);\n    __c.on('end', () => {\n      clearTimeout(__timeoutId);\n      !pass && log && console.log(\n        '\\\\n[RNDebugger] Try to set port of React Native server failed.\\\\n'\n      );\n      cb(pass);\n    });\n\n  });\n}\n\nvar __rndebuggerIsOpening = false;\nfunction launchChromeDevTools(port, skipRNDebugger) {\n  var __rnd_path = 'rndebugger://set-debugger-loc?host=' + 'localhost&port=' + port;\n\n  if (__rndebuggerIsOpening) return;\n  __rndebuggerIsOpening = true;\n  if (process.platform === 'darwin' && !skipRNDebugger) {\n    var __env = Object.assign({}, process.env);\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete __env.ELECTRON_RUN_AS_NODE;\n    __childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', __rnd_path], { env: __env })\n      .once('close', code => {\n        if (code > 0) {\n          __connectToRND(__rnd_path, false, pass => {\n            if (!pass) {\n              console.log(\n                '\\\\n[RNDebugger] Cannot open the app, maybe not install?\\\\n' +\n                '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\\\n' +\n                'Or it\\\\'s never started. (Not registered URI Scheme)\\\\n'\n              );\n            }\n            __rndebuggerIsOpening = false;\n            !pass && launchChromeDevTools(port, true);\n          });\n        } else {\n          __rndebuggerIsOpening = false;\n        }\n      })\n    return;\n  } else if (!skipRNDebugger) {\n    __connectToRND(__rnd_path, true, pass => {\n      __rndebuggerIsOpening = false;\n      !pass && launchChromeDevTools(port, true);\n    });\n    return;\n  }\n  __rndebuggerIsOpening = false;\n/* react-native-debugger-patch end */\n\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui';\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  return '\"' + pathname + '\"'; // \" Can escape paths with spaces in OS X, Windows, and *nix\n}\n\nfunction launchDevTools({port, projectRoots}, isChromeConnected) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function (error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/debugger-ui') {\n      var debuggerPath = path.join(__dirname, '..', 'util', 'debugger.html');\n      res.writeHead(200, {'Content-Type': 'text/html'});\n      fs.createReadStream(debuggerPath).pipe(res);\n    } else if (req.url === '/debuggerWorker.js') {\n      var workerPath = path.join(__dirname, '..', 'util', 'debuggerWorker.js');\n      res.writeHead(200, {'Content-Type': 'application/javascript'});\n      fs.createReadStream(workerPath).pipe(res);\n    } else if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n        'If you still need this, please let us know.'\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n        ' probably using an application created with an older CLI with the ' +\n        ' packager of a newer CLI. Please upgrade your application: ' +\n        'https://facebook.github.io/react-native/docs/upgrading.html');\n        launchDevTools(options, isChromeConnected);\n        res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n\nexports[`Inject to devtoolsMiddleware of React Native packager inject / revert in react-native-macos 3`] = `\n\"/**\n * Copyright (c) 2015-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n'use strict';\n\nconst fs = require('fs');\nconst launchChrome = require('../util/launchChrome');\nconst path = require('path');\n\nconst {exec} = require('child_process');\n\nfunction launchChromeDevTools(port) {\n\n  var debuggerURL = 'http://localhost:' + port + '/debugger-ui';\n  console.log('Launching Dev Tools...');\n  launchChrome(debuggerURL);\n}\n\nfunction escapePath(pathname) {\n  return '\"' + pathname + '\"'; // \" Can escape paths with spaces in OS X, Windows, and *nix\n}\n\nfunction launchDevTools({port, projectRoots}, isChromeConnected) {\n  // Explicit config always wins\n  var customDebugger = process.env.REACT_DEBUGGER;\n  if (customDebugger) {\n    var projects = projectRoots.map(escapePath).join(' ');\n    var command = customDebugger + ' ' + projects;\n    console.log('Starting custom debugger by executing: ' + command);\n    exec(command, function (error, stdout, stderr) {\n      if (error !== null) {\n        console.log('Error while starting custom debugger: ' + error);\n      }\n    });\n  } else if (!isChromeConnected()) {\n    // Dev tools are not yet open; we need to open a session\n    launchChromeDevTools(port);\n  }\n}\n\nmodule.exports = function(options, isChromeConnected) {\n  return function(req, res, next) {\n    if (req.url === '/debugger-ui') {\n      var debuggerPath = path.join(__dirname, '..', 'util', 'debugger.html');\n      res.writeHead(200, {'Content-Type': 'text/html'});\n      fs.createReadStream(debuggerPath).pipe(res);\n    } else if (req.url === '/debuggerWorker.js') {\n      var workerPath = path.join(__dirname, '..', 'util', 'debuggerWorker.js');\n      res.writeHead(200, {'Content-Type': 'application/javascript'});\n      fs.createReadStream(workerPath).pipe(res);\n    } else if (req.url === '/launch-safari-devtools') {\n      // TODO: remove \\`console.log\\` and dev tools binary\n      console.log(\n        'We removed support for Safari dev-tools. ' +\n        'If you still need this, please let us know.'\n      );\n    } else if (req.url === '/launch-chrome-devtools') {\n      // TODO: Remove this case in the future\n      console.log(\n        'The method /launch-chrome-devtools is deprecated. You are ' +\n        ' probably using an application created with an older CLI with the ' +\n        ' packager of a newer CLI. Please upgrade your application: ' +\n        'https://facebook.github.io/react-native/docs/upgrading.html');\n        launchDevTools(options, isChromeConnected);\n        res.end('OK');\n    } else if (req.url === '/launch-js-devtools') {\n      launchDevTools(options, isChromeConnected);\n      res.end('OK');\n    } else {\n      next();\n    }\n  };\n};\n\"\n`;\n"
  },
  {
    "path": "npm-package/src/__tests__/injectDevToolsMiddleware.test.js",
    "content": "import fs from 'fs-extra'\nimport path from 'path'\nimport fetch from 'node-fetch'\nimport { inject, revert } from '../injectDevToolsMiddleware'\n\nconst getRemoteMiddlewarePath = (version) => `https://raw.githubusercontent.com/facebook/react-native/${version}-stable/local-cli/server/middleware/getDevToolsMiddleware.js`\n\nconst modulePath = path.join(__dirname, 'tmp')\n\nconst middlewareDir = 'local-cli/server/middleware'\nconst middlewarePath = path.join(middlewareDir, 'getDevToolsMiddleware.js')\n\njest.setTimeout(30000)\n\ndescribe('Inject to devtoolsMiddleware of React Native packager', () => {\n  afterEach(() => {\n    fs.removeSync(path.join(__dirname, 'tmp'))\n  })\n  const oldVersions = ['0.49', '0.50']\n  oldVersions.forEach((version) => {\n    test(`inject / revert in react-native ${version}`, async () => {\n      const code = await fetch(getRemoteMiddlewarePath(version)).then((res) => res.text())\n      fs.ensureDirSync(path.join(modulePath, 'react-native', middlewareDir))\n      fs.outputFileSync(\n        path.join(modulePath, 'react-native', middlewarePath),\n        code,\n      )\n      fs.outputFileSync(\n        path.join(modulePath, 'react-native', 'package.json'),\n        JSON.stringify({\n          version: `${version}.0`,\n          name: 'react-native',\n        }),\n      )\n\n      expect(code).toMatchSnapshot()\n      inject(modulePath, 'react-native')\n      expect(\n        fs.readFileSync(\n          path.join(modulePath, 'react-native', middlewarePath),\n          'utf-8',\n        ),\n      ).toMatchSnapshot()\n      revert(modulePath, 'react-native')\n      expect(\n        fs.readFileSync(\n          path.join(modulePath, 'react-native', middlewarePath),\n          'utf-8',\n        ),\n      ).toMatchSnapshot()\n    })\n  })\n\n  test('inject / revert in react-native-macos', async () => {\n    const code = await fetch(\n      'https://raw.githubusercontent.com/ptmt/react-native-macos/merge-0.44.0/local-cli/server/middleware/getDevToolsMiddleware.js',\n    ).then((res) => res.text())\n    fs.ensureDirSync(\n      path.join(modulePath, 'react-native-macos', middlewareDir),\n    )\n    fs.outputFileSync(\n      path.join(modulePath, 'react-native-macos', middlewarePath),\n      code,\n    )\n    fs.outputFileSync(\n      path.join(modulePath, 'react-native-macos', 'package.json'),\n      JSON.stringify({\n        version: '0.8.7',\n        name: 'react-native-macos',\n      }),\n    )\n\n    expect(code).toMatchSnapshot()\n    inject(modulePath, 'react-native-macos')\n    expect(\n      fs.readFileSync(\n        path.join(modulePath, 'react-native-macos', middlewarePath),\n        'utf-8',\n      ),\n    ).toMatchSnapshot()\n    revert(modulePath, 'react-native-macos')\n    expect(\n      fs.readFileSync(\n        path.join(modulePath, 'react-native-macos', middlewarePath),\n        'utf-8',\n      ),\n    ).toMatchSnapshot()\n  })\n\n  const oldCliVersions = [\n    {\n      rn: '0.59.0-rc.0',\n      cli: ['1.5.0'],\n    },\n    {\n      rn: '0.60.0',\n      cli: ['2.8.3', '2.9.0'],\n    },\n    {\n      rn: '0.61.0',\n      cli: ['3.0.0-alpha.7', '3.0.1'],\n    },\n  ]\n  const oldPkgName = '@react-native-community/cli'\n  oldCliVersions.forEach(({ rn, cli }) => {\n    cli.forEach((version) => {\n      test(`inject / revert in ${oldPkgName} (${rn} - v${version})`, async () => {\n        const mDir = 'build/commands/server/middleware'\n        const mPath = path.join(mDir, 'getDevToolsMiddleware.js')\n        const code = await fetch(\n          `https://unpkg.com/${oldPkgName}@${version}/build/commands/server/middleware/getDevToolsMiddleware.js`,\n        ).then((res) => res.text())\n        fs.ensureDirSync(\n          path.join(modulePath, oldPkgName, mDir),\n        )\n        fs.outputFileSync(\n          path.join(modulePath, oldPkgName, mPath),\n          code,\n        )\n        fs.outputFileSync(\n          path.join(modulePath, 'react-native', 'package.json'),\n          JSON.stringify({\n            version: rn,\n            name: 'react-native',\n          }),\n        )\n\n        expect(code).toMatchSnapshot()\n        inject(modulePath, 'react-native')\n        expect(\n          fs.readFileSync(\n            path.join(modulePath, oldPkgName, mPath),\n            'utf-8',\n          ),\n        ).toMatchSnapshot()\n        revert(modulePath, 'react-native')\n        expect(\n          fs.readFileSync(\n            path.join(modulePath, oldPkgName, mPath),\n            'utf-8',\n          ),\n        ).toMatchSnapshot()\n      })\n    })\n  })\n\n  const newCliVersions = [\n    {\n      rn: '0.71.8',\n      cli: ['10.1.1'],\n    },\n  ]\n  const newPkgName = '@react-native-community/cli-server-api'\n  newCliVersions.forEach(({ rn, cli }) => {\n    cli.forEach((version) => {\n      test(`inject / revert in ${newPkgName} (${rn} - v${version})`, async () => {\n        const mDir = 'build/'\n        const mPath = path.join(mDir, 'devToolsMiddleware.js')\n        const code = await fetch(\n          `https://unpkg.com/${newPkgName}@${version}/build/devToolsMiddleware.js`,\n        ).then((res) => res.text())\n        fs.ensureDirSync(\n          path.join(modulePath, newPkgName, mDir),\n        )\n        fs.outputFileSync(\n          path.join(modulePath, newPkgName, mPath),\n          code,\n        )\n        fs.outputFileSync(\n          path.join(modulePath, 'react-native', 'package.json'),\n          JSON.stringify({\n            version: rn,\n            name: 'react-native',\n          }),\n        )\n\n        expect(code).toMatchSnapshot()\n        inject(modulePath, 'react-native')\n        expect(\n          fs.readFileSync(\n            path.join(\n              modulePath,\n              newPkgName,\n              mPath,\n            ),\n            'utf-8',\n          ),\n        ).toMatchSnapshot()\n        revert(modulePath, 'react-native')\n        expect(\n          fs.readFileSync(\n            path.join(\n              modulePath,\n              newPkgName,\n              mPath,\n            ),\n            'utf-8',\n          ),\n        ).toMatchSnapshot()\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "npm-package/src/injectDevToolsMiddleware.js",
    "content": "import fs from 'fs'\nimport { join } from 'path'\nimport es6Template from 'es6-template'\nimport semver from 'semver'\n\nconst tmplPath = join(__dirname, 'injectDevToolsMiddleware.tmpl.js')\nconst tmplPathInDev = join(\n  __dirname,\n  '../lib/injectDevToolsMiddleware.tmpl.js',\n)\n\nconst template = fs.readFileSync(\n  fs.existsSync(tmplPath) ? tmplPath : tmplPathInDev,\n  'utf-8',\n)\n\nconst name = 'react-native-debugger-patch'\nconst startFlag = `/* ${name} start */`\nconst endFlag = `/* ${name} end */`\n\nconst rnFlags = {\n  '0.50.0-rc.0': {\n    target: 'react-native',\n    dir: 'local-cli/server/middleware',\n    file: 'getDevToolsMiddleware.js',\n    keyFunc: 'launchChromeDevTools',\n    func: \"function launchChromeDevTools(port, args = '') {\",\n    replaceFunc:\n      \"function launchChromeDevTools(port, args = '', skipRNDebugger) {\",\n    funcCall: '(port, args, true)',\n    args: \"'localhost&port=' + port + '&args=' + args\",\n  },\n  '0.53.0': {\n    target: 'react-native',\n    dir: 'local-cli/server/middleware',\n    file: 'getDevToolsMiddleware.js',\n    keyFunc: 'launchChromeDevTools',\n    func: \"function launchChromeDevTools(host, args = '') {\",\n    replaceFunc:\n      \"function launchChromeDevTools(host, args = '', skipRNDebugger) {\",\n    funcCall: '(host, args, true)',\n    args:\n      \"'localhost&port=' + (host && host.split(':')[1] || '8081') + '&args=' + args\",\n  },\n  '0.59.0-rc.0': [\n    {\n      target: '@react-native-community/cli',\n      dir: 'build/commands/server/middleware',\n      file: 'getDevToolsMiddleware.js',\n      keyFunc: 'launchChromeDevTools',\n      func: \"function launchChromeDevTools(port, args = '') {\",\n      replaceFunc:\n        \"function launchChromeDevTools(port, args = '', skipRNDebugger) {\",\n      funcCall: '(port, args, true)',\n      args: \"'localhost&port=' + port + '&args=' + args\",\n    },\n    {\n      target: '@react-native-community/cli', // 3.0.0 alpha\n      dir: 'build/commands/server/middleware',\n      file: 'getDevToolsMiddleware.js',\n      keyFunc: 'launchDevTools',\n      func:\n        'function launchDevTools({\\n  port,\\n  watchFolders\\n}, isDebuggerConnected) {',\n      replaceFunc:\n        'function launchDevTools({port, watchFolders},'\n        + ' isDebuggerConnected, skipRNDebugger) {',\n      funcCall: '({port, watchFolders}, isDebuggerConnected, true)',\n      args:\n        \"'localhost&port=' + port + '&watchFolders=' + \"\n        // eslint-disable-next-line no-template-curly-in-string\n        + 'watchFolders.map(f => `\"${f}\"`).join(\\',\\')',\n    },\n    {\n      target: '@react-native-community/cli', // 3.0.0\n      dir: 'build/commands/server/middleware',\n      file: 'getDevToolsMiddleware.js',\n      keyFunc: 'launchDefaultDebugger',\n      func: \"function launchDefaultDebugger(host, port, args = '') {\",\n      replaceFunc:\n        \"function launchDefaultDebugger(host, port, args = '', skipRNDebugger) {\",\n      funcCall: '(host, port, args, true)',\n      args: \"host + '&port=' + port + '&args=' + args\",\n    },\n  ],\n  '0.62.0-rc.0': [ // Tested ~ 0.71.x\n    {\n      target: '@react-native-community/cli-server-api',\n      dir: 'build',\n      file: 'devToolsMiddleware.js',\n      keyFunc: 'launchDefaultDebugger',\n      func: \"function launchDefaultDebugger(host, port, args = '') {\",\n      replaceFunc:\n        \"function launchDefaultDebugger(host, port, args = '', skipRNDebugger) {\",\n      funcCall: '(host, port, args, true)',\n      args: \"(host || 'localhost') + '&port=' + port + '&projectRoots=' + process.cwd() + \"\n        + \"'&args=' + args\",\n    },\n  ],\n}\n\nconst flags = {\n  'react-native': rnFlags,\n  'react-native-tvos': rnFlags,\n  'react-native-macos': {\n    '0.0.0': {\n      target: 'react-native-macos',\n      dir: 'local-cli/server/middleware',\n      file: 'getDevToolsMiddleware.js',\n      keyFunc: 'launchChromeDevTools',\n      func: 'function launchChromeDevTools(port) {',\n      replaceFunc: 'function launchChromeDevTools(port, skipRNDebugger) {',\n      funcCall: '(port, true)',\n      args: \"'localhost&port=' + port\",\n    },\n  },\n  // react-native\n  default: {\n    target: 'react-native',\n    dir: 'local-cli/server/middleware',\n    file: 'getDevToolsMiddleware.js',\n    keyFunc: 'launchChromeDevTools',\n    func: 'function launchChromeDevTools(port) {',\n    replaceFunc: 'function launchChromeDevTools(port, skipRNDebugger) {',\n    funcCall: '(port, true)',\n    args: \"'localhost&port=' + port\",\n  },\n}\n\nconst getModuleInfo = (modulePath, moduleName) => {\n  const pkg = JSON.parse(\n    fs.readFileSync(join(modulePath, moduleName, 'package.json')),\n  ); // eslint-disable-line\n  return { version: pkg.version, name: pkg.name }\n}\n\nfunction getFlag(moduleName, version) {\n  const list = flags[moduleName || 'react-native'] || {}\n  const versions = Object.keys(list)\n  let flag = flags.default\n  for (let i = 0; i < versions.length; i += 1) {\n    if (semver.gte(version, versions[i])) {\n      flag = list[versions[i]]\n    }\n  }\n  return flag\n}\n\nconst injectCode = (\n  modulePath,\n  {\n    keyFunc,\n    func: funcFlag,\n    replaceFunc: replaceFuncFlag,\n    funcCall,\n    args,\n    target,\n    dir,\n    file,\n  },\n) => {\n  const filePath = join(modulePath, target, dir, file)\n  if (!fs.existsSync(filePath)) return false\n  const code = es6Template(template, {\n    startFlag,\n    replaceFuncFlag,\n    keyFunc,\n    funcCall,\n    endFlag,\n    args,\n  })\n\n  const middlewareCode = fs.readFileSync(filePath, 'utf-8')\n  let start = middlewareCode.indexOf(startFlag)\n  let end = middlewareCode.indexOf(endFlag) + endFlag.length\n  // already injected\n  if (start > -1 && middlewareCode.indexOf(replaceFuncFlag) === -1) {\n    start = -1\n    end = -1\n  }\n  if (start === -1) {\n    start = middlewareCode.indexOf(funcFlag)\n    end = start + funcFlag.length\n  }\n  if (start === -1) return false\n  fs.writeFileSync(\n    filePath,\n    middlewareCode.substr(0, start)\n      + code\n      + middlewareCode.substr(end, middlewareCode.length),\n  )\n  return true\n}\n\nexport const inject = (modulePath, moduleName) => {\n  const info = getModuleInfo(modulePath, moduleName)\n  const flagList = getFlag(info.name, info.version)\n  if (Array.isArray(flagList)) {\n    flagList.some((flag) => injectCode(modulePath, flag))\n  } else {\n    injectCode(modulePath, flagList)\n  }\n  return true\n}\n\nconst revertCode = (\n  modulePath,\n  {\n    func: funcFlag, replaceFunc: replaceFuncFlag, target, dir, file,\n  },\n) => {\n  const filePath = join(modulePath, target, dir, file)\n  if (!fs.existsSync(filePath)) return false\n\n  const middlewareCode = fs.readFileSync(filePath, 'utf-8')\n  let start = middlewareCode.indexOf(startFlag)\n  let end = middlewareCode.indexOf(endFlag) + endFlag.length\n  // already injected\n  if (start > -1 && middlewareCode.indexOf(replaceFuncFlag) === -1) {\n    start = -1\n    end = -1\n  }\n  if (start === -1) return false\n  fs.writeFileSync(\n    filePath,\n    middlewareCode.substr(0, start)\n      + funcFlag\n      + middlewareCode.substr(end, middlewareCode.length),\n  )\n  return true\n}\n\nexport const revert = (modulePath, moduleName) => {\n  const info = getModuleInfo(modulePath, moduleName)\n  const flagList = getFlag(info.name, info.version)\n  if (Array.isArray(flagList)) {\n    flagList.some((flag) => revertCode(modulePath, flag))\n  } else {\n    revertCode(modulePath, flagList)\n  }\n  return true\n}\n"
  },
  {
    "path": "npm-package/src/main.js",
    "content": "import fs from 'fs'\nimport cp from 'child_process'\nimport path from 'path'\nimport chalk from 'chalk'\nimport { inject as injectMiddleware, revert as revertMiddleware } from './injectDevToolsMiddleware'\n\nconst modulePath = path.join(process.cwd(), 'node_modules')\n\nconst log = (pass, msg) => {\n  const prefix = pass ? chalk.green.bgBlack('PASS') : chalk.red.bgBlack('FAIL')\n  const color = pass ? chalk.blue : chalk.red\n  console.log(prefix, color(msg))\n}\n\nexport default (argv, cb) => {\n  let moduleName\n  if (argv.macos) {\n    moduleName = 'react-native-macos'\n  } else {\n    moduleName = 'react-native'\n  }\n\n  // Revert injection\n  if (argv.revert) {\n    const passMiddleware = revertMiddleware(modulePath, moduleName)\n    const msg = 'Revert injection of React Native Debugger from React Native packager'\n    log(passMiddleware, msg + (!passMiddleware ? ', the file inject file not found.' : '.'))\n    return cb(passMiddleware)\n  }\n\n  const inject = () => {\n    const pass = injectMiddleware(modulePath, moduleName)\n    const msg = 'Replace `open debugger-ui with Chrome` to `open React Native Debugger`'\n    log(pass, msg + (pass ? '.' : ', the file inject file not found.'))\n    cb(pass)\n  }\n\n  if (process.platform !== 'darwin') {\n    inject()\n  } else {\n    const cwd =      '/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/'; // eslint-disable-line\n    const lsregisterPath = 'lsregister'\n    if (!fs.existsSync(cwd + lsregisterPath)) return inject()\n\n    cp.exec(`./${lsregisterPath} -dump | grep rndebugger:`, { cwd }, (err, stdout) => {\n      if (stdout.length === 0) {\n        log(\n          false,\n          '[RNDebugger] The `rndebugger://` URI scheme seems not registered, '\n            + \"maybe you haven't install the app? \"\n            + 'Run `brew update && brew install --cask react-native-debugger` '\n            + 'or download from https://github.com/jhen0409/react-native-debugger/releases '\n            + 'then open it to register the URI scheme.',\n        )\n      }\n      inject()\n    })\n  }\n}\n"
  },
  {
    "path": "npm-package/src/open.js",
    "content": "import fs from 'fs'\nimport path from 'path'\nimport net from 'net'\nimport childProcess from 'child_process'\n\nconst homeEnv = process.platform === 'win32' ? 'USERPROFILE' : 'HOME'\nconst portFile = path.join(process.env[homeEnv], '.rndebugger_port')\n\nfunction connectToRND(rndPath, log, cb) {\n  let port\n  try {\n    port = fs.readFileSync(portFile, 'utf-8')\n  } catch (e) {\n    if (log) {\n      console.log(\n        '\\n[RNDebugger] The port file `$HOME/.rndebugger_port` not found\\n'\n          + 'Maybe the React Native Debugger (^0.3) is not open?\\n'\n          + '(Please visit https://github.com/jhen0409/react-native-debugger#installation)\\n',\n      )\n    }\n    return cb(false)\n  }\n  const connection = net.createConnection({ host: '127.0.0.1', port }, () => {\n    let pass = false\n    connection.setEncoding('utf-8')\n    connection.write(JSON.stringify({ path: rndPath }))\n    connection.on('data', (data) => {\n      pass = data === 'success'\n      connection.end()\n    })\n    const timeoutId = setTimeout(() => {\n      if (log) {\n        console.log(`\\n[RNDebugger] Cannot connect to server with port ${port}.\\n`)\n      }\n      connection.end()\n    }, 1000)\n    connection.on('end', () => {\n      clearTimeout(timeoutId)\n      if (!pass && log) {\n        console.log('\\n[RNDebugger] Try to set port of React Native packager failed.\\n')\n      }\n      cb(pass)\n    })\n  })\n}\n\nexport default ({ port, host = 'localhost' }, cb) => {\n  const rndPath = `rndebugger://set-debugger-loc?host=${host}&port=${port}`\n\n  if (process.platform === 'darwin') {\n    const env = { ...process.env }\n    // This env is specified from Expo (and CRNA), we need avoid it included in rndebugger\n    delete env.ELECTRON_RUN_AS_NODE\n    childProcess\n      .spawn('open', ['-g', '-a', 'React Native Debugger', rndPath], { env })\n      .once('close', (code) => {\n        if (code > 0) {\n          connectToRND(rndPath, false, (pass) => {\n            if (!pass) {\n              console.log(\n                \"\\n[RNDebugger] Cannot open the app, maybe you haven't install the app?\\n\"\n                  + 'Run `brew update && brew cask install react-native-debugger` '\n                  + 'or download from https://github.com/jhen0409/react-native-debugger/releases\\n',\n              )\n            }\n            cb(pass, true)\n          })\n        } else {\n          cb(true)\n        }\n      })\n  } else {\n    connectToRND(rndPath, true, (pass) => {\n      cb(pass, true)\n    })\n  }\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-native-debugger\",\n  \"version\": \"0.14.0\",\n  \"productName\": \"React Native Debugger In Dev\",\n  \"description\": \"The standalone app for React Native Debugger, with React DevTools / Redux DevTools\",\n  \"main\": \"electron/main.js\",\n  \"scripts\": {\n    \"pack-macos\": \"./scripts/package-macos.sh\",\n    \"pack-linux\": \"./scripts/package-linux.sh\",\n    \"pack-windows\": \"sh ./scripts/package-windows.sh\",\n    \"pack\": \"yarn build && ./scripts/package-linux.sh && ./scripts/package-windows.sh && ./scripts/package-macos.sh\",\n    \"start\": \"cd dist && cross-env NODE_ENV=production PACKAGE=no electron ./\",\n    \"build:main\": \"cross-env NODE_ENV=production webpack --config webpack/main.prod.js --progress --profile\",\n    \"build:renderer\": \"cross-env NODE_ENV=production webpack --config webpack/renderer.prod.js --progress --profile\",\n    \"build\": \"yarn build:main && yarn build:renderer\",\n    \"dev:webpack\": \"webpack-dev-server --config webpack/renderer.dev.js --port 3000 --allowed-hosts all\",\n    \"dev:electron\": \"cross-env NODE_ENV=development electron -r @babel/register -r ./electron/debug .\",\n    \"lint\": \"eslint .\",\n    \"test\": \"yarn lint && jest __tests__\",\n    \"test-e2e\": \"jest __e2e__ --runInBand  --forceExit\",\n    \"postinstall\": \"patch-package && node ./scripts/postinstall.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/jhen0409/react-native-debugger.git\"\n  },\n  \"author\": \"Jhen <developer@jhen.me>\",\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"@apollo/client\": \"^3.7.17\",\n    \"@babel/core\": \"^7.22.9\",\n    \"@babel/eslint-parser\": \"^7.22.9\",\n    \"@babel/plugin-transform-react-constant-elements\": \"^7.22.5\",\n    \"@babel/plugin-transform-react-inline-elements\": \"^7.22.5\",\n    \"@babel/preset-env\": \"^7.22.9\",\n    \"@babel/preset-react\": \"^7.22.5\",\n    \"@babel/register\": \"^7.22.5\",\n    \"@electron/notarize\": \"^2.1.0\",\n    \"@electron/osx-sign\": \"^1.0.4\",\n    \"@electron/universal\": \"^1.4.1\",\n    \"babel-loader\": \"^9.1.3\",\n    \"babel-plugin-transform-react-remove-prop-types\": \"^0.4.10\",\n    \"cross-env\": \"^5.2.0\",\n    \"css-loader\": \"^6.8.1\",\n    \"electron\": \"^25.3.0\",\n    \"electron-debug\": \"^3.2.0\",\n    \"electron-installer-dmg\": \"^4.0.0\",\n    \"electron-installer-windows\": \"^3.0.0\",\n    \"electron-packager\": \"^17.1.1\",\n    \"eslint\": \"^8.45.0\",\n    \"eslint-config-airbnb\": \"^19.0.4\",\n    \"eslint-config-prettier\": \"^8.8.0\",\n    \"eslint-plugin-import\": \"^2.27.5\",\n    \"eslint-plugin-jsx-a11y\": \"^6.7.1\",\n    \"eslint-plugin-react\": \"^7.33.0\",\n    \"jest\": \"^29.6.1\",\n    \"mobx\": \"^3.6.2\",\n    \"mobx-remotedev\": \"^0.2.8\",\n    \"patch-package\": \"^6.2.2\",\n    \"playwright-core\": \"^1.36.1\",\n    \"shelljs\": \"^0.8.5\",\n    \"style-loader\": \"^3.3.3\",\n    \"terser-webpack-plugin\": \"^5.3.9\",\n    \"wait-for-expect\": \"^3.0.2\",\n    \"webpack\": \"^5.88.2\",\n    \"webpack-bundle-analyzer\": \"^4.9.0\",\n    \"webpack-cli\": \"^5.1.4\",\n    \"webpack-dev-server\": \"^4.15.1\",\n    \"whatwg-fetch\": \"^3.6.17\",\n    \"ws\": \"^7.5.9\"\n  },\n  \"dependencies\": {\n    \"@electron/remote\": \"^2.0.10\",\n    \"@redux-devtools/app\": \"^2.2.1\",\n    \"@redux-devtools/core\": \"^3.13.1\",\n    \"@redux-devtools/instrument\": \"^2.1.0\",\n    \"@redux-devtools/ui\": \"^1.3.0\",\n    \"@redux-devtools/utils\": \"^2.0.1\",\n    \"adbkit\": \"^2.11.0\",\n    \"apollo-client-devtools\": \"^4.1.4\",\n    \"electron-context-menu\": \"^3.6.1\",\n    \"electron-fetch\": \"^1.2.1\",\n    \"electron-gh-releases\": \"^2.0.4\",\n    \"electron-store\": \"^1.2.0\",\n    \"header-case-normalizer\": \"^1.0.3\",\n    \"jsan\": \"^3.1.9\",\n    \"json5\": \"^0.5.1\",\n    \"localforage\": \"^1.10.0\",\n    \"multiline-template\": \"^0.1.2\",\n    \"portscanner\": \"^2.1.1\",\n    \"prop-types\": \"^15.8.1\",\n    \"react\": \"^18.2.0\",\n    \"react-dev-utils\": \"^4.2.1\",\n    \"react-devtools-core\": \"^4.28.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-icons\": \"^4.10.1\",\n    \"react-redux\": \"^8.1.1\",\n    \"redux\": \"^4.2.1\",\n    \"redux-persist\": \"^6.0.0\",\n    \"styled-components\": \"^6.0.5\"\n  },\n  \"optionalDependencies\": {\n    \"electron-installer-debian\": \"^2.0.1\",\n    \"electron-installer-redhat\": \"^2.0.0\"\n  },\n  \"resolutions\": {\n    \"ws\": \"^7.5.9\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\"\n  },\n  \"jest\": {\n    \"testEnvironment\": \"node\"\n  }\n}\n"
  },
  {
    "path": "patches/@redux-devtools+inspector-monitor-trace-tab+1.0.0.patch",
    "content": "diff --git a/node_modules/@redux-devtools/inspector-monitor-trace-tab/src/openFile.ts b/node_modules/@redux-devtools/inspector-monitor-trace-tab/src/openFile.ts\nindex d3cfdc9..9aeafeb 100644\n--- a/node_modules/@redux-devtools/inspector-monitor-trace-tab/src/openFile.ts\n+++ b/node_modules/@redux-devtools/inspector-monitor-trace-tab/src/openFile.ts\n@@ -101,41 +101,5 @@ export default function openFile(\n   lineNumber: number,\n   stackFrame: StackFrame\n ) {\n-  if (!chrome || !chrome.storage) return; // TODO: Pass editor settings for using outside of browser extension\n-  const storage = isFF\n-    ? chrome.storage.local\n-    : chrome.storage.sync || chrome.storage.local;\n-  storage.get(\n-    ['useEditor', 'editor', 'projectPath'],\n-    function ({ useEditor, editor, projectPath }) {\n-      if (\n-        useEditor &&\n-        projectPath &&\n-        typeof editor === 'string' &&\n-        /^\\w{1,30}$/.test(editor)\n-      ) {\n-        openInEditor(editor.toLowerCase(), projectPath as string, stackFrame);\n-      } else {\n-        if (\n-          chrome.devtools &&\n-          chrome.devtools.panels &&\n-          !!chrome.devtools.panels.openResource\n-        ) {\n-          openResource(fileName, lineNumber, stackFrame);\n-        } else if (chrome.runtime && (chrome.runtime.openOptionsPage || isFF)) {\n-          if (chrome.devtools && isFF) {\n-            chrome.devtools.inspectedWindow.eval(\n-              'confirm(\"Set the editor to open the file in?\")',\n-              (result) => {\n-                if (!result) return;\n-                void chrome.runtime.sendMessage({ type: 'OPEN_OPTIONS' });\n-              }\n-            );\n-          } else if (confirm('Set the editor to open the file in?')) {\n-            chrome.runtime.openOptionsPage();\n-          }\n-        }\n-      }\n-    }\n-  );\n+  window.openInEditor && window.openInEditor(fileName, lineNumber)\n }\n"
  },
  {
    "path": "patches/@redux-devtools+ui+1.3.0.patch",
    "content": "diff --git a/node_modules/@redux-devtools/ui/lib/esm/Tabs/Tabs.js b/node_modules/@redux-devtools/ui/lib/esm/Tabs/Tabs.js\nindex 5454804..df65ca0 100644\n--- a/node_modules/@redux-devtools/ui/lib/esm/Tabs/Tabs.js\n+++ b/node_modules/@redux-devtools/ui/lib/esm/Tabs/Tabs.js\n@@ -88,12 +88,14 @@ var Tabs = /*#__PURE__*/function (_Component) {\n \n       if (!this.SelectedComponent) {\n         return /*#__PURE__*/React.createElement(TabsContainer, {\n-          position: this.props.position\n+          position: this.props.position,\n+          style: this.props.style,\n         }, tabsHeader);\n       }\n \n       return /*#__PURE__*/React.createElement(TabsContainer, {\n-        position: this.props.position\n+        position: this.props.position,\n+        style: this.props.style,\n       }, tabsHeader, /*#__PURE__*/React.createElement(\"div\", null, /*#__PURE__*/React.createElement(this.SelectedComponent, this.selector && this.selector())));\n     }\n   }]);\n"
  },
  {
    "path": "patches/apollo-client-devtools+4.1.4.patch",
    "content": "diff --git a/node_modules/apollo-client-devtools/build/background.js b/node_modules/apollo-client-devtools/build/background.js\nindex 1b46d15..5767881 100644\n--- a/node_modules/apollo-client-devtools/build/background.js\n+++ b/node_modules/apollo-client-devtools/build/background.js\n@@ -171,21 +171,21 @@ chrome.runtime.onConnect.addListener(port => {\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ })\ndiff --git a/node_modules/apollo-client-devtools/build/devtools.js b/node_modules/apollo-client-devtools/build/devtools.js\nindex 165495f..8290715 100644\n--- a/node_modules/apollo-client-devtools/build/devtools.js\n+++ b/node_modules/apollo-client-devtools/build/devtools.js\n@@ -165,22 +165,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n-\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n /***/ }),\n \ndiff --git a/node_modules/apollo-client-devtools/build/hook.js b/node_modules/apollo-client-devtools/build/hook.js\nindex 63aa181..d6539a7 100644\n--- a/node_modules/apollo-client-devtools/build/hook.js\n+++ b/node_modules/apollo-client-devtools/build/hook.js\n@@ -4712,21 +4712,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ }),\n@@ -4859,7 +4859,7 @@ function initializeHook() {\n     });\n     const clientRelay = new Relay_1.default();\n     clientRelay.addConnection(\"tab\", (message) => {\n-        window.postMessage(message, \"*\");\n+        window.postMessage(message);\n     });\n     window.addEventListener(\"message\", ({ data }) => {\n         clientRelay.broadcast(data);\ndiff --git a/node_modules/apollo-client-devtools/build/panel.js b/node_modules/apollo-client-devtools/build/panel.js\nindex 4b3ad6e..f7e021e 100644\n--- a/node_modules/apollo-client-devtools/build/panel.js\n+++ b/node_modules/apollo-client-devtools/build/panel.js\n@@ -54713,21 +54713,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ }),\ndiff --git a/node_modules/apollo-client-devtools/build/tab.js b/node_modules/apollo-client-devtools/build/tab.js\nindex 9ed84be..702f76c 100644\n--- a/node_modules/apollo-client-devtools/build/tab.js\n+++ b/node_modules/apollo-client-devtools/build/tab.js\n@@ -135,21 +135,21 @@ exports[\"default\"] = EventTarget;\n \n Object.defineProperty(exports, \"__esModule\", ({ value: true }));\n exports.RELOAD_TAB_COMPLETE = exports.RELOADING_TAB = exports.EXPLORER_RESPONSE = exports.EXPLORER_REQUEST = exports.PANEL_CLOSED = exports.PANEL_OPEN = exports.UPDATE = exports.REQUEST_DATA = exports.ACTION_HOOK_FIRED = exports.CREATE_DEVTOOLS_PANEL = exports.APOLLO_CLIENT_FOUND = exports.FIND_APOLLO_CLIENT = exports.DEVTOOLS_INITIALIZED = exports.REQUEST_TAB_ID = exports.CLIENT_FOUND = void 0;\n-exports.CLIENT_FOUND = \"client-found\";\n-exports.REQUEST_TAB_ID = \"request-tab-id\";\n-exports.DEVTOOLS_INITIALIZED = \"devtools-initialized\";\n-exports.FIND_APOLLO_CLIENT = \"find-apollo-client\";\n-exports.APOLLO_CLIENT_FOUND = \"apollo-client-found\";\n-exports.CREATE_DEVTOOLS_PANEL = \"create-devtools-panel\";\n-exports.ACTION_HOOK_FIRED = \"action-hook-fired\";\n-exports.REQUEST_DATA = \"request-data\";\n-exports.UPDATE = \"update\";\n-exports.PANEL_OPEN = \"panel-open\";\n-exports.PANEL_CLOSED = \"panel-closed\";\n-exports.EXPLORER_REQUEST = \"explorer-request\";\n-exports.EXPLORER_RESPONSE = \"explorer-response\";\n-exports.RELOADING_TAB = \"reloading-tab\";\n-exports.RELOAD_TAB_COMPLETE = \"reload-tab-complete\";\n+exports.CLIENT_FOUND = \"ac-devtools:client-found\";\n+exports.REQUEST_TAB_ID = \"ac-devtools:request-tab-id\";\n+exports.DEVTOOLS_INITIALIZED = \"ac-devtools:devtools-initialized\";\n+exports.FIND_APOLLO_CLIENT = \"ac-devtools:find-apollo-client\";\n+exports.APOLLO_CLIENT_FOUND = \"ac-devtools:apollo-client-found\";\n+exports.CREATE_DEVTOOLS_PANEL = \"ac-devtools:create-devtools-panel\";\n+exports.ACTION_HOOK_FIRED = \"ac-devtools:action-hook-fired\";\n+exports.REQUEST_DATA = \"ac-devtools:request-data\";\n+exports.UPDATE = \"ac-devtools:update\";\n+exports.PANEL_OPEN = \"ac-devtools:panel-open\";\n+exports.PANEL_CLOSED = \"ac-devtools:panel-closed\";\n+exports.EXPLORER_REQUEST = \"ac-devtools:explorer-request\";\n+exports.EXPLORER_RESPONSE = \"ac-devtools:explorer-response\";\n+exports.RELOADING_TAB = \"ac-devtools:reloading-tab\";\n+exports.RELOAD_TAB_COMPLETE = \"ac-devtools:reload-tab-complete\";\n \n \n /***/ }),\n@@ -260,22 +260,22 @@ __webpack_require__(/*! ./tabRelay */ \"./src/extension/tab/tabRelay.ts\");\n   A common workaround for this issue is to inject an inlined function\n   into the inspected tab.\n */\n-if (typeof document === \"object\" && document instanceof HTMLDocument) {\n-    const script = document.createElement(\"script\");\n-    script.setAttribute(\"type\", \"module\");\n-    script.setAttribute(\"src\", chrome.extension.getURL(\"hook.js\"));\n-    document.addEventListener(\"DOMContentLoaded\", () => {\n-        var _a;\n-        const importMap = document.querySelector(\"script[type=\\\"importmap\\\"]\");\n-        if (importMap != null) {\n-            (_a = importMap.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(script, importMap.nextSibling);\n-        }\n-        else {\n-            const head = document.head || document.getElementsByTagName(\"head\")[0] || document.documentElement;\n-            head.insertBefore(script, head.lastChild);\n-        }\n-    });\n-}\n+// if (typeof document === \"object\" && document instanceof HTMLDocument) {\n+//     const script = document.createElement(\"script\");\n+//     script.setAttribute(\"type\", \"module\");\n+//     script.setAttribute(\"src\", chrome.extension.getURL(\"hook.js\"));\n+//     document.addEventListener(\"DOMContentLoaded\", () => {\n+//         var _a;\n+//         const importMap = document.querySelector(\"script[type=\\\"importmap\\\"]\");\n+//         if (importMap != null) {\n+//             (_a = importMap.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(script, importMap.nextSibling);\n+//         }\n+//         else {\n+//             const head = document.head || document.getElementsByTagName(\"head\")[0] || document.documentElement;\n+//             head.insertBefore(script, head.lastChild);\n+//         }\n+//     });\n+// }\n \n })();\n \n"
  },
  {
    "path": "patches/electron-gh-releases+2.0.4.patch",
    "content": "diff --git a/node_modules/electron-gh-releases/GhReleases.js b/node_modules/electron-gh-releases/GhReleases.js\nindex cabe3b9..5ce1e2c 100644\n--- a/node_modules/electron-gh-releases/GhReleases.js\n+++ b/node_modules/electron-gh-releases/GhReleases.js\n@@ -103,7 +103,7 @@ var GhReleases = function (_events$EventEmitter) {\n       }\n \n       // On Mac we need to use the `auto_updater.json`\n-      feedUrl = 'https://raw.githubusercontent.com/' + this.repo + '/master/auto_updater.json';\n+      feedUrl = 'https://raw.githubusercontent.com/' + this.repo + '/master/auto_update.json';\n \n       // Make sure feedUrl exists\n       return got.get(feedUrl).then(function (res) {\n"
  },
  {
    "path": "patches/react-dev-utils+4.2.3.patch",
    "content": "diff --git a/node_modules/react-dev-utils/launchEditor.js b/node_modules/react-dev-utils/launchEditor.js\nindex 3bb1d55..b78289e 100644\n--- a/node_modules/react-dev-utils/launchEditor.js\n+++ b/node_modules/react-dev-utils/launchEditor.js\n@@ -10,7 +10,7 @@ const fs = require('fs');\n const path = require('path');\n const child_process = require('child_process');\n const os = require('os');\n-const chalk = require('chalk');\n+const chalk = {red:f=>f,cyan:f=>f,green:f=>f};\n const shellQuote = require('shell-quote');\n \n function isTerminalEditor(editor) {\n"
  },
  {
    "path": "scripts/config.json",
    "content": "{\n  \"dest\": \"release/\",\n  \"icon\": \"electron/logo.ico\",\n  \"categories\": [\"Utility\"],\n  \"lintianOverrides\": [\"changelog-file-missing-in-native-package\"],\n  \"mimeType\": [\"x-scheme-handler/rndebugger\"]\n}\n"
  },
  {
    "path": "scripts/mac/createDMG.js",
    "content": "const path = require('path')\nconst createDMG = require('electron-installer-dmg')\nconst pkg = require('../../package.json')\n\nconst appPath = path.join(__dirname, '../../release/React Native Debugger.app')\n\ncreateDMG(\n  {\n    appPath,\n    name: 'React Native Debugger',\n    title: 'React Native Debugger',\n    // https://github.com/sindresorhus/create-dmg/tree/master/assets\n    background: path.join(__dirname, 'dmg-background.png'),\n    icon: path.join(__dirname, '../../electron/logo.icns'),\n    overwrite: true,\n    contents: [\n      {\n        x: 180,\n        y: 170,\n        type: 'file',\n        path: appPath,\n      },\n      {\n        x: 480,\n        y: 170,\n        type: 'link',\n        path: '/Applications',\n      },\n    ],\n    dmgPath: path.join(\n      __dirname,\n      `../../release/react-native-debugger_${pkg.version}_universal.dmg`,\n    ),\n  },\n  (err) => {\n    if (err) console.log(err)\n  },\n)\n"
  },
  {
    "path": "scripts/mac/createUniversalApp.js",
    "content": "const path = require('path')\nconst { version: electronVersion } = require('electron/package.json')\nconst { makeUniversalApp } = require('@electron/universal')\nconst { signAsync } = require('@electron/osx-sign')\nconst { notarize } = require('@electron/notarize')\n\nconst isNotarizeNeeded = process.argv.includes('--notarize')\n\nconst developerId = `${process.env.APPLE_DEVELOPER_NAME} (${process.env.APPLE_TEAM_ID})`\n\nasync function run() {\n  const appPath = path.join(\n    __dirname,\n    '../../release/React Native Debugger.app',\n  )\n  const x64AppPath = path.join(\n    __dirname,\n    '../../release/React Native Debugger-darwin-x64/React Native Debugger.app',\n  )\n  const arm64AppPath = path.join(\n    __dirname,\n    '../../release/React Native Debugger-darwin-arm64/React Native Debugger.app',\n  )\n  await makeUniversalApp({\n    force: true,\n    x64AppPath,\n    arm64AppPath,\n    outAppPath: appPath,\n  })\n\n  if (!isNotarizeNeeded) return\n\n  const pathes = [appPath, x64AppPath, arm64AppPath]\n  await pathes.reduce(async (promise, p) => {\n    await promise\n    try {\n      await signAsync({\n        app: p,\n        identity: `Developer ID Application: ${developerId}`,\n        optionsForFile: () => ({\n          hardenedRuntime: true,\n          entitlements: 'scripts/mac/entitlements.plist',\n        }),\n        platform: 'darwin',\n        version: electronVersion,\n      })\n      await notarize({\n        tool: 'notarytool',\n        // xcrun notarytool store-credentials \"AC_PASSWORD\"\n        //  --apple-id \"xxx\" --team-id \"xxx\" --password \"<app-specific-password>\"\n        keychainProfile: 'AC_PASSWORD',\n        appPath: p,\n      })\n    } catch (e) {\n      console.log(e)\n    }\n  }, Promise.resolve())\n}\n\nrun()\n"
  },
  {
    "path": "scripts/mac/entitlements.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>com.apple.security.cs.allow-jit</key><true/>\n    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>\n    <key>com.apple.security.cs.disable-library-validation</key><true/>\n    <key>com.apple.security.cs.disable-executable-page-protection</key><true/>\n  </dict>\n</plist>"
  },
  {
    "path": "scripts/package-linux.sh",
    "content": "#!/bin/bash\n\nPACKAGE_VERSION=$(node -e \"console.log(require('./package.json').version)\")\n\necho \"[v$PACKAGE_VERSION] Packaging linux x64...\"\n\n# cp apollo-client-devtools/build to ac-devtools-ext\ncp -r dist/node_modules/apollo-client-devtools/build dist/node_modules/apollo-client-devtools/ac-devtools-ext-build\n\nelectron-packager dist/ \\\n  --executable-name \"react-native-debugger\" \\\n  --overwrite \\\n  --platform linux \\\n  --arch x64 \\\n  --asar \\\n  --extra-resource=dist/devtools-helper \\\n  --extra-resource=dist/node_modules/apollo-client-devtools/ac-devtools-ext-build \\\n  --prune \\\n  --out release \\\n  --electron-version $(node -e \"console.log(require('electron/package').version)\") \\\n  --app-version $PACKAGE_VERSION\n\nelectron-installer-debian --src release/React\\ Native\\ Debugger-linux-x64 --dest release/ --arch amd64 --config scripts/config.json\nelectron-installer-redhat --src release/React\\ Native\\ Debugger-linux-x64 --dest release/ --arch amd64 --config scripts/config.json\n\ncd release/React\\ Native\\ Debugger-linux-x64\nzip -ryq9 ../rn-debugger-linux-x64.zip *\n"
  },
  {
    "path": "scripts/package-macos.sh",
    "content": "#!/bin/bash\n\nPACKAGE_VERSION=$(node -e \"console.log(require('./package.json').version)\")\n\necho \"[v$PACKAGE_VERSION] Packaging darwin x64...\"\n\n# Check arg no-notarize\nif [ \"$1\" == \"--notarize\" ]; then\n  NOTARIZE=1\nfi\n\nif [ \"$NOTARIZE\" == \"1\" ]; then\n  if [ -z \"$APPLE_DEVELOPER_NAME\" ]; then\n    echo -e \"Apple Developer Name: \\c\"\n    read APPLE_DEVELOPER_NAME\n  fi\n\n  if [ -z \"$APPLE_TEAM_ID\" ]; then\n    echo -e \"Apple Team ID: \\c\"\n    read APPLE_TEAM_ID\n  fi\nfi\n\n# cp apollo-client-devtools/build to ac-devtools-ext\ncp -r dist/node_modules/apollo-client-devtools/build dist/node_modules/apollo-client-devtools/ac-devtools-ext-build\n\nfunction build_with_arch() {\n  electron-packager dist/ \\\n    --overwrite \\\n    --platform darwin \\\n    --arch $1 \\\n    --asar \\\n    --extra-resource=dist/devtools-helper \\\n    --extra-resource=dist/node_modules/apollo-client-devtools/ac-devtools-ext-build \\\n    --prune \\\n    --out release \\\n    --protocol-name \"React Native Debugger\" \\\n    --protocol \"rndebugger\" \\\n    --electron-version $(node -e \"console.log(require('electron/package').version)\") \\\n    --app-version $PACKAGE_VERSION \\\n    --icon electron/logo.icns \\\n    --darwin-dark-mode-support\n}\n\nbuild_with_arch x64\nbuild_with_arch arm64\n\nif [ \"$NOTARIZE\" == \"1\" ]; then\n  node scripts/mac/createUniversalApp.js --notarize\nelse\n  node scripts/mac/createUniversalApp.js\nfi\n\nnode scripts/mac/createDMG.js\n\ncd release\nditto -c -k --keepParent React\\ Native\\ Debugger.app rn-debugger-macos-universal.zip\ncd React\\ Native\\ Debugger-darwin-arm64\nditto -c -k --keepParent React\\ Native\\ Debugger.app ../rn-debugger-macos-arm64.zip \ncd ../React\\ Native\\ Debugger-darwin-x64\nditto -c -k --keepParent React\\ Native\\ Debugger.app ../rn-debugger-macos-x64.zip\ncd ..\n\n# Print codesign information\ncodesign -dv --verbose=4 React\\ Native\\ Debugger.app\n\necho sha256: `shasum -a 256 rn-debugger-macos-universal.zip`\n"
  },
  {
    "path": "scripts/package-windows.sh",
    "content": "#!/bin/bash\n\nPACKAGE_VERSION=$(node -e \"console.log(require('./package.json').version)\")\n\necho \"[v$PACKAGE_VERSION] Packaging win32...\"\n\n# cp apollo-client-devtools/build to ac-devtools-ext\ncp -r dist/node_modules/apollo-client-devtools/build dist/node_modules/apollo-client-devtools/ac-devtools-ext-build\n\nelectron-packager dist/ \\\n  --executable-name \"react-native-debugger\" \\\n  --overwrite \\\n  --platform win32 \\\n  --arch x64 \\\n  --asar \\\n  --extra-resource=dist/devtools-helper \\\n  --extra-resource=dist/node_modules/apollo-client-devtools/ac-devtools-ext-build \\\n  --prune \\\n  --out release \\\n  --electron-version $(node -e \"console.log(require('electron/package').version)\") \\\n  --app-version $PACKAGE_VERSION \\\n  --icon electron/logo.ico\n\nelectron-installer-windows --src release/React\\ Native\\ Debugger-win32-x64 --dest release/ --config scripts/config.json\n\ncd release/React\\ Native\\ Debugger-win32-x64\nnpx bestzip ../rn-debugger-windows-x64.zip *\n"
  },
  {
    "path": "scripts/patch-modules.js",
    "content": "const shell = require('shelljs')\nconst path = require('path')\n\nconsole.log('Patch react-devtools-core')\n\nconst rdStandalone = path.join(\n  __dirname,\n  '../dist/node_modules/react-devtools-core/dist/standalone.js',\n)\n\n// Avoid source map not found warning\nshell.sed(\n  '-i',\n  /sourceMappingURL=importFile\\.worker\\.worker\\.js\\.map'\\]\\)\\),\\{name:\"\\[name\\]\\.worker\\.js/g,\n  `sourceMappingURL_NotUsed=importFile.worker.worker.js.map'])),{name:\"ReactDevToolsImportFile.worker.js`,\n  rdStandalone,\n)\n"
  },
  {
    "path": "scripts/postinstall.js",
    "content": "const shell = require('shelljs')\n\nasync function run() {\n  shell.cd('npm-package')\n  shell.exec('yarn')\n  shell.cd('-')\n  shell.cd('dist')\n  shell.exec('yarn')\n  shell.rm(\n    '-rf',\n    'node_modules/*/{example,examples,test,tests,*.md,*.markdown,CHANGELOG*,.*,Makefile}',\n  )\n  // Remove unnecessary files in apollo-client-devtools\n  shell.rm(\n    '-rf',\n    'node_modules/apollo-client-devtools/{assets,development/dev,src}',\n  )\n  // eslint-disable-next-line\n  require('./patch-modules')\n}\n\nrun()\n"
  },
  {
    "path": "webpack/.eslintrc",
    "content": "{\n  \"rules\": {\n    \"import/no-extraneous-dependencies\": 0\n  }\n}"
  },
  {
    "path": "webpack/base.js",
    "content": "const path = require('path')\nconst electronPkg = require('electron/package.json')\nconst babelConfig = require('../babel.config')({ cache: () => {} })\n\n// Webpack 2 have native import / export support\nbabelConfig.presets = [\n  [\n    '@babel/preset-env',\n    {\n      targets: { electron: electronPkg.version },\n      modules: false,\n    },\n  ],\n  '@babel/preset-react',\n]\nbabelConfig.babelrc = false\n\nmodule.exports = {\n  output: {\n    path: path.join(__dirname, '../dist/js'),\n    filename: 'bundle.js',\n    libraryTarget: 'commonjs2',\n  },\n  plugins: [],\n  resolve: {\n    extensions: ['.js'],\n    alias: {},\n  },\n  module: {\n    rules: [\n      {\n        test: /\\.js$/,\n        use: [\n          {\n            loader: 'babel-loader',\n            options: babelConfig,\n          },\n        ],\n        exclude: /node_modules/,\n      },\n    ],\n  },\n  externals: [\n    'react-devtools-core/standalone',\n    // https://github.com/sindresorhus/conf/blob/master/index.js#L13\n    'electron-store',\n    'adbkit',\n    'electron-named-image',\n  ],\n}\n"
  },
  {
    "path": "webpack/main.prod.js",
    "content": "const path = require('path')\nconst webpack = require('webpack')\nconst TerserPlugin = require('terser-webpack-plugin')\nconst baseConfig = require('./base')\n\nmodule.exports = {\n  ...baseConfig,\n  mode: 'production',\n  devtool: 'hidden-source-map',\n  entry: './electron/main',\n  output: {\n    ...baseConfig.output,\n    path: path.join(__dirname, '../dist'),\n    filename: './main.js',\n  },\n  plugins: [\n    new webpack.DefinePlugin({\n      'process.env.NODE_ENV': JSON.stringify('production'),\n    }),\n    new webpack.optimize.ModuleConcatenationPlugin(),\n  ],\n  optimization: {\n    minimize: true,\n    minimizer: [\n      new TerserPlugin({\n        terserOptions: { output: { comments: false } },\n      }),\n    ],\n  },\n  target: 'electron-main',\n  node: {\n    __dirname: false,\n    __filename: false,\n  },\n}\n"
  },
  {
    "path": "webpack/renderer.dev.js",
    "content": "const webpack = require('webpack')\nconst baseConfig = require('./base')\n\nconst port = 3000\n\nconst baseDevConfig = {\n  ...baseConfig,\n  mode: 'development',\n  devtool: 'inline-source-map',\n  output: {\n    ...baseConfig.output,\n    publicPath: `http://localhost:${port}/js/`,\n  },\n  module: {\n    rules: [\n      ...baseConfig.module.rules,\n      {\n        test: /\\.css?$/,\n        use: ['style-loader', 'css-loader'],\n      },\n    ],\n  },\n  plugins: [\n    ...baseConfig.plugins,\n    new webpack.DefinePlugin({\n      'process.env.NODE_ENV': JSON.stringify('development'),\n    }),\n  ],\n}\n\nconst buildDevConfig = (config) => ({\n  ...baseDevConfig,\n  ...config,\n})\n\nmodule.exports = [\n  buildDevConfig({\n    entry: './app/index',\n    target: 'electron-renderer',\n  }),\n  buildDevConfig({\n    entry: './app/worker/index.js',\n    resolve: {\n      ...baseDevConfig.resolve,\n      aliasFields: ['browser'],\n    },\n    output: {\n      ...baseDevConfig.output,\n      filename: 'RNDebuggerWorker.js',\n      libraryTarget: undefined,\n    },\n    target: 'webworker',\n  }),\n]\n"
  },
  {
    "path": "webpack/renderer.prod.js",
    "content": "const webpack = require('webpack')\nconst TerserPlugin = require('terser-webpack-plugin')\nconst { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')\nconst baseConfig = require('./base')\n\nconst baseProdConfig = {\n  ...baseConfig,\n  mode: 'production',\n  devtool: 'hidden-source-map',\n  output: {\n    ...baseConfig.output,\n    publicPath: 'js/',\n  },\n  module: {\n    rules: [\n      ...baseConfig.module.rules,\n      {\n        test: /\\.css?$/,\n        use: ['style-loader', 'css-loader'],\n      },\n    ],\n  },\n  plugins: [\n    ...baseConfig.plugins,\n    new webpack.DefinePlugin({\n      'process.env.NODE_ENV': JSON.stringify('production'),\n      __REACT_DEVTOOLS_GLOBAL_HOOK__: 'false',\n    }),\n    new webpack.optimize.ModuleConcatenationPlugin(),\n  ],\n  optimization: {\n    minimize: true,\n    minimizer: [\n      new TerserPlugin({\n        terserOptions: { output: { comments: false } },\n      }),\n    ],\n  },\n}\n\nconst buildProdConfig = (config) => ({\n  ...baseProdConfig,\n  ...config,\n})\n\nmodule.exports = [\n  buildProdConfig({\n    entry: './app/index',\n    target: 'electron-renderer',\n    plugins: [\n      ...baseProdConfig.plugins,\n      process.env.ANALYZE_BUNDLE ? new BundleAnalyzerPlugin() : null,\n    ].filter(Boolean),\n  }),\n  buildProdConfig({\n    entry: './app/worker/index.js',\n    resolve: {\n      ...baseProdConfig.resolve,\n      aliasFields: ['browser'],\n    },\n    output: {\n      ...baseProdConfig.output,\n      filename: 'RNDebuggerWorker.js',\n      libraryTarget: undefined,\n    },\n    target: 'webworker',\n  }),\n]\n"
  }
]