[
  {
    "path": ".gitattributes",
    "content": "/.yarn/**            linguist-vendored\n/.yarn/releases/*    binary\n/.yarn/plugins/**/*  binary\n/.pnp.*              binary linguist-generated\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"npm\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\n\non:\n    workflow_dispatch:\n    push:\n\njobs:\n    build:\n        runs-on: ubuntu-latest\n        permissions:\n            contents: write\n        steps:\n            - uses: actions/checkout@v3\n\n            - name: Use Node.js\n              uses: actions/setup-node@v3\n              with:\n                  node-version: 18.x\n\n            - name: Setup Corepack\n              run: corepack enable\n\n            - name: Cache Yarn dependencies\n              id: yarn-cache\n              uses: actions/cache@v3\n              with:\n                  path: |\n                      .yarn/cache\n                      .yarn/unplugged\n                      .yarn/install-state.gz\n                      .pnp.cjs\n                  key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}\n                  restore-keys: |\n                      ${{ runner.os }}-yarn-\n\n            - name: Install Yarn dependencies\n              run: yarn install\n\n            - name: Build\n              run: yarn build:linux\n\n            - name: Compress files\n              run: |\n                  mkdir upload\n                  pushd dist\n                  tar -zcvf ../upload/qqntim-build.tar.gz . \n                  zip -r9 ../upload/qqntim-build.zip .\n                  popd\n\n            - name: Upload artifact\n              uses: actions/upload-artifact@v3\n              with:\n                  name: build\n                  path: upload/*\n\n            - name: Create release\n              if: github.ref_type == 'tag'\n              uses: softprops/action-gh-release@v1\n              with:\n                  files: upload/*\n                  generate_release_notes: true\n                  tag_name: ${{ github.ref_name }}\n                  prerelease: ${{ endsWith(github.ref_name, 'alpha') }}\n                  draft: false\n                  name: ${{ github.ref_name }}\n\n            - name: Setup .yarnrc.yml\n              if: github.ref_type == 'tag'\n              run: |\n                  yarn config set npmRegistryServer https://registry.npmjs.org\n                  yarn config set npmAlwaysAuth true\n                  yarn config set npmAuthToken $NPM_AUTH_TOKEN\n              env:\n                  NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n\n            - name: Publish NPM Package\n              if: github.ref_type == 'tag'\n              run: yarn workspace @flysoftbeta/qqntim-typings npm publish\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n.pnpm-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Snowpack dependency directory (https://snowpack.dev/)\nweb_modules/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional stylelint cache\n.stylelintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\nout\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# vuepress v2.x temp and cache directory\n.temp\n.cache\n\n# Docusaurus cache and generated files\n.docusaurus\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/sdks\n!.yarn/versions\n\n# Swap the comments on the following lines if you don't wish to use zero-installs\n# Documentation here: https://yarnpkg.com/features/zero-installs\n# !.yarn/cache\n.pnp.*\n\ntest.sh"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n    \"recommendations\": [\"arcanis.vscode-zipfs\"]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"search.exclude\": {\n        \"**/.yarn\": true,\n        \"**/.pnp.*\": true\n    },\n    \"typescript.tsdk\": \".yarn/sdks/typescript/lib\",\n    \"typescript.enablePromptUseWorkspaceTsdk\": true\n}\n"
  },
  {
    "path": ".yarn/sdks/integrations.yml",
    "content": "# This file is automatically generated by @yarnpkg/sdks.\n# Manual changes might be lost!\n\nintegrations:\n  - vscode\n"
  },
  {
    "path": ".yarn/sdks/typescript/bin/tsc",
    "content": "#!/usr/bin/env node\n\nconst {existsSync} = require(`fs`);\nconst {createRequire} = require(`module`);\nconst {resolve} = require(`path`);\n\nconst relPnpApiPath = \"../../../../.pnp.cjs\";\n\nconst absPnpApiPath = resolve(__dirname, relPnpApiPath);\nconst absRequire = createRequire(absPnpApiPath);\n\nif (existsSync(absPnpApiPath)) {\n  if (!process.versions.pnp) {\n    // Setup the environment to be able to require typescript/bin/tsc\n    require(absPnpApiPath).setup();\n  }\n}\n\n// Defer to the real typescript/bin/tsc your application uses\nmodule.exports = absRequire(`typescript/bin/tsc`);\n"
  },
  {
    "path": ".yarn/sdks/typescript/bin/tsserver",
    "content": "#!/usr/bin/env node\n\nconst {existsSync} = require(`fs`);\nconst {createRequire} = require(`module`);\nconst {resolve} = require(`path`);\n\nconst relPnpApiPath = \"../../../../.pnp.cjs\";\n\nconst absPnpApiPath = resolve(__dirname, relPnpApiPath);\nconst absRequire = createRequire(absPnpApiPath);\n\nif (existsSync(absPnpApiPath)) {\n  if (!process.versions.pnp) {\n    // Setup the environment to be able to require typescript/bin/tsserver\n    require(absPnpApiPath).setup();\n  }\n}\n\n// Defer to the real typescript/bin/tsserver your application uses\nmodule.exports = absRequire(`typescript/bin/tsserver`);\n"
  },
  {
    "path": ".yarn/sdks/typescript/lib/tsc.js",
    "content": "#!/usr/bin/env node\n\nconst {existsSync} = require(`fs`);\nconst {createRequire} = require(`module`);\nconst {resolve} = require(`path`);\n\nconst relPnpApiPath = \"../../../../.pnp.cjs\";\n\nconst absPnpApiPath = resolve(__dirname, relPnpApiPath);\nconst absRequire = createRequire(absPnpApiPath);\n\nif (existsSync(absPnpApiPath)) {\n  if (!process.versions.pnp) {\n    // Setup the environment to be able to require typescript/lib/tsc.js\n    require(absPnpApiPath).setup();\n  }\n}\n\n// Defer to the real typescript/lib/tsc.js your application uses\nmodule.exports = absRequire(`typescript/lib/tsc.js`);\n"
  },
  {
    "path": ".yarn/sdks/typescript/lib/tsserver.js",
    "content": "#!/usr/bin/env node\n\nconst {existsSync} = require(`fs`);\nconst {createRequire} = require(`module`);\nconst {resolve} = require(`path`);\n\nconst relPnpApiPath = \"../../../../.pnp.cjs\";\n\nconst absPnpApiPath = resolve(__dirname, relPnpApiPath);\nconst absRequire = createRequire(absPnpApiPath);\n\nconst moduleWrapper = tsserver => {\n  if (!process.versions.pnp) {\n    return tsserver;\n  }\n\n  const {isAbsolute} = require(`path`);\n  const pnpApi = require(`pnpapi`);\n\n  const isVirtual = str => str.match(/\\/(\\$\\$virtual|__virtual__)\\//);\n  const isPortal = str => str.startsWith(\"portal:/\");\n  const normalize = str => str.replace(/\\\\/g, `/`).replace(/^\\/?/, `/`);\n\n  const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {\n    return `${locator.name}@${locator.reference}`;\n  }));\n\n  // VSCode sends the zip paths to TS using the \"zip://\" prefix, that TS\n  // doesn't understand. This layer makes sure to remove the protocol\n  // before forwarding it to TS, and to add it back on all returned paths.\n\n  function toEditorPath(str) {\n    // We add the `zip:` prefix to both `.zip/` paths and virtual paths\n    if (isAbsolute(str) && !str.match(/^\\^?(zip:|\\/zip\\/)/) && (str.match(/\\.zip\\//) || isVirtual(str))) {\n      // We also take the opportunity to turn virtual paths into physical ones;\n      // this makes it much easier to work with workspaces that list peer\n      // dependencies, since otherwise Ctrl+Click would bring us to the virtual\n      // file instances instead of the real ones.\n      //\n      // We only do this to modules owned by the the dependency tree roots.\n      // This avoids breaking the resolution when jumping inside a vendor\n      // with peer dep (otherwise jumping into react-dom would show resolution\n      // errors on react).\n      //\n      const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;\n      if (resolved) {\n        const locator = pnpApi.findPackageLocator(resolved);\n        if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {\n          str = resolved;\n        }\n      }\n\n      str = normalize(str);\n\n      if (str.match(/\\.zip\\//)) {\n        switch (hostInfo) {\n          // Absolute VSCode `Uri.fsPath`s need to start with a slash.\n          // VSCode only adds it automatically for supported schemes,\n          // so we have to do it manually for the `zip` scheme.\n          // The path needs to start with a caret otherwise VSCode doesn't handle the protocol\n          //\n          // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910\n          //\n          // 2021-10-08: VSCode changed the format in 1.61.\n          // Before | ^zip:/c:/foo/bar.zip/package.json\n          // After  | ^/zip//c:/foo/bar.zip/package.json\n          //\n          // 2022-04-06: VSCode changed the format in 1.66.\n          // Before | ^/zip//c:/foo/bar.zip/package.json\n          // After  | ^/zip/c:/foo/bar.zip/package.json\n          //\n          // 2022-05-06: VSCode changed the format in 1.68\n          // Before | ^/zip/c:/foo/bar.zip/package.json\n          // After  | ^/zip//c:/foo/bar.zip/package.json\n          //\n          case `vscode <1.61`: {\n            str = `^zip:${str}`;\n          } break;\n\n          case `vscode <1.66`: {\n            str = `^/zip/${str}`;\n          } break;\n\n          case `vscode <1.68`: {\n            str = `^/zip${str}`;\n          } break;\n\n          case `vscode`: {\n            str = `^/zip/${str}`;\n          } break;\n\n          // To make \"go to definition\" work,\n          // We have to resolve the actual file system path from virtual path\n          // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)\n          case `coc-nvim`: {\n            str = normalize(resolved).replace(/\\.zip\\//, `.zip::`);\n            str = resolve(`zipfile:${str}`);\n          } break;\n\n          // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)\n          // We have to resolve the actual file system path from virtual path,\n          // everything else is up to neovim\n          case `neovim`: {\n            str = normalize(resolved).replace(/\\.zip\\//, `.zip::`);\n            str = `zipfile://${str}`;\n          } break;\n\n          default: {\n            str = `zip:${str}`;\n          } break;\n        }\n      } else {\n        str = str.replace(/^\\/?/, process.platform === `win32` ? `` : `/`);\n      }\n    }\n\n    return str;\n  }\n\n  function fromEditorPath(str) {\n    switch (hostInfo) {\n      case `coc-nvim`: {\n        str = str.replace(/\\.zip::/, `.zip/`);\n        // The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...\n        // So in order to convert it back, we use .* to match all the thing\n        // before `zipfile:`\n        return process.platform === `win32`\n          ? str.replace(/^.*zipfile:\\//, ``)\n          : str.replace(/^.*zipfile:/, ``);\n      } break;\n\n      case `neovim`: {\n        str = str.replace(/\\.zip::/, `.zip/`);\n        // The path for neovim is in format of zipfile:///<pwd>/.yarn/...\n        return str.replace(/^zipfile:\\/\\//, ``);\n      } break;\n\n      case `vscode`:\n      default: {\n        return str.replace(/^\\^?(zip:|\\/zip(\\/ts-nul-authority)?)\\/+/, process.platform === `win32` ? `` : `/`)\n      } break;\n    }\n  }\n\n  // Force enable 'allowLocalPluginLoads'\n  // TypeScript tries to resolve plugins using a path relative to itself\n  // which doesn't work when using the global cache\n  // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238\n  // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but\n  // TypeScript already does local loads and if this code is running the user trusts the workspace\n  // https://github.com/microsoft/vscode/issues/45856\n  const ConfiguredProject = tsserver.server.ConfiguredProject;\n  const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;\n  ConfiguredProject.prototype.enablePluginsWithOptions = function() {\n    this.projectService.allowLocalPluginLoads = true;\n    return originalEnablePluginsWithOptions.apply(this, arguments);\n  };\n\n  // And here is the point where we hijack the VSCode <-> TS communications\n  // by adding ourselves in the middle. We locate everything that looks\n  // like an absolute path of ours and normalize it.\n\n  const Session = tsserver.server.Session;\n  const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;\n  let hostInfo = `unknown`;\n\n  Object.assign(Session.prototype, {\n    onMessage(/** @type {string | object} */ message) {\n      const isStringMessage = typeof message === 'string';\n      const parsedMessage = isStringMessage ? JSON.parse(message) : message;\n\n      if (\n        parsedMessage != null &&\n        typeof parsedMessage === `object` &&\n        parsedMessage.arguments &&\n        typeof parsedMessage.arguments.hostInfo === `string`\n      ) {\n        hostInfo = parsedMessage.arguments.hostInfo;\n        if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {\n          const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(\n            // The RegExp from https://semver.org/ but without the caret at the start\n            /(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/\n          ) ?? []).map(Number)\n\n          if (major === 1) {\n            if (minor < 61) {\n              hostInfo += ` <1.61`;\n            } else if (minor < 66) {\n              hostInfo += ` <1.66`;\n            } else if (minor < 68) {\n              hostInfo += ` <1.68`;\n            }\n          }\n        }\n      }\n\n      const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {\n        return typeof value === 'string' ? fromEditorPath(value) : value;\n      });\n\n      return originalOnMessage.call(\n        this,\n        isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)\n      );\n    },\n\n    send(/** @type {any} */ msg) {\n      return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {\n        return typeof value === `string` ? toEditorPath(value) : value;\n      })));\n    }\n  });\n\n  return tsserver;\n};\n\nif (existsSync(absPnpApiPath)) {\n  if (!process.versions.pnp) {\n    // Setup the environment to be able to require typescript/lib/tsserver.js\n    require(absPnpApiPath).setup();\n  }\n}\n\n// Defer to the real typescript/lib/tsserver.js your application uses\nmodule.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`));\n"
  },
  {
    "path": ".yarn/sdks/typescript/lib/tsserverlibrary.js",
    "content": "#!/usr/bin/env node\n\nconst {existsSync} = require(`fs`);\nconst {createRequire} = require(`module`);\nconst {resolve} = require(`path`);\n\nconst relPnpApiPath = \"../../../../.pnp.cjs\";\n\nconst absPnpApiPath = resolve(__dirname, relPnpApiPath);\nconst absRequire = createRequire(absPnpApiPath);\n\nconst moduleWrapper = tsserver => {\n  if (!process.versions.pnp) {\n    return tsserver;\n  }\n\n  const {isAbsolute} = require(`path`);\n  const pnpApi = require(`pnpapi`);\n\n  const isVirtual = str => str.match(/\\/(\\$\\$virtual|__virtual__)\\//);\n  const isPortal = str => str.startsWith(\"portal:/\");\n  const normalize = str => str.replace(/\\\\/g, `/`).replace(/^\\/?/, `/`);\n\n  const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {\n    return `${locator.name}@${locator.reference}`;\n  }));\n\n  // VSCode sends the zip paths to TS using the \"zip://\" prefix, that TS\n  // doesn't understand. This layer makes sure to remove the protocol\n  // before forwarding it to TS, and to add it back on all returned paths.\n\n  function toEditorPath(str) {\n    // We add the `zip:` prefix to both `.zip/` paths and virtual paths\n    if (isAbsolute(str) && !str.match(/^\\^?(zip:|\\/zip\\/)/) && (str.match(/\\.zip\\//) || isVirtual(str))) {\n      // We also take the opportunity to turn virtual paths into physical ones;\n      // this makes it much easier to work with workspaces that list peer\n      // dependencies, since otherwise Ctrl+Click would bring us to the virtual\n      // file instances instead of the real ones.\n      //\n      // We only do this to modules owned by the the dependency tree roots.\n      // This avoids breaking the resolution when jumping inside a vendor\n      // with peer dep (otherwise jumping into react-dom would show resolution\n      // errors on react).\n      //\n      const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;\n      if (resolved) {\n        const locator = pnpApi.findPackageLocator(resolved);\n        if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {\n          str = resolved;\n        }\n      }\n\n      str = normalize(str);\n\n      if (str.match(/\\.zip\\//)) {\n        switch (hostInfo) {\n          // Absolute VSCode `Uri.fsPath`s need to start with a slash.\n          // VSCode only adds it automatically for supported schemes,\n          // so we have to do it manually for the `zip` scheme.\n          // The path needs to start with a caret otherwise VSCode doesn't handle the protocol\n          //\n          // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910\n          //\n          // 2021-10-08: VSCode changed the format in 1.61.\n          // Before | ^zip:/c:/foo/bar.zip/package.json\n          // After  | ^/zip//c:/foo/bar.zip/package.json\n          //\n          // 2022-04-06: VSCode changed the format in 1.66.\n          // Before | ^/zip//c:/foo/bar.zip/package.json\n          // After  | ^/zip/c:/foo/bar.zip/package.json\n          //\n          // 2022-05-06: VSCode changed the format in 1.68\n          // Before | ^/zip/c:/foo/bar.zip/package.json\n          // After  | ^/zip//c:/foo/bar.zip/package.json\n          //\n          case `vscode <1.61`: {\n            str = `^zip:${str}`;\n          } break;\n\n          case `vscode <1.66`: {\n            str = `^/zip/${str}`;\n          } break;\n\n          case `vscode <1.68`: {\n            str = `^/zip${str}`;\n          } break;\n\n          case `vscode`: {\n            str = `^/zip/${str}`;\n          } break;\n\n          // To make \"go to definition\" work,\n          // We have to resolve the actual file system path from virtual path\n          // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)\n          case `coc-nvim`: {\n            str = normalize(resolved).replace(/\\.zip\\//, `.zip::`);\n            str = resolve(`zipfile:${str}`);\n          } break;\n\n          // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)\n          // We have to resolve the actual file system path from virtual path,\n          // everything else is up to neovim\n          case `neovim`: {\n            str = normalize(resolved).replace(/\\.zip\\//, `.zip::`);\n            str = `zipfile://${str}`;\n          } break;\n\n          default: {\n            str = `zip:${str}`;\n          } break;\n        }\n      } else {\n        str = str.replace(/^\\/?/, process.platform === `win32` ? `` : `/`);\n      }\n    }\n\n    return str;\n  }\n\n  function fromEditorPath(str) {\n    switch (hostInfo) {\n      case `coc-nvim`: {\n        str = str.replace(/\\.zip::/, `.zip/`);\n        // The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...\n        // So in order to convert it back, we use .* to match all the thing\n        // before `zipfile:`\n        return process.platform === `win32`\n          ? str.replace(/^.*zipfile:\\//, ``)\n          : str.replace(/^.*zipfile:/, ``);\n      } break;\n\n      case `neovim`: {\n        str = str.replace(/\\.zip::/, `.zip/`);\n        // The path for neovim is in format of zipfile:///<pwd>/.yarn/...\n        return str.replace(/^zipfile:\\/\\//, ``);\n      } break;\n\n      case `vscode`:\n      default: {\n        return str.replace(/^\\^?(zip:|\\/zip(\\/ts-nul-authority)?)\\/+/, process.platform === `win32` ? `` : `/`)\n      } break;\n    }\n  }\n\n  // Force enable 'allowLocalPluginLoads'\n  // TypeScript tries to resolve plugins using a path relative to itself\n  // which doesn't work when using the global cache\n  // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238\n  // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but\n  // TypeScript already does local loads and if this code is running the user trusts the workspace\n  // https://github.com/microsoft/vscode/issues/45856\n  const ConfiguredProject = tsserver.server.ConfiguredProject;\n  const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;\n  ConfiguredProject.prototype.enablePluginsWithOptions = function() {\n    this.projectService.allowLocalPluginLoads = true;\n    return originalEnablePluginsWithOptions.apply(this, arguments);\n  };\n\n  // And here is the point where we hijack the VSCode <-> TS communications\n  // by adding ourselves in the middle. We locate everything that looks\n  // like an absolute path of ours and normalize it.\n\n  const Session = tsserver.server.Session;\n  const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;\n  let hostInfo = `unknown`;\n\n  Object.assign(Session.prototype, {\n    onMessage(/** @type {string | object} */ message) {\n      const isStringMessage = typeof message === 'string';\n      const parsedMessage = isStringMessage ? JSON.parse(message) : message;\n\n      if (\n        parsedMessage != null &&\n        typeof parsedMessage === `object` &&\n        parsedMessage.arguments &&\n        typeof parsedMessage.arguments.hostInfo === `string`\n      ) {\n        hostInfo = parsedMessage.arguments.hostInfo;\n        if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {\n          const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(\n            // The RegExp from https://semver.org/ but without the caret at the start\n            /(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/\n          ) ?? []).map(Number)\n\n          if (major === 1) {\n            if (minor < 61) {\n              hostInfo += ` <1.61`;\n            } else if (minor < 66) {\n              hostInfo += ` <1.66`;\n            } else if (minor < 68) {\n              hostInfo += ` <1.68`;\n            }\n          }\n        }\n      }\n\n      const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {\n        return typeof value === 'string' ? fromEditorPath(value) : value;\n      });\n\n      return originalOnMessage.call(\n        this,\n        isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)\n      );\n    },\n\n    send(/** @type {any} */ msg) {\n      return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {\n        return typeof value === `string` ? toEditorPath(value) : value;\n      })));\n    }\n  });\n\n  return tsserver;\n};\n\nif (existsSync(absPnpApiPath)) {\n  if (!process.versions.pnp) {\n    // Setup the environment to be able to require typescript/lib/tsserverlibrary.js\n    require(absPnpApiPath).setup();\n  }\n}\n\n// Defer to the real typescript/lib/tsserverlibrary.js your application uses\nmodule.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`));\n"
  },
  {
    "path": ".yarn/sdks/typescript/lib/typescript.js",
    "content": "#!/usr/bin/env node\n\nconst {existsSync} = require(`fs`);\nconst {createRequire} = require(`module`);\nconst {resolve} = require(`path`);\n\nconst relPnpApiPath = \"../../../../.pnp.cjs\";\n\nconst absPnpApiPath = resolve(__dirname, relPnpApiPath);\nconst absRequire = createRequire(absPnpApiPath);\n\nif (existsSync(absPnpApiPath)) {\n  if (!process.versions.pnp) {\n    // Setup the environment to be able to require typescript/lib/typescript.js\n    require(absPnpApiPath).setup();\n  }\n}\n\n// Defer to the real typescript/lib/typescript.js your application uses\nmodule.exports = absRequire(`typescript/lib/typescript.js`);\n"
  },
  {
    "path": ".yarn/sdks/typescript/package.json",
    "content": "{\n  \"name\": \"typescript\",\n  \"version\": \"5.0.4-sdk\",\n  \"main\": \"./lib/typescript.js\",\n  \"type\": \"commonjs\"\n}\n"
  },
  {
    "path": "COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "COPYING.LESSER",
    "content": "                   GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\n  This version of the GNU Lesser General Public License incorporates\nthe terms and conditions of version 3 of the GNU General Public\nLicense, supplemented by the additional permissions listed below.\n\n  0. Additional Definitions.\n\n  As used herein, \"this License\" refers to version 3 of the GNU Lesser\nGeneral Public License, and the \"GNU GPL\" refers to version 3 of the GNU\nGeneral Public License.\n\n  \"The Library\" refers to a covered work governed by this License,\nother than an Application or a Combined Work as defined below.\n\n  An \"Application\" is any work that makes use of an interface provided\nby the Library, but which is not otherwise based on the Library.\nDefining a subclass of a class defined by the Library is deemed a mode\nof using an interface provided by the Library.\n\n  A \"Combined Work\" is a work produced by combining or linking an\nApplication with the Library.  The particular version of the Library\nwith which the Combined Work was made is also called the \"Linked\nVersion\".\n\n  The \"Minimal Corresponding Source\" for a Combined Work means the\nCorresponding Source for the Combined Work, excluding any source code\nfor portions of the Combined Work that, considered in isolation, are\nbased on the Application, and not on the Linked Version.\n\n  The \"Corresponding Application Code\" for a Combined Work means the\nobject code and/or source code for the Application, including any data\nand utility programs needed for reproducing the Combined Work from the\nApplication, but excluding the System Libraries of the Combined Work.\n\n  1. Exception to Section 3 of the GNU GPL.\n\n  You may convey a covered work under sections 3 and 4 of this License\nwithout being bound by section 3 of the GNU GPL.\n\n  2. Conveying Modified Versions.\n\n  If you modify a copy of the Library, and, in your modifications, a\nfacility refers to a function or data to be supplied by an Application\nthat uses the facility (other than as an argument passed when the\nfacility is invoked), then you may convey a copy of the modified\nversion:\n\n   a) under this License, provided that you make a good faith effort to\n   ensure that, in the event an Application does not supply the\n   function or data, the facility still operates, and performs\n   whatever part of its purpose remains meaningful, or\n\n   b) under the GNU GPL, with none of the additional permissions of\n   this License applicable to that copy.\n\n  3. Object Code Incorporating Material from Library Header Files.\n\n  The object code form of an Application may incorporate material from\na header file that is part of the Library.  You may convey such object\ncode under terms of your choice, provided that, if the incorporated\nmaterial is not limited to numerical parameters, data structure\nlayouts and accessors, or small macros, inline functions and templates\n(ten or fewer lines in length), you do both of the following:\n\n   a) Give prominent notice with each copy of the object code that the\n   Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the object code with a copy of the GNU GPL and this license\n   document.\n\n  4. Combined Works.\n\n  You may convey a Combined Work under terms of your choice that,\ntaken together, effectively do not restrict modification of the\nportions of the Library contained in the Combined Work and reverse\nengineering for debugging such modifications, if you also do each of\nthe following:\n\n   a) Give prominent notice with each copy of the Combined Work that\n   the Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the Combined Work with a copy of the GNU GPL and this license\n   document.\n\n   c) For a Combined Work that displays copyright notices during\n   execution, include the copyright notice for the Library among\n   these notices, as well as a reference directing the user to the\n   copies of the GNU GPL and this license document.\n\n   d) Do one of the following:\n\n       0) Convey the Minimal Corresponding Source under the terms of this\n       License, and the Corresponding Application Code in a form\n       suitable for, and under terms that permit, the user to\n       recombine or relink the Application with a modified version of\n       the Linked Version to produce a modified Combined Work, in the\n       manner specified by section 6 of the GNU GPL for conveying\n       Corresponding Source.\n\n       1) Use a suitable shared library mechanism for linking with the\n       Library.  A suitable mechanism is one that (a) uses at run time\n       a copy of the Library already present on the user's computer\n       system, and (b) will operate properly with a modified version\n       of the Library that is interface-compatible with the Linked\n       Version.\n\n   e) Provide Installation Information, but only if you would otherwise\n   be required to provide such information under section 6 of the\n   GNU GPL, and only to the extent that such information is\n   necessary to install and execute a modified version of the\n   Combined Work produced by recombining or relinking the\n   Application with a modified version of the Linked Version. (If\n   you use option 4d0, the Installation Information must accompany\n   the Minimal Corresponding Source and Corresponding Application\n   Code. If you use option 4d1, you must provide the Installation\n   Information in the manner specified by section 6 of the GNU GPL\n   for conveying Corresponding Source.)\n\n  5. Combined Libraries.\n\n  You may place library facilities that are a work based on the\nLibrary side by side in a single library together with other library\nfacilities that are not Applications and are not covered by this\nLicense, and convey such a combined library under terms of your\nchoice, if you do both of the following:\n\n   a) Accompany the combined library with a copy of the same work based\n   on the Library, uncombined with any other library facilities,\n   conveyed under the terms of this License.\n\n   b) Give prominent notice with the combined library that part of it\n   is a work based on the Library, and explaining where to find the\n   accompanying uncombined form of the same work.\n\n  6. Revised Versions of the GNU Lesser General Public License.\n\n  The Free Software Foundation may publish revised and/or new versions\nof the GNU Lesser General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\n  Each version is given a distinguishing version number. If the\nLibrary as you received it specifies that a certain numbered version\nof the GNU Lesser General Public License \"or any later version\"\napplies to it, you have the option of following the terms and\nconditions either of that published version or of any later version\npublished by the Free Software Foundation. If the Library as you\nreceived it does not specify a version number of the GNU Lesser\nGeneral Public License, you may choose any version of the GNU Lesser\nGeneral Public License ever published by the Free Software Foundation.\n\n  If the Library as you received it specifies that a proxy can decide\nwhether future versions of the GNU Lesser General Public License shall\napply, that proxy's public statement of acceptance of any version is\npermanent authorization for you to choose that version for the\nLibrary.\n"
  },
  {
    "path": "DEVELOPMENT.md",
    "content": "# 开发文档\n\n此文档包含了插件开发文档（插件清单规范 v2.0）。\n\n**在开始之前，强烈建议你使用我们的[插件模板仓库](https://github.com/Flysoft-Studio/QQNTim-Plugin-Template)进行开发。** 模板仓库已经包含了 TypeScript 类型定义、自动构建及发布等内容，无需手动配置。\n\n## 文件结构\n\n### 数据文件夹\n\n请查看 [使用手册-数据文件夹](MANUAL.md#数据文件夹) 查看默认的数据文件夹路径及其修改方式。\n\n数据文件夹存放了所有插件和设置。\n\n以下是一个结构示意图：\n\n```\nQQNTim\n  ├─ plugins\n  ├─ plugins-user\n  └─ config.json\n```\n\n### `plugins` 文件夹\n\n存放所有插件的文件夹。在此文件夹下的插件**对所有账户都生效**。\n\n以下是一个结构示意图：\n\n```\nplugins\n  ├─ 插件1 (文件夹)\n  │  ├─ qqntim.json\n  │  ├─ renderer.js\n  │  └─ style.css\n  └─ 插件2 (文件夹)\n     ├─ qqntim.json\n     ├─ main.js\n     ├─ renderer.js\n     ├─ example.jpg\n     └─ native.node\n```\n\n### `plugins-user` 文件夹\n\n存放指定账户插件的文件夹。在此文件夹下的插件**只对指定账户生效**。\n\n以下是一个结构示意图：\n\n```\nplugins-user\n  ├─ 10000\n  │  ├─ 插件1\n  │  └─ 插件2\n  └─ 10001\n     └─ ...\n```\n\n### `config.json` 文件\n\n存放 QQNTim 配置的文件。\n\n一个示例配置文件如下所示：\n\n```json\n{\n    // (可选) 插件加载相关设置\n    \"plugins\": {\n        // 插件加载黑、白名单\n        // (应指定插件的 ID，可以在插件的 qqntim.json 内的 id 栏查看)\n        // ----------------------------------------------------\n        // (string[] 可选) 插件加载白名单\n        \"whitelist\": [],\n        // (string[] 可选) 插件加载黑名单\n        \"blacklist\": [\"mica\", \"mica-ui\"]\n        // ----------------------------------------------------\n    }\n}\n```\n\n## 插件文件夹\n\n插件文件夹存放了所有插件和设置。\n\n### `qqntim.json` 文件\n\n存放插件信息的清单文件，包含了插件的基本信息、插件加载条件、要注入的 [JS 脚本](#js-文件)等。\n\n类型：[Manifest](#manifest)\n\n一个完整的示例如下：\n\n```json\n{\n    \"manifestVersion\": \"2.0\",\n    \"id\": \"my-plugin\",\n    \"name\": \"我的插件\",\n    \"author\": \"Flysoft\",\n    \"requirements\": {\n        \"os\": [\n            {\n                \"platform\": \"win32\",\n                \"lte\": \"10.0.22621\",\n                \"gte\": \"6.1.0\"\n            }\n        ]\n    },\n    \"injections\": [\n        {\n            \"type\": \"main\",\n            \"script\": \"main.js\"\n        },\n        {\n            \"type\": \"renderer\",\n            \"page\": [\"main\", \"chat\"],\n            \"script\": \"main.js\",\n            \"stylesheet\": \"style.css\"\n        }\n    ]\n}\n```\n\n### `*.js` 文件\n\n脚本入口文件。\n\n#### 主进程脚本\n\n该脚本必须使用 CommonJS 标准默认导出一个实现 [`QQNTim.Entry.Main`](src/typings/index.d.ts) 的类。\n\n一个示例如下：\n\n```typescript\nimport { QQNTim } from \"@flysoftbeta/qqntim-typings\";\n// 例子：QQNT 启动时显示一条 Hello world! 控制台信息\n// `qqntim` 内包含了很多实用的 API，可以帮助你对 QQNT 做出修改\nexport default class Entry implements QQNTim.Entry.Main {\n    constructor(qqntim: QQNTim.API.Main.API) {\n        console.log(\"Hello world!\", qqntim);\n    }\n}\n```\n\n#### 渲染进程脚本\n\n该脚本必须使用 CommonJS 标准默认导出一个实现 `QQNTim.Entry.Renderer` 的类。\n\n一个示例如下：\n\n```typescript\nimport { QQNTim } from \"@flysoftbeta/qqntim-typings\";\n// 例子：QQNT 启动时显示一条 Hello world! 控制台信息\n// `qqntim` 内包含了很多实用的 API，可以帮助你对 QQNT 做出修改\nexport default class Entry implements QQNTim.Entry.Renderer {\n    constructor(qqntim: QQNTim.API.Renderer.API) {\n        console.log(\"Hello world!\", qqntim);\n    }\n}\n```\n\n## 类型定义\n\n请查看 QQNTim 的 [TypeScript 类型定义文件](src/typings/index.d.ts)。此类型定义可通过安装 NPM 包 `@flysoftbeta/qqntim-typings` 添加到你的项目中。\n"
  },
  {
    "path": "MANUAL.md",
    "content": "# 使用手册\n\n此文档包含了使用教程。\n\n## 已知支持的 QQNT 版本\n\n| 操作系统 | 最高版本 | 最低版本 |\n| -------- | -------- | -------- |\n| Windows  | 9.9.1    | 9.8.0    |\n| Linux    | 3.1.2    | 3.0.0    |\n| macOS    | 6.9.17 (12118)     | 6.9.12 (10951)     |\n\n## 安装\n\n**请务必仔细阅读本章节内容以避免不必要的麻烦！**\n\nQQNTim 支持 LiteLoader，但**不支持 BetterQQNT**。\n\n> ### LiteLoader 相关安装教程：\n>\n> #### 如果你已经安装了 LiteLoader，想安装 QQNTim：\n>\n> 1. **确保 LiteLoader 文件夹名称为 `LiteLoader` 或 `LiteLoaderQQNT`。否则 LiteLoader 将不会被加载！**\n>\n> 2. 到 `QQNT 根目录/resources/app` 下修改 `package.json`，将 `\"LiteLoader\"` 修改为 `\"./app_launcher/index.js\"`，之后再运行 QQNTim 的安装脚本即可。\n>\n> #### 如果你已经安装了 QQNTim，想安装 LiteLoader：\n>\n> 请遵循 [LiteLoader 官方安装教程](https://github.com/mo-jinran/LiteLoaderQQNT/blob/main/README.md#安装方法) 进行安装即可，但请注意以下两点：\n>\n> 1. **确保 LiteLoader 文件夹名称为 `LiteLoader` 或 `LiteLoaderQQNT`。否则 LiteLoader 将不会被加载！**\n>\n> 2. **不要按照教程中的方法修改 `package.json`！否则 QQNTim 将不会加载。你只需保持它原样即可。**\n\n安装前请确保电脑上已经安装了 QQNT。\n\n如果你正在使用的是 **[不支持的 QQNT 版本](#已知支持的-qqnt-版本)、发现 QQNTim 无法正常使用且希望申请适配**，请通过 [附录-显示终端日志](#显示终端日志) 中提供的方法收集日志，并[向我们**提交此问题**](https://github.com/Flysoft-Studio/QQNTim/issues)。\n\n请先从 [Releases](https://github.com/Flysoft-Studio/QQNTim/releases) 中下载最新的版本（对于一般用户，建议下载 `qqntim-build.zip`），下载后，请确保你**解压了所有文件（必须包含 `_` 文件夹）**！\n\n在 Windows 下，请运行 `install.cmd` 安装或运行 `uninstall.cmd` 卸载。\n\n在 Linux 下，请在安装文件夹下运行：\n\n```bash\n# 安装\nchmod +x ./install.sh\n./install.sh\n# 卸载\nchmod +x ./uninstall.sh\n./uninstall.sh\n```\n在 macOS 下，打开 `终端.app` 执行以下操作：\n\n```zsh\n# 安装\nchmod +x <install_macos.sh>    <----将 install_macos.sh 文件拖进终端窗口后按回车运行\n<install_macos.sh>             <----将 install_macos.sh 文件拖进终端窗口后按回车运行\n# 卸载\nchmod +x <uninstall_macos.sh>    <----将 uninstall_macos.sh 文件拖进终端窗口后按回车运行\n<uninstall_macos.sh>             <----将 uninstall_macos.sh 文件拖进终端窗口后按回车运行\n```\n需要输入管理员密码鉴权，同时在弹出的通知中选择允许终端修改App，或前往 `系统设置->隐私与安全性->App管理` 中打开/添加 `终端` 来允许终端修改文件。\n\n安装后，打开 \"设置\" 页面：\n\n![设置入口](.github/settings-entry.png)\n\n如果左侧菜单出现 \"QQNTim 设置\"，即代表安装成功：\n\n![QQNTim 设置页面](.github/qqntim-settings-page.png)\n\n如果此项目并未按预期出现，则可能代表 QQNTim 安装没有成功，或 QQNTim 加载失败。请通过 [附录-显示终端日志](#显示终端日志) 中提供的方法收集日志，并[向我们**提交此问题**](https://github.com/Flysoft-Studio/QQNTim/issues)。\n\n## 插件管理\n\n### 获取插件\n\n**[Plugins Galaxy](https://github.com/FlysoftBeta/QQNTim-Plugins-Galaxy) 中拥有很多功能丰富的插件，欢迎下载。**\n\n支持 QQNTim 3.0 及以上版本的插件：\n\n| 名称                                                                                                     | 说明                                                  | 作者                                         |\n| -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | -------------------------------------------- |\n| [QQNTim-Plugin-Markdown](https://github.com/Flysoft-Studio/QQNTim-Plugin-Markdown)                       | 显示 Markdown 消息/LaTeX 渲染插件                     | [Flysoft](https://github.com/Flysoft-Studio) |\n| [QQNTim-Plugin-Wallpaper](https://github.com/Flysoft-Studio/QQNTim-Plugin-Wallpaper)                     | 自定义你的壁纸                                        | [Flysoft](https://github.com/Flysoft-Studio) |\n| [QQNTim-Plugin-No-Revoked-Messages](https://github.com/Flysoft-Studio/QQNTim-Plugin-No-Revoked-Messages) | 支持消息持久化保存的防撤回插件                        | [Flysoft](https://github.com/Flysoft-Studio) |\n| [QQNTim-Plugins-Galaxy](https://github.com/FlysoftBeta/QQNTim-Plugins-Galaxy)                            | 插件商城（注意：只有 GaussianUI 插件支持 QQNTim 3.0） | [Flysoft](https://github.com/Flysoft-Studio) |\n\n仅支持 QQNTim 2.2 及以下版本的插件：\n\n| 名称                                                                          | 说明                                                   | 作者                                         |\n| ----------------------------------------------------------------------------- | ------------------------------------------------------ | -------------------------------------------- |\n| [QQNTim-Plugin-NTHttp](https://github.com/Rei1mu/QQNTim-Plugin-NTHttp)        | WebSocket+Http 的通信实现                              | [Rei1mu](https://github.com/Rei1mu)          |\n| [QQNTim-Plugin-NoUpdate](https://github.com/Rei1mu/QQNTim-Plugin-NoUpdate)    | 取消提示自动更新的烦人弹窗                             | [Rei1mu](https://github.com/Rei1mu)          |\n| [QQNTim-Plugins-Galaxy](https://github.com/FlysoftBeta/QQNTim-Plugins-Galaxy) | 插件商城（注意：壁纸插件不支持 QQNTim 2.2 及以下版本） | [Flysoft](https://github.com/Flysoft-Studio) |\n\n### 安装插件\n\n要安装插件，请准备一个插件**压缩包 (.zip) 或文件夹**。\n\n结构如下图所示（每个插件结构各不相同，这里提供的结构图仅供参考）：\n\n```\n我的插件\n  ├─ qqntim.json\n  ├─ renderer.js\n  ├─ style.css\n  └─ ...\n```\n\n打开 \"设置\" 页面，选中 \"插件管理\"：\n\n![插件管理页面](.github/qqntim-plugin-management-page.png)\n\n如果你登录了多个 QQ 账户，且希望某个插件只对当前账户生效，那么请点击 \"仅对账号 [你的 QQ 号] 生效的插件\" 右侧的安装按钮。\n\n如果你希望插件对所有账户生效，那么请点击 \"对所有账号生效的插件\" 右侧的安装按钮进行安装。\n\n**_注意：根据提示选择插件相关文件安装后，你可能需要重启 QQ 才能使这些插件开始生效。_**\n\n安装插件后，如果插件没有按预期正常工作，请通过 [附录-显示终端日志](#显示终端日志) 中提供的方法收集日志，并向插件作者提交此问题。\n\n### 管理现有插件\n\n打开 \"设置\" 页面，选中 \"插件管理\"：\n\n![插件管理页面](.github/qqntim-plugin-management-page.png)\n\n目前，你可以启用、禁用或删除插件。\n\n**_注意：修改设置之后需要点击 \"保存并重启\" 才能使设置生效。_**\n\n## 数据文件夹\n\n数据文件夹存放了所有插件和设置。\n\n在 Windows 下，默认数据文件夹位于 `%UserProfile%/.qqntim`（例如：`C:/Users/[你的用户名]/.qqntim`）。\n\n在 Linux 下，默认数据文件夹位于 `$HOME/.local/share/QQNTim`（例如：`/home/[你的用户名]/.local/share/QQNTim`，可能需要启用**显示隐藏文件**选项才能显示出来）。\n\n你可以修改 `QQNTIM_HOME` 环境变量以修改数据文件夹的位置。\n\n## 附录\n\n### 显示终端日志\n\n#### 在 Windows 下显示终端日志\n\n1. 桌面右键 QQ 图标，点击 \"打开文件所在位置\"。\n2. 在出现的文件夹窗口内按住 `Shift` 右键，点击 \"在此处打开命令窗口\" 或 \"在此处打开 PowerShell 窗口\"。\n3. 在弹出的控制台窗口内输入 \".\\QQ.exe\" 并按下 `Enter`。\n4. 日志信息将会出现在控制台窗口内。\n\n#### 在 GNOME (Linux) 下显示终端日志\n\n1. 按两次 `Super` 键，打开 \"所有应用\"。\n2. 输入 \"终端\"，并按下 `Enter`。\n3. 在弹出的控制台窗口内输入 \"linuxqq ; qq\" 并按下 `Enter`。\n4. 日志信息将会出现在控制台窗口内。\n\n#### 在 KDE (Linux) 下显示终端日志\n\n1. 按一次次 `Super` 键，打开 \"KDE 菜单\"。\n2. 输入 \"Konsole\"，并按下 `Enter`。\n3. 在弹出的控制台窗口内输入 \"linuxqq ; qq\" 并按下 `Enter`。\n4. 日志信息将会出现在控制台窗口内。\n"
  },
  {
    "path": "README.md",
    "content": "# QQNT-Improved - PC 端 QQNT 插件管理器\n\n此项目已废弃，我们正在全力开发全新 QQ 客户端——QPlugged，敬请期待。\n\n[![Maintainability](https://api.codeclimate.com/v1/badges/bb8c6d1f5c2647ae38e8/maintainability)](https://codeclimate.com/github/Flysoft-Studio/QQNTim/maintainability) [![License](https://img.shields.io/github/license/FlysoftBeta/QQNTim)](https://github.com/Flysoft-Studio/QQNTim/blob/dev/COPYING.LESSER) [![Build](https://img.shields.io/github/actions/workflow/status/Flysoft-Studio/QQNTim/build.yml)](https://github.com/Flysoft-Studio/QQNTim/actions/workflows/build.yml)\n\n![截图](.github/screenshot.png)\n\n<!-- **注意:** 我们注意到 QQNT (Windows) 最近在进行大幅度修改。为了防止我们的前功尽弃，我们将适当减小更新频率。 -->\n\nQQNT-Improved (简称 QQNTim) 是一个给 QQNT 的插件管理器，目前处于 Alpha 版本阶段，支持 Windows，Linux 等平台 (macOS 未测试，不保证可用性)。\n\n本程序**不提供任何担保**（包括但不限于使用导致的系统故障、封号等）。\n\nTelegram 群组：<https://t.me/qqntim>，欢迎加入。\n\n> QQNTim 可以与 **[LiteLoaderQQNT](https://github.com/mo-jinran/LiteLoaderQQNT)** 并存，快去试试吧！\n>\n> 请阅读 [使用手册-安装](MANUAL.md#安装) 查看如何安装。\n\n## 安装与使用\n\n请查看我们的[使用手册](MANUAL.md)。\n\n## 插件开发\n\n请查看我们的[开发文档](DEVELOPMENT.md)。\n\n## 协议\n\n本程序使用 GNU Lesser General Public License v3.0 or later 协议发行。\n\n请在此源代码树下的 [COPYING](./COPYING) 和 [COPYING.LESSER](./COPYING.LESSER) 查看完整的协议。\n"
  },
  {
    "path": "build.ts",
    "content": "import { BuildOptions, build } from \"esbuild\";\nimport { copy, emptyDir, ensureDir, readdir, writeFile } from \"fs-extra\";\nimport { dirname, sep as s } from \"path\";\nimport { getAllLocators, getPackageInformation } from \"pnpapi\";\n\ntype Package = {\n    packageLocation: string;\n    packageDependencies: Map<string, string>;\n};\ntype Packages = Record<string, Record<string, Package>>;\n\nconst unpackedPackages = [\"chii\"];\nconst junkFiles = [\n    \".d.ts\",\n    \".markdown\",\n    \".md\",\n    \"/.eslintrc\",\n    \"/.eslintrc.js\",\n    \"/.prettierrc\",\n    \"/.nycrc\",\n    \".yml\",\n    \".yaml\",\n    \".bak\",\n    \"/.editorconfig\",\n    \"/bower.json\",\n    \"/.jscs.json\",\n    \"/AUTHORS\",\n    \"/LICENSE\",\n    \"/License\",\n    \"/yarn.lock\",\n    \"/package-lock.json\",\n    \".map\",\n    \".debug.js\",\n    \".min.js\",\n    \".test.js\",\n    \"/test/\",\n    \"/bin/\",\n    \"/tests/\",\n    \"/.github/\",\n];\n\nconst isProduction = process.env[\"NODE_ENV\"] == \"production\";\nconst commonOptions: Partial<BuildOptions> = {\n    target: \"node18\",\n    bundle: true,\n    platform: \"node\",\n    write: true,\n    allowOverwrite: true,\n    sourcemap: isProduction ? false : \"inline\",\n    minify: isProduction,\n    treeShaking: isProduction,\n};\n\nasync function buildBundles() {\n    const buildPromise = Promise.all([\n        build({\n            ...commonOptions,\n            entryPoints: [`src${s}main${s}main.ts`],\n            outfile: `dist${s}_${s}qqntim.js`,\n            external: [\"electron\", \"./index.js\", ...unpackedPackages],\n        }),\n        build({\n            ...commonOptions,\n            entryPoints: [`src${s}renderer${s}main.ts`],\n            outfile: `dist${s}_${s}qqntim-renderer.js`,\n            external: [\"electron\", ...unpackedPackages],\n        }),\n    ]);\n\n    return await buildPromise;\n}\n\nasync function buildBuiltinPlugins() {\n    const rootDir = `src${s}builtins`;\n    const pluginsDir = await readdir(rootDir);\n    await Promise.all(\n        pluginsDir.map(async (dir) => {\n            const pluginDir = `${rootDir}${s}${dir}`;\n            const distDir = `dist${s}_${s}builtins${s}${dir}`;\n            await ensureDir(pluginDir);\n            await build({\n                ...commonOptions,\n                entryPoints: [`${pluginDir}${s}src${s}main.ts`, `${pluginDir}${s}src${s}renderer.ts`],\n                outdir: distDir,\n                external: [\"electron\", \"react\", \"react/jsx-runtime\", \"react-dom\", \"react-dom/client\", \"qqntim/main\", \"qqntim/renderer\"],\n                format: \"cjs\",\n            });\n            await copy(`${pluginDir}${s}publish`, `${distDir}`);\n        }),\n    );\n}\n\nasync function prepareDistDir() {\n    await emptyDir(\"dist\");\n    await ensureDir(`dist${s}_`);\n    await copy(\"publish\", \"dist\");\n}\n\nfunction collectDeps() {\n    const packages: Packages = {};\n    getAllLocators().forEach((locator) => {\n        if (!packages[locator.name]) packages[locator.name] = {};\n        packages[locator.name][locator.reference] = getPackageInformation(locator);\n    });\n    return packages;\n}\n\nasync function unpackPackage(packages: Packages, rootDir: string, name: string, reference?: string) {\n    const item = packages[name];\n    if (!item) return;\n    const location = item[reference ? reference : Object.keys(item)[0]];\n    const dir = `${rootDir}${s}node_modules${s}${name}`;\n    await ensureDir(dir);\n    await copy(location.packageLocation, dir, {\n        filter: (src) => {\n            for (const file of junkFiles) {\n                if (src.includes(file)) return false;\n            }\n            return true;\n        },\n    });\n    const promises: Promise<void>[] = [];\n    location.packageDependencies.forEach((depReference, depName) => {\n        if (name == depName) return;\n        promises.push(unpackPackage(packages, dir, depName, depReference));\n    });\n    await Promise.all(promises);\n}\n\nconst packages = collectDeps();\nprepareDistDir().then(() => Promise.all([buildBundles(), buildBuiltinPlugins(), Promise.all(unpackedPackages.map((unpackedPackage) => unpackPackage(packages, `dist${s}_`, unpackedPackage)))]));\n"
  },
  {
    "path": "examples/NT-API/consts.js",
    "content": "module.exports = {\n    id: \"example-nt-api\",\n    defaults: {\n        showAccountInfo: true,\n        showHistoryMessages: true,\n        historyMessageObject: \"both\",\n        autoReply: true,\n        testInputValue: \"默认值\",\n    },\n};\n"
  },
  {
    "path": "examples/NT-API/qqntim.json",
    "content": "{\n    \"manifestVersion\": \"3.0\",\n    \"id\": \"example-nt-api\",\n    \"name\": \"示例插件：NT API\",\n    \"author\": \"Flysoft\",\n    \"injections\": [{ \"type\": \"renderer\", \"script\": \"renderer.js\", \"page\": \"main\" }, { \"type\": \"renderer\", \"script\": \"settings.js\", \"page\": \"settings\" }]\n}\n"
  },
  {
    "path": "examples/NT-API/renderer.js",
    "content": "const path = require(\"path\");\nconst qqntim = require(\"qqntim/renderer\");\nconst { id, defaults } = require(\"./consts\");\n\nmodule.exports.default = class Entry {\n    constructor() {\n        const config = qqntim.env.config.plugins?.config?.[id];\n        const showAccountInfo = config?.showAccountInfo != undefined ? config.showAccountInfo : defaults.showAccountInfo;\n        const historyMessageObject = config?.historyMessageObject != undefined ? config.historyMessageObject : defaults.historyMessageObject;\n        const showHistoryMessages = config?.showHistoryMessages != undefined ? config.showHistoryMessages : defaults.showHistoryMessages;\n        const autoReply = config?.autoReply != undefined ? config.autoReply : defaults.autoReply;\n        const testInputValue = config?.testInputValue != undefined ? config.testInputValue : defaults.testInputValue;\n\n        //#region 示例：获取当前账号\n        if (showAccountInfo)\n            qqntim.nt.getAccountInfo().then((account) => {\n                console.log(\"[Example-NT-API] 当前账号信息\", account);\n            });\n        //#endregion\n\n        //#region 示例：获取好友和群的最近 20 条历史消息\n        if (showHistoryMessages) {\n            if (historyMessageObject == \"friends\" || historyMessageObject == \"both\")\n                qqntim.nt.getFriendsList().then((list) => {\n                    console.log(\"[Example-NT-API] 好友列表\", list);\n                    list.forEach((friend) => qqntim.nt.getPreviousMessages({ chatType: \"friend\", uid: friend.uid }, 20).then((messages) => qqntim.nt.getUserInfo(friend.uid).then((user) => console.log(\"[Example-NT-API] 好友\", user, \"的最近 20 条消息：\", messages))));\n                });\n            if (historyMessageObject == \"groups\" || historyMessageObject == \"both\")\n                qqntim.nt.getGroupsList().then((list) => {\n                    console.log(\"[Example-NT-API] 群组列表\", list);\n                    list.forEach((group) => qqntim.nt.getPreviousMessages({ chatType: \"group\", uid: group.uid }, 20).then((messages) => console.log(`[Example-NT-API] 群组 ${group.name} (${group.uid}) 的最近 20 条消息：`, messages)));\n                });\n        }\n        //#endregion\n\n        //#region 示例：自动回复\n        if (autoReply)\n            qqntim.nt.on(\"new-messages\", (messages) => {\n                console.log(\"[Example-NT-API] 收到新消息：\", messages);\n                messages.forEach((message) => {\n                    if (message.peer.chatType != \"friend\") return;\n                    message.allDownloadedPromise.then(() => {\n                        qqntim.nt\n                            .sendMessage(message.peer, [\n                                {\n                                    type: \"text\",\n                                    content: \"收到一条来自好友的消息：\",\n                                },\n                                ...message.elements,\n                                {\n                                    type: \"text\",\n                                    content: \"（此消息两秒后自动撤回）\\n示例图片：\",\n                                },\n                                // 附带一个插件目录下的 example.jpg 作为图片发送\n                                {\n                                    type: \"image\",\n                                    file: path.join(__dirname, \"example.jpg\"),\n                                },\n                            ])\n                            .then((id) => {\n                                setTimeout(() => {\n                                    qqntim.nt.revokeMessage(message.peer, id);\n                                }, 2000);\n                            });\n                    });\n                });\n            });\n        //#endregion\n\n        console.log(\"[Example-NT-API] 测试消息：\", testInputValue);\n    }\n};\n"
  },
  {
    "path": "examples/NT-API/settings.js",
    "content": "const { Fragment, createElement } = require(\"react\");\nconst { defineSettingsPanels } = require(\"qqntim-settings\");\nconst { SettingsSection, SettingsBox, SettingsBoxItem, Switch, Input, Dropdown } = require(\"qqntim-settings/components\");\nconst { id, defaults } = require(\"./consts\");\n\nfunction SettingsPanel({ config, setConfig }) {\n    return createElement(\n        Fragment,\n        undefined,\n        createElement(\n            SettingsSection,\n            { title: \"插件设置\" },\n            createElement(\n                SettingsBox,\n                undefined,\n                createElement(\n                    SettingsBoxItem,\n                    { title: \"显示账户信息\", description: [\"在控制台中显示当前登录的账户信息。\"] },\n                    createElement(Switch, {\n                        checked: config?.[id]?.showAccountInfo != undefined ? config?.[id]?.showAccountInfo : defaults.showAccountInfo,\n                        onToggle: (state) =>\n                            setConfig((prev) => {\n                                return {\n                                    ...(prev || {}),\n                                    [id]: {\n                                        ...(prev[id] || {}),\n                                        showAccountInfo: state,\n                                    },\n                                };\n                            }),\n                    }),\n                ),\n                createElement(\n                    SettingsBoxItem,\n                    { title: \"显示历史消息\", description: [\"在控制台中显示历史 20 条消息。\"] },\n                    createElement(Switch, {\n                        checked: config?.[id]?.showHistoryMessages != undefined ? config?.[id]?.showHistoryMessages : defaults.showHistoryMessages,\n                        onToggle: (state) =>\n                            setConfig((prev) => {\n                                return {\n                                    ...(prev || {}),\n                                    [id]: {\n                                        ...(prev[id] || {}),\n                                        showHistoryMessages: state,\n                                    },\n                                };\n                            }),\n                    }),\n                ),\n                (config?.[id]?.showHistoryMessages != undefined ? config?.[id]?.showHistoryMessages : defaults.showHistoryMessages) &&\n                    createElement(\n                        SettingsBoxItem,\n                        { title: \"获取历史消息的对象\" },\n                        createElement(Dropdown, {\n                            items: [\n                                [\"friends\", \"好友\"],\n                                [\"groups\", \"群\"],\n                                [\"both\", \"好友和群\"],\n                            ],\n                            selected: config?.[id]?.historyMessageObject != undefined ? config?.[id]?.historyMessageObject : defaults.historyMessageObject,\n                            onChange: (state) =>\n                                setConfig((prev) => {\n                                    return {\n                                        ...(prev || {}),\n                                        [id]: {\n                                            ...(prev[id] || {}),\n                                            historyMessageObject: state,\n                                        },\n                                    };\n                                }),\n                            width: \"150px\",\n                        }),\n                    ),\n                createElement(\n                    SettingsBoxItem,\n                    { title: \"自动回复\", description: [\"自动回复私聊消息。\"] },\n                    createElement(Switch, {\n                        checked: config?.[id]?.autoReply != undefined ? config?.[id]?.autoReply : defaults.autoReply,\n                        onToggle: (state) =>\n                            setConfig((prev) => {\n                                return {\n                                    ...(prev || {}),\n                                    [id]: {\n                                        ...(prev[id] || {}),\n                                        autoReply: state,\n                                    },\n                                };\n                            }),\n                    }),\n                ),\n                createElement(\n                    SettingsBoxItem,\n                    { title: \"测试\", description: [\"测试输入框。\"], isLast: true },\n                    createElement(Input, {\n                        value: config?.[id]?.testInputValue != undefined ? config?.[id]?.testInputValue : defaults.testInputValue,\n                        onChange: (state) =>\n                            setConfig((prev) => {\n                                return {\n                                    ...(prev || {}),\n                                    [id]: {\n                                        ...(prev[id] || {}),\n                                        testInputValue: state,\n                                    },\n                                };\n                            }),\n                    }),\n                ),\n            ),\n        ),\n    );\n}\n\nmodule.exports.default = class Entry {\n    constructor() {\n        defineSettingsPanels([\n            \"Example-NT-API 设置\",\n            SettingsPanel,\n            `<svg viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.0005 15C17.8572 15 20.173 12.6842 20.173 9.82756C20.173 6.97092 17.8572 4.65515 15.0005 4.65515H10.188C10.0247 4.65515 10.2276 4.85861 10.3157 4.99608C10.5913 5.42594 11.1765 6.21463 10.654 7.02266C10.1314 7.83069 9.82812 8.79371 9.82812 9.82756C9.82812 12.6842 12.1439 15 15.0005 15Z\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"square\"></path><path d=\"M6.66406 24.3091C6.66406 21.2081 9.6191 18.1656 13.4146 18.1656C14.6987 18.1656 15.3023 18.1656 16.5864 18.1656C20.4854 18.1656 23.337 21.2081 23.337 24.3091C23.337 24.4334 23.2362 24.5341 23.1119 24.5341H6.88908C6.76481 24.5341 6.66406 24.4334 6.66406 24.3091Z\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"square\"></path></svg>`,\n        ]);\n    }\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"qqnt-improved\",\n    \"private\": true,\n    \"version\": \"3.1.3\",\n    \"license\": \"LGPL-3.0-or-later\",\n    \"packageManager\": \"yarn@3.6.1\",\n    \"workspaces\": [\"src/electron\", \"src/typings\", \"src/builtins/*\"],\n    \"scripts\": {\n        \"dev\": \"TS_NODE_FILES=1 TS_NODE_TRANSPILE_ONLY=1 NODE_ENV=development ts-node ./build.ts\",\n        \"build:win\": \"TS_NODE_FILES=1 TS_NODE_TRANSPILE_ONLY=1 NODE_ENV=production ts-node ./build.ts && powershell -ExecutionPolicy Unrestricted -File ./scripts/pack.ps1\",\n        \"build:linux\": \"TS_NODE_FILES=1 TS_NODE_TRANSPILE_ONLY=1 NODE_ENV=production ts-node ./build.ts && chmod +x ./scripts/pack.sh && ./scripts/pack.sh\",\n        \"install:win\": \"QQNTIM_INSTALLER_NO_KILL_QQ=1 cmd /c start \\\"\\\" /wait cmd /c dist\\\\\\\\install.cmd\",\n        \"install:linux\": \"chmod +x ./dist/install.sh && QQNTIM_INSTALLER_NO_KILL_QQ=1 ./dist/install.sh\",\n        \"start:win\": \"powershell -ExecutionPolicy Unrestricted -File ./scripts/start.ps1\",\n        \"start:linux\": \"chmod +x ./scripts/start.sh && ./scripts/start.sh\",\n        \"lint\": \"tsc && rome check .\",\n        \"lint:apply\": \"rome check . --apply\",\n        \"lint:apply-unsafe\": \"rome check . --apply-unsafe\",\n        \"format\": \"rome format . --write\"\n    },\n    \"dependencies\": {\n        \"@electron/remote\": \"^2.0.11\",\n        \"@flysoftbeta/qqntim-typings\": \"workspace:*\",\n        \"axios\": \"^1.5.0\",\n        \"chii\": \"^1.9.0\",\n        \"electron\": \"workspace:*\",\n        \"fs-extra\": \"^11.1.1\",\n        \"react\": \"^18.2.0\",\n        \"react-dom\": \"^18.2.0\",\n        \"semver\": \"^7.5.4\",\n        \"supports-color\": \"^9.4.0\"\n    },\n    \"devDependencies\": {\n        \"@types/fs-extra\": \"^11.0.1\",\n        \"@types/node\": \"^20.6.2\",\n        \"@types/react\": \"^18.2.21\",\n        \"@types/react-dom\": \"^18.2.7\",\n        \"@types/semver\": \"^7.5.2\",\n        \"@yarnpkg/sdks\": \"^3.0.0-rc.50\",\n        \"esbuild\": \"^0.19.2\",\n        \"rome\": \"12.1.3\",\n        \"ts-node\": \"^10.9.1\",\n        \"typed-emitter\": \"^2.1.0\",\n        \"typescript\": \"^5.2.2\"\n    }\n}\n"
  },
  {
    "path": "publish/_/install.ps1",
    "content": "﻿$ErrorActionPreference = \"Stop\"\r\n\r\n$Host.UI.RawUI.WindowTitle = \"QQNTim 安装程序 (PowerShell)\"\r\nSet-Location (Split-Path -Parent $MyInvocation.MyCommand.Definition)\r\n$CD = (Get-Location).Path\r\n\r\n# 判断是否拥有管理员权限\r\nif (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]\"Administrator\")) {\r\n    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {\r\n        throw \"权限不足。\" \r\n    }\r\n}\r\n\r\n# 从注册表获取 QQ 安装路径\r\nforeach ($RegistryPath in @(\"HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\", \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\")) {\r\n    try {\r\n        foreach ($Item in (Get-ItemProperty $RegistryPath)) {\r\n            if ($Item.PSChildName -eq \"QQ\") {\r\n                $QQInstallDir = (Split-Path -Parent $Item.UninstallString)\r\n                break\r\n            }\r\n        }\r\n    }\r\n    catch {}\r\n}\r\n\r\nif (($null -eq $QQInstallDir) -or ((Test-Path $QQInstallDir) -eq $false)) {\r\n    throw \"未找到 QQNT 安装目录。\"\r\n}\r\n\r\n$QQExecutableFile = \"$QQInstallDir\\QQ.exe\"\r\n$QQExecutableBackupFile = \"$QQInstallDir\\QQ.exe.bak\"\r\n$QQExecutableHashFile = \"$QQInstallDir\\QQ.exe.md5\"\r\n$QQAppDir = \"$QQInstallDir\\resources\\app\"\r\n$QQAppLauncherDir = \"$QQAppDir\\app_launcher\"\r\n$PackageJSONFile = \"$QQAppDir\\package.json\"\r\n$QQNTimFlagFile = \"$QQAppLauncherDir\\qqntim-flag.txt\"\r\n$SuccessFlagFile = \"$env:TEMP\\qqntim-install-successful.tmp\"\r\n\r\n# 清理旧版文件，恢复被修改的入口文件\r\nif ((Test-Path \"$QQAppLauncherDir\\index.js.bak\") -eq $true) {\r\n    Write-Output \"正在清理旧版 QQNTim……\"\r\n    Move-Item \"$QQAppLauncherDir\\index.js.bak\" \"$QQAppLauncherDir\\index.js\" -Force\r\n    \"\" | Out-File $QQNTimFlagFile -Encoding UTF8 -Force\r\n}\r\n\r\n# 询问用户，如果存在旧版则不提示\r\nif ((Test-Path $QQNTimFlagFile) -eq $false) {\r\n    if ((Read-Host \"是否要安装 QQNTim (y/n)？\") -notcontains \"y\") {\r\n        throw \"安装已被用户取消。\"\r\n    }\r\n}\r\nelse {\r\n    Write-Output \"检测到已有安装，正在更新……\"\r\n}\r\n\r\nif ($env:QQNTIM_INSTALLER_NO_KILL_QQ -ne \"1\") {\r\n    Write-Output \"正在关闭 QQ……\"\r\n    Stop-Process -Name QQ -ErrorAction SilentlyContinue\r\n}\r\n\r\nWrite-Output \"正在复制文件……\"\r\n# 如果 node_modules 不存在或已经过期则执行复制\r\nif ((Test-Path .\\node_modules.zip.md5) -eq $true -and (Test-Path .\\node_modules.zip) -eq $true) {\r\n    if ((Test-Path \"$QQAppLauncherDir\\node_modules.zip.md5\") -eq $false -or (Get-Content \"$QQAppLauncherDir\\node_modules.zip.md5\" -Encoding UTF8 -Force) -ne (Get-Content .\\node_modules.zip.md5 -Encoding UTF8 -Force)) {\r\n        $SourceZipPath = \"$CD\\node_modules.zip\";\r\n        $DestinationDirPath = \"$QQAppLauncherDir\\node_modules\"\r\n        # 清空原有 node_modules 文件夹\r\n        if ((Test-Path $DestinationDirPath) -eq $true) {\r\n            Remove-Item $DestinationDirPath -Recurse -Force\r\n        }\r\n        New-Item $DestinationDirPath -ItemType Directory -Force | Out-Null\r\n        try {\r\n            # 回退 1 - 仅支持 .NET Framework 4.5 及以上\r\n            Add-Type -AssemblyName System.IO.Compression.Filesystem\r\n            [System.IO.Compression.ZipFile]::ExtractToDirectory($SourceZipPath, $DestinationDirPath)\r\n        }\r\n        catch { \r\n            # 回退 2 - 使用系统 COM 复制 API\r\n            $Shell = New-Object -ComObject Shell.Application\r\n            $Shell.NameSpace($DestinationDirPath).CopyHere($Shell.NameSpace($SourceZipPath).Items())\r\n        }\r\n    }\r\n    Copy-Item \".\\node_modules.zip.md5\" $QQAppLauncherDir -Recurse -Force\r\n}\r\nelseif ((Test-Path .\\node_modules) -eq $true) {\r\n    Copy-Item \".\\node_modules\" $QQAppLauncherDir -Recurse -Force\r\n}\r\nCopy-Item \".\\qqntim.js\", \".\\qqntim-renderer.js\", \".\\builtins\" $QQAppLauncherDir -Recurse -Force\r\n\r\nWrite-Output \"正在修补 package.json……\"\r\n# 使用 UTF-8 without BOM 进行保存\r\n$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False\r\n[System.IO.File]::WriteAllLines($PackageJSONFile, ((Get-Content $PackageJSONFile -Encoding UTF8 -Force) -replace \"./app_launcher/index.js\", \"./app_launcher/qqntim.js\"), $Utf8NoBomEncoding)\r\n\r\n# For QQ 9.9.1+\r\n# 如果 QQ.exe 未被修补或已被新安装覆盖则进行修补\r\nif ((Test-Path $QQExecutableHashFile) -eq $false -or (Get-Content $QQExecutableHashFile -Encoding UTF8 -Force) -replace \"`r`n\", \"\" -ne (Get-FileHash $QQExecutableFile -Algorithm MD5).Hash) {\r\n    Write-Output \"正在修补 QQ.exe，这可能需要一些时间……\"\r\n    Copy-Item $QQExecutableFile $QQExecutableBackupFile -Force\r\n    # 引入 crypt32.dll 定义\r\n    $Crypt32Def = @\"\r\n[DllImport(\"Crypt32.dll\", CharSet = CharSet.Auto, SetLastError = true)]\r\npublic static extern bool CryptStringToBinary(\r\n    string pszString,\r\n    int cchString,\r\n    int dwFlags,\r\n    byte[] pbBinary,\r\n    ref int pcbBinary,\r\n    int pdwSkip,\r\n    ref int pdwFlags\r\n);\r\n[DllImport(\"Crypt32.dll\", CharSet = CharSet.Auto, SetLastError = true)]\r\npublic static extern bool CryptBinaryToString(\r\n    byte[] pbBinary,\r\n    int cbBinary,\r\n    int dwFlags,\r\n    StringBuilder pszString,\r\n    ref int pcchString\r\n);\r\n\"@\r\n    Add-Type -MemberDefinition $Crypt32Def -Namespace PKI -Name Crypt32 -UsingNamespace \"System.Text\"\r\n    $HexRawEncoding = 12\r\n\r\n    $QQBin = [System.IO.File]::ReadAllBytes($QQExecutableFile)\r\n    # Byte[] 转 Hex String\r\n    $pcchString = 0 # Size\r\n    if ([PKI.Crypt32]::CryptBinaryToString($QQBin, $QQBin.Length, $HexRawEncoding, $null, [ref]$pcchString)) {\r\n        $QQHex = New-Object Text.StringBuilder $pcchString\r\n        [void][PKI.Crypt32]::CryptBinaryToString($QQBin, $QQBin.Length, $HexRawEncoding, $QQHex, [ref]$pcchString)\r\n        $PatchedQQHex = $QQHex.ToString() -replace \"7061636b6167652e6a736f6e00696e6465782e6a73006c61756e636865722e6a73006c61756e636865722e6e6f646500\", \"696e6465782e6a730000000000696e6465782e6a73006c61756e636865722e6a73006c61756e636865722e6e6f646500\" -replace \"7061636b6167652e488d942400020000488902c742086a736f6e\", \"6c61756e63686572488d942400020000488902c742082e6a7300\"\r\n        # Hex String 转 Byte[]\r\n        $pcbBinary = 0 # Size\r\n        $pdwFlags = 0\r\n        if ([PKI.Crypt32]::CryptStringToBinary($PatchedQQHex, $PatchedQQHex.Length, $HexRawEncoding, $null, [ref]$pcbBinary, 0, [ref]$pdwFlags)) {\r\n            $PatchedQQBin = New-Object byte[] -ArgumentList $pcbBinary\r\n            [void][PKI.Crypt32]::CryptStringToBinary($PatchedQQHex, $PatchedQQHex.Length, $HexRawEncoding, $PatchedQQBin, [ref]$pcbBinary, 0, [ref]$pdwFlags)\r\n\r\n            # 写出文件\r\n            [System.IO.File]::WriteAllBytes($QQExecutableFile, $PatchedQQBin)\r\n\r\n            # 写出 MD5\r\n            $QQFileHash = (Get-FileHash $QQExecutableFile -Algorithm MD5).Hash\r\n            [System.IO.File]::WriteAllLines($QQExecutableHashFile, $QQFileHash, $Utf8NoBomEncoding)\r\n        }\r\n        else {\r\n            throw $((New-Object ComponentModel.Win32Exception ([Runtime.InteropServices.Marshal]::GetLastWin32Error())).Message)\r\n        }\r\n    }\r\n    else {\r\n        throw $((New-Object ComponentModel.Win32Exception ([Runtime.InteropServices.Marshal]::GetLastWin32Error())).Message)\r\n    }\r\n}\r\nelse {\r\n    Write-Output \"QQ.exe 未更新，无需修补！\"\r\n}\r\n\r\nif ((Test-Path $QQNTimFlagFile) -eq $false) {\r\n    \"\" | Out-File $QQNTimFlagFile -Encoding UTF8 -Force\r\n}\r\n\r\nif ((Test-Path $SuccessFlagFile) -eq $false) {\r\n    \"\" | Out-File $SuccessFlagFile -Encoding UTF8 -Force\r\n}\r\n\r\nif ($env:QQNTIM_INSTALLER_NO_DELAYED_EXIT -ne \"1\") {\r\n    Write-Output \"安装成功。安装程序将在 5 秒后自动退出。\"\r\n    Start-Sleep -Seconds 5\r\n}\r\nelse {\r\n    Write-Output \"安装成功。\"\r\n}"
  },
  {
    "path": "publish/_/uninstall.ps1",
    "content": "﻿$ErrorActionPreference = \"Stop\"\r\n\r\n$Host.UI.RawUI.WindowTitle = \"QQNTim 卸载程序 (PowerShell)\"\r\nSet-Location (Split-Path -Parent $MyInvocation.MyCommand.Definition)\r\n\r\n# 判断是否拥有管理员权限\r\nif (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]\"Administrator\")) {\r\n    if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {\r\n        throw \"权限不足。\" \r\n    }\r\n}\r\n\r\n# 从注册表获取 QQ 安装路径\r\nforeach ($RegistryPath in @(\"HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\", \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\")) {\r\n    try {\r\n        foreach ($Item in (Get-ItemProperty $RegistryPath)) {\r\n            if ($Item.PSChildName -eq \"QQ\") {\r\n                $QQInstallDir = (Split-Path -Parent $Item.UninstallString)\r\n                break\r\n            }\r\n        }\r\n    }\r\n    catch {}\r\n}\r\n\r\nif (($null -eq $QQInstallDir) -or ((Test-Path $QQInstallDir) -eq $false)) {\r\n    throw \"未找到 QQNT 安装目录。\"\r\n}\r\n\r\n$QQExecutableFile = \"$QQInstallDir\\QQ.exe\"\r\n$QQExecutableBackupFile = \"$QQInstallDir\\QQ.exe.bak\"\r\n$QQExecutableHashFile = \"$QQInstallDir\\QQ.exe.md5\"\r\n$QQAppDir = \"$QQInstallDir\\resources\\app\"\r\n$QQAppLauncherDir = \"$QQAppDir\\app_launcher\"\r\n$QQNTimFlagFile = \"$QQAppLauncherDir\\qqntim-flag.txt\"\r\n$SuccessFlagFile = \"$env:TEMP\\qqntim-uninstall-successful.tmp\"\r\n\r\nif ((Test-Path $QQNTimFlagFile) -eq $false) {\r\n    throw \"QQNTim 未被安装。\"\r\n}\r\n\r\nif ((Read-Host \"是否要卸载 QQNTim (y/n)？\") -notcontains \"y\") {\r\n    throw \"卸载已被用户取消。\"\r\n}\r\n\r\nif ((Read-Host \"是否需要同时移除所有数据 (y/n)？\") -contains \"y\") {\r\n    Remove-Item \"${env:UserProfile}\\.qqntim\" -Recurse -Force -ErrorAction SilentlyContinue\r\n}\r\n\r\nif ($env:QQNTIM_UNINSTALLER_NO_KILL_QQ -ne \"1\") {\r\n    Write-Output \"正在关闭 QQ……\"\r\n    Stop-Process -Name QQ -ErrorAction SilentlyContinue\r\n}\r\n\r\nWrite-Output \"正在移除文件……\"\r\nif ((Test-Path \"$QQAppLauncherDir\\node_modules.zip.md5\") -eq $true) {\r\n    Remove-Item \"$QQAppLauncherDir\\node_modules.zip.md5\" -Force\r\n}\r\nRemove-Item \"$QQAppLauncherDir\\qqntim.js\", \"$QQAppLauncherDir\\qqntim-renderer.js\", \"$QQAppLauncherDir\\node_modules\", \"$QQAppLauncherDir\\builtins\" -Recurse -Force\r\n\r\nWrite-Output \"正在还原 package.json……\"\r\n$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False\r\n[System.IO.File]::WriteAllLines(\"$QQAppDir\\package.json\", ((Get-Content \"$QQAppDir\\package.json\" -Encoding UTF8 -Force) -replace \"./app_launcher/qqntim.js\", \"./app_launcher/index.js\"), $Utf8NoBomEncoding)\r\n\r\nWrite-Output \"正在还原 QQ.exe……\"\r\nif ((Test-Path $QQExecutableHashFile) -eq $true) {\r\n    Remove-Item $QQExecutableHashFile -Force\r\n}\r\nif ((Test-Path $QQExecutableBackupFile) -eq $true) {\r\n    Remove-Item $QQExecutableFile -Force\r\n    Move-Item $QQExecutableBackupFile $QQExecutableFile -Force\r\n}\r\n\r\nRemove-Item $QQNTimFlagFile -Force\r\n\r\nif ((Test-Path $SuccessFlagFile) -eq $false) {\r\n    \"\" | Out-File $SuccessFlagFile -Encoding UTF8 -Force\r\n}\r\n\r\nif ($env:QQNTIM_UNINSTALLER_NO_DELAYED_EXIT -ne \"1\") {\r\n    Write-Output \"卸载成功。卸载程序将在 5 秒后自动退出。\"\r\n    Start-Sleep -Seconds 5\r\n}\r\nelse {\r\n    Write-Output \"卸载成功。\"\r\n}"
  },
  {
    "path": "publish/install.cmd",
    "content": "@setlocal enableextensions\r\n@echo off\r\ncd /d %~dp0_\r\ncolor F0\r\nmode con cols=65 lines=16\r\n\r\nset PS_PREFIX=powershell -NoProfile -ExecutionPolicy Unrestricted\r\n\r\n\"%SYSTEMROOT%\\system32\\cacls.exe\" \"%SYSTEMROOT%\\system32\\config\\system\" >nul 2>nul \r\nif \"%ERRORLEVEL%\" neq \"0\" (\r\n    goto try_run_as\r\n) else (\r\n    goto main\r\n)\r\ngoto:eof\r\n\r\n:try_run_as\r\n%PS_PREFIX% -WindowStyle Hidden -Command Start-Process -Wait -FilePath \"\"\"%COMSPEC%\"\"\" -Verb RunAs -ArgumentList \"\"\"/c\"\"\",\"\"\"`\"\"\"%~f0`\"\"\"\"\"\"\r\ngoto:eof\r\n\r\n:main\r\nset SUCCESS_FLAG=%TEMP%\\qqntim-install-successful.tmp\r\nif exist \"%SUCCESS_FLAG%\" (\r\n    del /f /q \"%SUCCESS_FLAG%\"\r\n)\r\n%PS_PREFIX% -File .\\install.ps1\r\nif not exist \"%SUCCESS_FLAG%\" (\r\n    echo Installation error. If you believe this is an issue of QQNTim, please report it to us.\r\n    pause >nul 2>nul\r\n)\r\ngoto:eof"
  },
  {
    "path": "publish/install.sh",
    "content": "#!/usr/bin/env bash\n\npushd \"$( dirname \"${BASH_SOURCE[0]}\" )/_\" > /dev/null\n\n# 判断是否拥有 root 权限\nif [ ! \"$(whoami)\" == \"root\" ]; then\n    echo \"正在提升权限……\"\n    popd > /dev/null\n    sudo QQNTIM_INSTALLER_NO_KILL_QQ=\"$QQNTIM_INSTALLER_NO_KILL_QQ\" QQNTIM_INSTALLER_NO_DELAYED_EXIT=\"$QQNTIM_INSTALLER_NO_DELAYED_EXIT\" \"${BASH_SOURCE[0]}\"\n    exit 0\nfi\n\n# 获取 QQ 安装路径\nqq_installation_dir=$( dirname $( readlink $( which qq || which linuxqq ) ) 2>/dev/null || echo \"/var/lib/flatpak/app/com.qq.QQ/current/active/files/extra/QQ\" )\n\nif [ ! -d \"$qq_installation_dir\" ]; then\n    echo \"未找到 QQNT 安装目录。\"\nfi\n\nqq_app_dir=\"$qq_installation_dir/resources/app\"\nqq_applauncher_dir=\"$qq_app_dir/app_launcher\"\nqqntim_flag_file=\"$qq_applauncher_dir/qqntim-flag.txt\"\n\n# 询问用户，如果存在旧版则不提示\nif [ ! -f \"$qqntim_flag_file\" ]; then\n    read -p \"是否要安装 QQNTim (y/n)？\" choice\n    case $choice in\n    y) ;;\n    Y) ;;\n    *) exit -1 ;;\n    esac\nelse\n    echo \"检测到已有安装，正在更新……\"\nfi\n\nif [ \"$QQNTIM_INSTALLER_NO_KILL_QQ\" != \"1\" ]; then\n    echo \"正在关闭 QQ……\"\n    killall -w qq linuxqq > /dev/null 2>&1\nfi\n\necho \"正在复制文件……\"\n\nif [ -f \"./node_modules.zip.md5\" -a -f \"./node_modules.zip\" ]; then\n    diff \"$qq_applauncher_dir/node_modules.zip.md5\" \"./node_modules.zip.md5\" > /dev/null 2>&1\n    [ $? != 0 ] && unzip -qo ./node_modules.zip -d \"$qq_applauncher_dir/node_modules\"\n    cp -f ../node_modules.zip.md5 \"$qq_applauncher_dir\"\nelif [ -d \"./node_modules\" ]; then\n    cp -rf ./node_modules \"$qq_applauncher_dir\"\nfi\ncp -rf ./qqntim.js ./qqntim-renderer.js ./builtins \"$qq_applauncher_dir\"\n\necho \"正在修补 package.json……\"\nsed -i \"s#\\.\\/app_launcher\\/index\\.js#\\.\\/app_launcher\\/qqntim\\.js#g\" \"$qq_app_dir/package.json\"\n\ntouch \"$qqntim_flag_file\"\n\nif [ \"$QQNTIM_INSTALLER_NO_DELAYED_EXIT\" != \"1\" ]; then\n    echo \"安装成功。安装程序将在 5 秒后自动退出。\"\n    sleep 5s\nelse\n    echo \"安装成功。\"\nfi\n\nexit 0\n"
  },
  {
    "path": "publish/install_macos.sh",
    "content": "#!/usr/bin/env bash\n\npushd \"$( dirname \"${BASH_SOURCE[0]}\" )/_\" > /dev/null\n\n# 判断是否拥有 root 权限\nif [ ! \"$(whoami)\" == \"root\" ]; then\n    echo \"正在提升权限……\"\n    popd > /dev/null\n    sudo QQNTIM_INSTALLER_NO_KILL_QQ=\"$QQNTIM_INSTALLER_NO_KILL_QQ\" QQNTIM_INSTALLER_NO_DELAYED_EXIT=\"$QQNTIM_INSTALLER_NO_DELAYED_EXIT\" \"${BASH_SOURCE[0]}\"\n    exit 0\nfi\n\n# 获取 QQ 安装路径\nqq_installation_dir=\"/Applications/QQ.app/Contents\"\n\nif [ ! -d \"$qq_installation_dir\" ]; then\n    echo \"未找到 QQNT 安装目录。\"\nfi\n\nqq_app_dir=\"$qq_installation_dir/Resources/app\"\nqq_applauncher_dir=\"$qq_app_dir/app_launcher\"\nqqntim_flag_file=\"$qq_applauncher_dir/qqntim-flag.txt\"\n\n# 询问用户，如果存在旧版则不提示\nif [ ! -f \"$qqntim_flag_file\" ]; then\n    read -p \"是否要安装 QQNTim (y/n)？\" choice\n    case $choice in\n    y) ;;\n    Y) ;;\n    *) exit -1 ;;\n    esac\nelse\n    echo \"检测到已有安装，正在更新……\"\nfi\n\nif [ \"$QQNTIM_INSTALLER_NO_KILL_QQ\" != \"1\" ]; then\n    echo \"正在关闭 QQ……\"\n    pkill QQ > /dev/null 2>&1\nfi\n\necho \"正在复制文件……\"\n\n# 清理安装目录\nif [ -d \"$qq_applauncher_dir/node_modules\" ]; then\n    rm -rf\nelse\n    mkdir $qq_applauncher_dir/node_modules\nfi\n\nif [ -f \"./node_modules.zip.md5\" -a -f \"./node_modules.zip\" ]; then\n    diff \"$qq_applauncher_dir/node_modules.zip.md5\" \"./node_modules.zip.md5\" > /dev/null 2>&1\n    [ $? != 0 ]\n    unzip -qo ./node_modules.zip -d \"$qq_applauncher_dir/node_modules\"\n    cp -f ./node_modules.zip.md5 \"$qq_applauncher_dir\"\nelif [ -d \"./node_modules\" ]; then\n    cp -rf ./node_modules \"$qq_applauncher_dir\"\nfi\ncp -rf ./qqntim.js ./qqntim-renderer.js ./builtins \"$qq_applauncher_dir\"\n\necho \"正在修补 package.json……\"\nsed -i \"\" \"s#\\.\\/app_launcher\\/index\\.js#\\.\\/app_launcher\\/qqntim\\.js#g\" \"$qq_app_dir/package.json\"\n\ntouch \"$qqntim_flag_file\"\n\nif [ \"$QQNTIM_INSTALLER_NO_DELAYED_EXIT\" != \"1\" ]; then\n    echo \"安装成功。安装程序将在 5 秒后自动退出。\"\n    sleep 5\nelse\n    echo \"安装成功。\"\nfi\n\nexit 0\n"
  },
  {
    "path": "publish/uninstall.cmd",
    "content": "@setlocal enableextensions\r\n@echo off\r\ncd /d %~dp0_\r\ncolor F0\r\nmode con cols=65 lines=16\r\n\r\nset PS_PREFIX=powershell -NoProfile -ExecutionPolicy Unrestricted\r\n\r\n\"%SYSTEMROOT%\\system32\\cacls.exe\" \"%SYSTEMROOT%\\system32\\config\\system\" >nul 2>nul \r\nif \"%ERRORLEVEL%\" neq \"0\" (\r\n    goto try_run_as\r\n) else (\r\n    goto main\r\n)\r\ngoto:eof\r\n\r\n:try_run_as\r\n%PS_PREFIX% -WindowStyle Hidden -Command Start-Process -Wait -FilePath \"\"\"%COMSPEC%\"\"\" -Verb RunAs -ArgumentList \"\"\"/c\"\"\",\"\"\"`\"\"\"%~f0`\"\"\"\"\"\"\r\ngoto:eof\r\n\r\n:main\r\nset SUCCESS_FLAG=%TEMP%\\qqntim-uninstall-successful.tmp\r\nif exist \"%SUCCESS_FLAG%\" (\r\n    del /f /q \"%SUCCESS_FLAG%\"\r\n)\r\n%PS_PREFIX% -File .\\uninstall.ps1\r\nif not exist \"%SUCCESS_FLAG%\" (\r\n    echo Uninstallation error. If you believe this is an issue of QQNTim, please report it to us.\r\n    pause >nul 2>nul\r\n)\r\ngoto:eof"
  },
  {
    "path": "publish/uninstall.sh",
    "content": "#!/usr/bin/env bash\n\npushd \"$( dirname \"${BASH_SOURCE[0]}\" )/_\" > /dev/null\n\n# 判断是否拥有 root 权限\nif [ ! \"$(whoami)\" == \"root\" ]; then\n    echo \"正在提升权限……\"\n    popd > /dev/null\n    sudo QQNTIM_UNINSTALLER_NO_KILL_QQ=\"$QQNTIM_UNINSTALLER_NO_KILL_QQ\" QQNTIM_UNINSTALLER_NO_DELAYED_EXIT=\"$QQNTIM_UNINSTALLER_NO_DELAYED_EXIT\" \"${BASH_SOURCE[0]}\"\n    exit 0\nfi\n\n# 获取 QQ 安装路径\nqq_installation_dir=$( dirname $( readlink $( which qq || which linuxqq ) ) 2>/dev/null || echo \"/var/lib/flatpak/app/com.qq.QQ/current/active/files/extra/QQ\"  )\n\nif [ ! -d \"$qq_installation_dir\" ]; then\n    echo \"未找到 QQNT 安装目录。\"\nfi\n\nqq_app_dir=\"$qq_installation_dir/resources/app\"\nqq_applauncher_dir=\"$qq_app_dir/app_launcher\"\nqqntim_flag_file=\"$qq_applauncher_dir/qqntim-flag.txt\"\n\nif [ ! -f \"$qqntim_flag_file\" ]; then\n    echo \"QQNTim 未被安装。\"\n    exit -1\nfi\n\nread -p \"是否要卸载 QQNTim (y/n)？\" choice\ncase $choice in\n  y) ;;\n  *) exit -1 ;;\nesac\n\nread -p \"是否需要同时移除所有数据 (y/n)？\" choice\ncase $choice in\n  y) rm -rf \"$HOME/.local/share/QQNTim\" ;;\n  *) ;;\nesac\n\nif [ \"$QQNTIM_UNINSTALLER_NO_KILL_QQ\" != \"1\" ]; then\n    echo \"正在关闭 QQ……\"\n    killall -w qq linuxqq > /dev/null 2>&1\nfi\n\necho \"正在移除文件……\"\n[ -f \"$qq_applauncher_dir/node_modules.zip.md5\" ] && rm -f \"$qq_applauncher_dir/node_modules.zip.md5\"\nrm -rf \"$qq_applauncher_dir/qqntim.js\" \"$qq_applauncher_dir/qqntim-renderer.js\" \"$qq_applauncher_dir/node_modules\" \"$qq_applauncher_dir/builtins\"\n\necho \"正在还原 package.json……\"\nsed -i \"s#\\.\\/app_launcher\\/qqntim\\.js#\\.\\/app_launcher\\/index\\.js#g\" \"$qq_app_dir/package.json\"\n\nrm -f \"$qqntim_flag_file\"\n\nif [ \"$QQNTIM_UNINSTALLER_NO_DELAYED_EXIT\" != \"1\" ]; then\n    echo \"卸载成功。卸载程序将在 5 秒后自动退出。\"\n    sleep 5s\nelse\n    echo \"卸载成功。\"\nfi\nexit 0\n"
  },
  {
    "path": "publish/uninstall_macos.sh",
    "content": "#!/usr/bin/env bash\n\npushd \"$( dirname \"${BASH_SOURCE[0]}\" )/_\" > /dev/null\n\n# 判断是否拥有 root 权限\nif [ ! \"$(whoami)\" == \"root\" ]; then\n    echo \"正在提升权限……\"\n    popd > /dev/null\n    sudo QQNTIM_UNINSTALLER_NO_KILL_QQ=\"$QQNTIM_UNINSTALLER_NO_KILL_QQ\" QQNTIM_UNINSTALLER_NO_DELAYED_EXIT=\"$QQNTIM_UNINSTALLER_NO_DELAYED_EXIT\" \"${BASH_SOURCE[0]}\"\n    exit 0\nfi\n\n# 获取 QQ 安装路径\nqq_installation_dir=\"/Applications/QQ.app/Contents\"\n\nif [ ! -d \"$qq_installation_dir\" ]; then\n    echo \"未找到 QQNT 安装目录。\"\nfi\n\nqq_app_dir=\"$qq_installation_dir/Resources/app\"\nqq_applauncher_dir=\"$qq_app_dir/app_launcher\"\nqqntim_flag_file=\"$qq_applauncher_dir/qqntim-flag.txt\"\n\nif [ ! -f \"$qqntim_flag_file\" ]; then\n    echo \"QQNTim 未被安装。\"\n    exit -1\nfi\n\nread -p \"是否要卸载 QQNTim (y/n)？\" choice\ncase $choice in\n  y) ;;\n  *) exit -1 ;;\nesac\n\nread -p \"是否需要同时移除所有数据 (y/n)？\" choice\ncase $choice in\n  y) rm -rf \"$HOME/.local/share/QQNTim\" ;;\n  *) ;;\nesac\n\nif [ \"$QQNTIM_UNINSTALLER_NO_KILL_QQ\" != \"1\" ]; then\n    echo \"正在关闭 QQ……\"\n    pkill QQ > /dev/null 2>&1\nfi\n\necho \"正在移除文件……\"\n[ -f \"$qq_applauncher_dir/node_modules.zip.md5\" ] && rm -f \"$qq_applauncher_dir/node_modules.zip.md5\"\nrm -rf \"$qq_applauncher_dir/qqntim.js\" \"$qq_applauncher_dir/qqntim-renderer.js\" \"$qq_applauncher_dir/node_modules\" \"$qq_applauncher_dir/builtins\"\n\necho \"正在还原 package.json……\"\nsed -i \"\" \"s#\\.\\/app_launcher\\/qqntim\\.js#\\.\\/app_launcher\\/index\\.js#g\" \"$qq_app_dir/package.json\"\n\nrm -f \"$qqntim_flag_file\"\n\nif [ \"$QQNTIM_UNINSTALLER_NO_DELAYED_EXIT\" != \"1\" ]; then\n    echo \"卸载成功。卸载程序将在 5 秒后自动退出。\"\n    sleep 5\nelse\n    echo \"卸载成功。\"\nfi\nexit 0\n"
  },
  {
    "path": "rome.json",
    "content": "{\n    \"$schema\": \"https://docs.rome.tools/schemas/12.1.3/schema.json\",\n    \"organizeImports\": {\n        \"enabled\": true\n    },\n    \"files\": {\n        \"ignore\": [\".pnp.cjs\", \".pnp.loader.mjs\", \".yarn/*\", \"dist/*\", \"src/typings/src/electron.d.ts\"]\n    },\n    \"formatter\": {\n        \"indentSize\": 4,\n        \"indentStyle\": \"space\",\n        \"lineWidth\": 300\n    },\n    \"linter\": {\n        \"enabled\": true,\n        \"rules\": {\n            \"recommended\": true,\n            \"suspicious\": { \"noExplicitAny\": \"off\", \"noDoubleEquals\": \"off\" },\n            \"style\": { \"noParameterAssign\": \"off\", \"noNonNullAssertion\": \"off\" },\n            \"a11y\": { \"all\": false }\n        }\n    }\n}\n"
  },
  {
    "path": "scripts/pack.ps1",
    "content": "﻿$ErrorActionPreference = \"Stop\"\r\n\r\nSet-Location ((Split-Path -Parent $MyInvocation.MyCommand.Definition) + \"\\..\")\r\n$CD = (Get-Location).Path\r\n\r\n\r\n$SourceDirPath = \"$CD\\dist\\_\\node_modules\"\r\n$DestinationZipPath = \"$CD\\dist\\_\\node_modules.zip\"\r\n\r\n# 设置特定时间戳，确保两次构建结果 Hash 不变\r\nGet-ChildItem $SourceDirPath -Recurse | ForEach-Object { $_.LastWriteTimeUtc = \"01/01/1970 08:00:00\"; $_.LastAccessTimeUtc = \"01/01/1970 08:00:00\"; $_.CreationTimeUtc = \"01/01/1970 08:00:00\"; }\r\n\r\n# 打包 node_modules\r\n# 仅支持 .NET Framework 4.5 及以上\r\nAdd-Type -AssemblyName System.IO.Compression.Filesystem\r\n[System.IO.Compression.ZipFile]::CreateFromDirectory($SourceDirPath, $DestinationZipPath)\r\nRemove-Item $SourceDirPath -Recurse -Force\r\n\r\n# 生成 MD5 校验和\r\n$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $false\r\n[System.IO.File]::WriteAllLines($DestinationZipPath, (Get-FileHash \"$DestinationZipPath.md5\" -Algorithm MD5).Hash, $Utf8NoBomEncoding)\r\n"
  },
  {
    "path": "scripts/pack.sh",
    "content": "#!/usr/bin/env bash\n\ncd \"$( dirname \"${BASH_SOURCE[0]}\" )/..\"\n\npushd ./dist/_/node_modules > /dev/null\n\n# 设置特定时间戳，确保两次构建结果 Hash 不变\nfind . -exec touch -d @0 {} +\n\n# 打包 node_modules\nzip -Xyqr9 ../node_modules.zip .\n\npopd > /dev/null\n\nrm -rf ./dist/_/node_modules\n\n# 生成 MD5 校验和\n(md5sum -b ./dist/_/node_modules.zip | cut -d\" \" -f1) > ./dist/_/node_modules.zip.md5"
  },
  {
    "path": "scripts/start.ps1",
    "content": "﻿$ErrorActionPreference = \"Stop\"\r\n\r\nSet-Location ((Split-Path -Parent $MyInvocation.MyCommand.Definition) + \"\\..\")\r\n\r\n# 从注册表获取 QQ 安装路径\r\nforeach ($RegistryPath in @(\"HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\", \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*\")) {\r\n    try {\r\n        foreach ($Item in (Get-ItemProperty $RegistryPath)) {\r\n            if ($Item.PSChildName -eq \"QQ\") {\r\n                $QQInstallDir = (Split-Path -Parent $Item.UninstallString)\r\n                break\r\n            }\r\n        }\r\n    }\r\n    catch {}\r\n}\r\n\r\nif (($null -eq $QQInstallDir) -or ((Test-Path $QQInstallDir) -eq $false)) {\r\n    throw \"未找到 QQNT 安装目录。\"\r\n}\r\n\r\nStart-Process \"$QQInstallDir\\QQ.exe\" -Wait "
  },
  {
    "path": "scripts/start.sh",
    "content": "#!/usr/bin/env bash\n\ncd \"$( dirname \"${BASH_SOURCE[0]}\" )/..\"\n\n( qq || linuxqq || flatpak run com.qq.QQ ) 2>&1 | sed -e '/NODE_TLS_REJECT_UNAUTHORIZED/d' -e '/Gtk-Message/d' -e '/to show where the warning was created/d' -e '/gbm_wrapper\\.cc/d' -e '/node_bindings\\.cc/d' -e '/UnhandledPromiseRejectionWarning/d' -e '/\\[BuglyManager\\.cpp\\]/d' -e '/\\[NativeCrashHandler\\.cpp\\]/d' -e '/\\[BuglyService\\.cpp\\]/d' -e '/\\[HotUpdater\\]/d' -e '/ERROR:CONSOLE/d'\n"
  },
  {
    "path": "src/builtins/settings/package.json",
    "content": "{\n    \"name\": \"@flysoftbeta/qqntim-plugin-settings\",\n    \"private\": true,\n    \"devDependencies\": {\n        \"@flysoftbeta/qqntim-typings\": \"workspace:*\",\n        \"@types/node\": \"^20.6.2\",\n        \"@types/react\": \"^18.2.21\",\n        \"@types/react-dom\": \"^18.2.7\",\n        \"@types/unzipper\": \"^0.10.7\"\n    },\n    \"dependencies\": {\n        \"unzipper\": \"^0.10.14\"\n    }\n}\n"
  },
  {
    "path": "src/builtins/settings/publish/qqntim.json",
    "content": "{\n    \"manifestVersion\": \"3.0\",\n    \"id\": \"builtin-settings-ui\",\n    \"name\": \"设置\",\n    \"author\": \"Flysoft\",\n    \"injections\": [\n        {\n            \"type\": \"renderer\",\n            \"page\": \"settings\",\n            \"stylesheet\": \"style.css\",\n            \"script\": \"renderer.js\"\n        }\n    ]\n}\n"
  },
  {
    "path": "src/builtins/settings/publish/style.css",
    "content": ".q-switch {\n    position: relative;\n}\n\n.q-switch > input {\n    position: absolute;\n    left: 0;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    appearance: none !important;\n    margin: 0;\n    z-index: 10;\n}\n\n.q-button {\n    margin: 0 !important;\n}\n\n.qqntim-settings-panel-open\n    .setting-main\n    .setting-main__content:not(.qqntim-settings-panel),\nbody:not(.qqntim-settings-panel-open)\n    .setting-main\n    .setting-main__content.qqntim-settings-panel {\n    display: none !important;\n}\n\n.qqntim-settings-panel {\n    padding: 20px 16px 70px !important;\n}\n\n.qqntim-settings-panel-section-header {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    justify-content: space-between;\n    padding: 8px;\n}\n\n.qqntim-settings-panel-section-header-title {\n    font-size: min(var(--font_size_2), 18px) !important;\n}\n\n.qqntim-settings-panel-section-header-buttons {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    gap: 5px;\n}\n\n.qqntim-settings-panel-section-content {\n    border-radius: 5px;\n    padding: 0 16px;\n    background-color: var(--fg_white);\n}\n\n.qqntim-settings-panel-settings-versions {\n    display: flex;\n    flex-direction: row;\n    justify-content: space-between;\n    gap: 5px;\n    padding: 16px 0;\n}\n\n.qqntim-settings-panel-settings-versions-item {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    gap: 5px;\n    white-space: nowrap;\n    flex: 10;\n}\n\n.qqntim-settings-panel-settings-versions-item > h3 {\n    font-size: min(var(--font_size_3), 18px) !important;\n}\n\n.qqntim-settings-panel-settings-versions-item > div {\n    font-size: min(var(--font_size_2), 16px) !important;\n    color: var(--text_secondary_01);\n}\n\n.qqntim-settings-panel-box {\n    display: flex;\n    flex-direction: column;\n}\n\n.qqntim-settings-panel-box-item {\n    display: flex;\n    flex-direction: row;\n    justify-content: space-between;\n    align-items: center;\n    width: 100%;\n    min-height: 44px;\n    padding: 8px 0;\n}\n\n.qqntim-settings-panel-box-item > span {\n    display: flex;\n    flex-direction: column;\n    justify-content: center;\n}\n\n.qqntim-settings-panel-box-item > div {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    gap: 5px;\n}\n\n.qqntim-settings-panel-box-item-title {\n    font-size: min(var(--font_size_3), 18px) !important;\n}\n\n.qqntim-settings-panel-box-item-description {\n    font-size: min(var(--font_size_2), 16px) !important;\n    color: var(--text_secondary_01);\n}\n\n.qqntim-settings-panel-box-item:not(.qqntim-settings-panel-box-item-last) {\n    border-bottom: 1px solid var(--divider_standard);\n}\n\n.qqntim-settings-panel-save {\n    position: fixed;\n    right: 20px;\n    bottom: 20px;\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    gap: 10px;\n    z-index: 100;\n}\n"
  },
  {
    "path": "src/builtins/settings/src/_renderer.tsx",
    "content": "import * as exports from \"./exports\";\nimport * as exportsComponents from \"./exports/components\";\nimport { Navigation, TabWithOtherTab } from \"./nav\";\nimport { Panel } from \"./panel\";\nimport { cl } from \"./utils/consts\";\nimport { defineModules, nt, utils } from \"qqntim/renderer\";\nimport { createRoot } from \"react-dom/client\";\n\nexport default class Entry implements QQNTim.Entry.Renderer {\n    constructor() {\n        defineModules({ \"qqntim-settings\": exports as typeof QQNTim.Settings, \"qqntim-settings/components\": exportsComponents as typeof QQNTim.SettingsComponents });\n\n        Promise.all([nt.getAccountInfo(), utils.waitForElement<HTMLElement>(\".nav-bar:not(.qqntim-settings-nav)\"), utils.waitForElement<HTMLElement>(\".setting-main\"), utils.waitForElement<HTMLElement>(`.setting-main .setting-main__content:not(.${cl.panel.c})`)]).then(\n            ([account, nav, panel, panelContent]) => {\n                if (!account) throw new Error(\"获取当前账户信息时失败\");\n\n                const panelVueId = utils.getVueId(panelContent)!;\n                const panelContainer = document.createElement(\"div\");\n                panelContainer.classList.add(\"setting-main__content\", cl.panel.c);\n                panelContainer.setAttribute(panelVueId, \"\");\n                const panelRoot = createRoot(panelContainer);\n                const renderPanel = (currentTab: TabWithOtherTab) => {\n                    panelRoot.render(<Panel currentTab={currentTab} account={account} />);\n                };\n                panel.appendChild(panelContainer);\n\n                const navVueId = utils.getVueId(nav.firstElementChild as HTMLElement)!;\n                const navContainer = document.createElement(\"div\");\n                navContainer.classList.add(cl.nav.c);\n                const navRoot = createRoot(navContainer);\n                const renderNav = () => {\n                    navRoot.render(<Navigation vueId={navVueId} onCurrentTabChange={renderPanel} />);\n                };\n                nav.appendChild(navContainer);\n                exports.setRenderNavFunction(renderNav);\n                renderNav();\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "src/builtins/settings/src/exports/components.tsx",
    "content": "import { cl } from \"../utils/consts\";\nimport { Fragment, ReactNode, useState } from \"react\";\n\nexport function SettingsSection({ title, children, buttons }: { title: string; children: ReactNode; buttons?: ReactNode }) {\n    return (\n        <div className={cl.panel.section.c}>\n            <span className={cl.panel.section.header.c}>\n                <h2 className={cl.panel.section.header.title.c}>{title}</h2>\n                {!!buttons && <div className={cl.panel.section.header.buttons.c}>{buttons}</div>}\n            </span>\n            <div className={cl.panel.section.content.c}>{children}</div>\n        </div>\n    );\n}\n\nexport function SettingsBox({ children }: { children: ReactNode }) {\n    return <div className={cl.panel.box.c}>{children}</div>;\n}\n\nexport function SettingsBoxItem({ title, description, children, isLast = false }: { title: string; description?: string[]; children?: ReactNode; isLast?: boolean }) {\n    return (\n        <label className={`${cl.panel.box.item.c}${isLast ? ` ${cl.panel.box.item.last.c}` : \"\"}`}>\n            <span>\n                <span className={cl.panel.box.item.title.c}>{title}</span>\n                {description ? (\n                    <span className={cl.panel.box.item.description.c}>\n                        {description.map((text, idx, array) => {\n                            return (\n                                // rome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n                                <Fragment key={idx}>\n                                    <span>{text}</span>\n                                    {idx != array.length - 1 && <br />}\n                                </Fragment>\n                            );\n                        })}\n                    </span>\n                ) : null}\n            </span>\n            <div>{children}</div>\n        </label>\n    );\n}\n\nexport function Switch({ checked, onToggle }: { checked: boolean; onToggle: (checked: boolean) => void }) {\n    return (\n        <div className={`q-switch${checked ? \" is-active\" : \"\"}`} onClick={() => onToggle(!checked)}>\n            <input type=\"checkbox\" checked={checked} onChange={(event) => onToggle(event.target.checked)} />\n            <div className=\"q-switch__handle\" />\n        </div>\n    );\n}\n\nexport function Input({ value, onChange, width }: { value: string; onChange: (value: string) => void; width }) {\n    const [focus, setFocus] = useState<boolean>(false);\n\n    return (\n        <div className=\"q-input\" style={{ border: \"1px solid var(--divider_dark)\", height: \"26px\", width: width, background: \"var(--bg_white)\", boxSizing: \"border-box\", position: \"relative\" }}>\n            <input\n                type=\"text\"\n                className=\"q-input__inner\"\n                value={value}\n                onChange={(event) => onChange(event.target.value)}\n                onFocus={() => setFocus(true)}\n                onBlur={() => setFocus(false)}\n                spellCheck={false}\n                style={{\n                    fontSize: \"12px\",\n                    height: \"26px\",\n                    lineHeight: \"26px\",\n                    padding: \"0 32px 0 8px\",\n                    border: \"1px solid transparent\",\n                    borderRadius: \"4px\",\n                    boxSizing: \"border-box\",\n                    ...(focus && {\n                        border: \" 1px solid var(--brand_standard)\",\n                        borderRadius: \"4px\",\n                        caretColor: \"var(--brand_standard)\",\n                    }),\n                }}\n            />\n        </div>\n    );\n}\n\nexport function Dropdown<T>({ items, selected, onChange, width }: { items: [T, string][]; selected: T; onChange: (id: T) => void; width: string }) {\n    const [open, setOpen] = useState<boolean>(false);\n    const [selectedId, selectedContent] = items.find(([id]) => id == selected)!;\n\n    return (\n        <div className=\"q-pulldown-menu small-size\" style={{ width: width }}>\n            <div className=\"q-pulldown-menu-button\" onClick={() => setOpen((prev) => !prev)}>\n                <div className=\"content\">{selectedContent}</div>\n                <span className=\"icon\">\n                    <i\n                        className=\"q-icon\"\n                        style={{\n                            width: \"16px\",\n                            height: \"16px\",\n                            color: \"inherit\",\n                            alignItems: \"center\",\n                            display: \"inline-flex\",\n                            justifyContent: \"center\",\n                        }}\n                    >\n                        <svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ width: \"16px\", height: \"16px\" }}>\n                            <path d=\"M12 6.0001L8.00004 10L4 6\" stroke=\"currentColor\" strokeLinejoin=\"round\" />\n                        </svg>\n                    </i>\n                </span>\n            </div>\n            {open && (\n                <div className=\"q-pulldown-menu-wrapper\">\n                    <ul className=\"q-pulldown-menu-list\" style={{ maxHeight: \"unset\" }}>\n                        {items.map(([id, content]) => {\n                            const isSelected = id == selectedId;\n                            return (\n                                <li\n                                    className={`q-pulldown-menu-list-item${isSelected ? \" selected\" : \"\"}`}\n                                    tabIndex={0}\n                                    onClick={() => {\n                                        onChange(id);\n                                        setOpen(false);\n                                    }}\n                                >\n                                    <span className=\"content\">{content}</span>\n                                    {isSelected && (\n                                        <span className=\"icon\">\n                                            <i\n                                                className=\"q-icon\"\n                                                style={{\n                                                    width: \"1em\",\n                                                    height: \"1em\",\n                                                    color: \"inherit\",\n                                                    alignItems: \"center\",\n                                                    display: \"inline-flex\",\n                                                    justifyContent: \"center\",\n                                                }}\n                                            >\n                                                <svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ width: \"1em\", height: \"1em\" }}>\n                                                    <path d=\"M2 7L6.00001 11L14 3\" stroke=\"currentColor\" strokeLinejoin=\"round\" />\n                                                </svg>\n                                            </i>\n                                        </span>\n                                    )}\n                                </li>\n                            );\n                        })}\n                    </ul>\n                </div>\n            )}\n        </div>\n    );\n}\n\nexport function Button({ onClick, primary, small, children }: { onClick: () => void; primary: boolean; small: boolean; children: ReactNode }) {\n    return (\n        <button className={`q-button q-button--default ${primary ? \"q-button--primary\" : \"q-button--secondary\"}${small ? \" q-button--small\" : \"\"}`} onClick={() => onClick()}>\n            <span className=\"q-button__slot-warp\">{children}</span>\n        </button>\n    );\n}\n"
  },
  {
    "path": "src/builtins/settings/src/exports/index.ts",
    "content": "export const panels: [string, QQNTim.Settings.Panel, string | undefined][] = [];\nlet renderNav: Function = () => undefined;\n\nexport function defineSettingsPanels(...newSettingsPanels: [string, QQNTim.Settings.Panel, string | undefined][]) {\n    panels.push(...newSettingsPanels);\n    renderNav();\n}\n\nexport function setRenderNavFunction(newFunction: Function) {\n    renderNav = newFunction;\n}\n"
  },
  {
    "path": "src/builtins/settings/src/installer.ts",
    "content": "import { s } from \"./utils/sep\";\nimport { randomUUID } from \"crypto\";\nimport * as path from \"path\";\nimport { allPlugins, app, dialog, env, modules } from \"qqntim/renderer\";\nimport { Extract } from \"unzipper\";\nconst { fs } = modules;\n\nexport async function installZipPluginsForAccount(uin: string, requiresRestart: boolean) {\n    const result = await dialog.openDialog({ title: \"选择插件压缩包\", properties: [\"openFile\"], filters: [{ name: \"ZIP 压缩文件\", extensions: [\"zip\"] }] });\n    if (result.canceled) return;\n    const filePath = result.filePaths[0];\n    if (!(await fs.exists(filePath)) || !(await fs.stat(filePath)).isFile()) return;\n    const tmpDir = `${process.platform == \"win32\" ? process.env[\"TEMP\"] : \"/tmp\"}${s}${randomUUID()}`;\n\n    try {\n        await fs.ensureDir(tmpDir);\n        await new Promise<void>((resolve, reject) =>\n            fs\n                .createReadStream(result.filePaths[0])\n                .pipe(Extract({ path: tmpDir }))\n                .on(\"close\", () => resolve())\n                .on(\"error\", (error) => reject(error)),\n        );\n    } catch (reason) {\n        await dialog.alert(\"解压插件压缩包时出现错误：\\n\" + reason);\n        return false;\n    }\n\n    return await installPluginsForAccount(uin, requiresRestart, tmpDir);\n}\n\nexport async function installFolderPluginsForAccount(uin: string, requiresRestart: boolean) {\n    const result = await dialog.openDialog({ title: \"选择插件文件夹\", properties: [\"openDirectory\"] });\n    if (result.canceled) return;\n    const filePath = result.filePaths[0];\n    if (!(await fs.exists(filePath)) || !(await fs.stat(filePath)).isDirectory()) return false;\n\n    return await installPluginsForAccount(uin, requiresRestart, filePath);\n}\n\nasync function collectManifests(dir: string) {\n    const getManifestFile = async (dir: string) => {\n        const manifestFile = `${dir}${s}qqntim.json`;\n        if ((await fs.exists(manifestFile)) && (await fs.stat(manifestFile)).isFile()) return manifestFile;\n    };\n\n    let manifestFiles: string[] = [];\n    const manifestFile = await getManifestFile(dir);\n    if (!manifestFile) {\n        const folders = await fs.readdir(dir);\n        manifestFiles = (\n            await Promise.all(\n                folders.map(async (folder) => {\n                    const folderPath = `${dir}${s}${folder}`;\n                    if ((await fs.exists(folderPath)) && (await fs.stat(folderPath)).isDirectory()) {\n                        return await getManifestFile(folderPath);\n                    }\n                }),\n            )\n        ).filter(Boolean) as string[];\n    } else manifestFiles = [manifestFile];\n\n    return manifestFiles;\n}\n\nasync function installPluginsForAccount(uin: string, requiresRestart: boolean, dir: string) {\n    const manifestFiles = await collectManifests(dir);\n    if (manifestFiles.length == 0) {\n        await dialog.alert(\"未在目标文件夹或文件夹搜索到任何插件。\\n请联系插件作者以获得更多信息。\");\n        return false;\n    }\n\n    let count = 0;\n    for (const manifestFile of manifestFiles) {\n        const manifest = fs.readJSONSync(manifestFile) as QQNTim.Manifest;\n        const pluginDir = `${uin == \"\" ? env.path.pluginDir : `${env.path.pluginPerUserDir}${s}${uin}`}${s}${manifest.id}`;\n        if (!(await dialog.confirm(`扫描到一个插件：\\n\\nID：${manifest.id}\\n名称：${manifest.name}\\n作者：${manifest.author || \"未知\"}\\n说明：${manifest.description || \"该插件没有提供说明。\"}\\n\\n是否希望安装此插件？`))) continue;\n        try {\n            if (allPlugins[uin]?.[manifest.id]) await fs.rm(allPlugins[uin][manifest.id].dir);\n            await fs.ensureDir(pluginDir);\n            await fs.copy(path.dirname(manifestFile), pluginDir);\n            count++;\n        } catch (reason) {\n            await dialog.alert(\"复制插件时出现错误：\\n\" + reason);\n        }\n    }\n\n    await dialog.alert(`成功安装了 ${count} 个插件。${requiresRestart ? `\\n\\n点击 \"确定\" 将重启你的 QQ。` : \"\"}`);\n    if (requiresRestart) app.relaunch();\n    return true;\n}\n\nexport async function uninstallPlugin(requiresRestart: boolean, pluginDir: string) {\n    if (!(await dialog.confirm(\"是否要卸载此插件？\"))) return false;\n    try {\n        await fs.remove(pluginDir);\n        await dialog.alert(`成功卸载此插件。${requiresRestart ? `\\n\\n点击 \"确定\" 将重启你的 QQ。` : \"\"}`);\n        if (requiresRestart) app.relaunch();\n        return true;\n    } catch (reason) {\n        await dialog.alert(`卸载插件时出现错误：\\n${reason}`);\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/builtins/settings/src/main.ts",
    "content": ""
  },
  {
    "path": "src/builtins/settings/src/nav.tsx",
    "content": "import { panels } from \"./exports\";\nimport { cl } from \"./utils/consts\";\nimport { utils } from \"qqntim/renderer\";\nimport { Fragment, useEffect, useState } from \"react\";\n\ninterface OtherTab {\n    key?: undefined;\n    type?: undefined;\n    title?: string;\n    icon?: string;\n}\n\ninterface PluginsManagerTab {\n    key: string;\n    type: \"plugins-manager\";\n    title: string;\n    icon: string;\n}\n\ninterface SettingsTab {\n    key: string;\n    type: \"settings\";\n    title: string;\n    icon: string;\n}\n\ninterface PluginTab {\n    key: string;\n    type: \"plugin\";\n    title: string;\n    icon: string | undefined;\n    node: QQNTim.Settings.Panel;\n}\n\nexport type Tab = PluginsManagerTab | SettingsTab | PluginTab;\nexport type TabWithOtherTab = Tab | OtherTab;\n\nexport function Navigation({ vueId, onCurrentTabChange }: { vueId: string; onCurrentTabChange: (tab: TabWithOtherTab) => void }) {\n    const [currentTab, setCurrentTab] = useState<TabWithOtherTab>({});\n    useEffect(() => {\n        utils.waitForElement<HTMLElement>(\".nav-bar\").then((element) =>\n            element.addEventListener(\"click\", (event) => {\n                const item = (event.target as HTMLElement).closest(\".nav-item\");\n                if (!item) return;\n                if (item.classList.contains(cl.nav.item.c)) return;\n                item.classList.toggle(\"nav-item-active\", true);\n\n                const title = item.firstElementChild?.nextElementSibling as HTMLElement;\n                if (title) setCurrentTab({ title: title.innerText });\n            }),\n        );\n    }, []);\n    useEffect(() => {\n        if (currentTab.type) utils.waitForElement<HTMLElement>(`.nav-item.nav-item-active:not(.${cl.nav.item.c})`).then((element) => element.classList.remove(\"nav-item-active\"));\n        onCurrentTabChange(currentTab);\n    }, [currentTab]);\n\n    const tabs: Tab[] = [\n        {\n            key: \"settings\",\n            type: \"settings\",\n            title: \"QQNTim 设置\",\n            icon: `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8 2.15771L13 5.07438L13 10.9256L8 13.8423L3 10.9256L3 5.07438L8 2.15771ZM7.49613 1.29394C7.80749 1.11231 8.19251 1.11231 8.50387 1.29394L13.5039 4.2106C13.8111 4.38981 14 4.71871 14 5.07438V10.9256C14 11.2813 13.8111 11.6102 13.5039 11.7894L8.50387 14.7061C8.19251 14.8877 7.80749 14.8877 7.49613 14.7061L2.49613 11.7894C2.18891 11.6102 2 11.2813 2 10.9256V5.07438C2 4.71871 2.18891 4.38981 2.49613 4.2106L7.49613 1.29394ZM10.2633 6.09507L5 9.13385L5.5 9.99988L10.7633 6.96109L10.2633 6.09507Z\" fill=\"currentColor\"></path></svg>`,\n        },\n        {\n            key: \"plugins-manager\",\n            type: \"plugins-manager\",\n            title: \"插件管理\",\n            icon: `<svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3.75\" y=\"3.75\" width=\"6.5\" height=\"6.5\" rx=\"1.25\" stroke=\"currentColor\" stroke-width=\"1.5\"></rect><rect x=\"12.4038\" y=\"7\" width=\"6.5\" height=\"6.5\" rx=\"1.25\" transform=\"rotate(-45 12.4038 7)\" stroke=\"currentColor\" stroke-width=\"1.5\"></rect><rect x=\"3.75\" y=\"13.75\" width=\"6.5\" height=\"6.5\" rx=\"1.25\" stroke=\"currentColor\" stroke-width=\"1.5\"></rect><rect x=\"13.75\" y=\"13.75\" width=\"6.5\" height=\"6.5\" rx=\"1.25\" stroke=\"currentColor\" stroke-width=\"1.5\"></rect></svg>`,\n        },\n        ...panels.map(([title, node, icon], idx): PluginTab => {\n            return {\n                key: `plugin-${idx}`,\n                type: \"plugin\",\n                title: title,\n                icon: icon,\n                node: node,\n            };\n        }),\n    ];\n\n    return (\n        <Fragment>\n            {tabs.map((item) => (\n                <div key={item.key} className={`nav-item ${cl.nav.item.c}${currentTab.key == item.key ? \" nav-item-active\" : \"\"}`} onClick={() => setCurrentTab(item)} {...{ [vueId]: \"\" }}>\n                    {!!item.icon && (\n                        <i\n                            className=\"q-icon icon\"\n                            /* rome-ignore lint/security/noDangerouslySetInnerHtml: <explanation> */\n                            dangerouslySetInnerHTML={{ __html: item.icon }}\n                            style={{\n                                width: \"16px\",\n                                height: \"16px\",\n                                marginRight: \"8px\",\n                                alignItems: \"center\",\n                                color: \"inherit\",\n                                display: \"inline-flex\",\n                                justifyContent: \"center\",\n                            }}\n                        />\n                    )}\n                    <div className=\"name\" {...{ [vueId]: \"\" }}>\n                        {item.title}\n                    </div>\n                </div>\n            ))}\n        </Fragment>\n    );\n}\n"
  },
  {
    "path": "src/builtins/settings/src/panel.tsx",
    "content": "import { Button, SettingsBox, SettingsBoxItem, SettingsSection, Switch } from \"./exports/components\";\nimport { installFolderPluginsForAccount, installZipPluginsForAccount, uninstallPlugin } from \"./installer\";\nimport { TabWithOtherTab } from \"./nav\";\nimport { cl } from \"./utils/consts\";\nimport { enablePlugin, getPluginDescription, isInBlacklist, isInWhitelist, isPluginsExistent } from \"./utils/utils\";\nimport { shell } from \"electron\";\nimport { allPlugins, app, env, modules, utils } from \"qqntim/renderer\";\nimport { useEffect, useState } from \"react\";\nconst { fs } = modules;\n\ninterface PanelProps {\n    account: QQNTim.API.Renderer.NT.LoginAccount;\n    config: Required<QQNTim.Configuration>;\n    setConfig: React.Dispatch<React.SetStateAction<Required<QQNTim.Configuration>>>;\n}\n\nexport function Panel({ currentTab, account }: { currentTab: TabWithOtherTab; account: QQNTim.API.Renderer.NT.LoginAccount }) {\n    const [config, setConfig] = useState<Required<QQNTim.Configuration>>(env.config);\n    const [pluginsConfig, setPluginsConfig] = useState<Record<string, object>>(config.plugins.config || {});\n\n    const saveConfigAndRestart = () => {\n        fs.writeJSONSync(env.path.configFile, config);\n        app.relaunch();\n    };\n\n    const resetConfigAndRestart = () => {\n        fs.writeJSONSync(env.path.configFile, {});\n        app.relaunch();\n    };\n\n    useEffect(\n        () =>\n            setConfig((prev) => {\n                return { ...prev, plugins: { ...prev.plugins, config: pluginsConfig } };\n            }),\n        [pluginsConfig],\n    );\n\n    useEffect(() => {\n        document.body.classList.toggle(cl.panel.open.c, !!currentTab.type);\n        utils.waitForElement<HTMLElement>(\".setting-title\").then((element) => {\n            if (element.__VUE__?.[0]?.props?.title && currentTab.title) element.__VUE__[0].props.title = currentTab.title;\n        });\n    }, [currentTab]);\n\n    const panelProps: PanelProps = {\n        account,\n        config,\n        setConfig,\n    };\n\n    return (\n        <>\n            {currentTab.type == \"settings\" ? <SettingsPanel {...panelProps} /> : currentTab.type == \"plugins-manager\" ? <PluginsManagerPanel {...panelProps} /> : currentTab.type == \"plugin\" ? <currentTab.node config={pluginsConfig} setConfig={setPluginsConfig} /> : null}\n            <div className={cl.panel.save.c}>\n                <Button onClick={() => resetConfigAndRestart()} small={false} primary={false}>\n                    重置所有设置并重启\n                </Button>\n                <Button onClick={() => saveConfigAndRestart()} small={false} primary={true}>\n                    保存并重启\n                </Button>\n            </div>\n        </>\n    );\n}\n\nfunction SettingsPanel({ config, setConfig }: PanelProps) {\n    return (\n        <>\n            <SettingsSection title=\"版本信息\">\n                <div className={cl.panel.settings.versions.c}>\n                    {[\n                        [\"QQNTim\", process.versions.qqntim],\n                        [\"QQNT\", process.versions.qqnt],\n                        [\"Electron\", process.versions.electron],\n                        [\"Node.js\", process.versions.node],\n                        [\"Chromium\", process.versions.chrome],\n                        [\"V8\", process.versions.v8],\n                    ].map(([name, version]) => (\n                        <div key={name} className={cl.panel.settings.versions.item.c}>\n                            <h3>{name}</h3>\n                            <div>{version}</div>\n                        </div>\n                    ))}\n                </div>\n            </SettingsSection>\n            <SettingsSection title=\"选项\">\n                <SettingsBox>\n                    {(\n                        [\n                            [\n                                \"显示详细日志输出\",\n                                \"开启后，可以在控制台内查看到 IPC 通信、部分 Electron 对象的成员访问信息等。\",\n                                config.verboseLogging,\n                                (state: boolean) =>\n                                    setConfig((prev) => {\n                                        return { ...prev, verboseLogging: state };\n                                    }),\n                            ],\n                            [\n                                \"使用原版 DevTools\",\n                                \"使用 Chromium DevTools 而不是 chii DevTools (Windows 版 9.8.5 及以上不可用)。\",\n                                config.useNativeDevTools,\n                                (state) =>\n                                    setConfig((prev) => {\n                                        return { ...prev, useNativeDevTools: state };\n                                    }),\n                            ],\n                            [\n                                \"禁用兼容性处理\",\n                                \"禁用后，LiteLoader 可能将不能与 QQNTim 一起使用。\",\n                                config.disableCompatibilityProcessing,\n                                (state) =>\n                                    setConfig((prev) => {\n                                        return { ...prev, disableCompatibilityProcessing: state };\n                                    }),\n                            ],\n                        ] as [string, string, boolean, (state: boolean) => void][]\n                    ).map(([title, description, value, setValue], idx, array) => (\n                        // rome-ignore lint/suspicious/noArrayIndexKey: <explanation>\n                        <SettingsBoxItem key={idx} title={title} description={[description]} isLast={idx == array.length - 1}>\n                            <Switch checked={value} onToggle={setValue} />\n                        </SettingsBoxItem>\n                    ))}\n                </SettingsBox>\n            </SettingsSection>\n        </>\n    );\n}\n\nfunction PluginsManagerPanel({ account, config, setConfig }: PanelProps) {\n    const [existentPlugins, setExistentPlugins] = useState<string[]>(isPluginsExistent());\n\n    return Array.from(new Set([...Object.keys(allPlugins), account.uin]))\n        .sort()\n        .map((uin: string) => {\n            const plugins = allPlugins[uin] || {};\n            const requiresRestart = uin == account.uin || uin == \"\";\n            const isEmpty = Object.keys(plugins).length == 0;\n            if (uin != account.uin && isEmpty) return;\n            return (\n                <SettingsSection\n                    key={uin}\n                    title={uin == \"\" ? \"对所有账号生效的插件\" : `仅对账号 ${uin} 生效的插件`}\n                    buttons={\n                        <>\n                            <Button onClick={() => installZipPluginsForAccount(uin, requiresRestart)} primary={false} small={true}>\n                                安装插件压缩包 (.zip)\n                            </Button>\n                            <Button onClick={() => installFolderPluginsForAccount(uin, requiresRestart)} primary={false} small={true}>\n                                安装插件文件夹\n                            </Button>\n                        </>\n                    }\n                >\n                    <SettingsBox>\n                        {!isEmpty ? (\n                            Object.keys(plugins)\n                                .sort()\n                                .map((id, idx, array) => {\n                                    const plugin = plugins[id];\n                                    const inWhitelist = isInWhitelist(id, config.plugins.whitelist);\n                                    const inBlacklist = isInBlacklist(id, config.plugins.blacklist);\n                                    const description = getPluginDescription(plugin);\n\n                                    if (!existentPlugins.includes(id)) return;\n                                    return (\n                                        <SettingsBoxItem key={id} title={plugin.manifest.name} description={description} isLast={idx == array.length - 1}>\n                                            <Switch checked={!!(inWhitelist || (!inWhitelist && !inBlacklist))} onToggle={(state) => enablePlugin(setConfig, id, state, inWhitelist, inBlacklist)} />\n                                            <Button onClick={() => shell.openPath(plugin.dir)} small={true} primary={false}>\n                                                文件夹\n                                            </Button>\n                                            <Button onClick={() => uninstallPlugin(requiresRestart, plugin.dir).then((success) => success && setExistentPlugins((prev) => prev.filter((pluginId) => pluginId != id)))} small={true} primary={false}>\n                                                删除\n                                            </Button>\n                                        </SettingsBoxItem>\n                                    );\n                                })\n                        ) : (\n                            <SettingsBoxItem title=\"此处还没有任何插件 :(\" isLast={true} />\n                        )}\n                    </SettingsBox>\n                </SettingsSection>\n            );\n        });\n}\n"
  },
  {
    "path": "src/builtins/settings/src/qqntim-env.d.ts",
    "content": "/// <reference types=\"@flysoftbeta/qqntim-typings\" />\n"
  },
  {
    "path": "src/builtins/settings/src/renderer.ts",
    "content": "import Entry from \"./_renderer\";\nexport default Entry;\n"
  },
  {
    "path": "src/builtins/settings/src/utils/consts.ts",
    "content": "export const cl = {\n    nav: {\n        c: \"qqntim-settings-nav\",\n        item: {\n            c: \"qqntim-settings-nav-item\",\n        },\n    },\n    panel: {\n        c: \"qqntim-settings-panel\",\n        open: {\n            c: \"qqntim-settings-panel-open\",\n        },\n        settings: {\n            versions: {\n                c: \"qqntim-settings-panel-settings-versions\",\n                item: {\n                    c: \"qqntim-settings-panel-settings-versions-item\",\n                },\n            },\n        },\n        section: {\n            c: \"qqntim-settings-panel-section\",\n            header: {\n                c: \"qqntim-settings-panel-section-header\",\n                title: {\n                    c: \"qqntim-settings-panel-section-header-title\",\n                },\n                buttons: {\n                    c: \"qqntim-settings-panel-section-header-buttons\",\n                },\n            },\n            content: {\n                c: \"qqntim-settings-panel-section-content\",\n            },\n        },\n        box: {\n            c: \"qqntim-settings-panel-box\",\n            item: {\n                c: \"qqntim-settings-panel-box-item\",\n                last: {\n                    c: \"qqntim-settings-panel-box-item-last\",\n                },\n                title: {\n                    c: \"qqntim-settings-panel-box-item-title\",\n                },\n                description: {\n                    c: \"qqntim-settings-panel-box-item-description\",\n                },\n            },\n        },\n        save: {\n            c: \"qqntim-settings-panel-save\",\n        },\n    },\n};\n"
  },
  {
    "path": "src/builtins/settings/src/utils/hooks.tsx",
    "content": "import { useEffect, useRef } from \"react\";\n\n// Thanks https://learnersbucket.com/examples/interview/useprevious-hook-in-react/\nexport function usePrevious<T>(value: T) {\n    const ref = useRef<T>();\n\n    useEffect(() => {\n        ref.current = value;\n    }, [value]);\n\n    return ref.current;\n}\n"
  },
  {
    "path": "src/builtins/settings/src/utils/sep.ts",
    "content": "export { sep as s } from \"path\";\n"
  },
  {
    "path": "src/builtins/settings/src/utils/utils.ts",
    "content": "import { allPlugins, modules } from \"qqntim/renderer\";\nconst { fs } = modules;\n\nexport function isInWhitelist(id: string, whitelist?: string[]) {\n    return !!(whitelist && !whitelist.includes(id));\n}\nexport function isInBlacklist(id: string, blacklist?: string[]) {\n    return !!blacklist?.includes(id);\n}\n\nfunction addItemToArray<T>(array: T[], item: T) {\n    return [...array, item];\n}\nfunction removeItemFromArray<T>(array: T[], item: T) {\n    return array.filter((value) => value != item);\n}\nexport function enablePlugin(setConfig: React.Dispatch<React.SetStateAction<Required<QQNTim.Configuration>>>, id: string, enable: boolean, inWhitelist: boolean, inBlacklist: boolean) {\n    setConfig((prev) => {\n        let _config = prev;\n        if (_config.plugins.whitelist && enable != inWhitelist)\n            _config = {\n                ..._config,\n                plugins: {\n                    ..._config.plugins,\n                    whitelist: (enable ? addItemToArray : removeItemFromArray)(_config.plugins.whitelist!, id),\n                },\n            };\n        else if (!_config.plugins.blacklist) _config.plugins.blacklist = [];\n        if (_config.plugins.blacklist && enable == inBlacklist)\n            _config = {\n                ..._config,\n                plugins: {\n                    ..._config.plugins,\n                    blacklist: (!enable ? addItemToArray : removeItemFromArray)(_config.plugins.blacklist!, id),\n                },\n            };\n        return _config;\n    });\n}\n\nexport function isPluginsExistent() {\n    const ids: string[] = [];\n    Object.keys(allPlugins).forEach((uin) =>\n        Object.keys(allPlugins[uin]).forEach((id) => {\n            const plugin = allPlugins[uin][id];\n            if (fs.existsSync(plugin.dir) && fs.statSync(plugin.dir).isDirectory()) ids.push(id);\n        }),\n    );\n    return ids;\n}\n\nexport function getPluginDescription(plugin: QQNTim.Plugin) {\n    const versionText = [plugin.manifest.version, plugin.manifest.author].filter(Boolean).join(\" - \");\n    const warnText = [!plugin.meetRequirements && \"当前环境不满足需求，未加载\", plugin.manifest.manifestVersion != \"3.0\" && \"插件使用了过时的插件标准，请提醒作者更新\"].filter(Boolean).join(\"; \");\n    const description = plugin.manifest.description || \"该插件没有提供说明。\";\n    return [versionText, warnText && `警告: ${warnText}。`, description].filter(Boolean);\n}\n"
  },
  {
    "path": "src/builtins/settings/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"jsx\": \"react-jsx\",\n        \"module\": \"CommonJS\",\n        \"moduleResolution\": \"Node\",\n        \"target\": \"ESNext\",\n        \"resolveJsonModule\": true,\n        \"strictNullChecks\": true,\n        \"strictFunctionTypes\": true,\n        \"noEmit\": true\n    },\n    \"include\": [\"src\"],\n    \"exclude\": [\"node_modules\", \"**/node_modules/*\"]\n}\n"
  },
  {
    "path": "src/common/global.ts",
    "content": "export const env = {} as QQNTim.Environment;\nexport const allPlugins = {} as QQNTim.Plugin.AllUsersPlugins;\n\nexport const setEnv = (value: QQNTim.Environment) => Object.assign(env, value);\nexport const setAllPlugins = (value: QQNTim.Plugin.AllUsersPlugins) => Object.assign(allPlugins, value);\n"
  },
  {
    "path": "src/common/ipc.ts",
    "content": "import { env } from \"./global\";\nimport { printObject } from \"./utils/console\";\nimport { isMainProcess } from \"./utils/process\";\n\nconst interruptIpcs: [QQNTim.IPC.InterruptFunction, QQNTim.IPC.InterruptIPCOptions | undefined][] = [];\n\nfunction interruptIpc(args: QQNTim.IPC.Args<any>, direction: QQNTim.IPC.Direction, channel: string, sender?: Electron.WebContents) {\n    for (const [func, options] of interruptIpcs) {\n        if (options?.cmdName && (!args[1] || (args[1][0]?.cmdName != options?.cmdName && args[1][0] != options?.cmdName))) continue;\n        if (options?.eventName && !args[0]?.eventName?.startsWith(`${options?.eventName}-`)) continue;\n        if (options?.type && (!args[0] || args[0].type != options?.type)) continue;\n        if (options?.direction && options?.direction != direction) continue;\n\n        const ret = func(args, channel, sender);\n        if (ret == false) return false;\n    }\n\n    return true;\n}\n\nexport function handleIpc(args: QQNTim.IPC.Args<any>, direction: QQNTim.IPC.Direction, channel: string, sender?: Electron.WebContents) {\n    if (args[0]?.eventName?.startsWith(\"ns-LoggerApi-\")) return false;\n    return interruptIpc(args, direction, channel, sender);\n}\n\nexport function addInterruptIpc(func: QQNTim.IPC.InterruptFunction, options?: QQNTim.IPC.InterruptIPCOptions) {\n    interruptIpcs.push([func, options]);\n}\n\nexport function watchIpc() {\n    if (env.config.verboseLogging && (env.config.useNativeDevTools || (!env.config.useNativeDevTools && isMainProcess))) {\n        ([\"in\", \"out\"] as QQNTim.IPC.Direction[]).forEach((type) => {\n            addInterruptIpc((args, channel, sender) => console.debug(`[!Watch:IPC?${type == \"in\" ? \"In\" : \"Out\"}${sender ? `:${sender.id.toString()}` : \"\"}] ${channel}`, printObject(args)), { direction: type });\n        });\n    }\n}\n"
  },
  {
    "path": "src/common/loader.ts",
    "content": "import { s } from \"./sep\";\n\nconst loadedPlugins: QQNTim.Plugin.LoadedPlugins = {};\n\nfunction getUserPlugins(allPlugins: QQNTim.Plugin.AllUsersPlugins, uin: string) {\n    const userPlugins = allPlugins[uin];\n    if (!userPlugins) {\n        console.warn(`[!Loader] 账户 (${uin}) 没有插件，跳过加载`);\n        return;\n    }\n    if (uin != \"\") console.log(`[!Loader] 正在为账户 (${uin}) 加载插件`);\n    else console.log(\"[!Loader] 正在为所有账户加载插件\");\n    return userPlugins;\n}\n\nexport function loadPlugins(allPlugins: QQNTim.Plugin.AllUsersPlugins, uin: string, shouldInject: (injection: QQNTim.Plugin.Injection) => boolean, scripts: [QQNTim.Plugin, string][], stylesheets?: [QQNTim.Plugin, string][]) {\n    const userPlugins = getUserPlugins(allPlugins, uin);\n    if (!userPlugins) return false;\n\n    for (const id in userPlugins) {\n        if (loadedPlugins[id]) continue;\n        const plugin = userPlugins[id];\n        if (!plugin.loaded) continue;\n        loadedPlugins[id] = plugin;\n        console.log(`[!Loader] 正在加载插件：${id}`);\n\n        plugin.injections.forEach((injection) => {\n            const rendererInjection = injection as QQNTim.Plugin.InjectionRenderer;\n            if (!shouldInject(injection)) return;\n            stylesheets && rendererInjection.stylesheet && stylesheets.push([plugin, `${plugin.dir}${s}${rendererInjection.stylesheet}`]);\n            injection.script && scripts.push([plugin, `${plugin.dir}${s}${injection.script}`]);\n        });\n    }\n\n    return true;\n}\n"
  },
  {
    "path": "src/common/patch.ts",
    "content": "const modules: Record<string, any> = {};\n\nexport function defineModules(newModules: Record<string, any>) {\n    for (const name in newModules) {\n        if (modules[name]) throw new Error(`模块名已经被使用：${name}`);\n        modules[name] = newModules[name];\n    }\n}\n\nexport function getModule(name: string) {\n    return modules[name];\n}\n"
  },
  {
    "path": "src/common/paths.ts",
    "content": "import { s } from \"./sep\";\n\nexport const dataDir = process.env[\"QQNTIM_HOME\"] || (process.platform == \"win32\" ? `${process.env[\"UserProfile\"]}${s}.qqntim` : `${process.env[\"HOME\"]}${s}.local${s}share${s}QQNTim`);\nexport const configFile = `${dataDir}${s}config.json`;\nexport const pluginDir = `${dataDir}${s}plugins`;\nexport const pluginPerUserDir = `${dataDir}${s}plugins-user`;\n"
  },
  {
    "path": "src/common/sep.ts",
    "content": "export { sep as s } from \"path\";\n"
  },
  {
    "path": "src/common/utils/console.ts",
    "content": "import { isMainProcess } from \"./process\";\nimport supportsColor from \"supports-color\";\nimport { inspect } from \"util\";\n\nexport const hasColorSupport = !!supportsColor.stdout;\n\nexport function printObject(object: any, enableColorSupport = isMainProcess && hasColorSupport) {\n    return inspect(object, {\n        compact: true,\n        depth: null,\n        showHidden: true,\n        colors: enableColorSupport,\n    });\n}\n"
  },
  {
    "path": "src/common/utils/freePort.ts",
    "content": "import { AddressInfo, createServer } from \"net\";\n\nexport function findFreePort() {\n    const server = createServer().listen(0);\n    const { port } = server.address()! as AddressInfo;\n    server.close();\n    return port;\n}\n"
  },
  {
    "path": "src/common/utils/ntVersion.ts",
    "content": "import { s } from \"../sep\";\nimport { readJSONSync } from \"fs-extra\";\n\nexport function getCurrentNTVersion() {\n    let version: string;\n    if (process.platform == \"win32\") {\n        version = readJSONSync(`${__dirname}${s}..${s}versions${s}config.json`)?.curVersion;\n    } else if (process.platform == \"linux\" || process.platform == \"darwin\") {\n        version = readJSONSync(`${__dirname}${s}..${s}package.json`)?.version;\n    } else throw new Error(`unsupported platform: ${process.platform}`);\n    if (!version) throw new Error(\"cannot determine QQNT version\");\n    return version;\n}\n"
  },
  {
    "path": "src/common/utils/process.ts",
    "content": "import { app } from \"electron\";\n\nexport const isMainProcess = !!app as boolean;\n"
  },
  {
    "path": "src/common/version.ts",
    "content": "import { version } from \"../../package.json\";\nimport { getCurrentNTVersion } from \"./utils/ntVersion\";\n\nexport function mountVersion() {\n    const ntVersion = getCurrentNTVersion();\n    Object.defineProperties(process.versions, {\n        qqnt: { value: ntVersion, writable: false },\n        qqntim: { value: version, writable: false },\n    });\n}\n"
  },
  {
    "path": "src/common/watch.ts",
    "content": "import { env } from \"./global\";\nimport { printObject } from \"./utils/console\";\n\ntype Constructor<T> = new (...args: any[]) => T;\n\nexport function getter<T, R extends keyof T>(scope: string | undefined, target: T, p: R) {\n    if (p == \"__qqntim_original_object\") return target;\n    if (typeof target[p] == \"function\")\n        return (...argArray: any[]) => {\n            const res = (target[p] as Function).apply(target, argArray);\n            if (scope && env.config.verboseLogging) console.debug(`[!Watch:${scope}] 调用：${p as string}`, printObject(argArray), res != target ? printObject(res) : \"[已隐藏]\");\n            return res;\n        };\n    else {\n        const res = target[p];\n        if (scope && env.config.verboseLogging) console.debug(`[!Watch:${scope}] 获取：${p as string}`);\n        return res;\n    }\n}\n\nexport function setter<T, R extends keyof T>(scope: string | undefined, _: T, p: R, newValue: T[R]) {\n    if (scope && env.config.verboseLogging) console.debug(`[!Watch:${scope}] 设置：${p as string}`, printObject(newValue));\n    return true;\n}\n\nexport function construct<F, T extends Constructor<F>>(scope: string | undefined, target: T, argArray: any[]) {\n    if (scope && env.config.verboseLogging) console.debug(`[!Watch:${scope}] 构造新实例：`, printObject(argArray));\n    return new target(...argArray);\n}\n\nexport function apply<T extends Function>(target: T, thisArg: any, argArray: any[]) {\n    return target.apply(thisArg, argArray);\n}\n"
  },
  {
    "path": "src/electron/README.txt",
    "content": "Silence is golden.\n"
  },
  {
    "path": "src/electron/package.json",
    "content": "{\n    \"name\": \"electron\",\n    \"private\": true,\n    \"version\": \"25.2.0\"\n}\n"
  },
  {
    "path": "src/main/api.ts",
    "content": "import { env } from \"../common/global\";\nimport { addInterruptIpc } from \"../common/ipc\";\nimport { defineModules } from \"../common/patch\";\nimport { mountVersion } from \"../common/version\";\nimport { addInterruptWindowArgs, addInterruptWindowCreation } from \"./patch\";\nimport { plugins } from \"./plugins\";\nimport * as fs from \"fs-extra\";\n\nexport let api: typeof QQNTim.API.Main;\n\nexport function initAPI() {\n    mountVersion();\n\n    api = {\n        allPlugins: plugins,\n        env: env,\n        interrupt: {\n            ipc: addInterruptIpc,\n            windowCreation: addInterruptWindowCreation,\n            windowArgs: addInterruptWindowArgs,\n        },\n        defineModules: defineModules,\n        modules: {\n            fs: fs,\n        },\n    };\n\n    defineModules({ \"qqntim/main\": api });\n}\n"
  },
  {
    "path": "src/main/compatibility.ts",
    "content": "import { env } from \"../common/global\";\nimport { existsSync } from \"fs-extra\";\nimport { resolve } from \"path\";\n\nexport function loadCustomLoaders() {\n    if (env.config.disableCompatibilityProcessing) return;\n    console.log(\"[!Compatibility] 正在进行兼容性处理\");\n    env.config.pluginLoaders.map((loader: string) => {\n        const path = resolve(__dirname, \"..\", loader);\n        if (existsSync(path)) require(path);\n    });\n}\n"
  },
  {
    "path": "src/main/config.ts",
    "content": "import { configFile, dataDir, pluginDir, pluginPerUserDir } from \"../common/paths\";\nimport * as fs from \"fs-extra\";\n\nfunction toBoolean(item: boolean | undefined, env: string, defaultValue: boolean) {\n    const envValue = process.env[env];\n    return envValue ? !!parseInt(envValue) : typeof item == \"boolean\" ? item : defaultValue;\n}\n\nfunction toStringArray<T extends string[], R extends T | undefined>(item: R, env: string, defaultValue: R) {\n    const envValue = process.env[env];\n    return envValue ? envValue.split(\";\") : item && item instanceof Array ? item : defaultValue;\n}\n\n// function toNumberArray(\n//     item: number[] | undefined,\n//     env: string,\n//     defaultValue: number[] | undefined,\n//     isFloat = false\n// ) {\n//     const envValue = process.env[env];\n//     return envValue\n//         ? envValue\n//               .split(\";\")\n//               .map((value) => (isFloat ? parseFloat(value) : parseInt(value)))\n//         : item instanceof Array\n//         ? item\n//         : defaultValue;\n// }\n\nexport function getEnvironment(config: QQNTim.Configuration): QQNTim.Environment {\n    return {\n        config: {\n            plugins: {\n                whitelist: toStringArray(config.plugins?.whitelist, \"QQNTIM_PLUGINS_WHITELIST\", undefined),\n                blacklist: toStringArray(config.plugins?.blacklist, \"QQNTIM_PLUGINS_BLACKLIST\", undefined),\n                config: config.plugins?.config || {},\n            },\n            pluginLoaders: toStringArray(config.pluginLoaders, \"QQNTIM_PLUGIN_LOADER\", [\"LiteLoader\", \"LiteLoaderQQNT\"]),\n            verboseLogging: toBoolean(config.verboseLogging, \"QQNTIM_VERBOSE_LOGGING\", false),\n            useNativeDevTools: toBoolean(config.useNativeDevTools, \"QQNTIM_USE_NATIVE_DEVTOOLS\", false),\n            disableCompatibilityProcessing: toBoolean(config.disableCompatibilityProcessing, \"QQNTIM_NO_COMPATIBILITY_PROCESSING\", false),\n        },\n        path: {\n            dataDir,\n            configFile,\n            pluginDir,\n            pluginPerUserDir,\n        },\n    };\n}\n\nfunction prepareDataDir() {\n    fs.ensureDirSync(dataDir);\n    fs.ensureDirSync(pluginDir);\n    fs.ensureDirSync(pluginPerUserDir);\n    if (!fs.existsSync(configFile)) fs.writeJSONSync(configFile, {});\n}\n\nexport function loadConfig() {\n    prepareDataDir();\n    const config = fs.readJSONSync(configFile) || {};\n    return getEnvironment(config);\n}\n"
  },
  {
    "path": "src/main/debugger.ts",
    "content": "import { env } from \"../common/global\";\nimport { findFreePort } from \"../common/utils/freePort\";\nimport axios from \"axios\";\nimport { start } from \"chii/server\";\nimport { BrowserWindow } from \"electron\";\n\nexport let debuggerHost = \"\";\nexport let debuggerPort = -1;\nexport let debuggerOrigin = \"\";\n\nexport async function initDebugger() {\n    if (!env.config.useNativeDevTools) {\n        debuggerPort = findFreePort();\n        debuggerHost = \"127.0.0.1\";\n        debuggerOrigin = `http://${debuggerHost}:${debuggerPort}`;\n\n        console.log(`[!Debugger] 正在启动 chii 调试器：${debuggerOrigin}`);\n        await start({\n            host: debuggerHost,\n            port: debuggerPort,\n            useHttps: false,\n        });\n    }\n}\n\nasync function listChiiTargets() {\n    const res = await axios.get(`${debuggerOrigin}/targets`);\n    return (res.data.targets as any[]).map((target) => [target.title, target.id]);\n}\n\nexport async function createDebuggerWindow(debuggerId: string, win: BrowserWindow) {\n    const targets = await listChiiTargets();\n    for (const [id, target] of targets) {\n        if (id == debuggerId) {\n            const url = `${debuggerOrigin}/front_end/chii_app.html?ws=${debuggerHost}:${debuggerPort}/client/${(Math.random() * 6).toString()}?target=${target}`;\n\n            console.log(`[!Debugger] 正在打开 chii 调试器窗口：${url}`);\n\n            const debuggerWin = new BrowserWindow({\n                width: 800,\n                height: 600,\n                show: true,\n                webPreferences: {\n                    webSecurity: false,\n                    allowRunningInsecureContent: true,\n                    devTools: false,\n                    nodeIntegration: false,\n                    nodeIntegrationInSubFrames: false,\n                    contextIsolation: true,\n                },\n            });\n\n            debuggerWin.webContents.loadURL(url);\n\n            win.on(\"closed\", () => debuggerWin.destroy());\n\n            break;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/loader.ts",
    "content": "import { loadPlugins } from \"../common/loader\";\n\nlet scripts: [QQNTim.Plugin, string][] = [];\n\nfunction shouldInject(injection: QQNTim.Plugin.Injection) {\n    return injection.type == \"main\";\n}\n\nexport function applyPlugins(allPlugins: QQNTim.Plugin.AllUsersPlugins, uin = \"\") {\n    loadPlugins(allPlugins, uin, shouldInject, scripts);\n    applyScripts();\n\n    return true;\n}\n\nfunction applyScripts() {\n    scripts = scripts.filter(([plugin, script]) => {\n        try {\n            const mod = require(script);\n            if (mod) new ((mod.default || mod) as typeof QQNTim.Entry.Main)();\n            return false;\n        } catch (reason) {\n            console.error(`[!Loader] 运行此插件脚本时出现意外错误：${script}，请联系插件作者 (${plugin.manifest.author}) 解决`);\n            console.error(reason);\n        }\n        return true;\n    });\n}\n"
  },
  {
    "path": "src/main/main.ts",
    "content": "/**\n * @license\n * Copyright (c) Flysoft.\n */\n\nimport { setAllPlugins, setEnv } from \"../common/global\";\nimport { watchIpc } from \"../common/ipc\";\nimport { initAPI } from \"./api\";\nimport { loadCustomLoaders } from \"./compatibility\";\nimport { loadConfig } from \"./config\";\nimport { initDebugger } from \"./debugger\";\nimport { applyPlugins } from \"./loader\";\nimport { patchModuleLoader } from \"./patch\";\nimport { collectPlugins, plugins } from \"./plugins\";\n\nsetEnv(loadConfig());\ninitDebugger();\npatchModuleLoader();\nwatchIpc();\nloadCustomLoaders();\ncollectPlugins();\nsetAllPlugins(plugins);\ninitAPI();\napplyPlugins(plugins);\nconsole.log(\"[!Main] QQNTim 加载成功\");\nrequire(\"./index.js\");\n"
  },
  {
    "path": "src/main/patch.ts",
    "content": "import { env } from \"../common/global\";\nimport { handleIpc } from \"../common/ipc\";\nimport { defineModules, getModule } from \"../common/patch\";\nimport { s } from \"../common/sep\";\nimport { hasColorSupport } from \"../common/utils/console\";\nimport { apply, construct, getter, setter } from \"../common/watch\";\nimport { createDebuggerWindow, debuggerOrigin } from \"./debugger\";\nimport { applyPlugins } from \"./loader\";\nimport { plugins } from \"./plugins\";\nimport { enable, initialize } from \"@electron/remote/main\";\nimport { BrowserWindow, Menu, MenuItem, app, dialog, ipcMain } from \"electron\";\nimport { Module } from \"module\";\n\nconst interruptWindowArgs: QQNTim.WindowCreation.InterruptArgsFunction[] = [];\nconst interruptWindowCreation: QQNTim.WindowCreation.InterruptFunction[] = [];\n\nipcMain.on(\"___!boot\", (event) => {\n    if (!event.returnValue) event.returnValue = { enabled: false };\n});\n\nipcMain.on(\"___!log\", (event, level, ...args) => {\n    console[{ 0: \"debug\", 1: \"log\", 2: \"info\", 3: \"warn\", 4: \"error\" }[level] || \"log\"](`[!Renderer:Log:${event.sender.id}]`, ...args);\n});\n\nipcMain.handle(\"___!dialog\", (event, method: string, options: object) => dialog[method](BrowserWindow.fromWebContents(event.sender), options));\n\nfunction patchBrowserWindow() {\n    const windowMenu: Electron.MenuItem[] = [\n        new MenuItem({\n            label: \"刷新\",\n            role: \"reload\",\n            accelerator: \"F5\",\n        }),\n        new MenuItem({\n            label: \"开发者工具\",\n            accelerator: \"F12\",\n            ...(env.config.useNativeDevTools\n                ? { role: \"toggleDevTools\" }\n                : {\n                      click: (_, win) => {\n                          if (!win) return;\n                          const debuggerId = win.webContents.id.toString();\n                          createDebuggerWindow(debuggerId, win);\n                      },\n                  }),\n        }),\n    ];\n    return new Proxy(BrowserWindow, {\n        apply(target, thisArg, argArray) {\n            return apply(target, thisArg, argArray);\n        },\n        get(target, p) {\n            return getter(undefined, target, p as any);\n        },\n        set(target, p, newValue) {\n            return setter(undefined, target, p as any, newValue);\n        },\n        construct(target, [options]: [Electron.BrowserWindowConstructorOptions]) {\n            let patchedArgs: Electron.BrowserWindowConstructorOptions = {\n                ...options,\n                webPreferences: {\n                    ...options.webPreferences,\n                    preload: `${__dirname}${s}qqntim-renderer.js`,\n                    webSecurity: false,\n                    allowRunningInsecureContent: true,\n                    nodeIntegration: true,\n                    nodeIntegrationInSubFrames: true,\n                    contextIsolation: false,\n                    devTools: env.config.useNativeDevTools,\n                    sandbox: false,\n                },\n            };\n            interruptWindowArgs.forEach((func) => {\n                patchedArgs = func(patchedArgs);\n            });\n            const win = construct(\"BrowserWindow\", target, [patchedArgs]) as BrowserWindow;\n\n            const webContentsId = win.webContents.id.toString();\n\n            let thirdpartyPreloads: string[] = win.webContents.session.getPreloads();\n            win.webContents.session.setPreloads([]);\n            enable(win.webContents);\n\n            const session = new Proxy(win.webContents.session, {\n                get(target, p) {\n                    const res = getter(undefined, target, p as any);\n                    if (p == \"setPreloads\")\n                        return (newPreloads: string[]) => {\n                            thirdpartyPreloads = newPreloads;\n                        };\n                    return res;\n                },\n                set(target, p, newValue) {\n                    return setter(undefined, target, p as any, newValue);\n                },\n            });\n            const webContents = new Proxy(win.webContents, {\n                get(target, p) {\n                    const res = getter(undefined, target, p as any);\n                    if (p == \"session\") return session;\n                    return res;\n                },\n                set(target, p, newValue) {\n                    return setter(undefined, target, p as any, newValue);\n                },\n            });\n\n            const send = win.webContents.send;\n            win.webContents.send = (channel: string, ...args: QQNTim.IPC.Args<any>) => {\n                handleIpc(args, \"out\", channel);\n                return send.call(win.webContents, channel, ...args);\n            };\n            win.webContents.on(\"ipc-message\", (_, channel, ...args) => {\n                if (!handleIpc(args as any, \"in\", channel, win.webContents)) throw new Error(\"QQNTim 已强行中断了一条 IPC 消息\");\n                if (channel == \"___!apply_plugins\") applyPlugins(plugins, args[0] as string);\n            });\n            win.webContents.on(\"ipc-message-sync\", (event, channel, ...args) => {\n                handleIpc(args as any, \"in\", channel, win.webContents);\n                if (channel == \"___!boot\") {\n                    event.returnValue = {\n                        enabled: true,\n                        preload: Array.from(new Set([...thirdpartyPreloads, options.webPreferences?.preload].filter(Boolean))),\n                        debuggerOrigin: !env.config.useNativeDevTools && debuggerOrigin,\n                        webContentsId: webContentsId,\n                        plugins: plugins,\n                        env: env,\n                        hasColorSupport: hasColorSupport,\n                    };\n                } else if (channel == \"___!browserwindow_api\") {\n                    event.returnValue = win[args[0][0]](...args[0][1]);\n                } else if (channel == \"___!app_api\") {\n                    event.returnValue = app[args[0][0]](...args[0][1]);\n                }\n            });\n\n            const setMenu = win.setMenu;\n            win.setMenu = (menu) => {\n                const patchedMenu = Menu.buildFromTemplate([...(menu?.items || []), ...windowMenu]);\n                return setMenu.call(win, patchedMenu);\n            };\n            win.setMenu(null);\n\n            return new Proxy(win, {\n                get(target, p) {\n                    const res = getter(undefined, target, p as any);\n                    if (p == \"webContents\") return webContents;\n                    return res;\n                },\n                set(target, p, newValue) {\n                    return setter(undefined, target, p as any, newValue);\n                },\n            });\n        },\n    });\n}\n\nexport function addInterruptWindowCreation(func: QQNTim.WindowCreation.InterruptFunction) {\n    interruptWindowCreation.push(func);\n}\n\nexport function addInterruptWindowArgs(func: QQNTim.WindowCreation.InterruptArgsFunction) {\n    interruptWindowArgs.push(func);\n}\n\nexport function patchModuleLoader() {\n    // 阻止 Electron 默认菜单生成\n    Menu.setApplicationMenu(null);\n    initialize();\n\n    const patchedElectron: typeof Electron.CrossProcessExports = {\n        ...require(\"electron\"),\n        BrowserWindow: patchBrowserWindow(),\n    };\n\n    defineModules({ electron: patchedElectron });\n\n    const loadBackend = (Module as any)._load;\n    (Module as any)._load = (request: string, parent: NodeModule, isMain: boolean) => {\n        return getModule(request) || loadBackend(request, parent, isMain);\n    };\n}\n"
  },
  {
    "path": "src/main/plugins.ts",
    "content": "import { env } from \"../common/global\";\nimport { s } from \"../common/sep\";\nimport * as fs from \"fs-extra\";\nimport * as os from \"os\";\nimport * as semver from \"semver\";\n\nconst supportedManifestVersions: QQNTim.Manifest.ManifestVersion[] = [\"3.0\"];\nexport const plugins: QQNTim.Plugin.AllUsersPlugins = {};\n\nfunction isPluginEnabled(manifest: QQNTim.Manifest) {\n    if (env.config.plugins.whitelist) return env.config.plugins.whitelist.includes(manifest.id);\n    else if (env.config.plugins.blacklist) return !env.config.plugins.blacklist.includes(manifest.id);\n    else return true;\n}\n\nfunction isPluginRequirementsMet(manifest: QQNTim.Manifest) {\n    if (manifest.requirements?.os) {\n        let meetRequirements = false;\n        const osRelease = os.release();\n        for (const item of manifest.requirements.os) {\n            if (item.platform != process.platform) continue;\n            if (item.lte && !semver.lte(item.lte, osRelease)) continue;\n            if (item.lt && !semver.lt(item.lt, osRelease)) continue;\n            if (item.gte && !semver.gte(item.gte, osRelease)) continue;\n            if (item.gt && !semver.gt(item.gt, osRelease)) continue;\n            if (item.eq && !semver.eq(item.eq, osRelease)) continue;\n            meetRequirements = true;\n            break;\n        }\n        if (!meetRequirements) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nexport function parsePlugin(dir: string) {\n    try {\n        const manifestFile = `${dir}${s}qqntim.json`;\n        if (!fs.existsSync(manifestFile)) return null;\n        const manifest = fs.readJSONSync(manifestFile) as QQNTim.Manifest;\n        if (!manifest.manifestVersion) manifest.manifestVersion = supportedManifestVersions[0];\n        else if (!supportedManifestVersions.includes(manifest.manifestVersion)) throw new TypeError(`此插件包含一个无效的清单版本：${manifest.manifestVersion}，支持的版本有：${supportedManifestVersions.join(\", \")}`);\n\n        const meetRequirements = isPluginRequirementsMet(manifest);\n        const enabled = isPluginEnabled(manifest);\n        const loaded = meetRequirements && enabled;\n        if (!meetRequirements) console.error(`[!Plugins] 跳过加载插件：${manifest.id}（当前环境不满足要求）`);\n        else if (!enabled) console.error(`[!Plugins] 跳过加载插件：${manifest.id}（插件已被禁用）`);\n\n        return {\n            enabled: enabled,\n            meetRequirements: meetRequirements,\n            loaded: loaded,\n            id: manifest.id,\n            dir: dir,\n            injections: manifest.injections.map((injection) => {\n                return injection.type == \"main\"\n                    ? { ...injection }\n                    : {\n                          ...injection,\n                          pattern: injection.pattern && new RegExp(injection.pattern),\n                      };\n            }),\n            manifest: manifest,\n        } as QQNTim.Plugin;\n    } catch (reason) {\n        console.error(\"[!Plugins] 解析插件时出现意外错误：\", dir);\n        console.error(reason);\n        return null;\n    }\n}\n\nfunction collectPluginsFromDir(baseDir: string, uin = \"\") {\n    const folders = fs.readdirSync(baseDir);\n    if (!plugins[uin]) plugins[uin] = {};\n    folders.forEach((folder) => {\n        const folderPath = `${baseDir}${s}${folder}`;\n        if (fs.existsSync(folderPath) && fs.statSync(folderPath).isDirectory()) {\n            const plugin = parsePlugin(folderPath);\n            if (!plugin) return;\n            if (plugins[uin][plugin.id]) return;\n            plugins[uin][plugin.id] = plugin;\n        }\n    });\n}\n\nexport function collectPlugins() {\n    collectPluginsFromDir(`${__dirname}${s}builtins`);\n    collectPluginsFromDir(env.path.pluginDir);\n    const folders = fs.readdirSync(env.path.pluginPerUserDir);\n    folders.forEach((folder) => {\n        const folderPath = `${env.path.pluginPerUserDir}${s}${folder}`;\n        if (fs.statSync(folderPath).isDirectory()) {\n            collectPluginsFromDir(folderPath, folder);\n        }\n    });\n}\n"
  },
  {
    "path": "src/qqntim-env.d.ts",
    "content": "/// <reference types=\"@flysoftbeta/qqntim-typings\" />\n"
  },
  {
    "path": "src/renderer/api/app.ts",
    "content": "import { ipcRenderer } from \"electron\";\n\nclass AppAPI implements QQNTim.API.Renderer.AppAPI {\n    relaunch() {\n        ipcRenderer.sendSync(\"___!app_api\", [\"relaunch\", []]);\n        this.quit();\n    }\n\n    quit() {\n        ipcRenderer.sendSync(\"___!app_api\", [\"quit\", []]);\n    }\n\n    exit() {\n        ipcRenderer.sendSync(\"___!app_api\", [\"exit\", []]);\n    }\n}\n\nexport const appApi = new AppAPI();\n"
  },
  {
    "path": "src/renderer/api/browserWindow.ts",
    "content": "import { ipcRenderer } from \"electron\";\n\nclass BrowserWindowAPI implements QQNTim.API.Renderer.BrowserWindowAPI {\n    setSize(width: number, height: number) {\n        ipcRenderer.sendSync(\n            \"___!browserwindow_api\",\n            {\n                eventName: \"QQNTIM_BROWSERWINDOW_API\",\n            },\n            [\"setSize\", [width, height]],\n        );\n    }\n\n    setMinimumSize(width: number, height: number) {\n        ipcRenderer.sendSync(\n            \"___!browserwindow_api\",\n            {\n                eventName: \"QQNTIM_BROWSERWINDOW_API\",\n            },\n            [\"setMinimumSize\", [width, height]],\n        );\n    }\n}\n\nexport const browserWindowApi = new BrowserWindowAPI();\n"
  },
  {
    "path": "src/renderer/api/dialog.ts",
    "content": "import { ipcRenderer } from \"electron\";\n\nclass DialogAPI implements QQNTim.API.Renderer.DialogAPI {\n    async confirm(message = \"\") {\n        const res = await this.messageBox({ message, buttons: [\"确定\", \"取消\"], defaultId: 0, type: \"question\" });\n        return res.response == 0;\n    }\n\n    async alert(message = \"\") {\n        await this.messageBox({ message, buttons: [\"确定\"], defaultId: 0, type: \"info\" });\n        return;\n    }\n\n    messageBox(options: Electron.MessageBoxOptions): Promise<Electron.MessageBoxReturnValue> {\n        return ipcRenderer.invoke(\"___!dialog\", \"showMessageBox\", options);\n    }\n\n    openDialog(options: Electron.OpenDialogOptions): Promise<Electron.OpenDialogReturnValue> {\n        return ipcRenderer.invoke(\"___!dialog\", \"showOpenDialog\", options);\n    }\n\n    saveDialog(options: Electron.SaveDialogOptions): Promise<Electron.SaveDialogReturnValue> {\n        return ipcRenderer.invoke(\"___!dialog\", \"showSaveDialog\", options);\n    }\n}\n\nexport const dialogApi = new DialogAPI();\n"
  },
  {
    "path": "src/renderer/api/getVueId.ts",
    "content": "export function getVueId(element: HTMLElement) {\n    let vueId: string | undefined;\n\n    for (const item in element.dataset) {\n        if (item.startsWith(\"v\"))\n            vueId = `data-${item\n                .split(\"\")\n                .map((item) => {\n                    const low = item.toLocaleLowerCase();\n                    if (low != item) return `-${low}`;\n                    else return low;\n                })\n                .join(\"\")}`;\n    }\n\n    return vueId;\n}\n"
  },
  {
    "path": "src/renderer/api/index.ts",
    "content": "import { allPlugins, env } from \"../../common/global\";\nimport { addInterruptIpc } from \"../../common/ipc\";\nimport { defineModules } from \"../../common/patch\";\nimport { mountVersion } from \"../../common/version\";\nimport { appApi } from \"./app\";\nimport { browserWindowApi } from \"./browserWindow\";\nimport { dialogApi } from \"./dialog\";\nimport { getVueId } from \"./getVueId\";\nimport { nt } from \"./nt\";\nimport { ntCall } from \"./nt/call\";\nimport { waitForElement } from \"./waitForElement\";\nimport { windowLoadPromise } from \"./windowLoadPromise\";\nimport * as fs from \"fs-extra\";\n\nexport let api: typeof QQNTim.API.Renderer;\n\nexport function initAPI() {\n    mountVersion();\n    nt.init();\n\n    api = {\n        allPlugins: allPlugins,\n        env: env,\n        interrupt: {\n            ipc: addInterruptIpc,\n        },\n        nt: nt,\n        browserWindow: browserWindowApi,\n        app: appApi,\n        dialog: dialogApi,\n        modules: {\n            fs: fs,\n        },\n        defineModules: defineModules,\n        utils: {\n            waitForElement: waitForElement,\n            getVueId: getVueId,\n            ntCall: ntCall,\n        },\n        windowLoadPromise: windowLoadPromise,\n    };\n\n    defineModules({ \"qqntim/renderer\": api });\n}\n"
  },
  {
    "path": "src/renderer/api/nt/call.ts",
    "content": "import { addInterruptIpc } from \"../../../common/ipc\";\nimport { webContentsId } from \"../../main\";\nimport { randomUUID } from \"crypto\";\nimport { ipcRenderer } from \"electron\";\n\nclass NTCallError extends Error {\n    public code: number;\n    public message: string;\n    constructor(code: number, message: string) {\n        super();\n        this.code = code;\n        this.message = message;\n    }\n}\n\nconst pendingCallbacks: Record<string, Function> = {};\n\naddInterruptIpc(\n    (args) => {\n        const id = args[0].callbackId;\n        if (pendingCallbacks[id]) {\n            pendingCallbacks[id](args);\n            delete pendingCallbacks[id];\n            return false;\n        }\n    },\n    {\n        direction: \"in\",\n    },\n);\n\nexport function ntCall(eventName: string, cmdName: string, args: any[], isRegister = false) {\n    return new Promise<any>((resolve, reject) => {\n        const uuid = randomUUID();\n        pendingCallbacks[uuid] = (args: QQNTim.IPC.Args<QQNTim.IPC.Response>) => {\n            if (args[1] && args[1].result != undefined && args[1].result != 0) reject(new NTCallError(args[1].result, args[1].errMsg));\n            else resolve(args[1]);\n        };\n        ipcRenderer.send(\n            `IPC_UP_${webContentsId}`,\n            {\n                type: \"request\",\n                callbackId: uuid,\n                eventName: `${eventName}-${webContentsId}${isRegister ? \"-register\" : \"\"}`,\n            },\n            [cmdName, ...args],\n        );\n    });\n}\n"
  },
  {
    "path": "src/renderer/api/nt/constructor.ts",
    "content": "import { ntMedia } from \"./media\";\n\nexport function constructTextElement(ele: any): QQNTim.API.Renderer.NT.MessageElementText {\n    return {\n        type: \"text\",\n        content: ele.textElement.content,\n        raw: ele,\n    };\n}\n\nexport function constructImageElement(ele: any, msg: any): QQNTim.API.Renderer.NT.MessageElementImage {\n    return {\n        type: \"image\",\n        file: ele.picElement.sourcePath,\n        downloadedPromise: ntMedia.downloadMedia(msg.msgId, ele.elementId, msg.peerUid, msg.chatType, ele.picElement.thumbPath.get(0), ele.picElement.sourcePath),\n        raw: ele,\n    };\n}\nexport function constructFaceElement(ele: any): QQNTim.API.Renderer.NT.MessageElementFace {\n    return {\n        type: \"face\",\n        faceIndex: ele.faceElement.faceIndex,\n        faceType: ele.faceElement.faceType == 1 ? \"normal\" : ele.faceElement.faceType == 2 ? \"normal-extended\" : ele.faceElement.faceType == 3 ? \"super\" : ele.faceElement.faceType,\n        faceSuperIndex: ele.faceElement.stickerId && parseInt(ele.faceElement.stickerId),\n        raw: ele,\n    };\n}\nexport function constructRawElement(ele: any): QQNTim.API.Renderer.NT.MessageElementRaw {\n    return {\n        type: \"raw\",\n        raw: ele,\n    };\n}\nexport function constructMessage(msg: any): QQNTim.API.Renderer.NT.Message {\n    const downloadedPromises: Promise<void>[] = [];\n    const elements = (msg.elements as any[]).map((ele): QQNTim.API.Renderer.NT.MessageElement => {\n        if (ele.elementType == 1) return constructTextElement(ele);\n        else if (ele.elementType == 2) {\n            const element = constructImageElement(ele, msg);\n            downloadedPromises.push(element.downloadedPromise);\n            return element;\n        } else if (ele.elementType == 6) return constructFaceElement(ele);\n        else return constructRawElement(ele);\n    });\n    return {\n        allDownloadedPromise: Promise.all(downloadedPromises),\n        peer: {\n            uid: msg.peerUid,\n            name: msg.peerName,\n            chatType: msg.chatType == 1 ? \"friend\" : msg.chatType == 2 ? \"group\" : \"others\",\n        },\n        sender: {\n            uid: msg.senderUid,\n            memberName: msg.sendMemberName || msg.sendNickName,\n            nickName: msg.sendNickName,\n        },\n        elements: elements,\n        raw: msg,\n    };\n}\nexport function constructUser(user: any): QQNTim.API.Renderer.NT.User {\n    return {\n        uid: user.uid,\n        qid: user.qid,\n        uin: user.uin,\n        avatarUrl: user.avatarUrl,\n        nickName: user.nick,\n        bio: user.longNick,\n        sex: { 1: \"male\", 2: \"female\", 255: \"unset\", 0: \"unset\" }[user.sex] || \"others\",\n        raw: user,\n    };\n}\nexport function constructGroup(group: any): QQNTim.API.Renderer.NT.Group {\n    return {\n        uid: group.groupCode,\n        avatarUrl: group.avatarUrl,\n        name: group.groupName,\n        role: { 4: \"master\", 3: \"moderator\", 2: \"member\" }[group.memberRole] || \"others\",\n        maxMembers: group.maxMember,\n        members: group.memberCount,\n        raw: group,\n    };\n}\n"
  },
  {
    "path": "src/renderer/api/nt/destructor.ts",
    "content": "export function destructTextElement(element: QQNTim.API.Renderer.NT.MessageElementText) {\n    return {\n        elementType: 1,\n        elementId: \"\",\n        textElement: {\n            content: element.content,\n            atType: 0,\n            atUid: \"\",\n            atTinyId: \"\",\n            atNtUid: \"\",\n        },\n    };\n}\n\nexport function destructImageElement(element: QQNTim.API.Renderer.NT.MessageElementImage, picElement: any) {\n    return {\n        elementType: 2,\n        elementId: \"\",\n        picElement: picElement,\n    };\n}\n\nexport function destructFaceElement(element: QQNTim.API.Renderer.NT.MessageElementFace) {\n    return {\n        elementType: 6,\n        elementId: \"\",\n        faceElement: {\n            faceIndex: element.faceIndex,\n            faceType: element.faceType == \"normal\" ? 1 : element.faceType == \"normal-extended\" ? 2 : element.faceType == \"super\" ? 3 : element.faceType,\n            ...((element.faceType == \"super\" || element.faceType == 3) && {\n                packId: \"1\",\n                stickerId: (element.faceSuperIndex || \"0\").toString(),\n                stickerType: 1,\n                sourceType: 1,\n                resultId: \"\",\n                superisedId: \"\",\n                randomType: 1,\n            }),\n        },\n    };\n}\n\nexport function destructRawElement(element: QQNTim.API.Renderer.NT.MessageElementRaw) {\n    return element.raw;\n}\n\nexport function destructPeer(peer: QQNTim.API.Renderer.NT.Peer) {\n    return {\n        chatType: peer.chatType == \"friend\" ? 1 : peer.chatType == \"group\" ? 2 : 1,\n        peerUid: peer.uid,\n        guildId: \"\",\n    };\n}\n"
  },
  {
    "path": "src/renderer/api/nt/index.ts",
    "content": "import { addInterruptIpc } from \"../../../common/ipc\";\nimport { ntCall } from \"./call\";\nimport { constructGroup, constructMessage, constructUser } from \"./constructor\";\nimport { destructFaceElement, destructImageElement, destructPeer, destructRawElement, destructTextElement } from \"./destructor\";\nimport { ntMedia } from \"./media\";\nimport { NTWatcher } from \"./watcher\";\nimport { EventEmitter } from \"events\";\n\nconst NTEventEmitter = EventEmitter as new () => QQNTim.API.Renderer.NT.EventEmitter;\nclass NT extends NTEventEmitter implements QQNTim.API.Renderer.NT {\n    private sentMessageWatcher: NTWatcher<string>;\n    private profileChangeWatcher: NTWatcher<string>;\n    private friendsList: QQNTim.API.Renderer.NT.User[] = [];\n    private groupsList: QQNTim.API.Renderer.NT.Group[] = [];\n\n    public init() {\n        this.listenNewMessages();\n        this.listenContactListChange();\n        ntMedia.init();\n        this.sentMessageWatcher = new NTWatcher((args) => args?.[1]?.[0]?.payload?.msgRecord?.peerUid, \"ns-ntApi\", \"nodeIKernelMsgListener/onAddSendMsg\", \"in\", \"request\");\n        this.profileChangeWatcher = new NTWatcher((args) => args?.[1]?.[0]?.payload?.profiles?.keys()?.next()?.value, \"ns-ntApi\", \"nodeIKernelProfileListener/onProfileSimpleChanged\", \"in\", \"request\");\n    }\n\n    private listenNewMessages() {\n        addInterruptIpc(\n            (args) => {\n                const messages = (args?.[1]?.[0]?.payload?.msgList as any[]).map((msg): QQNTim.API.Renderer.NT.Message => constructMessage(msg));\n                this.emit(\"new-messages\", messages);\n            },\n            { eventName: \"ns-ntApi\", cmdName: \"nodeIKernelMsgListener/onRecvMsg\", direction: \"in\", type: \"request\" },\n        );\n    }\n\n    private listenContactListChange() {\n        addInterruptIpc(\n            (args) => {\n                this.friendsList = [];\n                ((args?.[1]?.[0]?.payload?.data || []) as any[]).forEach((category) => this.friendsList.push(...((category?.buddyList || []) as any[]).map((friend) => constructUser(friend))));\n                this.emit(\"friends-list-updated\", this.friendsList);\n            },\n            { eventName: \"ns-ntApi\", cmdName: \"nodeIKernelBuddyListener/onBuddyListChange\", direction: \"in\", type: \"request\" },\n        );\n        addInterruptIpc(\n            (args) => {\n                this.groupsList = ((args[1]?.[0]?.payload?.groupList || []) as any[]).map((group) => constructGroup(group));\n                this.emit(\"groups-list-updated\", this.groupsList);\n            },\n            { eventName: \"ns-ntApi\", cmdName: \"nodeIKernelGroupListener/onGroupListUpdate\", direction: \"in\", type: \"request\" },\n        );\n    }\n\n    async getAccountInfo(): Promise<QQNTim.API.Renderer.NT.LoginAccount | undefined> {\n        return await ntCall(\"ns-BusinessApi\", \"fetchAuthData\", []).then((data) => {\n            if (!data) return;\n            return { uid: data.uid, uin: data.uin } as QQNTim.API.Renderer.NT.LoginAccount;\n        });\n    }\n\n    async getUserInfo(uid: string): Promise<QQNTim.API.Renderer.NT.User> {\n        ntCall(\"ns-ntApi\", \"nodeIKernelProfileService/getUserDetailInfo\", [{ uid: uid }, undefined]);\n        return await this.profileChangeWatcher.wait(uid).then((args) => constructUser(args?.[1]?.[0]?.payload?.profiles?.get(uid)));\n    }\n\n    async revokeMessage(peer: QQNTim.API.Renderer.NT.Peer, message: string) {\n        await ntCall(\"ns-ntApi\", \"nodeIKernelMsgService/recallMsg\", [\n            {\n                peer: destructPeer(peer),\n                msgIds: [message],\n            },\n        ]);\n    }\n\n    async sendMessage(peer: QQNTim.API.Renderer.NT.Peer, elements: QQNTim.API.Renderer.NT.MessageElement[]) {\n        ntCall(\"ns-ntApi\", \"nodeIKernelMsgService/sendMsg\", [\n            {\n                msgId: \"0\",\n                peer: destructPeer(peer),\n                msgElements: await Promise.all(\n                    elements.map(async (element) => {\n                        if (element.type == \"text\") return destructTextElement(element);\n                        else if (element.type == \"image\") return destructImageElement(element, await ntMedia.prepareImageElement(element.file));\n                        else if (element.type == \"face\") return destructFaceElement(element);\n                        else if (element.type == \"raw\") return destructRawElement(element);\n                        else return null;\n                    }),\n                ),\n            },\n            null,\n        ]);\n        return await this.sentMessageWatcher.wait(peer.uid).then((args) => args?.[1]?.[0]?.payload?.msgRecord?.msgId);\n    }\n\n    async getFriendsList(forced: boolean) {\n        ntCall(\"ns-ntApi\", \"nodeIKernelBuddyService/getBuddyList\", [{ force_update: forced }, undefined]);\n        return await new Promise<QQNTim.API.Renderer.NT.User[]>((resolve) => {\n            this.once(\"friends-list-updated\", (list) => resolve(list));\n        });\n    }\n\n    async getGroupsList(forced: boolean) {\n        ntCall(\"ns-ntApi\", \"nodeIKernelGroupService/getGroupList\", [{ forceFetch: forced }, undefined]);\n        return await new Promise<QQNTim.API.Renderer.NT.Group[]>((resolve) => {\n            this.once(\"groups-list-updated\", (list) => resolve(list));\n        });\n    }\n\n    async getPreviousMessages(peer: QQNTim.API.Renderer.NT.Peer, count = 20, startMsgId = \"0\") {\n        try {\n            const msgs = await ntCall(\"ns-ntApi\", \"nodeIKernelMsgService/getMsgsIncludeSelf\", [\n                {\n                    peer: destructPeer(peer),\n                    msgId: startMsgId,\n                    cnt: count,\n                    queryOrder: true,\n                },\n                undefined,\n            ]);\n            const messages = (msgs.msgList as any[]).map((msg) => constructMessage(msg));\n            return messages;\n        } catch {\n            return [];\n        }\n    }\n}\n\nexport const nt = new NT();\n"
  },
  {
    "path": "src/renderer/api/nt/media.ts",
    "content": "import { ntCall } from \"./call\";\nimport { NTWatcher } from \"./watcher\";\nimport { exists } from \"fs-extra\";\n\nclass NTMedia {\n    private mediaDownloadWatcher: NTWatcher<string>;\n    private registerEventsPromise: Promise<void>;\n    public init() {\n        this.mediaDownloadWatcher = new NTWatcher((args) => args[1][0].payload?.notifyInfo?.msgElementId, \"ns-ntApi\", \"nodeIKernelMsgListener/onRichMediaDownloadComplete\", \"in\", \"request\");\n        this.registerEventsPromise = ntCall(\"ns-ntApi\", \"nodeIKernelMsgListener/onRichMediaDownloadComplete\", [], true);\n    }\n    public async prepareImageElement(file: string) {\n        const type = await ntCall(\"ns-fsApi\", \"getFileType\", [file]);\n        const md5 = await ntCall(\"ns-fsApi\", \"getFileMd5\", [file]);\n        const fileName = `${md5}.${type.ext}`;\n        const filePath = await ntCall(\"ns-ntApi\", \"nodeIKernelMsgService/getRichMediaFilePath\", [\n            {\n                md5HexStr: md5,\n                fileName: fileName,\n                elementType: 2,\n                elementSubType: 0,\n                thumbSize: 0,\n                needCreate: true,\n                fileType: 1,\n            },\n        ]);\n        await ntCall(\"ns-fsApi\", \"copyFile\", [{ fromPath: file, toPath: filePath }]);\n        const imageSize = await ntCall(\"ns-fsApi\", \"getImageSizeFromPath\", [file]);\n        const fileSize = await ntCall(\"ns-fsApi\", \"getFileSize\", [file]);\n        return {\n            md5HexStr: md5,\n            fileSize: fileSize,\n            picWidth: imageSize.width,\n            picHeight: imageSize.height,\n            fileName: fileName,\n            sourcePath: filePath,\n            original: true,\n            picType: 1001,\n            picSubType: 0,\n            fileUuid: \"\",\n            fileSubId: \"\",\n            thumbFileSize: 0,\n            summary: \"\",\n        };\n    }\n    public async downloadMedia(msgId: string, elementId: string, peerUid: string, chatType: number, filePath: string, originalFilePath: string) {\n        if (await exists(originalFilePath)) return;\n        await this.registerEventsPromise;\n        ntCall(\"ns-ntApi\", \"nodeIKernelMsgService/downloadRichMedia\", [\n            {\n                getReq: {\n                    msgId: msgId,\n                    chatType: chatType,\n                    peerUid: peerUid,\n                    elementId: elementId,\n                    thumbSize: 0,\n                    downloadType: 2,\n                    filePath: filePath,\n                },\n            },\n            undefined,\n        ]);\n        return await this.mediaDownloadWatcher.wait(elementId).then(() => undefined);\n    }\n}\n\nexport const ntMedia = new NTMedia();\n"
  },
  {
    "path": "src/renderer/api/nt/watcher.ts",
    "content": "import { addInterruptIpc } from \"../../../common/ipc\";\n\nexport class NTWatcher<T extends string | number> {\n    private pendingList = {} as Record<T, Function>;\n    constructor(getId: (args: QQNTim.IPC.Args<any>) => T, eventName: string, cmdName: string, direction?: QQNTim.IPC.Direction, type?: QQNTim.IPC.Type) {\n        addInterruptIpc(\n            (args) => {\n                const id = getId(args);\n                if (this.pendingList[id]) {\n                    this.pendingList[id](args);\n                    delete this.pendingList[id];\n                    return false;\n                }\n            },\n            { type: type, eventName: eventName, cmdName: cmdName, direction: direction },\n        );\n    }\n    wait(id: T) {\n        return new Promise<QQNTim.IPC.Args<any>>((resolve) => {\n            this.pendingList[id] = (args: QQNTim.IPC.Args<any>) => {\n                resolve(args);\n            };\n        });\n    }\n}\n"
  },
  {
    "path": "src/renderer/api/waitForElement.ts",
    "content": "import { windowLoadPromise } from \"./windowLoadPromise\";\n\nlet waitForElementSelectors: [string, (element: Element) => void][] = [];\n\nwindowLoadPromise.then(() =>\n    new MutationObserver(() => refreshStatus()).observe(document.documentElement, {\n        childList: true,\n        subtree: true,\n    }),\n);\n\nexport function refreshStatus() {\n    waitForElementSelectors = waitForElementSelectors.filter(([selector, callback]) => {\n        const element = document.querySelector<Element>(selector);\n        element && callback(element);\n        return !element;\n    });\n}\n\nexport function waitForElement<T extends Element>(selector: string) {\n    return new Promise<T>((resolve) => {\n        waitForElementSelectors.push([\n            selector,\n            (element) => {\n                resolve(element as T);\n            },\n        ]);\n        refreshStatus();\n    });\n}\n"
  },
  {
    "path": "src/renderer/api/windowLoadPromise.ts",
    "content": "export const windowLoadPromise = new Promise<void>((resolve) => window.addEventListener(\"load\", () => resolve()));\n"
  },
  {
    "path": "src/renderer/debugger.ts",
    "content": "import { env } from \"../common/global\";\nimport { debuggerOrigin, webContentsId } from \"./main\";\n\nexport function attachDebugger() {\n    if (!env.config.useNativeDevTools)\n        window.addEventListener(\"DOMContentLoaded\", () => {\n            // 将标题临时改为当前 WebContents ID 用于标识此窗口\n            const oldTitle = document.title;\n            document.title = webContentsId;\n            window.addEventListener(\"load\", () => {\n                document.title = oldTitle == \"\" ? \"QQ\" : oldTitle;\n            });\n\n            const scriptTag = document.createElement(\"script\");\n            scriptTag.src = `${debuggerOrigin}/target.js`;\n            document.head.appendChild(scriptTag);\n        });\n}\n"
  },
  {
    "path": "src/renderer/loader.ts",
    "content": "import { loadPlugins } from \"../common/loader\";\nimport { windowLoadPromise } from \"./api/windowLoadPromise\";\nimport { ipcRenderer } from \"electron\";\nimport * as fs from \"fs-extra\";\n\nlet scripts: [QQNTim.Plugin, string][] = [];\nconst stylesheets: [QQNTim.Plugin, string][] = [];\n\nfunction detectCurrentPage(): QQNTim.Manifest.PageWithAbout {\n    const url = window.location.href;\n    for (const [keyword, name] of [\n        [\"login\", \"login\"],\n        [\"main\", \"main\"],\n        [\"chat\", \"chat\"],\n        [\"setting\", \"settings\"],\n        [\"about\", \"about\"],\n    ] as [string, QQNTim.Manifest.PageWithAbout][]) {\n        if (url.includes(keyword)) return name;\n    }\n    return \"others\";\n}\n\nfunction shouldInject(injection: QQNTim.Plugin.Injection, page: QQNTim.Manifest.Page) {\n    return injection.type == \"renderer\" && (!injection.pattern || injection.pattern.test(window.location.href)) && (!injection.page || injection.page.includes(page));\n}\n\nexport function applyPlugins(allPlugins: QQNTim.Plugin.AllUsersPlugins, uin = \"\") {\n    const page = detectCurrentPage();\n    if (page == \"about\") return false;\n\n    loadPlugins(allPlugins, uin, (injection) => shouldInject(injection, page), scripts, stylesheets);\n    applyScripts();\n\n    windowLoadPromise.then(() => applyStylesheets());\n\n    if (uin != \"\") ipcRenderer.send(\"___!apply_plugins\", uin);\n\n    return true;\n}\n\nfunction applyStylesheets() {\n    console.log(\"[!Loader] 正在注入 CSS\", stylesheets);\n\n    let element: HTMLStyleElement = document.querySelector(\"#qqntim_injected_styles\")!;\n    if (element) element.remove();\n\n    element = document.createElement(\"style\");\n    element.id = \"qqntim_injected_styles\";\n    element.innerHTML = stylesheets.map(([plugin, stylesheet]) => `/* ${plugin.manifest.id.replaceAll(\"/\", \"-\")} - ${stylesheet.replaceAll(\"/\", \"-\")} */\\n${fs.readFileSync(stylesheet).toString()}`).join(\"\\n\");\n    document.body.appendChild(element);\n}\n\nfunction applyScripts() {\n    scripts = scripts.filter(([plugin, script]) => {\n        try {\n            const mod = require(script);\n            if (mod) {\n                const entry = new ((mod.default || mod) as typeof QQNTim.Entry.Renderer)();\n                windowLoadPromise.then(() => entry.onWindowLoaded?.());\n            }\n            return false;\n        } catch (reason) {\n            console.error(`[!Loader] 运行此插件脚本时出现意外错误：${script}，请联系插件作者 (${plugin.manifest.author}) 解决`);\n            console.error(reason);\n        }\n        return true;\n    });\n}\n"
  },
  {
    "path": "src/renderer/main.ts",
    "content": "import { setAllPlugins, setEnv } from \"../common/global\";\nimport { watchIpc } from \"../common/ipc\";\nimport { initAPI } from \"./api\";\nimport { nt } from \"./api/nt\";\nimport { attachDebugger } from \"./debugger\";\nimport { applyPlugins } from \"./loader\";\nimport { patchLogger, patchModuleLoader } from \"./patch\";\nimport { hookVue3 } from \"./vueHelper\";\nimport { ipcRenderer } from \"electron\";\n\nexport const { enabled, preload, debuggerOrigin, webContentsId, plugins, env, hasColorSupport } = ipcRenderer.sendSync(\"___!boot\");\n\npatchModuleLoader();\nif (enabled) {\n    setEnv(env);\n    setAllPlugins(plugins);\n    patchLogger();\n    watchIpc();\n    hookVue3();\n    attachDebugger();\n    initAPI();\n\n    const timer = setInterval(() => {\n        if (window.location.href.includes(\"blank\")) return;\n        clearInterval(timer);\n        applyPlugins(plugins);\n        nt.getAccountInfo().then((account) => {\n            if (!account) return;\n            const uin = account.uin;\n            applyPlugins(plugins, uin);\n        });\n        console.log(\"[!Main] QQNTim 加载成功\");\n    }, 1);\n}\n\npreload.forEach((item: string) => require(item));\n"
  },
  {
    "path": "src/renderer/patch.ts",
    "content": "import { env } from \"../common/global\";\nimport { handleIpc } from \"../common/ipc\";\nimport { defineModules, getModule } from \"../common/patch\";\nimport { printObject } from \"../common/utils/console\";\nimport { getter, setter } from \"../common/watch\";\nimport { hasColorSupport } from \"./main\";\nimport { contextBridge, ipcRenderer } from \"electron\";\nimport { Module } from \"module\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport * as ReactDOMClient from \"react-dom/client\";\nimport * as ReactJSXRuntime from \"react/jsx-runtime\";\n\nfunction patchIpcRenderer() {\n    return new Proxy(ipcRenderer, {\n        get(target, p) {\n            if (p == \"on\")\n                return (channel: string, listener: (event: any, ...args: any[]) => void) => {\n                    target.on(channel, (event: any, ...args: QQNTim.IPC.Args<any>) => {\n                        if (handleIpc(args, \"in\", channel)) listener(event, ...args);\n                    });\n                };\n            else if (p == \"send\")\n                return (channel: string, ...args: QQNTim.IPC.Args<any>) => {\n                    if (handleIpc(args, \"out\", channel)) target.send(channel, ...args);\n                };\n            else if (p == \"sendSync\")\n                return (channel: string, ...args: QQNTim.IPC.Args<any>) => {\n                    if (handleIpc(args, \"out\", channel)) return target.sendSync(channel, ...args);\n                };\n            return getter(undefined, target, p as any);\n        },\n        set(target, p, newValue) {\n            return setter(undefined, target, p as any, newValue);\n        },\n    });\n}\n\nfunction patchContextBridge() {\n    return new Proxy(contextBridge, {\n        get(target, p) {\n            if (p == \"exposeInMainWorld\")\n                return (apiKey: string, api: any) => {\n                    window[apiKey] = api;\n                };\n            return getter(undefined, target, p as any);\n        },\n        set(target, p, newValue) {\n            return setter(undefined, target, p as any, newValue);\n        },\n    });\n}\n\nexport function patchModuleLoader() {\n    const patchedElectron: typeof Electron.CrossProcessExports = {\n        ...require(\"electron\"),\n        ipcRenderer: patchIpcRenderer(),\n        contextBridge: patchContextBridge(),\n    };\n\n    defineModules({ electron: patchedElectron, react: React, \"react/jsx-runtime\": ReactJSXRuntime, \"react-dom\": ReactDOM, \"react-dom/client\": ReactDOMClient });\n\n    const loadBackend = (Module as any)._load;\n    (Module as any)._load = (request: string, parent: NodeModule, isMain: boolean) => {\n        // 重写模块加载以隐藏 `vm` 模块弃用提示\n        if (request == \"vm\") request = \"node:vm\";\n        return getModule(request) || loadBackend(request, parent, isMain);\n    };\n}\n\nexport function patchLogger() {\n    if (env.config.useNativeDevTools) return;\n    const log = (level: number, ...args: any[]) => {\n        const serializedArgs: any[] = [];\n        for (const arg of args) {\n            serializedArgs.push(typeof arg == \"string\" ? arg : printObject(arg, hasColorSupport));\n        }\n        ipcRenderer.send(\"___!log\", level, ...serializedArgs);\n    };\n    (\n        [\n            [\"debug\", 0],\n            [\"log\", 1],\n            [\"info\", 2],\n            [\"warn\", 3],\n            [\"error\", 4],\n        ] as [string, number][]\n    ).forEach(([method, level]) => {\n        console[method] = (...args: any[]) => log(level, ...args);\n    });\n}\n"
  },
  {
    "path": "src/renderer/vueHelper.ts",
    "content": "interface Component {\n    vnode: {\n        el: VueElement;\n        component: Component;\n    };\n    bum: Function[];\n    uid: number;\n}\n\ninterface VueElement extends HTMLElement {\n    __VUE__?: Component[];\n}\n\n// Modified from https://greasyfork.org/zh-CN/scripts/449444-hook-vue3-app\n// Thanks to DreamNya & Cesaryuan ;)\n\nconst elements = new WeakMap<VueElement, Component[]>();\n(window as any).__VUE_ELEMENTS__ = elements;\n\nfunction watchComponentUnmount(component: Component) {\n    if (!component.bum) component.bum = [];\n    component.bum.push(() => {\n        const element = component.vnode.el;\n        if (element) {\n            const components = elements.get(element);\n            if (components?.length == 1) elements.delete(element);\n            else components?.splice(components.indexOf(component));\n            if (element.__VUE__?.length == 1) element.__VUE__ = undefined;\n            else element.__VUE__?.splice(element.__VUE__.indexOf(component));\n        }\n    });\n}\n\nfunction watchComponentMount(component: Component) {\n    let value: HTMLElement;\n    Object.defineProperty(component.vnode, \"el\", {\n        get() {\n            return value;\n        },\n        set(newValue) {\n            value = newValue;\n            if (value) recordComponent(component);\n        },\n    });\n}\n\nfunction recordComponent(component: Component) {\n    let element = component.vnode.el;\n    while (!(element instanceof HTMLElement)) element = (element as VueElement).parentElement!;\n\n    // Expose component to element's __VUE__ property\n    if (element.__VUE__) element.__VUE__.push(component);\n    else element.__VUE__ = [component];\n\n    // Add class to element\n    element.classList.add(\"vue-component\");\n\n    // Map element to components\n    const components = elements.get(element);\n    if (components) components.push(component);\n    else elements.set(element, [component]);\n\n    watchComponentUnmount(component);\n}\n\nexport function hookVue3() {\n    window.Proxy = new Proxy(window.Proxy, {\n        construct(target, [proxyTarget, proxyHandler]) {\n            const component = proxyTarget?._ as Component;\n            if (component?.uid >= 0) {\n                const element = component.vnode.el;\n                if (element) recordComponent(component);\n                else watchComponentMount(component);\n            }\n            return new target(proxyTarget, proxyHandler);\n        },\n    });\n\n    console.log(\"[!VueHelper] 输入 `__VUE_ELEMENTS__` 查看所有已挂载的 Vue 组件\");\n}\n"
  },
  {
    "path": "src/typings/COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "src/typings/COPYING.LESSER",
    "content": "                   GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\n  This version of the GNU Lesser General Public License incorporates\nthe terms and conditions of version 3 of the GNU General Public\nLicense, supplemented by the additional permissions listed below.\n\n  0. Additional Definitions.\n\n  As used herein, \"this License\" refers to version 3 of the GNU Lesser\nGeneral Public License, and the \"GNU GPL\" refers to version 3 of the GNU\nGeneral Public License.\n\n  \"The Library\" refers to a covered work governed by this License,\nother than an Application or a Combined Work as defined below.\n\n  An \"Application\" is any work that makes use of an interface provided\nby the Library, but which is not otherwise based on the Library.\nDefining a subclass of a class defined by the Library is deemed a mode\nof using an interface provided by the Library.\n\n  A \"Combined Work\" is a work produced by combining or linking an\nApplication with the Library.  The particular version of the Library\nwith which the Combined Work was made is also called the \"Linked\nVersion\".\n\n  The \"Minimal Corresponding Source\" for a Combined Work means the\nCorresponding Source for the Combined Work, excluding any source code\nfor portions of the Combined Work that, considered in isolation, are\nbased on the Application, and not on the Linked Version.\n\n  The \"Corresponding Application Code\" for a Combined Work means the\nobject code and/or source code for the Application, including any data\nand utility programs needed for reproducing the Combined Work from the\nApplication, but excluding the System Libraries of the Combined Work.\n\n  1. Exception to Section 3 of the GNU GPL.\n\n  You may convey a covered work under sections 3 and 4 of this License\nwithout being bound by section 3 of the GNU GPL.\n\n  2. Conveying Modified Versions.\n\n  If you modify a copy of the Library, and, in your modifications, a\nfacility refers to a function or data to be supplied by an Application\nthat uses the facility (other than as an argument passed when the\nfacility is invoked), then you may convey a copy of the modified\nversion:\n\n   a) under this License, provided that you make a good faith effort to\n   ensure that, in the event an Application does not supply the\n   function or data, the facility still operates, and performs\n   whatever part of its purpose remains meaningful, or\n\n   b) under the GNU GPL, with none of the additional permissions of\n   this License applicable to that copy.\n\n  3. Object Code Incorporating Material from Library Header Files.\n\n  The object code form of an Application may incorporate material from\na header file that is part of the Library.  You may convey such object\ncode under terms of your choice, provided that, if the incorporated\nmaterial is not limited to numerical parameters, data structure\nlayouts and accessors, or small macros, inline functions and templates\n(ten or fewer lines in length), you do both of the following:\n\n   a) Give prominent notice with each copy of the object code that the\n   Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the object code with a copy of the GNU GPL and this license\n   document.\n\n  4. Combined Works.\n\n  You may convey a Combined Work under terms of your choice that,\ntaken together, effectively do not restrict modification of the\nportions of the Library contained in the Combined Work and reverse\nengineering for debugging such modifications, if you also do each of\nthe following:\n\n   a) Give prominent notice with each copy of the Combined Work that\n   the Library is used in it and that the Library and its use are\n   covered by this License.\n\n   b) Accompany the Combined Work with a copy of the GNU GPL and this license\n   document.\n\n   c) For a Combined Work that displays copyright notices during\n   execution, include the copyright notice for the Library among\n   these notices, as well as a reference directing the user to the\n   copies of the GNU GPL and this license document.\n\n   d) Do one of the following:\n\n       0) Convey the Minimal Corresponding Source under the terms of this\n       License, and the Corresponding Application Code in a form\n       suitable for, and under terms that permit, the user to\n       recombine or relink the Application with a modified version of\n       the Linked Version to produce a modified Combined Work, in the\n       manner specified by section 6 of the GNU GPL for conveying\n       Corresponding Source.\n\n       1) Use a suitable shared library mechanism for linking with the\n       Library.  A suitable mechanism is one that (a) uses at run time\n       a copy of the Library already present on the user's computer\n       system, and (b) will operate properly with a modified version\n       of the Library that is interface-compatible with the Linked\n       Version.\n\n   e) Provide Installation Information, but only if you would otherwise\n   be required to provide such information under section 6 of the\n   GNU GPL, and only to the extent that such information is\n   necessary to install and execute a modified version of the\n   Combined Work produced by recombining or relinking the\n   Application with a modified version of the Linked Version. (If\n   you use option 4d0, the Installation Information must accompany\n   the Minimal Corresponding Source and Corresponding Application\n   Code. If you use option 4d1, you must provide the Installation\n   Information in the manner specified by section 6 of the GNU GPL\n   for conveying Corresponding Source.)\n\n  5. Combined Libraries.\n\n  You may place library facilities that are a work based on the\nLibrary side by side in a single library together with other library\nfacilities that are not Applications and are not covered by this\nLicense, and convey such a combined library under terms of your\nchoice, if you do both of the following:\n\n   a) Accompany the combined library with a copy of the same work based\n   on the Library, uncombined with any other library facilities,\n   conveyed under the terms of this License.\n\n   b) Give prominent notice with the combined library that part of it\n   is a work based on the Library, and explaining where to find the\n   accompanying uncombined form of the same work.\n\n  6. Revised Versions of the GNU Lesser General Public License.\n\n  The Free Software Foundation may publish revised and/or new versions\nof the GNU Lesser General Public License from time to time. Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.\n\n  Each version is given a distinguishing version number. If the\nLibrary as you received it specifies that a certain numbered version\nof the GNU Lesser General Public License \"or any later version\"\napplies to it, you have the option of following the terms and\nconditions either of that published version or of any later version\npublished by the Free Software Foundation. If the Library as you\nreceived it does not specify a version number of the GNU Lesser\nGeneral Public License, you may choose any version of the GNU Lesser\nGeneral Public License ever published by the Free Software Foundation.\n\n  If the Library as you received it specifies that a proxy can decide\nwhether future versions of the GNU Lesser General Public License shall\napply, that proxy's public statement of acceptance of any version is\npermanent authorization for you to choose that version for the\nLibrary.\n"
  },
  {
    "path": "src/typings/electron.d.ts",
    "content": "// Type definitions for Electron 25.2.0\n// Project: http://electronjs.org/\n// Definitions by: The Electron Team <https://github.com/electron/electron>\n// Definitions: https://github.com/electron/typescript-definitions\n\n/// <reference types=\"node\" />\n\ntype DOMEvent = Event;\ntype GlobalResponse = Response;\ntype GlobalRequest = Request;\n\ndeclare namespace Electron {\n    const NodeEventEmitter: typeof import(\"events\").EventEmitter;\n\n    type Accelerator = string;\n    type Event<Params extends object = {}> = {\n        preventDefault: () => void;\n        readonly defaultPrevented: boolean;\n    } & Params;\n\n    interface App extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/app\n\n        /**\n         * Emitted when Chrome's accessibility support changes. This event fires when\n         * assistive technologies, such as screen readers, are enabled or disabled. See\n         * https://www.chromium.org/developers/design-documents/accessibility for more\n         * details.\n         *\n         * @platform darwin,win32\n         */\n        on(\n            event: \"accessibility-support-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` when Chrome's accessibility support is enabled, `false` otherwise.\n                 */\n                accessibilitySupportEnabled: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"accessibility-support-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` when Chrome's accessibility support is enabled, `false` otherwise.\n                 */\n                accessibilitySupportEnabled: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"accessibility-support-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` when Chrome's accessibility support is enabled, `false` otherwise.\n                 */\n                accessibilitySupportEnabled: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"accessibility-support-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` when Chrome's accessibility support is enabled, `false` otherwise.\n                 */\n                accessibilitySupportEnabled: boolean,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the application is activated. Various actions can trigger this\n         * event, such as launching the application for the first time, attempting to\n         * re-launch the application when it's already running, or clicking on the\n         * application's dock or taskbar icon.\n         *\n         * @platform darwin\n         */\n        on(event: \"activate\", listener: (event: Event, hasVisibleWindows: boolean) => void): this;\n        once(event: \"activate\", listener: (event: Event, hasVisibleWindows: boolean) => void): this;\n        addListener(event: \"activate\", listener: (event: Event, hasVisibleWindows: boolean) => void): this;\n        removeListener(event: \"activate\", listener: (event: Event, hasVisibleWindows: boolean) => void): this;\n        /**\n         * Emitted during Handoff after an activity from this device was successfully\n         * resumed on another one.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"activity-was-continued\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        once(\n            event: \"activity-was-continued\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"activity-was-continued\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"activity-was-continued\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        /**\n         * Emitted before the application starts closing its windows. Calling\n         * `event.preventDefault()` will prevent the default behavior, which is terminating\n         * the application.\n         *\n         * **Note:** If application quit was initiated by `autoUpdater.quitAndInstall()`,\n         * then `before-quit` is emitted _after_ emitting `close` event on all windows and\n         * closing them.\n         *\n         * **Note:** On Windows, this event will not be emitted if the app is closed due to\n         * a shutdown/restart of the system or a user logout.\n         */\n        on(event: \"before-quit\", listener: (event: Event) => void): this;\n        once(event: \"before-quit\", listener: (event: Event) => void): this;\n        addListener(event: \"before-quit\", listener: (event: Event) => void): this;\n        removeListener(event: \"before-quit\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when a browserWindow gets blurred.\n         */\n        on(event: \"browser-window-blur\", listener: (event: Event, window: BrowserWindow) => void): this;\n        once(event: \"browser-window-blur\", listener: (event: Event, window: BrowserWindow) => void): this;\n        addListener(event: \"browser-window-blur\", listener: (event: Event, window: BrowserWindow) => void): this;\n        removeListener(event: \"browser-window-blur\", listener: (event: Event, window: BrowserWindow) => void): this;\n        /**\n         * Emitted when a new browserWindow is created.\n         */\n        on(event: \"browser-window-created\", listener: (event: Event, window: BrowserWindow) => void): this;\n        once(event: \"browser-window-created\", listener: (event: Event, window: BrowserWindow) => void): this;\n        addListener(event: \"browser-window-created\", listener: (event: Event, window: BrowserWindow) => void): this;\n        removeListener(event: \"browser-window-created\", listener: (event: Event, window: BrowserWindow) => void): this;\n        /**\n         * Emitted when a browserWindow gets focused.\n         */\n        on(event: \"browser-window-focus\", listener: (event: Event, window: BrowserWindow) => void): this;\n        once(event: \"browser-window-focus\", listener: (event: Event, window: BrowserWindow) => void): this;\n        addListener(event: \"browser-window-focus\", listener: (event: Event, window: BrowserWindow) => void): this;\n        removeListener(event: \"browser-window-focus\", listener: (event: Event, window: BrowserWindow) => void): this;\n        /**\n         * Emitted when failed to verify the `certificate` for `url`, to trust the\n         * certificate you should prevent the default behavior with\n         * `event.preventDefault()` and call `callback(true)`.\n         */\n        on(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                webContents: WebContents,\n                url: string,\n                /**\n                 * The error code\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                webContents: WebContents,\n                url: string,\n                /**\n                 * The error code\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                webContents: WebContents,\n                url: string,\n                /**\n                 * The error code\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                webContents: WebContents,\n                url: string,\n                /**\n                 * The error code\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the child process unexpectedly disappears. This is normally because\n         * it was crashed or killed. It does not include renderer processes.\n         */\n        on(event: \"child-process-gone\", listener: (event: Event, details: Details) => void): this;\n        once(event: \"child-process-gone\", listener: (event: Event, details: Details) => void): this;\n        addListener(event: \"child-process-gone\", listener: (event: Event, details: Details) => void): this;\n        removeListener(event: \"child-process-gone\", listener: (event: Event, details: Details) => void): this;\n        /**\n         * Emitted during Handoff when an activity from a different device wants to be\n         * resumed. You should call `event.preventDefault()` if you want to handle this\n         * event.\n         *\n         * A user activity can be continued only in an app that has the same developer Team\n         * ID as the activity's source app and that supports the activity's type. Supported\n         * activity types are specified in the app's `Info.plist` under the\n         * `NSUserActivityTypes` key.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity on another device.\n                 */\n                userInfo: unknown,\n                details: ContinueActivityDetails,\n            ) => void,\n        ): this;\n        once(\n            event: \"continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity on another device.\n                 */\n                userInfo: unknown,\n                details: ContinueActivityDetails,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity on another device.\n                 */\n                userInfo: unknown,\n                details: ContinueActivityDetails,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity on another device.\n                 */\n                userInfo: unknown,\n                details: ContinueActivityDetails,\n            ) => void,\n        ): this;\n        /**\n         * Emitted during Handoff when an activity from a different device fails to be\n         * resumed.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"continue-activity-error\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * A string with the error's localized description.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"continue-activity-error\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * A string with the error's localized description.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"continue-activity-error\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * A string with the error's localized description.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"continue-activity-error\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * A string with the error's localized description.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the application becomes active. This differs from the `activate`\n         * event in that `did-become-active` is emitted every time the app becomes active,\n         * not only when Dock icon is clicked or application is re-launched. It is also\n         * emitted when a user switches to the app via the macOS App Switcher.\n         *\n         * @platform darwin\n         */\n        on(event: \"did-become-active\", listener: (event: Event) => void): this;\n        once(event: \"did-become-active\", listener: (event: Event) => void): this;\n        addListener(event: \"did-become-active\", listener: (event: Event) => void): this;\n        removeListener(event: \"did-become-active\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when the app is no longer active and doesn’t have focus. This can be\n         * triggered, for example, by clicking on another application or by using the macOS\n         * App Switcher to switch to another application.\n         *\n         * @platform darwin\n         */\n        on(event: \"did-resign-active\", listener: (event: Event) => void): this;\n        once(event: \"did-resign-active\", listener: (event: Event) => void): this;\n        addListener(event: \"did-resign-active\", listener: (event: Event) => void): this;\n        removeListener(event: \"did-resign-active\", listener: (event: Event) => void): this;\n        /**\n         * Emitted whenever there is a GPU info update.\n         */\n        on(event: \"gpu-info-update\", listener: Function): this;\n        once(event: \"gpu-info-update\", listener: Function): this;\n        addListener(event: \"gpu-info-update\", listener: Function): this;\n        removeListener(event: \"gpu-info-update\", listener: Function): this;\n        /**\n         * Emitted when the GPU process crashes or is killed.\n         *\n         * **Deprecated:** This event is superceded by the `child-process-gone` event which\n         * contains more information about why the child process disappeared. It isn't\n         * always because it crashed. The `killed` boolean can be replaced by checking\n         * `reason === 'killed'` when you switch to that event.\n         *\n         * @deprecated\n         */\n        on(event: \"gpu-process-crashed\", listener: (event: Event, killed: boolean) => void): this;\n        once(event: \"gpu-process-crashed\", listener: (event: Event, killed: boolean) => void): this;\n        addListener(event: \"gpu-process-crashed\", listener: (event: Event, killed: boolean) => void): this;\n        removeListener(event: \"gpu-process-crashed\", listener: (event: Event, killed: boolean) => void): this;\n        /**\n         * Emitted when `webContents` wants to do basic auth.\n         *\n         * The default behavior is to cancel all authentications. To override this you\n         * should prevent the default behavior with `event.preventDefault()` and call\n         * `callback(username, password)` with the credentials.\n         *\n         * If `callback` is called without a username or password, the authentication\n         * request will be cancelled and the authentication error will be returned to the\n         * page.\n         */\n        on(event: \"login\", listener: (event: Event, webContents: WebContents, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        once(event: \"login\", listener: (event: Event, webContents: WebContents, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        addListener(event: \"login\", listener: (event: Event, webContents: WebContents, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        removeListener(event: \"login\", listener: (event: Event, webContents: WebContents, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        /**\n         * Emitted when the user clicks the native macOS new tab button. The new tab button\n         * is only visible if the current `BrowserWindow` has a `tabbingIdentifier`\n         *\n         * @platform darwin\n         */\n        on(event: \"new-window-for-tab\", listener: (event: Event) => void): this;\n        once(event: \"new-window-for-tab\", listener: (event: Event) => void): this;\n        addListener(event: \"new-window-for-tab\", listener: (event: Event) => void): this;\n        removeListener(event: \"new-window-for-tab\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when the user wants to open a file with the application. The `open-file`\n         * event is usually emitted when the application is already open and the OS wants\n         * to reuse the application to open the file. `open-file` is also emitted when a\n         * file is dropped onto the dock and the application is not yet running. Make sure\n         * to listen for the `open-file` event very early in your application startup to\n         * handle this case (even before the `ready` event is emitted).\n         *\n         * You should call `event.preventDefault()` if you want to handle this event.\n         *\n         * On Windows, you have to parse `process.argv` (in the main process) to get the\n         * filepath.\n         *\n         * @platform darwin\n         */\n        on(event: \"open-file\", listener: (event: Event, path: string) => void): this;\n        once(event: \"open-file\", listener: (event: Event, path: string) => void): this;\n        addListener(event: \"open-file\", listener: (event: Event, path: string) => void): this;\n        removeListener(event: \"open-file\", listener: (event: Event, path: string) => void): this;\n        /**\n         * Emitted when the user wants to open a URL with the application. Your\n         * application's `Info.plist` file must define the URL scheme within the\n         * `CFBundleURLTypes` key, and set `NSPrincipalClass` to `AtomApplication`.\n         *\n         * As with the `open-file` event, be sure to register a listener for the `open-url`\n         * event early in your application startup to detect if the the application being\n         * is being opened to handle a URL. If you register the listener in response to a\n         * `ready` event, you'll miss URLs that trigger the launch of your application.\n         *\n         * @platform darwin\n         */\n        on(event: \"open-url\", listener: (event: Event, url: string) => void): this;\n        once(event: \"open-url\", listener: (event: Event, url: string) => void): this;\n        addListener(event: \"open-url\", listener: (event: Event, url: string) => void): this;\n        removeListener(event: \"open-url\", listener: (event: Event, url: string) => void): this;\n        /**\n         * Emitted when the application is quitting.\n         *\n         * **Note:** On Windows, this event will not be emitted if the app is closed due to\n         * a shutdown/restart of the system or a user logout.\n         */\n        on(event: \"quit\", listener: (event: Event, exitCode: number) => void): this;\n        once(event: \"quit\", listener: (event: Event, exitCode: number) => void): this;\n        addListener(event: \"quit\", listener: (event: Event, exitCode: number) => void): this;\n        removeListener(event: \"quit\", listener: (event: Event, exitCode: number) => void): this;\n        /**\n         * Emitted once, when Electron has finished initializing. On macOS, `launchInfo`\n         * holds the `userInfo` of the `NSUserNotification` or information from\n         * `UNNotificationResponse` that was used to open the application, if it was\n         * launched from Notification Center. You can also call `app.isReady()` to check if\n         * this event has already fired and `app.whenReady()` to get a Promise that is\n         * fulfilled when Electron is initialized.\n         */\n        on(\n            event: \"ready\",\n            listener: (\n                event: Event,\n                /**\n                 * @platform darwin\n                 */\n                launchInfo: Record<string, any> | NotificationResponse,\n            ) => void,\n        ): this;\n        once(\n            event: \"ready\",\n            listener: (\n                event: Event,\n                /**\n                 * @platform darwin\n                 */\n                launchInfo: Record<string, any> | NotificationResponse,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"ready\",\n            listener: (\n                event: Event,\n                /**\n                 * @platform darwin\n                 */\n                launchInfo: Record<string, any> | NotificationResponse,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"ready\",\n            listener: (\n                event: Event,\n                /**\n                 * @platform darwin\n                 */\n                launchInfo: Record<string, any> | NotificationResponse,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the renderer process unexpectedly disappears.  This is normally\n         * because it was crashed or killed.\n         */\n        on(event: \"render-process-gone\", listener: (event: Event, webContents: WebContents, details: RenderProcessGoneDetails) => void): this;\n        once(event: \"render-process-gone\", listener: (event: Event, webContents: WebContents, details: RenderProcessGoneDetails) => void): this;\n        addListener(event: \"render-process-gone\", listener: (event: Event, webContents: WebContents, details: RenderProcessGoneDetails) => void): this;\n        removeListener(event: \"render-process-gone\", listener: (event: Event, webContents: WebContents, details: RenderProcessGoneDetails) => void): this;\n        /**\n         * Emitted when the renderer process of `webContents` crashes or is killed.\n         *\n         * **Deprecated:** This event is superceded by the `render-process-gone` event\n         * which contains more information about why the render process disappeared. It\n         * isn't always because it crashed.  The `killed` boolean can be replaced by\n         * checking `reason === 'killed'` when you switch to that event.\n         *\n         * @deprecated\n         */\n        on(event: \"renderer-process-crashed\", listener: (event: Event, webContents: WebContents, killed: boolean) => void): this;\n        once(event: \"renderer-process-crashed\", listener: (event: Event, webContents: WebContents, killed: boolean) => void): this;\n        addListener(event: \"renderer-process-crashed\", listener: (event: Event, webContents: WebContents, killed: boolean) => void): this;\n        removeListener(event: \"renderer-process-crashed\", listener: (event: Event, webContents: WebContents, killed: boolean) => void): this;\n        /**\n         * This event will be emitted inside the primary instance of your application when\n         * a second instance has been executed and calls `app.requestSingleInstanceLock()`.\n         *\n         * `argv` is an Array of the second instance's command line arguments, and\n         * `workingDirectory` is its current working directory. Usually applications\n         * respond to this by making their primary window focused and non-minimized.\n         *\n         * **Note:** `argv` will not be exactly the same list of arguments as those passed\n         * to the second instance. The order might change and additional arguments might be\n         * appended. If you need to maintain the exact same arguments, it's advised to use\n         * `additionalData` instead.\n         *\n         * **Note:** If the second instance is started by a different user than the first,\n         * the `argv` array will not include the arguments.\n         *\n         * This event is guaranteed to be emitted after the `ready` event of `app` gets\n         * emitted.\n         *\n         * **Note:** Extra command line arguments might be added by Chromium, such as\n         * `--original-process-start-time`.\n         */\n        on(\n            event: \"second-instance\",\n            listener: (\n                event: Event,\n                /**\n                 * An array of the second instance's command line arguments\n                 */\n                argv: string[],\n                /**\n                 * The second instance's working directory\n                 */\n                workingDirectory: string,\n                /**\n                 * A JSON object of additional data passed from the second instance\n                 */\n                additionalData: unknown,\n            ) => void,\n        ): this;\n        once(\n            event: \"second-instance\",\n            listener: (\n                event: Event,\n                /**\n                 * An array of the second instance's command line arguments\n                 */\n                argv: string[],\n                /**\n                 * The second instance's working directory\n                 */\n                workingDirectory: string,\n                /**\n                 * A JSON object of additional data passed from the second instance\n                 */\n                additionalData: unknown,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"second-instance\",\n            listener: (\n                event: Event,\n                /**\n                 * An array of the second instance's command line arguments\n                 */\n                argv: string[],\n                /**\n                 * The second instance's working directory\n                 */\n                workingDirectory: string,\n                /**\n                 * A JSON object of additional data passed from the second instance\n                 */\n                additionalData: unknown,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"second-instance\",\n            listener: (\n                event: Event,\n                /**\n                 * An array of the second instance's command line arguments\n                 */\n                argv: string[],\n                /**\n                 * The second instance's working directory\n                 */\n                workingDirectory: string,\n                /**\n                 * A JSON object of additional data passed from the second instance\n                 */\n                additionalData: unknown,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a client certificate is requested.\n         *\n         * The `url` corresponds to the navigation entry requesting the client certificate\n         * and `callback` can be called with an entry filtered from the list. Using\n         * `event.preventDefault()` prevents the application from using the first\n         * certificate from the store.\n         */\n        on(event: \"select-client-certificate\", listener: (event: Event, webContents: WebContents, url: string, certificateList: Certificate[], callback: (certificate?: Certificate) => void) => void): this;\n        once(event: \"select-client-certificate\", listener: (event: Event, webContents: WebContents, url: string, certificateList: Certificate[], callback: (certificate?: Certificate) => void) => void): this;\n        addListener(event: \"select-client-certificate\", listener: (event: Event, webContents: WebContents, url: string, certificateList: Certificate[], callback: (certificate?: Certificate) => void) => void): this;\n        removeListener(event: \"select-client-certificate\", listener: (event: Event, webContents: WebContents, url: string, certificateList: Certificate[], callback: (certificate?: Certificate) => void) => void): this;\n        /**\n         * Emitted when Electron has created a new `session`.\n         */\n        on(event: \"session-created\", listener: (session: Session) => void): this;\n        once(event: \"session-created\", listener: (session: Session) => void): this;\n        addListener(event: \"session-created\", listener: (session: Session) => void): this;\n        removeListener(event: \"session-created\", listener: (session: Session) => void): this;\n        /**\n         * Emitted when Handoff is about to be resumed on another device. If you need to\n         * update the state to be transferred, you should call `event.preventDefault()`\n         * immediately, construct a new `userInfo` dictionary and call\n         * `app.updateCurrentActivity()` in a timely manner. Otherwise, the operation will\n         * fail and `continue-activity-error` will be called.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"update-activity-state\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        once(\n            event: \"update-activity-state\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"update-activity-state\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"update-activity-state\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n                /**\n                 * Contains app-specific state stored by the activity.\n                 */\n                userInfo: unknown,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a new webContents is created.\n         */\n        on(event: \"web-contents-created\", listener: (event: Event, webContents: WebContents) => void): this;\n        once(event: \"web-contents-created\", listener: (event: Event, webContents: WebContents) => void): this;\n        addListener(event: \"web-contents-created\", listener: (event: Event, webContents: WebContents) => void): this;\n        removeListener(event: \"web-contents-created\", listener: (event: Event, webContents: WebContents) => void): this;\n        /**\n         * Emitted during Handoff before an activity from a different device wants to be\n         * resumed. You should call `event.preventDefault()` if you want to handle this\n         * event.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"will-continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"will-continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"will-continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"will-continue-activity\",\n            listener: (\n                event: Event,\n                /**\n                 * A string identifying the activity. Maps to `NSUserActivity.activityType`.\n                 */\n                type: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the application has finished basic startup. On Windows and Linux,\n         * the `will-finish-launching` event is the same as the `ready` event; on macOS,\n         * this event represents the `applicationWillFinishLaunching` notification of\n         * `NSApplication`.\n         *\n         * In most cases, you should do everything in the `ready` event handler.\n         */\n        on(event: \"will-finish-launching\", listener: Function): this;\n        once(event: \"will-finish-launching\", listener: Function): this;\n        addListener(event: \"will-finish-launching\", listener: Function): this;\n        removeListener(event: \"will-finish-launching\", listener: Function): this;\n        /**\n         * Emitted when all windows have been closed and the application will quit. Calling\n         * `event.preventDefault()` will prevent the default behavior, which is terminating\n         * the application.\n         *\n         * See the description of the `window-all-closed` event for the differences between\n         * the `will-quit` and `window-all-closed` events.\n         *\n         * **Note:** On Windows, this event will not be emitted if the app is closed due to\n         * a shutdown/restart of the system or a user logout.\n         */\n        on(event: \"will-quit\", listener: (event: Event) => void): this;\n        once(event: \"will-quit\", listener: (event: Event) => void): this;\n        addListener(event: \"will-quit\", listener: (event: Event) => void): this;\n        removeListener(event: \"will-quit\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when all windows have been closed.\n         *\n         * If you do not subscribe to this event and all windows are closed, the default\n         * behavior is to quit the app; however, if you subscribe, you control whether the\n         * app quits or not. If the user pressed `Cmd + Q`, or the developer called\n         * `app.quit()`, Electron will first try to close all the windows and then emit the\n         * `will-quit` event, and in this case the `window-all-closed` event would not be\n         * emitted.\n         */\n        on(event: \"window-all-closed\", listener: Function): this;\n        once(event: \"window-all-closed\", listener: Function): this;\n        addListener(event: \"window-all-closed\", listener: Function): this;\n        removeListener(event: \"window-all-closed\", listener: Function): this;\n        /**\n         * Adds `path` to the recent documents list.\n         *\n         * This list is managed by the OS. On Windows, you can visit the list from the task\n         * bar, and on macOS, you can visit it from dock menu.\n         *\n         * @platform darwin,win32\n         */\n        addRecentDocument(path: string): void;\n        /**\n         * Clears the recent documents list.\n         *\n         * @platform darwin,win32\n         */\n        clearRecentDocuments(): void;\n        /**\n         * Configures host resolution (DNS and DNS-over-HTTPS). By default, the following\n         * resolvers will be used, in order:\n         *\n         * * DNS-over-HTTPS, if the DNS provider supports it, then\n         * * the built-in resolver (enabled on macOS only by default), then\n         * * the system's resolver (e.g. `getaddrinfo`).\n         *\n         * This can be configured to either restrict usage of non-encrypted DNS\n         * (`secureDnsMode: \"secure\"`), or disable DNS-over-HTTPS (`secureDnsMode: \"off\"`).\n         * It is also possible to enable or disable the built-in resolver.\n         *\n         * To disable insecure DNS, you can specify a `secureDnsMode` of `\"secure\"`. If you\n         * do so, you should make sure to provide a list of DNS-over-HTTPS servers to use,\n         * in case the user's DNS configuration does not include a provider that supports\n         * DoH.\n         *\n         * This API must be called after the `ready` event is emitted.\n         */\n        configureHostResolver(options: ConfigureHostResolverOptions): void;\n        /**\n         * By default, Chromium disables 3D APIs (e.g. WebGL) until restart on a per domain\n         * basis if the GPU processes crashes too frequently. This function disables that\n         * behavior.\n         *\n         * This method can only be called before app is ready.\n         */\n        disableDomainBlockingFor3DAPIs(): void;\n        /**\n         * Disables hardware acceleration for current app.\n         *\n         * This method can only be called before app is ready.\n         */\n        disableHardwareAcceleration(): void;\n        /**\n         * Enables full sandbox mode on the app. This means that all renderers will be\n         * launched sandboxed, regardless of the value of the `sandbox` flag in\n         * WebPreferences.\n         *\n         * This method can only be called before app is ready.\n         */\n        enableSandbox(): void;\n        /**\n         * Exits immediately with `exitCode`. `exitCode` defaults to 0.\n         *\n         * All windows will be closed immediately without asking the user, and the\n         * `before-quit` and `will-quit` events will not be emitted.\n         */\n        exit(exitCode?: number): void;\n        /**\n         * On Linux, focuses on the first visible window. On macOS, makes the application\n         * the active app. On Windows, focuses on the application's first window.\n         *\n         * You should seek to use the `steal` option as sparingly as possible.\n         */\n        focus(options?: FocusOptions): void;\n        /**\n         * Resolve with an object containing the following:\n         *\n         * * `icon` NativeImage - the display icon of the app handling the protocol.\n         * * `path` string  - installation path of the app handling the protocol.\n         * * `name` string - display name of the app handling the protocol.\n         *\n         * This method returns a promise that contains the application name, icon and path\n         * of the default handler for the protocol (aka URI scheme) of a URL.\n         *\n         * @platform darwin,win32\n         */\n        getApplicationInfoForProtocol(url: string): Promise<Electron.ApplicationInfoForProtocolReturnValue>;\n        /**\n         * Name of the application handling the protocol, or an empty string if there is no\n         * handler. For instance, if Electron is the default handler of the URL, this could\n         * be `Electron` on Windows and Mac. However, don't rely on the precise format\n         * which is not guaranteed to remain unchanged. Expect a different format on Linux,\n         * possibly with a `.desktop` suffix.\n         *\n         * This method returns the application name of the default handler for the protocol\n         * (aka URI scheme) of a URL.\n         */\n        getApplicationNameForProtocol(url: string): string;\n        /**\n         * Array of `ProcessMetric` objects that correspond to memory and CPU usage\n         * statistics of all the processes associated with the app.\n         */\n        getAppMetrics(): ProcessMetric[];\n        /**\n         * The current application directory.\n         */\n        getAppPath(): string;\n        /**\n         * The current value displayed in the counter badge.\n         *\n         * @platform linux,darwin\n         */\n        getBadgeCount(): number;\n        /**\n         * The type of the currently running activity.\n         *\n         * @platform darwin\n         */\n        getCurrentActivityType(): string;\n        /**\n         * fulfilled with the app's icon, which is a NativeImage.\n         *\n         * Fetches a path's associated icon.\n         *\n         * On _Windows_, there a 2 kinds of icons:\n         *\n         * * Icons associated with certain file extensions, like `.mp3`, `.png`, etc.\n         * * Icons inside the file itself, like `.exe`, `.dll`, `.ico`.\n         *\n         * On _Linux_ and _macOS_, icons depend on the application associated with file\n         * mime type.\n         */\n        getFileIcon(path: string, options?: FileIconOptions): Promise<Electron.NativeImage>;\n        /**\n         * The Graphics Feature Status from `chrome://gpu/`.\n         *\n         * **Note:** This information is only usable after the `gpu-info-update` event is\n         * emitted.\n         */\n        getGPUFeatureStatus(): GPUFeatureStatus;\n        /**\n         * For `infoType` equal to `complete`: Promise is fulfilled with `Object`\n         * containing all the GPU Information as in chromium's GPUInfo object. This\n         * includes the version and driver information that's shown on `chrome://gpu` page.\n         *\n         * For `infoType` equal to `basic`: Promise is fulfilled with `Object` containing\n         * fewer attributes than when requested with `complete`. Here's an example of basic\n         * response:\n         *\n         * Using `basic` should be preferred if only basic information like `vendorId` or\n         * `deviceId` is needed.\n         */\n        getGPUInfo(infoType: \"basic\" | \"complete\"): Promise<unknown>;\n        /**\n         * * `minItems` Integer - The minimum number of items that will be shown in the\n         * Jump List (for a more detailed description of this value see the MSDN docs).\n         * * `removedItems` JumpListItem[] - Array of `JumpListItem` objects that\n         * correspond to items that the user has explicitly removed from custom categories\n         * in the Jump List. These items must not be re-added to the Jump List in the\n         * **next** call to `app.setJumpList()`, Windows will not display any custom\n         * category that contains any of the removed items.\n         *\n         * @platform win32\n         */\n        getJumpListSettings(): JumpListSettings;\n        /**\n         * The current application locale, fetched using Chromium's `l10n_util` library.\n         * Possible return values are documented here.\n         *\n         * To set the locale, you'll want to use a command line switch at app startup,\n         * which may be found here.\n         *\n         * **Note:** When distributing your packaged app, you have to also ship the\n         * `locales` folder.\n         *\n         * **Note:** This API must be called after the `ready` event is emitted.\n         *\n         * **Note:** To see example return values of this API compared to other locale and\n         * language APIs, see `app.getPreferredSystemLanguages()`.\n         */\n        getLocale(): string;\n        /**\n         * User operating system's locale two-letter ISO 3166 country code. The value is\n         * taken from native OS APIs.\n         *\n         * **Note:** When unable to detect locale country code, it returns empty string.\n         */\n        getLocaleCountryCode(): string;\n        /**\n         * If you provided `path` and `args` options to `app.setLoginItemSettings`, then\n         * you need to pass the same arguments here for `openAtLogin` to be set correctly.\n         *\n         *\n         * * `openAtLogin` boolean - `true` if the app is set to open at login.\n         * * `openAsHidden` boolean _macOS_ - `true` if the app is set to open as hidden at\n         * login. This setting is not available on MAS builds.\n         * * `wasOpenedAtLogin` boolean _macOS_ - `true` if the app was opened at login\n         * automatically. This setting is not available on MAS builds.\n         * * `wasOpenedAsHidden` boolean _macOS_ - `true` if the app was opened as a hidden\n         * login item. This indicates that the app should not open any windows at startup.\n         * This setting is not available on MAS builds.\n         * * `restoreState` boolean _macOS_ - `true` if the app was opened as a login item\n         * that should restore the state from the previous session. This indicates that the\n         * app should restore the windows that were open the last time the app was closed.\n         * This setting is not available on MAS builds.\n         * * `executableWillLaunchAtLogin` boolean _Windows_ - `true` if app is set to open\n         * at login and its run key is not deactivated. This differs from `openAtLogin` as\n         * it ignores the `args` option, this property will be true if the given executable\n         * would be launched at login with **any** arguments.\n         * * `launchItems` Object[] _Windows_\n         *   * `name` string _Windows_ - name value of a registry entry.\n         *   * `path` string _Windows_ - The executable to an app that corresponds to a\n         * registry entry.\n         *   * `args` string[] _Windows_ - the command-line arguments to pass to the\n         * executable.\n         *   * `scope` string _Windows_ - one of `user` or `machine`. Indicates whether the\n         * registry entry is under `HKEY_CURRENT USER` or `HKEY_LOCAL_MACHINE`.\n         *   * `enabled` boolean _Windows_ - `true` if the app registry key is startup\n         * approved and therefore shows as `enabled` in Task Manager and Windows settings.\n         *\n         * @platform darwin,win32\n         */\n        getLoginItemSettings(options?: LoginItemSettingsOptions): LoginItemSettings;\n        /**\n         * The current application's name, which is the name in the application's\n         * `package.json` file.\n         *\n         * Usually the `name` field of `package.json` is a short lowercase name, according\n         * to the npm modules spec. You should usually also specify a `productName` field,\n         * which is your application's full capitalized name, and which will be preferred\n         * over `name` by Electron.\n         */\n        getName(): string;\n        /**\n         * A path to a special directory or file associated with `name`. On failure, an\n         * `Error` is thrown.\n         *\n         * If `app.getPath('logs')` is called without called `app.setAppLogsPath()` being\n         * called first, a default log directory will be created equivalent to calling\n         * `app.setAppLogsPath()` without a `path` parameter.\n         */\n        getPath(name: \"home\" | \"appData\" | \"userData\" | \"sessionData\" | \"temp\" | \"exe\" | \"module\" | \"desktop\" | \"documents\" | \"downloads\" | \"music\" | \"pictures\" | \"videos\" | \"recent\" | \"logs\" | \"crashDumps\"): string;\n        /**\n         * The user's preferred system languages from most preferred to least preferred,\n         * including the country codes if applicable. A user can modify and add to this\n         * list on Windows or macOS through the Language and Region settings.\n         *\n         * The API uses `GlobalizationPreferences` (with a fallback to\n         * `GetSystemPreferredUILanguages`) on Windows, `\\[NSLocale preferredLanguages\\]`\n         * on macOS, and `g_get_language_names` on Linux.\n         *\n         * This API can be used for purposes such as deciding what language to present the\n         * application in.\n         *\n         * Here are some examples of return values of the various language and locale APIs\n         * with different configurations:\n         *\n         * On Windows, given application locale is German, the regional format is Finnish\n         * (Finland), and the preferred system languages from most to least preferred are\n         * French (Canada), English (US), Simplified Chinese (China), Finnish, and Spanish\n         * (Latin America):\n         *\n         * On macOS, given the application locale is German, the region is Finland, and the\n         * preferred system languages from most to least preferred are French (Canada),\n         * English (US), Simplified Chinese, and Spanish (Latin America):\n         *\n         * Both the available languages and regions and the possible return values differ\n         * between the two operating systems.\n         *\n         * As can be seen with the example above, on Windows, it is possible that a\n         * preferred system language has no country code, and that one of the preferred\n         * system languages corresponds with the language used for the regional format. On\n         * macOS, the region serves more as a default country code: the user doesn't need\n         * to have Finnish as a preferred language to use Finland as the region,and the\n         * country code `FI` is used as the country code for preferred system languages\n         * that do not have associated countries in the language name.\n         */\n        getPreferredSystemLanguages(): string[];\n        /**\n         * The current system locale. On Windows and Linux, it is fetched using Chromium's\n         * `i18n` library. On macOS, `[NSLocale currentLocale]` is used instead. To get the\n         * user's current system language, which is not always the same as the locale, it\n         * is better to use `app.getPreferredSystemLanguages()`.\n         *\n         * Different operating systems also use the regional data differently:\n         *\n         * * Windows 11 uses the regional format for numbers, dates, and times.\n         * * macOS Monterey uses the region for formatting numbers, dates, times, and for\n         * selecting the currency symbol to use.\n         *\n         * Therefore, this API can be used for purposes such as choosing a format for\n         * rendering dates and times in a calendar app, especially when the developer wants\n         * the format to be consistent with the OS.\n         *\n         * **Note:** This API must be called after the `ready` event is emitted.\n         *\n         * **Note:** To see example return values of this API compared to other locale and\n         * language APIs, see `app.getPreferredSystemLanguages()`.\n         */\n        getSystemLocale(): string;\n        /**\n         * The version of the loaded application. If no version is found in the\n         * application's `package.json` file, the version of the current bundle or\n         * executable is returned.\n         */\n        getVersion(): string;\n        /**\n         * This method returns whether or not this instance of your app is currently\n         * holding the single instance lock.  You can request the lock with\n         * `app.requestSingleInstanceLock()` and release with\n         * `app.releaseSingleInstanceLock()`\n         */\n        hasSingleInstanceLock(): boolean;\n        /**\n         * Hides all application windows without minimizing them.\n         *\n         * @platform darwin\n         */\n        hide(): void;\n        /**\n         * Imports the certificate in pkcs12 format into the platform certificate store.\n         * `callback` is called with the `result` of import operation, a value of `0`\n         * indicates success while any other value indicates failure according to Chromium\n         * net_error_list.\n         *\n         * @platform linux\n         */\n        importCertificate(options: ImportCertificateOptions, callback: (result: number) => void): void;\n        /**\n         * Invalidates the current Handoff user activity.\n         *\n         * @platform darwin\n         */\n        invalidateCurrentActivity(): void;\n        /**\n         * `true` if Chrome's accessibility support is enabled, `false` otherwise. This API\n         * will return `true` if the use of assistive technologies, such as screen readers,\n         * has been detected. See\n         * https://www.chromium.org/developers/design-documents/accessibility for more\n         * details.\n         *\n         * @platform darwin,win32\n         */\n        isAccessibilitySupportEnabled(): boolean;\n        /**\n         * Whether the current executable is the default handler for a protocol (aka URI\n         * scheme).\n         *\n         * **Note:** On macOS, you can use this method to check if the app has been\n         * registered as the default protocol handler for a protocol. You can also verify\n         * this by checking `~/Library/Preferences/com.apple.LaunchServices.plist` on the\n         * macOS machine. Please refer to Apple's documentation for details.\n         *\n         * The API uses the Windows Registry and `LSCopyDefaultHandlerForURLScheme`\n         * internally.\n         */\n        isDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean;\n        /**\n         * whether or not the current OS version allows for native emoji pickers.\n         */\n        isEmojiPanelSupported(): boolean;\n        /**\n         * `true` if the application—including all of its windows—is hidden (e.g. with\n         * `Command-H`), `false` otherwise.\n         *\n         * @platform darwin\n         */\n        isHidden(): boolean;\n        /**\n         * Whether the application is currently running from the systems Application\n         * folder. Use in combination with `app.moveToApplicationsFolder()`\n         *\n         * @platform darwin\n         */\n        isInApplicationsFolder(): boolean;\n        /**\n         * `true` if Electron has finished initializing, `false` otherwise. See also\n         * `app.whenReady()`.\n         */\n        isReady(): boolean;\n        /**\n         * whether `Secure Keyboard Entry` is enabled.\n         *\n         * By default this API will return `false`.\n         *\n         * @platform darwin\n         */\n        isSecureKeyboardEntryEnabled(): boolean;\n        /**\n         * Whether the current desktop environment is Unity launcher.\n         *\n         * @platform linux\n         */\n        isUnityRunning(): boolean;\n        /**\n         * Whether the move was successful. Please note that if the move is successful,\n         * your application will quit and relaunch.\n         *\n         * No confirmation dialog will be presented by default. If you wish to allow the\n         * user to confirm the operation, you may do so using the `dialog` API.\n         *\n         * **NOTE:** This method throws errors if anything other than the user causes the\n         * move to fail. For instance if the user cancels the authorization dialog, this\n         * method returns false. If we fail to perform the copy, then this method will\n         * throw an error. The message in the error should be informative and tell you\n         * exactly what went wrong.\n         *\n         * By default, if an app of the same name as the one being moved exists in the\n         * Applications directory and is _not_ running, the existing app will be trashed\n         * and the active app moved into its place. If it _is_ running, the preexisting\n         * running app will assume focus and the previously active app will quit itself.\n         * This behavior can be changed by providing the optional conflict handler, where\n         * the boolean returned by the handler determines whether or not the move conflict\n         * is resolved with default behavior.  i.e. returning `false` will ensure no\n         * further action is taken, returning `true` will result in the default behavior\n         * and the method continuing.\n         *\n         * For example:\n         *\n         * Would mean that if an app already exists in the user directory, if the user\n         * chooses to 'Continue Move' then the function would continue with its default\n         * behavior and the existing app will be trashed and the active app moved into its\n         * place.\n         *\n         * @platform darwin\n         */\n        moveToApplicationsFolder(options?: MoveToApplicationsFolderOptions): boolean;\n        /**\n         * Try to close all windows. The `before-quit` event will be emitted first. If all\n         * windows are successfully closed, the `will-quit` event will be emitted and by\n         * default the application will terminate.\n         *\n         * This method guarantees that all `beforeunload` and `unload` event handlers are\n         * correctly executed. It is possible that a window cancels the quitting by\n         * returning `false` in the `beforeunload` event handler.\n         */\n        quit(): void;\n        /**\n         * Relaunches the app when current instance exits.\n         *\n         * By default, the new instance will use the same working directory and command\n         * line arguments with current instance. When `args` is specified, the `args` will\n         * be passed as command line arguments instead. When `execPath` is specified, the\n         * `execPath` will be executed for relaunch instead of current app.\n         *\n         * Note that this method does not quit the app when executed, you have to call\n         * `app.quit` or `app.exit` after calling `app.relaunch` to make the app restart.\n         *\n         * When `app.relaunch` is called for multiple times, multiple instances will be\n         * started after current instance exited.\n         *\n         * An example of restarting current instance immediately and adding a new command\n         * line argument to the new instance:\n         */\n        relaunch(options?: RelaunchOptions): void;\n        /**\n         * Releases all locks that were created by `requestSingleInstanceLock`. This will\n         * allow multiple instances of the application to once again run side by side.\n         */\n        releaseSingleInstanceLock(): void;\n        /**\n         * Whether the call succeeded.\n         *\n         * This method checks if the current executable as the default handler for a\n         * protocol (aka URI scheme). If so, it will remove the app as the default handler.\n         *\n         * @platform darwin,win32\n         */\n        removeAsDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean;\n        /**\n         * The return value of this method indicates whether or not this instance of your\n         * application successfully obtained the lock.  If it failed to obtain the lock,\n         * you can assume that another instance of your application is already running with\n         * the lock and exit immediately.\n         *\n         * I.e. This method returns `true` if your process is the primary instance of your\n         * application and your app should continue loading.  It returns `false` if your\n         * process should immediately quit as it has sent its parameters to another\n         * instance that has already acquired the lock.\n         *\n         * On macOS, the system enforces single instance automatically when users try to\n         * open a second instance of your app in Finder, and the `open-file` and `open-url`\n         * events will be emitted for that. However when users start your app in command\n         * line, the system's single instance mechanism will be bypassed, and you have to\n         * use this method to ensure single instance.\n         *\n         * An example of activating the window of primary instance when a second instance\n         * starts:\n         */\n        requestSingleInstanceLock(additionalData?: Record<any, any>): boolean;\n        /**\n         * Marks the current Handoff user activity as inactive without invalidating it.\n         *\n         * @platform darwin\n         */\n        resignCurrentActivity(): void;\n        /**\n         * Set the about panel options. This will override the values defined in the app's\n         * `.plist` file on macOS. See the Apple docs for more details. On Linux, values\n         * must be set in order to be shown; there are no defaults.\n         *\n         * If you do not set `credits` but still wish to surface them in your app, AppKit\n         * will look for a file named \"Credits.html\", \"Credits.rtf\", and \"Credits.rtfd\", in\n         * that order, in the bundle returned by the NSBundle class method main. The first\n         * file found is used, and if none is found, the info area is left blank. See Apple\n         * documentation for more information.\n         */\n        setAboutPanelOptions(options: AboutPanelOptionsOptions): void;\n        /**\n         * Manually enables Chrome's accessibility support, allowing to expose\n         * accessibility switch to users in application settings. See Chromium's\n         * accessibility docs for more details. Disabled by default.\n         *\n         * This API must be called after the `ready` event is emitted.\n         *\n         * **Note:** Rendering accessibility tree can significantly affect the performance\n         * of your app. It should not be enabled by default.\n         *\n         * @platform darwin,win32\n         */\n        setAccessibilitySupportEnabled(enabled: boolean): void;\n        /**\n         * Sets the activation policy for a given app.\n         *\n         * Activation policy types:\n         *\n         * * 'regular' - The application is an ordinary app that appears in the Dock and\n         * may have a user interface.\n         * * 'accessory' - The application doesn’t appear in the Dock and doesn’t have a\n         * menu bar, but it may be activated programmatically or by clicking on one of its\n         * windows.\n         * * 'prohibited' - The application doesn’t appear in the Dock and may not create\n         * windows or be activated.\n         *\n         * @platform darwin\n         */\n        setActivationPolicy(policy: \"regular\" | \"accessory\" | \"prohibited\"): void;\n        /**\n         * Sets or creates a directory your app's logs which can then be manipulated with\n         * `app.getPath()` or `app.setPath(pathName, newPath)`.\n         *\n         * Calling `app.setAppLogsPath()` without a `path` parameter will result in this\n         * directory being set to `~/Library/Logs/YourAppName` on _macOS_, and inside the\n         * `userData` directory on _Linux_ and _Windows_.\n         */\n        setAppLogsPath(path?: string): void;\n        /**\n         * Changes the Application User Model ID to `id`.\n         *\n         * @platform win32\n         */\n        setAppUserModelId(id: string): void;\n        /**\n         * Whether the call succeeded.\n         *\n         * Sets the current executable as the default handler for a protocol (aka URI\n         * scheme). It allows you to integrate your app deeper into the operating system.\n         * Once registered, all links with `your-protocol://` will be opened with the\n         * current executable. The whole link, including protocol, will be passed to your\n         * application as a parameter.\n         *\n         * **Note:** On macOS, you can only register protocols that have been added to your\n         * app's `info.plist`, which cannot be modified at runtime. However, you can change\n         * the file during build time via Electron Forge, Electron Packager, or by editing\n         * `info.plist` with a text editor. Please refer to Apple's documentation for\n         * details.\n         *\n         * **Note:** In a Windows Store environment (when packaged as an `appx`) this API\n         * will return `true` for all calls but the registry key it sets won't be\n         * accessible by other applications.  In order to register your Windows Store\n         * application as a default protocol handler you must declare the protocol in your\n         * manifest.\n         *\n         * The API uses the Windows Registry and `LSSetDefaultHandlerForURLScheme`\n         * internally.\n         */\n        setAsDefaultProtocolClient(protocol: string, path?: string, args?: string[]): boolean;\n        /**\n         * Whether the call succeeded.\n         *\n         * Sets the counter badge for current app. Setting the count to `0` will hide the\n         * badge.\n         *\n         * On macOS, it shows on the dock icon. On Linux, it only works for Unity launcher.\n         *\n         * **Note:** Unity launcher requires a `.desktop` file to work. For more\n         * information, please read the Unity integration documentation.\n         *\n         * @platform linux,darwin\n         */\n        setBadgeCount(count?: number): boolean;\n        /**\n         * Sets or removes a custom Jump List for the application, and returns one of the\n         * following strings:\n         *\n         * * `ok` - Nothing went wrong.\n         * * `error` - One or more errors occurred, enable runtime logging to figure out\n         * the likely cause.\n         * * `invalidSeparatorError` - An attempt was made to add a separator to a custom\n         * category in the Jump List. Separators are only allowed in the standard `Tasks`\n         * category.\n         * * `fileTypeRegistrationError` - An attempt was made to add a file link to the\n         * Jump List for a file type the app isn't registered to handle.\n         * * `customCategoryAccessDeniedError` - Custom categories can't be added to the\n         * Jump List due to user privacy or group policy settings.\n         *\n         * If `categories` is `null` the previously set custom Jump List (if any) will be\n         * replaced by the standard Jump List for the app (managed by Windows).\n         *\n         * **Note:** If a `JumpListCategory` object has neither the `type` nor the `name`\n         * property set then its `type` is assumed to be `tasks`. If the `name` property is\n         * set but the `type` property is omitted then the `type` is assumed to be\n         * `custom`.\n         *\n         * **Note:** Users can remove items from custom categories, and Windows will not\n         * allow a removed item to be added back into a custom category until **after** the\n         * next successful call to `app.setJumpList(categories)`. Any attempt to re-add a\n         * removed item to a custom category earlier than that will result in the entire\n         * custom category being omitted from the Jump List. The list of removed items can\n         * be obtained using `app.getJumpListSettings()`.\n         *\n         * **Note:** The maximum length of a Jump List item's `description` property is 260\n         * characters. Beyond this limit, the item will not be added to the Jump List, nor\n         * will it be displayed.\n         *\n         * Here's a very simple example of creating a custom Jump List:\n         *\n         * @platform win32\n         */\n        setJumpList(categories: JumpListCategory[] | null): \"ok\" | \"error\" | \"invalidSeparatorError\" | \"fileTypeRegistrationError\" | \"customCategoryAccessDeniedError\";\n        /**\n         * To work with Electron's `autoUpdater` on Windows, which uses Squirrel, you'll\n         * want to set the launch path to Update.exe, and pass arguments that specify your\n         * application name. For example:\n         *\n         * @platform darwin,win32\n         */\n        setLoginItemSettings(settings: Settings): void;\n        /**\n         * Overrides the current application's name.\n         *\n         * **Note:** This function overrides the name used internally by Electron; it does\n         * not affect the name that the OS uses.\n         */\n        setName(name: string): void;\n        /**\n         * Overrides the `path` to a special directory or file associated with `name`. If\n         * the path specifies a directory that does not exist, an `Error` is thrown. In\n         * that case, the directory should be created with `fs.mkdirSync` or similar.\n         *\n         * You can only override paths of a `name` defined in `app.getPath`.\n         *\n         * By default, web pages' cookies and caches will be stored under the `sessionData`\n         * directory. If you want to change this location, you have to override the\n         * `sessionData` path before the `ready` event of the `app` module is emitted.\n         */\n        setPath(name: string, path: string): void;\n        /**\n         * Set the `Secure Keyboard Entry` is enabled in your application.\n         *\n         * By using this API, important information such as password and other sensitive\n         * information can be prevented from being intercepted by other processes.\n         *\n         * See Apple's documentation for more details.\n         *\n         * **Note:** Enable `Secure Keyboard Entry` only when it is needed and disable it\n         * when it is no longer needed.\n         *\n         * @platform darwin\n         */\n        setSecureKeyboardEntryEnabled(enabled: boolean): void;\n        /**\n         * Creates an `NSUserActivity` and sets it as the current activity. The activity is\n         * eligible for Handoff to another device afterward.\n         *\n         * @platform darwin\n         */\n        setUserActivity(type: string, userInfo: any, webpageURL?: string): void;\n        /**\n         * Adds `tasks` to the Tasks category of the Jump List on Windows.\n         *\n         * `tasks` is an array of `Task` objects.\n         *\n         * Whether the call succeeded.\n         *\n         * **Note:** If you'd like to customize the Jump List even more use\n         * `app.setJumpList(categories)` instead.\n         *\n         * @platform win32\n         */\n        setUserTasks(tasks: Task[]): boolean;\n        /**\n         * Shows application windows after they were hidden. Does not automatically focus\n         * them.\n         *\n         * @platform darwin\n         */\n        show(): void;\n        /**\n         * Show the app's about panel options. These options can be overridden with\n         * `app.setAboutPanelOptions(options)`. This function runs asynchronously.\n         */\n        showAboutPanel(): void;\n        /**\n         * Show the platform's native emoji picker.\n         *\n         * @platform darwin,win32\n         */\n        showEmojiPanel(): void;\n        /**\n         * This function **must** be called once you have finished accessing the security\n         * scoped file. If you do not remember to stop accessing the bookmark, kernel\n         * resources will be leaked and your app will lose its ability to reach outside the\n         * sandbox completely, until your app is restarted.\n         *\n         * Start accessing a security scoped resource. With this method Electron\n         * applications that are packaged for the Mac App Store may reach outside their\n         * sandbox to access files chosen by the user. See Apple's documentation for a\n         * description of how this system works.\n         *\n         * @platform mas\n         */\n        startAccessingSecurityScopedResource(bookmarkData: string): Function;\n        /**\n         * Updates the current activity if its type matches `type`, merging the entries\n         * from `userInfo` into its current `userInfo` dictionary.\n         *\n         * @platform darwin\n         */\n        updateCurrentActivity(type: string, userInfo: any): void;\n        /**\n         * fulfilled when Electron is initialized. May be used as a convenient alternative\n         * to checking `app.isReady()` and subscribing to the `ready` event if the app is\n         * not ready yet.\n         */\n        whenReady(): Promise<void>;\n        /**\n         * A `boolean` property that's `true` if Chrome's accessibility support is enabled,\n         * `false` otherwise. This property will be `true` if the use of assistive\n         * technologies, such as screen readers, has been detected. Setting this property\n         * to `true` manually enables Chrome's accessibility support, allowing developers\n         * to expose accessibility switch to users in application settings.\n         *\n         * See Chromium's accessibility docs for more details. Disabled by default.\n         *\n         * This API must be called after the `ready` event is emitted.\n         *\n         * **Note:** Rendering accessibility tree can significantly affect the performance\n         * of your app. It should not be enabled by default.\n         *\n         * @platform darwin,win32\n         */\n        accessibilitySupportEnabled: boolean;\n        /**\n         * A `Menu | null` property that returns `Menu` if one has been set and `null`\n         * otherwise. Users can pass a Menu to set this property.\n         */\n        applicationMenu: Menu | null;\n        /**\n         * An `Integer` property that returns the badge count for current app. Setting the\n         * count to `0` will hide the badge.\n         *\n         * On macOS, setting this with any nonzero integer shows on the dock icon. On\n         * Linux, this property only works for Unity launcher.\n         *\n         * **Note:** Unity launcher requires a `.desktop` file to work. For more\n         * information, please read the Unity integration documentation.\n         *\n         * **Note:** On macOS, you need to ensure that your application has the permission\n         * to display notifications for this property to take effect.\n         *\n         * @platform linux,darwin\n         */\n        badgeCount: number;\n        /**\n         * A `CommandLine` object that allows you to read and manipulate the command line\n         * arguments that Chromium uses.\n         *\n         */\n        readonly commandLine: CommandLine;\n        /**\n         * A `Dock` `| undefined` object that allows you to perform actions on your app\n         * icon in the user's dock on macOS.\n         *\n         * @platform darwin\n         */\n        readonly dock: Dock;\n        /**\n         * A `boolean` property that returns  `true` if the app is packaged, `false`\n         * otherwise. For many apps, this property can be used to distinguish development\n         * and production environments.\n         *\n         */\n        readonly isPackaged: boolean;\n        /**\n         * A `string` property that indicates the current application's name, which is the\n         * name in the application's `package.json` file.\n         *\n         * Usually the `name` field of `package.json` is a short lowercase name, according\n         * to the npm modules spec. You should usually also specify a `productName` field,\n         * which is your application's full capitalized name, and which will be preferred\n         * over `name` by Electron.\n         */\n        name: string;\n        /**\n         * A `boolean` which when `true` indicates that the app is currently running under\n         * an ARM64 translator (like the macOS Rosetta Translator Environment or Windows\n         * WOW).\n         *\n         * You can use this property to prompt users to download the arm64 version of your\n         * application when they are mistakenly running the x64 version under Rosetta or\n         * WOW.\n         *\n         * @platform darwin,win32\n         */\n        readonly runningUnderARM64Translation: boolean;\n        /**\n         * A `boolean` which when `true` indicates that the app is currently running under\n         * the Rosetta Translator Environment.\n         *\n         * You can use this property to prompt users to download the arm64 version of your\n         * application when they are running the x64 version under Rosetta incorrectly.\n         *\n         * **Deprecated:** This property is superceded by the\n         * `runningUnderARM64Translation` property which detects when the app is being\n         * translated to ARM64 in both macOS and Windows.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        readonly runningUnderRosettaTranslation: boolean;\n        /**\n         * A `string` which is the user agent string Electron will use as a global\n         * fallback.\n         *\n         * This is the user agent that will be used when no user agent is set at the\n         * `webContents` or `session` level.  It is useful for ensuring that your entire\n         * app has the same user agent.  Set to a custom value as early as possible in your\n         * app's initialization to ensure that your overridden value is used.\n         */\n        userAgentFallback: string;\n    }\n\n    interface AutoUpdater extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/auto-updater\n\n        /**\n         * This event is emitted after a user calls `quitAndInstall()`.\n         *\n         * When this API is called, the `before-quit` event is not emitted before all\n         * windows are closed. As a result you should listen to this event if you wish to\n         * perform actions before the windows are closed while a process is quitting, as\n         * well as listening to `before-quit`.\n         */\n        on(event: \"before-quit-for-update\", listener: Function): this;\n        once(event: \"before-quit-for-update\", listener: Function): this;\n        addListener(event: \"before-quit-for-update\", listener: Function): this;\n        removeListener(event: \"before-quit-for-update\", listener: Function): this;\n        /**\n         * Emitted when checking if an update has started.\n         */\n        on(event: \"checking-for-update\", listener: Function): this;\n        once(event: \"checking-for-update\", listener: Function): this;\n        addListener(event: \"checking-for-update\", listener: Function): this;\n        removeListener(event: \"checking-for-update\", listener: Function): this;\n        /**\n         * Emitted when there is an error while updating.\n         */\n        on(event: \"error\", listener: (error: Error) => void): this;\n        once(event: \"error\", listener: (error: Error) => void): this;\n        addListener(event: \"error\", listener: (error: Error) => void): this;\n        removeListener(event: \"error\", listener: (error: Error) => void): this;\n        /**\n         * Emitted when there is an available update. The update is downloaded\n         * automatically.\n         */\n        on(event: \"update-available\", listener: Function): this;\n        once(event: \"update-available\", listener: Function): this;\n        addListener(event: \"update-available\", listener: Function): this;\n        removeListener(event: \"update-available\", listener: Function): this;\n        /**\n         * Emitted when an update has been downloaded.\n         *\n         * On Windows only `releaseName` is available.\n         *\n         * **Note:** It is not strictly necessary to handle this event. A successfully\n         * downloaded update will still be applied the next time the application starts.\n         */\n        on(event: \"update-downloaded\", listener: (event: Event, releaseNotes: string, releaseName: string, releaseDate: Date, updateURL: string) => void): this;\n        once(event: \"update-downloaded\", listener: (event: Event, releaseNotes: string, releaseName: string, releaseDate: Date, updateURL: string) => void): this;\n        addListener(event: \"update-downloaded\", listener: (event: Event, releaseNotes: string, releaseName: string, releaseDate: Date, updateURL: string) => void): this;\n        removeListener(event: \"update-downloaded\", listener: (event: Event, releaseNotes: string, releaseName: string, releaseDate: Date, updateURL: string) => void): this;\n        /**\n         * Emitted when there is no available update.\n         */\n        on(event: \"update-not-available\", listener: Function): this;\n        once(event: \"update-not-available\", listener: Function): this;\n        addListener(event: \"update-not-available\", listener: Function): this;\n        removeListener(event: \"update-not-available\", listener: Function): this;\n        /**\n         * Asks the server whether there is an update. You must call `setFeedURL` before\n         * using this API.\n         *\n         * **Note:** If an update is available it will be downloaded automatically. Calling\n         * `autoUpdater.checkForUpdates()` twice will download the update two times.\n         */\n        checkForUpdates(): void;\n        /**\n         * The current update feed URL.\n         */\n        getFeedURL(): string;\n        /**\n         * Restarts the app and installs the update after it has been downloaded. It should\n         * only be called after `update-downloaded` has been emitted.\n         *\n         * Under the hood calling `autoUpdater.quitAndInstall()` will close all application\n         * windows first, and automatically call `app.quit()` after all windows have been\n         * closed.\n         *\n         * **Note:** It is not strictly necessary to call this function to apply an update,\n         * as a successfully downloaded update will always be applied the next time the\n         * application starts.\n         */\n        quitAndInstall(): void;\n        /**\n         * Sets the `url` and initialize the auto updater.\n         */\n        setFeedURL(options: FeedURLOptions): void;\n    }\n\n    interface BluetoothDevice {\n        // Docs: https://electronjs.org/docs/api/structures/bluetooth-device\n\n        deviceId: string;\n        deviceName: string;\n    }\n\n    class BrowserView {\n        // Docs: https://electronjs.org/docs/api/browser-view\n\n        /**\n         * BrowserView\n         */\n        constructor(options?: BrowserViewConstructorOptions);\n        /**\n         * The `bounds` of this BrowserView instance as `Object`.\n         *\n         * @experimental\n         */\n        getBounds(): Rectangle;\n        /**\n         * @experimental\n         */\n        setAutoResize(options: AutoResizeOptions): void;\n        /**\n         * Examples of valid `color` values:\n         *\n         * * Hex\n         *   * #fff (RGB)\n         *   * #ffff (ARGB)\n         *   * #ffffff (RRGGBB)\n         *   * #ffffffff (AARRGGBB)\n         * * RGB\n         *   * rgb(([\\d]+),\\s*([\\d]+),\\s*([\\d]+))\n         *     * e.g. rgb(255, 255, 255)\n         * * RGBA\n         *   * rgba(([\\d]+),\\s*([\\d]+),\\s*([\\d]+),\\s*([\\d.]+))\n         *     * e.g. rgba(255, 255, 255, 1.0)\n         * * HSL\n         *   * hsl((-?[\\d.]+),\\s*([\\d.]+)%,\\s*([\\d.]+)%)\n         *     * e.g. hsl(200, 20%, 50%)\n         * * HSLA\n         *   * hsla((-?[\\d.]+),\\s*([\\d.]+)%,\\s*([\\d.]+)%,\\s*([\\d.]+))\n         *     * e.g. hsla(200, 20%, 50%, 0.5)\n         * * Color name\n         *   * Options are listed in SkParseColor.cpp\n         *   * Similar to CSS Color Module Level 3 keywords, but case-sensitive.\n         *     * e.g. `blueviolet` or `red`\n         *\n         * **Note:** Hex format with alpha takes `AARRGGBB` or `ARGB`, _not_ `RRGGBBA` or\n         * `RGA`.\n         *\n         * @experimental\n         */\n        setBackgroundColor(color: string): void;\n        /**\n         * Resizes and moves the view to the supplied bounds relative to the window.\n         *\n         * @experimental\n         */\n        setBounds(bounds: Rectangle): void;\n        /**\n         * A `WebContents` object owned by this view.\n         *\n         * @experimental\n         */\n        webContents: WebContents;\n    }\n\n    class BrowserWindow extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/browser-window\n\n        /**\n         * Emitted when the window is set or unset to show always on top of other windows.\n         */\n        on(event: \"always-on-top-changed\", listener: (event: Event, isAlwaysOnTop: boolean) => void): this;\n        once(event: \"always-on-top-changed\", listener: (event: Event, isAlwaysOnTop: boolean) => void): this;\n        addListener(event: \"always-on-top-changed\", listener: (event: Event, isAlwaysOnTop: boolean) => void): this;\n        removeListener(event: \"always-on-top-changed\", listener: (event: Event, isAlwaysOnTop: boolean) => void): this;\n        /**\n         * Emitted when an App Command is invoked. These are typically related to keyboard\n         * media keys or browser commands, as well as the \"Back\" button built into some\n         * mice on Windows.\n         *\n         * Commands are lowercased, underscores are replaced with hyphens, and the\n         * `APPCOMMAND_` prefix is stripped off. e.g. `APPCOMMAND_BROWSER_BACKWARD` is\n         * emitted as `browser-backward`.\n         *\n         * The following app commands are explicitly supported on Linux:\n         *\n         * * `browser-backward`\n         * * `browser-forward`\n         *\n         * @platform win32,linux\n         */\n        on(event: \"app-command\", listener: (event: Event, command: string) => void): this;\n        once(event: \"app-command\", listener: (event: Event, command: string) => void): this;\n        addListener(event: \"app-command\", listener: (event: Event, command: string) => void): this;\n        removeListener(event: \"app-command\", listener: (event: Event, command: string) => void): this;\n        /**\n         * Emitted when the window loses focus.\n         */\n        on(event: \"blur\", listener: Function): this;\n        once(event: \"blur\", listener: Function): this;\n        addListener(event: \"blur\", listener: Function): this;\n        removeListener(event: \"blur\", listener: Function): this;\n        /**\n         * Emitted when the window is going to be closed. It's emitted before the\n         * `beforeunload` and `unload` event of the DOM. Calling `event.preventDefault()`\n         * will cancel the close.\n         *\n         * Usually you would want to use the `beforeunload` handler to decide whether the\n         * window should be closed, which will also be called when the window is reloaded.\n         * In Electron, returning any value other than `undefined` would cancel the close.\n         * For example:\n         *\n         * _**Note**: There is a subtle difference between the behaviors of\n         * `window.onbeforeunload = handler` and `window.addEventListener('beforeunload',\n         * handler)`. It is recommended to always set the `event.returnValue` explicitly,\n         * instead of only returning a value, as the former works more consistently within\n         * Electron._\n         */\n        on(event: \"close\", listener: (event: Event) => void): this;\n        once(event: \"close\", listener: (event: Event) => void): this;\n        addListener(event: \"close\", listener: (event: Event) => void): this;\n        removeListener(event: \"close\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when the window is closed. After you have received this event you should\n         * remove the reference to the window and avoid using it any more.\n         */\n        on(event: \"closed\", listener: Function): this;\n        once(event: \"closed\", listener: Function): this;\n        addListener(event: \"closed\", listener: Function): this;\n        removeListener(event: \"closed\", listener: Function): this;\n        /**\n         * Emitted when the window enters a full-screen state.\n         */\n        on(event: \"enter-full-screen\", listener: Function): this;\n        once(event: \"enter-full-screen\", listener: Function): this;\n        addListener(event: \"enter-full-screen\", listener: Function): this;\n        removeListener(event: \"enter-full-screen\", listener: Function): this;\n        /**\n         * Emitted when the window enters a full-screen state triggered by HTML API.\n         */\n        on(event: \"enter-html-full-screen\", listener: Function): this;\n        once(event: \"enter-html-full-screen\", listener: Function): this;\n        addListener(event: \"enter-html-full-screen\", listener: Function): this;\n        removeListener(event: \"enter-html-full-screen\", listener: Function): this;\n        /**\n         * Emitted when the window gains focus.\n         */\n        on(event: \"focus\", listener: Function): this;\n        once(event: \"focus\", listener: Function): this;\n        addListener(event: \"focus\", listener: Function): this;\n        removeListener(event: \"focus\", listener: Function): this;\n        /**\n         * Emitted when the window is hidden.\n         */\n        on(event: \"hide\", listener: Function): this;\n        once(event: \"hide\", listener: Function): this;\n        addListener(event: \"hide\", listener: Function): this;\n        removeListener(event: \"hide\", listener: Function): this;\n        /**\n         * Emitted when the window leaves a full-screen state.\n         */\n        on(event: \"leave-full-screen\", listener: Function): this;\n        once(event: \"leave-full-screen\", listener: Function): this;\n        addListener(event: \"leave-full-screen\", listener: Function): this;\n        removeListener(event: \"leave-full-screen\", listener: Function): this;\n        /**\n         * Emitted when the window leaves a full-screen state triggered by HTML API.\n         */\n        on(event: \"leave-html-full-screen\", listener: Function): this;\n        once(event: \"leave-html-full-screen\", listener: Function): this;\n        addListener(event: \"leave-html-full-screen\", listener: Function): this;\n        removeListener(event: \"leave-html-full-screen\", listener: Function): this;\n        /**\n         * Emitted when window is maximized.\n         */\n        on(event: \"maximize\", listener: Function): this;\n        once(event: \"maximize\", listener: Function): this;\n        addListener(event: \"maximize\", listener: Function): this;\n        removeListener(event: \"maximize\", listener: Function): this;\n        /**\n         * Emitted when the window is minimized.\n         */\n        on(event: \"minimize\", listener: Function): this;\n        once(event: \"minimize\", listener: Function): this;\n        addListener(event: \"minimize\", listener: Function): this;\n        removeListener(event: \"minimize\", listener: Function): this;\n        /**\n         * Emitted when the window is being moved to a new position.\n         */\n        on(event: \"move\", listener: Function): this;\n        once(event: \"move\", listener: Function): this;\n        addListener(event: \"move\", listener: Function): this;\n        removeListener(event: \"move\", listener: Function): this;\n        /**\n         * Emitted once when the window is moved to a new position.\n         *\n         * **Note**: On macOS this event is an alias of `move`.\n         *\n         * @platform darwin,win32\n         */\n        on(event: \"moved\", listener: Function): this;\n        once(event: \"moved\", listener: Function): this;\n        addListener(event: \"moved\", listener: Function): this;\n        removeListener(event: \"moved\", listener: Function): this;\n        /**\n         * Emitted when the native new tab button is clicked.\n         *\n         * @platform darwin\n         */\n        on(event: \"new-window-for-tab\", listener: Function): this;\n        once(event: \"new-window-for-tab\", listener: Function): this;\n        addListener(event: \"new-window-for-tab\", listener: Function): this;\n        removeListener(event: \"new-window-for-tab\", listener: Function): this;\n        /**\n         * Emitted when the document changed its title, calling `event.preventDefault()`\n         * will prevent the native window's title from changing. `explicitSet` is false\n         * when title is synthesized from file URL.\n         */\n        on(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        once(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        addListener(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        removeListener(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        /**\n         * Emitted when the web page has been rendered (while not being shown) and window\n         * can be displayed without a visual flash.\n         *\n         * Please note that using this event implies that the renderer will be considered\n         * \"visible\" and paint even though `show` is false.  This event will never fire if\n         * you use `paintWhenInitiallyHidden: false`\n         */\n        on(event: \"ready-to-show\", listener: Function): this;\n        once(event: \"ready-to-show\", listener: Function): this;\n        addListener(event: \"ready-to-show\", listener: Function): this;\n        removeListener(event: \"ready-to-show\", listener: Function): this;\n        /**\n         * Emitted after the window has been resized.\n         */\n        on(event: \"resize\", listener: Function): this;\n        once(event: \"resize\", listener: Function): this;\n        addListener(event: \"resize\", listener: Function): this;\n        removeListener(event: \"resize\", listener: Function): this;\n        /**\n         * Emitted once when the window has finished being resized.\n         *\n         * This is usually emitted when the window has been resized manually. On macOS,\n         * resizing the window with `setBounds`/`setSize` and setting the `animate`\n         * parameter to `true` will also emit this event once resizing has finished.\n         *\n         * @platform darwin,win32\n         */\n        on(event: \"resized\", listener: Function): this;\n        once(event: \"resized\", listener: Function): this;\n        addListener(event: \"resized\", listener: Function): this;\n        removeListener(event: \"resized\", listener: Function): this;\n        /**\n         * Emitted when the unresponsive web page becomes responsive again.\n         */\n        on(event: \"responsive\", listener: Function): this;\n        once(event: \"responsive\", listener: Function): this;\n        addListener(event: \"responsive\", listener: Function): this;\n        removeListener(event: \"responsive\", listener: Function): this;\n        /**\n         * Emitted when the window is restored from a minimized state.\n         */\n        on(event: \"restore\", listener: Function): this;\n        once(event: \"restore\", listener: Function): this;\n        addListener(event: \"restore\", listener: Function): this;\n        removeListener(event: \"restore\", listener: Function): this;\n        /**\n         * Emitted on trackpad rotation gesture. Continually emitted until rotation gesture\n         * is ended. The `rotation` value on each emission is the angle in degrees rotated\n         * since the last emission. The last emitted event upon a rotation gesture will\n         * always be of value `0`. Counter-clockwise rotation values are positive, while\n         * clockwise ones are negative.\n         *\n         * @platform darwin\n         */\n        on(event: \"rotate-gesture\", listener: (event: Event, rotation: number) => void): this;\n        once(event: \"rotate-gesture\", listener: (event: Event, rotation: number) => void): this;\n        addListener(event: \"rotate-gesture\", listener: (event: Event, rotation: number) => void): this;\n        removeListener(event: \"rotate-gesture\", listener: (event: Event, rotation: number) => void): this;\n        /**\n         * Emitted when scroll wheel event phase has begun.\n         *\n         * > **Note** This event is deprecated beginning in Electron 22.0.0. See Breaking\n         * Changes for details of how to migrate to using the WebContents `input-event`\n         * event.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        on(event: \"scroll-touch-begin\", listener: Function): this;\n        once(event: \"scroll-touch-begin\", listener: Function): this;\n        addListener(event: \"scroll-touch-begin\", listener: Function): this;\n        removeListener(event: \"scroll-touch-begin\", listener: Function): this;\n        /**\n         * Emitted when scroll wheel event phase filed upon reaching the edge of element.\n         *\n         * > **Note** This event is deprecated beginning in Electron 22.0.0. See Breaking\n         * Changes for details of how to migrate to using the WebContents `input-event`\n         * event.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        on(event: \"scroll-touch-edge\", listener: Function): this;\n        once(event: \"scroll-touch-edge\", listener: Function): this;\n        addListener(event: \"scroll-touch-edge\", listener: Function): this;\n        removeListener(event: \"scroll-touch-edge\", listener: Function): this;\n        /**\n         * Emitted when scroll wheel event phase has ended.\n         *\n         * > **Note** This event is deprecated beginning in Electron 22.0.0. See Breaking\n         * Changes for details of how to migrate to using the WebContents `input-event`\n         * event.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        on(event: \"scroll-touch-end\", listener: Function): this;\n        once(event: \"scroll-touch-end\", listener: Function): this;\n        addListener(event: \"scroll-touch-end\", listener: Function): this;\n        removeListener(event: \"scroll-touch-end\", listener: Function): this;\n        /**\n         * Emitted when window session is going to end due to force shutdown or machine\n         * restart or session log off.\n         *\n         * @platform win32\n         */\n        on(event: \"session-end\", listener: Function): this;\n        once(event: \"session-end\", listener: Function): this;\n        addListener(event: \"session-end\", listener: Function): this;\n        removeListener(event: \"session-end\", listener: Function): this;\n        /**\n         * Emitted when the window opens a sheet.\n         *\n         * @platform darwin\n         */\n        on(event: \"sheet-begin\", listener: Function): this;\n        once(event: \"sheet-begin\", listener: Function): this;\n        addListener(event: \"sheet-begin\", listener: Function): this;\n        removeListener(event: \"sheet-begin\", listener: Function): this;\n        /**\n         * Emitted when the window has closed a sheet.\n         *\n         * @platform darwin\n         */\n        on(event: \"sheet-end\", listener: Function): this;\n        once(event: \"sheet-end\", listener: Function): this;\n        addListener(event: \"sheet-end\", listener: Function): this;\n        removeListener(event: \"sheet-end\", listener: Function): this;\n        /**\n         * Emitted when the window is shown.\n         */\n        on(event: \"show\", listener: Function): this;\n        once(event: \"show\", listener: Function): this;\n        addListener(event: \"show\", listener: Function): this;\n        removeListener(event: \"show\", listener: Function): this;\n        /**\n         * Emitted on 3-finger swipe. Possible directions are `up`, `right`, `down`,\n         * `left`.\n         *\n         * The method underlying this event is built to handle older macOS-style trackpad\n         * swiping, where the content on the screen doesn't move with the swipe. Most macOS\n         * trackpads are not configured to allow this kind of swiping anymore, so in order\n         * for it to emit properly the 'Swipe between pages' preference in `System\n         * Preferences > Trackpad > More Gestures` must be set to 'Swipe with two or three\n         * fingers'.\n         *\n         * @platform darwin\n         */\n        on(event: \"swipe\", listener: (event: Event, direction: string) => void): this;\n        once(event: \"swipe\", listener: (event: Event, direction: string) => void): this;\n        addListener(event: \"swipe\", listener: (event: Event, direction: string) => void): this;\n        removeListener(event: \"swipe\", listener: (event: Event, direction: string) => void): this;\n        /**\n         * Emitted when the system context menu is triggered on the window, this is\n         * normally only triggered when the user right clicks on the non-client area of\n         * your window.  This is the window titlebar or any area you have declared as\n         * `-webkit-app-region: drag` in a frameless window.\n         *\n         * Calling `event.preventDefault()` will prevent the menu from being displayed.\n         *\n         * @platform win32\n         */\n        on(\n            event: \"system-context-menu\",\n            listener: (\n                event: Event,\n                /**\n                 * The screen coordinates the context menu was triggered at\n                 */\n                point: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"system-context-menu\",\n            listener: (\n                event: Event,\n                /**\n                 * The screen coordinates the context menu was triggered at\n                 */\n                point: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"system-context-menu\",\n            listener: (\n                event: Event,\n                /**\n                 * The screen coordinates the context menu was triggered at\n                 */\n                point: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"system-context-menu\",\n            listener: (\n                event: Event,\n                /**\n                 * The screen coordinates the context menu was triggered at\n                 */\n                point: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the window exits from a maximized state.\n         */\n        on(event: \"unmaximize\", listener: Function): this;\n        once(event: \"unmaximize\", listener: Function): this;\n        addListener(event: \"unmaximize\", listener: Function): this;\n        removeListener(event: \"unmaximize\", listener: Function): this;\n        /**\n         * Emitted when the web page becomes unresponsive.\n         */\n        on(event: \"unresponsive\", listener: Function): this;\n        once(event: \"unresponsive\", listener: Function): this;\n        addListener(event: \"unresponsive\", listener: Function): this;\n        removeListener(event: \"unresponsive\", listener: Function): this;\n        /**\n         * Emitted before the window is moved. On Windows, calling `event.preventDefault()`\n         * will prevent the window from being moved.\n         *\n         * Note that this is only emitted when the window is being moved manually. Moving\n         * the window with `setPosition`/`setBounds`/`center` will not emit this event.\n         *\n         * @platform darwin,win32\n         */\n        on(\n            event: \"will-move\",\n            listener: (\n                event: Event,\n                /**\n                 * Location the window is being moved to.\n                 */\n                newBounds: Rectangle,\n            ) => void,\n        ): this;\n        once(\n            event: \"will-move\",\n            listener: (\n                event: Event,\n                /**\n                 * Location the window is being moved to.\n                 */\n                newBounds: Rectangle,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"will-move\",\n            listener: (\n                event: Event,\n                /**\n                 * Location the window is being moved to.\n                 */\n                newBounds: Rectangle,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"will-move\",\n            listener: (\n                event: Event,\n                /**\n                 * Location the window is being moved to.\n                 */\n                newBounds: Rectangle,\n            ) => void,\n        ): this;\n        /**\n         * Emitted before the window is resized. Calling `event.preventDefault()` will\n         * prevent the window from being resized.\n         *\n         * Note that this is only emitted when the window is being resized manually.\n         * Resizing the window with `setBounds`/`setSize` will not emit this event.\n         *\n         * The possible values and behaviors of the `edge` option are platform dependent.\n         * Possible values are:\n         *\n         * * On Windows, possible values are `bottom`, `top`, `left`, `right`, `top-left`,\n         * `top-right`, `bottom-left`, `bottom-right`.\n         * * On macOS, possible values are `bottom` and `right`.\n         *   * The value `bottom` is used to denote vertical resizing.\n         *   * The value `right` is used to denote horizontal resizing.\n         *\n         * @platform darwin,win32\n         */\n        on(\n            event: \"will-resize\",\n            listener: (\n                event: Event,\n                /**\n                 * Size the window is being resized to.\n                 */\n                newBounds: Rectangle,\n                details: WillResizeDetails,\n            ) => void,\n        ): this;\n        once(\n            event: \"will-resize\",\n            listener: (\n                event: Event,\n                /**\n                 * Size the window is being resized to.\n                 */\n                newBounds: Rectangle,\n                details: WillResizeDetails,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"will-resize\",\n            listener: (\n                event: Event,\n                /**\n                 * Size the window is being resized to.\n                 */\n                newBounds: Rectangle,\n                details: WillResizeDetails,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"will-resize\",\n            listener: (\n                event: Event,\n                /**\n                 * Size the window is being resized to.\n                 */\n                newBounds: Rectangle,\n                details: WillResizeDetails,\n            ) => void,\n        ): this;\n        /**\n         * BrowserWindow\n         */\n        constructor(options?: BrowserWindowConstructorOptions);\n        /**\n         * The window that owns the given `browserView`. If the given view is not attached\n         * to any window, returns `null`.\n         */\n        static fromBrowserView(browserView: BrowserView): BrowserWindow | null;\n        /**\n         * The window with the given `id`.\n         */\n        static fromId(id: number): BrowserWindow | null;\n        /**\n         * The window that owns the given `webContents` or `null` if the contents are not\n         * owned by a window.\n         */\n        static fromWebContents(webContents: WebContents): BrowserWindow | null;\n        /**\n         * An array of all opened browser windows.\n         */\n        static getAllWindows(): BrowserWindow[];\n        /**\n         * The window that is focused in this application, otherwise returns `null`.\n         */\n        static getFocusedWindow(): BrowserWindow | null;\n        /**\n         * Replacement API for setBrowserView supporting work with multi browser views.\n         *\n         * @experimental\n         */\n        addBrowserView(browserView: BrowserView): void;\n        /**\n         * Adds a window as a tab on this window, after the tab for the window instance.\n         *\n         * @platform darwin\n         */\n        addTabbedWindow(browserWindow: BrowserWindow): void;\n        /**\n         * Removes focus from the window.\n         */\n        blur(): void;\n        blurWebView(): void;\n        /**\n         * Resolves with a NativeImage\n         *\n         * Captures a snapshot of the page within `rect`. Omitting `rect` will capture the\n         * whole visible page. If the page is not visible, `rect` may be empty. The page is\n         * considered visible when its browser window is hidden and the capturer count is\n         * non-zero. If you would like the page to stay hidden, you should ensure that\n         * `stayHidden` is set to true.\n         */\n        capturePage(rect?: Rectangle, opts?: Opts): Promise<Electron.NativeImage>;\n        /**\n         * Moves window to the center of the screen.\n         */\n        center(): void;\n        /**\n         * Try to close the window. This has the same effect as a user manually clicking\n         * the close button of the window. The web page may cancel the close though. See\n         * the close event.\n         */\n        close(): void;\n        /**\n         * Closes the currently open Quick Look panel.\n         *\n         * @platform darwin\n         */\n        closeFilePreview(): void;\n        /**\n         * Force closing the window, the `unload` and `beforeunload` event won't be emitted\n         * for the web page, and `close` event will also not be emitted for this window,\n         * but it guarantees the `closed` event will be emitted.\n         */\n        destroy(): void;\n        /**\n         * Starts or stops flashing the window to attract user's attention.\n         */\n        flashFrame(flag: boolean): void;\n        /**\n         * Focuses on the window.\n         */\n        focus(): void;\n        focusOnWebView(): void;\n        /**\n         * Gets the background color of the window in Hex (`#RRGGBB`) format.\n         *\n         * See Setting `backgroundColor`.\n         *\n         * **Note:** The alpha value is _not_ returned alongside the red, green, and blue\n         * values.\n         */\n        getBackgroundColor(): string;\n        /**\n         * The `bounds` of the window as `Object`.\n         */\n        getBounds(): Rectangle;\n        /**\n         * The `BrowserView` attached to `win`. Returns `null` if one is not attached.\n         * Throws an error if multiple `BrowserView`s are attached.\n         *\n         * @experimental\n         */\n        getBrowserView(): BrowserView | null;\n        /**\n         * an array of all BrowserViews that have been attached with `addBrowserView` or\n         * `setBrowserView`.\n         *\n         * **Note:** The BrowserView API is currently experimental and may change or be\n         * removed in future Electron releases.\n         *\n         * @experimental\n         */\n        getBrowserViews(): BrowserView[];\n        /**\n         * All child windows.\n         */\n        getChildWindows(): BrowserWindow[];\n        /**\n         * The `bounds` of the window's client area as `Object`.\n         */\n        getContentBounds(): Rectangle;\n        /**\n         * Contains the window's client area's width and height.\n         */\n        getContentSize(): number[];\n        /**\n         * Contains the window's maximum width and height.\n         */\n        getMaximumSize(): number[];\n        /**\n         * Window id in the format of DesktopCapturerSource's id. For example\n         * \"window:1324:0\".\n         *\n         * More precisely the format is `window:id:other_id` where `id` is `HWND` on\n         * Windows, `CGWindowID` (`uint64_t`) on macOS and `Window` (`unsigned long`) on\n         * Linux. `other_id` is used to identify web contents (tabs) so within the same top\n         * level window.\n         */\n        getMediaSourceId(): string;\n        /**\n         * Contains the window's minimum width and height.\n         */\n        getMinimumSize(): number[];\n        /**\n         * The platform-specific handle of the window.\n         *\n         * The native type of the handle is `HWND` on Windows, `NSView*` on macOS, and\n         * `Window` (`unsigned long`) on Linux.\n         */\n        getNativeWindowHandle(): Buffer;\n        /**\n         * Contains the window bounds of the normal state\n         *\n         * **Note:** whatever the current state of the window : maximized, minimized or in\n         * fullscreen, this function always returns the position and size of the window in\n         * normal state. In normal state, getBounds and getNormalBounds returns the same\n         * `Rectangle`.\n         */\n        getNormalBounds(): Rectangle;\n        /**\n         * between 0.0 (fully transparent) and 1.0 (fully opaque). On Linux, always returns\n         * 1.\n         */\n        getOpacity(): number;\n        /**\n         * The parent window or `null` if there is no parent.\n         */\n        getParentWindow(): BrowserWindow | null;\n        /**\n         * Contains the window's current position.\n         */\n        getPosition(): number[];\n        /**\n         * The pathname of the file the window represents.\n         *\n         * @platform darwin\n         */\n        getRepresentedFilename(): string;\n        /**\n         * Contains the window's width and height.\n         */\n        getSize(): number[];\n        /**\n         * The title of the native window.\n         *\n         * **Note:** The title of the web page can be different from the title of the\n         * native window.\n         */\n        getTitle(): string;\n        /**\n         * The custom position for the traffic light buttons in frameless window, `{ x: 0,\n         * y: 0 }` will be returned when there is no custom position.\n         *\n         * > **Note** This function is deprecated. Use getWindowButtonPosition instead.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        getTrafficLightPosition(): Point;\n        /**\n         * The custom position for the traffic light buttons in frameless window, `null`\n         * will be returned when there is no custom position.\n         *\n         * @platform darwin\n         */\n        getWindowButtonPosition(): Point | null;\n        /**\n         * Whether the window has a shadow.\n         */\n        hasShadow(): boolean;\n        /**\n         * Hides the window.\n         */\n        hide(): void;\n        /**\n         * Hooks a windows message. The `callback` is called when the message is received\n         * in the WndProc.\n         *\n         * @platform win32\n         */\n        hookWindowMessage(message: number, callback: (wParam: Buffer, lParam: Buffer) => void): void;\n        /**\n         * Invalidates the window shadow so that it is recomputed based on the current\n         * window shape.\n         *\n         * `BrowserWindows` that are transparent can sometimes leave behind visual\n         * artifacts on macOS. This method can be used to clear these artifacts when, for\n         * example, performing an animation.\n         *\n         * @platform darwin\n         */\n        invalidateShadow(): void;\n        /**\n         * Whether the window is always on top of other windows.\n         */\n        isAlwaysOnTop(): boolean;\n        /**\n         * Whether the window can be manually closed by user.\n         *\n         * On Linux always returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        isClosable(): boolean;\n        /**\n         * Whether the window is destroyed.\n         */\n        isDestroyed(): boolean;\n        /**\n         * Whether the window's document has been edited.\n         *\n         * @platform darwin\n         */\n        isDocumentEdited(): boolean;\n        /**\n         * whether the window is enabled.\n         */\n        isEnabled(): boolean;\n        /**\n         * Whether the window can be focused.\n         *\n         * @platform darwin,win32\n         */\n        isFocusable(): boolean;\n        /**\n         * Whether the window is focused.\n         */\n        isFocused(): boolean;\n        /**\n         * Whether the window is in fullscreen mode.\n         */\n        isFullScreen(): boolean;\n        /**\n         * Whether the maximize/zoom window button toggles fullscreen mode or maximizes the\n         * window.\n         */\n        isFullScreenable(): boolean;\n        /**\n         * Whether the window will be hidden when the user toggles into mission control.\n         *\n         * @platform darwin\n         */\n        isHiddenInMissionControl(): boolean;\n        /**\n         * Whether the window is in kiosk mode.\n         */\n        isKiosk(): boolean;\n        /**\n         * Whether the window can be manually maximized by user.\n         *\n         * On Linux always returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        isMaximizable(): boolean;\n        /**\n         * Whether the window is maximized.\n         */\n        isMaximized(): boolean;\n        /**\n         * Whether menu bar automatically hides itself.\n         *\n         * @platform win32,linux\n         */\n        isMenuBarAutoHide(): boolean;\n        /**\n         * Whether the menu bar is visible.\n         *\n         * @platform win32,linux\n         */\n        isMenuBarVisible(): boolean;\n        /**\n         * Whether the window can be manually minimized by the user.\n         *\n         * On Linux always returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        isMinimizable(): boolean;\n        /**\n         * Whether the window is minimized.\n         */\n        isMinimized(): boolean;\n        /**\n         * Whether current window is a modal window.\n         */\n        isModal(): boolean;\n        /**\n         * Whether the window can be moved by user.\n         *\n         * On Linux always returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        isMovable(): boolean;\n        /**\n         * Whether the window is in normal state (not maximized, not minimized, not in\n         * fullscreen mode).\n         */\n        isNormal(): boolean;\n        /**\n         * Whether the window can be manually resized by the user.\n         */\n        isResizable(): boolean;\n        /**\n         * Whether the window is in simple (pre-Lion) fullscreen mode.\n         *\n         * @platform darwin\n         */\n        isSimpleFullScreen(): boolean;\n        /**\n         * Whether the window is in Windows 10 tablet mode.\n         *\n         * Since Windows 10 users can use their PC as tablet, under this mode apps can\n         * choose to optimize their UI for tablets, such as enlarging the titlebar and\n         * hiding titlebar buttons.\n         *\n         * This API returns whether the window is in tablet mode, and the `resize` event\n         * can be be used to listen to changes to tablet mode.\n         *\n         * @platform win32\n         */\n        isTabletMode(): boolean;\n        /**\n         * Whether the window is visible to the user in the foreground of the app.\n         */\n        isVisible(): boolean;\n        /**\n         * Whether the window is visible on all workspaces.\n         *\n         * **Note:** This API always returns false on Windows.\n         *\n         * @platform darwin,linux\n         */\n        isVisibleOnAllWorkspaces(): boolean;\n        /**\n         * `true` or `false` depending on whether the message is hooked.\n         *\n         * @platform win32\n         */\n        isWindowMessageHooked(message: number): boolean;\n        /**\n         * the promise will resolve when the page has finished loading (see\n         * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`).\n         *\n         * Same as `webContents.loadFile`, `filePath` should be a path to an HTML file\n         * relative to the root of your application.  See the `webContents` docs for more\n         * information.\n         */\n        loadFile(filePath: string, options?: LoadFileOptions): Promise<void>;\n        /**\n         * the promise will resolve when the page has finished loading (see\n         * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`).\n         *\n         * Same as `webContents.loadURL(url[, options])`.\n         *\n         * The `url` can be a remote address (e.g. `http://`) or a path to a local HTML\n         * file using the `file://` protocol.\n         *\n         * To ensure that file URLs are properly formatted, it is recommended to use Node's\n         * `url.format` method:\n         *\n         * You can load a URL using a `POST` request with URL-encoded data by doing the\n         * following:\n         */\n        loadURL(url: string, options?: LoadURLOptions): Promise<void>;\n        /**\n         * Maximizes the window. This will also show (but not focus) the window if it isn't\n         * being displayed already.\n         */\n        maximize(): void;\n        /**\n         * Merges all windows into one window with multiple tabs when native tabs are\n         * enabled and there is more than one open window.\n         *\n         * @platform darwin\n         */\n        mergeAllWindows(): void;\n        /**\n         * Minimizes the window. On some platforms the minimized window will be shown in\n         * the Dock.\n         */\n        minimize(): void;\n        /**\n         * Moves window above the source window in the sense of z-order. If the\n         * `mediaSourceId` is not of type window or if the window does not exist then this\n         * method throws an error.\n         */\n        moveAbove(mediaSourceId: string): void;\n        /**\n         * Moves the current tab into a new window if native tabs are enabled and there is\n         * more than one tab in the current window.\n         *\n         * @platform darwin\n         */\n        moveTabToNewWindow(): void;\n        /**\n         * Moves window to top(z-order) regardless of focus\n         */\n        moveTop(): void;\n        /**\n         * Uses Quick Look to preview a file at a given path.\n         *\n         * @platform darwin\n         */\n        previewFile(path: string, displayName?: string): void;\n        /**\n         * Same as `webContents.reload`.\n         */\n        reload(): void;\n        /**\n         * @experimental\n         */\n        removeBrowserView(browserView: BrowserView): void;\n        /**\n         * Remove the window's menu bar.\n         *\n         * @platform linux,win32\n         */\n        removeMenu(): void;\n        /**\n         * Restores the window from minimized state to its previous state.\n         */\n        restore(): void;\n        /**\n         * Selects the next tab when native tabs are enabled and there are other tabs in\n         * the window.\n         *\n         * @platform darwin\n         */\n        selectNextTab(): void;\n        /**\n         * Selects the previous tab when native tabs are enabled and there are other tabs\n         * in the window.\n         *\n         * @platform darwin\n         */\n        selectPreviousTab(): void;\n        /**\n         * Sets whether the window should show always on top of other windows. After\n         * setting this, the window is still a normal window, not a toolbox window which\n         * can not be focused on.\n         */\n        setAlwaysOnTop(flag: boolean, level?: \"normal\" | \"floating\" | \"torn-off-menu\" | \"modal-panel\" | \"main-menu\" | \"status\" | \"pop-up-menu\" | \"screen-saver\", relativeLevel?: number): void;\n        /**\n         * Sets the properties for the window's taskbar button.\n         *\n         * **Note:** `relaunchCommand` and `relaunchDisplayName` must always be set\n         * together. If one of those properties is not set, then neither will be used.\n         *\n         * @platform win32\n         */\n        setAppDetails(options: AppDetailsOptions): void;\n        /**\n         * This will make a window maintain an aspect ratio. The extra size allows a\n         * developer to have space, specified in pixels, not included within the aspect\n         * ratio calculations. This API already takes into account the difference between a\n         * window's size and its content size.\n         *\n         * Consider a normal window with an HD video player and associated controls.\n         * Perhaps there are 15 pixels of controls on the left edge, 25 pixels of controls\n         * on the right edge and 50 pixels of controls below the player. In order to\n         * maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within\n         * the player itself we would call this function with arguments of 16/9 and {\n         * width: 40, height: 50 }. The second argument doesn't care where the extra width\n         * and height are within the content view--only that they exist. Sum any extra\n         * width and height areas you have within the overall content view.\n         *\n         * The aspect ratio is not respected when window is resized programmatically with\n         * APIs like `win.setSize`.\n         *\n         * To reset an aspect ratio, pass 0 as the `aspectRatio` value:\n         * `win.setAspectRatio(0)`.\n         */\n        setAspectRatio(aspectRatio: number, extraSize?: Size): void;\n        /**\n         * Controls whether to hide cursor when typing.\n         *\n         * @platform darwin\n         */\n        setAutoHideCursor(autoHide: boolean): void;\n        /**\n         * Sets whether the window menu bar should hide itself automatically. Once set the\n         * menu bar will only show when users press the single `Alt` key.\n         *\n         * If the menu bar is already visible, calling `setAutoHideMenuBar(true)` won't\n         * hide it immediately.\n         *\n         * @platform win32,linux\n         */\n        setAutoHideMenuBar(hide: boolean): void;\n        /**\n         * Examples of valid `backgroundColor` values:\n         *\n         * * Hex\n         *   * #fff (shorthand RGB)\n         *   * #ffff (shorthand ARGB)\n         *   * #ffffff (RGB)\n         *   * #ffffffff (ARGB)\n         * * RGB\n         *   * rgb(([\\d]+),\\s*([\\d]+),\\s*([\\d]+))\n         *     * e.g. rgb(255, 255, 255)\n         * * RGBA\n         *   * rgba(([\\d]+),\\s*([\\d]+),\\s*([\\d]+),\\s*([\\d.]+))\n         *     * e.g. rgba(255, 255, 255, 1.0)\n         * * HSL\n         *   * hsl((-?[\\d.]+),\\s*([\\d.]+)%,\\s*([\\d.]+)%)\n         *     * e.g. hsl(200, 20%, 50%)\n         * * HSLA\n         *   * hsla((-?[\\d.]+),\\s*([\\d.]+)%,\\s*([\\d.]+)%,\\s*([\\d.]+))\n         *     * e.g. hsla(200, 20%, 50%, 0.5)\n         * * Color name\n         *   * Options are listed in SkParseColor.cpp\n         *   * Similar to CSS Color Module Level 3 keywords, but case-sensitive.\n         *     * e.g. `blueviolet` or `red`\n         *\n         * Sets the background color of the window. See Setting `backgroundColor`.\n         */\n        setBackgroundColor(backgroundColor: string): void;\n        /**\n         * This method sets the browser window's system-drawn background material,\n         * including behind the non-client area.\n         *\n         * See the Windows documentation for more details.\n         *\n         * **Note:** This method is only supported on Windows 11 22H2 and up.\n         *\n         * @platform win32\n         */\n        setBackgroundMaterial(material: \"auto\" | \"none\" | \"mica\" | \"acrylic\" | \"tabbed\"): void;\n        /**\n         * Resizes and moves the window to the supplied bounds. Any properties that are not\n         * supplied will default to their current values.\n         */\n        setBounds(bounds: Partial<Rectangle>, animate?: boolean): void;\n        /**\n         * @experimental\n         */\n        setBrowserView(browserView: BrowserView | null): void;\n        /**\n         * Sets whether the window can be manually closed by user. On Linux does nothing.\n         *\n         * @platform darwin,win32\n         */\n        setClosable(closable: boolean): void;\n        /**\n         * Resizes and moves the window's client area (e.g. the web page) to the supplied\n         * bounds.\n         */\n        setContentBounds(bounds: Rectangle, animate?: boolean): void;\n        /**\n         * Prevents the window contents from being captured by other apps.\n         *\n         * On macOS it sets the NSWindow's sharingType to NSWindowSharingNone. On Windows\n         * it calls SetWindowDisplayAffinity with `WDA_EXCLUDEFROMCAPTURE`. For Windows 10\n         * version 2004 and up the window will be removed from capture entirely, older\n         * Windows versions behave as if `WDA_MONITOR` is applied capturing a black window.\n         *\n         * @platform darwin,win32\n         */\n        setContentProtection(enable: boolean): void;\n        /**\n         * Resizes the window's client area (e.g. the web page) to `width` and `height`.\n         */\n        setContentSize(width: number, height: number, animate?: boolean): void;\n        /**\n         * Specifies whether the window’s document has been edited, and the icon in title\n         * bar will become gray when set to `true`.\n         *\n         * @platform darwin\n         */\n        setDocumentEdited(edited: boolean): void;\n        /**\n         * Disable or enable the window.\n         */\n        setEnabled(enable: boolean): void;\n        /**\n         * Changes whether the window can be focused.\n         *\n         * On macOS it does not remove the focus from the window.\n         *\n         * @platform darwin,win32\n         */\n        setFocusable(focusable: boolean): void;\n        /**\n         * Sets whether the window should be in fullscreen mode.\n         *\n         * **Note:** On macOS, fullscreen transitions take place asynchronously. If further\n         * actions depend on the fullscreen state, use the 'enter-full-screen' or\n         * 'leave-full-screen' events.\n         */\n        setFullScreen(flag: boolean): void;\n        /**\n         * Sets whether the maximize/zoom window button toggles fullscreen mode or\n         * maximizes the window.\n         */\n        setFullScreenable(fullscreenable: boolean): void;\n        /**\n         * Sets whether the window should have a shadow.\n         */\n        setHasShadow(hasShadow: boolean): void;\n        /**\n         * Sets whether the window will be hidden when the user toggles into mission\n         * control.\n         *\n         * @platform darwin\n         */\n        setHiddenInMissionControl(hidden: boolean): void;\n        /**\n         * Changes window icon.\n         *\n         * @platform win32,linux\n         */\n        setIcon(icon: NativeImage | string): void;\n        /**\n         * Makes the window ignore all mouse events.\n         *\n         * All mouse events happened in this window will be passed to the window below this\n         * window, but if this window has focus, it will still receive keyboard events.\n         */\n        setIgnoreMouseEvents(ignore: boolean, options?: IgnoreMouseEventsOptions): void;\n        /**\n         * Enters or leaves kiosk mode.\n         */\n        setKiosk(flag: boolean): void;\n        /**\n         * Sets whether the window can be manually maximized by user. On Linux does\n         * nothing.\n         *\n         * @platform darwin,win32\n         */\n        setMaximizable(maximizable: boolean): void;\n        /**\n         * Sets the maximum size of window to `width` and `height`.\n         */\n        setMaximumSize(width: number, height: number): void;\n        /**\n         * Sets the `menu` as the window's menu bar.\n         *\n         * @platform linux,win32\n         */\n        setMenu(menu: Menu | null): void;\n        /**\n         * Sets whether the menu bar should be visible. If the menu bar is auto-hide, users\n         * can still bring up the menu bar by pressing the single `Alt` key.\n         *\n         * @platform win32,linux\n         */\n        setMenuBarVisibility(visible: boolean): void;\n        /**\n         * Sets whether the window can be manually minimized by user. On Linux does\n         * nothing.\n         *\n         * @platform darwin,win32\n         */\n        setMinimizable(minimizable: boolean): void;\n        /**\n         * Sets the minimum size of window to `width` and `height`.\n         */\n        setMinimumSize(width: number, height: number): void;\n        /**\n         * Sets whether the window can be moved by user. On Linux does nothing.\n         *\n         * @platform darwin,win32\n         */\n        setMovable(movable: boolean): void;\n        /**\n         * Sets the opacity of the window. On Linux, does nothing. Out of bound number\n         * values are clamped to the [0, 1] range.\n         *\n         * @platform win32,darwin\n         */\n        setOpacity(opacity: number): void;\n        /**\n         * Sets a 16 x 16 pixel overlay onto the current taskbar icon, usually used to\n         * convey some sort of application status or to passively notify the user.\n         *\n         * @platform win32\n         */\n        setOverlayIcon(overlay: NativeImage | null, description: string): void;\n        /**\n         * Sets `parent` as current window's parent window, passing `null` will turn\n         * current window into a top-level window.\n         */\n        setParentWindow(parent: BrowserWindow | null): void;\n        /**\n         * Moves window to `x` and `y`.\n         */\n        setPosition(x: number, y: number, animate?: boolean): void;\n        /**\n         * Sets progress value in progress bar. Valid range is [0, 1.0].\n         *\n         * Remove progress bar when progress < 0; Change to indeterminate mode when\n         * progress > 1.\n         *\n         * On Linux platform, only supports Unity desktop environment, you need to specify\n         * the `*.desktop` file name to `desktopName` field in `package.json`. By default,\n         * it will assume `{app.name}.desktop`.\n         *\n         * On Windows, a mode can be passed. Accepted values are `none`, `normal`,\n         * `indeterminate`, `error`, and `paused`. If you call `setProgressBar` without a\n         * mode set (but with a value within the valid range), `normal` will be assumed.\n         */\n        setProgressBar(progress: number, options?: ProgressBarOptions): void;\n        /**\n         * Sets the pathname of the file the window represents, and the icon of the file\n         * will show in window's title bar.\n         *\n         * @platform darwin\n         */\n        setRepresentedFilename(filename: string): void;\n        /**\n         * Sets whether the window can be manually resized by the user.\n         */\n        setResizable(resizable: boolean): void;\n        /**\n         * Setting a window shape determines the area within the window where the system\n         * permits drawing and user interaction. Outside of the given region, no pixels\n         * will be drawn and no mouse events will be registered. Mouse events outside of\n         * the region will not be received by that window, but will fall through to\n         * whatever is behind the window.\n         *\n         * @experimental\n         * @platform win32,linux\n         */\n        setShape(rects: Rectangle[]): void;\n        /**\n         * Changes the attachment point for sheets on macOS. By default, sheets are\n         * attached just below the window frame, but you may want to display them beneath a\n         * HTML-rendered toolbar. For example:\n         *\n         * @platform darwin\n         */\n        setSheetOffset(offsetY: number, offsetX?: number): void;\n        /**\n         * Enters or leaves simple fullscreen mode.\n         *\n         * Simple fullscreen mode emulates the native fullscreen behavior found in versions\n         * of macOS prior to Lion (10.7).\n         *\n         * @platform darwin\n         */\n        setSimpleFullScreen(flag: boolean): void;\n        /**\n         * Resizes the window to `width` and `height`. If `width` or `height` are below any\n         * set minimum size constraints the window will snap to its minimum size.\n         */\n        setSize(width: number, height: number, animate?: boolean): void;\n        /**\n         * Makes the window not show in the taskbar.\n         *\n         * @platform darwin,win32\n         */\n        setSkipTaskbar(skip: boolean): void;\n        /**\n         * Whether the buttons were added successfully\n         *\n         * Add a thumbnail toolbar with a specified set of buttons to the thumbnail image\n         * of a window in a taskbar button layout. Returns a `boolean` object indicates\n         * whether the thumbnail has been added successfully.\n         *\n         * The number of buttons in thumbnail toolbar should be no greater than 7 due to\n         * the limited room. Once you setup the thumbnail toolbar, the toolbar cannot be\n         * removed due to the platform's limitation. But you can call the API with an empty\n         * array to clean the buttons.\n         *\n         * The `buttons` is an array of `Button` objects:\n         *\n         * * `Button` Object\n         *   * `icon` NativeImage - The icon showing in thumbnail toolbar.\n         *   * `click` Function\n         *   * `tooltip` string (optional) - The text of the button's tooltip.\n         *   * `flags` string[] (optional) - Control specific states and behaviors of the\n         * button. By default, it is `['enabled']`.\n         *\n         * The `flags` is an array that can include following `string`s:\n         *\n         * * `enabled` - The button is active and available to the user.\n         * * `disabled` - The button is disabled. It is present, but has a visual state\n         * indicating it will not respond to user action.\n         * * `dismissonclick` - When the button is clicked, the thumbnail window closes\n         * immediately.\n         * * `nobackground` - Do not draw a button border, use only the image.\n         * * `hidden` - The button is not shown to the user.\n         * * `noninteractive` - The button is enabled but not interactive; no pressed\n         * button state is drawn. This value is intended for instances where the button is\n         * used in a notification.\n         *\n         * @platform win32\n         */\n        setThumbarButtons(buttons: ThumbarButton[]): boolean;\n        /**\n         * Sets the region of the window to show as the thumbnail image displayed when\n         * hovering over the window in the taskbar. You can reset the thumbnail to be the\n         * entire window by specifying an empty region: `{ x: 0, y: 0, width: 0, height: 0\n         * }`.\n         *\n         * @platform win32\n         */\n        setThumbnailClip(region: Rectangle): void;\n        /**\n         * Sets the toolTip that is displayed when hovering over the window thumbnail in\n         * the taskbar.\n         *\n         * @platform win32\n         */\n        setThumbnailToolTip(toolTip: string): void;\n        /**\n         * Changes the title of native window to `title`.\n         */\n        setTitle(title: string): void;\n        /**\n         * On a Window with Window Controls Overlay already enabled, this method updates\n         * the style of the title bar overlay.\n         *\n         * @platform win32\n         */\n        setTitleBarOverlay(options: TitleBarOverlayOptions): void;\n        /**\n         * Raises `browserView` above other `BrowserView`s attached to `win`. Throws an\n         * error if `browserView` is not attached to `win`.\n         *\n         * @experimental\n         */\n        setTopBrowserView(browserView: BrowserView): void;\n        /**\n         * Sets the touchBar layout for the current window. Specifying `null` or\n         * `undefined` clears the touch bar. This method only has an effect if the machine\n         * has a touch bar.\n         *\n         * **Note:** The TouchBar API is currently experimental and may change or be\n         * removed in future Electron releases.\n         *\n         * @platform darwin\n         */\n        setTouchBar(touchBar: TouchBar | null): void;\n        /**\n         * Set a custom position for the traffic light buttons in frameless window. Passing\n         * `{ x: 0, y: 0 }` will reset the position to default.\n         *\n         * > **Note** This function is deprecated. Use setWindowButtonPosition instead.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        setTrafficLightPosition(position: Point): void;\n        /**\n         * Adds a vibrancy effect to the browser window. Passing `null` or an empty string\n         * will remove the vibrancy effect on the window.\n         *\n         * Note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark`\n         * have been deprecated and will be removed in an upcoming version of macOS.\n         *\n         * @platform darwin\n         */\n        setVibrancy(type: (\"appearance-based\" | \"light\" | \"dark\" | \"titlebar\" | \"selection\" | \"menu\" | \"popover\" | \"sidebar\" | \"medium-light\" | \"ultra-dark\" | \"header\" | \"sheet\" | \"window\" | \"hud\" | \"fullscreen-ui\" | \"tooltip\" | \"content\" | \"under-window\" | \"under-page\") | null): void;\n        /**\n         * Sets whether the window should be visible on all workspaces.\n         *\n         * **Note:** This API does nothing on Windows.\n         *\n         * @platform darwin,linux\n         */\n        setVisibleOnAllWorkspaces(visible: boolean, options?: VisibleOnAllWorkspacesOptions): void;\n        /**\n         * Set a custom position for the traffic light buttons in frameless window. Passing\n         * `null` will reset the position to default.\n         *\n         * @platform darwin\n         */\n        setWindowButtonPosition(position: Point | null): void;\n        /**\n         * Sets whether the window traffic light buttons should be visible.\n         *\n         * @platform darwin\n         */\n        setWindowButtonVisibility(visible: boolean): void;\n        /**\n         * Shows and gives focus to the window.\n         */\n        show(): void;\n        /**\n         * Same as `webContents.showDefinitionForSelection()`.\n         *\n         * @platform darwin\n         */\n        showDefinitionForSelection(): void;\n        /**\n         * Shows the window but doesn't focus on it.\n         */\n        showInactive(): void;\n        /**\n         * Toggles the visibility of the tab bar if native tabs are enabled and there is\n         * only one tab in the current window.\n         *\n         * @platform darwin\n         */\n        toggleTabBar(): void;\n        /**\n         * Unhooks all of the window messages.\n         *\n         * @platform win32\n         */\n        unhookAllWindowMessages(): void;\n        /**\n         * Unhook the window message.\n         *\n         * @platform win32\n         */\n        unhookWindowMessage(message: number): void;\n        /**\n         * Unmaximizes the window.\n         */\n        unmaximize(): void;\n        /**\n         * A `string` property that defines an alternative title provided only to\n         * accessibility tools such as screen readers. This string is not directly visible\n         * to users.\n         */\n        accessibleTitle: string;\n        /**\n         * A `boolean` property that determines whether the window menu bar should hide\n         * itself automatically. Once set, the menu bar will only show when users press the\n         * single `Alt` key.\n         *\n         * If the menu bar is already visible, setting this property to `true` won't hide\n         * it immediately.\n         */\n        autoHideMenuBar: boolean;\n        /**\n         * A `boolean` property that determines whether the window can be manually closed\n         * by user.\n         *\n         * On Linux the setter is a no-op, although the getter returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        closable: boolean;\n        /**\n         * A `boolean` property that specifies whether the window’s document has been\n         * edited.\n         *\n         * The icon in title bar will become gray when set to `true`.\n         *\n         * @platform darwin\n         */\n        documentEdited: boolean;\n        /**\n         * A `boolean` property that determines whether the window is excluded from the\n         * application’s Windows menu. `false` by default.\n         *\n         * @platform darwin\n         */\n        excludedFromShownWindowsMenu: boolean;\n        /**\n         * A `boolean` property that determines whether the window is focusable.\n         *\n         * @platform win32,darwin\n         */\n        focusable: boolean;\n        /**\n         * A `boolean` property that determines whether the window is in fullscreen mode.\n         */\n        fullScreen: boolean;\n        /**\n         * A `boolean` property that determines whether the maximize/zoom window button\n         * toggles fullscreen mode or maximizes the window.\n         */\n        fullScreenable: boolean;\n        /**\n         * A `Integer` property representing the unique ID of the window. Each ID is unique\n         * among all `BrowserWindow` instances of the entire Electron application.\n         *\n         */\n        readonly id: number;\n        /**\n         * A `boolean` property that determines whether the window is in kiosk mode.\n         */\n        kiosk: boolean;\n        /**\n         * A `boolean` property that determines whether the window can be manually\n         * maximized by user.\n         *\n         * On Linux the setter is a no-op, although the getter returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        maximizable: boolean;\n        /**\n         * A `boolean` property that determines whether the menu bar should be visible.\n         *\n         * **Note:** If the menu bar is auto-hide, users can still bring up the menu bar by\n         * pressing the single `Alt` key.\n         *\n         * @platform win32,linux\n         */\n        menuBarVisible: boolean;\n        /**\n         * A `boolean` property that determines whether the window can be manually\n         * minimized by user.\n         *\n         * On Linux the setter is a no-op, although the getter returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        minimizable: boolean;\n        /**\n         * A `boolean` property that determines Whether the window can be moved by user.\n         *\n         * On Linux the setter is a no-op, although the getter returns `true`.\n         *\n         * @platform darwin,win32\n         */\n        movable: boolean;\n        /**\n         * A `string` property that determines the pathname of the file the window\n         * represents, and the icon of the file will show in window's title bar.\n         *\n         * @platform darwin\n         */\n        representedFilename: string;\n        /**\n         * A `boolean` property that determines whether the window can be manually resized\n         * by user.\n         */\n        resizable: boolean;\n        /**\n         * A `boolean` property that determines whether the window has a shadow.\n         */\n        shadow: boolean;\n        /**\n         * A `boolean` property that determines whether the window is in simple (pre-Lion)\n         * fullscreen mode.\n         */\n        simpleFullScreen: boolean;\n        /**\n         * A `string` property that determines the title of the native window.\n         *\n         * **Note:** The title of the web page can be different from the title of the\n         * native window.\n         */\n        title: string;\n        /**\n         * A `boolean` property that determines whether the window is visible on all\n         * workspaces.\n         *\n         * **Note:** Always returns false on Windows.\n         *\n         * @platform darwin,linux\n         */\n        visibleOnAllWorkspaces: boolean;\n        /**\n         * A `WebContents` object this window owns. All web page related events and\n         * operations will be done via it.\n         *\n         * See the `webContents` documentation for its methods and events.\n         *\n         */\n        readonly webContents: WebContents;\n    }\n\n    interface Certificate {\n        // Docs: https://electronjs.org/docs/api/structures/certificate\n\n        /**\n         * PEM encoded data\n         */\n        data: string;\n        /**\n         * Fingerprint of the certificate\n         */\n        fingerprint: string;\n        /**\n         * Issuer principal\n         */\n        issuer: CertificatePrincipal;\n        /**\n         * Issuer certificate (if not self-signed)\n         */\n        issuerCert: Certificate;\n        /**\n         * Issuer's Common Name\n         */\n        issuerName: string;\n        /**\n         * Hex value represented string\n         */\n        serialNumber: string;\n        /**\n         * Subject principal\n         */\n        subject: CertificatePrincipal;\n        /**\n         * Subject's Common Name\n         */\n        subjectName: string;\n        /**\n         * End date of the certificate being valid in seconds\n         */\n        validExpiry: number;\n        /**\n         * Start date of the certificate being valid in seconds\n         */\n        validStart: number;\n    }\n\n    interface CertificatePrincipal {\n        // Docs: https://electronjs.org/docs/api/structures/certificate-principal\n\n        /**\n         * Common Name.\n         */\n        commonName: string;\n        /**\n         * Country or region.\n         */\n        country: string;\n        /**\n         * Locality.\n         */\n        locality: string;\n        /**\n         * Organization names.\n         */\n        organizations: string[];\n        /**\n         * Organization Unit names.\n         */\n        organizationUnits: string[];\n        /**\n         * State or province.\n         */\n        state: string;\n    }\n\n    class ClientRequest extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/client-request\n\n        /**\n         * Emitted when the `request` is aborted. The `abort` event will not be fired if\n         * the `request` is already closed.\n         */\n        on(event: \"abort\", listener: Function): this;\n        once(event: \"abort\", listener: Function): this;\n        addListener(event: \"abort\", listener: Function): this;\n        removeListener(event: \"abort\", listener: Function): this;\n        /**\n         * Emitted as the last event in the HTTP request-response transaction. The `close`\n         * event indicates that no more events will be emitted on either the `request` or\n         * `response` objects.\n         */\n        on(event: \"close\", listener: Function): this;\n        once(event: \"close\", listener: Function): this;\n        addListener(event: \"close\", listener: Function): this;\n        removeListener(event: \"close\", listener: Function): this;\n        /**\n         * Emitted when the `net` module fails to issue a network request. Typically when\n         * the `request` object emits an `error` event, a `close` event will subsequently\n         * follow and no response object will be provided.\n         */\n        on(\n            event: \"error\",\n            listener: (\n                /**\n                 * an error object providing some information about the failure.\n                 */\n                error: Error,\n            ) => void,\n        ): this;\n        once(\n            event: \"error\",\n            listener: (\n                /**\n                 * an error object providing some information about the failure.\n                 */\n                error: Error,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"error\",\n            listener: (\n                /**\n                 * an error object providing some information about the failure.\n                 */\n                error: Error,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"error\",\n            listener: (\n                /**\n                 * an error object providing some information about the failure.\n                 */\n                error: Error,\n            ) => void,\n        ): this;\n        /**\n         * Emitted just after the last chunk of the `request`'s data has been written into\n         * the `request` object.\n         */\n        on(event: \"finish\", listener: Function): this;\n        once(event: \"finish\", listener: Function): this;\n        addListener(event: \"finish\", listener: Function): this;\n        removeListener(event: \"finish\", listener: Function): this;\n        /**\n         * Emitted when an authenticating proxy is asking for user credentials.\n         *\n         * The `callback` function is expected to be called back with user credentials:\n         *\n         * * `username` string\n         * * `password` string\n         *\n         * Providing empty credentials will cancel the request and report an authentication\n         * error on the response object:\n         */\n        on(event: \"login\", listener: (authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        once(event: \"login\", listener: (authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        addListener(event: \"login\", listener: (authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        removeListener(event: \"login\", listener: (authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        /**\n         * Emitted when the server returns a redirect response (e.g. 301 Moved\n         * Permanently). Calling `request.followRedirect` will continue with the\n         * redirection.  If this event is handled, `request.followRedirect` must be called\n         * **synchronously**, otherwise the request will be cancelled.\n         */\n        on(event: \"redirect\", listener: (statusCode: number, method: string, redirectUrl: string, responseHeaders: Record<string, string[]>) => void): this;\n        once(event: \"redirect\", listener: (statusCode: number, method: string, redirectUrl: string, responseHeaders: Record<string, string[]>) => void): this;\n        addListener(event: \"redirect\", listener: (statusCode: number, method: string, redirectUrl: string, responseHeaders: Record<string, string[]>) => void): this;\n        removeListener(event: \"redirect\", listener: (statusCode: number, method: string, redirectUrl: string, responseHeaders: Record<string, string[]>) => void): this;\n        on(\n            event: \"response\",\n            listener: (\n                /**\n                 * An object representing the HTTP response message.\n                 */\n                response: IncomingMessage,\n            ) => void,\n        ): this;\n        once(\n            event: \"response\",\n            listener: (\n                /**\n                 * An object representing the HTTP response message.\n                 */\n                response: IncomingMessage,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"response\",\n            listener: (\n                /**\n                 * An object representing the HTTP response message.\n                 */\n                response: IncomingMessage,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"response\",\n            listener: (\n                /**\n                 * An object representing the HTTP response message.\n                 */\n                response: IncomingMessage,\n            ) => void,\n        ): this;\n        /**\n         * ClientRequest\n         */\n        constructor(options: ClientRequestConstructorOptions | string);\n        /**\n         * Cancels an ongoing HTTP transaction. If the request has already emitted the\n         * `close` event, the abort operation will have no effect. Otherwise an ongoing\n         * event will emit `abort` and `close` events. Additionally, if there is an ongoing\n         * response object,it will emit the `aborted` event.\n         */\n        abort(): void;\n        /**\n         * Sends the last chunk of the request data. Subsequent write or end operations\n         * will not be allowed. The `finish` event is emitted just after the end operation.\n         */\n        end(chunk?: string | Buffer, encoding?: string, callback?: () => void): this;\n        /**\n         * Continues any pending redirection. Can only be called during a `'redirect'`\n         * event.\n         */\n        followRedirect(): void;\n        /**\n         * The value of a previously set extra header name.\n         */\n        getHeader(name: string): string;\n        /**\n         * * `active` boolean - Whether the request is currently active. If this is false\n         * no other properties will be set\n         * * `started` boolean - Whether the upload has started. If this is false both\n         * `current` and `total` will be set to 0.\n         * * `current` Integer - The number of bytes that have been uploaded so far\n         * * `total` Integer - The number of bytes that will be uploaded this request\n         *\n         * You can use this method in conjunction with `POST` requests to get the progress\n         * of a file upload or other data transfer.\n         */\n        getUploadProgress(): UploadProgress;\n        /**\n         * Removes a previously set extra header name. This method can be called only\n         * before first write. Trying to call it after the first write will throw an error.\n         */\n        removeHeader(name: string): void;\n        /**\n         * Adds an extra HTTP header. The header name will be issued as-is without\n         * lowercasing. It can be called only before first write. Calling this method after\n         * the first write will throw an error. If the passed value is not a `string`, its\n         * `toString()` method will be called to obtain the final value.\n         *\n         * Certain headers are restricted from being set by apps. These headers are listed\n         * below. More information on restricted headers can be found in Chromium's header\n         * utils.\n         *\n         * * `Content-Length`\n         * * `Host`\n         * * `Trailer` or `Te`\n         * * `Upgrade`\n         * * `Cookie2`\n         * * `Keep-Alive`\n         * * `Transfer-Encoding`\n         *\n         * Additionally, setting the `Connection` header to the value `upgrade` is also\n         * disallowed.\n         */\n        setHeader(name: string, value: string): void;\n        /**\n         * `callback` is essentially a dummy function introduced in the purpose of keeping\n         * similarity with the Node.js API. It is called asynchronously in the next tick\n         * after `chunk` content have been delivered to the Chromium networking layer.\n         * Contrary to the Node.js implementation, it is not guaranteed that `chunk`\n         * content have been flushed on the wire before `callback` is called.\n         *\n         * Adds a chunk of data to the request body. The first write operation may cause\n         * the request headers to be issued on the wire. After the first write operation,\n         * it is not allowed to add or remove a custom header.\n         */\n        write(chunk: string | Buffer, encoding?: string, callback?: () => void): void;\n        /**\n         * A `boolean` specifying whether the request will use HTTP chunked transfer\n         * encoding or not. Defaults to false. The property is readable and writable,\n         * however it can be set only before the first write operation as the HTTP headers\n         * are not yet put on the wire. Trying to set the `chunkedEncoding` property after\n         * the first write will throw an error.\n         *\n         * Using chunked encoding is strongly recommended if you need to send a large\n         * request body as data will be streamed in small chunks instead of being\n         * internally buffered inside Electron process memory.\n         */\n        chunkedEncoding: boolean;\n    }\n\n    interface Clipboard {\n        // Docs: https://electronjs.org/docs/api/clipboard\n\n        /**\n         * An array of supported formats for the clipboard `type`.\n         */\n        availableFormats(type?: \"selection\" | \"clipboard\"): string[];\n        /**\n         * Clears the clipboard content.\n         */\n        clear(type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Whether the clipboard supports the specified `format`.\n         *\n         * @experimental\n         */\n        has(format: string, type?: \"selection\" | \"clipboard\"): boolean;\n        /**\n         * Reads `format` type from the clipboard.\n         *\n         * `format` should contain valid ASCII characters and have `/` separator. `a/c`,\n         * `a/bc` are valid formats while `/abc`, `abc/`, `a/`, `/a`, `a` are not valid.\n         *\n         * @experimental\n         */\n        read(format: string): string;\n        /**\n         * * `title` string\n         * * `url` string\n         *\n         * Returns an Object containing `title` and `url` keys representing the bookmark in\n         * the clipboard. The `title` and `url` values will be empty strings when the\n         * bookmark is unavailable.  The `title` value will always be empty on Windows.\n         *\n         * @platform darwin,win32\n         */\n        readBookmark(): ReadBookmark;\n        /**\n         * Reads `format` type from the clipboard.\n         *\n         * @experimental\n         */\n        readBuffer(format: string): Buffer;\n        /**\n         * The text on the find pasteboard, which is the pasteboard that holds information\n         * about the current state of the active application’s find panel.\n         *\n         * This method uses synchronous IPC when called from the renderer process. The\n         * cached value is reread from the find pasteboard whenever the application is\n         * activated.\n         *\n         * @platform darwin\n         */\n        readFindText(): string;\n        /**\n         * The content in the clipboard as markup.\n         */\n        readHTML(type?: \"selection\" | \"clipboard\"): string;\n        /**\n         * The image content in the clipboard.\n         */\n        readImage(type?: \"selection\" | \"clipboard\"): NativeImage;\n        /**\n         * The content in the clipboard as RTF.\n         */\n        readRTF(type?: \"selection\" | \"clipboard\"): string;\n        /**\n         * The content in the clipboard as plain text.\n         */\n        readText(type?: \"selection\" | \"clipboard\"): string;\n        /**\n         * Writes `data` to the clipboard.\n         */\n        write(data: Data, type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Writes the `title` (macOS only) and `url` into the clipboard as a bookmark.\n         *\n         * **Note:** Most apps on Windows don't support pasting bookmarks into them so you\n         * can use `clipboard.write` to write both a bookmark and fallback text to the\n         * clipboard.\n         *\n         * @platform darwin,win32\n         */\n        writeBookmark(title: string, url: string, type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Writes the `buffer` into the clipboard as `format`.\n         *\n         * @experimental\n         */\n        writeBuffer(format: string, buffer: Buffer, type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Writes the `text` into the find pasteboard (the pasteboard that holds\n         * information about the current state of the active application’s find panel) as\n         * plain text. This method uses synchronous IPC when called from the renderer\n         * process.\n         *\n         * @platform darwin\n         */\n        writeFindText(text: string): void;\n        /**\n         * Writes `markup` to the clipboard.\n         */\n        writeHTML(markup: string, type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Writes `image` to the clipboard.\n         */\n        writeImage(image: NativeImage, type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Writes the `text` into the clipboard in RTF.\n         */\n        writeRTF(text: string, type?: \"selection\" | \"clipboard\"): void;\n        /**\n         * Writes the `text` into the clipboard as plain text.\n         */\n        writeText(text: string, type?: \"selection\" | \"clipboard\"): void;\n    }\n\n    class CommandLine {\n        // Docs: https://electronjs.org/docs/api/command-line\n\n        /**\n         * Append an argument to Chromium's command line. The argument will be quoted\n         * correctly. Switches will precede arguments regardless of appending order.\n         *\n         * If you're appending an argument like `--switch=value`, consider using\n         * `appendSwitch('switch', 'value')` instead.\n         *\n         * **Note:** This will not affect `process.argv`. The intended usage of this\n         * function is to control Chromium's behavior.\n         */\n        appendArgument(value: string): void;\n        /**\n         * Append a switch (with optional `value`) to Chromium's command line.\n         *\n         * **Note:** This will not affect `process.argv`. The intended usage of this\n         * function is to control Chromium's behavior.\n         */\n        appendSwitch(the_switch: string, value?: string): void;\n        /**\n         * The command-line switch value.\n         *\n         * **Note:** When the switch is not present or has no value, it returns empty\n         * string.\n         */\n        getSwitchValue(the_switch: string): string;\n        /**\n         * Whether the command-line switch is present.\n         */\n        hasSwitch(the_switch: string): boolean;\n        /**\n         * Removes the specified switch from Chromium's command line.\n         *\n         * **Note:** This will not affect `process.argv`. The intended usage of this\n         * function is to control Chromium's behavior.\n         */\n        removeSwitch(the_switch: string): void;\n    }\n\n    interface ContentTracing {\n        // Docs: https://electronjs.org/docs/api/content-tracing\n\n        /**\n         * resolves with an array of category groups once all child processes have\n         * acknowledged the `getCategories` request\n         *\n         * Get a set of category groups. The category groups can change as new code paths\n         * are reached. See also the list of built-in tracing categories.\n         *\n         * > **NOTE:** Electron adds a non-default tracing category called `\"electron\"`.\n         * This category can be used to capture Electron-specific tracing events.\n         */\n        getCategories(): Promise<string[]>;\n        /**\n         * Resolves with an object containing the `value` and `percentage` of trace buffer\n         * maximum usage\n         *\n         * * `value` number\n         * * `percentage` number\n         *\n         * Get the maximum usage across processes of trace buffer as a percentage of the\n         * full state.\n         */\n        getTraceBufferUsage(): Promise<Electron.TraceBufferUsageReturnValue>;\n        /**\n         * resolved once all child processes have acknowledged the `startRecording`\n         * request.\n         *\n         * Start recording on all processes.\n         *\n         * Recording begins immediately locally and asynchronously on child processes as\n         * soon as they receive the EnableRecording request.\n         *\n         * If a recording is already running, the promise will be immediately resolved, as\n         * only one trace operation can be in progress at a time.\n         */\n        startRecording(options: TraceConfig | TraceCategoriesAndOptions): Promise<void>;\n        /**\n         * resolves with a path to a file that contains the traced data once all child\n         * processes have acknowledged the `stopRecording` request\n         *\n         * Stop recording on all processes.\n         *\n         * Child processes typically cache trace data and only rarely flush and send trace\n         * data back to the main process. This helps to minimize the runtime overhead of\n         * tracing since sending trace data over IPC can be an expensive operation. So, to\n         * end tracing, Chromium asynchronously asks all child processes to flush any\n         * pending trace data.\n         *\n         * Trace data will be written into `resultFilePath`. If `resultFilePath` is empty\n         * or not provided, trace data will be written to a temporary file, and the path\n         * will be returned in the promise.\n         */\n        stopRecording(resultFilePath?: string): Promise<string>;\n    }\n\n    interface ContextBridge {\n        // Docs: https://electronjs.org/docs/api/context-bridge\n\n        exposeInIsolatedWorld(worldId: number, apiKey: string, api: any): void;\n        exposeInMainWorld(apiKey: string, api: any): void;\n    }\n\n    interface Cookie {\n        // Docs: https://electronjs.org/docs/api/structures/cookie\n\n        /**\n         * The domain of the cookie; this will be normalized with a preceding dot so that\n         * it's also valid for subdomains.\n         */\n        domain?: string;\n        /**\n         * The expiration date of the cookie as the number of seconds since the UNIX epoch.\n         * Not provided for session cookies.\n         */\n        expirationDate?: number;\n        /**\n         * Whether the cookie is a host-only cookie; this will only be `true` if no domain\n         * was passed.\n         */\n        hostOnly?: boolean;\n        /**\n         * Whether the cookie is marked as HTTP only.\n         */\n        httpOnly?: boolean;\n        /**\n         * The name of the cookie.\n         */\n        name: string;\n        /**\n         * The path of the cookie.\n         */\n        path?: string;\n        /**\n         * The Same Site policy applied to this cookie.  Can be `unspecified`,\n         * `no_restriction`, `lax` or `strict`.\n         */\n        sameSite: \"unspecified\" | \"no_restriction\" | \"lax\" | \"strict\";\n        /**\n         * Whether the cookie is marked as secure.\n         */\n        secure?: boolean;\n        /**\n         * Whether the cookie is a session cookie or a persistent cookie with an expiration\n         * date.\n         */\n        session?: boolean;\n        /**\n         * The value of the cookie.\n         */\n        value: string;\n    }\n\n    class Cookies extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/cookies\n\n        /**\n         * Emitted when a cookie is changed because it was added, edited, removed, or\n         * expired.\n         */\n        on(\n            event: \"changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The cookie that was changed.\n                 */\n                cookie: Cookie,\n                /**\n                 * The cause of the change with one of the following values:\n                 */\n                cause: \"explicit\" | \"overwrite\" | \"expired\" | \"evicted\" | \"expired-overwrite\",\n                /**\n                 * `true` if the cookie was removed, `false` otherwise.\n                 */\n                removed: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The cookie that was changed.\n                 */\n                cookie: Cookie,\n                /**\n                 * The cause of the change with one of the following values:\n                 */\n                cause: \"explicit\" | \"overwrite\" | \"expired\" | \"evicted\" | \"expired-overwrite\",\n                /**\n                 * `true` if the cookie was removed, `false` otherwise.\n                 */\n                removed: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The cookie that was changed.\n                 */\n                cookie: Cookie,\n                /**\n                 * The cause of the change with one of the following values:\n                 */\n                cause: \"explicit\" | \"overwrite\" | \"expired\" | \"evicted\" | \"expired-overwrite\",\n                /**\n                 * `true` if the cookie was removed, `false` otherwise.\n                 */\n                removed: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The cookie that was changed.\n                 */\n                cookie: Cookie,\n                /**\n                 * The cause of the change with one of the following values:\n                 */\n                cause: \"explicit\" | \"overwrite\" | \"expired\" | \"evicted\" | \"expired-overwrite\",\n                /**\n                 * `true` if the cookie was removed, `false` otherwise.\n                 */\n                removed: boolean,\n            ) => void,\n        ): this;\n        /**\n         * A promise which resolves when the cookie store has been flushed\n         *\n         * Writes any unwritten cookies data to disk.\n         */\n        flushStore(): Promise<void>;\n        /**\n         * A promise which resolves an array of cookie objects.\n         *\n         * Sends a request to get all cookies matching `filter`, and resolves a promise\n         * with the response.\n         */\n        get(filter: CookiesGetFilter): Promise<Electron.Cookie[]>;\n        /**\n         * A promise which resolves when the cookie has been removed\n         *\n         * Removes the cookies matching `url` and `name`\n         */\n        remove(url: string, name: string): Promise<void>;\n        /**\n         * A promise which resolves when the cookie has been set\n         *\n         * Sets a cookie with `details`.\n         */\n        set(details: CookiesSetDetails): Promise<void>;\n    }\n\n    interface CPUUsage {\n        // Docs: https://electronjs.org/docs/api/structures/cpu-usage\n\n        /**\n         * The number of average idle CPU wakeups per second since the last call to\n         * getCPUUsage. First call returns 0. Will always return 0 on Windows.\n         */\n        idleWakeupsPerSecond: number;\n        /**\n         * Percentage of CPU used since the last call to getCPUUsage. First call returns 0.\n         */\n        percentCPUUsage: number;\n    }\n\n    interface CrashReport {\n        // Docs: https://electronjs.org/docs/api/structures/crash-report\n\n        date: Date;\n        id: string;\n    }\n\n    interface CrashReporter {\n        // Docs: https://electronjs.org/docs/api/crash-reporter\n\n        /**\n         * Set an extra parameter to be sent with the crash report. The values specified\n         * here will be sent in addition to any values set via the `extra` option when\n         * `start` was called.\n         *\n         * Parameters added in this fashion (or via the `extra` parameter to\n         * `crashReporter.start`) are specific to the calling process. Adding extra\n         * parameters in the main process will not cause those parameters to be sent along\n         * with crashes from renderer or other child processes. Similarly, adding extra\n         * parameters in a renderer process will not result in those parameters being sent\n         * with crashes that occur in other renderer processes or in the main process.\n         *\n         * **Note:** Parameters have limits on the length of the keys and values. Key names\n         * must be no longer than 39 bytes, and values must be no longer than 20320 bytes.\n         * Keys with names longer than the maximum will be silently ignored. Key values\n         * longer than the maximum length will be truncated.\n         */\n        addExtraParameter(key: string, value: string): void;\n        /**\n         * The date and ID of the last crash report. Only crash reports that have been\n         * uploaded will be returned; even if a crash report is present on disk it will not\n         * be returned until it is uploaded. In the case that there are no uploaded\n         * reports, `null` is returned.\n         *\n         * **Note:** This method is only available in the main process.\n         */\n        getLastCrashReport(): CrashReport;\n        /**\n         * The current 'extra' parameters of the crash reporter.\n         */\n        getParameters(): Record<string, string>;\n        /**\n         * Returns all uploaded crash reports. Each report contains the date and uploaded\n         * ID.\n         *\n         * **Note:** This method is only available in the main process.\n         */\n        getUploadedReports(): CrashReport[];\n        /**\n         * Whether reports should be submitted to the server. Set through the `start`\n         * method or `setUploadToServer`.\n         *\n         * **Note:** This method is only available in the main process.\n         */\n        getUploadToServer(): boolean;\n        /**\n         * Remove an extra parameter from the current set of parameters. Future crashes\n         * will not include this parameter.\n         */\n        removeExtraParameter(key: string): void;\n        /**\n         * This would normally be controlled by user preferences. This has no effect if\n         * called before `start` is called.\n         *\n         * **Note:** This method is only available in the main process.\n         */\n        setUploadToServer(uploadToServer: boolean): void;\n        /**\n         * This method must be called before using any other `crashReporter` APIs. Once\n         * initialized this way, the crashpad handler collects crashes from all\n         * subsequently created processes. The crash reporter cannot be disabled once\n         * started.\n         *\n         * This method should be called as early as possible in app startup, preferably\n         * before `app.on('ready')`. If the crash reporter is not initialized at the time a\n         * renderer process is created, then that renderer process will not be monitored by\n         * the crash reporter.\n         *\n         * **Note:** You can test out the crash reporter by generating a crash using\n         * `process.crash()`.\n         *\n         * **Note:** If you need to send additional/updated `extra` parameters after your\n         * first call `start` you can call `addExtraParameter`.\n         *\n         * **Note:** Parameters passed in `extra`, `globalExtra` or set with\n         * `addExtraParameter` have limits on the length of the keys and values. Key names\n         * must be at most 39 bytes long, and values must be no longer than 127 bytes. Keys\n         * with names longer than the maximum will be silently ignored. Key values longer\n         * than the maximum length will be truncated.\n         *\n         * **Note:** This method is only available in the main process.\n         */\n        start(options: CrashReporterStartOptions): void;\n    }\n\n    interface CustomScheme {\n        // Docs: https://electronjs.org/docs/api/structures/custom-scheme\n\n        privileges?: Privileges;\n        /**\n         * Custom schemes to be registered with options.\n         */\n        scheme: string;\n    }\n\n    class Debugger extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/debugger\n\n        /**\n         * Emitted when the debugging session is terminated. This happens either when\n         * `webContents` is closed or devtools is invoked for the attached `webContents`.\n         */\n        on(\n            event: \"detach\",\n            listener: (\n                event: Event,\n                /**\n                 * Reason for detaching debugger.\n                 */\n                reason: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"detach\",\n            listener: (\n                event: Event,\n                /**\n                 * Reason for detaching debugger.\n                 */\n                reason: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"detach\",\n            listener: (\n                event: Event,\n                /**\n                 * Reason for detaching debugger.\n                 */\n                reason: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"detach\",\n            listener: (\n                event: Event,\n                /**\n                 * Reason for detaching debugger.\n                 */\n                reason: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted whenever the debugging target issues an instrumentation event.\n         */\n        on(\n            event: \"message\",\n            listener: (\n                event: Event,\n                /**\n                 * Method name.\n                 */\n                method: string,\n                /**\n                 * Event parameters defined by the 'parameters' attribute in the remote debugging\n                 * protocol.\n                 */\n                params: any,\n                /**\n                 * Unique identifier of attached debugging session, will match the value sent from\n                 * `debugger.sendCommand`.\n                 */\n                sessionId: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"message\",\n            listener: (\n                event: Event,\n                /**\n                 * Method name.\n                 */\n                method: string,\n                /**\n                 * Event parameters defined by the 'parameters' attribute in the remote debugging\n                 * protocol.\n                 */\n                params: any,\n                /**\n                 * Unique identifier of attached debugging session, will match the value sent from\n                 * `debugger.sendCommand`.\n                 */\n                sessionId: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"message\",\n            listener: (\n                event: Event,\n                /**\n                 * Method name.\n                 */\n                method: string,\n                /**\n                 * Event parameters defined by the 'parameters' attribute in the remote debugging\n                 * protocol.\n                 */\n                params: any,\n                /**\n                 * Unique identifier of attached debugging session, will match the value sent from\n                 * `debugger.sendCommand`.\n                 */\n                sessionId: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"message\",\n            listener: (\n                event: Event,\n                /**\n                 * Method name.\n                 */\n                method: string,\n                /**\n                 * Event parameters defined by the 'parameters' attribute in the remote debugging\n                 * protocol.\n                 */\n                params: any,\n                /**\n                 * Unique identifier of attached debugging session, will match the value sent from\n                 * `debugger.sendCommand`.\n                 */\n                sessionId: string,\n            ) => void,\n        ): this;\n        /**\n         * Attaches the debugger to the `webContents`.\n         */\n        attach(protocolVersion?: string): void;\n        /**\n         * Detaches the debugger from the `webContents`.\n         */\n        detach(): void;\n        /**\n         * Whether a debugger is attached to the `webContents`.\n         */\n        isAttached(): boolean;\n        /**\n         * A promise that resolves with the response defined by the 'returns' attribute of\n         * the command description in the remote debugging protocol or is rejected\n         * indicating the failure of the command.\n         *\n         * Send given command to the debugging target.\n         */\n        sendCommand(method: string, commandParams?: any, sessionId?: string): Promise<any>;\n    }\n\n    interface DesktopCapturer {\n        // Docs: https://electronjs.org/docs/api/desktop-capturer\n\n        /**\n         * Resolves with an array of `DesktopCapturerSource` objects, each\n         * `DesktopCapturerSource` represents a screen or an individual window that can be\n         * captured.\n         *\n         * **Note** Capturing the screen contents requires user consent on macOS 10.15\n         * Catalina or higher, which can detected by\n         * `systemPreferences.getMediaAccessStatus`.\n         */\n        getSources(options: SourcesOptions): Promise<Electron.DesktopCapturerSource[]>;\n    }\n\n    interface DesktopCapturerSource {\n        // Docs: https://electronjs.org/docs/api/structures/desktop-capturer-source\n\n        /**\n         * An icon image of the application that owns the window or null if the source has\n         * a type screen. The size of the icon is not known in advance and depends on what\n         * the application provides.\n         */\n        appIcon: NativeImage;\n        /**\n         * A unique identifier that will correspond to the `id` of the matching Display\n         * returned by the Screen API. On some platforms, this is equivalent to the `XX`\n         * portion of the `id` field above and on others it will differ. It will be an\n         * empty string if not available.\n         */\n        display_id: string;\n        /**\n         * The identifier of a window or screen that can be used as a `chromeMediaSourceId`\n         * constraint when calling `navigator.getUserMedia`. The format of the identifier\n         * will be `window:XX:YY` or `screen:ZZ:0`. XX is the windowID/handle. YY is 1 for\n         * the current process, and 0 for all others. ZZ is a sequential number that\n         * represents the screen, and it does not equal to the index in the source's name.\n         */\n        id: string;\n        /**\n         * A screen source will be named either `Entire Screen` or `Screen <index>`, while\n         * the name of a window source will match the window title.\n         */\n        name: string;\n        /**\n         * A thumbnail image. **Note:** There is no guarantee that the size of the\n         * thumbnail is the same as the `thumbnailSize` specified in the `options` passed\n         * to `desktopCapturer.getSources`. The actual size depends on the scale of the\n         * screen or window.\n         */\n        thumbnail: NativeImage;\n    }\n\n    interface Dialog {\n        // Docs: https://electronjs.org/docs/api/dialog\n\n        /**\n         * resolves when the certificate trust dialog is shown.\n         *\n         * On macOS, this displays a modal dialog that shows a message and certificate\n         * information, and gives the user the option of trusting/importing the\n         * certificate. If you provide a `browserWindow` argument the dialog will be\n         * attached to the parent window, making it modal.\n         *\n         * On Windows the options are more limited, due to the Win32 APIs used:\n         *\n         * * The `message` argument is not used, as the OS provides its own confirmation\n         * dialog.\n         * * The `browserWindow` argument is ignored since it is not possible to make this\n         * confirmation dialog modal.\n         *\n         * @platform darwin,win32\n         */\n        showCertificateTrustDialog(browserWindow: BrowserWindow, options: CertificateTrustDialogOptions): Promise<void>;\n        /**\n         * resolves when the certificate trust dialog is shown.\n         *\n         * On macOS, this displays a modal dialog that shows a message and certificate\n         * information, and gives the user the option of trusting/importing the\n         * certificate. If you provide a `browserWindow` argument the dialog will be\n         * attached to the parent window, making it modal.\n         *\n         * On Windows the options are more limited, due to the Win32 APIs used:\n         *\n         * * The `message` argument is not used, as the OS provides its own confirmation\n         * dialog.\n         * * The `browserWindow` argument is ignored since it is not possible to make this\n         * confirmation dialog modal.\n         *\n         * @platform darwin,win32\n         */\n        showCertificateTrustDialog(options: CertificateTrustDialogOptions): Promise<void>;\n        /**\n         * Displays a modal dialog that shows an error message.\n         *\n         * This API can be called safely before the `ready` event the `app` module emits,\n         * it is usually used to report errors in early stage of startup. If called before\n         * the app `ready`event on Linux, the message will be emitted to stderr, and no GUI\n         * dialog will appear.\n         */\n        showErrorBox(title: string, content: string): void;\n        /**\n         * resolves with a promise containing the following properties:\n         *\n         * * `response` number - The index of the clicked button.\n         * * `checkboxChecked` boolean - The checked state of the checkbox if\n         * `checkboxLabel` was set. Otherwise `false`.\n         *\n         * Shows a message box.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         */\n        showMessageBox(browserWindow: BrowserWindow, options: MessageBoxOptions): Promise<Electron.MessageBoxReturnValue>;\n        /**\n         * resolves with a promise containing the following properties:\n         *\n         * * `response` number - The index of the clicked button.\n         * * `checkboxChecked` boolean - The checked state of the checkbox if\n         * `checkboxLabel` was set. Otherwise `false`.\n         *\n         * Shows a message box.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         */\n        showMessageBox(options: MessageBoxOptions): Promise<Electron.MessageBoxReturnValue>;\n        /**\n         * the index of the clicked button.\n         *\n         * Shows a message box, it will block the process until the message box is closed.\n         * It returns the index of the clicked button.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal. If `browserWindow` is not shown dialog will not be\n         * attached to it. In such case it will be displayed as an independent window.\n         */\n        showMessageBoxSync(browserWindow: BrowserWindow, options: MessageBoxSyncOptions): number;\n        /**\n         * the index of the clicked button.\n         *\n         * Shows a message box, it will block the process until the message box is closed.\n         * It returns the index of the clicked button.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal. If `browserWindow` is not shown dialog will not be\n         * attached to it. In such case it will be displayed as an independent window.\n         */\n        showMessageBoxSync(options: MessageBoxSyncOptions): number;\n        /**\n         * Resolve with an object containing the following:\n         *\n         * * `canceled` boolean - whether or not the dialog was canceled.\n         * * `filePaths` string[] - An array of file paths chosen by the user. If the\n         * dialog is cancelled this will be an empty array.\n         * * `bookmarks` string[] (optional) _macOS_ _mas_ - An array matching the\n         * `filePaths` array of base64 encoded strings which contains security scoped\n         * bookmark data. `securityScopedBookmarks` must be enabled for this to be\n         * populated. (For return values, see table here.)\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed or selected\n         * when you want to limit the user to a specific type. For example:\n         *\n         * The `extensions` array should contain extensions without wildcards or dots (e.g.\n         * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the\n         * `'*'` wildcard (no other wildcard is supported).\n         *\n         * **Note:** On Windows and Linux an open dialog can not be both a file selector\n         * and a directory selector, so if you set `properties` to `['openFile',\n         * 'openDirectory']` on these platforms, a directory selector will be shown.\n         */\n        showOpenDialog(browserWindow: BrowserWindow, options: OpenDialogOptions): Promise<Electron.OpenDialogReturnValue>;\n        /**\n         * Resolve with an object containing the following:\n         *\n         * * `canceled` boolean - whether or not the dialog was canceled.\n         * * `filePaths` string[] - An array of file paths chosen by the user. If the\n         * dialog is cancelled this will be an empty array.\n         * * `bookmarks` string[] (optional) _macOS_ _mas_ - An array matching the\n         * `filePaths` array of base64 encoded strings which contains security scoped\n         * bookmark data. `securityScopedBookmarks` must be enabled for this to be\n         * populated. (For return values, see table here.)\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed or selected\n         * when you want to limit the user to a specific type. For example:\n         *\n         * The `extensions` array should contain extensions without wildcards or dots (e.g.\n         * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the\n         * `'*'` wildcard (no other wildcard is supported).\n         *\n         * **Note:** On Windows and Linux an open dialog can not be both a file selector\n         * and a directory selector, so if you set `properties` to `['openFile',\n         * 'openDirectory']` on these platforms, a directory selector will be shown.\n         */\n        showOpenDialog(options: OpenDialogOptions): Promise<Electron.OpenDialogReturnValue>;\n        /**\n         * the file paths chosen by the user; if the dialog is cancelled it returns\n         * `undefined`.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed or selected\n         * when you want to limit the user to a specific type. For example:\n         *\n         * The `extensions` array should contain extensions without wildcards or dots (e.g.\n         * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the\n         * `'*'` wildcard (no other wildcard is supported).\n         *\n         * **Note:** On Windows and Linux an open dialog can not be both a file selector\n         * and a directory selector, so if you set `properties` to `['openFile',\n         * 'openDirectory']` on these platforms, a directory selector will be shown.\n         */\n        showOpenDialogSync(browserWindow: BrowserWindow, options: OpenDialogSyncOptions): string[] | undefined;\n        /**\n         * the file paths chosen by the user; if the dialog is cancelled it returns\n         * `undefined`.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed or selected\n         * when you want to limit the user to a specific type. For example:\n         *\n         * The `extensions` array should contain extensions without wildcards or dots (e.g.\n         * `'png'` is good but `'.png'` and `'*.png'` are bad). To show all files, use the\n         * `'*'` wildcard (no other wildcard is supported).\n         *\n         * **Note:** On Windows and Linux an open dialog can not be both a file selector\n         * and a directory selector, so if you set `properties` to `['openFile',\n         * 'openDirectory']` on these platforms, a directory selector will be shown.\n         */\n        showOpenDialogSync(options: OpenDialogSyncOptions): string[] | undefined;\n        /**\n         * Resolve with an object containing the following:\n         *\n         * * `canceled` boolean - whether or not the dialog was canceled.\n         * * `filePath` string (optional) - If the dialog is canceled, this will be\n         * `undefined`.\n         * * `bookmark` string (optional) _macOS_ _mas_ - Base64 encoded string which\n         * contains the security scoped bookmark data for the saved file.\n         * `securityScopedBookmarks` must be enabled for this to be present. (For return\n         * values, see table here.)\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed, see\n         * `dialog.showOpenDialog` for an example.\n         *\n         * **Note:** On macOS, using the asynchronous version is recommended to avoid\n         * issues when expanding and collapsing the dialog.\n         */\n        showSaveDialog(browserWindow: BrowserWindow, options: SaveDialogOptions): Promise<Electron.SaveDialogReturnValue>;\n        /**\n         * Resolve with an object containing the following:\n         *\n         * * `canceled` boolean - whether or not the dialog was canceled.\n         * * `filePath` string (optional) - If the dialog is canceled, this will be\n         * `undefined`.\n         * * `bookmark` string (optional) _macOS_ _mas_ - Base64 encoded string which\n         * contains the security scoped bookmark data for the saved file.\n         * `securityScopedBookmarks` must be enabled for this to be present. (For return\n         * values, see table here.)\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed, see\n         * `dialog.showOpenDialog` for an example.\n         *\n         * **Note:** On macOS, using the asynchronous version is recommended to avoid\n         * issues when expanding and collapsing the dialog.\n         */\n        showSaveDialog(options: SaveDialogOptions): Promise<Electron.SaveDialogReturnValue>;\n        /**\n         * the path of the file chosen by the user; if the dialog is cancelled it returns\n         * `undefined`.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed, see\n         * `dialog.showOpenDialog` for an example.\n         */\n        showSaveDialogSync(browserWindow: BrowserWindow, options: SaveDialogSyncOptions): string | undefined;\n        /**\n         * the path of the file chosen by the user; if the dialog is cancelled it returns\n         * `undefined`.\n         *\n         * The `browserWindow` argument allows the dialog to attach itself to a parent\n         * window, making it modal.\n         *\n         * The `filters` specifies an array of file types that can be displayed, see\n         * `dialog.showOpenDialog` for an example.\n         */\n        showSaveDialogSync(options: SaveDialogSyncOptions): string | undefined;\n    }\n\n    interface Display {\n        // Docs: https://electronjs.org/docs/api/structures/display\n\n        /**\n         * Can be `available`, `unavailable`, `unknown`.\n         */\n        accelerometerSupport: \"available\" | \"unavailable\" | \"unknown\";\n        /**\n         * the bounds of the display in DIP points.\n         */\n        bounds: Rectangle;\n        /**\n         * The number of bits per pixel.\n         */\n        colorDepth: number;\n        /**\n         *  represent a color space (three-dimensional object which contains all realizable\n         * color combinations) for the purpose of color conversions\n         */\n        colorSpace: string;\n        /**\n         * The number of bits per color component.\n         */\n        depthPerComponent: number;\n        /**\n         * The display refresh rate.\n         */\n        displayFrequency: number;\n        /**\n         * Unique identifier associated with the display.\n         */\n        id: number;\n        /**\n         * `true` for an internal display and `false` for an external display\n         */\n        internal: boolean;\n        /**\n         * User-friendly label, determined by the platform.\n         */\n        label: string;\n        /**\n         * Whether or not the display is a monochrome display.\n         */\n        monochrome: boolean;\n        /**\n         * Can be 0, 90, 180, 270, represents screen rotation in clock-wise degrees.\n         */\n        rotation: number;\n        /**\n         * Output device's pixel scale factor.\n         */\n        scaleFactor: number;\n        size: Size;\n        /**\n         * Can be `available`, `unavailable`, `unknown`.\n         */\n        touchSupport: \"available\" | \"unavailable\" | \"unknown\";\n        /**\n         * the work area of the display in DIP points.\n         */\n        workArea: Rectangle;\n        workAreaSize: Size;\n    }\n\n    class Dock {\n        // Docs: https://electronjs.org/docs/api/dock\n\n        /**\n         * an ID representing the request.\n         *\n         * When `critical` is passed, the dock icon will bounce until either the\n         * application becomes active or the request is canceled.\n         *\n         * When `informational` is passed, the dock icon will bounce for one second.\n         * However, the request remains active until either the application becomes active\n         * or the request is canceled.\n         *\n         * **Note:** This method can only be used while the app is not focused; when the\n         * app is focused it will return -1.\n         *\n         * @platform darwin\n         */\n        bounce(type?: \"critical\" | \"informational\"): number;\n        /**\n         * Cancel the bounce of `id`.\n         *\n         * @platform darwin\n         */\n        cancelBounce(id: number): void;\n        /**\n         * Bounces the Downloads stack if the filePath is inside the Downloads folder.\n         *\n         * @platform darwin\n         */\n        downloadFinished(filePath: string): void;\n        /**\n         * The badge string of the dock.\n         *\n         * @platform darwin\n         */\n        getBadge(): string;\n        /**\n         * The application's dock menu.\n         *\n         * @platform darwin\n         */\n        getMenu(): Menu | null;\n        /**\n         * Hides the dock icon.\n         *\n         * @platform darwin\n         */\n        hide(): void;\n        /**\n         * Whether the dock icon is visible.\n         *\n         * @platform darwin\n         */\n        isVisible(): boolean;\n        /**\n         * Sets the string to be displayed in the dock’s badging area.\n         *\n         * @platform darwin\n         */\n        setBadge(text: string): void;\n        /**\n         * Sets the `image` associated with this dock icon.\n         *\n         * @platform darwin\n         */\n        setIcon(image: NativeImage | string): void;\n        /**\n         * Sets the application's dock menu.\n         *\n         * @platform darwin\n         */\n        setMenu(menu: Menu): void;\n        /**\n         * Resolves when the dock icon is shown.\n         *\n         * @platform darwin\n         */\n        show(): Promise<void>;\n    }\n\n    class DownloadItem extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/download-item\n\n        /**\n         * Emitted when the download is in a terminal state. This includes a completed\n         * download, a cancelled download (via `downloadItem.cancel()`), and interrupted\n         * download that can't be resumed.\n         *\n         * The `state` can be one of following:\n         *\n         * * `completed` - The download completed successfully.\n         * * `cancelled` - The download has been cancelled.\n         * * `interrupted` - The download has interrupted and can not resume.\n         */\n        on(\n            event: \"done\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `completed`, `cancelled` or `interrupted`.\n                 */\n                state: \"completed\" | \"cancelled\" | \"interrupted\",\n            ) => void,\n        ): this;\n        once(\n            event: \"done\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `completed`, `cancelled` or `interrupted`.\n                 */\n                state: \"completed\" | \"cancelled\" | \"interrupted\",\n            ) => void,\n        ): this;\n        addListener(\n            event: \"done\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `completed`, `cancelled` or `interrupted`.\n                 */\n                state: \"completed\" | \"cancelled\" | \"interrupted\",\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"done\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `completed`, `cancelled` or `interrupted`.\n                 */\n                state: \"completed\" | \"cancelled\" | \"interrupted\",\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the download has been updated and is not done.\n         *\n         * The `state` can be one of following:\n         *\n         * * `progressing` - The download is in-progress.\n         * * `interrupted` - The download has interrupted and can be resumed.\n         */\n        on(\n            event: \"updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `progressing` or `interrupted`.\n                 */\n                state: \"progressing\" | \"interrupted\",\n            ) => void,\n        ): this;\n        once(\n            event: \"updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `progressing` or `interrupted`.\n                 */\n                state: \"progressing\" | \"interrupted\",\n            ) => void,\n        ): this;\n        addListener(\n            event: \"updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `progressing` or `interrupted`.\n                 */\n                state: \"progressing\" | \"interrupted\",\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `progressing` or `interrupted`.\n                 */\n                state: \"progressing\" | \"interrupted\",\n            ) => void,\n        ): this;\n        /**\n         * Cancels the download operation.\n         */\n        cancel(): void;\n        /**\n         * Whether the download can resume.\n         */\n        canResume(): boolean;\n        /**\n         * The Content-Disposition field from the response header.\n         */\n        getContentDisposition(): string;\n        /**\n         * ETag header value.\n         */\n        getETag(): string;\n        /**\n         * The file name of the download item.\n         *\n         * **Note:** The file name is not always the same as the actual one saved in local\n         * disk. If user changes the file name in a prompted download saving dialog, the\n         * actual name of saved file will be different.\n         */\n        getFilename(): string;\n        /**\n         * Last-Modified header value.\n         */\n        getLastModifiedTime(): string;\n        /**\n         * The files mime type.\n         */\n        getMimeType(): string;\n        /**\n         * The received bytes of the download item.\n         */\n        getReceivedBytes(): number;\n        /**\n         * Returns the object previously set by\n         * `downloadItem.setSaveDialogOptions(options)`.\n         */\n        getSaveDialogOptions(): SaveDialogOptions;\n        /**\n         * The save path of the download item. This will be either the path set via\n         * `downloadItem.setSavePath(path)` or the path selected from the shown save\n         * dialog.\n         */\n        getSavePath(): string;\n        /**\n         * Number of seconds since the UNIX epoch when the download was started.\n         */\n        getStartTime(): number;\n        /**\n         * The current state. Can be `progressing`, `completed`, `cancelled` or\n         * `interrupted`.\n         *\n         * **Note:** The following methods are useful specifically to resume a `cancelled`\n         * item when session is restarted.\n         */\n        getState(): \"progressing\" | \"completed\" | \"cancelled\" | \"interrupted\";\n        /**\n         * The total size in bytes of the download item.\n         *\n         * If the size is unknown, it returns 0.\n         */\n        getTotalBytes(): number;\n        /**\n         * The origin URL where the item is downloaded from.\n         */\n        getURL(): string;\n        /**\n         * The complete URL chain of the item including any redirects.\n         */\n        getURLChain(): string[];\n        /**\n         * Whether the download has user gesture.\n         */\n        hasUserGesture(): boolean;\n        /**\n         * Whether the download is paused.\n         */\n        isPaused(): boolean;\n        /**\n         * Pauses the download.\n         */\n        pause(): void;\n        /**\n         * Resumes the download that has been paused.\n         *\n         * **Note:** To enable resumable downloads the server you are downloading from must\n         * support range requests and provide both `Last-Modified` and `ETag` header\n         * values. Otherwise `resume()` will dismiss previously received bytes and restart\n         * the download from the beginning.\n         */\n        resume(): void;\n        /**\n         * This API allows the user to set custom options for the save dialog that opens\n         * for the download item by default. The API is only available in session's\n         * `will-download` callback function.\n         */\n        setSaveDialogOptions(options: SaveDialogOptions): void;\n        /**\n         * The API is only available in session's `will-download` callback function. If\n         * `path` doesn't exist, Electron will try to make the directory recursively. If\n         * user doesn't set the save path via the API, Electron will use the original\n         * routine to determine the save path; this usually prompts a save dialog.\n         */\n        setSavePath(path: string): void;\n        /**\n         * A `string` property that determines the save file path of the download item.\n         *\n         * The property is only available in session's `will-download` callback function.\n         * If user doesn't set the save path via the property, Electron will use the\n         * original routine to determine the save path; this usually prompts a save dialog.\n         */\n        savePath: string;\n    }\n\n    interface Extension {\n        // Docs: https://electronjs.org/docs/api/structures/extension\n\n        id: string;\n        /**\n         * Copy of the extension's manifest data.\n         */\n        manifest: any;\n        name: string;\n        /**\n         * The extension's file path.\n         */\n        path: string;\n        /**\n         * The extension's `chrome-extension://` URL.\n         */\n        url: string;\n        version: string;\n    }\n\n    interface ExtensionInfo {\n        // Docs: https://electronjs.org/docs/api/structures/extension-info\n\n        name: string;\n        version: string;\n    }\n\n    interface FileFilter {\n        // Docs: https://electronjs.org/docs/api/structures/file-filter\n\n        extensions: string[];\n        name: string;\n    }\n\n    interface FilePathWithHeaders {\n        // Docs: https://electronjs.org/docs/api/structures/file-path-with-headers\n\n        /**\n         * Additional headers to be sent.\n         */\n        headers?: Record<string, string>;\n        /**\n         * The path to the file to send.\n         */\n        path: string;\n    }\n\n    interface GlobalShortcut {\n        // Docs: https://electronjs.org/docs/api/global-shortcut\n\n        /**\n         * Whether this application has registered `accelerator`.\n         *\n         * When the accelerator is already taken by other applications, this call will\n         * still return `false`. This behavior is intended by operating systems, since they\n         * don't want applications to fight for global shortcuts.\n         */\n        isRegistered(accelerator: Accelerator): boolean;\n        /**\n         * Whether or not the shortcut was registered successfully.\n         *\n         * Registers a global shortcut of `accelerator`. The `callback` is called when the\n         * registered shortcut is pressed by the user.\n         *\n         * When the accelerator is already taken by other applications, this call will\n         * silently fail. This behavior is intended by operating systems, since they don't\n         * want applications to fight for global shortcuts.\n         *\n         * The following accelerators will not be registered successfully on macOS 10.14\n         * Mojave unless the app has been authorized as a trusted accessibility client:\n         *\n         * * \"Media Play/Pause\"\n         * * \"Media Next Track\"\n         * * \"Media Previous Track\"\n         * * \"Media Stop\"\n         */\n        register(accelerator: Accelerator, callback: () => void): boolean;\n        /**\n         * Registers a global shortcut of all `accelerator` items in `accelerators`. The\n         * `callback` is called when any of the registered shortcuts are pressed by the\n         * user.\n         *\n         * When a given accelerator is already taken by other applications, this call will\n         * silently fail. This behavior is intended by operating systems, since they don't\n         * want applications to fight for global shortcuts.\n         *\n         * The following accelerators will not be registered successfully on macOS 10.14\n         * Mojave unless the app has been authorized as a trusted accessibility client:\n         *\n         * * \"Media Play/Pause\"\n         * * \"Media Next Track\"\n         * * \"Media Previous Track\"\n         * * \"Media Stop\"\n         */\n        registerAll(accelerators: Accelerator[], callback: () => void): void;\n        /**\n         * Unregisters the global shortcut of `accelerator`.\n         */\n        unregister(accelerator: Accelerator): void;\n        /**\n         * Unregisters all of the global shortcuts.\n         */\n        unregisterAll(): void;\n    }\n\n    interface GPUFeatureStatus {\n        // Docs: https://electronjs.org/docs/api/structures/gpu-feature-status\n\n        /**\n         * Canvas.\n         */\n        \"2d_canvas\": string;\n        /**\n         * Flash.\n         */\n        flash_3d: string;\n        /**\n         * Flash Stage3D.\n         */\n        flash_stage3d: string;\n        /**\n         * Flash Stage3D Baseline profile.\n         */\n        flash_stage3d_baseline: string;\n        /**\n         * Compositing.\n         */\n        gpu_compositing: string;\n        /**\n         * Multiple Raster Threads.\n         */\n        multiple_raster_threads: string;\n        /**\n         * Native GpuMemoryBuffers.\n         */\n        native_gpu_memory_buffers: string;\n        /**\n         * Rasterization.\n         */\n        rasterization: string;\n        /**\n         * Video Decode.\n         */\n        video_decode: string;\n        /**\n         * Video Encode.\n         */\n        video_encode: string;\n        /**\n         * VPx Video Decode.\n         */\n        vpx_decode: string;\n        /**\n         * WebGL.\n         */\n        webgl: string;\n        /**\n         * WebGL2.\n         */\n        webgl2: string;\n    }\n\n    interface HIDDevice {\n        // Docs: https://electronjs.org/docs/api/structures/hid-device\n\n        /**\n         * Unique identifier for the device.\n         */\n        deviceId: string;\n        /**\n         * Unique identifier for the HID interface.  A device may have multiple HID\n         * interfaces.\n         */\n        guid?: string;\n        /**\n         * Name of the device.\n         */\n        name: string;\n        /**\n         * The USB product ID.\n         */\n        productId: number;\n        /**\n         * The USB device serial number.\n         */\n        serialNumber?: string;\n        /**\n         * The USB vendor ID.\n         */\n        vendorId: number;\n    }\n\n    interface InAppPurchase extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/in-app-purchase\n\n        on(event: \"transactions-updated\", listener: Function): this;\n        once(event: \"transactions-updated\", listener: Function): this;\n        addListener(event: \"transactions-updated\", listener: Function): this;\n        removeListener(event: \"transactions-updated\", listener: Function): this;\n        /**\n         * whether a user can make a payment.\n         */\n        canMakePayments(): boolean;\n        /**\n         * Completes all pending transactions.\n         */\n        finishAllTransactions(): void;\n        /**\n         * Completes the pending transactions corresponding to the date.\n         */\n        finishTransactionByDate(date: string): void;\n        /**\n         * Resolves with an array of `Product` objects.\n         *\n         * Retrieves the product descriptions.\n         */\n        getProducts(productIDs: string[]): Promise<Electron.Product[]>;\n        /**\n         * the path to the receipt.\n         */\n        getReceiptURL(): string;\n        /**\n         * Returns `true` if the product is valid and added to the payment queue.\n         *\n         * You should listen for the `transactions-updated` event as soon as possible and\n         * certainly before you call `purchaseProduct`.\n         */\n        purchaseProduct(productID: string, opts?: number | PurchaseProductOpts): Promise<boolean>;\n        /**\n         * Restores finished transactions. This method can be called either to install\n         * purchases on additional devices, or to restore purchases for an application that\n         * the user deleted and reinstalled.\n         *\n         * The payment queue delivers a new transaction for each previously completed\n         * transaction that can be restored. Each transaction includes a copy of the\n         * original transaction.\n         */\n        restoreCompletedTransactions(): void;\n    }\n\n    class IncomingMessage extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/incoming-message\n\n        /**\n         * Emitted when a request has been canceled during an ongoing HTTP transaction.\n         */\n        on(event: \"aborted\", listener: Function): this;\n        once(event: \"aborted\", listener: Function): this;\n        addListener(event: \"aborted\", listener: Function): this;\n        removeListener(event: \"aborted\", listener: Function): this;\n        /**\n         * The `data` event is the usual method of transferring response data into\n         * applicative code.\n         */\n        on(\n            event: \"data\",\n            listener: (\n                /**\n                 * A chunk of response body's data.\n                 */\n                chunk: Buffer,\n            ) => void,\n        ): this;\n        once(\n            event: \"data\",\n            listener: (\n                /**\n                 * A chunk of response body's data.\n                 */\n                chunk: Buffer,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"data\",\n            listener: (\n                /**\n                 * A chunk of response body's data.\n                 */\n                chunk: Buffer,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"data\",\n            listener: (\n                /**\n                 * A chunk of response body's data.\n                 */\n                chunk: Buffer,\n            ) => void,\n        ): this;\n        /**\n         * Indicates that response body has ended. Must be placed before 'data' event.\n         */\n        on(event: \"end\", listener: Function): this;\n        once(event: \"end\", listener: Function): this;\n        addListener(event: \"end\", listener: Function): this;\n        removeListener(event: \"end\", listener: Function): this;\n        /**\n         * Returns:\n         *\n         * `error` Error - Typically holds an error string identifying failure root cause.\n         *\n         * Emitted when an error was encountered while streaming response data events. For\n         * instance, if the server closes the underlying while the response is still\n         * streaming, an `error` event will be emitted on the response object and a `close`\n         * event will subsequently follow on the request object.\n         */\n        on(event: \"error\", listener: Function): this;\n        once(event: \"error\", listener: Function): this;\n        addListener(event: \"error\", listener: Function): this;\n        removeListener(event: \"error\", listener: Function): this;\n        /**\n         * A `Record<string, string | string[]>` representing the HTTP response headers.\n         * The `headers` object is formatted as follows:\n         *\n         * * All header names are lowercased.\n         * * Duplicates of `age`, `authorization`, `content-length`, `content-type`,\n         * `etag`, `expires`, `from`, `host`, `if-modified-since`, `if-unmodified-since`,\n         * `last-modified`, `location`, `max-forwards`, `proxy-authorization`, `referer`,\n         * `retry-after`, `server`, or `user-agent` are discarded.\n         * * `set-cookie` is always an array. Duplicates are added to the array.\n         * * For duplicate `cookie` headers, the values are joined together with '; '.\n         * * For all other headers, the values are joined together with ', '.\n         */\n        headers: Record<string, string | string[]>;\n        /**\n         * A `string` indicating the HTTP protocol version number. Typical values are '1.0'\n         * or '1.1'. Additionally `httpVersionMajor` and `httpVersionMinor` are two\n         * Integer-valued readable properties that return respectively the HTTP major and\n         * minor version numbers.\n         */\n        httpVersion: string;\n        /**\n         * An `Integer` indicating the HTTP protocol major version number.\n         */\n        httpVersionMajor: number;\n        /**\n         * An `Integer` indicating the HTTP protocol minor version number.\n         */\n        httpVersionMinor: number;\n        /**\n         * A `string[]` containing the raw HTTP response headers exactly as they were\n         * received. The keys and values are in the same list. It is not a list of tuples.\n         * So, the even-numbered offsets are key values, and the odd-numbered offsets are\n         * the associated values. Header names are not lowercased, and duplicates are not\n         * merged.\n         */\n        rawHeaders: string[];\n        /**\n         * An `Integer` indicating the HTTP response status code.\n         */\n        statusCode: number;\n        /**\n         * A `string` representing the HTTP status message.\n         */\n        statusMessage: string;\n    }\n\n    interface InputEvent {\n        // Docs: https://electronjs.org/docs/api/structures/input-event\n\n        /**\n         * An array of modifiers of the event, can be `shift`, `control`, `ctrl`, `alt`,\n         * `meta`, `command`, `cmd`, `isKeypad`, `isAutoRepeat`, `leftButtonDown`,\n         * `middleButtonDown`, `rightButtonDown`, `capsLock`, `numLock`, `left`, `right`.\n         */\n        modifiers?: Array<\"shift\" | \"control\" | \"ctrl\" | \"alt\" | \"meta\" | \"command\" | \"cmd\" | \"isKeypad\" | \"isAutoRepeat\" | \"leftButtonDown\" | \"middleButtonDown\" | \"rightButtonDown\" | \"capsLock\" | \"numLock\" | \"left\" | \"right\">;\n        /**\n         * Can be `undefined`, `mouseDown`, `mouseUp`, `mouseMove`, `mouseEnter`,\n         * `mouseLeave`, `contextMenu`, `mouseWheel`, `rawKeyDown`, `keyDown`, `keyUp`,\n         * `char`, `gestureScrollBegin`, `gestureScrollEnd`, `gestureScrollUpdate`,\n         * `gestureFlingStart`, `gestureFlingCancel`, `gesturePinchBegin`,\n         * `gesturePinchEnd`, `gesturePinchUpdate`, `gestureTapDown`, `gestureShowPress`,\n         * `gestureTap`, `gestureTapCancel`, `gestureShortPress`, `gestureLongPress`,\n         * `gestureLongTap`, `gestureTwoFingerTap`, `gestureTapUnconfirmed`,\n         * `gestureDoubleTap`, `touchStart`, `touchMove`, `touchEnd`, `touchCancel`,\n         * `touchScrollStarted`, `pointerDown`, `pointerUp`, `pointerMove`,\n         * `pointerRawUpdate`, `pointerCancel` or `pointerCausedUaAction`.\n         */\n        type:\n            | \"undefined\"\n            | \"mouseDown\"\n            | \"mouseUp\"\n            | \"mouseMove\"\n            | \"mouseEnter\"\n            | \"mouseLeave\"\n            | \"contextMenu\"\n            | \"mouseWheel\"\n            | \"rawKeyDown\"\n            | \"keyDown\"\n            | \"keyUp\"\n            | \"char\"\n            | \"gestureScrollBegin\"\n            | \"gestureScrollEnd\"\n            | \"gestureScrollUpdate\"\n            | \"gestureFlingStart\"\n            | \"gestureFlingCancel\"\n            | \"gesturePinchBegin\"\n            | \"gesturePinchEnd\"\n            | \"gesturePinchUpdate\"\n            | \"gestureTapDown\"\n            | \"gestureShowPress\"\n            | \"gestureTap\"\n            | \"gestureTapCancel\"\n            | \"gestureShortPress\"\n            | \"gestureLongPress\"\n            | \"gestureLongTap\"\n            | \"gestureTwoFingerTap\"\n            | \"gestureTapUnconfirmed\"\n            | \"gestureDoubleTap\"\n            | \"touchStart\"\n            | \"touchMove\"\n            | \"touchEnd\"\n            | \"touchCancel\"\n            | \"touchScrollStarted\"\n            | \"pointerDown\"\n            | \"pointerUp\"\n            | \"pointerMove\"\n            | \"pointerRawUpdate\"\n            | \"pointerCancel\"\n            | \"pointerCausedUaAction\";\n    }\n\n    interface IOCounters {\n        // Docs: https://electronjs.org/docs/api/structures/io-counters\n\n        /**\n         * Then number of I/O other operations.\n         */\n        otherOperationCount: number;\n        /**\n         * Then number of I/O other transfers.\n         */\n        otherTransferCount: number;\n        /**\n         * The number of I/O read operations.\n         */\n        readOperationCount: number;\n        /**\n         * The number of I/O read transfers.\n         */\n        readTransferCount: number;\n        /**\n         * The number of I/O write operations.\n         */\n        writeOperationCount: number;\n        /**\n         * The number of I/O write transfers.\n         */\n        writeTransferCount: number;\n    }\n\n    interface IpcMain extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/ipc-main\n\n        /**\n         * Adds a handler for an `invoke`able IPC. This handler will be called whenever a\n         * renderer calls `ipcRenderer.invoke(channel, ...args)`.\n         *\n         * If `listener` returns a Promise, the eventual result of the promise will be\n         * returned as a reply to the remote caller. Otherwise, the return value of the\n         * listener will be used as the value of the reply.\n         *\n         * The `event` that is passed as the first argument to the handler is the same as\n         * that passed to a regular event listener. It includes information about which\n         * WebContents is the source of the invoke request.\n         *\n         * Errors thrown through `handle` in the main process are not transparent as they\n         * are serialized and only the `message` property from the original error is\n         * provided to the renderer process. Please refer to #24427 for details.\n         */\n        handle(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => Promise<void> | any): void;\n        /**\n         * Handles a single `invoke`able IPC message, then removes the listener. See\n         * `ipcMain.handle(channel, listener)`.\n         */\n        handleOnce(channel: string, listener: (event: IpcMainInvokeEvent, ...args: any[]) => Promise<void> | any): void;\n        /**\n         * Listens to `channel`, when a new message arrives `listener` would be called with\n         * `listener(event, args...)`.\n         */\n        on(channel: string, listener: (event: IpcMainEvent, ...args: any[]) => void): this;\n        /**\n         * Adds a one time `listener` function for the event. This `listener` is invoked\n         * only the next time a message is sent to `channel`, after which it is removed.\n         */\n        once(channel: string, listener: (event: IpcMainEvent, ...args: any[]) => void): this;\n        /**\n         * Removes listeners of the specified `channel`.\n         */\n        removeAllListeners(channel?: string): this;\n        /**\n         * Removes any handler for `channel`, if present.\n         */\n        removeHandler(channel: string): void;\n        /**\n         * Removes the specified `listener` from the listener array for the specified\n         * `channel`.\n         */\n        removeListener(channel: string, listener: (...args: any[]) => void): this;\n    }\n\n    interface IpcMainEvent extends Event {\n        // Docs: https://electronjs.org/docs/api/structures/ipc-main-event\n\n        /**\n         * The ID of the renderer frame that sent this message\n         */\n        frameId: number;\n        /**\n         * A list of MessagePorts that were transferred with this message\n         */\n        ports: MessagePortMain[];\n        /**\n         * The internal ID of the renderer process that sent this message\n         */\n        processId: number;\n        /**\n         * A function that will send an IPC message to the renderer frame that sent the\n         * original message that you are currently handling.  You should use this method to\n         * \"reply\" to the sent message in order to guarantee the reply will go to the\n         * correct process and frame.\n         */\n        reply: (channel: string, ...args: any[]) => void;\n        /**\n         * Set this to the value to be returned in a synchronous message\n         */\n        returnValue: any;\n        /**\n         * Returns the `webContents` that sent the message\n         */\n        sender: WebContents;\n        /**\n         * The frame that sent this message\n         *\n         */\n        readonly senderFrame: WebFrameMain;\n    }\n\n    interface IpcMainInvokeEvent extends Event {\n        // Docs: https://electronjs.org/docs/api/structures/ipc-main-invoke-event\n\n        /**\n         * The ID of the renderer frame that sent this message\n         */\n        frameId: number;\n        /**\n         * The internal ID of the renderer process that sent this message\n         */\n        processId: number;\n        /**\n         * Returns the `webContents` that sent the message\n         */\n        sender: WebContents;\n        /**\n         * The frame that sent this message\n         *\n         */\n        readonly senderFrame: WebFrameMain;\n    }\n\n    interface IpcRenderer extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/ipc-renderer\n\n        /**\n         * Resolves with the response from the main process.\n         *\n         * Send a message to the main process via `channel` and expect a result\n         * asynchronously. Arguments will be serialized with the Structured Clone\n         * Algorithm, just like `window.postMessage`, so prototype chains will not be\n         * included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw\n         * an exception.\n         *\n         * The main process should listen for `channel` with `ipcMain.handle()`.\n         *\n         * For example:\n         *\n         * If you need to transfer a `MessagePort` to the main process, use\n         * `ipcRenderer.postMessage`.\n         *\n         * If you do not need a response to the message, consider using `ipcRenderer.send`.\n         *\n         * > **Note** Sending non-standard JavaScript types such as DOM objects or special\n         * Electron objects will throw an exception.\n         *\n         * Since the main process does not have support for DOM objects such as\n         * `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over\n         * Electron's IPC to the main process, as the main process would have no way to\n         * decode them. Attempting to send such objects over IPC will result in an error.\n         *\n         * > **Note** If the handler in the main process throws an error, the promise\n         * returned by `invoke` will reject. However, the `Error` object in the renderer\n         * process will not be the same as the one thrown in the main process.\n         */\n        invoke(channel: string, ...args: any[]): Promise<any>;\n        /**\n         * Listens to `channel`, when a new message arrives `listener` would be called with\n         * `listener(event, args...)`.\n         */\n        on(channel: string, listener: (event: IpcRendererEvent, ...args: any[]) => void): this;\n        /**\n         * Adds a one time `listener` function for the event. This `listener` is invoked\n         * only the next time a message is sent to `channel`, after which it is removed.\n         */\n        once(channel: string, listener: (event: IpcRendererEvent, ...args: any[]) => void): this;\n        /**\n         * Send a message to the main process, optionally transferring ownership of zero or\n         * more `MessagePort` objects.\n         *\n         * The transferred `MessagePort` objects will be available in the main process as\n         * `MessagePortMain` objects by accessing the `ports` property of the emitted\n         * event.\n         *\n         * For example:\n         *\n         * For more information on using `MessagePort` and `MessageChannel`, see the MDN\n         * documentation.\n         */\n        postMessage(channel: string, message: any, transfer?: MessagePort[]): void;\n        /**\n         * Removes all listeners, or those of the specified `channel`.\n         */\n        removeAllListeners(channel: string): this;\n        /**\n         * Removes the specified `listener` from the listener array for the specified\n         * `channel`.\n         */\n        removeListener(channel: string, listener: (...args: any[]) => void): this;\n        /**\n         * Send an asynchronous message to the main process via `channel`, along with\n         * arguments. Arguments will be serialized with the Structured Clone Algorithm,\n         * just like `window.postMessage`, so prototype chains will not be included.\n         * Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an\n         * exception.\n         *\n         * > **NOTE:** Sending non-standard JavaScript types such as DOM objects or special\n         * Electron objects will throw an exception.\n         *\n         * Since the main process does not have support for DOM objects such as\n         * `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over\n         * Electron's IPC to the main process, as the main process would have no way to\n         * decode them. Attempting to send such objects over IPC will result in an error.\n         *\n         * The main process handles it by listening for `channel` with the `ipcMain`\n         * module.\n         *\n         * If you need to transfer a `MessagePort` to the main process, use\n         * `ipcRenderer.postMessage`.\n         *\n         * If you want to receive a single response from the main process, like the result\n         * of a method call, consider using `ipcRenderer.invoke`.\n         */\n        send(channel: string, ...args: any[]): void;\n        /**\n         * The value sent back by the `ipcMain` handler.\n         *\n         * Send a message to the main process via `channel` and expect a result\n         * synchronously. Arguments will be serialized with the Structured Clone Algorithm,\n         * just like `window.postMessage`, so prototype chains will not be included.\n         * Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an\n         * exception.\n         *\n         * > **NOTE:** Sending non-standard JavaScript types such as DOM objects or special\n         * Electron objects will throw an exception.\n         *\n         * Since the main process does not have support for DOM objects such as\n         * `ImageBitmap`, `File`, `DOMMatrix` and so on, such objects cannot be sent over\n         * Electron's IPC to the main process, as the main process would have no way to\n         * decode them. Attempting to send such objects over IPC will result in an error.\n         *\n         * The main process handles it by listening for `channel` with `ipcMain` module,\n         * and replies by setting `event.returnValue`.\n         *\n         * > :warning: **WARNING**: Sending a synchronous message will block the whole\n         * renderer process until the reply is received, so use this method only as a last\n         * resort. It's much better to use the asynchronous version, `invoke()`.\n         */\n        sendSync(channel: string, ...args: any[]): any;\n        /**\n         * Sends a message to a window with `webContentsId` via `channel`.\n         */\n        sendTo(webContentsId: number, channel: string, ...args: any[]): void;\n        /**\n         * Like `ipcRenderer.send` but the event will be sent to the `<webview>` element in\n         * the host page instead of the main process.\n         */\n        sendToHost(channel: string, ...args: any[]): void;\n    }\n\n    interface IpcRendererEvent extends Event {\n        // Docs: https://electronjs.org/docs/api/structures/ipc-renderer-event\n\n        /**\n         * A list of MessagePorts that were transferred with this message\n         */\n        ports: MessagePort[];\n        /**\n         * The `IpcRenderer` instance that emitted the event originally\n         */\n        sender: IpcRenderer;\n        /**\n         * The `webContents.id` that sent the message, you can call\n         * `event.sender.sendTo(event.senderId, ...)` to reply to the message, see\n         * ipcRenderer.sendTo for more information. This only applies to messages sent from\n         * a different renderer. Messages sent directly from the main process set\n         * `event.senderId` to `0`.\n         */\n        senderId: number;\n    }\n\n    interface JumpListCategory {\n        // Docs: https://electronjs.org/docs/api/structures/jump-list-category\n\n        /**\n         * Array of `JumpListItem` objects if `type` is `tasks` or `custom`, otherwise it\n         * should be omitted.\n         */\n        items?: JumpListItem[];\n        /**\n         * Must be set if `type` is `custom`, otherwise it should be omitted.\n         */\n        name?: string;\n        /**\n         * One of the following:\n         */\n        type?: \"tasks\" | \"frequent\" | \"recent\" | \"custom\";\n    }\n\n    interface JumpListItem {\n        // Docs: https://electronjs.org/docs/api/structures/jump-list-item\n\n        /**\n         * The command line arguments when `program` is executed. Should only be set if\n         * `type` is `task`.\n         */\n        args?: string;\n        /**\n         * Description of the task (displayed in a tooltip). Should only be set if `type`\n         * is `task`. Maximum length 260 characters.\n         */\n        description?: string;\n        /**\n         * The index of the icon in the resource file. If a resource file contains multiple\n         * icons this value can be used to specify the zero-based index of the icon that\n         * should be displayed for this task. If a resource file contains only one icon,\n         * this property should be set to zero.\n         */\n        iconIndex?: number;\n        /**\n         * The absolute path to an icon to be displayed in a Jump List, which can be an\n         * arbitrary resource file that contains an icon (e.g. `.ico`, `.exe`, `.dll`). You\n         * can usually specify `process.execPath` to show the program icon.\n         */\n        iconPath?: string;\n        /**\n         * Path of the file to open, should only be set if `type` is `file`.\n         */\n        path?: string;\n        /**\n         * Path of the program to execute, usually you should specify `process.execPath`\n         * which opens the current program. Should only be set if `type` is `task`.\n         */\n        program?: string;\n        /**\n         * The text to be displayed for the item in the Jump List. Should only be set if\n         * `type` is `task`.\n         */\n        title?: string;\n        /**\n         * One of the following:\n         */\n        type?: \"task\" | \"separator\" | \"file\";\n        /**\n         * The working directory. Default is empty.\n         */\n        workingDirectory?: string;\n    }\n\n    interface KeyboardEvent {\n        // Docs: https://electronjs.org/docs/api/structures/keyboard-event\n\n        /**\n         * whether an Alt key was used in an accelerator to trigger the Event\n         */\n        altKey?: boolean;\n        /**\n         * whether the Control key was used in an accelerator to trigger the Event\n         */\n        ctrlKey?: boolean;\n        /**\n         * whether a meta key was used in an accelerator to trigger the Event\n         */\n        metaKey?: boolean;\n        /**\n         * whether a Shift key was used in an accelerator to trigger the Event\n         */\n        shiftKey?: boolean;\n        /**\n         * whether an accelerator was used to trigger the event as opposed to another user\n         * gesture like mouse click\n         */\n        triggeredByAccelerator?: boolean;\n    }\n\n    interface KeyboardInputEvent extends InputEvent {\n        // Docs: https://electronjs.org/docs/api/structures/keyboard-input-event\n\n        /**\n         * The character that will be sent as the keyboard event. Should only use the valid\n         * key codes in Accelerator.\n         */\n        keyCode: string;\n        /**\n         * The type of the event, can be `rawKeyDown`, `keyDown`, `keyUp` or `char`.\n         */\n        type: \"rawKeyDown\" | \"keyDown\" | \"keyUp\" | \"char\";\n    }\n\n    interface MemoryInfo {\n        // Docs: https://electronjs.org/docs/api/structures/memory-info\n\n        /**\n         * The maximum amount of memory that has ever been pinned to actual physical RAM.\n         */\n        peakWorkingSetSize: number;\n        /**\n         * The amount of memory not shared by other processes, such as JS heap or HTML\n         * content.\n         *\n         * @platform win32\n         */\n        privateBytes?: number;\n        /**\n         * The amount of memory currently pinned to actual physical RAM.\n         */\n        workingSetSize: number;\n    }\n\n    interface MemoryUsageDetails {\n        // Docs: https://electronjs.org/docs/api/structures/memory-usage-details\n\n        count: number;\n        liveSize: number;\n        size: number;\n    }\n\n    class Menu extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/menu\n\n        /**\n         * Emitted when a popup is closed either manually or with `menu.closePopup()`.\n         */\n        on(event: \"menu-will-close\", listener: (event: Event) => void): this;\n        once(event: \"menu-will-close\", listener: (event: Event) => void): this;\n        addListener(event: \"menu-will-close\", listener: (event: Event) => void): this;\n        removeListener(event: \"menu-will-close\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when `menu.popup()` is called.\n         */\n        on(event: \"menu-will-show\", listener: (event: Event) => void): this;\n        once(event: \"menu-will-show\", listener: (event: Event) => void): this;\n        addListener(event: \"menu-will-show\", listener: (event: Event) => void): this;\n        removeListener(event: \"menu-will-show\", listener: (event: Event) => void): this;\n        /**\n         * Menu\n         */\n        constructor();\n        /**\n         * Generally, the `template` is an array of `options` for constructing a MenuItem.\n         * The usage can be referenced above.\n         *\n         * You can also attach other fields to the element of the `template` and they will\n         * become properties of the constructed menu items.\n         */\n        static buildFromTemplate(template: Array<MenuItemConstructorOptions | MenuItem>): Menu;\n        /**\n         * The application menu, if set, or `null`, if not set.\n         *\n         * **Note:** The returned `Menu` instance doesn't support dynamic addition or\n         * removal of menu items. Instance properties can still be dynamically modified.\n         */\n        static getApplicationMenu(): Menu | null;\n        /**\n         * Sends the `action` to the first responder of application. This is used for\n         * emulating default macOS menu behaviors. Usually you would use the `role`\n         * property of a `MenuItem`.\n         *\n         * See the macOS Cocoa Event Handling Guide for more information on macOS' native\n         * actions.\n         *\n         * @platform darwin\n         */\n        static sendActionToFirstResponder(action: string): void;\n        /**\n         * Sets `menu` as the application menu on macOS. On Windows and Linux, the `menu`\n         * will be set as each window's top menu.\n         *\n         * Also on Windows and Linux, you can use a `&` in the top-level item name to\n         * indicate which letter should get a generated accelerator. For example, using\n         * `&File` for the file menu would result in a generated `Alt-F` accelerator that\n         * opens the associated menu. The indicated character in the button label then gets\n         * an underline, and the `&` character is not displayed on the button label.\n         *\n         * In order to escape the `&` character in an item name, add a proceeding `&`. For\n         * example, `&&File` would result in `&File` displayed on the button label.\n         *\n         * Passing `null` will suppress the default menu. On Windows and Linux, this has\n         * the additional effect of removing the menu bar from the window.\n         *\n         * **Note:** The default menu will be created automatically if the app does not set\n         * one. It contains standard items such as `File`, `Edit`, `View`, `Window` and\n         * `Help`.\n         */\n        static setApplicationMenu(menu: Menu | null): void;\n        /**\n         * Appends the `menuItem` to the menu.\n         */\n        append(menuItem: MenuItem): void;\n        /**\n         * Closes the context menu in the `browserWindow`.\n         */\n        closePopup(browserWindow?: BrowserWindow): void;\n        /**\n         * the item with the specified `id`\n         */\n        getMenuItemById(id: string): MenuItem | null;\n        /**\n         * Inserts the `menuItem` to the `pos` position of the menu.\n         */\n        insert(pos: number, menuItem: MenuItem): void;\n        /**\n         * Pops up this menu as a context menu in the `BrowserWindow`.\n         */\n        popup(options?: PopupOptions): void;\n        /**\n         * A `MenuItem[]` array containing the menu's items.\n         *\n         * Each `Menu` consists of multiple `MenuItem`s and each `MenuItem` can have a\n         * submenu.\n         */\n        items: MenuItem[];\n    }\n\n    class MenuItem {\n        // Docs: https://electronjs.org/docs/api/menu-item\n\n        /**\n         * MenuItem\n         */\n        constructor(options: MenuItemConstructorOptions);\n        /**\n         * An `Accelerator` (optional) indicating the item's accelerator, if set.\n         */\n        accelerator?: Accelerator;\n        /**\n         * A `boolean` indicating whether the item is checked, this property can be\n         * dynamically changed.\n         *\n         * A `checkbox` menu item will toggle the `checked` property on and off when\n         * selected.\n         *\n         * A `radio` menu item will turn on its `checked` property when clicked, and will\n         * turn off that property for all adjacent items in the same menu.\n         *\n         * You can add a `click` function for additional behavior.\n         */\n        checked: boolean;\n        /**\n         * A `Function` that is fired when the MenuItem receives a click event. It can be\n         * called with `menuItem.click(event, focusedWindow, focusedWebContents)`.\n         *\n         * * `event` KeyboardEvent\n         * * `focusedWindow` BrowserWindow\n         * * `focusedWebContents` WebContents\n         */\n        click: Function;\n        /**\n         * A `number` indicating an item's sequential unique id.\n         */\n        commandId: number;\n        /**\n         * A `boolean` indicating whether the item is enabled, this property can be\n         * dynamically changed.\n         */\n        enabled: boolean;\n        /**\n         * A `NativeImage | string` (optional) indicating the item's icon, if set.\n         */\n        icon?: NativeImage | string;\n        /**\n         * A `string` indicating the item's unique id, this property can be dynamically\n         * changed.\n         */\n        id: string;\n        /**\n         * A `string` indicating the item's visible label.\n         */\n        label: string;\n        /**\n         * A `Menu` that the item is a part of.\n         */\n        menu: Menu;\n        /**\n         * A `boolean` indicating if the accelerator should be registered with the system\n         * or just displayed.\n         *\n         * This property can be dynamically changed.\n         */\n        registerAccelerator: boolean;\n        /**\n         * A `string` (optional) indicating the item's role, if set. Can be `undo`, `redo`,\n         * `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`,\n         * `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`,\n         * `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`, `close`, `help`,\n         * `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`,\n         * `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`,\n         * `shareMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`,\n         * `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`,\n         * `moveTabToNewWindow` or `windowMenu`\n         */\n        role?:\n            | \"undo\"\n            | \"redo\"\n            | \"cut\"\n            | \"copy\"\n            | \"paste\"\n            | \"pasteAndMatchStyle\"\n            | \"delete\"\n            | \"selectAll\"\n            | \"reload\"\n            | \"forceReload\"\n            | \"toggleDevTools\"\n            | \"resetZoom\"\n            | \"zoomIn\"\n            | \"zoomOut\"\n            | \"toggleSpellChecker\"\n            | \"togglefullscreen\"\n            | \"window\"\n            | \"minimize\"\n            | \"close\"\n            | \"help\"\n            | \"about\"\n            | \"services\"\n            | \"hide\"\n            | \"hideOthers\"\n            | \"unhide\"\n            | \"quit\"\n            | \"startSpeaking\"\n            | \"stopSpeaking\"\n            | \"zoom\"\n            | \"front\"\n            | \"appMenu\"\n            | \"fileMenu\"\n            | \"editMenu\"\n            | \"viewMenu\"\n            | \"shareMenu\"\n            | \"recentDocuments\"\n            | \"toggleTabBar\"\n            | \"selectNextTab\"\n            | \"selectPreviousTab\"\n            | \"mergeAllWindows\"\n            | \"clearRecentDocuments\"\n            | \"moveTabToNewWindow\"\n            | \"windowMenu\";\n        /**\n         * A `SharingItem` indicating the item to share when the `role` is `shareMenu`.\n         *\n         * This property can be dynamically changed.\n         *\n         * @platform darwin\n         */\n        sharingItem: SharingItem;\n        /**\n         * A `string` indicating the item's sublabel.\n         */\n        sublabel: string;\n        /**\n         * A `Menu` (optional) containing the menu item's submenu, if present.\n         */\n        submenu?: Menu;\n        /**\n         * A `string` indicating the item's hover text.\n         *\n         * @platform darwin\n         */\n        toolTip: string;\n        /**\n         * A `string` indicating the type of the item. Can be `normal`, `separator`,\n         * `submenu`, `checkbox` or `radio`.\n         */\n        type: \"normal\" | \"separator\" | \"submenu\" | \"checkbox\" | \"radio\";\n        /**\n         * An `Accelerator | null` indicating the item's user-assigned accelerator for the\n         * menu item.\n         *\n         * **Note:** This property is only initialized after the `MenuItem` has been added\n         * to a `Menu`. Either via `Menu.buildFromTemplate` or via\n         * `Menu.append()/insert()`.  Accessing before initialization will just return\n         * `null`.\n         *\n         * @platform darwin\n         */\n        readonly userAccelerator: Accelerator | null;\n        /**\n         * A `boolean` indicating whether the item is visible, this property can be\n         * dynamically changed.\n         */\n        visible: boolean;\n    }\n\n    class MessageChannelMain extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/message-channel-main\n\n        /**\n         * A `MessagePortMain` property.\n         */\n        port1: MessagePortMain;\n        /**\n         * A `MessagePortMain` property.\n         */\n        port2: MessagePortMain;\n    }\n\n    class MessagePortMain extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/message-port-main\n\n        /**\n         * Emitted when the remote end of a MessagePortMain object becomes disconnected.\n         */\n        on(event: \"close\", listener: Function): this;\n        once(event: \"close\", listener: Function): this;\n        addListener(event: \"close\", listener: Function): this;\n        removeListener(event: \"close\", listener: Function): this;\n        /**\n         * Emitted when a MessagePortMain object receives a message.\n         */\n        on(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        once(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        addListener(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        removeListener(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        /**\n         * Disconnects the port, so it is no longer active.\n         */\n        close(): void;\n        /**\n         * Sends a message from the port, and optionally, transfers ownership of objects to\n         * other browsing contexts.\n         */\n        postMessage(message: any, transfer?: MessagePortMain[]): void;\n        /**\n         * Starts the sending of messages queued on the port. Messages will be queued until\n         * this method is called.\n         */\n        start(): void;\n    }\n\n    interface MimeTypedBuffer {\n        // Docs: https://electronjs.org/docs/api/structures/mime-typed-buffer\n\n        /**\n         * Charset of the buffer.\n         */\n        charset?: string;\n        /**\n         * The actual Buffer content.\n         */\n        data: Buffer;\n        /**\n         * MIME type of the buffer.\n         */\n        mimeType?: string;\n    }\n\n    interface MouseInputEvent extends InputEvent {\n        // Docs: https://electronjs.org/docs/api/structures/mouse-input-event\n\n        /**\n         * The button pressed, can be `left`, `middle`, `right`.\n         */\n        button?: \"left\" | \"middle\" | \"right\";\n        clickCount?: number;\n        globalX?: number;\n        globalY?: number;\n        movementX?: number;\n        movementY?: number;\n        /**\n         * The type of the event, can be `mouseDown`, `mouseUp`, `mouseEnter`,\n         * `mouseLeave`, `contextMenu`, `mouseWheel` or `mouseMove`.\n         */\n        type: \"mouseDown\" | \"mouseUp\" | \"mouseEnter\" | \"mouseLeave\" | \"contextMenu\" | \"mouseWheel\" | \"mouseMove\";\n        x: number;\n        y: number;\n    }\n\n    interface MouseWheelInputEvent extends MouseInputEvent {\n        // Docs: https://electronjs.org/docs/api/structures/mouse-wheel-input-event\n\n        accelerationRatioX?: number;\n        accelerationRatioY?: number;\n        canScroll?: boolean;\n        deltaX?: number;\n        deltaY?: number;\n        hasPreciseScrollingDeltas?: boolean;\n        /**\n         * The type of the event, can be `mouseWheel`.\n         */\n        type: \"mouseWheel\";\n        wheelTicksX?: number;\n        wheelTicksY?: number;\n    }\n\n    class NativeImage {\n        // Docs: https://electronjs.org/docs/api/native-image\n\n        /**\n         * Creates an empty `NativeImage` instance.\n         */\n        static createEmpty(): NativeImage;\n        /**\n         * Creates a new `NativeImage` instance from `buffer` that contains the raw bitmap\n         * pixel data returned by `toBitmap()`. The specific format is platform-dependent.\n         */\n        static createFromBitmap(buffer: Buffer, options: CreateFromBitmapOptions): NativeImage;\n        /**\n         * Creates a new `NativeImage` instance from `buffer`. Tries to decode as PNG or\n         * JPEG first.\n         */\n        static createFromBuffer(buffer: Buffer, options?: CreateFromBufferOptions): NativeImage;\n        /**\n         * Creates a new `NativeImage` instance from `dataURL`.\n         */\n        static createFromDataURL(dataURL: string): NativeImage;\n        /**\n         * Creates a new `NativeImage` instance from the NSImage that maps to the given\n         * image name. See `System Icons` for a list of possible values.\n         *\n         * The `hslShift` is applied to the image with the following rules:\n         *\n         * * `hsl_shift[0]` (hue): The absolute hue value for the image - 0 and 1 map to 0\n         * and 360 on the hue color wheel (red).\n         * * `hsl_shift[1]` (saturation): A saturation shift for the image, with the\n         * following key values: 0 = remove all color. 0.5 = leave unchanged. 1 = fully\n         * saturate the image.\n         * * `hsl_shift[2]` (lightness): A lightness shift for the image, with the\n         * following key values: 0 = remove all lightness (make all pixels black). 0.5 =\n         * leave unchanged. 1 = full lightness (make all pixels white).\n         *\n         * This means that `[-1, 0, 1]` will make the image completely white and `[-1, 1,\n         * 0]` will make the image completely black.\n         *\n         * In some cases, the `NSImageName` doesn't match its string representation; one\n         * example of this is `NSFolderImageName`, whose string representation would\n         * actually be `NSFolder`. Therefore, you'll need to determine the correct string\n         * representation for your image before passing it in. This can be done with the\n         * following:\n         *\n         * `echo -e '#import <Cocoa/Cocoa.h>\\nint main() { NSLog(@\"%@\", SYSTEM_IMAGE_NAME);\n         * }' | clang -otest -x objective-c -framework Cocoa - && ./test`\n         *\n         * where `SYSTEM_IMAGE_NAME` should be replaced with any value from this list.\n         *\n         * @platform darwin\n         */\n        static createFromNamedImage(imageName: string, hslShift?: number[]): NativeImage;\n        /**\n         * Creates a new `NativeImage` instance from a file located at `path`. This method\n         * returns an empty image if the `path` does not exist, cannot be read, or is not a\n         * valid image.\n         */\n        static createFromPath(path: string): NativeImage;\n        /**\n         * fulfilled with the file's thumbnail preview image, which is a NativeImage.\n         *\n         * Note: The Windows implementation will ignore `size.height` and scale the height\n         * according to `size.width`.\n         *\n         * @platform darwin,win32\n         */\n        static createThumbnailFromPath(path: string, size: Size): Promise<Electron.NativeImage>;\n        /**\n         * Add an image representation for a specific scale factor. This can be used to\n         * explicitly add different scale factor representations to an image. This can be\n         * called on empty images.\n         */\n        addRepresentation(options: AddRepresentationOptions): void;\n        /**\n         * The cropped image.\n         */\n        crop(rect: Rectangle): NativeImage;\n        /**\n         * The image's aspect ratio.\n         *\n         * If `scaleFactor` is passed, this will return the aspect ratio corresponding to\n         * the image representation most closely matching the passed value.\n         */\n        getAspectRatio(scaleFactor?: number): number;\n        /**\n         * A Buffer that contains the image's raw bitmap pixel data.\n         *\n         * The difference between `getBitmap()` and `toBitmap()` is that `getBitmap()` does\n         * not copy the bitmap data, so you have to use the returned Buffer immediately in\n         * current event loop tick; otherwise the data might be changed or destroyed.\n         */\n        getBitmap(options?: BitmapOptions): Buffer;\n        /**\n         * A Buffer that stores C pointer to underlying native handle of the image. On\n         * macOS, a pointer to `NSImage` instance would be returned.\n         *\n         * Notice that the returned pointer is a weak pointer to the underlying native\n         * image instead of a copy, so you _must_ ensure that the associated `nativeImage`\n         * instance is kept around.\n         *\n         * @platform darwin\n         */\n        getNativeHandle(): Buffer;\n        /**\n         * An array of all scale factors corresponding to representations for a given\n         * nativeImage.\n         */\n        getScaleFactors(): number[];\n        /**\n         * If `scaleFactor` is passed, this will return the size corresponding to the image\n         * representation most closely matching the passed value.\n         */\n        getSize(scaleFactor?: number): Size;\n        /**\n         * Whether the image is empty.\n         */\n        isEmpty(): boolean;\n        /**\n         * Whether the image is a template image.\n         */\n        isTemplateImage(): boolean;\n        /**\n         * The resized image.\n         *\n         * If only the `height` or the `width` are specified then the current aspect ratio\n         * will be preserved in the resized image.\n         */\n        resize(options: ResizeOptions): NativeImage;\n        /**\n         * Marks the image as a template image.\n         */\n        setTemplateImage(option: boolean): void;\n        /**\n         * A Buffer that contains a copy of the image's raw bitmap pixel data.\n         */\n        toBitmap(options?: ToBitmapOptions): Buffer;\n        /**\n         * The data URL of the image.\n         */\n        toDataURL(options?: ToDataURLOptions): string;\n        /**\n         * A Buffer that contains the image's `JPEG` encoded data.\n         */\n        toJPEG(quality: number): Buffer;\n        /**\n         * A Buffer that contains the image's `PNG` encoded data.\n         */\n        toPNG(options?: ToPNGOptions): Buffer;\n        /**\n         * A `boolean` property that determines whether the image is considered a template\n         * image.\n         *\n         * Please note that this property only has an effect on macOS.\n         *\n         * @platform darwin\n         */\n        isMacTemplateImage: boolean;\n    }\n\n    interface NativeTheme extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/native-theme\n\n        /**\n         * Emitted when something in the underlying NativeTheme has changed. This normally\n         * means that either the value of `shouldUseDarkColors`,\n         * `shouldUseHighContrastColors` or `shouldUseInvertedColorScheme` has changed. You\n         * will have to check them to determine which one has changed.\n         */\n        on(event: \"updated\", listener: Function): this;\n        once(event: \"updated\", listener: Function): this;\n        addListener(event: \"updated\", listener: Function): this;\n        removeListener(event: \"updated\", listener: Function): this;\n        /**\n         * A `boolean` indicating whether Chromium is in forced colors mode, controlled by\n         * system accessibility settings. Currently, Windows high contrast is the only\n         * system setting that triggers forced colors mode.\n         *\n         * @platform win32\n         */\n        readonly inForcedColorsMode: boolean;\n        /**\n         * A `boolean` for if the OS / Chromium currently has a dark mode enabled or is\n         * being instructed to show a dark-style UI.  If you want to modify this value you\n         * should use `themeSource` below.\n         *\n         */\n        readonly shouldUseDarkColors: boolean;\n        /**\n         * A `boolean` for if the OS / Chromium currently has high-contrast mode enabled or\n         * is being instructed to show a high-contrast UI.\n         *\n         * @platform darwin,win32\n         */\n        readonly shouldUseHighContrastColors: boolean;\n        /**\n         * A `boolean` for if the OS / Chromium currently has an inverted color scheme or\n         * is being instructed to use an inverted color scheme.\n         *\n         * @platform darwin,win32\n         */\n        readonly shouldUseInvertedColorScheme: boolean;\n        /**\n         * A `string` property that can be `system`, `light` or `dark`.  It is used to\n         * override and supersede the value that Chromium has chosen to use internally.\n         *\n         * Setting this property to `system` will remove the override and everything will\n         * be reset to the OS default.  By default `themeSource` is `system`.\n         *\n         * Settings this property to `dark` will have the following effects:\n         *\n         * * `nativeTheme.shouldUseDarkColors` will be `true` when accessed\n         * * Any UI Electron renders on Linux and Windows including context menus,\n         * devtools, etc. will use the dark UI.\n         * * Any UI the OS renders on macOS including menus, window frames, etc. will use\n         * the dark UI.\n         * * The `prefers-color-scheme` CSS query will match `dark` mode.\n         * * The `updated` event will be emitted\n         *\n         * Settings this property to `light` will have the following effects:\n         *\n         * * `nativeTheme.shouldUseDarkColors` will be `false` when accessed\n         * * Any UI Electron renders on Linux and Windows including context menus,\n         * devtools, etc. will use the light UI.\n         * * Any UI the OS renders on macOS including menus, window frames, etc. will use\n         * the light UI.\n         * * The `prefers-color-scheme` CSS query will match `light` mode.\n         * * The `updated` event will be emitted\n         *\n         * The usage of this property should align with a classic \"dark mode\" state machine\n         * in your application where the user has three options.\n         *\n         * * `Follow OS` --> `themeSource = 'system'`\n         * * `Dark Mode` --> `themeSource = 'dark'`\n         * * `Light Mode` --> `themeSource = 'light'`\n         *\n         * Your application should then always use `shouldUseDarkColors` to determine what\n         * CSS to apply.\n         */\n        themeSource: \"system\" | \"light\" | \"dark\";\n    }\n\n    interface Net {\n        // Docs: https://electronjs.org/docs/api/net\n\n        /**\n         * see Response.\n         *\n         * Sends a request, similarly to how `fetch()` works in the renderer, using\n         * Chrome's network stack. This differs from Node's `fetch()`, which uses Node.js's\n         * HTTP stack.\n         *\n         * Example:\n         *\n         * This method will issue requests from the default session. To send a `fetch`\n         * request from another session, use ses.fetch().\n         *\n         * See the MDN documentation for `fetch()` for more details.\n         *\n         * Limitations:\n         *\n         * * `net.fetch()` does not support the `data:` or `blob:` schemes.\n         * * The value of the `integrity` option is ignored.\n         * * The `.type` and `.url` values of the returned `Response` object are incorrect.\n         *\n         * By default, requests made with `net.fetch` can be made to custom protocols as\n         * well as `file:`, and will trigger webRequest handlers if present. When the\n         * non-standard `bypassCustomProtocolHandlers` option is set in RequestInit, custom\n         * protocol handlers will not be called for this request. This allows forwarding an\n         * intercepted request to the built-in handler. webRequest handlers will still be\n         * triggered when bypassing custom protocols.\n         */\n        fetch(input: string | GlobalRequest, init?: RequestInit & { bypassCustomProtocolHandlers?: boolean }): Promise<GlobalResponse>;\n        /**\n         * Whether there is currently internet connection.\n         *\n         * A return value of `false` is a pretty strong indicator that the user won't be\n         * able to connect to remote sites. However, a return value of `true` is\n         * inconclusive; even if some link is up, it is uncertain whether a particular\n         * connection attempt to a particular remote site will be successful.\n         */\n        isOnline(): boolean;\n        /**\n         * Creates a `ClientRequest` instance using the provided `options` which are\n         * directly forwarded to the `ClientRequest` constructor. The `net.request` method\n         * would be used to issue both secure and insecure HTTP requests according to the\n         * specified protocol scheme in the `options` object.\n         */\n        request(options: ClientRequestConstructorOptions | string): ClientRequest;\n        /**\n         * Resolves with the resolved IP addresses for the `host`.\n         *\n         * This method will resolve hosts from the default session. To resolve a host from\n         * another session, use ses.resolveHost().\n         */\n        resolveHost(host: string, options?: ResolveHostOptions): Promise<Electron.ResolvedHost>;\n        /**\n         * A `boolean` property. Whether there is currently internet connection.\n         *\n         * A return value of `false` is a pretty strong indicator that the user won't be\n         * able to connect to remote sites. However, a return value of `true` is\n         * inconclusive; even if some link is up, it is uncertain whether a particular\n         * connection attempt to a particular remote site will be successful.\n         *\n         */\n        readonly online: boolean;\n    }\n\n    interface NetLog {\n        // Docs: https://electronjs.org/docs/api/net-log\n\n        /**\n         * resolves when the net log has begun recording.\n         *\n         * Starts recording network events to `path`.\n         */\n        startLogging(path: string, options?: StartLoggingOptions): Promise<void>;\n        /**\n         * resolves when the net log has been flushed to disk.\n         *\n         * Stops recording network events. If not called, net logging will automatically\n         * end when app quits.\n         */\n        stopLogging(): Promise<void>;\n        /**\n         * A `boolean` property that indicates whether network logs are currently being\n         * recorded.\n         *\n         */\n        readonly currentlyLogging: boolean;\n    }\n\n    class Notification extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/notification\n\n        /**\n         * @platform darwin\n         */\n        on(\n            event: \"action\",\n            listener: (\n                event: Event,\n                /**\n                 * The index of the action that was activated.\n                 */\n                index: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"action\",\n            listener: (\n                event: Event,\n                /**\n                 * The index of the action that was activated.\n                 */\n                index: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"action\",\n            listener: (\n                event: Event,\n                /**\n                 * The index of the action that was activated.\n                 */\n                index: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"action\",\n            listener: (\n                event: Event,\n                /**\n                 * The index of the action that was activated.\n                 */\n                index: number,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the notification is clicked by the user.\n         */\n        on(event: \"click\", listener: (event: Event) => void): this;\n        once(event: \"click\", listener: (event: Event) => void): this;\n        addListener(event: \"click\", listener: (event: Event) => void): this;\n        removeListener(event: \"click\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when the notification is closed by manual intervention from the user.\n         *\n         * This event is not guaranteed to be emitted in all cases where the notification\n         * is closed.\n         */\n        on(event: \"close\", listener: (event: Event) => void): this;\n        once(event: \"close\", listener: (event: Event) => void): this;\n        addListener(event: \"close\", listener: (event: Event) => void): this;\n        removeListener(event: \"close\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when an error is encountered while creating and showing the native\n         * notification.\n         *\n         * @platform win32\n         */\n        on(\n            event: \"failed\",\n            listener: (\n                event: Event,\n                /**\n                 * The error encountered during execution of the `show()` method.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"failed\",\n            listener: (\n                event: Event,\n                /**\n                 * The error encountered during execution of the `show()` method.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"failed\",\n            listener: (\n                event: Event,\n                /**\n                 * The error encountered during execution of the `show()` method.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"failed\",\n            listener: (\n                event: Event,\n                /**\n                 * The error encountered during execution of the `show()` method.\n                 */\n                error: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the user clicks the \"Reply\" button on a notification with\n         * `hasReply: true`.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"reply\",\n            listener: (\n                event: Event,\n                /**\n                 * The string the user entered into the inline reply field.\n                 */\n                reply: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"reply\",\n            listener: (\n                event: Event,\n                /**\n                 * The string the user entered into the inline reply field.\n                 */\n                reply: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"reply\",\n            listener: (\n                event: Event,\n                /**\n                 * The string the user entered into the inline reply field.\n                 */\n                reply: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"reply\",\n            listener: (\n                event: Event,\n                /**\n                 * The string the user entered into the inline reply field.\n                 */\n                reply: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the notification is shown to the user. Note that this event can be\n         * fired multiple times as a notification can be shown multiple times through the\n         * `show()` method.\n         */\n        on(event: \"show\", listener: (event: Event) => void): this;\n        once(event: \"show\", listener: (event: Event) => void): this;\n        addListener(event: \"show\", listener: (event: Event) => void): this;\n        removeListener(event: \"show\", listener: (event: Event) => void): this;\n        /**\n         * Notification\n         */\n        constructor(options?: NotificationConstructorOptions);\n        /**\n         * Whether or not desktop notifications are supported on the current system\n         */\n        static isSupported(): boolean;\n        /**\n         * Dismisses the notification.\n         */\n        close(): void;\n        /**\n         * Immediately shows the notification to the user. Unlike the web notification API,\n         * instantiating a `new Notification()` does not immediately show it to the user.\n         * Instead, you need to call this method before the OS will display it.\n         *\n         * If the notification has been shown before, this method will dismiss the\n         * previously shown notification and create a new one with identical properties.\n         */\n        show(): void;\n        /**\n         * A `NotificationAction[]` property representing the actions of the notification.\n         */\n        actions: NotificationAction[];\n        /**\n         * A `string` property representing the body of the notification.\n         */\n        body: string;\n        /**\n         * A `string` property representing the close button text of the notification.\n         */\n        closeButtonText: string;\n        /**\n         * A `boolean` property representing whether the notification has a reply action.\n         */\n        hasReply: boolean;\n        /**\n         * A `string` property representing the reply placeholder of the notification.\n         */\n        replyPlaceholder: string;\n        /**\n         * A `boolean` property representing whether the notification is silent.\n         */\n        silent: boolean;\n        /**\n         * A `string` property representing the sound of the notification.\n         */\n        sound: string;\n        /**\n         * A `string` property representing the subtitle of the notification.\n         */\n        subtitle: string;\n        /**\n         * A `string` property representing the type of timeout duration for the\n         * notification. Can be 'default' or 'never'.\n         *\n         * If `timeoutType` is set to 'never', the notification never expires. It stays\n         * open until closed by the calling API or the user.\n         *\n         * @platform linux,win32\n         */\n        timeoutType: \"default\" | \"never\";\n        /**\n         * A `string` property representing the title of the notification.\n         */\n        title: string;\n        /**\n         * A `string` property representing the custom Toast XML of the notification.\n         *\n         * @platform win32\n         */\n        toastXml: string;\n        /**\n         * A `string` property representing the urgency level of the notification. Can be\n         * 'normal', 'critical', or 'low'.\n         *\n         * Default is 'low' - see NotifyUrgency for more information.\n         *\n         * @platform linux\n         */\n        urgency: \"normal\" | \"critical\" | \"low\";\n    }\n\n    interface NotificationAction {\n        // Docs: https://electronjs.org/docs/api/structures/notification-action\n\n        /**\n         * The label for the given action.\n         */\n        text?: string;\n        /**\n         * The type of action, can be `button`.\n         */\n        type: \"button\";\n    }\n\n    interface NotificationResponse {\n        // Docs: https://electronjs.org/docs/api/structures/notification-response\n\n        /**\n         * The identifier string of the action that the user selected.\n         */\n        actionIdentifier: string;\n        /**\n         * The delivery date of the notification.\n         */\n        date: number;\n        /**\n         * The unique identifier for this notification request.\n         */\n        identifier: string;\n        /**\n         * A dictionary of custom information associated with the notification.\n         */\n        userInfo: Record<string, any>;\n        /**\n         * The text entered or chosen by the user.\n         */\n        userText?: string;\n    }\n\n    interface ParentPort extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/parent-port\n\n        /**\n         * Emitted when the process receives a message. Messages received on this port will\n         * be queued up until a handler is registered for this event.\n         */\n        on(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        once(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        addListener(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        removeListener(event: \"message\", listener: (messageEvent: MessageEvent) => void): this;\n        /**\n         * Sends a message from the process to its parent.\n         */\n        postMessage(message: any): void;\n    }\n\n    interface PaymentDiscount {\n        // Docs: https://electronjs.org/docs/api/structures/payment-discount\n\n        /**\n         * A string used to uniquely identify a discount offer for a product.\n         */\n        identifier: string;\n        /**\n         * A string that identifies the key used to generate the signature.\n         */\n        keyIdentifier: string;\n        /**\n         * A universally unique ID (UUID) value that you define.\n         */\n        nonce: string;\n        /**\n         * A UTF-8 string representing the properties of a specific discount offer,\n         * cryptographically signed.\n         */\n        signature: string;\n        /**\n         * The date and time of the signature's creation in milliseconds, formatted in Unix\n         * epoch time.\n         */\n        timestamp: number;\n    }\n\n    interface Point {\n        // Docs: https://electronjs.org/docs/api/structures/point\n\n        x: number;\n        y: number;\n    }\n\n    interface PostBody {\n        // Docs: https://electronjs.org/docs/api/structures/post-body\n\n        /**\n         * The boundary used to separate multiple parts of the message. Only valid when\n         * `contentType` is `multipart/form-data`.\n         */\n        boundary?: string;\n        /**\n         * The `content-type` header used for the data. One of\n         * `application/x-www-form-urlencoded` or `multipart/form-data`. Corresponds to the\n         * `enctype` attribute of the submitted HTML form.\n         */\n        contentType: string;\n        /**\n         * The post data to be sent to the new window.\n         */\n        data: Array<UploadRawData | UploadFile>;\n    }\n\n    interface PowerMonitor extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/power-monitor\n\n        /**\n         * Emitted when the system is about to lock the screen.\n         *\n         * @platform darwin,win32\n         */\n        on(event: \"lock-screen\", listener: Function): this;\n        once(event: \"lock-screen\", listener: Function): this;\n        addListener(event: \"lock-screen\", listener: Function): this;\n        removeListener(event: \"lock-screen\", listener: Function): this;\n        /**\n         * Emitted when the system changes to AC power.\n         *\n         * @platform darwin,win32\n         */\n        on(event: \"on-ac\", listener: Function): this;\n        once(event: \"on-ac\", listener: Function): this;\n        addListener(event: \"on-ac\", listener: Function): this;\n        removeListener(event: \"on-ac\", listener: Function): this;\n        /**\n         * Emitted when system changes to battery power.\n         *\n         * @platform darwin\n         */\n        on(event: \"on-battery\", listener: Function): this;\n        once(event: \"on-battery\", listener: Function): this;\n        addListener(event: \"on-battery\", listener: Function): this;\n        removeListener(event: \"on-battery\", listener: Function): this;\n        /**\n         * Emitted when system is resuming.\n         */\n        on(event: \"resume\", listener: Function): this;\n        once(event: \"resume\", listener: Function): this;\n        addListener(event: \"resume\", listener: Function): this;\n        removeListener(event: \"resume\", listener: Function): this;\n        /**\n         * Emitted when the system is about to reboot or shut down. If the event handler\n         * invokes `e.preventDefault()`, Electron will attempt to delay system shutdown in\n         * order for the app to exit cleanly. If `e.preventDefault()` is called, the app\n         * should exit as soon as possible by calling something like `app.quit()`.\n         *\n         * @platform linux,darwin\n         */\n        on(event: \"shutdown\", listener: Function): this;\n        once(event: \"shutdown\", listener: Function): this;\n        addListener(event: \"shutdown\", listener: Function): this;\n        removeListener(event: \"shutdown\", listener: Function): this;\n        /**\n         * Notification of a change in the operating system's advertised speed limit for\n         * CPUs, in percent. Values below 100 indicate that the system is impairing\n         * processing power due to thermal management.\n         *\n         * @platform darwin,win32\n         */\n        on(event: \"speed-limit-change\", listener: Function): this;\n        once(event: \"speed-limit-change\", listener: Function): this;\n        addListener(event: \"speed-limit-change\", listener: Function): this;\n        removeListener(event: \"speed-limit-change\", listener: Function): this;\n        /**\n         * Emitted when the system is suspending.\n         */\n        on(event: \"suspend\", listener: Function): this;\n        once(event: \"suspend\", listener: Function): this;\n        addListener(event: \"suspend\", listener: Function): this;\n        removeListener(event: \"suspend\", listener: Function): this;\n        /**\n         * Emitted when the thermal state of the system changes. Notification of a change\n         * in the thermal status of the system, such as entering a critical temperature\n         * range. Depending on the severity, the system might take steps to reduce said\n         * temperature, for example, throttling the CPU or switching on the fans if\n         * available.\n         *\n         * Apps may react to the new state by reducing expensive computing tasks (e.g.\n         * video encoding), or notifying the user. The same state might be received\n         * repeatedly.\n         *\n         * See\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         * nce/Conceptual/power_efficiency_guidelines_osx/RespondToThermalStateChanges.html\n         *\n         * @platform darwin\n         */\n        on(event: \"thermal-state-change\", listener: Function): this;\n        once(event: \"thermal-state-change\", listener: Function): this;\n        addListener(event: \"thermal-state-change\", listener: Function): this;\n        removeListener(event: \"thermal-state-change\", listener: Function): this;\n        /**\n         * Emitted as soon as the systems screen is unlocked.\n         *\n         * @platform darwin,win32\n         */\n        on(event: \"unlock-screen\", listener: Function): this;\n        once(event: \"unlock-screen\", listener: Function): this;\n        addListener(event: \"unlock-screen\", listener: Function): this;\n        removeListener(event: \"unlock-screen\", listener: Function): this;\n        /**\n         * Emitted when a login session is activated. See documentation for more\n         * information.\n         *\n         * @platform darwin\n         */\n        on(event: \"user-did-become-active\", listener: Function): this;\n        once(event: \"user-did-become-active\", listener: Function): this;\n        addListener(event: \"user-did-become-active\", listener: Function): this;\n        removeListener(event: \"user-did-become-active\", listener: Function): this;\n        /**\n         * Emitted when a login session is deactivated. See documentation for more\n         * information.\n         *\n         * @platform darwin\n         */\n        on(event: \"user-did-resign-active\", listener: Function): this;\n        once(event: \"user-did-resign-active\", listener: Function): this;\n        addListener(event: \"user-did-resign-active\", listener: Function): this;\n        removeListener(event: \"user-did-resign-active\", listener: Function): this;\n        /**\n         * The system's current thermal state. Can be `unknown`, `nominal`, `fair`,\n         * `serious`, or `critical`.\n         *\n         * @platform darwin\n         */\n        getCurrentThermalState(): \"unknown\" | \"nominal\" | \"fair\" | \"serious\" | \"critical\";\n        /**\n         * The system's current idle state. Can be `active`, `idle`, `locked` or `unknown`.\n         *\n         * Calculate the system idle state. `idleThreshold` is the amount of time (in\n         * seconds) before considered idle.  `locked` is available on supported systems\n         * only.\n         */\n        getSystemIdleState(idleThreshold: number): \"active\" | \"idle\" | \"locked\" | \"unknown\";\n        /**\n         * Idle time in seconds\n         *\n         * Calculate system idle time in seconds.\n         */\n        getSystemIdleTime(): number;\n        /**\n         * Whether the system is on battery power.\n         *\n         * To monitor for changes in this property, use the `on-battery` and `on-ac`\n         * events.\n         */\n        isOnBatteryPower(): boolean;\n        /**\n         * A `boolean` property. True if the system is on battery power.\n         *\n         * See `powerMonitor.isOnBatteryPower()`.\n         */\n        onBatteryPower: boolean;\n    }\n\n    interface PowerSaveBlocker {\n        // Docs: https://electronjs.org/docs/api/power-save-blocker\n\n        /**\n         * Whether the corresponding `powerSaveBlocker` has started.\n         */\n        isStarted(id: number): boolean;\n        /**\n         * The blocker ID that is assigned to this power blocker.\n         *\n         * Starts preventing the system from entering lower-power mode. Returns an integer\n         * identifying the power save blocker.\n         *\n         * **Note:** `prevent-display-sleep` has higher precedence over\n         * `prevent-app-suspension`. Only the highest precedence type takes effect. In\n         * other words, `prevent-display-sleep` always takes precedence over\n         * `prevent-app-suspension`.\n         *\n         * For example, an API calling A requests for `prevent-app-suspension`, and another\n         * calling B requests for `prevent-display-sleep`. `prevent-display-sleep` will be\n         * used until B stops its request. After that, `prevent-app-suspension` is used.\n         */\n        start(type: \"prevent-app-suspension\" | \"prevent-display-sleep\"): number;\n        /**\n         * Stops the specified power save blocker.\n         */\n        stop(id: number): void;\n    }\n\n    interface PrinterInfo {\n        // Docs: https://electronjs.org/docs/api/structures/printer-info\n\n        /**\n         * a longer description of the printer's type.\n         */\n        description: string;\n        /**\n         * the name of the printer as shown in Print Preview.\n         */\n        displayName: string;\n        /**\n         * whether or not a given printer is set as the default printer on the OS.\n         */\n        isDefault: boolean;\n        /**\n         * the name of the printer as understood by the OS.\n         */\n        name: string;\n        /**\n         * an object containing a variable number of platform-specific printer information.\n         */\n        options: Options;\n        /**\n         * the current status of the printer.\n         */\n        status: number;\n    }\n\n    interface ProcessMemoryInfo {\n        // Docs: https://electronjs.org/docs/api/structures/process-memory-info\n\n        /**\n         * The amount of memory not shared by other processes, such as JS heap or HTML\n         * content in Kilobytes.\n         */\n        private: number;\n        /**\n         * The amount of memory currently pinned to actual physical RAM in Kilobytes.\n         *\n         * @platform linux,win32\n         */\n        residentSet: number;\n        /**\n         * The amount of memory shared between processes, typically memory consumed by the\n         * Electron code itself in Kilobytes.\n         */\n        shared: number;\n    }\n\n    interface ProcessMetric {\n        // Docs: https://electronjs.org/docs/api/structures/process-metric\n\n        /**\n         * CPU usage of the process.\n         */\n        cpu: CPUUsage;\n        /**\n         * Creation time for this process. The time is represented as number of\n         * milliseconds since epoch. Since the `pid` can be reused after a process dies, it\n         * is useful to use both the `pid` and the `creationTime` to uniquely identify a\n         * process.\n         */\n        creationTime: number;\n        /**\n         * One of the following values:\n         *\n         * @platform win32\n         */\n        integrityLevel?: \"untrusted\" | \"low\" | \"medium\" | \"high\" | \"unknown\";\n        /**\n         * Memory information for the process.\n         */\n        memory: MemoryInfo;\n        /**\n         * The name of the process. Examples for utility: `Audio Service`, `Content\n         * Decryption Module Service`, `Network Service`, `Video Capture`, etc.\n         */\n        name?: string;\n        /**\n         * Process id of the process.\n         */\n        pid: number;\n        /**\n         * Whether the process is sandboxed on OS level.\n         *\n         * @platform darwin,win32\n         */\n        sandboxed?: boolean;\n        /**\n         * The non-localized name of the process.\n         */\n        serviceName?: string;\n        /**\n         * Process type. One of the following values:\n         */\n        type: \"Browser\" | \"Tab\" | \"Utility\" | \"Zygote\" | \"Sandbox helper\" | \"GPU\" | \"Pepper Plugin\" | \"Pepper Plugin Broker\" | \"Unknown\";\n    }\n\n    interface Product {\n        // Docs: https://electronjs.org/docs/api/structures/product\n\n        /**\n         * The total size of the content, in bytes.\n         */\n        contentLengths: number[];\n        /**\n         * A string that identifies the version of the content.\n         */\n        contentVersion: string;\n        /**\n         * 3 character code presenting a product's currency based on the ISO 4217 standard.\n         */\n        currencyCode: string;\n        /**\n         * An array of discount offers\n         */\n        discounts: ProductDiscount[];\n        /**\n         * The total size of the content, in bytes.\n         */\n        downloadContentLengths: number[];\n        /**\n         * A string that identifies the version of the content.\n         */\n        downloadContentVersion: string;\n        /**\n         * The locale formatted price of the product.\n         */\n        formattedPrice: string;\n        /**\n         * The object containing introductory price information for the product. available\n         * for the product.\n         */\n        introductoryPrice?: ProductDiscount;\n        /**\n         * A boolean value that indicates whether the App Store has downloadable content\n         * for this product. `true` if at least one file has been associated with the\n         * product.\n         */\n        isDownloadable: boolean;\n        /**\n         * A description of the product.\n         */\n        localizedDescription: string;\n        /**\n         * The name of the product.\n         */\n        localizedTitle: string;\n        /**\n         * The cost of the product in the local currency.\n         */\n        price: number;\n        /**\n         * The string that identifies the product to the Apple App Store.\n         */\n        productIdentifier: string;\n        /**\n         * The identifier of the subscription group to which the subscription belongs.\n         */\n        subscriptionGroupIdentifier: string;\n        /**\n         * The period details for products that are subscriptions.\n         */\n        subscriptionPeriod?: ProductSubscriptionPeriod;\n    }\n\n    interface ProductDiscount {\n        // Docs: https://electronjs.org/docs/api/structures/product-discount\n\n        /**\n         * A string used to uniquely identify a discount offer for a product.\n         */\n        identifier: string;\n        /**\n         * An integer that indicates the number of periods the product discount is\n         * available.\n         */\n        numberOfPeriods: number;\n        /**\n         * The payment mode for this product discount. Can be `payAsYouGo`, `payUpFront`,\n         * or `freeTrial`.\n         */\n        paymentMode: \"payAsYouGo\" | \"payUpFront\" | \"freeTrial\";\n        /**\n         * The discount price of the product in the local currency.\n         */\n        price: number;\n        /**\n         * The locale used to format the discount price of the product.\n         */\n        priceLocale: string;\n        /**\n         * An object that defines the period for the product discount.\n         */\n        subscriptionPeriod?: ProductSubscriptionPeriod;\n        /**\n         * The type of discount offer.\n         */\n        type: number;\n    }\n\n    interface ProductSubscriptionPeriod {\n        // Docs: https://electronjs.org/docs/api/structures/product-subscription-period\n\n        /**\n         * The number of units per subscription period.\n         */\n        numberOfUnits: number;\n        /**\n         * The increment of time that a subscription period is specified in. Can be `day`,\n         * `week`, `month`, `year`.\n         */\n        unit: \"day\" | \"week\" | \"month\" | \"year\";\n    }\n\n    interface Protocol {\n        // Docs: https://electronjs.org/docs/api/protocol\n\n        /**\n         * Register a protocol handler for `scheme`. Requests made to URLs with this scheme\n         * will delegate to this handler to determine what response should be sent.\n         *\n         * Either a `Response` or a `Promise<Response>` can be returned.\n         *\n         * Example:\n         *\n         * See the MDN docs for `Request` and `Response` for more details.\n         */\n        handle(scheme: string, handler: (request: GlobalRequest) => GlobalResponse | Promise<GlobalResponse>): void;\n        /**\n         * Whether the protocol was successfully intercepted\n         *\n         * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler\n         * which sends a `Buffer` as a response.\n         *\n         * @deprecated\n         */\n        interceptBufferProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: Buffer | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully intercepted\n         *\n         * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler\n         * which sends a file as a response.\n         *\n         * @deprecated\n         */\n        interceptFileProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: string | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully intercepted\n         *\n         * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler\n         * which sends a new HTTP request as a response.\n         *\n         * @deprecated\n         */\n        interceptHttpProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully intercepted\n         *\n         * Same as `protocol.registerStreamProtocol`, except that it replaces an existing\n         * protocol handler.\n         *\n         * @deprecated\n         */\n        interceptStreamProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: NodeJS.ReadableStream | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully intercepted\n         *\n         * Intercepts `scheme` protocol and uses `handler` as the protocol's new handler\n         * which sends a `string` as a response.\n         *\n         * @deprecated\n         */\n        interceptStringProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: string | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether `scheme` is already handled.\n         */\n        isProtocolHandled(scheme: string): boolean;\n        /**\n         * Whether `scheme` is already intercepted.\n         *\n         * @deprecated\n         */\n        isProtocolIntercepted(scheme: string): boolean;\n        /**\n         * Whether `scheme` is already registered.\n         *\n         * @deprecated\n         */\n        isProtocolRegistered(scheme: string): boolean;\n        /**\n         * Whether the protocol was successfully registered\n         *\n         * Registers a protocol of `scheme` that will send a `Buffer` as a response.\n         *\n         * The usage is the same with `registerFileProtocol`, except that the `callback`\n         * should be called with either a `Buffer` object or an object that has the `data`\n         * property.\n         *\n         * Example:\n         *\n         * @deprecated\n         */\n        registerBufferProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: Buffer | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully registered\n         *\n         * Registers a protocol of `scheme` that will send a file as the response. The\n         * `handler` will be called with `request` and `callback` where `request` is an\n         * incoming request for the `scheme`.\n         *\n         * To handle the `request`, the `callback` should be called with either the file's\n         * path or an object that has a `path` property, e.g. `callback(filePath)` or\n         * `callback({ path: filePath })`. The `filePath` must be an absolute path.\n         *\n         * By default the `scheme` is treated like `http:`, which is parsed differently\n         * from protocols that follow the \"generic URI syntax\" like `file:`.\n         *\n         * @deprecated\n         */\n        registerFileProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: string | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully registered\n         *\n         * Registers a protocol of `scheme` that will send an HTTP request as a response.\n         *\n         * The usage is the same with `registerFileProtocol`, except that the `callback`\n         * should be called with an object that has the `url` property.\n         *\n         * @deprecated\n         */\n        registerHttpProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: ProtocolResponse) => void) => void): boolean;\n        /**\n         * **Note:** This method can only be used before the `ready` event of the `app`\n         * module gets emitted and can be called only once.\n         *\n         * Registers the `scheme` as standard, secure, bypasses content security policy for\n         * resources, allows registering ServiceWorker, supports fetch API, and streaming\n         * video/audio. Specify a privilege with the value of `true` to enable the\n         * capability.\n         *\n         * An example of registering a privileged scheme, that bypasses Content Security\n         * Policy:\n         *\n         * A standard scheme adheres to what RFC 3986 calls generic URI syntax. For example\n         * `http` and `https` are standard schemes, while `file` is not.\n         *\n         * Registering a scheme as standard allows relative and absolute resources to be\n         * resolved correctly when served. Otherwise the scheme will behave like the `file`\n         * protocol, but without the ability to resolve relative URLs.\n         *\n         * For example when you load following page with custom protocol without\n         * registering it as standard scheme, the image will not be loaded because\n         * non-standard schemes can not recognize relative URLs:\n         *\n         * Registering a scheme as standard will allow access to files through the\n         * FileSystem API. Otherwise the renderer will throw a security error for the\n         * scheme.\n         *\n         * By default web storage apis (localStorage, sessionStorage, webSQL, indexedDB,\n         * cookies) are disabled for non standard schemes. So in general if you want to\n         * register a custom protocol to replace the `http` protocol, you have to register\n         * it as a standard scheme.\n         *\n         * Protocols that use streams (http and stream protocols) should set `stream:\n         * true`. The `<video>` and `<audio>` HTML elements expect protocols to buffer\n         * their responses by default. The `stream` flag configures those elements to\n         * correctly expect streaming responses.\n         */\n        registerSchemesAsPrivileged(customSchemes: CustomScheme[]): void;\n        /**\n         * Whether the protocol was successfully registered\n         *\n         * Registers a protocol of `scheme` that will send a stream as a response.\n         *\n         * The usage is the same with `registerFileProtocol`, except that the `callback`\n         * should be called with either a `ReadableStream` object or an object that has the\n         * `data` property.\n         *\n         * Example:\n         *\n         * It is possible to pass any object that implements the readable stream API (emits\n         * `data`/`end`/`error` events). For example, here's how a file could be returned:\n         *\n         * @deprecated\n         */\n        registerStreamProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: NodeJS.ReadableStream | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Whether the protocol was successfully registered\n         *\n         * Registers a protocol of `scheme` that will send a `string` as a response.\n         *\n         * The usage is the same with `registerFileProtocol`, except that the `callback`\n         * should be called with either a `string` or an object that has the `data`\n         * property.\n         *\n         * @deprecated\n         */\n        registerStringProtocol(scheme: string, handler: (request: ProtocolRequest, callback: (response: string | ProtocolResponse) => void) => void): boolean;\n        /**\n         * Removes a protocol handler registered with `protocol.handle`.\n         */\n        unhandle(scheme: string): void;\n        /**\n         * Whether the protocol was successfully unintercepted\n         *\n         * Remove the interceptor installed for `scheme` and restore its original handler.\n         *\n         * @deprecated\n         */\n        uninterceptProtocol(scheme: string): boolean;\n        /**\n         * Whether the protocol was successfully unregistered\n         *\n         * Unregisters the custom protocol of `scheme`.\n         *\n         * @deprecated\n         */\n        unregisterProtocol(scheme: string): boolean;\n    }\n\n    interface ProtocolRequest {\n        // Docs: https://electronjs.org/docs/api/structures/protocol-request\n\n        headers: Record<string, string>;\n        method: string;\n        referrer: string;\n        uploadData?: UploadData[];\n        url: string;\n    }\n\n    interface ProtocolResponse {\n        // Docs: https://electronjs.org/docs/api/structures/protocol-response\n\n        /**\n         * The charset of response body, default is `\"utf-8\"`.\n         */\n        charset?: string;\n        /**\n         * The response body. When returning stream as response, this is a Node.js readable\n         * stream representing the response body. When returning `Buffer` as response, this\n         * is a `Buffer`. When returning `string` as response, this is a `string`. This is\n         * ignored for other types of responses.\n         */\n        data?: Buffer | string | NodeJS.ReadableStream;\n        /**\n         * When assigned, the `request` will fail with the `error` number . For the\n         * available error numbers you can use, please see the net error list.\n         */\n        error?: number;\n        /**\n         * An object containing the response headers. The keys must be string, and values\n         * must be either string or Array of string.\n         */\n        headers?: Record<string, string | string[]>;\n        /**\n         * The HTTP `method`. This is only used for file and URL responses.\n         */\n        method?: string;\n        /**\n         * The MIME type of response body, default is `\"text/html\"`. Setting `mimeType`\n         * would implicitly set the `content-type` header in response, but if\n         * `content-type` is already set in `headers`, the `mimeType` would be ignored.\n         */\n        mimeType?: string;\n        /**\n         * Path to the file which would be sent as response body. This is only used for\n         * file responses.\n         */\n        path?: string;\n        /**\n         * The `referrer` URL. This is only used for file and URL responses.\n         */\n        referrer?: string;\n        /**\n         * The session used for requesting URL, by default the HTTP request will reuse the\n         * current session. Setting `session` to `null` would use a random independent\n         * session. This is only used for URL responses.\n         */\n        session?: Session;\n        /**\n         * The HTTP response code, default is 200.\n         */\n        statusCode?: number;\n        /**\n         * The data used as upload data. This is only used for URL responses when `method`\n         * is `\"POST\"`.\n         */\n        uploadData?: ProtocolResponseUploadData;\n        /**\n         * Download the `url` and pipe the result as response body. This is only used for\n         * URL responses.\n         */\n        url?: string;\n    }\n\n    interface ProtocolResponseUploadData {\n        // Docs: https://electronjs.org/docs/api/structures/protocol-response-upload-data\n\n        /**\n         * MIME type of the content.\n         */\n        contentType: string;\n        /**\n         * Content to be sent.\n         */\n        data: string | Buffer;\n    }\n\n    interface PushNotifications extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/push-notifications\n\n        /**\n         * Emitted when the app receives a remote notification while running. See:\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         * com/documentation/appkit/nsapplicationdelegate/1428430-application?language=objc\n         *\n         * @platform darwin\n         */\n        on(event: \"received-apns-notification\", listener: (event: Event, userInfo: Record<string, any>) => void): this;\n        once(event: \"received-apns-notification\", listener: (event: Event, userInfo: Record<string, any>) => void): this;\n        addListener(event: \"received-apns-notification\", listener: (event: Event, userInfo: Record<string, any>) => void): this;\n        removeListener(event: \"received-apns-notification\", listener: (event: Event, userInfo: Record<string, any>) => void): this;\n        /**\n         * Registers the app with Apple Push Notification service (APNS) to receive Badge,\n         * Sound, and Alert notifications. If registration is successful, the promise will\n         * be resolved with the APNS device token. Otherwise, the promise will be rejected\n         * with an error message. See:\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         * tion/appkit/nsapplication/1428476-registerforremotenotificationtyp?language=objc\n         *\n         * @platform darwin\n         */\n        registerForAPNSNotifications(): Promise<string>;\n        /**\n         * Unregisters the app from notifications received from APNS. See:\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         *\n         * tion/appkit/nsapplication/1428747-unregisterforremotenotifications?language=objc\n         *\n         * @platform darwin\n         */\n        unregisterForAPNSNotifications(): void;\n    }\n\n    interface Rectangle {\n        // Docs: https://electronjs.org/docs/api/structures/rectangle\n\n        /**\n         * The height of the rectangle (must be an integer).\n         */\n        height: number;\n        /**\n         * The width of the rectangle (must be an integer).\n         */\n        width: number;\n        /**\n         * The x coordinate of the origin of the rectangle (must be an integer).\n         */\n        x: number;\n        /**\n         * The y coordinate of the origin of the rectangle (must be an integer).\n         */\n        y: number;\n    }\n\n    interface Referrer {\n        // Docs: https://electronjs.org/docs/api/structures/referrer\n\n        /**\n         * Can be `default`, `unsafe-url`, `no-referrer-when-downgrade`, `no-referrer`,\n         * `origin`, `strict-origin-when-cross-origin`, `same-origin` or `strict-origin`.\n         * See the Referrer-Policy spec for more details on the meaning of these values.\n         */\n        policy: \"default\" | \"unsafe-url\" | \"no-referrer-when-downgrade\" | \"no-referrer\" | \"origin\" | \"strict-origin-when-cross-origin\" | \"same-origin\" | \"strict-origin\";\n        /**\n         * HTTP Referrer URL.\n         */\n        url: string;\n    }\n\n    interface ResolvedEndpoint {\n        // Docs: https://electronjs.org/docs/api/structures/resolved-endpoint\n\n        address: string;\n        /**\n         * One of the following:\n         */\n        family: \"ipv4\" | \"ipv6\" | \"unspec\";\n    }\n\n    interface ResolvedHost {\n        // Docs: https://electronjs.org/docs/api/structures/resolved-host\n\n        /**\n         * resolved DNS entries for the hostname\n         */\n        endpoints: ResolvedEndpoint[];\n    }\n\n    interface SafeStorage extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/safe-storage\n\n        /**\n         * the decrypted string. Decrypts the encrypted buffer obtained  with\n         * `safeStorage.encryptString` back into a string.\n         *\n         * This function will throw an error if decryption fails.\n         */\n        decryptString(encrypted: Buffer): string;\n        /**\n         * An array of bytes representing the encrypted string.\n         *\n         * This function will throw an error if encryption fails.\n         */\n        encryptString(plainText: string): Buffer;\n        /**\n         * Whether encryption is available.\n         *\n         * On Linux, returns true if the app has emitted the `ready` event and the secret\n         * key is available. On MacOS, returns true if Keychain is available. On Windows,\n         * returns true once the app has emitted the `ready` event.\n         */\n        isEncryptionAvailable(): boolean;\n    }\n\n    interface Screen extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/screen\n\n        /**\n         * Emitted when `newDisplay` has been added.\n         */\n        on(event: \"display-added\", listener: (event: Event, newDisplay: Display) => void): this;\n        once(event: \"display-added\", listener: (event: Event, newDisplay: Display) => void): this;\n        addListener(event: \"display-added\", listener: (event: Event, newDisplay: Display) => void): this;\n        removeListener(event: \"display-added\", listener: (event: Event, newDisplay: Display) => void): this;\n        /**\n         * Emitted when one or more metrics change in a `display`. The `changedMetrics` is\n         * an array of strings that describe the changes. Possible changes are `bounds`,\n         * `workArea`, `scaleFactor` and `rotation`.\n         */\n        on(event: \"display-metrics-changed\", listener: (event: Event, display: Display, changedMetrics: string[]) => void): this;\n        once(event: \"display-metrics-changed\", listener: (event: Event, display: Display, changedMetrics: string[]) => void): this;\n        addListener(event: \"display-metrics-changed\", listener: (event: Event, display: Display, changedMetrics: string[]) => void): this;\n        removeListener(event: \"display-metrics-changed\", listener: (event: Event, display: Display, changedMetrics: string[]) => void): this;\n        /**\n         * Emitted when `oldDisplay` has been removed.\n         */\n        on(event: \"display-removed\", listener: (event: Event, oldDisplay: Display) => void): this;\n        once(event: \"display-removed\", listener: (event: Event, oldDisplay: Display) => void): this;\n        addListener(event: \"display-removed\", listener: (event: Event, oldDisplay: Display) => void): this;\n        removeListener(event: \"display-removed\", listener: (event: Event, oldDisplay: Display) => void): this;\n        /**\n         * Converts a screen DIP point to a screen physical point. The DPI scale is\n         * performed relative to the display containing the DIP point.\n         *\n         * @platform win32\n         */\n        dipToScreenPoint(point: Point): Point;\n        /**\n         * Converts a screen DIP rect to a screen physical rect. The DPI scale is performed\n         * relative to the display nearest to `window`. If `window` is null, scaling will\n         * be performed to the display nearest to `rect`.\n         *\n         * @platform win32\n         */\n        dipToScreenRect(window: BrowserWindow | null, rect: Rectangle): Rectangle;\n        /**\n         * An array of displays that are currently available.\n         */\n        getAllDisplays(): Display[];\n        /**\n         * The current absolute position of the mouse pointer.\n         *\n         * **Note:** The return value is a DIP point, not a screen physical point.\n         */\n        getCursorScreenPoint(): Point;\n        /**\n         * The display that most closely intersects the provided bounds.\n         */\n        getDisplayMatching(rect: Rectangle): Display;\n        /**\n         * The display nearest the specified point.\n         */\n        getDisplayNearestPoint(point: Point): Display;\n        /**\n         * The primary display.\n         */\n        getPrimaryDisplay(): Display;\n        /**\n         * Converts a screen physical point to a screen DIP point. The DPI scale is\n         * performed relative to the display containing the physical point.\n         *\n         * @platform win32\n         */\n        screenToDipPoint(point: Point): Point;\n        /**\n         * Converts a screen physical rect to a screen DIP rect. The DPI scale is performed\n         * relative to the display nearest to `window`. If `window` is null, scaling will\n         * be performed to the display nearest to `rect`.\n         *\n         * @platform win32\n         */\n        screenToDipRect(window: BrowserWindow | null, rect: Rectangle): Rectangle;\n    }\n\n    interface ScrubberItem {\n        // Docs: https://electronjs.org/docs/api/structures/scrubber-item\n\n        /**\n         * The image to appear in this item.\n         */\n        icon?: NativeImage;\n        /**\n         * The text to appear in this item.\n         */\n        label?: string;\n    }\n\n    interface SegmentedControlSegment {\n        // Docs: https://electronjs.org/docs/api/structures/segmented-control-segment\n\n        /**\n         * Whether this segment is selectable. Default: true.\n         */\n        enabled?: boolean;\n        /**\n         * The image to appear in this segment.\n         */\n        icon?: NativeImage;\n        /**\n         * The text to appear in this segment.\n         */\n        label?: string;\n    }\n\n    interface SerialPort {\n        // Docs: https://electronjs.org/docs/api/structures/serial-port\n\n        /**\n         * A stable identifier on Windows that can be used for device permissions.\n         *\n         * @platform win32\n         */\n        deviceInstanceId?: string;\n        /**\n         * A string suitable for display to the user for describing this device.\n         */\n        displayName?: string;\n        /**\n         * Unique identifier for the port.\n         */\n        portId: string;\n        /**\n         * Name of the port.\n         */\n        portName: string;\n        /**\n         * The USB product ID.\n         */\n        productId?: string;\n        /**\n         * The USB device serial number.\n         */\n        serialNumber?: string;\n        /**\n         * Represents a single serial port on macOS can be enumerated by multiple drivers.\n         *\n         * @platform darwin\n         */\n        usbDriverName?: string;\n        /**\n         * The USB vendor ID.\n         */\n        vendorId?: string;\n    }\n\n    interface ServiceWorkerInfo {\n        // Docs: https://electronjs.org/docs/api/structures/service-worker-info\n\n        /**\n         * The virtual ID of the process that this service worker is running in.  This is\n         * not an OS level PID.  This aligns with the ID set used for\n         * `webContents.getProcessId()`.\n         */\n        renderProcessId: number;\n        /**\n         * The base URL that this service worker is active for.\n         */\n        scope: string;\n        /**\n         * The full URL to the script that this service worker runs\n         */\n        scriptUrl: string;\n    }\n\n    class ServiceWorkers extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/service-workers\n\n        /**\n         * Emitted when a service worker logs something to the console.\n         */\n        on(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the console message\n                 */\n                messageDetails: MessageDetails,\n            ) => void,\n        ): this;\n        once(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the console message\n                 */\n                messageDetails: MessageDetails,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the console message\n                 */\n                messageDetails: MessageDetails,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the console message\n                 */\n                messageDetails: MessageDetails,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a service worker has been registered. Can occur after a call to\n         * `navigator.serviceWorker.register('/sw.js')` successfully resolves or when a\n         * Chrome extension is loaded.\n         */\n        on(\n            event: \"registration-completed\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the registered service worker\n                 */\n                details: RegistrationCompletedDetails,\n            ) => void,\n        ): this;\n        once(\n            event: \"registration-completed\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the registered service worker\n                 */\n                details: RegistrationCompletedDetails,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"registration-completed\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the registered service worker\n                 */\n                details: RegistrationCompletedDetails,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"registration-completed\",\n            listener: (\n                event: Event,\n                /**\n                 * Information about the registered service worker\n                 */\n                details: RegistrationCompletedDetails,\n            ) => void,\n        ): this;\n        /**\n         * A ServiceWorkerInfo object where the keys are the service worker version ID and\n         * the values are the information about that service worker.\n         */\n        getAllRunning(): Record<number, ServiceWorkerInfo>;\n        /**\n         * Information about this service worker\n         *\n         * If the service worker does not exist or is not running this method will throw an\n         * exception.\n         */\n        getFromVersionID(versionId: number): ServiceWorkerInfo;\n    }\n\n    class Session extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/session\n\n        /**\n         * A session instance from `partition` string. When there is an existing `Session`\n         * with the same `partition`, it will be returned; otherwise a new `Session`\n         * instance will be created with `options`.\n         *\n         * If `partition` starts with `persist:`, the page will use a persistent session\n         * available to all pages in the app with the same `partition`. if there is no\n         * `persist:` prefix, the page will use an in-memory session. If the `partition` is\n         * empty then default session of the app will be returned.\n         *\n         * To create a `Session` with `options`, you have to ensure the `Session` with the\n         * `partition` has never been used before. There is no way to change the `options`\n         * of an existing `Session` object.\n         */\n        static fromPartition(partition: string, options?: FromPartitionOptions): Session;\n        /**\n         * A session instance from the absolute path as specified by the `path` string.\n         * When there is an existing `Session` with the same absolute path, it will be\n         * returned; otherwise a new `Session` instance will be created with `options`. The\n         * call will throw an error if the path is not an absolute path. Additionally, an\n         * error will be thrown if an empty string is provided.\n         *\n         * To create a `Session` with `options`, you have to ensure the `Session` with the\n         * `path` has never been used before. There is no way to change the `options` of an\n         * existing `Session` object.\n         */\n        static fromPath(path: string, options?: FromPathOptions): Session;\n        /**\n         * A `Session` object, the default session object of the app.\n         */\n        static defaultSession: Session;\n        /**\n         * Emitted after an extension is loaded. This occurs whenever an extension is added\n         * to the \"enabled\" set of extensions. This includes:\n         *\n         * * Extensions being loaded from `Session.loadExtension`.\n         * * Extensions being reloaded:\n         *   * from a crash.\n         *   * if the extension requested it (`chrome.runtime.reload()`).\n         */\n        on(event: \"extension-loaded\", listener: (event: Event, extension: Extension) => void): this;\n        once(event: \"extension-loaded\", listener: (event: Event, extension: Extension) => void): this;\n        addListener(event: \"extension-loaded\", listener: (event: Event, extension: Extension) => void): this;\n        removeListener(event: \"extension-loaded\", listener: (event: Event, extension: Extension) => void): this;\n        /**\n         * Emitted after an extension is loaded and all necessary browser state is\n         * initialized to support the start of the extension's background page.\n         */\n        on(event: \"extension-ready\", listener: (event: Event, extension: Extension) => void): this;\n        once(event: \"extension-ready\", listener: (event: Event, extension: Extension) => void): this;\n        addListener(event: \"extension-ready\", listener: (event: Event, extension: Extension) => void): this;\n        removeListener(event: \"extension-ready\", listener: (event: Event, extension: Extension) => void): this;\n        /**\n         * Emitted after an extension is unloaded. This occurs when\n         * `Session.removeExtension` is called.\n         */\n        on(event: \"extension-unloaded\", listener: (event: Event, extension: Extension) => void): this;\n        once(event: \"extension-unloaded\", listener: (event: Event, extension: Extension) => void): this;\n        addListener(event: \"extension-unloaded\", listener: (event: Event, extension: Extension) => void): this;\n        removeListener(event: \"extension-unloaded\", listener: (event: Event, extension: Extension) => void): this;\n        /**\n         * Emitted after `navigator.hid.requestDevice` has been called and\n         * `select-hid-device` has fired if a new device becomes available before the\n         * callback from `select-hid-device` is called.  This event is intended for use\n         * when using a UI to ask users to pick a device so that the UI can be updated with\n         * the newly added device.\n         */\n        on(event: \"hid-device-added\", listener: (event: Event, details: HidDeviceAddedDetails) => void): this;\n        once(event: \"hid-device-added\", listener: (event: Event, details: HidDeviceAddedDetails) => void): this;\n        addListener(event: \"hid-device-added\", listener: (event: Event, details: HidDeviceAddedDetails) => void): this;\n        removeListener(event: \"hid-device-added\", listener: (event: Event, details: HidDeviceAddedDetails) => void): this;\n        /**\n         * Emitted after `navigator.hid.requestDevice` has been called and\n         * `select-hid-device` has fired if a device has been removed before the callback\n         * from `select-hid-device` is called.  This event is intended for use when using a\n         * UI to ask users to pick a device so that the UI can be updated to remove the\n         * specified device.\n         */\n        on(event: \"hid-device-removed\", listener: (event: Event, details: HidDeviceRemovedDetails) => void): this;\n        once(event: \"hid-device-removed\", listener: (event: Event, details: HidDeviceRemovedDetails) => void): this;\n        addListener(event: \"hid-device-removed\", listener: (event: Event, details: HidDeviceRemovedDetails) => void): this;\n        removeListener(event: \"hid-device-removed\", listener: (event: Event, details: HidDeviceRemovedDetails) => void): this;\n        /**\n         * Emitted after `HIDDevice.forget()` has been called.  This event can be used to\n         * help maintain persistent storage of permissions when\n         * `setDevicePermissionHandler` is used.\n         */\n        on(event: \"hid-device-revoked\", listener: (event: Event, details: HidDeviceRevokedDetails) => void): this;\n        once(event: \"hid-device-revoked\", listener: (event: Event, details: HidDeviceRevokedDetails) => void): this;\n        addListener(event: \"hid-device-revoked\", listener: (event: Event, details: HidDeviceRevokedDetails) => void): this;\n        removeListener(event: \"hid-device-revoked\", listener: (event: Event, details: HidDeviceRevokedDetails) => void): this;\n        /**\n         * Emitted when a render process requests preconnection to a URL, generally due to\n         * a resource hint.\n         */\n        on(\n            event: \"preconnect\",\n            listener: (\n                event: Event,\n                /**\n                 * The URL being requested for preconnection by the renderer.\n                 */\n                preconnectUrl: string,\n                /**\n                 * True if the renderer is requesting that the connection include credentials (see\n                 * the spec for more details.)\n                 */\n                allowCredentials: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"preconnect\",\n            listener: (\n                event: Event,\n                /**\n                 * The URL being requested for preconnection by the renderer.\n                 */\n                preconnectUrl: string,\n                /**\n                 * True if the renderer is requesting that the connection include credentials (see\n                 * the spec for more details.)\n                 */\n                allowCredentials: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"preconnect\",\n            listener: (\n                event: Event,\n                /**\n                 * The URL being requested for preconnection by the renderer.\n                 */\n                preconnectUrl: string,\n                /**\n                 * True if the renderer is requesting that the connection include credentials (see\n                 * the spec for more details.)\n                 */\n                allowCredentials: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"preconnect\",\n            listener: (\n                event: Event,\n                /**\n                 * The URL being requested for preconnection by the renderer.\n                 */\n                preconnectUrl: string,\n                /**\n                 * True if the renderer is requesting that the connection include credentials (see\n                 * the spec for more details.)\n                 */\n                allowCredentials: boolean,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a HID device needs to be selected when a call to\n         * `navigator.hid.requestDevice` is made. `callback` should be called with\n         * `deviceId` to be selected; passing no arguments to `callback` will cancel the\n         * request.  Additionally, permissioning on `navigator.hid` can be further managed\n         * by using `ses.setPermissionCheckHandler(handler)` and\n         * `ses.setDevicePermissionHandler(handler)`.\n         */\n        on(event: \"select-hid-device\", listener: (event: Event, details: SelectHidDeviceDetails, callback: (deviceId?: string | null) => void) => void): this;\n        once(event: \"select-hid-device\", listener: (event: Event, details: SelectHidDeviceDetails, callback: (deviceId?: string | null) => void) => void): this;\n        addListener(event: \"select-hid-device\", listener: (event: Event, details: SelectHidDeviceDetails, callback: (deviceId?: string | null) => void) => void): this;\n        removeListener(event: \"select-hid-device\", listener: (event: Event, details: SelectHidDeviceDetails, callback: (deviceId?: string | null) => void) => void): this;\n        /**\n         * Emitted when a serial port needs to be selected when a call to\n         * `navigator.serial.requestPort` is made. `callback` should be called with\n         * `portId` to be selected, passing an empty string to `callback` will cancel the\n         * request.  Additionally, permissioning on `navigator.serial` can be managed by\n         * using ses.setPermissionCheckHandler(handler) with the `serial` permission.\n         */\n        on(event: \"select-serial-port\", listener: (event: Event, portList: SerialPort[], webContents: WebContents, callback: (portId: string) => void) => void): this;\n        once(event: \"select-serial-port\", listener: (event: Event, portList: SerialPort[], webContents: WebContents, callback: (portId: string) => void) => void): this;\n        addListener(event: \"select-serial-port\", listener: (event: Event, portList: SerialPort[], webContents: WebContents, callback: (portId: string) => void) => void): this;\n        removeListener(event: \"select-serial-port\", listener: (event: Event, portList: SerialPort[], webContents: WebContents, callback: (portId: string) => void) => void): this;\n        /**\n         * Emitted when a USB device needs to be selected when a call to\n         * `navigator.usb.requestDevice` is made. `callback` should be called with\n         * `deviceId` to be selected; passing no arguments to `callback` will cancel the\n         * request.  Additionally, permissioning on `navigator.usb` can be further managed\n         * by using `ses.setPermissionCheckHandler(handler)` and\n         * `ses.setDevicePermissionHandler(handler)`.\n         */\n        on(event: \"select-usb-device\", listener: (event: Event, details: SelectUsbDeviceDetails, callback: (deviceId?: string) => void) => void): this;\n        once(event: \"select-usb-device\", listener: (event: Event, details: SelectUsbDeviceDetails, callback: (deviceId?: string) => void) => void): this;\n        addListener(event: \"select-usb-device\", listener: (event: Event, details: SelectUsbDeviceDetails, callback: (deviceId?: string) => void) => void): this;\n        removeListener(event: \"select-usb-device\", listener: (event: Event, details: SelectUsbDeviceDetails, callback: (deviceId?: string) => void) => void): this;\n        /**\n         * Emitted after `navigator.serial.requestPort` has been called and\n         * `select-serial-port` has fired if a new serial port becomes available before the\n         * callback from `select-serial-port` is called.  This event is intended for use\n         * when using a UI to ask users to pick a port so that the UI can be updated with\n         * the newly added port.\n         */\n        on(event: \"serial-port-added\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        once(event: \"serial-port-added\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        addListener(event: \"serial-port-added\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        removeListener(event: \"serial-port-added\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        /**\n         * Emitted after `navigator.serial.requestPort` has been called and\n         * `select-serial-port` has fired if a serial port has been removed before the\n         * callback from `select-serial-port` is called.  This event is intended for use\n         * when using a UI to ask users to pick a port so that the UI can be updated to\n         * remove the specified port.\n         */\n        on(event: \"serial-port-removed\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        once(event: \"serial-port-removed\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        addListener(event: \"serial-port-removed\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        removeListener(event: \"serial-port-removed\", listener: (event: Event, port: SerialPort, webContents: WebContents) => void): this;\n        /**\n         * Emitted after `SerialPort.forget()` has been called.  This event can be used to\n         * help maintain persistent storage of permissions when\n         * `setDevicePermissionHandler` is used.\n         */\n        on(event: \"serial-port-revoked\", listener: (event: Event, details: SerialPortRevokedDetails) => void): this;\n        once(event: \"serial-port-revoked\", listener: (event: Event, details: SerialPortRevokedDetails) => void): this;\n        addListener(event: \"serial-port-revoked\", listener: (event: Event, details: SerialPortRevokedDetails) => void): this;\n        removeListener(event: \"serial-port-revoked\", listener: (event: Event, details: SerialPortRevokedDetails) => void): this;\n        /**\n         * Emitted when a hunspell dictionary file starts downloading\n         */\n        on(\n            event: \"spellcheck-dictionary-download-begin\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"spellcheck-dictionary-download-begin\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"spellcheck-dictionary-download-begin\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"spellcheck-dictionary-download-begin\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a hunspell dictionary file download fails.  For details on the\n         * failure you should collect a netlog and inspect the download request.\n         */\n        on(\n            event: \"spellcheck-dictionary-download-failure\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"spellcheck-dictionary-download-failure\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"spellcheck-dictionary-download-failure\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"spellcheck-dictionary-download-failure\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a hunspell dictionary file has been successfully downloaded\n         */\n        on(\n            event: \"spellcheck-dictionary-download-success\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"spellcheck-dictionary-download-success\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"spellcheck-dictionary-download-success\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"spellcheck-dictionary-download-success\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a hunspell dictionary file has been successfully initialized. This\n         * occurs after the file has been downloaded.\n         */\n        on(\n            event: \"spellcheck-dictionary-initialized\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"spellcheck-dictionary-initialized\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"spellcheck-dictionary-initialized\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"spellcheck-dictionary-initialized\",\n            listener: (\n                event: Event,\n                /**\n                 * The language code of the dictionary file\n                 */\n                languageCode: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted after `navigator.usb.requestDevice` has been called and\n         * `select-usb-device` has fired if a new device becomes available before the\n         * callback from `select-usb-device` is called.  This event is intended for use\n         * when using a UI to ask users to pick a device so that the UI can be updated with\n         * the newly added device.\n         */\n        on(event: \"usb-device-added\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        once(event: \"usb-device-added\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        addListener(event: \"usb-device-added\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        removeListener(event: \"usb-device-added\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        /**\n         * Emitted after `navigator.usb.requestDevice` has been called and\n         * `select-usb-device` has fired if a device has been removed before the callback\n         * from `select-usb-device` is called.  This event is intended for use when using a\n         * UI to ask users to pick a device so that the UI can be updated to remove the\n         * specified device.\n         */\n        on(event: \"usb-device-removed\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        once(event: \"usb-device-removed\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        addListener(event: \"usb-device-removed\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        removeListener(event: \"usb-device-removed\", listener: (event: Event, device: USBDevice, webContents: WebContents) => void): this;\n        /**\n         * Emitted after `USBDevice.forget()` has been called.  This event can be used to\n         * help maintain persistent storage of permissions when\n         * `setDevicePermissionHandler` is used.\n         */\n        on(event: \"usb-device-revoked\", listener: (event: Event, details: UsbDeviceRevokedDetails) => void): this;\n        once(event: \"usb-device-revoked\", listener: (event: Event, details: UsbDeviceRevokedDetails) => void): this;\n        addListener(event: \"usb-device-revoked\", listener: (event: Event, details: UsbDeviceRevokedDetails) => void): this;\n        removeListener(event: \"usb-device-revoked\", listener: (event: Event, details: UsbDeviceRevokedDetails) => void): this;\n        /**\n         * Emitted when Electron is about to download `item` in `webContents`.\n         *\n         * Calling `event.preventDefault()` will cancel the download and `item` will not be\n         * available from next tick of the process.\n         */\n        on(event: \"will-download\", listener: (event: Event, item: DownloadItem, webContents: WebContents) => void): this;\n        once(event: \"will-download\", listener: (event: Event, item: DownloadItem, webContents: WebContents) => void): this;\n        addListener(event: \"will-download\", listener: (event: Event, item: DownloadItem, webContents: WebContents) => void): this;\n        removeListener(event: \"will-download\", listener: (event: Event, item: DownloadItem, webContents: WebContents) => void): this;\n        /**\n         * Whether the word was successfully written to the custom dictionary. This API\n         * will not work on non-persistent (in-memory) sessions.\n         *\n         * **Note:** On macOS and Windows 10 this word will be written to the OS custom\n         * dictionary as well\n         */\n        addWordToSpellCheckerDictionary(word: string): boolean;\n        /**\n         * Dynamically sets whether to always send credentials for HTTP NTLM or Negotiate\n         * authentication.\n         */\n        allowNTLMCredentialsForDomains(domains: string): void;\n        /**\n         * resolves when the session’s HTTP authentication cache has been cleared.\n         */\n        clearAuthCache(): Promise<void>;\n        /**\n         * resolves when the cache clear operation is complete.\n         *\n         * Clears the session’s HTTP cache.\n         */\n        clearCache(): Promise<void>;\n        /**\n         * resolves when the code cache clear operation is complete.\n         */\n        clearCodeCaches(options: ClearCodeCachesOptions): Promise<void>;\n        /**\n         * Resolves when the operation is complete.\n         *\n         * Clears the host resolver cache.\n         */\n        clearHostResolverCache(): Promise<void>;\n        /**\n         * resolves when the storage data has been cleared.\n         */\n        clearStorageData(options?: ClearStorageDataOptions): Promise<void>;\n        /**\n         * Resolves when all connections are closed.\n         *\n         * **Note:** It will terminate / fail all requests currently in flight.\n         */\n        closeAllConnections(): Promise<void>;\n        /**\n         * Allows resuming `cancelled` or `interrupted` downloads from previous `Session`.\n         * The API will generate a DownloadItem that can be accessed with the will-download\n         * event. The DownloadItem will not have any `WebContents` associated with it and\n         * the initial state will be `interrupted`. The download will start only when the\n         * `resume` API is called on the DownloadItem.\n         */\n        createInterruptedDownload(options: CreateInterruptedDownloadOptions): void;\n        /**\n         * Disables any network emulation already active for the `session`. Resets to the\n         * original network configuration.\n         */\n        disableNetworkEmulation(): void;\n        /**\n         * Initiates a download of the resource at `url`. The API will generate a\n         * DownloadItem that can be accessed with the will-download event.\n         *\n         * **Note:** This does not perform any security checks that relate to a page's\n         * origin, unlike `webContents.downloadURL`.\n         */\n        downloadURL(url: string): void;\n        /**\n         * Emulates network with the given configuration for the `session`.\n         */\n        enableNetworkEmulation(options: EnableNetworkEmulationOptions): void;\n        /**\n         * see Response.\n         *\n         * Sends a request, similarly to how `fetch()` works in the renderer, using\n         * Chrome's network stack. This differs from Node's `fetch()`, which uses Node.js's\n         * HTTP stack.\n         *\n         * Example:\n         *\n         * See also `net.fetch()`, a convenience method which issues requests from the\n         * default session.\n         *\n         * See the MDN documentation for `fetch()` for more details.\n         *\n         * Limitations:\n         *\n         * * `net.fetch()` does not support the `data:` or `blob:` schemes.\n         * * The value of the `integrity` option is ignored.\n         * * The `.type` and `.url` values of the returned `Response` object are incorrect.\n         *\n         * By default, requests made with `net.fetch` can be made to custom protocols as\n         * well as `file:`, and will trigger webRequest handlers if present. When the\n         * non-standard `bypassCustomProtocolHandlers` option is set in RequestInit, custom\n         * protocol handlers will not be called for this request. This allows forwarding an\n         * intercepted request to the built-in handler. webRequest handlers will still be\n         * triggered when bypassing custom protocols.\n         */\n        fetch(input: string | GlobalRequest, init?: RequestInit): Promise<GlobalResponse>;\n        /**\n         * Writes any unwritten DOMStorage data to disk.\n         */\n        flushStorageData(): void;\n        /**\n         * Resolves when the all internal states of proxy service is reset and the latest\n         * proxy configuration is reapplied if it's already available. The pac script will\n         * be fetched from `pacScript` again if the proxy mode is `pac_script`.\n         */\n        forceReloadProxyConfig(): Promise<void>;\n        /**\n         * A list of all loaded extensions.\n         *\n         * **Note:** This API cannot be called before the `ready` event of the `app` module\n         * is emitted.\n         */\n        getAllExtensions(): Extension[];\n        /**\n         * resolves with blob data.\n         */\n        getBlobData(identifier: string): Promise<Buffer>;\n        /**\n         * the session's current cache size, in bytes.\n         */\n        getCacheSize(): Promise<number>;\n        /**\n         * | `null` - The loaded extension with the given ID.\n         *\n         * **Note:** This API cannot be called before the `ready` event of the `app` module\n         * is emitted.\n         */\n        getExtension(extensionId: string): Extension;\n        /**\n         * an array of paths to preload scripts that have been registered.\n         */\n        getPreloads(): string[];\n        /**\n         * An array of language codes the spellchecker is enabled for.  If this list is\n         * empty the spellchecker will fallback to using `en-US`.  By default on launch if\n         * this setting is an empty list Electron will try to populate this setting with\n         * the current OS locale.  This setting is persisted across restarts.\n         *\n         * **Note:** On macOS the OS spellchecker is used and has its own list of\n         * languages. On macOS, this API will return whichever languages have been\n         * configured by the OS.\n         */\n        getSpellCheckerLanguages(): string[];\n        /**\n         * The absolute file system path where data for this session is persisted on disk.\n         * For in memory sessions this returns `null`.\n         */\n        getStoragePath(): string | null;\n        /**\n         * The user agent for this session.\n         */\n        getUserAgent(): string;\n        /**\n         * Whether or not this session is a persistent one. The default `webContents`\n         * session of a `BrowserWindow` is persistent. When creating a session from a\n         * partition, session prefixed with `persist:` will be persistent, while others\n         * will be temporary.\n         */\n        isPersistent(): boolean;\n        /**\n         * Whether the builtin spell checker is enabled.\n         */\n        isSpellCheckerEnabled(): boolean;\n        /**\n         * An array of all words in app's custom dictionary. Resolves when the full\n         * dictionary is loaded from disk.\n         */\n        listWordsInSpellCheckerDictionary(): Promise<string[]>;\n        /**\n         * resolves when the extension is loaded.\n         *\n         * This method will raise an exception if the extension could not be loaded. If\n         * there are warnings when installing the extension (e.g. if the extension requests\n         * an API that Electron does not support) then they will be logged to the console.\n         *\n         * Note that Electron does not support the full range of Chrome extensions APIs.\n         * See Supported Extensions APIs for more details on what is supported.\n         *\n         * Note that in previous versions of Electron, extensions that were loaded would be\n         * remembered for future runs of the application. This is no longer the case:\n         * `loadExtension` must be called on every boot of your app if you want the\n         * extension to be loaded.\n         *\n         * This API does not support loading packed (.crx) extensions.\n         *\n         * **Note:** This API cannot be called before the `ready` event of the `app` module\n         * is emitted.\n         *\n         * **Note:** Loading extensions into in-memory (non-persistent) sessions is not\n         * supported and will throw an error.\n         */\n        loadExtension(path: string, options?: LoadExtensionOptions): Promise<Electron.Extension>;\n        /**\n         * Preconnects the given number of sockets to an origin.\n         */\n        preconnect(options: PreconnectOptions): void;\n        /**\n         * Unloads an extension.\n         *\n         * **Note:** This API cannot be called before the `ready` event of the `app` module\n         * is emitted.\n         */\n        removeExtension(extensionId: string): void;\n        /**\n         * Whether the word was successfully removed from the custom dictionary. This API\n         * will not work on non-persistent (in-memory) sessions.\n         *\n         * **Note:** On macOS and Windows 10 this word will be removed from the OS custom\n         * dictionary as well\n         */\n        removeWordFromSpellCheckerDictionary(word: string): boolean;\n        /**\n         * Resolves with the resolved IP addresses for the `host`.\n         */\n        resolveHost(host: string, options?: ResolveHostOptions): Promise<Electron.ResolvedHost>;\n        /**\n         * Resolves with the proxy information for `url`.\n         */\n        resolveProxy(url: string): Promise<string>;\n        /**\n         * Sets a handler to respond to Bluetooth pairing requests. This handler allows\n         * developers to handle devices that require additional validation before pairing.\n         * When a handler is not defined, any pairing on Linux or Windows that requires\n         * additional validation will be automatically cancelled. macOS does not require a\n         * handler because macOS handles the pairing automatically.  To clear the handler,\n         * call `setBluetoothPairingHandler(null)`.\n         *\n         * @platform win32,linux\n         */\n        setBluetoothPairingHandler(handler: ((details: BluetoothPairingHandlerHandlerDetails, callback: (response: Response) => void) => void) | null): void;\n        /**\n         * Sets the certificate verify proc for `session`, the `proc` will be called with\n         * `proc(request, callback)` whenever a server certificate verification is\n         * requested. Calling `callback(0)` accepts the certificate, calling `callback(-2)`\n         * rejects it.\n         *\n         * Calling `setCertificateVerifyProc(null)` will revert back to default certificate\n         * verify proc.\n         *\n         * > **NOTE:** The result of this procedure is cached by the network service.\n         */\n        setCertificateVerifyProc(proc: ((request: Request, callback: (verificationResult: number) => void) => void) | null): void;\n        /**\n         * Sets the directory to store the generated JS code cache for this session. The\n         * directory is not required to be created by the user before this call, the\n         * runtime will create if it does not exist otherwise will use the existing\n         * directory. If directory cannot be created, then code cache will not be used and\n         * all operations related to code cache will fail silently inside the runtime. By\n         * default, the directory will be `Code Cache` under the respective user data\n         * folder.\n         */\n        setCodeCachePath(path: string): void;\n        /**\n         * Sets the handler which can be used to respond to device permission checks for\n         * the `session`. Returning `true` will allow the device to be permitted and\n         * `false` will reject it. To clear the handler, call\n         * `setDevicePermissionHandler(null)`. This handler can be used to provide default\n         * permissioning to devices without first calling for permission to devices (eg via\n         * `navigator.hid.requestDevice`).  If this handler is not defined, the default\n         * device permissions as granted through device selection (eg via\n         * `navigator.hid.requestDevice`) will be used. Additionally, the default behavior\n         * of Electron is to store granted device permision in memory. If longer term\n         * storage is needed, a developer can store granted device permissions (eg when\n         * handling the `select-hid-device` event) and then read from that storage with\n         * `setDevicePermissionHandler`.\n         */\n        setDevicePermissionHandler(handler: ((details: DevicePermissionHandlerHandlerDetails) => boolean) | null): void;\n        /**\n         * This handler will be called when web content requests access to display media\n         * via the `navigator.mediaDevices.getDisplayMedia` API. Use the desktopCapturer\n         * API to choose which stream(s) to grant access to.\n         *\n         * Passing a WebFrameMain object as a video or audio stream will capture the video\n         * or audio stream from that frame.\n         *\n         * Passing `null` instead of a function resets the handler to its default state.\n         */\n        setDisplayMediaRequestHandler(handler: ((request: DisplayMediaRequestHandlerHandlerRequest, callback: (streams: Streams) => void) => void) | null): void;\n        /**\n         * Sets download saving directory. By default, the download directory will be the\n         * `Downloads` under the respective app folder.\n         */\n        setDownloadPath(path: string): void;\n        /**\n         * Sets the handler which can be used to respond to permission checks for the\n         * `session`. Returning `true` will allow the permission and `false` will reject\n         * it.  Please note that you must also implement `setPermissionRequestHandler` to\n         * get complete permission handling. Most web APIs do a permission check and then\n         * make a permission request if the check is denied. To clear the handler, call\n         * `setPermissionCheckHandler(null)`.\n         */\n        setPermissionCheckHandler(handler: ((webContents: WebContents | null, permission: string, requestingOrigin: string, details: PermissionCheckHandlerHandlerDetails) => boolean) | null): void;\n        /**\n         * Sets the handler which can be used to respond to permission requests for the\n         * `session`. Calling `callback(true)` will allow the permission and\n         * `callback(false)` will reject it. To clear the handler, call\n         * `setPermissionRequestHandler(null)`.  Please note that you must also implement\n         * `setPermissionCheckHandler` to get complete permission handling. Most web APIs\n         * do a permission check and then make a permission request if the check is denied.\n         */\n        setPermissionRequestHandler(\n            handler:\n                | ((\n                      webContents: WebContents,\n                      permission: \"clipboard-read\" | \"clipboard-sanitized-write\" | \"media\" | \"display-capture\" | \"mediaKeySystem\" | \"geolocation\" | \"notifications\" | \"midi\" | \"midiSysex\" | \"pointerLock\" | \"fullscreen\" | \"openExternal\" | \"window-management\" | \"unknown\",\n                      callback: (permissionGranted: boolean) => void,\n                      details: PermissionRequestHandlerHandlerDetails,\n                  ) => void)\n                | null,\n        ): void;\n        /**\n         * Adds scripts that will be executed on ALL web contents that are associated with\n         * this session just before normal `preload` scripts run.\n         */\n        setPreloads(preloads: string[]): void;\n        /**\n         * Resolves when the proxy setting process is complete.\n         *\n         * Sets the proxy settings.\n         *\n         * When `mode` is unspecified, `pacScript` and `proxyRules` are provided together,\n         * the `proxyRules` option is ignored and `pacScript` configuration is applied.\n         *\n         * You may need `ses.closeAllConnections` to close currently in flight connections\n         * to prevent pooled sockets using previous proxy from being reused by future\n         * requests.\n         *\n         * The `proxyRules` has to follow the rules below:\n         *\n         * For example:\n         *\n         * * `http=foopy:80;ftp=foopy2` - Use HTTP proxy `foopy:80` for `http://` URLs, and\n         * HTTP proxy `foopy2:80` for `ftp://` URLs.\n         * * `foopy:80` - Use HTTP proxy `foopy:80` for all URLs.\n         * * `foopy:80,bar,direct://` - Use HTTP proxy `foopy:80` for all URLs, failing\n         * over to `bar` if `foopy:80` is unavailable, and after that using no proxy.\n         * * `socks4://foopy` - Use SOCKS v4 proxy `foopy:1080` for all URLs.\n         * * `http=foopy,socks5://bar.com` - Use HTTP proxy `foopy` for http URLs, and fail\n         * over to the SOCKS5 proxy `bar.com` if `foopy` is unavailable.\n         * * `http=foopy,direct://` - Use HTTP proxy `foopy` for http URLs, and use no\n         * proxy if `foopy` is unavailable.\n         * * `http=foopy;socks=foopy2` - Use HTTP proxy `foopy` for http URLs, and use\n         * `socks4://foopy2` for all other URLs.\n         *\n         * The `proxyBypassRules` is a comma separated list of rules described below:\n         *\n         * * `[ URL_SCHEME \"://\" ] HOSTNAME_PATTERN [ \":\" <port> ]`\n         *\n         * Match all hostnames that match the pattern HOSTNAME_PATTERN.\n         *\n         * Examples: \"foobar.com\", \"*foobar.com\", \"*.foobar.com\", \"*foobar.com:99\",\n         * \"https://x.*.y.com:99\"\n         * * `\".\" HOSTNAME_SUFFIX_PATTERN [ \":\" PORT ]`\n         *\n         * Match a particular domain suffix.\n         *\n         * Examples: \".google.com\", \".com\", \"http://.google.com\"\n         * * `[ SCHEME \"://\" ] IP_LITERAL [ \":\" PORT ]`\n         *\n         * Match URLs which are IP address literals.\n         *\n         * Examples: \"127.0.1\", \"[0:0::1]\", \"[::1]\", \"http://[::1]:99\"\n         * * `IP_LITERAL \"/\" PREFIX_LENGTH_IN_BITS`\n         *\n         * Match any URL that is to an IP literal that falls between the given range. IP\n         * range is specified using CIDR notation.\n         *\n         * Examples: \"192.168.1.1/16\", \"fefe:13::abc/33\".\n         * * `<local>`\n         *\n         * Match local addresses. The meaning of `<local>` is whether the host matches one\n         * of: \"127.0.0.1\", \"::1\", \"localhost\".\n         */\n        setProxy(config: Config): Promise<void>;\n        /**\n         * By default Electron will download hunspell dictionaries from the Chromium CDN.\n         * If you want to override this behavior you can use this API to point the\n         * dictionary downloader at your own hosted version of the hunspell dictionaries.\n         * We publish a `hunspell_dictionaries.zip` file with each release which contains\n         * the files you need to host here.\n         *\n         * The file server must be **case insensitive**. If you cannot do this, you must\n         * upload each file twice: once with the case it has in the ZIP file and once with\n         * the filename as all lowercase.\n         *\n         * If the files present in `hunspell_dictionaries.zip` are available at\n         * `https://example.com/dictionaries/language-code.bdic` then you should call this\n         * api with\n         * `ses.setSpellCheckerDictionaryDownloadURL('https://example.com/dictionaries/')`.\n         *  Please note the trailing slash.  The URL to the dictionaries is formed as\n         * `${url}${filename}`.\n         *\n         * **Note:** On macOS the OS spellchecker is used and therefore we do not download\n         * any dictionary files.  This API is a no-op on macOS.\n         */\n        setSpellCheckerDictionaryDownloadURL(url: string): void;\n        /**\n         * Sets whether to enable the builtin spell checker.\n         */\n        setSpellCheckerEnabled(enable: boolean): void;\n        /**\n         * The built in spellchecker does not automatically detect what language a user is\n         * typing in.  In order for the spell checker to correctly check their words you\n         * must call this API with an array of language codes.  You can get the list of\n         * supported language codes with the `ses.availableSpellCheckerLanguages` property.\n         *\n         * **Note:** On macOS the OS spellchecker is used and will detect your language\n         * automatically.  This API is a no-op on macOS.\n         */\n        setSpellCheckerLanguages(languages: string[]): void;\n        /**\n         * Sets the SSL configuration for the session. All subsequent network requests will\n         * use the new configuration. Existing network connections (such as WebSocket\n         * connections) will not be terminated, but old sockets in the pool will not be\n         * reused for new connections.\n         */\n        setSSLConfig(config: SSLConfigConfig): void;\n        /**\n         * Sets the handler which can be used to override which USB classes are protected.\n         * The return value for the handler is a string array of USB classes which should\n         * be considered protected (eg not available in the renderer).  Valid values for\n         * the array are:\n         *\n         * * `audio`\n         * * `audio-video`\n         * * `hid`\n         * * `mass-storage`\n         * * `smart-card`\n         * * `video`\n         * * `wireless`\n         *\n         * Returning an empty string array from the handler will allow all USB classes;\n         * returning the passed in array will maintain the default list of protected USB\n         * classes (this is also the default behavior if a handler is not defined). To\n         * clear the handler, call `setUSBProtectedClassesHandler(null)`.\n         */\n        setUSBProtectedClassesHandler(handler: ((details: USBProtectedClassesHandlerHandlerDetails) => string[]) | null): void;\n        /**\n         * Overrides the `userAgent` and `acceptLanguages` for this session.\n         *\n         * The `acceptLanguages` must a comma separated ordered list of language codes, for\n         * example `\"en-US,fr,de,ko,zh-CN,ja\"`.\n         *\n         * This doesn't affect existing `WebContents`, and each `WebContents` can use\n         * `webContents.setUserAgent` to override the session-wide user agent.\n         */\n        setUserAgent(userAgent: string, acceptLanguages?: string): void;\n        /**\n         * A `string[]` array which consists of all the known available spell checker\n         * languages.  Providing a language code to the `setSpellCheckerLanguages` API that\n         * isn't in this array will result in an error.\n         *\n         */\n        readonly availableSpellCheckerLanguages: string[];\n        /**\n         * A `Cookies` object for this session.\n         *\n         */\n        readonly cookies: Cookies;\n        /**\n         * A `NetLog` object for this session.\n         *\n         */\n        readonly netLog: NetLog;\n        /**\n         * A `Protocol` object for this session.\n         *\n         */\n        readonly protocol: Protocol;\n        /**\n         * A `ServiceWorkers` object for this session.\n         *\n         */\n        readonly serviceWorkers: ServiceWorkers;\n        /**\n         * A `boolean` indicating whether builtin spell checker is enabled.\n         */\n        spellCheckerEnabled: boolean;\n        /**\n         * A `string | null` indicating the absolute file system path where data for this\n         * session is persisted on disk.  For in memory sessions this returns `null`.\n         *\n         */\n        readonly storagePath: string | null;\n        /**\n         * A `WebRequest` object for this session.\n         *\n         */\n        readonly webRequest: WebRequest;\n    }\n\n    interface SharedWorkerInfo {\n        // Docs: https://electronjs.org/docs/api/structures/shared-worker-info\n\n        /**\n         * The unique id of the shared worker.\n         */\n        id: string;\n        /**\n         * The url of the shared worker.\n         */\n        url: string;\n    }\n\n    class ShareMenu extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/share-menu\n\n        /**\n         * ShareMenu\n         */\n        constructor(sharingItem: SharingItem);\n        /**\n         * Closes the context menu in the `browserWindow`.\n         */\n        closePopup(browserWindow?: BrowserWindow): void;\n        /**\n         * Pops up this menu as a context menu in the `BrowserWindow`.\n         */\n        popup(options?: PopupOptions): void;\n    }\n\n    interface SharingItem {\n        // Docs: https://electronjs.org/docs/api/structures/sharing-item\n\n        /**\n         * An array of files to share.\n         */\n        filePaths?: string[];\n        /**\n         * An array of text to share.\n         */\n        texts?: string[];\n        /**\n         * An array of URLs to share.\n         */\n        urls?: string[];\n    }\n\n    interface Shell {\n        // Docs: https://electronjs.org/docs/api/shell\n\n        /**\n         * Play the beep sound.\n         */\n        beep(): void;\n        /**\n         * Open the given external protocol URL in the desktop's default manner. (For\n         * example, mailto: URLs in the user's default mail agent).\n         */\n        openExternal(url: string, options?: OpenExternalOptions): Promise<void>;\n        /**\n         * Resolves with a string containing the error message corresponding to the failure\n         * if a failure occurred, otherwise \"\".\n         *\n         * Open the given file in the desktop's default manner.\n         */\n        openPath(path: string): Promise<string>;\n        /**\n         * Resolves the shortcut link at `shortcutPath`.\n         *\n         * An exception will be thrown when any error happens.\n         *\n         * @platform win32\n         */\n        readShortcutLink(shortcutPath: string): ShortcutDetails;\n        /**\n         * Show the given file in a file manager. If possible, select the file.\n         */\n        showItemInFolder(fullPath: string): void;\n        /**\n         * Resolves when the operation has been completed. Rejects if there was an error\n         * while deleting the requested item.\n         *\n         * This moves a path to the OS-specific trash location (Trash on macOS, Recycle Bin\n         * on Windows, and a desktop-environment-specific location on Linux).\n         */\n        trashItem(path: string): Promise<void>;\n        /**\n         * Whether the shortcut was created successfully.\n         *\n         * Creates or updates a shortcut link at `shortcutPath`.\n         *\n         * @platform win32\n         */\n        writeShortcutLink(shortcutPath: string, operation: \"create\" | \"update\" | \"replace\", options: ShortcutDetails): boolean;\n        /**\n         * Whether the shortcut was created successfully.\n         *\n         * Creates or updates a shortcut link at `shortcutPath`.\n         *\n         * @platform win32\n         */\n        writeShortcutLink(shortcutPath: string, options: ShortcutDetails): boolean;\n    }\n\n    interface ShortcutDetails {\n        // Docs: https://electronjs.org/docs/api/structures/shortcut-details\n\n        /**\n         * The Application User Model ID. Default is empty.\n         */\n        appUserModelId?: string;\n        /**\n         * The arguments to be applied to `target` when launching from this shortcut.\n         * Default is empty.\n         */\n        args?: string;\n        /**\n         * The working directory. Default is empty.\n         */\n        cwd?: string;\n        /**\n         * The description of the shortcut. Default is empty.\n         */\n        description?: string;\n        /**\n         * The path to the icon, can be a DLL or EXE. `icon` and `iconIndex` have to be set\n         * together. Default is empty, which uses the target's icon.\n         */\n        icon?: string;\n        /**\n         * The resource ID of icon when `icon` is a DLL or EXE. Default is 0.\n         */\n        iconIndex?: number;\n        /**\n         * The target to launch from this shortcut.\n         */\n        target: string;\n        /**\n         * The Application Toast Activator CLSID. Needed for participating in Action\n         * Center.\n         */\n        toastActivatorClsid?: string;\n    }\n\n    interface Size {\n        // Docs: https://electronjs.org/docs/api/structures/size\n\n        height: number;\n        width: number;\n    }\n\n    interface SystemPreferences extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/system-preferences\n\n        /**\n         * @platform win32\n         */\n        on(\n            event: \"accent-color-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The new RGBA color the user assigned to be their system accent color.\n                 */\n                newColor: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"accent-color-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The new RGBA color the user assigned to be their system accent color.\n                 */\n                newColor: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"accent-color-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The new RGBA color the user assigned to be their system accent color.\n                 */\n                newColor: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"accent-color-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The new RGBA color the user assigned to be their system accent color.\n                 */\n                newColor: string,\n            ) => void,\n        ): this;\n        /**\n         * @platform win32\n         */\n        on(event: \"color-changed\", listener: (event: Event) => void): this;\n        once(event: \"color-changed\", listener: (event: Event) => void): this;\n        addListener(event: \"color-changed\", listener: (event: Event) => void): this;\n        removeListener(event: \"color-changed\", listener: (event: Event) => void): this;\n        /**\n         * **Deprecated:** Should use the new `updated` event on the `nativeTheme` module.\n         *\n         * @deprecated\n         * @platform win32\n         */\n        on(\n            event: \"high-contrast-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if a high contrast theme is being used, `false` otherwise.\n                 */\n                highContrastColorScheme: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"high-contrast-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if a high contrast theme is being used, `false` otherwise.\n                 */\n                highContrastColorScheme: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"high-contrast-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if a high contrast theme is being used, `false` otherwise.\n                 */\n                highContrastColorScheme: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"high-contrast-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if a high contrast theme is being used, `false` otherwise.\n                 */\n                highContrastColorScheme: boolean,\n            ) => void,\n        ): this;\n        /**\n         * **Deprecated:** Should use the new `updated` event on the `nativeTheme` module.\n         *\n         * @deprecated\n         * @platform win32\n         */\n        on(\n            event: \"inverted-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if an inverted color scheme (a high contrast color scheme with light text\n                 * and dark backgrounds) is being used, `false` otherwise.\n                 */\n                invertedColorScheme: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"inverted-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if an inverted color scheme (a high contrast color scheme with light text\n                 * and dark backgrounds) is being used, `false` otherwise.\n                 */\n                invertedColorScheme: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"inverted-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if an inverted color scheme (a high contrast color scheme with light text\n                 * and dark backgrounds) is being used, `false` otherwise.\n                 */\n                invertedColorScheme: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"inverted-color-scheme-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * `true` if an inverted color scheme (a high contrast color scheme with light text\n                 * and dark backgrounds) is being used, `false` otherwise.\n                 */\n                invertedColorScheme: boolean,\n            ) => void,\n        ): this;\n        /**\n         * A promise that resolves with `true` if consent was granted and `false` if it was\n         * denied. If an invalid `mediaType` is passed, the promise will be rejected. If an\n         * access request was denied and later is changed through the System Preferences\n         * pane, a restart of the app will be required for the new permissions to take\n         * effect. If access has already been requested and denied, it _must_ be changed\n         * through the preference pane; an alert will not pop up and the promise will\n         * resolve with the existing access status.\n         *\n         * **Important:** In order to properly leverage this API, you must set the\n         * `NSMicrophoneUsageDescription` and `NSCameraUsageDescription` strings in your\n         * app's `Info.plist` file. The values for these keys will be used to populate the\n         * permission dialogs so that the user will be properly informed as to the purpose\n         * of the permission request. See Electron Application Distribution for more\n         * information about how to set these in the context of Electron.\n         *\n         * This user consent was not required until macOS 10.14 Mojave, so this method will\n         * always return `true` if your system is running 10.13 High Sierra.\n         *\n         * @platform darwin\n         */\n        askForMediaAccess(mediaType: \"microphone\" | \"camera\"): Promise<boolean>;\n        /**\n         * whether or not this device has the ability to use Touch ID.\n         *\n         * @platform darwin\n         */\n        canPromptTouchID(): boolean;\n        /**\n         * The users current system wide accent color preference in RGBA hexadecimal form.\n         *\n         * This API is only available on macOS 10.14 Mojave or newer.\n         *\n         * @platform win32,darwin\n         */\n        getAccentColor(): string;\n        /**\n         * * `shouldRenderRichAnimation` boolean - Returns true if rich animations should\n         * be rendered. Looks at session type (e.g. remote desktop) and accessibility\n         * settings to give guidance for heavy animations.\n         * * `scrollAnimationsEnabledBySystem` boolean - Determines on a per-platform basis\n         * whether scroll animations (e.g. produced by home/end key) should be enabled.\n         * * `prefersReducedMotion` boolean - Determines whether the user desires reduced\n         * motion based on platform APIs.\n         *\n         * Returns an object with system animation settings.\n         */\n        getAnimationSettings(): AnimationSettings;\n        /**\n         * | `null` - Can be `dark`, `light` or `unknown`.\n         *\n         * Gets the macOS appearance setting that you have declared you want for your\n         * application, maps to NSApplication.appearance. You can use the\n         * `setAppLevelAppearance` API to set this value.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        getAppLevelAppearance(): \"dark\" | \"light\" | \"unknown\";\n        /**\n         * The system color setting in RGB hexadecimal form (`#ABCDEF`). See the Windows\n         * docs and the macOS docs for more details.\n         *\n         * The following colors are only available on macOS 10.14: `find-highlight`,\n         * `selected-content-background`, `separator`,\n         * `unemphasized-selected-content-background`,\n         * `unemphasized-selected-text-background`, and `unemphasized-selected-text`.\n         *\n         * @platform win32,darwin\n         */\n        getColor(\n            color:\n                | \"3d-dark-shadow\"\n                | \"3d-face\"\n                | \"3d-highlight\"\n                | \"3d-light\"\n                | \"3d-shadow\"\n                | \"active-border\"\n                | \"active-caption\"\n                | \"active-caption-gradient\"\n                | \"app-workspace\"\n                | \"button-text\"\n                | \"caption-text\"\n                | \"desktop\"\n                | \"disabled-text\"\n                | \"highlight\"\n                | \"highlight-text\"\n                | \"hotlight\"\n                | \"inactive-border\"\n                | \"inactive-caption\"\n                | \"inactive-caption-gradient\"\n                | \"inactive-caption-text\"\n                | \"info-background\"\n                | \"info-text\"\n                | \"menu\"\n                | \"menu-highlight\"\n                | \"menubar\"\n                | \"menu-text\"\n                | \"scrollbar\"\n                | \"window\"\n                | \"window-frame\"\n                | \"window-text\"\n                | \"alternate-selected-control-text\"\n                | \"control-background\"\n                | \"control\"\n                | \"control-text\"\n                | \"disabled-control-text\"\n                | \"find-highlight\"\n                | \"grid\"\n                | \"header-text\"\n                | \"highlight\"\n                | \"keyboard-focus-indicator\"\n                | \"label\"\n                | \"link\"\n                | \"placeholder-text\"\n                | \"quaternary-label\"\n                | \"scrubber-textured-background\"\n                | \"secondary-label\"\n                | \"selected-content-background\"\n                | \"selected-control\"\n                | \"selected-control-text\"\n                | \"selected-menu-item-text\"\n                | \"selected-text-background\"\n                | \"selected-text\"\n                | \"separator\"\n                | \"shadow\"\n                | \"tertiary-label\"\n                | \"text-background\"\n                | \"text\"\n                | \"under-page-background\"\n                | \"unemphasized-selected-content-background\"\n                | \"unemphasized-selected-text-background\"\n                | \"unemphasized-selected-text\"\n                | \"window-background\"\n                | \"window-frame-text\",\n        ): string;\n        /**\n         * Can be `dark`, `light` or `unknown`.\n         *\n         * Gets the macOS appearance setting that is currently applied to your application,\n         * maps to NSApplication.effectiveAppearance\n         *\n         * @platform darwin\n         */\n        getEffectiveAppearance(): \"dark\" | \"light\" | \"unknown\";\n        /**\n         * Can be `not-determined`, `granted`, `denied`, `restricted` or `unknown`.\n         *\n         * This user consent was not required on macOS 10.13 High Sierra so this method\n         * will always return `granted`. macOS 10.14 Mojave or higher requires consent for\n         * `microphone` and `camera` access. macOS 10.15 Catalina or higher requires\n         * consent for `screen` access.\n         *\n         * Windows 10 has a global setting controlling `microphone` and `camera` access for\n         * all win32 applications. It will always return `granted` for `screen` and for all\n         * media types on older versions of Windows.\n         *\n         * @platform win32,darwin\n         */\n        getMediaAccessStatus(mediaType: \"microphone\" | \"camera\" | \"screen\"): \"not-determined\" | \"granted\" | \"denied\" | \"restricted\" | \"unknown\";\n        /**\n         * The standard system color formatted as `#RRGGBBAA`.\n         *\n         * Returns one of several standard system colors that automatically adapt to\n         * vibrancy and changes in accessibility settings like 'Increase contrast' and\n         * 'Reduce transparency'. See Apple Documentation for  more details.\n         *\n         * @platform darwin\n         */\n        getSystemColor(color: \"blue\" | \"brown\" | \"gray\" | \"green\" | \"orange\" | \"pink\" | \"purple\" | \"red\" | \"yellow\"): string;\n        /**\n         * The value of `key` in `NSUserDefaults`.\n         *\n         * Some popular `key` and `type`s are:\n         *\n         * * `AppleInterfaceStyle`: `string`\n         * * `AppleAquaColorVariant`: `integer`\n         * * `AppleHighlightColor`: `string`\n         * * `AppleShowScrollBars`: `string`\n         * * `NSNavRecentPlaces`: `array`\n         * * `NSPreferredWebServices`: `dictionary`\n         * * `NSUserDictionaryReplacementItems`: `array`\n         *\n         * @platform darwin\n         */\n        getUserDefault<Type extends keyof UserDefaultTypes>(key: string, type: Type): UserDefaultTypes[Type];\n        /**\n         * `true` if DWM composition (Aero Glass) is enabled, and `false` otherwise.\n         *\n         * An example of using it to determine if you should create a transparent window or\n         * not (transparent windows won't work correctly when DWM composition is disabled):\n         *\n         * @platform win32\n         */\n        isAeroGlassEnabled(): boolean;\n        /**\n         * Whether the system is in Dark Mode.\n         *\n         * **Deprecated:** Should use the new `nativeTheme.shouldUseDarkColors` API.\n         *\n         * @deprecated\n         * @platform darwin,win32\n         */\n        isDarkMode(): boolean;\n        /**\n         * `true` if a high contrast theme is active, `false` otherwise.\n         *\n         * **Deprecated:** Should use the new `nativeTheme.shouldUseHighContrastColors`\n         * API.\n         *\n         * @deprecated\n         * @platform darwin,win32\n         */\n        isHighContrastColorScheme(): boolean;\n        /**\n         * `true` if an inverted color scheme (a high contrast color scheme with light text\n         * and dark backgrounds) is active, `false` otherwise.\n         *\n         * **Deprecated:** Should use the new `nativeTheme.shouldUseInvertedColorScheme`\n         * API.\n         *\n         * @deprecated\n         * @platform win32\n         */\n        isInvertedColorScheme(): boolean;\n        /**\n         * Whether the Swipe between pages setting is on.\n         *\n         * @platform darwin\n         */\n        isSwipeTrackingFromScrollEventsEnabled(): boolean;\n        /**\n         * `true` if the current process is a trusted accessibility client and `false` if\n         * it is not.\n         *\n         * @platform darwin\n         */\n        isTrustedAccessibilityClient(prompt: boolean): boolean;\n        /**\n         * Posts `event` as native notifications of macOS. The `userInfo` is an Object that\n         * contains the user information dictionary sent along with the notification.\n         *\n         * @platform darwin\n         */\n        postLocalNotification(event: string, userInfo: Record<string, any>): void;\n        /**\n         * Posts `event` as native notifications of macOS. The `userInfo` is an Object that\n         * contains the user information dictionary sent along with the notification.\n         *\n         * @platform darwin\n         */\n        postNotification(event: string, userInfo: Record<string, any>, deliverImmediately?: boolean): void;\n        /**\n         * Posts `event` as native notifications of macOS. The `userInfo` is an Object that\n         * contains the user information dictionary sent along with the notification.\n         *\n         * @platform darwin\n         */\n        postWorkspaceNotification(event: string, userInfo: Record<string, any>): void;\n        /**\n         * resolves if the user has successfully authenticated with Touch ID.\n         *\n         * This API itself will not protect your user data; rather, it is a mechanism to\n         * allow you to do so. Native apps will need to set Access Control Constants like\n         * `kSecAccessControlUserPresence` on their keychain entry so that reading it would\n         * auto-prompt for Touch ID biometric consent. This could be done with\n         * `node-keytar`, such that one would store an encryption key with `node-keytar`\n         * and only fetch it if `promptTouchID()` resolves.\n         *\n         * @platform darwin\n         */\n        promptTouchID(reason: string): Promise<void>;\n        /**\n         * Add the specified defaults to your application's `NSUserDefaults`.\n         *\n         * @platform darwin\n         */\n        registerDefaults(defaults: Record<string, string | boolean | number>): void;\n        /**\n         * Removes the `key` in `NSUserDefaults`. This can be used to restore the default\n         * or global value of a `key` previously set with `setUserDefault`.\n         *\n         * @platform darwin\n         */\n        removeUserDefault(key: string): void;\n        /**\n         * Sets the appearance setting for your application, this should override the\n         * system default and override the value of `getEffectiveAppearance`.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        setAppLevelAppearance(appearance: (\"dark\" | \"light\") | null): void;\n        /**\n         * Set the value of `key` in `NSUserDefaults`.\n         *\n         * Note that `type` should match actual type of `value`. An exception is thrown if\n         * they don't.\n         *\n         * Some popular `key` and `type`s are:\n         *\n         * * `ApplePressAndHoldEnabled`: `boolean`\n         *\n         * @platform darwin\n         */\n        setUserDefault<Type extends keyof UserDefaultTypes>(key: string, type: Type, value: UserDefaultTypes[Type]): void;\n        /**\n         * The ID of this subscription\n         *\n         * Same as `subscribeNotification`, but uses `NSNotificationCenter` for local\n         * defaults. This is necessary for events such as\n         * `NSUserDefaultsDidChangeNotification`.\n         *\n         * If `event` is null, the `NSNotificationCenter` doesn’t use it as criteria for\n         * delivery to the observer. See docs for more information.\n         *\n         * @platform darwin\n         */\n        subscribeLocalNotification(event: string | null, callback: (event: string, userInfo: Record<string, unknown>, object: string) => void): number;\n        /**\n         * The ID of this subscription\n         *\n         * Subscribes to native notifications of macOS, `callback` will be called with\n         * `callback(event, userInfo)` when the corresponding `event` happens. The\n         * `userInfo` is an Object that contains the user information dictionary sent along\n         * with the notification. The `object` is the sender of the notification, and only\n         * supports `NSString` values for now.\n         *\n         * The `id` of the subscriber is returned, which can be used to unsubscribe the\n         * `event`.\n         *\n         * Under the hood this API subscribes to `NSDistributedNotificationCenter`, example\n         * values of `event` are:\n         *\n         * * `AppleInterfaceThemeChangedNotification`\n         * * `AppleAquaColorVariantChanged`\n         * * `AppleColorPreferencesChangedNotification`\n         * * `AppleShowScrollBarsSettingChanged`\n         *\n         * If `event` is null, the `NSDistributedNotificationCenter` doesn’t use it as\n         * criteria for delivery to the observer. See docs  for more information.\n         *\n         * @platform darwin\n         */\n        subscribeNotification(event: string | null, callback: (event: string, userInfo: Record<string, unknown>, object: string) => void): number;\n        /**\n         * The ID of this subscription\n         *\n         * Same as `subscribeNotification`, but uses\n         * `NSWorkspace.sharedWorkspace.notificationCenter`. This is necessary for events\n         * such as `NSWorkspaceDidActivateApplicationNotification`.\n         *\n         * If `event` is null, the `NSWorkspaceNotificationCenter` doesn’t use it as\n         * criteria for delivery to the observer. See docs for more information.\n         *\n         * @platform darwin\n         */\n        subscribeWorkspaceNotification(event: string | null, callback: (event: string, userInfo: Record<string, unknown>, object: string) => void): number;\n        /**\n         * Same as `unsubscribeNotification`, but removes the subscriber from\n         * `NSNotificationCenter`.\n         *\n         * @platform darwin\n         */\n        unsubscribeLocalNotification(id: number): void;\n        /**\n         * Removes the subscriber with `id`.\n         *\n         * @platform darwin\n         */\n        unsubscribeNotification(id: number): void;\n        /**\n         * Same as `unsubscribeNotification`, but removes the subscriber from\n         * `NSWorkspace.sharedWorkspace.notificationCenter`.\n         *\n         * @platform darwin\n         */\n        unsubscribeWorkspaceNotification(id: number): void;\n        /**\n         * A `string` property that can be `dark`, `light` or `unknown`. It determines the\n         * macOS appearance setting for your application. This maps to values in:\n         * NSApplication.appearance. Setting this will override the system default as well\n         * as the value of `getEffectiveAppearance`.\n         *\n         * Possible values that can be set are `dark` and `light`, and possible return\n         * values are `dark`, `light`, and `unknown`.\n         *\n         * This property is only available on macOS 10.14 Mojave or newer.\n         *\n         * @platform darwin\n         */\n        appLevelAppearance: \"dark\" | \"light\" | \"unknown\";\n        /**\n         * A `string` property that can be `dark`, `light` or `unknown`.\n         *\n         * Returns the macOS appearance setting that is currently applied to your\n         * application, maps to NSApplication.effectiveAppearance\n         *\n         * @platform darwin\n         */\n        readonly effectiveAppearance: \"dark\" | \"light\" | \"unknown\";\n    }\n\n    interface Task {\n        // Docs: https://electronjs.org/docs/api/structures/task\n\n        /**\n         * The command line arguments when `program` is executed.\n         */\n        arguments: string;\n        /**\n         * Description of this task.\n         */\n        description: string;\n        /**\n         * The icon index in the icon file. If an icon file consists of two or more icons,\n         * set this value to identify the icon. If an icon file consists of one icon, this\n         * value is 0.\n         */\n        iconIndex: number;\n        /**\n         * The absolute path to an icon to be displayed in a JumpList, which can be an\n         * arbitrary resource file that contains an icon. You can usually specify\n         * `process.execPath` to show the icon of the program.\n         */\n        iconPath: string;\n        /**\n         * Path of the program to execute, usually you should specify `process.execPath`\n         * which opens the current program.\n         */\n        program: string;\n        /**\n         * The string to be displayed in a JumpList.\n         */\n        title: string;\n        /**\n         * The working directory. Default is empty.\n         */\n        workingDirectory?: string;\n    }\n\n    interface ThumbarButton {\n        // Docs: https://electronjs.org/docs/api/structures/thumbar-button\n\n        click: () => void;\n        /**\n         * Control specific states and behaviors of the button. By default, it is\n         * `['enabled']`.\n         */\n        flags?: string[];\n        /**\n         * The icon showing in thumbnail toolbar.\n         */\n        icon: NativeImage;\n        /**\n         * The text of the button's tooltip.\n         */\n        tooltip?: string;\n    }\n\n    class TouchBar {\n        // Docs: https://electronjs.org/docs/api/touch-bar\n\n        /**\n         * TouchBar\n         */\n        constructor(options: TouchBarConstructorOptions);\n        /**\n         * A `TouchBarItem` that will replace the \"esc\" button on the touch bar when set.\n         * Setting to `null` restores the default \"esc\" button. Changing this value\n         * immediately updates the escape item in the touch bar.\n         */\n        escapeItem: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null;\n        /**\n         * A `typeof TouchBarButton` reference to the `TouchBarButton` class.\n         */\n        static TouchBarButton: typeof TouchBarButton;\n        /**\n         * A `typeof TouchBarColorPicker` reference to the `TouchBarColorPicker` class.\n         */\n        static TouchBarColorPicker: typeof TouchBarColorPicker;\n        /**\n         * A `typeof TouchBarGroup` reference to the `TouchBarGroup` class.\n         */\n        static TouchBarGroup: typeof TouchBarGroup;\n        /**\n         * A `typeof TouchBarLabel` reference to the `TouchBarLabel` class.\n         */\n        static TouchBarLabel: typeof TouchBarLabel;\n        /**\n         * A `typeof TouchBarOtherItemsProxy` reference to the `TouchBarOtherItemsProxy`\n         * class.\n         */\n        static TouchBarOtherItemsProxy: typeof TouchBarOtherItemsProxy;\n        /**\n         * A `typeof TouchBarPopover` reference to the `TouchBarPopover` class.\n         */\n        static TouchBarPopover: typeof TouchBarPopover;\n        /**\n         * A `typeof TouchBarScrubber` reference to the `TouchBarScrubber` class.\n         */\n        static TouchBarScrubber: typeof TouchBarScrubber;\n        /**\n         * A `typeof TouchBarSegmentedControl` reference to the `TouchBarSegmentedControl`\n         * class.\n         */\n        static TouchBarSegmentedControl: typeof TouchBarSegmentedControl;\n        /**\n         * A `typeof TouchBarSlider` reference to the `TouchBarSlider` class.\n         */\n        static TouchBarSlider: typeof TouchBarSlider;\n        /**\n         * A `typeof TouchBarSpacer` reference to the `TouchBarSpacer` class.\n         */\n        static TouchBarSpacer: typeof TouchBarSpacer;\n    }\n\n    class TouchBarButton {\n        // Docs: https://electronjs.org/docs/api/touch-bar-button\n\n        /**\n         * TouchBarButton\n         */\n        constructor(options: TouchBarButtonConstructorOptions);\n        /**\n         * A `string` representing the description of the button to be read by a screen\n         * reader. Will only be read by screen readers if no label is set.\n         */\n        accessibilityLabel: string;\n        /**\n         * A `string` hex code representing the button's current background color. Changing\n         * this value immediately updates the button in the touch bar.\n         */\n        backgroundColor: string;\n        /**\n         * A `boolean` representing whether the button is in an enabled state.\n         */\n        enabled: boolean;\n        /**\n         * A `NativeImage` representing the button's current icon. Changing this value\n         * immediately updates the button in the touch bar.\n         */\n        icon: NativeImage;\n        /**\n         * A `string` - Can be `left`, `right` or `overlay`.  Defaults to `overlay`.\n         */\n        iconPosition: \"left\" | \"right\" | \"overlay\";\n        /**\n         * A `string` representing the button's current text. Changing this value\n         * immediately updates the button in the touch bar.\n         */\n        label: string;\n    }\n\n    class TouchBarColorPicker extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-color-picker\n\n        /**\n         * TouchBarColorPicker\n         */\n        constructor(options: TouchBarColorPickerConstructorOptions);\n        /**\n         * A `string[]` array representing the color picker's available colors to select.\n         * Changing this value immediately updates the color picker in the touch bar.\n         */\n        availableColors: string[];\n        /**\n         * A `string` hex code representing the color picker's currently selected color.\n         * Changing this value immediately updates the color picker in the touch bar.\n         */\n        selectedColor: string;\n    }\n\n    class TouchBarGroup extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-group\n\n        /**\n         * TouchBarGroup\n         */\n        constructor(options: TouchBarGroupConstructorOptions);\n    }\n\n    class TouchBarLabel extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-label\n\n        /**\n         * TouchBarLabel\n         */\n        constructor(options: TouchBarLabelConstructorOptions);\n        /**\n         * A `string` representing the description of the label to be read by a screen\n         * reader.\n         */\n        accessibilityLabel: string;\n        /**\n         * A `string` representing the label's current text. Changing this value\n         * immediately updates the label in the touch bar.\n         */\n        label: string;\n        /**\n         * A `string` hex code representing the label's current text color. Changing this\n         * value immediately updates the label in the touch bar.\n         */\n        textColor: string;\n    }\n\n    class TouchBarOtherItemsProxy extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-other-items-proxy\n\n        /**\n         * TouchBarOtherItemsProxy\n         */\n        constructor();\n    }\n\n    class TouchBarPopover extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-popover\n\n        /**\n         * TouchBarPopover\n         */\n        constructor(options: TouchBarPopoverConstructorOptions);\n        /**\n         * A `NativeImage` representing the popover's current button icon. Changing this\n         * value immediately updates the popover in the touch bar.\n         */\n        icon: NativeImage;\n        /**\n         * A `string` representing the popover's current button text. Changing this value\n         * immediately updates the popover in the touch bar.\n         */\n        label: string;\n    }\n\n    class TouchBarScrubber extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-scrubber\n\n        /**\n         * TouchBarScrubber\n         */\n        constructor(options: TouchBarScrubberConstructorOptions);\n        /**\n         * A `boolean` representing whether this scrubber is continuous or not. Updating\n         * this value immediately updates the control in the touch bar.\n         */\n        continuous: boolean;\n        /**\n         * A `ScrubberItem[]` array representing the items in this scrubber. Updating this\n         * value immediately updates the control in the touch bar. Updating deep properties\n         * inside this array **does not update the touch bar**.\n         */\n        items: ScrubberItem[];\n        /**\n         * A `string` representing the mode of this scrubber. Updating this value\n         * immediately updates the control in the touch bar. Possible values:\n         *\n         * * `fixed` - Maps to `NSScrubberModeFixed`.\n         * * `free` - Maps to `NSScrubberModeFree`.\n         */\n        mode: \"fixed\" | \"free\";\n        /**\n         * A `string` representing the style that selected items in the scrubber should\n         * have. This style is overlayed on top of the scrubber item instead of being\n         * placed behind it. Updating this value immediately updates the control in the\n         * touch bar. Possible values:\n         *\n         * * `background` - Maps to `[NSScrubberSelectionStyle roundedBackgroundStyle]`.\n         * * `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`.\n         * * `none` - Removes all styles.\n         */\n        overlayStyle: \"background\" | \"outline\" | \"none\";\n        /**\n         * A `string` representing the style that selected items in the scrubber should\n         * have. Updating this value immediately updates the control in the touch bar.\n         * Possible values:\n         *\n         * * `background` - Maps to `[NSScrubberSelectionStyle roundedBackgroundStyle]`.\n         * * `outline` - Maps to `[NSScrubberSelectionStyle outlineOverlayStyle]`.\n         * * `none` - Removes all styles.\n         */\n        selectedStyle: \"background\" | \"outline\" | \"none\";\n        /**\n         * A `boolean` representing whether to show the left / right selection arrows in\n         * this scrubber. Updating this value immediately updates the control in the touch\n         * bar.\n         */\n        showArrowButtons: boolean;\n    }\n\n    class TouchBarSegmentedControl extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-segmented-control\n\n        /**\n         * TouchBarSegmentedControl\n         */\n        constructor(options: TouchBarSegmentedControlConstructorOptions);\n        /**\n         * A `string` representing the current selection mode of the control.  Can be\n         * `single`, `multiple` or `buttons`.\n         */\n        mode: \"single\" | \"multiple\" | \"buttons\";\n        /**\n         * A `SegmentedControlSegment[]` array representing the segments in this control.\n         * Updating this value immediately updates the control in the touch bar. Updating\n         * deep properties inside this array **does not update the touch bar**.\n         */\n        segments: SegmentedControlSegment[];\n        /**\n         * A `string` representing the controls current segment style. Updating this value\n         * immediately updates the control in the touch bar.\n         */\n        segmentStyle: string;\n        /**\n         * An `Integer` representing the currently selected segment. Changing this value\n         * immediately updates the control in the touch bar. User interaction with the\n         * touch bar will update this value automatically.\n         */\n        selectedIndex: number;\n    }\n\n    class TouchBarSlider extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-slider\n\n        /**\n         * TouchBarSlider\n         */\n        constructor(options: TouchBarSliderConstructorOptions);\n        /**\n         * A `string` representing the slider's current text. Changing this value\n         * immediately updates the slider in the touch bar.\n         */\n        label: string;\n        /**\n         * A `number` representing the slider's current maximum value. Changing this value\n         * immediately updates the slider in the touch bar.\n         */\n        maxValue: number;\n        /**\n         * A `number` representing the slider's current minimum value. Changing this value\n         * immediately updates the slider in the touch bar.\n         */\n        minValue: number;\n        /**\n         * A `number` representing the slider's current value. Changing this value\n         * immediately updates the slider in the touch bar.\n         */\n        value: number;\n    }\n\n    class TouchBarSpacer extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/touch-bar-spacer\n\n        /**\n         * TouchBarSpacer\n         */\n        constructor(options: TouchBarSpacerConstructorOptions);\n        /**\n         * A `string` representing the size of the spacer.  Can be `small`, `large` or\n         * `flexible`.\n         */\n        size: \"small\" | \"large\" | \"flexible\";\n    }\n\n    interface TraceCategoriesAndOptions {\n        // Docs: https://electronjs.org/docs/api/structures/trace-categories-and-options\n\n        /**\n         * A filter to control what category groups should be traced. A filter can have an\n         * optional '-' prefix to exclude category groups that contain a matching category.\n         * Having both included and excluded category patterns in the same list is not\n         * supported. Examples: `test_MyTest*`, `test_MyTest*,test_OtherStuff`,\n         * `-excluded_category1,-excluded_category2`.\n         */\n        categoryFilter: string;\n        /**\n         * Controls what kind of tracing is enabled, it is a comma-delimited sequence of\n         * the following strings: `record-until-full`, `record-continuously`,\n         * `trace-to-console`, `enable-sampling`, `enable-systrace`, e.g.\n         * `'record-until-full,enable-sampling'`. The first 3 options are trace recording\n         * modes and hence mutually exclusive. If more than one trace recording modes\n         * appear in the `traceOptions` string, the last one takes precedence. If none of\n         * the trace recording modes are specified, recording mode is `record-until-full`.\n         * The trace option will first be reset to the default option (`record_mode` set to\n         * `record-until-full`, `enable_sampling` and `enable_systrace` set to `false`)\n         * before options parsed from `traceOptions` are applied on it.\n         */\n        traceOptions: string;\n    }\n\n    interface TraceConfig {\n        // Docs: https://electronjs.org/docs/api/structures/trace-config\n\n        /**\n         * if true, filter event data according to a specific list of events that have been\n         * manually vetted to not include any PII. See the implementation in Chromium for\n         * specifics.\n         */\n        enable_argument_filter?: boolean;\n        /**\n         * a list of tracing categories to exclude. Can include glob-like patterns using\n         * `*` at the end of the category name. See tracing categories for the list of\n         * categories.\n         */\n        excluded_categories?: string[];\n        /**\n         * a list of histogram names to report with the trace.\n         */\n        histogram_names?: string[];\n        /**\n         * a list of tracing categories to include. Can include glob-like patterns using\n         * `*` at the end of the category name. See tracing categories for the list of\n         * categories.\n         */\n        included_categories?: string[];\n        /**\n         * a list of process IDs to include in the trace. If not specified, trace all\n         * processes.\n         */\n        included_process_ids?: number[];\n        /**\n         * if the `disabled-by-default-memory-infra` category is enabled, this contains\n         * optional additional configuration for data collection. See the Chromium\n         * memory-infra docs for more information.\n         */\n        memory_dump_config?: Record<string, any>;\n        /**\n         * Can be `record-until-full`, `record-continuously`, `record-as-much-as-possible`\n         * or `trace-to-console`. Defaults to `record-until-full`.\n         */\n        recording_mode?: \"record-until-full\" | \"record-continuously\" | \"record-as-much-as-possible\" | \"trace-to-console\";\n        /**\n         * maximum size of the trace recording buffer in events.\n         */\n        trace_buffer_size_in_events?: number;\n        /**\n         * maximum size of the trace recording buffer in kilobytes. Defaults to 100MB.\n         */\n        trace_buffer_size_in_kb?: number;\n    }\n\n    interface Transaction {\n        // Docs: https://electronjs.org/docs/api/structures/transaction\n\n        /**\n         * The error code if an error occurred while processing the transaction.\n         */\n        errorCode: number;\n        /**\n         * The error message if an error occurred while processing the transaction.\n         */\n        errorMessage: string;\n        /**\n         * The identifier of the restored transaction by the App Store.\n         */\n        originalTransactionIdentifier: string;\n        payment: Payment;\n        /**\n         * The date the transaction was added to the App Store’s payment queue.\n         */\n        transactionDate: string;\n        /**\n         * A string that uniquely identifies a successful payment transaction.\n         */\n        transactionIdentifier: string;\n        /**\n         * The transaction state, can be `purchasing`, `purchased`, `failed`, `restored` or\n         * `deferred`.\n         */\n        transactionState: \"purchasing\" | \"purchased\" | \"failed\" | \"restored\" | \"deferred\";\n    }\n\n    class Tray extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/tray\n\n        /**\n         * Emitted when the tray balloon is clicked.\n         *\n         * @platform win32\n         */\n        on(event: \"balloon-click\", listener: Function): this;\n        once(event: \"balloon-click\", listener: Function): this;\n        addListener(event: \"balloon-click\", listener: Function): this;\n        removeListener(event: \"balloon-click\", listener: Function): this;\n        /**\n         * Emitted when the tray balloon is closed because of timeout or user manually\n         * closes it.\n         *\n         * @platform win32\n         */\n        on(event: \"balloon-closed\", listener: Function): this;\n        once(event: \"balloon-closed\", listener: Function): this;\n        addListener(event: \"balloon-closed\", listener: Function): this;\n        removeListener(event: \"balloon-closed\", listener: Function): this;\n        /**\n         * Emitted when the tray balloon shows.\n         *\n         * @platform win32\n         */\n        on(event: \"balloon-show\", listener: Function): this;\n        once(event: \"balloon-show\", listener: Function): this;\n        addListener(event: \"balloon-show\", listener: Function): this;\n        removeListener(event: \"balloon-show\", listener: Function): this;\n        /**\n         * Emitted when the tray icon is clicked.\n         *\n         * Note that on Linux this event is emitted when the tray icon receives an\n         * activation, which might not necessarily be left mouse click.\n         */\n        on(\n            event: \"click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the tray icon is double clicked.\n         *\n         * @platform darwin,win32\n         */\n        on(\n            event: \"double-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        once(\n            event: \"double-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"double-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"double-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a drag operation ends on the tray or ends at another location.\n         *\n         * @platform darwin\n         */\n        on(event: \"drag-end\", listener: Function): this;\n        once(event: \"drag-end\", listener: Function): this;\n        addListener(event: \"drag-end\", listener: Function): this;\n        removeListener(event: \"drag-end\", listener: Function): this;\n        /**\n         * Emitted when a drag operation enters the tray icon.\n         *\n         * @platform darwin\n         */\n        on(event: \"drag-enter\", listener: Function): this;\n        once(event: \"drag-enter\", listener: Function): this;\n        addListener(event: \"drag-enter\", listener: Function): this;\n        removeListener(event: \"drag-enter\", listener: Function): this;\n        /**\n         * Emitted when a drag operation exits the tray icon.\n         *\n         * @platform darwin\n         */\n        on(event: \"drag-leave\", listener: Function): this;\n        once(event: \"drag-leave\", listener: Function): this;\n        addListener(event: \"drag-leave\", listener: Function): this;\n        removeListener(event: \"drag-leave\", listener: Function): this;\n        /**\n         * Emitted when any dragged items are dropped on the tray icon.\n         *\n         * @platform darwin\n         */\n        on(event: \"drop\", listener: Function): this;\n        once(event: \"drop\", listener: Function): this;\n        addListener(event: \"drop\", listener: Function): this;\n        removeListener(event: \"drop\", listener: Function): this;\n        /**\n         * Emitted when dragged files are dropped in the tray icon.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"drop-files\",\n            listener: (\n                event: Event,\n                /**\n                 * The paths of the dropped files.\n                 */\n                files: string[],\n            ) => void,\n        ): this;\n        once(\n            event: \"drop-files\",\n            listener: (\n                event: Event,\n                /**\n                 * The paths of the dropped files.\n                 */\n                files: string[],\n            ) => void,\n        ): this;\n        addListener(\n            event: \"drop-files\",\n            listener: (\n                event: Event,\n                /**\n                 * The paths of the dropped files.\n                 */\n                files: string[],\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"drop-files\",\n            listener: (\n                event: Event,\n                /**\n                 * The paths of the dropped files.\n                 */\n                files: string[],\n            ) => void,\n        ): this;\n        /**\n         * Emitted when dragged text is dropped in the tray icon.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"drop-text\",\n            listener: (\n                event: Event,\n                /**\n                 * the dropped text string.\n                 */\n                text: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"drop-text\",\n            listener: (\n                event: Event,\n                /**\n                 * the dropped text string.\n                 */\n                text: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"drop-text\",\n            listener: (\n                event: Event,\n                /**\n                 * the dropped text string.\n                 */\n                text: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"drop-text\",\n            listener: (\n                event: Event,\n                /**\n                 * the dropped text string.\n                 */\n                text: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the mouse clicks the tray icon.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"mouse-down\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"mouse-down\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"mouse-down\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"mouse-down\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the mouse enters the tray icon.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"mouse-enter\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"mouse-enter\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"mouse-enter\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"mouse-enter\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the mouse exits the tray icon.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"mouse-leave\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"mouse-leave\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"mouse-leave\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"mouse-leave\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the mouse moves in the tray icon.\n         *\n         * @platform darwin,win32\n         */\n        on(\n            event: \"mouse-move\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"mouse-move\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"mouse-move\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"mouse-move\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the mouse is released from clicking the tray icon.\n         *\n         * Note: This will not be emitted if you have set a context menu for your Tray\n         * using `tray.setContextMenu`, as a result of macOS-level constraints.\n         *\n         * @platform darwin\n         */\n        on(\n            event: \"mouse-up\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"mouse-up\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"mouse-up\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"mouse-up\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The position of the event.\n                 */\n                position: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the tray icon is right clicked.\n         *\n         * @platform darwin,win32\n         */\n        on(\n            event: \"right-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        once(\n            event: \"right-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"right-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"right-click\",\n            listener: (\n                event: KeyboardEvent,\n                /**\n                 * The bounds of tray icon.\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        /**\n         * Tray\n         */\n        constructor(image: NativeImage | string, guid?: string);\n        /**\n         * Closes an open context menu, as set by `tray.setContextMenu()`.\n         *\n         * @platform darwin,win32\n         */\n        closeContextMenu(): void;\n        /**\n         * Destroys the tray icon immediately.\n         */\n        destroy(): void;\n        /**\n         * Displays a tray balloon.\n         *\n         * @platform win32\n         */\n        displayBalloon(options: DisplayBalloonOptions): void;\n        /**\n         * Returns focus to the taskbar notification area. Notification area icons should\n         * use this message when they have completed their UI operation. For example, if\n         * the icon displays a shortcut menu, but the user presses ESC to cancel it, use\n         * `tray.focus()` to return focus to the notification area.\n         *\n         * @platform win32\n         */\n        focus(): void;\n        /**\n         * The `bounds` of this tray icon as `Object`.\n         *\n         * @platform darwin,win32\n         */\n        getBounds(): Rectangle;\n        /**\n         * Whether double click events will be ignored.\n         *\n         * @platform darwin\n         */\n        getIgnoreDoubleClickEvents(): boolean;\n        /**\n         * the title displayed next to the tray icon in the status bar\n         *\n         * @platform darwin\n         */\n        getTitle(): string;\n        /**\n         * Whether the tray icon is destroyed.\n         */\n        isDestroyed(): boolean;\n        /**\n         * Pops up the context menu of the tray icon. When `menu` is passed, the `menu`\n         * will be shown instead of the tray icon's context menu.\n         *\n         * The `position` is only available on Windows, and it is (0, 0) by default.\n         *\n         * @platform darwin,win32\n         */\n        popUpContextMenu(menu?: Menu, position?: Point): void;\n        /**\n         * Removes a tray balloon.\n         *\n         * @platform win32\n         */\n        removeBalloon(): void;\n        /**\n         * Sets the context menu for this icon.\n         */\n        setContextMenu(menu: Menu | null): void;\n        /**\n         * Sets the option to ignore double click events. Ignoring these events allows you\n         * to detect every individual click of the tray icon.\n         *\n         * This value is set to false by default.\n         *\n         * @platform darwin\n         */\n        setIgnoreDoubleClickEvents(ignore: boolean): void;\n        /**\n         * Sets the `image` associated with this tray icon.\n         */\n        setImage(image: NativeImage | string): void;\n        /**\n         * Sets the `image` associated with this tray icon when pressed on macOS.\n         *\n         * @platform darwin\n         */\n        setPressedImage(image: NativeImage | string): void;\n        /**\n         * Sets the title displayed next to the tray icon in the status bar (Support ANSI\n         * colors).\n         *\n         * @platform darwin\n         */\n        setTitle(title: string, options?: TitleOptions): void;\n        /**\n         * Sets the hover text for this tray icon.\n         */\n        setToolTip(toolTip: string): void;\n    }\n\n    interface UploadData {\n        // Docs: https://electronjs.org/docs/api/structures/upload-data\n\n        /**\n         * UUID of blob data. Use ses.getBlobData method to retrieve the data.\n         */\n        blobUUID?: string;\n        /**\n         * Content being sent.\n         */\n        bytes: Buffer;\n        /**\n         * Path of file being uploaded.\n         */\n        file?: string;\n    }\n\n    interface UploadFile {\n        // Docs: https://electronjs.org/docs/api/structures/upload-file\n\n        /**\n         * Path of file to be uploaded.\n         */\n        filePath: string;\n        /**\n         * Number of bytes to read from `offset`. Defaults to `0`.\n         */\n        length?: number;\n        /**\n         * Last Modification time in number of seconds since the UNIX epoch. Defaults to\n         * `0`.\n         */\n        modificationTime?: number;\n        /**\n         * Defaults to `0`.\n         */\n        offset?: number;\n        /**\n         * `file`.\n         */\n        type: \"file\";\n    }\n\n    interface UploadRawData {\n        // Docs: https://electronjs.org/docs/api/structures/upload-raw-data\n\n        /**\n         * Data to be uploaded.\n         */\n        bytes: Buffer;\n        /**\n         * `rawData`.\n         */\n        type: \"rawData\";\n    }\n\n    interface USBDevice {\n        // Docs: https://electronjs.org/docs/api/structures/usb-device\n\n        /**\n         * The device class for the communication interface supported by the device\n         */\n        deviceClass: number;\n        /**\n         * Unique identifier for the device.\n         */\n        deviceId: string;\n        /**\n         * The device protocol for the communication interface supported by the device\n         */\n        deviceProtocol: number;\n        /**\n         * The device subclass for the communication interface supported by the device\n         */\n        deviceSubclass: number;\n        /**\n         * The major version number of the device as defined by the device manufacturer.\n         */\n        deviceVersionMajor: number;\n        /**\n         * The minor version number of the device as defined by the device manufacturer.\n         */\n        deviceVersionMinor: number;\n        /**\n         * The subminor version number of the device as defined by the device manufacturer.\n         */\n        deviceVersionSubminor: number;\n        /**\n         * The manufacturer name of the device.\n         */\n        manufacturerName?: string;\n        /**\n         * The USB product ID.\n         */\n        productId: number;\n        /**\n         * Name of the device.\n         */\n        productName?: string;\n        /**\n         * The USB device serial number.\n         */\n        serialNumber?: string;\n        /**\n         * The USB protocol major version supported by the device\n         */\n        usbVersionMajor: number;\n        /**\n         * The USB protocol minor version supported by the device\n         */\n        usbVersionMinor: number;\n        /**\n         * The USB protocol subminor version supported by the device\n         */\n        usbVersionSubminor: number;\n        /**\n         * The USB vendor ID.\n         */\n        vendorId: number;\n    }\n\n    interface UserDefaultTypes {\n        // Docs: https://electronjs.org/docs/api/structures/user-default-types\n\n        array: Array<unknown>;\n        boolean: boolean;\n        dictionary: Record<string, unknown>;\n        double: number;\n        float: number;\n        integer: number;\n        string: string;\n        url: string;\n    }\n\n    class UtilityProcess extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/utility-process\n\n        static fork(modulePath: string, args?: string[], options?: ForkOptions): UtilityProcess;\n        /**\n         * Emitted after the child process ends.\n         */\n        on(\n            event: \"exit\",\n            listener: (\n                /**\n                 * Contains the exit code for the process obtained from waitpid on posix, or\n                 * GetExitCodeProcess on windows.\n                 */\n                code: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"exit\",\n            listener: (\n                /**\n                 * Contains the exit code for the process obtained from waitpid on posix, or\n                 * GetExitCodeProcess on windows.\n                 */\n                code: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"exit\",\n            listener: (\n                /**\n                 * Contains the exit code for the process obtained from waitpid on posix, or\n                 * GetExitCodeProcess on windows.\n                 */\n                code: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"exit\",\n            listener: (\n                /**\n                 * Contains the exit code for the process obtained from waitpid on posix, or\n                 * GetExitCodeProcess on windows.\n                 */\n                code: number,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the child process sends a message using\n         * `process.parentPort.postMessage()`.\n         */\n        on(event: \"message\", listener: (message: any) => void): this;\n        once(event: \"message\", listener: (message: any) => void): this;\n        addListener(event: \"message\", listener: (message: any) => void): this;\n        removeListener(event: \"message\", listener: (message: any) => void): this;\n        /**\n         * Emitted once the child process has spawned successfully.\n         */\n        on(event: \"spawn\", listener: Function): this;\n        once(event: \"spawn\", listener: Function): this;\n        addListener(event: \"spawn\", listener: Function): this;\n        removeListener(event: \"spawn\", listener: Function): this;\n        /**\n         * Terminates the process gracefully. On POSIX, it uses SIGTERM but will ensure the\n         * process is reaped on exit. This function returns true if the kill is successful,\n         * and false otherwise.\n         */\n        kill(): boolean;\n        /**\n         * Send a message to the child process, optionally transferring ownership of zero\n         * or more `MessagePortMain` objects.\n         *\n         * For example:\n         */\n        postMessage(message: any, transfer?: MessagePortMain[]): void;\n        /**\n         * A `Integer | undefined` representing the process identifier (PID) of the child\n         * process. If the child process fails to spawn due to errors, then the value is\n         * `undefined`. When the child process exits, then the value is `undefined` after\n         * the `exit` event is emitted.\n         */\n        pid: number | undefined;\n        /**\n         * A `NodeJS.ReadableStream | null` that represents the child process's stderr. If\n         * the child was spawned with options.stdio[2] set to anything other than 'pipe',\n         * then this will be `null`. When the child process exits, then the value is `null`\n         * after the `exit` event is emitted.\n         */\n        stderr: NodeJS.ReadableStream | null;\n        /**\n         * A `NodeJS.ReadableStream | null` that represents the child process's stdout. If\n         * the child was spawned with options.stdio[1] set to anything other than 'pipe',\n         * then this will be `null`. When the child process exits, then the value is `null`\n         * after the `exit` event is emitted.\n         */\n        stdout: NodeJS.ReadableStream | null;\n    }\n\n    class WebContents extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/web-contents\n\n        /**\n         * A WebContents instance with the given TargetID, or `undefined` if there is no\n         * WebContents associated with the given TargetID.\n         *\n         * When communicating with the Chrome DevTools Protocol, it can be useful to lookup\n         * a WebContents instance based on its assigned TargetID.\n         */\n        static fromDevToolsTargetId(targetId: string): WebContents | undefined;\n        /**\n         * A WebContents instance with the given WebFrameMain, or `undefined` if there is\n         * no WebContents associated with the given WebFrameMain.\n         */\n        static fromFrame(frame: WebFrameMain): WebContents | undefined;\n        /**\n         * A WebContents instance with the given ID, or `undefined` if there is no\n         * WebContents associated with the given ID.\n         */\n        static fromId(id: number): WebContents | undefined;\n        /**\n         * An array of all `WebContents` instances. This will contain web contents for all\n         * windows, webviews, opened devtools, and devtools extension background pages.\n         */\n        static getAllWebContents(): WebContents[];\n        /**\n         * The web contents that is focused in this application, otherwise returns `null`.\n         */\n        static getFocusedWebContents(): WebContents | null;\n        /**\n         * Emitted when media becomes audible or inaudible.\n         */\n        on(event: \"audio-state-changed\", listener: (event: Event<WebContentsAudioStateChangedEventParams>) => void): this;\n        once(event: \"audio-state-changed\", listener: (event: Event<WebContentsAudioStateChangedEventParams>) => void): this;\n        addListener(event: \"audio-state-changed\", listener: (event: Event<WebContentsAudioStateChangedEventParams>) => void): this;\n        removeListener(event: \"audio-state-changed\", listener: (event: Event<WebContentsAudioStateChangedEventParams>) => void): this;\n        /**\n         * Emitted before dispatching the `keydown` and `keyup` events in the page. Calling\n         * `event.preventDefault` will prevent the page `keydown`/`keyup` events and the\n         * menu shortcuts.\n         *\n         * To only prevent the menu shortcuts, use `setIgnoreMenuShortcuts`:\n         */\n        on(\n            event: \"before-input-event\",\n            listener: (\n                event: Event,\n                /**\n                 * Input properties.\n                 */\n                input: Input,\n            ) => void,\n        ): this;\n        once(\n            event: \"before-input-event\",\n            listener: (\n                event: Event,\n                /**\n                 * Input properties.\n                 */\n                input: Input,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"before-input-event\",\n            listener: (\n                event: Event,\n                /**\n                 * Input properties.\n                 */\n                input: Input,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"before-input-event\",\n            listener: (\n                event: Event,\n                /**\n                 * Input properties.\n                 */\n                input: Input,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the `WebContents` loses focus.\n         */\n        on(event: \"blur\", listener: Function): this;\n        once(event: \"blur\", listener: Function): this;\n        addListener(event: \"blur\", listener: Function): this;\n        removeListener(event: \"blur\", listener: Function): this;\n        /**\n         * Emitted when failed to verify the `certificate` for `url`.\n         *\n         * The usage is the same with the `certificate-error` event of `app`.\n         */\n        on(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * The error code.\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        once(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * The error code.\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * The error code.\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"certificate-error\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * The error code.\n                 */\n                error: string,\n                certificate: Certificate,\n                callback: (isTrusted: boolean) => void,\n                isMainFrame: boolean,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the associated window logs a console message.\n         */\n        on(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and\n                 * `error`.\n                 */\n                level: number,\n                /**\n                 * The actual console message\n                 */\n                message: string,\n                /**\n                 * The line number of the source that triggered this console message\n                 */\n                line: number,\n                sourceId: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and\n                 * `error`.\n                 */\n                level: number,\n                /**\n                 * The actual console message\n                 */\n                message: string,\n                /**\n                 * The line number of the source that triggered this console message\n                 */\n                line: number,\n                sourceId: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and\n                 * `error`.\n                 */\n                level: number,\n                /**\n                 * The actual console message\n                 */\n                message: string,\n                /**\n                 * The line number of the source that triggered this console message\n                 */\n                line: number,\n                sourceId: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"console-message\",\n            listener: (\n                event: Event,\n                /**\n                 * The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and\n                 * `error`.\n                 */\n                level: number,\n                /**\n                 * The actual console message\n                 */\n                message: string,\n                /**\n                 * The line number of the source that triggered this console message\n                 */\n                line: number,\n                sourceId: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the page calls `window.moveTo`, `window.resizeTo` or related APIs.\n         *\n         * By default, this will move the window. To prevent that behavior, call\n         * `event.preventDefault()`.\n         */\n        on(\n            event: \"content-bounds-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * requested new content bounds\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        once(\n            event: \"content-bounds-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * requested new content bounds\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"content-bounds-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * requested new content bounds\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"content-bounds-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * requested new content bounds\n                 */\n                bounds: Rectangle,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when there is a new context menu that needs to be handled.\n         */\n        on(event: \"context-menu\", listener: (event: Event, params: ContextMenuParams) => void): this;\n        once(event: \"context-menu\", listener: (event: Event, params: ContextMenuParams) => void): this;\n        addListener(event: \"context-menu\", listener: (event: Event, params: ContextMenuParams) => void): this;\n        removeListener(event: \"context-menu\", listener: (event: Event, params: ContextMenuParams) => void): this;\n        /**\n         * Emitted when the renderer process crashes or is killed.\n         *\n         * **Deprecated:** This event is superceded by the `render-process-gone` event\n         * which contains more information about why the render process disappeared. It\n         * isn't always because it crashed.  The `killed` boolean can be replaced by\n         * checking `reason === 'killed'` when you switch to that event.\n         *\n         * @deprecated\n         */\n        on(event: \"crashed\", listener: (event: Event, killed: boolean) => void): this;\n        once(event: \"crashed\", listener: (event: Event, killed: boolean) => void): this;\n        addListener(event: \"crashed\", listener: (event: Event, killed: boolean) => void): this;\n        removeListener(event: \"crashed\", listener: (event: Event, killed: boolean) => void): this;\n        /**\n         * Emitted when the cursor's type changes. The `type` parameter can be `pointer`,\n         * `crosshair`, `hand`, `text`, `wait`, `help`, `e-resize`, `n-resize`,\n         * `ne-resize`, `nw-resize`, `s-resize`, `se-resize`, `sw-resize`, `w-resize`,\n         * `ns-resize`, `ew-resize`, `nesw-resize`, `nwse-resize`, `col-resize`,\n         * `row-resize`, `m-panning`, `m-panning-vertical`, `m-panning-horizontal`,\n         * `e-panning`, `n-panning`, `ne-panning`, `nw-panning`, `s-panning`, `se-panning`,\n         * `sw-panning`, `w-panning`, `move`, `vertical-text`, `cell`, `context-menu`,\n         * `alias`, `progress`, `nodrop`, `copy`, `none`, `not-allowed`, `zoom-in`,\n         * `zoom-out`, `grab`, `grabbing`, `custom`, `null`, `drag-drop-none`,\n         * `drag-drop-move`, `drag-drop-copy`, `drag-drop-link`, `ns-no-resize`,\n         * `ew-no-resize`, `nesw-no-resize`, `nwse-no-resize`, or `default`.\n         *\n         * If the `type` parameter is `custom`, the `image` parameter will hold the custom\n         * cursor image in a `NativeImage`, and `scale`, `size` and `hotspot` will hold\n         * additional information about the custom cursor.\n         */\n        on(\n            event: \"cursor-changed\",\n            listener: (\n                event: Event,\n                type: string,\n                image: NativeImage,\n                /**\n                 * scaling factor for the custom cursor.\n                 */\n                scale: number,\n                /**\n                 * the size of the `image`.\n                 */\n                size: Size,\n                /**\n                 * coordinates of the custom cursor's hotspot.\n                 */\n                hotspot: Point,\n            ) => void,\n        ): this;\n        once(\n            event: \"cursor-changed\",\n            listener: (\n                event: Event,\n                type: string,\n                image: NativeImage,\n                /**\n                 * scaling factor for the custom cursor.\n                 */\n                scale: number,\n                /**\n                 * the size of the `image`.\n                 */\n                size: Size,\n                /**\n                 * coordinates of the custom cursor's hotspot.\n                 */\n                hotspot: Point,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"cursor-changed\",\n            listener: (\n                event: Event,\n                type: string,\n                image: NativeImage,\n                /**\n                 * scaling factor for the custom cursor.\n                 */\n                scale: number,\n                /**\n                 * the size of the `image`.\n                 */\n                size: Size,\n                /**\n                 * coordinates of the custom cursor's hotspot.\n                 */\n                hotspot: Point,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"cursor-changed\",\n            listener: (\n                event: Event,\n                type: string,\n                image: NativeImage,\n                /**\n                 * scaling factor for the custom cursor.\n                 */\n                scale: number,\n                /**\n                 * the size of the `image`.\n                 */\n                size: Size,\n                /**\n                 * coordinates of the custom cursor's hotspot.\n                 */\n                hotspot: Point,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when `webContents` is destroyed.\n         */\n        on(event: \"destroyed\", listener: Function): this;\n        once(event: \"destroyed\", listener: Function): this;\n        addListener(event: \"destroyed\", listener: Function): this;\n        removeListener(event: \"destroyed\", listener: Function): this;\n        /**\n         * Emitted when DevTools is closed.\n         */\n        on(event: \"devtools-closed\", listener: Function): this;\n        once(event: \"devtools-closed\", listener: Function): this;\n        addListener(event: \"devtools-closed\", listener: Function): this;\n        removeListener(event: \"devtools-closed\", listener: Function): this;\n        /**\n         * Emitted when DevTools is focused / opened.\n         */\n        on(event: \"devtools-focused\", listener: Function): this;\n        once(event: \"devtools-focused\", listener: Function): this;\n        addListener(event: \"devtools-focused\", listener: Function): this;\n        removeListener(event: \"devtools-focused\", listener: Function): this;\n        /**\n         * Emitted when a link is clicked in DevTools or 'Open in new tab' is selected for\n         * a link in its context menu.\n         */\n        on(\n            event: \"devtools-open-url\",\n            listener: (\n                event: Event,\n                /**\n                 * URL of the link that was clicked or selected.\n                 */\n                url: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"devtools-open-url\",\n            listener: (\n                event: Event,\n                /**\n                 * URL of the link that was clicked or selected.\n                 */\n                url: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"devtools-open-url\",\n            listener: (\n                event: Event,\n                /**\n                 * URL of the link that was clicked or selected.\n                 */\n                url: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"devtools-open-url\",\n            listener: (\n                event: Event,\n                /**\n                 * URL of the link that was clicked or selected.\n                 */\n                url: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when DevTools is opened.\n         */\n        on(event: \"devtools-opened\", listener: Function): this;\n        once(event: \"devtools-opened\", listener: Function): this;\n        addListener(event: \"devtools-opened\", listener: Function): this;\n        removeListener(event: \"devtools-opened\", listener: Function): this;\n        /**\n         * Emitted when the devtools window instructs the webContents to reload\n         */\n        on(event: \"devtools-reload-page\", listener: Function): this;\n        once(event: \"devtools-reload-page\", listener: Function): this;\n        addListener(event: \"devtools-reload-page\", listener: Function): this;\n        removeListener(event: \"devtools-reload-page\", listener: Function): this;\n        /**\n         * Emitted when a `<webview>` has been attached to this web contents.\n         */\n        on(\n            event: \"did-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The guest web contents that is used by the `<webview>`.\n                 */\n                webContents: WebContents,\n            ) => void,\n        ): this;\n        once(\n            event: \"did-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The guest web contents that is used by the `<webview>`.\n                 */\n                webContents: WebContents,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"did-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The guest web contents that is used by the `<webview>`.\n                 */\n                webContents: WebContents,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"did-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The guest web contents that is used by the `<webview>`.\n                 */\n                webContents: WebContents,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a page's theme color changes. This is usually due to encountering a\n         * meta tag:\n         */\n        on(\n            event: \"did-change-theme-color\",\n            listener: (\n                event: Event,\n                /**\n                 * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set.\n                 */\n                color: string | null,\n            ) => void,\n        ): this;\n        once(\n            event: \"did-change-theme-color\",\n            listener: (\n                event: Event,\n                /**\n                 * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set.\n                 */\n                color: string | null,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"did-change-theme-color\",\n            listener: (\n                event: Event,\n                /**\n                 * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set.\n                 */\n                color: string | null,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"did-change-theme-color\",\n            listener: (\n                event: Event,\n                /**\n                 * Theme color is in format of '#rrggbb'. It is `null` when no theme color is set.\n                 */\n                color: string | null,\n            ) => void,\n        ): this;\n        /**\n         * Emitted _after_ successful creation of a window via `window.open` in the\n         * renderer. Not emitted if the creation of the window is canceled from\n         * `webContents.setWindowOpenHandler`.\n         *\n         * See `window.open()` for more details and how to use this in conjunction with\n         * `webContents.setWindowOpenHandler`.\n         */\n        on(event: \"did-create-window\", listener: (window: BrowserWindow, details: DidCreateWindowDetails) => void): this;\n        once(event: \"did-create-window\", listener: (window: BrowserWindow, details: DidCreateWindowDetails) => void): this;\n        addListener(event: \"did-create-window\", listener: (window: BrowserWindow, details: DidCreateWindowDetails) => void): this;\n        removeListener(event: \"did-create-window\", listener: (window: BrowserWindow, details: DidCreateWindowDetails) => void): this;\n        /**\n         * This event is like `did-finish-load` but emitted when the load failed. The full\n         * list of error codes and their meaning is available here.\n         */\n        on(event: \"did-fail-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        once(event: \"did-fail-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        addListener(event: \"did-fail-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        removeListener(event: \"did-fail-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        /**\n         * This event is like `did-fail-load` but emitted when the load was cancelled (e.g.\n         * `window.stop()` was invoked).\n         */\n        on(event: \"did-fail-provisional-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        once(event: \"did-fail-provisional-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        addListener(event: \"did-fail-provisional-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        removeListener(event: \"did-fail-provisional-load\", listener: (event: Event, errorCode: number, errorDescription: string, validatedURL: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        /**\n         * Emitted when the navigation is done, i.e. the spinner of the tab has stopped\n         * spinning, and the `onload` event was dispatched.\n         */\n        on(event: \"did-finish-load\", listener: Function): this;\n        once(event: \"did-finish-load\", listener: Function): this;\n        addListener(event: \"did-finish-load\", listener: Function): this;\n        removeListener(event: \"did-finish-load\", listener: Function): this;\n        /**\n         * Emitted when a frame has done navigation.\n         */\n        on(event: \"did-frame-finish-load\", listener: (event: Event, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        once(event: \"did-frame-finish-load\", listener: (event: Event, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        addListener(event: \"did-frame-finish-load\", listener: (event: Event, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        removeListener(event: \"did-frame-finish-load\", listener: (event: Event, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        /**\n         * Emitted when any frame navigation is done.\n         *\n         * This event is not emitted for in-page navigations, such as clicking anchor links\n         * or updating the `window.location.hash`. Use `did-navigate-in-page` event for\n         * this purpose.\n         */\n        on(\n            event: \"did-frame-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations,\n                 */\n                httpStatusText: string,\n                isMainFrame: boolean,\n                frameProcessId: number,\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"did-frame-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations,\n                 */\n                httpStatusText: string,\n                isMainFrame: boolean,\n                frameProcessId: number,\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"did-frame-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations,\n                 */\n                httpStatusText: string,\n                isMainFrame: boolean,\n                frameProcessId: number,\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"did-frame-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations,\n                 */\n                httpStatusText: string,\n                isMainFrame: boolean,\n                frameProcessId: number,\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a main frame navigation is done.\n         *\n         * This event is not emitted for in-page navigations, such as clicking anchor links\n         * or updating the `window.location.hash`. Use `did-navigate-in-page` event for\n         * this purpose.\n         */\n        on(\n            event: \"did-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations\n                 */\n                httpStatusText: string,\n            ) => void,\n        ): this;\n        once(\n            event: \"did-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations\n                 */\n                httpStatusText: string,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"did-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations\n                 */\n                httpStatusText: string,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"did-navigate\",\n            listener: (\n                event: Event,\n                url: string,\n                /**\n                 * -1 for non HTTP navigations\n                 */\n                httpResponseCode: number,\n                /**\n                 * empty for non HTTP navigations\n                 */\n                httpStatusText: string,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when an in-page navigation happened in any frame.\n         *\n         * When in-page navigation happens, the page URL changes but does not cause\n         * navigation outside of the page. Examples of this occurring are when anchor links\n         * are clicked or when the DOM `hashchange` event is triggered.\n         */\n        on(event: \"did-navigate-in-page\", listener: (event: Event, url: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        once(event: \"did-navigate-in-page\", listener: (event: Event, url: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        addListener(event: \"did-navigate-in-page\", listener: (event: Event, url: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        removeListener(event: \"did-navigate-in-page\", listener: (event: Event, url: string, isMainFrame: boolean, frameProcessId: number, frameRoutingId: number) => void): this;\n        /**\n         * Emitted after a server side redirect occurs during navigation.  For example a\n         * 302 redirect.\n         *\n         * This event cannot be prevented, if you want to prevent redirects you should\n         * checkout out the `will-redirect` event above.\n         */\n        on(\n            event: \"did-redirect-navigation\",\n            listener: (\n                details: Event<WebContentsDidRedirectNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"did-redirect-navigation\",\n            listener: (\n                details: Event<WebContentsDidRedirectNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"did-redirect-navigation\",\n            listener: (\n                details: Event<WebContentsDidRedirectNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"did-redirect-navigation\",\n            listener: (\n                details: Event<WebContentsDidRedirectNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        /**\n         * Corresponds to the points in time when the spinner of the tab started spinning.\n         */\n        on(event: \"did-start-loading\", listener: Function): this;\n        once(event: \"did-start-loading\", listener: Function): this;\n        addListener(event: \"did-start-loading\", listener: Function): this;\n        removeListener(event: \"did-start-loading\", listener: Function): this;\n        /**\n         * Emitted when any frame (including main) starts navigating.\n         */\n        on(\n            event: \"did-start-navigation\",\n            listener: (\n                details: Event<WebContentsDidStartNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"did-start-navigation\",\n            listener: (\n                details: Event<WebContentsDidStartNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"did-start-navigation\",\n            listener: (\n                details: Event<WebContentsDidStartNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"did-start-navigation\",\n            listener: (\n                details: Event<WebContentsDidStartNavigationEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        /**\n         * Corresponds to the points in time when the spinner of the tab stopped spinning.\n         */\n        on(event: \"did-stop-loading\", listener: Function): this;\n        once(event: \"did-stop-loading\", listener: Function): this;\n        addListener(event: \"did-stop-loading\", listener: Function): this;\n        removeListener(event: \"did-stop-loading\", listener: Function): this;\n        /**\n         * Emitted when the document in the top-level frame is loaded.\n         */\n        on(event: \"dom-ready\", listener: Function): this;\n        once(event: \"dom-ready\", listener: Function): this;\n        addListener(event: \"dom-ready\", listener: Function): this;\n        removeListener(event: \"dom-ready\", listener: Function): this;\n        /**\n         * Emitted when the window enters a full-screen state triggered by HTML API.\n         */\n        on(event: \"enter-html-full-screen\", listener: Function): this;\n        once(event: \"enter-html-full-screen\", listener: Function): this;\n        addListener(event: \"enter-html-full-screen\", listener: Function): this;\n        removeListener(event: \"enter-html-full-screen\", listener: Function): this;\n        /**\n         * Emitted when the `WebContents` gains focus.\n         *\n         * Note that on macOS, having focus means the `WebContents` is the first responder\n         * of window, so switching focus between windows would not trigger the `focus` and\n         * `blur` events of `WebContents`, as the first responder of each window is not\n         * changed.\n         *\n         * The `focus` and `blur` events of `WebContents` should only be used to detect\n         * focus change between different `WebContents` and `BrowserView` in the same\n         * window.\n         */\n        on(event: \"focus\", listener: Function): this;\n        once(event: \"focus\", listener: Function): this;\n        addListener(event: \"focus\", listener: Function): this;\n        removeListener(event: \"focus\", listener: Function): this;\n        /**\n         * Emitted when a result is available for `webContents.findInPage` request.\n         */\n        on(event: \"found-in-page\", listener: (event: Event, result: Result) => void): this;\n        once(event: \"found-in-page\", listener: (event: Event, result: Result) => void): this;\n        addListener(event: \"found-in-page\", listener: (event: Event, result: Result) => void): this;\n        removeListener(event: \"found-in-page\", listener: (event: Event, result: Result) => void): this;\n        /**\n         * Emitted when the mainFrame, an `<iframe>`, or a nested `<iframe>` is loaded\n         * within the page.\n         */\n        on(event: \"frame-created\", listener: (event: Event, details: FrameCreatedDetails) => void): this;\n        once(event: \"frame-created\", listener: (event: Event, details: FrameCreatedDetails) => void): this;\n        addListener(event: \"frame-created\", listener: (event: Event, details: FrameCreatedDetails) => void): this;\n        removeListener(event: \"frame-created\", listener: (event: Event, details: FrameCreatedDetails) => void): this;\n        /**\n         * Emitted when an input event is sent to the WebContents. See InputEvent for\n         * details.\n         */\n        on(event: \"input-event\", listener: (event: Event, inputEvent: InputEvent) => void): this;\n        once(event: \"input-event\", listener: (event: Event, inputEvent: InputEvent) => void): this;\n        addListener(event: \"input-event\", listener: (event: Event, inputEvent: InputEvent) => void): this;\n        removeListener(event: \"input-event\", listener: (event: Event, inputEvent: InputEvent) => void): this;\n        /**\n         * Emitted when the renderer process sends an asynchronous message via\n         * `ipcRenderer.send()`.\n         *\n         * See also `webContents.ipc`, which provides an `IpcMain`-like interface for\n         * responding to IPC messages specifically from this WebContents.\n         */\n        on(event: \"ipc-message\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        once(event: \"ipc-message\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        addListener(event: \"ipc-message\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        removeListener(event: \"ipc-message\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        /**\n         * Emitted when the renderer process sends a synchronous message via\n         * `ipcRenderer.sendSync()`.\n         *\n         * See also `webContents.ipc`, which provides an `IpcMain`-like interface for\n         * responding to IPC messages specifically from this WebContents.\n         */\n        on(event: \"ipc-message-sync\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        once(event: \"ipc-message-sync\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        addListener(event: \"ipc-message-sync\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        removeListener(event: \"ipc-message-sync\", listener: (event: IpcMainEvent, channel: string, ...args: any[]) => void): this;\n        /**\n         * Emitted when the window leaves a full-screen state triggered by HTML API.\n         */\n        on(event: \"leave-html-full-screen\", listener: Function): this;\n        once(event: \"leave-html-full-screen\", listener: Function): this;\n        addListener(event: \"leave-html-full-screen\", listener: Function): this;\n        removeListener(event: \"leave-html-full-screen\", listener: Function): this;\n        /**\n         * Emitted when `webContents` wants to do basic auth.\n         *\n         * The usage is the same with the `login` event of `app`.\n         */\n        on(event: \"login\", listener: (event: Event, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        once(event: \"login\", listener: (event: Event, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        addListener(event: \"login\", listener: (event: Event, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        removeListener(event: \"login\", listener: (event: Event, authenticationResponseDetails: AuthenticationResponseDetails, authInfo: AuthInfo, callback: (username?: string, password?: string) => void) => void): this;\n        /**\n         * Emitted when media is paused or done playing.\n         */\n        on(event: \"media-paused\", listener: Function): this;\n        once(event: \"media-paused\", listener: Function): this;\n        addListener(event: \"media-paused\", listener: Function): this;\n        removeListener(event: \"media-paused\", listener: Function): this;\n        /**\n         * Emitted when media starts playing.\n         */\n        on(event: \"media-started-playing\", listener: Function): this;\n        once(event: \"media-started-playing\", listener: Function): this;\n        addListener(event: \"media-started-playing\", listener: Function): this;\n        removeListener(event: \"media-started-playing\", listener: Function): this;\n        /**\n         * Emitted when page receives favicon urls.\n         */\n        on(\n            event: \"page-favicon-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Array of URLs.\n                 */\n                favicons: string[],\n            ) => void,\n        ): this;\n        once(\n            event: \"page-favicon-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Array of URLs.\n                 */\n                favicons: string[],\n            ) => void,\n        ): this;\n        addListener(\n            event: \"page-favicon-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Array of URLs.\n                 */\n                favicons: string[],\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"page-favicon-updated\",\n            listener: (\n                event: Event,\n                /**\n                 * Array of URLs.\n                 */\n                favicons: string[],\n            ) => void,\n        ): this;\n        /**\n         * Fired when page title is set during navigation. `explicitSet` is false when\n         * title is synthesized from file url.\n         */\n        on(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        once(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        addListener(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        removeListener(event: \"page-title-updated\", listener: (event: Event, title: string, explicitSet: boolean) => void): this;\n        /**\n         * Emitted when a new frame is generated. Only the dirty area is passed in the\n         * buffer.\n         */\n        on(\n            event: \"paint\",\n            listener: (\n                event: Event,\n                dirtyRect: Rectangle,\n                /**\n                 * The image data of the whole frame.\n                 */\n                image: NativeImage,\n            ) => void,\n        ): this;\n        once(\n            event: \"paint\",\n            listener: (\n                event: Event,\n                dirtyRect: Rectangle,\n                /**\n                 * The image data of the whole frame.\n                 */\n                image: NativeImage,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"paint\",\n            listener: (\n                event: Event,\n                dirtyRect: Rectangle,\n                /**\n                 * The image data of the whole frame.\n                 */\n                image: NativeImage,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"paint\",\n            listener: (\n                event: Event,\n                dirtyRect: Rectangle,\n                /**\n                 * The image data of the whole frame.\n                 */\n                image: NativeImage,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a plugin process has crashed.\n         */\n        on(event: \"plugin-crashed\", listener: (event: Event, name: string, version: string) => void): this;\n        once(event: \"plugin-crashed\", listener: (event: Event, name: string, version: string) => void): this;\n        addListener(event: \"plugin-crashed\", listener: (event: Event, name: string, version: string) => void): this;\n        removeListener(event: \"plugin-crashed\", listener: (event: Event, name: string, version: string) => void): this;\n        /**\n         * Emitted when the `WebContents` preferred size has changed.\n         *\n         * This event will only be emitted when `enablePreferredSizeMode` is set to `true`\n         * in `webPreferences`.\n         */\n        on(\n            event: \"preferred-size-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The minimum size needed to contain the layout of the document—without requiring\n                 * scrolling.\n                 */\n                preferredSize: Size,\n            ) => void,\n        ): this;\n        once(\n            event: \"preferred-size-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The minimum size needed to contain the layout of the document—without requiring\n                 * scrolling.\n                 */\n                preferredSize: Size,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"preferred-size-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The minimum size needed to contain the layout of the document—without requiring\n                 * scrolling.\n                 */\n                preferredSize: Size,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"preferred-size-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * The minimum size needed to contain the layout of the document—without requiring\n                 * scrolling.\n                 */\n                preferredSize: Size,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the preload script `preloadPath` throws an unhandled exception\n         * `error`.\n         */\n        on(event: \"preload-error\", listener: (event: Event, preloadPath: string, error: Error) => void): this;\n        once(event: \"preload-error\", listener: (event: Event, preloadPath: string, error: Error) => void): this;\n        addListener(event: \"preload-error\", listener: (event: Event, preloadPath: string, error: Error) => void): this;\n        removeListener(event: \"preload-error\", listener: (event: Event, preloadPath: string, error: Error) => void): this;\n        /**\n         * Emitted when the renderer process unexpectedly disappears.  This is normally\n         * because it was crashed or killed.\n         */\n        on(event: \"render-process-gone\", listener: (event: Event, details: RenderProcessGoneDetails) => void): this;\n        once(event: \"render-process-gone\", listener: (event: Event, details: RenderProcessGoneDetails) => void): this;\n        addListener(event: \"render-process-gone\", listener: (event: Event, details: RenderProcessGoneDetails) => void): this;\n        removeListener(event: \"render-process-gone\", listener: (event: Event, details: RenderProcessGoneDetails) => void): this;\n        /**\n         * Emitted when the unresponsive web page becomes responsive again.\n         */\n        on(event: \"responsive\", listener: Function): this;\n        once(event: \"responsive\", listener: Function): this;\n        addListener(event: \"responsive\", listener: Function): this;\n        removeListener(event: \"responsive\", listener: Function): this;\n        /**\n         * Emitted when a bluetooth device needs to be selected when a call to\n         * `navigator.bluetooth.requestDevice` is made. `callback` should be called with\n         * the `deviceId` of the device to be selected.  Passing an empty string to\n         * `callback` will cancel the request.\n         *\n         * If an event listener is not added for this event, or if `event.preventDefault`\n         * is not called when handling this event, the first available device will be\n         * automatically selected.\n         *\n         * Due to the nature of bluetooth, scanning for devices when\n         * `navigator.bluetooth.requestDevice` is called may take time and will cause\n         * `select-bluetooth-device` to fire multiple times until `callback` is called with\n         * either a device id or an empty string to cancel the request.\n         */\n        on(event: \"select-bluetooth-device\", listener: (event: Event, devices: BluetoothDevice[], callback: (deviceId: string) => void) => void): this;\n        once(event: \"select-bluetooth-device\", listener: (event: Event, devices: BluetoothDevice[], callback: (deviceId: string) => void) => void): this;\n        addListener(event: \"select-bluetooth-device\", listener: (event: Event, devices: BluetoothDevice[], callback: (deviceId: string) => void) => void): this;\n        removeListener(event: \"select-bluetooth-device\", listener: (event: Event, devices: BluetoothDevice[], callback: (deviceId: string) => void) => void): this;\n        /**\n         * Emitted when a client certificate is requested.\n         *\n         * The usage is the same with the `select-client-certificate` event of `app`.\n         */\n        on(event: \"select-client-certificate\", listener: (event: Event, url: string, certificateList: Certificate[], callback: (certificate: Certificate) => void) => void): this;\n        once(event: \"select-client-certificate\", listener: (event: Event, url: string, certificateList: Certificate[], callback: (certificate: Certificate) => void) => void): this;\n        addListener(event: \"select-client-certificate\", listener: (event: Event, url: string, certificateList: Certificate[], callback: (certificate: Certificate) => void) => void): this;\n        removeListener(event: \"select-client-certificate\", listener: (event: Event, url: string, certificateList: Certificate[], callback: (certificate: Certificate) => void) => void): this;\n        /**\n         * Emitted when the web page becomes unresponsive.\n         */\n        on(event: \"unresponsive\", listener: Function): this;\n        once(event: \"unresponsive\", listener: Function): this;\n        addListener(event: \"unresponsive\", listener: Function): this;\n        removeListener(event: \"unresponsive\", listener: Function): this;\n        /**\n         * Emitted when mouse moves over a link or the keyboard moves the focus to a link.\n         */\n        on(event: \"update-target-url\", listener: (event: Event, url: string) => void): this;\n        once(event: \"update-target-url\", listener: (event: Event, url: string) => void): this;\n        addListener(event: \"update-target-url\", listener: (event: Event, url: string) => void): this;\n        removeListener(event: \"update-target-url\", listener: (event: Event, url: string) => void): this;\n        /**\n         * Emitted when a `<webview>`'s web contents is being attached to this web\n         * contents. Calling `event.preventDefault()` will destroy the guest page.\n         *\n         * This event can be used to configure `webPreferences` for the `webContents` of a\n         * `<webview>` before it's loaded, and provides the ability to set settings that\n         * can't be set via `<webview>` attributes.\n         */\n        on(\n            event: \"will-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The web preferences that will be used by the guest page. This object can be\n                 * modified to adjust the preferences for the guest page.\n                 */\n                webPreferences: WebPreferences,\n                /**\n                 * The other `<webview>` parameters such as the `src` URL. This object can be\n                 * modified to adjust the parameters of the guest page.\n                 */\n                params: Record<string, string>,\n            ) => void,\n        ): this;\n        once(\n            event: \"will-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The web preferences that will be used by the guest page. This object can be\n                 * modified to adjust the preferences for the guest page.\n                 */\n                webPreferences: WebPreferences,\n                /**\n                 * The other `<webview>` parameters such as the `src` URL. This object can be\n                 * modified to adjust the parameters of the guest page.\n                 */\n                params: Record<string, string>,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"will-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The web preferences that will be used by the guest page. This object can be\n                 * modified to adjust the preferences for the guest page.\n                 */\n                webPreferences: WebPreferences,\n                /**\n                 * The other `<webview>` parameters such as the `src` URL. This object can be\n                 * modified to adjust the parameters of the guest page.\n                 */\n                params: Record<string, string>,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"will-attach-webview\",\n            listener: (\n                event: Event,\n                /**\n                 * The web preferences that will be used by the guest page. This object can be\n                 * modified to adjust the preferences for the guest page.\n                 */\n                webPreferences: WebPreferences,\n                /**\n                 * The other `<webview>` parameters such as the `src` URL. This object can be\n                 * modified to adjust the parameters of the guest page.\n                 */\n                params: Record<string, string>,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a user or the page wants to start navigation in any frame. It can\n         * happen when the `window.location` object is changed or a user clicks a link in\n         * the page.\n         *\n         * Unlike `will-navigate`, `will-frame-navigate` is fired when the main frame or\n         * any of its subframes attempts to navigate. When the navigation event comes from\n         * the main frame, `isMainFrame` will be `true`.\n         *\n         * This event will not emit when the navigation is started programmatically with\n         * APIs like `webContents.loadURL` and `webContents.back`.\n         *\n         * It is also not emitted for in-page navigations, such as clicking anchor links or\n         * updating the `window.location.hash`. Use `did-navigate-in-page` event for this\n         * purpose.\n         *\n         * Calling `event.preventDefault()` will prevent the navigation.\n         */\n        on(event: \"will-frame-navigate\", listener: (details: Event<WebContentsWillFrameNavigateEventParams>) => void): this;\n        once(event: \"will-frame-navigate\", listener: (details: Event<WebContentsWillFrameNavigateEventParams>) => void): this;\n        addListener(event: \"will-frame-navigate\", listener: (details: Event<WebContentsWillFrameNavigateEventParams>) => void): this;\n        removeListener(event: \"will-frame-navigate\", listener: (details: Event<WebContentsWillFrameNavigateEventParams>) => void): this;\n        /**\n         * Emitted when a user or the page wants to start navigation on the main frame. It\n         * can happen when the `window.location` object is changed or a user clicks a link\n         * in the page.\n         *\n         * This event will not emit when the navigation is started programmatically with\n         * APIs like `webContents.loadURL` and `webContents.back`.\n         *\n         * It is also not emitted for in-page navigations, such as clicking anchor links or\n         * updating the `window.location.hash`. Use `did-navigate-in-page` event for this\n         * purpose.\n         *\n         * Calling `event.preventDefault()` will prevent the navigation.\n         */\n        on(\n            event: \"will-navigate\",\n            listener: (\n                details: Event<WebContentsWillNavigateEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"will-navigate\",\n            listener: (\n                details: Event<WebContentsWillNavigateEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"will-navigate\",\n            listener: (\n                details: Event<WebContentsWillNavigateEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"will-navigate\",\n            listener: (\n                details: Event<WebContentsWillNavigateEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when a `beforeunload` event handler is attempting to cancel a page\n         * unload.\n         *\n         * Calling `event.preventDefault()` will ignore the `beforeunload` event handler\n         * and allow the page to be unloaded.\n         *\n         * **Note:** This will be emitted for `BrowserViews` but will _not_ be respected -\n         * this is because we have chosen not to tie the `BrowserView` lifecycle to its\n         * owning BrowserWindow should one exist per the specification.\n         */\n        on(event: \"will-prevent-unload\", listener: (event: Event) => void): this;\n        once(event: \"will-prevent-unload\", listener: (event: Event) => void): this;\n        addListener(event: \"will-prevent-unload\", listener: (event: Event) => void): this;\n        removeListener(event: \"will-prevent-unload\", listener: (event: Event) => void): this;\n        /**\n         * Emitted when a server side redirect occurs during navigation.  For example a 302\n         * redirect.\n         *\n         * This event will be emitted after `did-start-navigation` and always before the\n         * `did-redirect-navigation` event for the same navigation.\n         *\n         * Calling `event.preventDefault()` will prevent the navigation (not just the\n         * redirect).\n         */\n        on(\n            event: \"will-redirect\",\n            listener: (\n                details: Event<WebContentsWillRedirectEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        once(\n            event: \"will-redirect\",\n            listener: (\n                details: Event<WebContentsWillRedirectEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        addListener(\n            event: \"will-redirect\",\n            listener: (\n                details: Event<WebContentsWillRedirectEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"will-redirect\",\n            listener: (\n                details: Event<WebContentsWillRedirectEventParams>,\n                /**\n                 * @deprecated\n                 */\n                url: string,\n                /**\n                 * @deprecated\n                 */\n                isInPlace: boolean,\n                /**\n                 * @deprecated\n                 */\n                isMainFrame: boolean,\n                /**\n                 * @deprecated\n                 */\n                frameProcessId: number,\n                /**\n                 * @deprecated\n                 */\n                frameRoutingId: number,\n            ) => void,\n        ): this;\n        /**\n         * Emitted when the user is requesting to change the zoom level using the mouse\n         * wheel.\n         */\n        on(\n            event: \"zoom-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `in` or `out`.\n                 */\n                zoomDirection: \"in\" | \"out\",\n            ) => void,\n        ): this;\n        once(\n            event: \"zoom-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `in` or `out`.\n                 */\n                zoomDirection: \"in\" | \"out\",\n            ) => void,\n        ): this;\n        addListener(\n            event: \"zoom-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `in` or `out`.\n                 */\n                zoomDirection: \"in\" | \"out\",\n            ) => void,\n        ): this;\n        removeListener(\n            event: \"zoom-changed\",\n            listener: (\n                event: Event,\n                /**\n                 * Can be `in` or `out`.\n                 */\n                zoomDirection: \"in\" | \"out\",\n            ) => void,\n        ): this;\n        /**\n         * Adds the specified path to DevTools workspace. Must be used after DevTools\n         * creation:\n         */\n        addWorkSpace(path: string): void;\n        /**\n         * Adjusts the current text selection starting and ending points in the focused\n         * frame by the given amounts. A negative amount moves the selection towards the\n         * beginning of the document, and a positive amount moves the selection towards the\n         * end of the document.\n         *\n         * Example:\n         *\n         * For a call of `win.webContents.adjustSelection({ start: 1, end: 5 })`\n         *\n         * Before:\n         *\n         * <img width=\"487\" alt=\"Image Before Text Selection Adjustment\"\n         * src=\"../images/web-contents-text-selection-before.png\"/>\n         *\n         * After:\n         *\n         * <img width=\"487\" alt=\"Image After Text Selection Adjustment\"\n         * src=\"../images/web-contents-text-selection-after.png\"/>\n         */\n        adjustSelection(options: AdjustSelectionOptions): void;\n        /**\n         * Begin subscribing for presentation events and captured frames, the `callback`\n         * will be called with `callback(image, dirtyRect)` when there is a presentation\n         * event.\n         *\n         * The `image` is an instance of NativeImage that stores the captured frame.\n         *\n         * The `dirtyRect` is an object with `x, y, width, height` properties that\n         * describes which part of the page was repainted. If `onlyDirty` is set to `true`,\n         * `image` will only contain the repainted area. `onlyDirty` defaults to `false`.\n         */\n        beginFrameSubscription(onlyDirty: boolean, callback: (image: NativeImage, dirtyRect: Rectangle) => void): void;\n        /**\n         * Begin subscribing for presentation events and captured frames, the `callback`\n         * will be called with `callback(image, dirtyRect)` when there is a presentation\n         * event.\n         *\n         * The `image` is an instance of NativeImage that stores the captured frame.\n         *\n         * The `dirtyRect` is an object with `x, y, width, height` properties that\n         * describes which part of the page was repainted. If `onlyDirty` is set to `true`,\n         * `image` will only contain the repainted area. `onlyDirty` defaults to `false`.\n         */\n        beginFrameSubscription(callback: (image: NativeImage, dirtyRect: Rectangle) => void): void;\n        /**\n         * Whether the browser can go back to previous web page.\n         */\n        canGoBack(): boolean;\n        /**\n         * Whether the browser can go forward to next web page.\n         */\n        canGoForward(): boolean;\n        /**\n         * Whether the web page can go to `offset`.\n         */\n        canGoToOffset(offset: number): boolean;\n        /**\n         * Resolves with a NativeImage\n         *\n         * Captures a snapshot of the page within `rect`. Omitting `rect` will capture the\n         * whole visible page. The page is considered visible when its browser window is\n         * hidden and the capturer count is non-zero. If you would like the page to stay\n         * hidden, you should ensure that `stayHidden` is set to true.\n         */\n        capturePage(rect?: Rectangle, opts?: Opts): Promise<Electron.NativeImage>;\n        /**\n         * Centers the current text selection in web page.\n         */\n        centerSelection(): void;\n        /**\n         * Clears the navigation history.\n         */\n        clearHistory(): void;\n        /**\n         * Closes the page, as if the web content had called `window.close()`.\n         *\n         * If the page is successfully closed (i.e. the unload is not prevented by the\n         * page, or `waitForBeforeUnload` is false or unspecified), the WebContents will be\n         * destroyed and no longer usable. The `destroyed` event will be emitted.\n         */\n        close(opts?: CloseOpts): void;\n        /**\n         * Closes the devtools.\n         */\n        closeDevTools(): void;\n        /**\n         * Executes the editing command `copy` in web page.\n         */\n        copy(): void;\n        /**\n         * Copy the image at the given position to the clipboard.\n         */\n        copyImageAt(x: number, y: number): void;\n        /**\n         * Executes the editing command `cut` in web page.\n         */\n        cut(): void;\n        /**\n         * Executes the editing command `delete` in web page.\n         */\n        delete(): void;\n        /**\n         * Disable device emulation enabled by `webContents.enableDeviceEmulation`.\n         */\n        disableDeviceEmulation(): void;\n        /**\n         * Initiates a download of the resource at `url` without navigating. The\n         * `will-download` event of `session` will be triggered.\n         */\n        downloadURL(url: string): void;\n        /**\n         * Enable device emulation with the given parameters.\n         */\n        enableDeviceEmulation(parameters: Parameters): void;\n        /**\n         * End subscribing for frame presentation events.\n         */\n        endFrameSubscription(): void;\n        /**\n         * A promise that resolves with the result of the executed code or is rejected if\n         * the result of the code is a rejected promise.\n         *\n         * Evaluates `code` in page.\n         *\n         * In the browser window some HTML APIs like `requestFullScreen` can only be\n         * invoked by a gesture from the user. Setting `userGesture` to `true` will remove\n         * this limitation.\n         *\n         * Code execution will be suspended until web page stop loading.\n         */\n        executeJavaScript(code: string, userGesture?: boolean): Promise<any>;\n        /**\n         * A promise that resolves with the result of the executed code or is rejected if\n         * the result of the code is a rejected promise.\n         *\n         * Works like `executeJavaScript` but evaluates `scripts` in an isolated context.\n         */\n        executeJavaScriptInIsolatedWorld(worldId: number, scripts: WebSource[], userGesture?: boolean): Promise<any>;\n        /**\n         * The request id used for the request.\n         *\n         * Starts a request to find all matches for the `text` in the web page. The result\n         * of the request can be obtained by subscribing to `found-in-page` event.\n         */\n        findInPage(text: string, options?: FindInPageOptions): number;\n        /**\n         * Focuses the web page.\n         */\n        focus(): void;\n        /**\n         * Forcefully terminates the renderer process that is currently hosting this\n         * `webContents`. This will cause the `render-process-gone` event to be emitted\n         * with the `reason=killed || reason=crashed`. Please note that some webContents\n         * share renderer processes and therefore calling this method may also crash the\n         * host process for other webContents as well.\n         *\n         * Calling `reload()` immediately after calling this method will force the reload\n         * to occur in a new process. This should be used when this process is unstable or\n         * unusable, for instance in order to recover from the `unresponsive` event.\n         */\n        forcefullyCrashRenderer(): void;\n        /**\n         * Information about all Shared Workers.\n         */\n        getAllSharedWorkers(): SharedWorkerInfo[];\n        /**\n         * whether or not this WebContents will throttle animations and timers when the\n         * page becomes backgrounded. This also affects the Page Visibility API.\n         */\n        getBackgroundThrottling(): boolean;\n        /**\n         * If _offscreen rendering_ is enabled returns the current frame rate.\n         */\n        getFrameRate(): number;\n        /**\n         * The identifier of a WebContents stream. This identifier can be used with\n         * `navigator.mediaDevices.getUserMedia` using a `chromeMediaSource` of `tab`. The\n         * identifier is restricted to the web contents that it is registered to and is\n         * only valid for 10 seconds.\n         */\n        getMediaSourceId(requestWebContents: WebContents): string;\n        /**\n         * The operating system `pid` of the associated renderer process.\n         */\n        getOSProcessId(): number;\n        /**\n         * Get the system printer list.\n         *\n         *\n         * **Deprecated:** Should use the new `contents.getPrintersAsync` API.\n         *\n         * @deprecated\n         */\n        getPrinters(): PrinterInfo[];\n        /**\n         * Get the system printer list.\n         *\n         * Resolves with a `PrinterInfo[]`\n         */\n        getPrintersAsync(): Promise<Electron.PrinterInfo[]>;\n        /**\n         * The Chromium internal `pid` of the associated renderer. Can be compared to the\n         * `frameProcessId` passed by frame specific navigation events (e.g.\n         * `did-frame-navigate`)\n         */\n        getProcessId(): number;\n        /**\n         * The title of the current web page.\n         */\n        getTitle(): string;\n        /**\n         * the type of the webContent. Can be `backgroundPage`, `window`, `browserView`,\n         * `remote`, `webview` or `offscreen`.\n         */\n        getType(): \"backgroundPage\" | \"window\" | \"browserView\" | \"remote\" | \"webview\" | \"offscreen\";\n        /**\n         * The URL of the current web page.\n         */\n        getURL(): string;\n        /**\n         * The user agent for this web page.\n         */\n        getUserAgent(): string;\n        /**\n         * Returns the WebRTC IP Handling Policy.\n         */\n        getWebRTCIPHandlingPolicy(): string;\n        /**\n         * the current zoom factor.\n         */\n        getZoomFactor(): number;\n        /**\n         * the current zoom level.\n         */\n        getZoomLevel(): number;\n        /**\n         * Makes the browser go back a web page.\n         */\n        goBack(): void;\n        /**\n         * Makes the browser go forward a web page.\n         */\n        goForward(): void;\n        /**\n         * Navigates browser to the specified absolute web page index.\n         */\n        goToIndex(index: number): void;\n        /**\n         * Navigates to the specified offset from the \"current entry\".\n         */\n        goToOffset(offset: number): void;\n        /**\n         * A promise that resolves with a key for the inserted CSS that can later be used\n         * to remove the CSS via `contents.removeInsertedCSS(key)`.\n         *\n         * Injects CSS into the current web page and returns a unique key for the inserted\n         * stylesheet.\n         */\n        insertCSS(css: string, options?: InsertCSSOptions): Promise<string>;\n        /**\n         * Inserts `text` to the focused element.\n         */\n        insertText(text: string): Promise<void>;\n        /**\n         * Starts inspecting element at position (`x`, `y`).\n         */\n        inspectElement(x: number, y: number): void;\n        /**\n         * Opens the developer tools for the service worker context.\n         */\n        inspectServiceWorker(): void;\n        /**\n         * Opens the developer tools for the shared worker context.\n         */\n        inspectSharedWorker(): void;\n        /**\n         * Inspects the shared worker based on its ID.\n         */\n        inspectSharedWorkerById(workerId: string): void;\n        /**\n         * Schedules a full repaint of the window this web contents is in.\n         *\n         * If _offscreen rendering_ is enabled invalidates the frame and generates a new\n         * one through the `'paint'` event.\n         */\n        invalidate(): void;\n        /**\n         * Whether this page has been muted.\n         */\n        isAudioMuted(): boolean;\n        /**\n         * Whether this page is being captured. It returns true when the capturer count is\n         * large then 0.\n         */\n        isBeingCaptured(): boolean;\n        /**\n         * Whether the renderer process has crashed.\n         */\n        isCrashed(): boolean;\n        /**\n         * Whether audio is currently playing.\n         */\n        isCurrentlyAudible(): boolean;\n        /**\n         * Whether the web page is destroyed.\n         */\n        isDestroyed(): boolean;\n        /**\n         * Whether the devtools view is focused .\n         */\n        isDevToolsFocused(): boolean;\n        /**\n         * Whether the devtools is opened.\n         */\n        isDevToolsOpened(): boolean;\n        /**\n         * Whether the web page is focused.\n         */\n        isFocused(): boolean;\n        /**\n         * Whether web page is still loading resources.\n         */\n        isLoading(): boolean;\n        /**\n         * Whether the main frame (and not just iframes or frames within it) is still\n         * loading.\n         */\n        isLoadingMainFrame(): boolean;\n        /**\n         * Indicates whether _offscreen rendering_ is enabled.\n         */\n        isOffscreen(): boolean;\n        /**\n         * If _offscreen rendering_ is enabled returns whether it is currently painting.\n         */\n        isPainting(): boolean;\n        /**\n         * Whether the web page is waiting for a first-response from the main resource of\n         * the page.\n         */\n        isWaitingForResponse(): boolean;\n        /**\n         * the promise will resolve when the page has finished loading (see\n         * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`).\n         *\n         * Loads the given file in the window, `filePath` should be a path to an HTML file\n         * relative to the root of your application.  For instance an app structure like\n         * this:\n         *\n         * Would require code like this\n         */\n        loadFile(filePath: string, options?: LoadFileOptions): Promise<void>;\n        /**\n         * the promise will resolve when the page has finished loading (see\n         * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`).\n         * A noop rejection handler is already attached, which avoids unhandled rejection\n         * errors.\n         *\n         * Loads the `url` in the window. The `url` must contain the protocol prefix, e.g.\n         * the `http://` or `file://`. If the load should bypass http cache then use the\n         * `pragma` header to achieve it.\n         */\n        loadURL(url: string, options?: LoadURLOptions): Promise<void>;\n        /**\n         * Opens the devtools.\n         *\n         * When `contents` is a `<webview>` tag, the `mode` would be `detach` by default,\n         * explicitly passing an empty `mode` can force using last used dock state.\n         *\n         * On Windows, if Windows Control Overlay is enabled, Devtools will be opened with\n         * `mode: 'detach'`.\n         */\n        openDevTools(options?: OpenDevToolsOptions): void;\n        /**\n         * Executes the editing command `paste` in web page.\n         */\n        paste(): void;\n        /**\n         * Executes the editing command `pasteAndMatchStyle` in web page.\n         */\n        pasteAndMatchStyle(): void;\n        /**\n         * Send a message to the renderer process, optionally transferring ownership of\n         * zero or more `MessagePortMain` objects.\n         *\n         * The transferred `MessagePortMain` objects will be available in the renderer\n         * process by accessing the `ports` property of the emitted event. When they arrive\n         * in the renderer, they will be native DOM `MessagePort` objects.\n         *\n         * For example:\n         */\n        postMessage(channel: string, message: any, transfer?: MessagePortMain[]): void;\n        /**\n         * When a custom `pageSize` is passed, Chromium attempts to validate platform\n         * specific minimum values for `width_microns` and `height_microns`. Width and\n         * height must both be minimum 353 microns but may be higher on some operating\n         * systems.\n         *\n         * Prints window's web page. When `silent` is set to `true`, Electron will pick the\n         * system's default printer if `deviceName` is empty and the default settings for\n         * printing.\n         *\n         * Use `page-break-before: always;` CSS style to force to print to a new page.\n         *\n         * Example usage:\n         */\n        print(options?: WebContentsPrintOptions, callback?: (success: boolean, failureReason: string) => void): void;\n        /**\n         * Resolves with the generated PDF data.\n         *\n         * Prints the window's web page as PDF.\n         *\n         * The `landscape` will be ignored if `@page` CSS at-rule is used in the web page.\n         *\n         * An example of `webContents.printToPDF`:\n         *\n         * See Page.printToPdf for more information.\n         */\n        printToPDF(options: PrintToPDFOptions): Promise<Buffer>;\n        /**\n         * Executes the editing command `redo` in web page.\n         */\n        redo(): void;\n        /**\n         * Reloads the current web page.\n         */\n        reload(): void;\n        /**\n         * Reloads current page and ignores cache.\n         */\n        reloadIgnoringCache(): void;\n        /**\n         * Resolves if the removal was successful.\n         *\n         * Removes the inserted CSS from the current web page. The stylesheet is identified\n         * by its key, which is returned from `contents.insertCSS(css)`.\n         */\n        removeInsertedCSS(key: string): Promise<void>;\n        /**\n         * Removes the specified path from DevTools workspace.\n         */\n        removeWorkSpace(path: string): void;\n        /**\n         * Executes the editing command `replace` in web page.\n         */\n        replace(text: string): void;\n        /**\n         * Executes the editing command `replaceMisspelling` in web page.\n         */\n        replaceMisspelling(text: string): void;\n        /**\n         * resolves if the page is saved.\n         */\n        savePage(fullPath: string, saveType: \"HTMLOnly\" | \"HTMLComplete\" | \"MHTML\"): Promise<void>;\n        /**\n         * Scrolls to the bottom of the current `webContents`.\n         */\n        scrollToBottom(): void;\n        /**\n         * Scrolls to the top of the current `webContents`.\n         */\n        scrollToTop(): void;\n        /**\n         * Executes the editing command `selectAll` in web page.\n         */\n        selectAll(): void;\n        /**\n         * Send an asynchronous message to the renderer process via `channel`, along with\n         * arguments. Arguments will be serialized with the Structured Clone Algorithm,\n         * just like `postMessage`, so prototype chains will not be included. Sending\n         * Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.\n         *\n         * :::warning\n         *\n         * Sending non-standard JavaScript types such as DOM objects or special Electron\n         * objects will throw an exception.\n         *\n         * :::\n         *\n         * For additional reading, refer to Electron's IPC guide.\n         */\n        send(channel: string, ...args: any[]): void;\n        /**\n         * Sends an input `event` to the page. **Note:** The `BrowserWindow` containing the\n         * contents needs to be focused for `sendInputEvent()` to work.\n         */\n        sendInputEvent(inputEvent: MouseInputEvent | MouseWheelInputEvent | KeyboardInputEvent): void;\n        /**\n         * Send an asynchronous message to a specific frame in a renderer process via\n         * `channel`, along with arguments. Arguments will be serialized with the\n         * Structured Clone Algorithm, just like `postMessage`, so prototype chains will\n         * not be included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets\n         * will throw an exception.\n         *\n         * > **NOTE:** Sending non-standard JavaScript types such as DOM objects or special\n         * Electron objects will throw an exception.\n         *\n         * The renderer process can handle the message by listening to `channel` with the\n         * `ipcRenderer` module.\n         *\n         * If you want to get the `frameId` of a given renderer context you should use the\n         * `webFrame.routingId` value.  E.g.\n         *\n         * You can also read `frameId` from all incoming IPC messages in the main process.\n         */\n        sendToFrame(frameId: number | [number, number], channel: string, ...args: any[]): void;\n        /**\n         * Mute the audio on the current web page.\n         */\n        setAudioMuted(muted: boolean): void;\n        /**\n         * Controls whether or not this WebContents will throttle animations and timers\n         * when the page becomes backgrounded. This also affects the Page Visibility API.\n         */\n        setBackgroundThrottling(allowed: boolean): void;\n        /**\n         * Uses the `devToolsWebContents` as the target `WebContents` to show devtools.\n         *\n         * The `devToolsWebContents` must not have done any navigation, and it should not\n         * be used for other purposes after the call.\n         *\n         * By default Electron manages the devtools by creating an internal `WebContents`\n         * with native view, which developers have very limited control of. With the\n         * `setDevToolsWebContents` method, developers can use any `WebContents` to show\n         * the devtools in it, including `BrowserWindow`, `BrowserView` and `<webview>`\n         * tag.\n         *\n         * Note that closing the devtools does not destroy the `devToolsWebContents`, it is\n         * caller's responsibility to destroy `devToolsWebContents`.\n         *\n         * An example of showing devtools in a `<webview>` tag:\n         *\n         * An example of showing devtools in a `BrowserWindow`:\n         */\n        setDevToolsWebContents(devToolsWebContents: WebContents): void;\n        /**\n         * If _offscreen rendering_ is enabled sets the frame rate to the specified number.\n         * Only values between 1 and 240 are accepted.\n         */\n        setFrameRate(fps: number): void;\n        /**\n         * Ignore application menu shortcuts while this web contents is focused.\n         */\n        setIgnoreMenuShortcuts(ignore: boolean): void;\n        /**\n         * Sets the image animation policy for this webContents.  The policy only affects\n         * _new_ images, existing images that are currently being animated are unaffected.\n         * This is a known limitation in Chromium, you can force image animation to be\n         * recalculated with `img.src = img.src` which will result in no network traffic\n         * but will update the animation policy.\n         *\n         * This corresponds to the animationPolicy accessibility feature in Chromium.\n         */\n        setImageAnimationPolicy(policy: \"animate\" | \"animateOnce\" | \"noAnimation\"): void;\n        /**\n         * Overrides the user agent for this web page.\n         */\n        setUserAgent(userAgent: string): void;\n        /**\n         * Sets the maximum and minimum pinch-to-zoom level.\n         *\n         * > **NOTE**: Visual zoom is disabled by default in Electron. To re-enable it,\n         * call:\n         */\n        setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): Promise<void>;\n        /**\n         * Setting the WebRTC IP handling policy allows you to control which IPs are\n         * exposed via WebRTC. See BrowserLeaks for more details.\n         */\n        setWebRTCIPHandlingPolicy(policy: \"default\" | \"default_public_interface_only\" | \"default_public_and_private_interfaces\" | \"disable_non_proxied_udp\"): void;\n        /**\n         * Called before creating a window a new window is requested by the renderer, e.g.\n         * by `window.open()`, a link with `target=\"_blank\"`, shift+clicking on a link, or\n         * submitting a form with `<form target=\"_blank\">`. See `window.open()` for more\n         * details and how to use this in conjunction with `did-create-window`.\n         */\n        setWindowOpenHandler(handler: (details: HandlerDetails) => { action: \"deny\" } | { action: \"allow\"; outlivesOpener?: boolean; overrideBrowserWindowOptions?: BrowserWindowConstructorOptions }): void;\n        /**\n         * Changes the zoom factor to the specified factor. Zoom factor is zoom percent\n         * divided by 100, so 300% = 3.0.\n         *\n         * The factor must be greater than 0.0.\n         */\n        setZoomFactor(factor: number): void;\n        /**\n         * Changes the zoom level to the specified level. The original size is 0 and each\n         * increment above or below represents zooming 20% larger or smaller to default\n         * limits of 300% and 50% of original size, respectively. The formula for this is\n         * `scale := 1.2 ^ level`.\n         *\n         * > **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that\n         * the zoom level for a specific domain propagates across all instances of windows\n         * with the same domain. Differentiating the window URLs will make zoom work\n         * per-window.\n         */\n        setZoomLevel(level: number): void;\n        /**\n         * Shows pop-up dictionary that searches the selected word on the page.\n         *\n         * @platform darwin\n         */\n        showDefinitionForSelection(): void;\n        /**\n         * Sets the `item` as dragging item for current drag-drop operation, `file` is the\n         * absolute path of the file to be dragged, and `icon` is the image showing under\n         * the cursor when dragging.\n         */\n        startDrag(item: Item): void;\n        /**\n         * If _offscreen rendering_ is enabled and not painting, start painting.\n         */\n        startPainting(): void;\n        /**\n         * Stops any pending navigation.\n         */\n        stop(): void;\n        /**\n         * Stops any `findInPage` request for the `webContents` with the provided `action`.\n         */\n        stopFindInPage(action: \"clearSelection\" | \"keepSelection\" | \"activateSelection\"): void;\n        /**\n         * If _offscreen rendering_ is enabled and painting, stop painting.\n         */\n        stopPainting(): void;\n        /**\n         * Indicates whether the snapshot has been created successfully.\n         *\n         * Takes a V8 heap snapshot and saves it to `filePath`.\n         */\n        takeHeapSnapshot(filePath: string): Promise<void>;\n        /**\n         * Toggles the developer tools.\n         */\n        toggleDevTools(): void;\n        /**\n         * Executes the editing command `undo` in web page.\n         */\n        undo(): void;\n        /**\n         * Executes the editing command `unselect` in web page.\n         */\n        unselect(): void;\n        /**\n         * A `boolean` property that determines whether this page is muted.\n         */\n        audioMuted: boolean;\n        /**\n         * A `boolean` property that determines whether or not this WebContents will\n         * throttle animations and timers when the page becomes backgrounded. This also\n         * affects the Page Visibility API.\n         */\n        backgroundThrottling: boolean;\n        /**\n         * A `Debugger` instance for this webContents.\n         *\n         */\n        readonly debugger: Debugger;\n        /**\n         * A `WebContents | null` property that represents the of DevTools `WebContents`\n         * associated with a given `WebContents`.\n         *\n         * **Note:** Users should never store this object because it may become `null` when\n         * the DevTools has been closed.\n         *\n         */\n        readonly devToolsWebContents: WebContents | null;\n        /**\n         * An `Integer` property that sets the frame rate of the web contents to the\n         * specified number. Only values between 1 and 240 are accepted.\n         *\n         * Only applicable if _offscreen rendering_ is enabled.\n         */\n        frameRate: number;\n        /**\n         * A `WebContents` instance that might own this `WebContents`.\n         *\n         */\n        readonly hostWebContents: WebContents;\n        /**\n         * A `Integer` representing the unique ID of this WebContents. Each ID is unique\n         * among all `WebContents` instances of the entire Electron application.\n         *\n         */\n        readonly id: number;\n        /**\n         * An `IpcMain` scoped to just IPC messages sent from this WebContents.\n         *\n         * IPC messages sent with `ipcRenderer.send`, `ipcRenderer.sendSync` or\n         * `ipcRenderer.postMessage` will be delivered in the following order:\n         *\n         * * `contents.on('ipc-message')`\n         * * `contents.mainFrame.on(channel)`\n         * * `contents.ipc.on(channel)`\n         * * `ipcMain.on(channel)`\n         *\n         * Handlers registered with `invoke` will be checked in the following order. The\n         * first one that is defined will be called, the rest will be ignored.\n         *\n         * * `contents.mainFrame.handle(channel)`\n         * * `contents.handle(channel)`\n         * * `ipcMain.handle(channel)`\n         *\n         * A handler or event listener registered on the WebContents will receive IPC\n         * messages sent from any frame, including child frames. In most cases, only the\n         * main frame can send IPC messages. However, if the `nodeIntegrationInSubFrames`\n         * option is enabled, it is possible for child frames to send IPC messages also. In\n         * that case, handlers should check the `senderFrame` property of the IPC event to\n         * ensure that the message is coming from the expected frame. Alternatively,\n         * register handlers on the appropriate frame directly using the `WebFrameMain.ipc`\n         * interface.\n         *\n         */\n        readonly ipc: IpcMain;\n        /**\n         * A `WebFrameMain` property that represents the top frame of the page's frame\n         * hierarchy.\n         *\n         */\n        readonly mainFrame: WebFrameMain;\n        /**\n         * A `WebFrameMain` property that represents the frame that opened this\n         * WebContents, either with open(), or by navigating a link with a target\n         * attribute.\n         *\n         */\n        readonly opener: WebFrameMain;\n        /**\n         * A `Session` used by this webContents.\n         *\n         */\n        readonly session: Session;\n        /**\n         * A `string` property that determines the user agent for this web page.\n         */\n        userAgent: string;\n        /**\n         * A `number` property that determines the zoom factor for this web contents.\n         *\n         * The zoom factor is the zoom percent divided by 100, so 300% = 3.0.\n         */\n        zoomFactor: number;\n        /**\n         * A `number` property that determines the zoom level for this web contents.\n         *\n         * The original size is 0 and each increment above or below represents zooming 20%\n         * larger or smaller to default limits of 300% and 50% of original size,\n         * respectively. The formula for this is `scale := 1.2 ^ level`.\n         */\n        zoomLevel: number;\n    }\n\n    interface WebFrame {\n        // Docs: https://electronjs.org/docs/api/web-frame\n\n        /**\n         * Attempts to free memory that is no longer being used (like images from a\n         * previous navigation).\n         *\n         * Note that blindly calling this method probably makes Electron slower since it\n         * will have to refill these emptied caches, you should only call it if an event in\n         * your app has occurred that makes you think your page is actually using less\n         * memory (i.e. you have navigated from a super heavy page to a mostly empty one,\n         * and intend to stay there).\n         */\n        clearCache(): void;\n        /**\n         * A promise that resolves with the result of the executed code or is rejected if\n         * execution throws or results in a rejected promise.\n         *\n         * Evaluates `code` in page.\n         *\n         * In the browser window some HTML APIs like `requestFullScreen` can only be\n         * invoked by a gesture from the user. Setting `userGesture` to `true` will remove\n         * this limitation.\n         */\n        executeJavaScript(code: string, userGesture?: boolean, callback?: (result: any, error: Error) => void): Promise<any>;\n        /**\n         * A promise that resolves with the result of the executed code or is rejected if\n         * execution could not start.\n         *\n         * Works like `executeJavaScript` but evaluates `scripts` in an isolated context.\n         *\n         * Note that when the execution of script fails, the returned promise will not\n         * reject and the `result` would be `undefined`. This is because Chromium does not\n         * dispatch errors of isolated worlds to foreign worlds.\n         */\n        executeJavaScriptInIsolatedWorld(worldId: number, scripts: WebSource[], userGesture?: boolean, callback?: (result: any, error: Error) => void): Promise<any>;\n        /**\n         * A child of `webFrame` with the supplied `name`, `null` would be returned if\n         * there's no such frame or if the frame is not in the current renderer process.\n         */\n        findFrameByName(name: string): WebFrame;\n        /**\n         * that has the supplied `routingId`, `null` if not found.\n         */\n        findFrameByRoutingId(routingId: number): WebFrame;\n        /**\n         * The frame element in `webFrame's` document selected by `selector`, `null` would\n         * be returned if `selector` does not select a frame or if the frame is not in the\n         * current renderer process.\n         */\n        getFrameForSelector(selector: string): WebFrame;\n        /**\n         * * `images` MemoryUsageDetails\n         * * `scripts` MemoryUsageDetails\n         * * `cssStyleSheets` MemoryUsageDetails\n         * * `xslStyleSheets` MemoryUsageDetails\n         * * `fonts` MemoryUsageDetails\n         * * `other` MemoryUsageDetails\n         *\n         * Returns an object describing usage information of Blink's internal memory\n         * caches.\n         *\n         * This will generate:\n         */\n        getResourceUsage(): ResourceUsage;\n        /**\n         * A list of suggested words for a given word. If the word is spelled correctly,\n         * the result will be empty.\n         */\n        getWordSuggestions(word: string): string[];\n        /**\n         * The current zoom factor.\n         */\n        getZoomFactor(): number;\n        /**\n         * The current zoom level.\n         */\n        getZoomLevel(): number;\n        /**\n         * A key for the inserted CSS that can later be used to remove the CSS via\n         * `webFrame.removeInsertedCSS(key)`.\n         *\n         * Injects CSS into the current web page and returns a unique key for the inserted\n         * stylesheet.\n         */\n        insertCSS(css: string, options?: InsertCSSOptions): string;\n        /**\n         * Inserts `text` to the focused element.\n         */\n        insertText(text: string): void;\n        /**\n         * True if the word is misspelled according to the built in spellchecker, false\n         * otherwise. If no dictionary is loaded, always return false.\n         */\n        isWordMisspelled(word: string): boolean;\n        /**\n         * Removes the inserted CSS from the current web page. The stylesheet is identified\n         * by its key, which is returned from `webFrame.insertCSS(css)`.\n         */\n        removeInsertedCSS(key: string): void;\n        /**\n         * Set the security origin, content security policy and name of the isolated world.\n         * Note: If the `csp` is specified, then the `securityOrigin` also has to be\n         * specified.\n         */\n        setIsolatedWorldInfo(worldId: number, info: Info): void;\n        /**\n         * Sets a provider for spell checking in input fields and text areas.\n         *\n         * If you want to use this method you must disable the builtin spellchecker when\n         * you construct the window.\n         *\n         * The `provider` must be an object that has a `spellCheck` method that accepts an\n         * array of individual words for spellchecking. The `spellCheck` function runs\n         * asynchronously and calls the `callback` function with an array of misspelt words\n         * when complete.\n         *\n         * An example of using node-spellchecker as provider:\n         */\n        setSpellCheckProvider(language: string, provider: Provider): void;\n        /**\n         * Sets the maximum and minimum pinch-to-zoom level.\n         *\n         * > **NOTE**: Visual zoom is disabled by default in Electron. To re-enable it,\n         * call:\n         *\n         * > **NOTE**: Visual zoom only applies to pinch-to-zoom behavior. Cmd+/-/0 zoom\n         * shortcuts are controlled by the 'zoomIn', 'zoomOut', and 'resetZoom' MenuItem\n         * roles in the application Menu. To disable shortcuts, manually define the Menu\n         * and omit zoom roles from the definition.\n         */\n        setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): void;\n        /**\n         * Changes the zoom factor to the specified factor. Zoom factor is zoom percent\n         * divided by 100, so 300% = 3.0.\n         *\n         * The factor must be greater than 0.0.\n         */\n        setZoomFactor(factor: number): void;\n        /**\n         * Changes the zoom level to the specified level. The original size is 0 and each\n         * increment above or below represents zooming 20% larger or smaller to default\n         * limits of 300% and 50% of original size, respectively.\n         *\n         * > **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that\n         * the zoom level for a specific domain propagates across all instances of windows\n         * with the same domain. Differentiating the window URLs will make zoom work\n         * per-window.\n         */\n        setZoomLevel(level: number): void;\n        /**\n         * A `WebFrame | null` representing the first child frame of `webFrame`, the\n         * property would be `null` if `webFrame` has no children or if first child is not\n         * in the current renderer process.\n         *\n         */\n        readonly firstChild: WebFrame | null;\n        /**\n         * A `WebFrame | null` representing next sibling frame, the property would be\n         * `null` if `webFrame` is the last frame in its parent or if the next sibling is\n         * not in the current renderer process.\n         *\n         */\n        readonly nextSibling: WebFrame | null;\n        /**\n         * A `WebFrame | null` representing the frame which opened `webFrame`, the property\n         * would be `null` if there's no opener or opener is not in the current renderer\n         * process.\n         *\n         */\n        readonly opener: WebFrame | null;\n        /**\n         * A `WebFrame | null` representing parent frame of `webFrame`, the property would\n         * be `null` if `webFrame` is top or parent is not in the current renderer process.\n         *\n         */\n        readonly parent: WebFrame | null;\n        /**\n         * An `Integer` representing the unique frame id in the current renderer process.\n         * Distinct WebFrame instances that refer to the same underlying frame will have\n         * the same `routingId`.\n         *\n         */\n        readonly routingId: number;\n        /**\n         * A `WebFrame | null` representing top frame in frame hierarchy to which\n         * `webFrame` belongs, the property would be `null` if top frame is not in the\n         * current renderer process.\n         *\n         */\n        readonly top: WebFrame | null;\n    }\n\n    class WebFrameMain extends NodeEventEmitter {\n        // Docs: https://electronjs.org/docs/api/web-frame-main\n\n        /**\n         * A frame with the given process and routing IDs, or `undefined` if there is no\n         * WebFrameMain associated with the given IDs.\n         */\n        static fromId(processId: number, routingId: number): WebFrameMain | undefined;\n        /**\n         * Emitted when the document is loaded.\n         */\n        on(event: \"dom-ready\", listener: Function): this;\n        once(event: \"dom-ready\", listener: Function): this;\n        addListener(event: \"dom-ready\", listener: Function): this;\n        removeListener(event: \"dom-ready\", listener: Function): this;\n        /**\n         * A promise that resolves with the result of the executed code or is rejected if\n         * execution throws or results in a rejected promise.\n         *\n         * Evaluates `code` in page.\n         *\n         * In the browser window some HTML APIs like `requestFullScreen` can only be\n         * invoked by a gesture from the user. Setting `userGesture` to `true` will remove\n         * this limitation.\n         */\n        executeJavaScript(code: string, userGesture?: boolean): Promise<unknown>;\n        /**\n         * Send a message to the renderer process, optionally transferring ownership of\n         * zero or more `MessagePortMain` objects.\n         *\n         * The transferred `MessagePortMain` objects will be available in the renderer\n         * process by accessing the `ports` property of the emitted event. When they arrive\n         * in the renderer, they will be native DOM `MessagePort` objects.\n         *\n         * For example:\n         */\n        postMessage(channel: string, message: any, transfer?: MessagePortMain[]): void;\n        /**\n         * Whether the reload was initiated successfully. Only results in `false` when the\n         * frame has no history.\n         */\n        reload(): boolean;\n        /**\n         * Send an asynchronous message to the renderer process via `channel`, along with\n         * arguments. Arguments will be serialized with the Structured Clone Algorithm,\n         * just like `postMessage`, so prototype chains will not be included. Sending\n         * Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.\n         *\n         * The renderer process can handle the message by listening to `channel` with the\n         * `ipcRenderer` module.\n         */\n        send(channel: string, ...args: any[]): void;\n        /**\n         * A `WebFrameMain[]` collection containing the direct descendents of `frame`.\n         *\n         */\n        readonly frames: WebFrameMain[];\n        /**\n         * A `WebFrameMain[]` collection containing every frame in the subtree of `frame`,\n         * including itself. This can be useful when traversing through all frames.\n         *\n         */\n        readonly framesInSubtree: WebFrameMain[];\n        /**\n         * An `Integer` representing the id of the frame's internal FrameTreeNode instance.\n         * This id is browser-global and uniquely identifies a frame that hosts content.\n         * The identifier is fixed at the creation of the frame and stays constant for the\n         * lifetime of the frame. When the frame is removed, the id is not used again.\n         *\n         */\n        readonly frameTreeNodeId: number;\n        /**\n         * An `IpcMain` instance scoped to the frame.\n         *\n         * IPC messages sent with `ipcRenderer.send`, `ipcRenderer.sendSync` or\n         * `ipcRenderer.postMessage` will be delivered in the following order:\n         *\n         * * `contents.on('ipc-message')`\n         * * `contents.mainFrame.on(channel)`\n         * * `contents.ipc.on(channel)`\n         * * `ipcMain.on(channel)`\n         *\n         * Handlers registered with `invoke` will be checked in the following order. The\n         * first one that is defined will be called, the rest will be ignored.\n         *\n         * * `contents.mainFrame.handle(channel)`\n         * * `contents.handle(channel)`\n         * * `ipcMain.handle(channel)`\n         *\n         * In most cases, only the main frame of a WebContents can send or receive IPC\n         * messages. However, if the `nodeIntegrationInSubFrames` option is enabled, it is\n         * possible for child frames to send and receive IPC messages also. The\n         * `WebContents.ipc` interface may be more convenient when\n         * `nodeIntegrationInSubFrames` is not enabled.\n         *\n         */\n        readonly ipc: IpcMain;\n        /**\n         * A `string` representing the frame name.\n         *\n         */\n        readonly name: string;\n        /**\n         * A `string` representing the current origin of the frame, serialized according to\n         * RFC 6454. This may be different from the URL. For instance, if the frame is a\n         * child window opened to `about:blank`, then `frame.origin` will return the parent\n         * frame's origin, while `frame.url` will return the empty string. Pages without a\n         * scheme/host/port triple origin will have the serialized origin of `\"null\"` (that\n         * is, the string containing the letters n, u, l, l).\n         *\n         */\n        readonly origin: string;\n        /**\n         * An `Integer` representing the operating system `pid` of the process which owns\n         * this frame.\n         *\n         */\n        readonly osProcessId: number;\n        /**\n         * A `WebFrameMain | null` representing parent frame of `frame`, the property would\n         * be `null` if `frame` is the top frame in the frame hierarchy.\n         *\n         */\n        readonly parent: WebFrameMain | null;\n        /**\n         * An `Integer` representing the Chromium internal `pid` of the process which owns\n         * this frame. This is not the same as the OS process ID; to read that use\n         * `frame.osProcessId`.\n         *\n         */\n        readonly processId: number;\n        /**\n         * An `Integer` representing the unique frame id in the current renderer process.\n         * Distinct `WebFrameMain` instances that refer to the same underlying frame will\n         * have the same `routingId`.\n         *\n         */\n        readonly routingId: number;\n        /**\n         * A `WebFrameMain | null` representing top frame in the frame hierarchy to which\n         * `frame` belongs.\n         *\n         */\n        readonly top: WebFrameMain | null;\n        /**\n         * A `string` representing the current URL of the frame.\n         *\n         */\n        readonly url: string;\n        /**\n         * A `string` representing the visibility state of the frame.\n         *\n         * See also how the Page Visibility API is affected by other Electron APIs.\n         *\n         */\n        readonly visibilityState: string;\n    }\n\n    class WebRequest {\n        // Docs: https://electronjs.org/docs/api/web-request\n\n        /**\n         * The `listener` will be called with `listener(details)` when a server initiated\n         * redirect is about to occur.\n         */\n        onBeforeRedirect(filter: WebRequestFilter, listener: ((details: OnBeforeRedirectListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when a server initiated\n         * redirect is about to occur.\n         */\n        onBeforeRedirect(listener: ((details: OnBeforeRedirectListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details, callback)` when a request\n         * is about to occur.\n         *\n         * The `uploadData` is an array of `UploadData` objects.\n         *\n         * The `callback` has to be called with an `response` object.\n         *\n         * Some examples of valid `urls`:\n         */\n        onBeforeRequest(filter: WebRequestFilter, listener: ((details: OnBeforeRequestListenerDetails, callback: (response: CallbackResponse) => void) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details, callback)` when a request\n         * is about to occur.\n         *\n         * The `uploadData` is an array of `UploadData` objects.\n         *\n         * The `callback` has to be called with an `response` object.\n         *\n         * Some examples of valid `urls`:\n         */\n        onBeforeRequest(listener: ((details: OnBeforeRequestListenerDetails, callback: (response: CallbackResponse) => void) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details, callback)` before sending\n         * an HTTP request, once the request headers are available. This may occur after a\n         * TCP connection is made to the server, but before any http data is sent.\n         *\n         * The `callback` has to be called with a `response` object.\n         */\n        onBeforeSendHeaders(filter: WebRequestFilter, listener: ((details: OnBeforeSendHeadersListenerDetails, callback: (beforeSendResponse: BeforeSendResponse) => void) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details, callback)` before sending\n         * an HTTP request, once the request headers are available. This may occur after a\n         * TCP connection is made to the server, but before any http data is sent.\n         *\n         * The `callback` has to be called with a `response` object.\n         */\n        onBeforeSendHeaders(listener: ((details: OnBeforeSendHeadersListenerDetails, callback: (beforeSendResponse: BeforeSendResponse) => void) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when a request is\n         * completed.\n         */\n        onCompleted(filter: WebRequestFilter, listener: ((details: OnCompletedListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when a request is\n         * completed.\n         */\n        onCompleted(listener: ((details: OnCompletedListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when an error occurs.\n         */\n        onErrorOccurred(filter: WebRequestFilter, listener: ((details: OnErrorOccurredListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when an error occurs.\n         */\n        onErrorOccurred(listener: ((details: OnErrorOccurredListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details, callback)` when HTTP\n         * response headers of a request have been received.\n         *\n         * The `callback` has to be called with a `response` object.\n         */\n        onHeadersReceived(filter: WebRequestFilter, listener: ((details: OnHeadersReceivedListenerDetails, callback: (headersReceivedResponse: HeadersReceivedResponse) => void) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details, callback)` when HTTP\n         * response headers of a request have been received.\n         *\n         * The `callback` has to be called with a `response` object.\n         */\n        onHeadersReceived(listener: ((details: OnHeadersReceivedListenerDetails, callback: (headersReceivedResponse: HeadersReceivedResponse) => void) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when first byte of the\n         * response body is received. For HTTP requests, this means that the status line\n         * and response headers are available.\n         */\n        onResponseStarted(filter: WebRequestFilter, listener: ((details: OnResponseStartedListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` when first byte of the\n         * response body is received. For HTTP requests, this means that the status line\n         * and response headers are available.\n         */\n        onResponseStarted(listener: ((details: OnResponseStartedListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` just before a request is\n         * going to be sent to the server, modifications of previous `onBeforeSendHeaders`\n         * response are visible by the time this listener is fired.\n         */\n        onSendHeaders(filter: WebRequestFilter, listener: ((details: OnSendHeadersListenerDetails) => void) | null): void;\n        /**\n         * The `listener` will be called with `listener(details)` just before a request is\n         * going to be sent to the server, modifications of previous `onBeforeSendHeaders`\n         * response are visible by the time this listener is fired.\n         */\n        onSendHeaders(listener: ((details: OnSendHeadersListenerDetails) => void) | null): void;\n    }\n\n    interface WebRequestFilter {\n        // Docs: https://electronjs.org/docs/api/structures/web-request-filter\n\n        /**\n         * Array of types that will be used to filter out the requests that do not match\n         * the types. When not specified, all types will be matched. Can be `mainFrame`,\n         * `subFrame`, `stylesheet`, `script`, `image`, `font`, `object`, `xhr`, `ping`,\n         * `cspReport`, `media` or `webSocket`.\n         */\n        types?: Array<\"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\">;\n        /**\n         * Array of URL patterns that will be used to filter out the requests that do not\n         * match the URL patterns.\n         */\n        urls: string[];\n    }\n\n    interface WebSource {\n        // Docs: https://electronjs.org/docs/api/structures/web-source\n\n        code: string;\n        url?: string;\n    }\n\n    interface WebviewTag extends HTMLElement {\n        // Docs: https://electronjs.org/docs/api/webview-tag\n\n        /**\n         * Fired when a load has committed. This includes navigation within the current\n         * document as well as subframe document-level loads, but does not include\n         * asynchronous resource loads.\n         */\n        addEventListener(event: \"load-commit\", listener: (event: LoadCommitEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"load-commit\", listener: (event: LoadCommitEvent) => void): this;\n        /**\n         * Fired when the navigation is done, i.e. the spinner of the tab will stop\n         * spinning, and the `onload` event is dispatched.\n         */\n        addEventListener(event: \"did-finish-load\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-finish-load\", listener: (event: DOMEvent) => void): this;\n        /**\n         * This event is like `did-finish-load`, but fired when the load failed or was\n         * cancelled, e.g. `window.stop()` is invoked.\n         */\n        addEventListener(event: \"did-fail-load\", listener: (event: DidFailLoadEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-fail-load\", listener: (event: DidFailLoadEvent) => void): this;\n        /**\n         * Fired when a frame has done navigation.\n         */\n        addEventListener(event: \"did-frame-finish-load\", listener: (event: DidFrameFinishLoadEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-frame-finish-load\", listener: (event: DidFrameFinishLoadEvent) => void): this;\n        /**\n         * Corresponds to the points in time when the spinner of the tab starts spinning.\n         */\n        addEventListener(event: \"did-start-loading\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-start-loading\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Corresponds to the points in time when the spinner of the tab stops spinning.\n         */\n        addEventListener(event: \"did-stop-loading\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-stop-loading\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when attached to the embedder web contents.\n         */\n        addEventListener(event: \"did-attach\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-attach\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when document in the given frame is loaded.\n         */\n        addEventListener(event: \"dom-ready\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"dom-ready\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when page title is set during navigation. `explicitSet` is false when\n         * title is synthesized from file url.\n         */\n        addEventListener(event: \"page-title-updated\", listener: (event: PageTitleUpdatedEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"page-title-updated\", listener: (event: PageTitleUpdatedEvent) => void): this;\n        /**\n         * Fired when page receives favicon urls.\n         */\n        addEventListener(event: \"page-favicon-updated\", listener: (event: PageFaviconUpdatedEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"page-favicon-updated\", listener: (event: PageFaviconUpdatedEvent) => void): this;\n        /**\n         * Fired when page enters fullscreen triggered by HTML API.\n         */\n        addEventListener(event: \"enter-html-full-screen\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"enter-html-full-screen\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when page leaves fullscreen triggered by HTML API.\n         */\n        addEventListener(event: \"leave-html-full-screen\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"leave-html-full-screen\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when the guest window logs a console message.\n         *\n         * The following example code forwards all log messages to the embedder's console\n         * without regard for log level or other properties.\n         */\n        addEventListener(event: \"console-message\", listener: (event: ConsoleMessageEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"console-message\", listener: (event: ConsoleMessageEvent) => void): this;\n        /**\n         * Fired when a result is available for `webview.findInPage` request.\n         */\n        addEventListener(event: \"found-in-page\", listener: (event: FoundInPageEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"found-in-page\", listener: (event: FoundInPageEvent) => void): this;\n        /**\n         * Emitted when a user or the page wants to start navigation. It can happen when\n         * the `window.location` object is changed or a user clicks a link in the page.\n         *\n         * This event will not emit when the navigation is started programmatically with\n         * APIs like `<webview>.loadURL` and `<webview>.back`.\n         *\n         * It is also not emitted during in-page navigation, such as clicking anchor links\n         * or updating the `window.location.hash`. Use `did-navigate-in-page` event for\n         * this purpose.\n         *\n         * Calling `event.preventDefault()` does **NOT** have any effect.\n         */\n        addEventListener(event: \"will-navigate\", listener: (event: WillNavigateEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"will-navigate\", listener: (event: WillNavigateEvent) => void): this;\n        /**\n         * Emitted when a user or the page wants to start navigation anywhere in the\n         * `<webview>` or any frames embedded within. It can happen when the\n         * `window.location` object is changed or a user clicks a link in the page.\n         *\n         * This event will not emit when the navigation is started programmatically with\n         * APIs like `<webview>.loadURL` and `<webview>.back`.\n         *\n         * It is also not emitted during in-page navigation, such as clicking anchor links\n         * or updating the `window.location.hash`. Use `did-navigate-in-page` event for\n         * this purpose.\n         *\n         * Calling `event.preventDefault()` does **NOT** have any effect.\n         */\n        addEventListener(event: \"will-frame-navigate\", listener: (event: WillFrameNavigateEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"will-frame-navigate\", listener: (event: WillFrameNavigateEvent) => void): this;\n        /**\n         * Emitted when any frame (including main) starts navigating. `isInPlace` will be\n         * `true` for in-page navigations.\n         */\n        addEventListener(event: \"did-start-navigation\", listener: (event: DidStartNavigationEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-start-navigation\", listener: (event: DidStartNavigationEvent) => void): this;\n        /**\n         * Emitted after a server side redirect occurs during navigation. For example a 302\n         * redirect.\n         */\n        addEventListener(event: \"did-redirect-navigation\", listener: (event: DidRedirectNavigationEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-redirect-navigation\", listener: (event: DidRedirectNavigationEvent) => void): this;\n        /**\n         * Emitted when a navigation is done.\n         *\n         * This event is not emitted for in-page navigations, such as clicking anchor links\n         * or updating the `window.location.hash`. Use `did-navigate-in-page` event for\n         * this purpose.\n         */\n        addEventListener(event: \"did-navigate\", listener: (event: DidNavigateEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-navigate\", listener: (event: DidNavigateEvent) => void): this;\n        /**\n         * Emitted when any frame navigation is done.\n         *\n         * This event is not emitted for in-page navigations, such as clicking anchor links\n         * or updating the `window.location.hash`. Use `did-navigate-in-page` event for\n         * this purpose.\n         */\n        addEventListener(event: \"did-frame-navigate\", listener: (event: DidFrameNavigateEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-frame-navigate\", listener: (event: DidFrameNavigateEvent) => void): this;\n        /**\n         * Emitted when an in-page navigation happened.\n         *\n         * When in-page navigation happens, the page URL changes but does not cause\n         * navigation outside of the page. Examples of this occurring are when anchor links\n         * are clicked or when the DOM `hashchange` event is triggered.\n         */\n        addEventListener(event: \"did-navigate-in-page\", listener: (event: DidNavigateInPageEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-navigate-in-page\", listener: (event: DidNavigateInPageEvent) => void): this;\n        /**\n         * Fired when the guest page attempts to close itself.\n         *\n         * The following example code navigates the `webview` to `about:blank` when the\n         * guest attempts to close itself.\n         */\n        addEventListener(event: \"close\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"close\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when the guest page has sent an asynchronous message to embedder page.\n         *\n         * With `sendToHost` method and `ipc-message` event you can communicate between\n         * guest page and embedder page:\n         */\n        addEventListener(event: \"ipc-message\", listener: (event: IpcMessageEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"ipc-message\", listener: (event: IpcMessageEvent) => void): this;\n        /**\n         * Fired when the renderer process is crashed.\n         */\n        addEventListener(event: \"crashed\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"crashed\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Fired when a plugin process is crashed.\n         */\n        addEventListener(event: \"plugin-crashed\", listener: (event: PluginCrashedEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"plugin-crashed\", listener: (event: PluginCrashedEvent) => void): this;\n        /**\n         * Fired when the WebContents is destroyed.\n         */\n        addEventListener(event: \"destroyed\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"destroyed\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Emitted when media starts playing.\n         */\n        addEventListener(event: \"media-started-playing\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"media-started-playing\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Emitted when media is paused or done playing.\n         */\n        addEventListener(event: \"media-paused\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"media-paused\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Emitted when a page's theme color changes. This is usually due to encountering a\n         * meta tag:\n         */\n        addEventListener(event: \"did-change-theme-color\", listener: (event: DidChangeThemeColorEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"did-change-theme-color\", listener: (event: DidChangeThemeColorEvent) => void): this;\n        /**\n         * Emitted when mouse moves over a link or the keyboard moves the focus to a link.\n         */\n        addEventListener(event: \"update-target-url\", listener: (event: UpdateTargetUrlEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"update-target-url\", listener: (event: UpdateTargetUrlEvent) => void): this;\n        /**\n         * Emitted when a link is clicked in DevTools or 'Open in new tab' is selected for\n         * a link in its context menu.\n         */\n        addEventListener(event: \"devtools-open-url\", listener: (event: DevtoolsOpenUrlEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"devtools-open-url\", listener: (event: DevtoolsOpenUrlEvent) => void): this;\n        /**\n         * Emitted when DevTools is opened.\n         */\n        addEventListener(event: \"devtools-opened\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"devtools-opened\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Emitted when DevTools is closed.\n         */\n        addEventListener(event: \"devtools-closed\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"devtools-closed\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Emitted when DevTools is focused / opened.\n         */\n        addEventListener(event: \"devtools-focused\", listener: (event: DOMEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"devtools-focused\", listener: (event: DOMEvent) => void): this;\n        /**\n         * Emitted when there is a new context menu that needs to be handled.\n         */\n        addEventListener(event: \"context-menu\", listener: (event: ContextMenuEvent) => void, useCapture?: boolean): this;\n        removeEventListener(event: \"context-menu\", listener: (event: ContextMenuEvent) => void): this;\n        addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;\n        addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;\n        removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;\n        removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;\n        /**\n         * Adjusts the current text selection starting and ending points in the focused\n         * frame by the given amounts. A negative amount moves the selection towards the\n         * beginning of the document, and a positive amount moves the selection towards the\n         * end of the document.\n         *\n         * See `webContents.adjustSelection` for examples.\n         */\n        adjustSelection(options: AdjustSelectionOptions): void;\n        /**\n         * Whether the guest page can go back.\n         */\n        canGoBack(): boolean;\n        /**\n         * Whether the guest page can go forward.\n         */\n        canGoForward(): boolean;\n        /**\n         * Whether the guest page can go to `offset`.\n         */\n        canGoToOffset(offset: number): boolean;\n        /**\n         * Resolves with a NativeImage\n         *\n         * Captures a snapshot of the page within `rect`. Omitting `rect` will capture the\n         * whole visible page.\n         */\n        capturePage(rect?: Rectangle): Promise<Electron.NativeImage>;\n        /**\n         * Centers the current text selection in page.\n         */\n        centerSelection(): void;\n        /**\n         * Clears the navigation history.\n         */\n        clearHistory(): void;\n        /**\n         * Closes the DevTools window of guest page.\n         */\n        closeDevTools(): void;\n        /**\n         * Executes editing command `copy` in page.\n         */\n        copy(): void;\n        /**\n         * Executes editing command `cut` in page.\n         */\n        cut(): void;\n        /**\n         * Executes editing command `delete` in page.\n         */\n        delete(): void;\n        /**\n         * Initiates a download of the resource at `url` without navigating.\n         */\n        downloadURL(url: string): void;\n        /**\n         * A promise that resolves with the result of the executed code or is rejected if\n         * the result of the code is a rejected promise.\n         *\n         * Evaluates `code` in page. If `userGesture` is set, it will create the user\n         * gesture context in the page. HTML APIs like `requestFullScreen`, which require\n         * user action, can take advantage of this option for automation.\n         */\n        executeJavaScript(code: string, userGesture?: boolean): Promise<any>;\n        /**\n         * The request id used for the request.\n         *\n         * Starts a request to find all matches for the `text` in the web page. The result\n         * of the request can be obtained by subscribing to `found-in-page` event.\n         */\n        findInPage(text: string, options?: FindInPageOptions): number;\n        /**\n         * The title of guest page.\n         */\n        getTitle(): string;\n        /**\n         * The URL of guest page.\n         */\n        getURL(): string;\n        /**\n         * The user agent for guest page.\n         */\n        getUserAgent(): string;\n        /**\n         * The WebContents ID of this `webview`.\n         */\n        getWebContentsId(): number;\n        /**\n         * the current zoom factor.\n         */\n        getZoomFactor(): number;\n        /**\n         * the current zoom level.\n         */\n        getZoomLevel(): number;\n        /**\n         * Makes the guest page go back.\n         */\n        goBack(): void;\n        /**\n         * Makes the guest page go forward.\n         */\n        goForward(): void;\n        /**\n         * Navigates to the specified absolute index.\n         */\n        goToIndex(index: number): void;\n        /**\n         * Navigates to the specified offset from the \"current entry\".\n         */\n        goToOffset(offset: number): void;\n        /**\n         * A promise that resolves with a key for the inserted CSS that can later be used\n         * to remove the CSS via `<webview>.removeInsertedCSS(key)`.\n         *\n         * Injects CSS into the current web page and returns a unique key for the inserted\n         * stylesheet.\n         */\n        insertCSS(css: string): Promise<string>;\n        /**\n         * Inserts `text` to the focused element.\n         */\n        insertText(text: string): Promise<void>;\n        /**\n         * Starts inspecting element at position (`x`, `y`) of guest page.\n         */\n        inspectElement(x: number, y: number): void;\n        /**\n         * Opens the DevTools for the service worker context present in the guest page.\n         */\n        inspectServiceWorker(): void;\n        /**\n         * Opens the DevTools for the shared worker context present in the guest page.\n         */\n        inspectSharedWorker(): void;\n        /**\n         * Whether guest page has been muted.\n         */\n        isAudioMuted(): boolean;\n        /**\n         * Whether the renderer process has crashed.\n         */\n        isCrashed(): boolean;\n        /**\n         * Whether audio is currently playing.\n         */\n        isCurrentlyAudible(): boolean;\n        /**\n         * Whether DevTools window of guest page is focused.\n         */\n        isDevToolsFocused(): boolean;\n        /**\n         * Whether guest page has a DevTools window attached.\n         */\n        isDevToolsOpened(): boolean;\n        /**\n         * Whether guest page is still loading resources.\n         */\n        isLoading(): boolean;\n        /**\n         * Whether the main frame (and not just iframes or frames within it) is still\n         * loading.\n         */\n        isLoadingMainFrame(): boolean;\n        /**\n         * Whether the guest page is waiting for a first-response for the main resource of\n         * the page.\n         */\n        isWaitingForResponse(): boolean;\n        /**\n         * The promise will resolve when the page has finished loading (see\n         * `did-finish-load`), and rejects if the page fails to load (see `did-fail-load`).\n         *\n         * Loads the `url` in the webview, the `url` must contain the protocol prefix, e.g.\n         * the `http://` or `file://`.\n         */\n        loadURL(url: string, options?: LoadURLOptions): Promise<void>;\n        /**\n         * Opens a DevTools window for guest page.\n         */\n        openDevTools(): void;\n        /**\n         * Executes editing command `paste` in page.\n         */\n        paste(): void;\n        /**\n         * Executes editing command `pasteAndMatchStyle` in page.\n         */\n        pasteAndMatchStyle(): void;\n        /**\n         * Prints `webview`'s web page. Same as `webContents.print([options])`.\n         */\n        print(options?: WebviewTagPrintOptions): Promise<void>;\n        /**\n         * Resolves with the generated PDF data.\n         *\n         * Prints `webview`'s web page as PDF, Same as `webContents.printToPDF(options)`.\n         */\n        printToPDF(options: PrintToPDFOptions): Promise<Uint8Array>;\n        /**\n         * Executes editing command `redo` in page.\n         */\n        redo(): void;\n        /**\n         * Reloads the guest page.\n         */\n        reload(): void;\n        /**\n         * Reloads the guest page and ignores cache.\n         */\n        reloadIgnoringCache(): void;\n        /**\n         * Resolves if the removal was successful.\n         *\n         * Removes the inserted CSS from the current web page. The stylesheet is identified\n         * by its key, which is returned from `<webview>.insertCSS(css)`.\n         */\n        removeInsertedCSS(key: string): Promise<void>;\n        /**\n         * Executes editing command `replace` in page.\n         */\n        replace(text: string): void;\n        /**\n         * Executes editing command `replaceMisspelling` in page.\n         */\n        replaceMisspelling(text: string): void;\n        /**\n         * Scrolls to the bottom of the current `<webview>`.\n         */\n        scrollToBottom(): void;\n        /**\n         * Scrolls to the top of the current `<webview>`.\n         */\n        scrollToTop(): void;\n        /**\n         * Executes editing command `selectAll` in page.\n         */\n        selectAll(): void;\n        /**\n         * Send an asynchronous message to renderer process via `channel`, you can also\n         * send arbitrary arguments. The renderer process can handle the message by\n         * listening to the `channel` event with the `ipcRenderer` module.\n         *\n         * See webContents.send for examples.\n         */\n        send(channel: string, ...args: any[]): Promise<void>;\n        /**\n         * Sends an input `event` to the page.\n         *\n         * See webContents.sendInputEvent for detailed description of `event` object.\n         */\n        sendInputEvent(event: MouseInputEvent | MouseWheelInputEvent | KeyboardInputEvent): Promise<void>;\n        /**\n         * Send an asynchronous message to renderer process via `channel`, you can also\n         * send arbitrary arguments. The renderer process can handle the message by\n         * listening to the `channel` event with the `ipcRenderer` module.\n         *\n         * See webContents.sendToFrame for examples.\n         */\n        sendToFrame(frameId: [number, number], channel: string, ...args: any[]): Promise<void>;\n        /**\n         * Set guest page muted.\n         */\n        setAudioMuted(muted: boolean): void;\n        /**\n         * Overrides the user agent for the guest page.\n         */\n        setUserAgent(userAgent: string): void;\n        /**\n         * Sets the maximum and minimum pinch-to-zoom level.\n         */\n        setVisualZoomLevelLimits(minimumLevel: number, maximumLevel: number): Promise<void>;\n        /**\n         * Changes the zoom factor to the specified factor. Zoom factor is zoom percent\n         * divided by 100, so 300% = 3.0.\n         */\n        setZoomFactor(factor: number): void;\n        /**\n         * Changes the zoom level to the specified level. The original size is 0 and each\n         * increment above or below represents zooming 20% larger or smaller to default\n         * limits of 300% and 50% of original size, respectively. The formula for this is\n         * `scale := 1.2 ^ level`.\n         *\n         * > **NOTE**: The zoom policy at the Chromium level is same-origin, meaning that\n         * the zoom level for a specific domain propagates across all instances of windows\n         * with the same domain. Differentiating the window URLs will make zoom work\n         * per-window.\n         */\n        setZoomLevel(level: number): void;\n        /**\n         * Shows pop-up dictionary that searches the selected word on the page.\n         *\n         * @platform darwin\n         */\n        showDefinitionForSelection(): void;\n        /**\n         * Stops any pending navigation.\n         */\n        stop(): void;\n        /**\n         * Stops any `findInPage` request for the `webview` with the provided `action`.\n         */\n        stopFindInPage(action: \"clearSelection\" | \"keepSelection\" | \"activateSelection\"): void;\n        /**\n         * Executes editing command `undo` in page.\n         */\n        undo(): void;\n        /**\n         * Executes editing command `unselect` in page.\n         */\n        unselect(): void;\n        /**\n         * A `boolean`. When this attribute is present the guest page will be allowed to\n         * open new windows. Popups are disabled by default.\n         */\n        allowpopups: boolean;\n        /**\n         * A `string` which is a list of strings which specifies the blink features to be\n         * disabled separated by `,`. The full list of supported feature strings can be\n         * found in the RuntimeEnabledFeatures.json5 file.\n         */\n        disableblinkfeatures: string;\n        /**\n         * A `boolean`. When this attribute is present the guest page will have web\n         * security disabled. Web security is enabled by default.\n         *\n         * This value can only be modified before the first navigation.\n         */\n        disablewebsecurity: boolean;\n        /**\n         * A `string` which is a list of strings which specifies the blink features to be\n         * enabled separated by `,`. The full list of supported feature strings can be\n         * found in the RuntimeEnabledFeatures.json5 file.\n         */\n        enableblinkfeatures: string;\n        /**\n         * A `string` that sets the referrer URL for the guest page.\n         */\n        httpreferrer: string;\n        /**\n         * A `boolean`. When this attribute is present the guest page in `webview` will\n         * have node integration and can use node APIs like `require` and `process` to\n         * access low level system resources. Node integration is disabled by default in\n         * the guest page.\n         */\n        nodeintegration: boolean;\n        /**\n         * A `boolean` for the experimental option for enabling NodeJS support in\n         * sub-frames such as iframes inside the `webview`. All your preloads will load for\n         * every iframe, you can use `process.isMainFrame` to determine if you are in the\n         * main frame or not. This option is disabled by default in the guest page.\n         */\n        nodeintegrationinsubframes: boolean;\n        /**\n         * A `string` that sets the session used by the page. If `partition` starts with\n         * `persist:`, the page will use a persistent session available to all pages in the\n         * app with the same `partition`. if there is no `persist:` prefix, the page will\n         * use an in-memory session. By assigning the same `partition`, multiple pages can\n         * share the same session. If the `partition` is unset then default session of the\n         * app will be used.\n         *\n         * This value can only be modified before the first navigation, since the session\n         * of an active renderer process cannot change. Subsequent attempts to modify the\n         * value will fail with a DOM exception.\n         */\n        partition: string;\n        /**\n         * A `boolean`. When this attribute is present the guest page in `webview` will be\n         * able to use browser plugins. Plugins are disabled by default.\n         */\n        plugins: boolean;\n        /**\n         * A `string` that specifies a script that will be loaded before other scripts run\n         * in the guest page. The protocol of script's URL must be `file:` (even when using\n         * `asar:` archives) because it will be loaded by Node's `require` under the hood,\n         * which treats `asar:` archives as virtual directories.\n         *\n         * When the guest page doesn't have node integration this script will still have\n         * access to all Node APIs, but global objects injected by Node will be deleted\n         * after this script has finished executing.\n         */\n        preload: string;\n        /**\n         * A `string` representing the visible URL. Writing to this attribute initiates\n         * top-level navigation.\n         *\n         * Assigning `src` its own value will reload the current page.\n         *\n         * The `src` attribute can also accept data URLs, such as `data:text/plain,Hello,\n         * world!`.\n         */\n        src: string;\n        /**\n         * A `string` that sets the user agent for the guest page before the page is\n         * navigated to. Once the page is loaded, use the `setUserAgent` method to change\n         * the user agent.\n         */\n        useragent: string;\n        /**\n         * A `string` which is a comma separated list of strings which specifies the web\n         * preferences to be set on the webview. The full list of supported preference\n         * strings can be found in BrowserWindow.\n         *\n         * The string follows the same format as the features string in `window.open`. A\n         * name by itself is given a `true` boolean value. A preference can be set to\n         * another value by including an `=`, followed by the value. Special values `yes`\n         * and `1` are interpreted as `true`, while `no` and `0` are interpreted as\n         * `false`.\n         */\n        webpreferences: string;\n    }\n\n    interface AboutPanelOptionsOptions {\n        /**\n         * The app's name.\n         */\n        applicationName?: string;\n        /**\n         * The app's version.\n         */\n        applicationVersion?: string;\n        /**\n         * Copyright information.\n         */\n        copyright?: string;\n        /**\n         * The app's build version number.\n         *\n         * @platform darwin\n         */\n        version?: string;\n        /**\n         * Credit information.\n         *\n         * @platform darwin,win32\n         */\n        credits?: string;\n        /**\n         * List of app authors.\n         *\n         * @platform linux\n         */\n        authors?: string[];\n        /**\n         * The app's website.\n         *\n         * @platform linux\n         */\n        website?: string;\n        /**\n         * Path to the app's icon in a JPEG or PNG file format. On Linux, will be shown as\n         * 64x64 pixels while retaining aspect ratio.\n         *\n         * @platform linux,win32\n         */\n        iconPath?: string;\n    }\n\n    interface AddRepresentationOptions {\n        /**\n         * The scale factor to add the image representation for.\n         */\n        scaleFactor?: number;\n        /**\n         * Defaults to 0. Required if a bitmap buffer is specified as `buffer`.\n         */\n        width?: number;\n        /**\n         * Defaults to 0. Required if a bitmap buffer is specified as `buffer`.\n         */\n        height?: number;\n        /**\n         * The buffer containing the raw image data.\n         */\n        buffer?: Buffer;\n        /**\n         * The data URL containing either a base 64 encoded PNG or JPEG image.\n         */\n        dataURL?: string;\n    }\n\n    interface AdjustSelectionOptions {\n        /**\n         * Amount to shift the start index of the current selection.\n         */\n        start?: number;\n        /**\n         * Amount to shift the end index of the current selection.\n         */\n        end?: number;\n    }\n\n    interface AnimationSettings {\n        /**\n         * Returns true if rich animations should be rendered. Looks at session type (e.g.\n         * remote desktop) and accessibility settings to give guidance for heavy\n         * animations.\n         */\n        shouldRenderRichAnimation: boolean;\n        /**\n         * Determines on a per-platform basis whether scroll animations (e.g. produced by\n         * home/end key) should be enabled.\n         */\n        scrollAnimationsEnabledBySystem: boolean;\n        /**\n         * Determines whether the user desires reduced motion based on platform APIs.\n         */\n        prefersReducedMotion: boolean;\n    }\n\n    interface AppDetailsOptions {\n        /**\n         * Window's App User Model ID. It has to be set, otherwise the other options will\n         * have no effect.\n         */\n        appId?: string;\n        /**\n         * Window's Relaunch Icon.\n         */\n        appIconPath?: string;\n        /**\n         * Index of the icon in `appIconPath`. Ignored when `appIconPath` is not set.\n         * Default is `0`.\n         */\n        appIconIndex?: number;\n        /**\n         * Window's Relaunch Command.\n         */\n        relaunchCommand?: string;\n        /**\n         * Window's Relaunch Display Name.\n         */\n        relaunchDisplayName?: string;\n    }\n\n    interface ApplicationInfoForProtocolReturnValue {\n        /**\n         * the display icon of the app handling the protocol.\n         */\n        icon: NativeImage;\n        /**\n         * installation path of the app handling the protocol.\n         */\n        path: string;\n        /**\n         * display name of the app handling the protocol.\n         */\n        name: string;\n    }\n\n    interface AuthenticationResponseDetails {\n        url: string;\n    }\n\n    interface AuthInfo {\n        isProxy: boolean;\n        scheme: string;\n        host: string;\n        port: number;\n        realm: string;\n    }\n\n    interface AutoResizeOptions {\n        /**\n         * If `true`, the view's width will grow and shrink together with the window.\n         * `false` by default.\n         */\n        width?: boolean;\n        /**\n         * If `true`, the view's height will grow and shrink together with the window.\n         * `false` by default.\n         */\n        height?: boolean;\n        /**\n         * If `true`, the view's x position and width will grow and shrink proportionally\n         * with the window. `false` by default.\n         */\n        horizontal?: boolean;\n        /**\n         * If `true`, the view's y position and height will grow and shrink proportionally\n         * with the window. `false` by default.\n         */\n        vertical?: boolean;\n    }\n\n    interface BeforeSendResponse {\n        cancel?: boolean;\n        /**\n         * When provided, request will be made with these headers.\n         */\n        requestHeaders?: Record<string, string | string[]>;\n    }\n\n    interface BitmapOptions {\n        /**\n         * Defaults to 1.0.\n         */\n        scaleFactor?: number;\n    }\n\n    interface BlinkMemoryInfo {\n        /**\n         * Size of all allocated objects in Kilobytes.\n         */\n        allocated: number;\n        /**\n         * Total allocated space in Kilobytes.\n         */\n        total: number;\n    }\n\n    interface BluetoothPairingHandlerHandlerDetails {\n        deviceId: string;\n        /**\n         * The type of pairing prompt being requested. One of the following values:\n         */\n        pairingKind: \"confirm\" | \"confirmPin\" | \"providePin\";\n        frame: WebFrameMain;\n        /**\n         * The pin value to verify if `pairingKind` is `confirmPin`.\n         */\n        pin?: string;\n    }\n\n    interface BrowserViewConstructorOptions {\n        /**\n         * See BrowserWindow.\n         */\n        webPreferences?: WebPreferences;\n    }\n\n    interface BrowserWindowConstructorOptions {\n        /**\n         * Window's width in pixels. Default is `800`.\n         */\n        width?: number;\n        /**\n         * Window's height in pixels. Default is `600`.\n         */\n        height?: number;\n        /**\n         * (**required** if y is used) Window's left offset from screen. Default is to\n         * center the window.\n         */\n        x?: number;\n        /**\n         * (**required** if x is used) Window's top offset from screen. Default is to\n         * center the window.\n         */\n        y?: number;\n        /**\n         * The `width` and `height` would be used as web page's size, which means the\n         * actual window's size will include window frame's size and be slightly larger.\n         * Default is `false`.\n         */\n        useContentSize?: boolean;\n        /**\n         * Show window in the center of the screen. Default is `false`.\n         */\n        center?: boolean;\n        /**\n         * Window's minimum width. Default is `0`.\n         */\n        minWidth?: number;\n        /**\n         * Window's minimum height. Default is `0`.\n         */\n        minHeight?: number;\n        /**\n         * Window's maximum width. Default is no limit.\n         */\n        maxWidth?: number;\n        /**\n         * Window's maximum height. Default is no limit.\n         */\n        maxHeight?: number;\n        /**\n         * Whether window is resizable. Default is `true`.\n         */\n        resizable?: boolean;\n        /**\n         * Whether window is movable. This is not implemented on Linux. Default is `true`.\n         *\n         * @platform darwin,win32\n         */\n        movable?: boolean;\n        /**\n         * Whether window is minimizable. This is not implemented on Linux. Default is\n         * `true`.\n         *\n         * @platform darwin,win32\n         */\n        minimizable?: boolean;\n        /**\n         * Whether window is maximizable. This is not implemented on Linux. Default is\n         * `true`.\n         *\n         * @platform darwin,win32\n         */\n        maximizable?: boolean;\n        /**\n         * Whether window is closable. This is not implemented on Linux. Default is `true`.\n         *\n         * @platform darwin,win32\n         */\n        closable?: boolean;\n        /**\n         * Whether the window can be focused. Default is `true`. On Windows setting\n         * `focusable: false` also implies setting `skipTaskbar: true`. On Linux setting\n         * `focusable: false` makes the window stop interacting with wm, so the window will\n         * always stay on top in all workspaces.\n         */\n        focusable?: boolean;\n        /**\n         * Whether the window should always stay on top of other windows. Default is\n         * `false`.\n         */\n        alwaysOnTop?: boolean;\n        /**\n         * Whether the window should show in fullscreen. When explicitly set to `false` the\n         * fullscreen button will be hidden or disabled on macOS. Default is `false`.\n         */\n        fullscreen?: boolean;\n        /**\n         * Whether the window can be put into fullscreen mode. On macOS, also whether the\n         * maximize/zoom button should toggle full screen mode or maximize window. Default\n         * is `true`.\n         */\n        fullscreenable?: boolean;\n        /**\n         * Use pre-Lion fullscreen on macOS. Default is `false`.\n         *\n         * @platform darwin\n         */\n        simpleFullscreen?: boolean;\n        /**\n         * Whether to show the window in taskbar. Default is `false`.\n         *\n         * @platform darwin,win32\n         */\n        skipTaskbar?: boolean;\n        /**\n         * Whether window should be hidden when the user toggles into mission control.\n         *\n         * @platform darwin\n         */\n        hiddenInMissionControl?: boolean;\n        /**\n         * Whether the window is in kiosk mode. Default is `false`.\n         */\n        kiosk?: boolean;\n        /**\n         * Default window title. Default is `\"Electron\"`. If the HTML tag `<title>` is\n         * defined in the HTML file loaded by `loadURL()`, this property will be ignored.\n         */\n        title?: string;\n        /**\n         * The window icon. On Windows it is recommended to use `ICO` icons to get best\n         * visual effects, you can also leave it undefined so the executable's icon will be\n         * used.\n         */\n        icon?: NativeImage | string;\n        /**\n         * Whether window should be shown when created. Default is `true`.\n         */\n        show?: boolean;\n        /**\n         * Whether the renderer should be active when `show` is `false` and it has just\n         * been created.  In order for `document.visibilityState` to work correctly on\n         * first load with `show: false` you should set this to `false`.  Setting this to\n         * `false` will cause the `ready-to-show` event to not fire.  Default is `true`.\n         */\n        paintWhenInitiallyHidden?: boolean;\n        /**\n         * Specify `false` to create a frameless window. Default is `true`.\n         */\n        frame?: boolean;\n        /**\n         * Specify parent window. Default is `null`.\n         */\n        parent?: BrowserWindow;\n        /**\n         * Whether this is a modal window. This only works when the window is a child\n         * window. Default is `false`.\n         */\n        modal?: boolean;\n        /**\n         * Whether clicking an inactive window will also click through to the web contents.\n         * Default is `false` on macOS. This option is not configurable on other platforms.\n         *\n         * @platform darwin\n         */\n        acceptFirstMouse?: boolean;\n        /**\n         * Whether to hide cursor when typing. Default is `false`.\n         */\n        disableAutoHideCursor?: boolean;\n        /**\n         * Auto hide the menu bar unless the `Alt` key is pressed. Default is `false`.\n         */\n        autoHideMenuBar?: boolean;\n        /**\n         * Enable the window to be resized larger than screen. Only relevant for macOS, as\n         * other OSes allow larger-than-screen windows by default. Default is `false`.\n         *\n         * @platform darwin\n         */\n        enableLargerThanScreen?: boolean;\n        /**\n         * The window's background color in Hex, RGB, RGBA, HSL, HSLA or named CSS color\n         * format. Alpha in #AARRGGBB format is supported if `transparent` is set to\n         * `true`. Default is `#FFF` (white). See win.setBackgroundColor for more\n         * information.\n         */\n        backgroundColor?: string;\n        /**\n         * Whether window should have a shadow. Default is `true`.\n         */\n        hasShadow?: boolean;\n        /**\n         * Set the initial opacity of the window, between 0.0 (fully transparent) and 1.0\n         * (fully opaque). This is only implemented on Windows and macOS.\n         *\n         * @platform darwin,win32\n         */\n        opacity?: number;\n        /**\n         * Forces using dark theme for the window, only works on some GTK+3 desktop\n         * environments. Default is `false`.\n         */\n        darkTheme?: boolean;\n        /**\n         * Makes the window transparent. Default is `false`. On Windows, does not work\n         * unless the window is frameless.\n         */\n        transparent?: boolean;\n        /**\n         * The type of window, default is normal window. See more about this below.\n         */\n        type?: string;\n        /**\n         * Specify how the material appearance should reflect window activity state on\n         * macOS. Must be used with the `vibrancy` property. Possible values are:\n         *\n         * @platform darwin\n         */\n        visualEffectState?: \"followWindow\" | \"active\" | \"inactive\";\n        /**\n         * The style of window title bar. Default is `default`. Possible values are:\n         *\n         * @platform darwin,win32\n         */\n        titleBarStyle?: \"default\" | \"hidden\" | \"hiddenInset\" | \"customButtonsOnHover\";\n        /**\n         * Set a custom position for the traffic light buttons in frameless windows.\n         *\n         * @platform darwin\n         */\n        trafficLightPosition?: Point;\n        /**\n         * Whether frameless window should have rounded corners on macOS. Default is\n         * `true`. Setting this property to `false` will prevent the window from being\n         * fullscreenable.\n         *\n         * @platform darwin\n         */\n        roundedCorners?: boolean;\n        /**\n         * Shows the title in the title bar in full screen mode on macOS for `hiddenInset`\n         * titleBarStyle. Default is `false`.\n         *\n         * @deprecated\n         * @platform darwin\n         */\n        fullscreenWindowTitle?: boolean;\n        /**\n         * Use `WS_THICKFRAME` style for frameless windows on Windows, which adds standard\n         * window frame. Setting it to `false` will remove window shadow and window\n         * animations. Default is `true`.\n         */\n        thickFrame?: boolean;\n        /**\n         * Add a type of vibrancy effect to the window, only on macOS. Can be\n         * `appearance-based`, `light`, `dark`, `titlebar`, `selection`, `menu`, `popover`,\n         * `sidebar`, `medium-light`, `ultra-dark`, `header`, `sheet`, `window`, `hud`,\n         * `fullscreen-ui`, `tooltip`, `content`, `under-window`, or `under-page`. Please\n         * note that `appearance-based`, `light`, `dark`, `medium-light`, and `ultra-dark`\n         * are deprecated and have been removed in macOS Catalina (10.15).\n         *\n         * @platform darwin\n         */\n        vibrancy?: \"appearance-based\" | \"light\" | \"dark\" | \"titlebar\" | \"selection\" | \"menu\" | \"popover\" | \"sidebar\" | \"medium-light\" | \"ultra-dark\" | \"header\" | \"sheet\" | \"window\" | \"hud\" | \"fullscreen-ui\" | \"tooltip\" | \"content\" | \"under-window\" | \"under-page\";\n        /**\n         * Set the window's system-drawn background material, including behind the\n         * non-client area. Can be `auto`, `none`, `mica`, `acrylic` or `tabbed`. See\n         * win.setBackgroundMaterial for more information.\n         *\n         * @platform win32\n         */\n        backgroundMaterial?: \"auto\" | \"none\" | \"mica\" | \"acrylic\" | \"tabbed\";\n        /**\n         * Controls the behavior on macOS when option-clicking the green stoplight button\n         * on the toolbar or by clicking the Window > Zoom menu item. If `true`, the window\n         * will grow to the preferred width of the web page when zoomed, `false` will cause\n         * it to zoom to the width of the screen. This will also affect the behavior when\n         * calling `maximize()` directly. Default is `false`.\n         *\n         * @platform darwin\n         */\n        zoomToPageWidth?: boolean;\n        /**\n         * Tab group name, allows opening the window as a native tab. Windows with the same\n         * tabbing identifier will be grouped together. This also adds a native new tab\n         * button to your window's tab bar and allows your `app` and window to receive the\n         * `new-window-for-tab` event.\n         *\n         * @platform darwin\n         */\n        tabbingIdentifier?: string;\n        /**\n         * Settings of web page's features.\n         */\n        webPreferences?: WebPreferences;\n        /**\n         *  When using a frameless window in conjunction with\n         * `win.setWindowButtonVisibility(true)` on macOS or using a `titleBarStyle` so\n         * that the standard window controls (\"traffic lights\" on macOS) are visible, this\n         * property enables the Window Controls Overlay JavaScript APIs and CSS Environment\n         * Variables. Specifying `true` will result in an overlay with default system\n         * colors. Default is `false`.\n         */\n        titleBarOverlay?: TitleBarOverlay | boolean;\n    }\n\n    interface CallbackResponse {\n        cancel?: boolean;\n        /**\n         * The original request is prevented from being sent or completed and is instead\n         * redirected to the given URL.\n         */\n        redirectURL?: string;\n    }\n\n    interface CertificateTrustDialogOptions {\n        /**\n         * The certificate to trust/import.\n         */\n        certificate: Certificate;\n        /**\n         * The message to display to the user.\n         */\n        message: string;\n    }\n\n    interface ClearCodeCachesOptions {\n        /**\n         * An array of url corresponding to the resource whose generated code cache needs\n         * to be removed. If the list is empty then all entries in the cache directory will\n         * be removed.\n         */\n        urls?: string[];\n    }\n\n    interface ClearStorageDataOptions {\n        /**\n         * Should follow `window.location.origin`’s representation `scheme://host:port`.\n         */\n        origin?: string;\n        /**\n         * The types of storages to clear, can contain: `cookies`, `filesystem`, `indexdb`,\n         * `localstorage`, `shadercache`, `websql`, `serviceworkers`, `cachestorage`. If\n         * not specified, clear all storage types.\n         */\n        storages?: string[];\n        /**\n         * The types of quotas to clear, can contain: `temporary`, `syncable`. If not\n         * specified, clear all quotas.\n         */\n        quotas?: string[];\n    }\n\n    interface ClientRequestConstructorOptions {\n        /**\n         * The HTTP request method. Defaults to the GET method.\n         */\n        method?: string;\n        /**\n         * The request URL. Must be provided in the absolute form with the protocol scheme\n         * specified as http or https.\n         */\n        url?: string;\n        /**\n         * The `Session` instance with which the request is associated.\n         */\n        session?: Session;\n        /**\n         * The name of the `partition` with which the request is associated. Defaults to\n         * the empty string. The `session` option supersedes `partition`. Thus if a\n         * `session` is explicitly specified, `partition` is ignored.\n         */\n        partition?: string;\n        /**\n         * Can be `include`, `omit` or `same-origin`. Whether to send credentials with this\n         * request. If set to `include`, credentials from the session associated with the\n         * request will be used. If set to `omit`, credentials will not be sent with the\n         * request (and the `'login'` event will not be triggered in the event of a 401).\n         * If set to `same-origin`, `origin` must also be specified. This matches the\n         * behavior of the fetch option of the same name. If this option is not specified,\n         * authentication data from the session will be sent, and cookies will not be sent\n         * (unless `useSessionCookies` is set).\n         */\n        credentials?: \"include\" | \"omit\" | \"same-origin\";\n        /**\n         * Whether to send cookies with this request from the provided session. If\n         * `credentials` is specified, this option has no effect. Default is `false`.\n         */\n        useSessionCookies?: boolean;\n        /**\n         * Can be `http:` or `https:`. The protocol scheme in the form 'scheme:'. Defaults\n         * to 'http:'.\n         */\n        protocol?: string;\n        /**\n         * The server host provided as a concatenation of the hostname and the port number\n         * 'hostname:port'.\n         */\n        host?: string;\n        /**\n         * The server host name.\n         */\n        hostname?: string;\n        /**\n         * The server's listening port number.\n         */\n        port?: number;\n        /**\n         * The path part of the request URL.\n         */\n        path?: string;\n        /**\n         * Can be `follow`, `error` or `manual`. The redirect mode for this request. When\n         * mode is `error`, any redirection will be aborted. When mode is `manual` the\n         * redirection will be cancelled unless `request.followRedirect` is invoked\n         * synchronously during the `redirect` event.  Defaults to `follow`.\n         */\n        redirect?: \"follow\" | \"error\" | \"manual\";\n        /**\n         * The origin URL of the request.\n         */\n        origin?: string;\n        /**\n         * can be `\"\"`, `no-referrer`, `no-referrer-when-downgrade`, `origin`,\n         * `origin-when-cross-origin`, `unsafe-url`, `same-origin`, `strict-origin`, or\n         * `strict-origin-when-cross-origin`. Defaults to\n         * `strict-origin-when-cross-origin`.\n         */\n        referrerPolicy?: string;\n        /**\n         * can be `default`, `no-store`, `reload`, `no-cache`, `force-cache` or\n         * `only-if-cached`.\n         */\n        cache?: \"default\" | \"no-store\" | \"reload\" | \"no-cache\" | \"force-cache\" | \"only-if-cached\";\n    }\n\n    interface CloseOpts {\n        /**\n         * if true, fire the `beforeunload` event before closing the page. If the page\n         * prevents the unload, the WebContents will not be closed. The\n         * `will-prevent-unload` will be fired if the page requests prevention of unload.\n         */\n        waitForBeforeUnload: boolean;\n    }\n\n    interface Config {\n        /**\n         * The proxy mode. Should be one of `direct`, `auto_detect`, `pac_script`,\n         * `fixed_servers` or `system`. If it's unspecified, it will be automatically\n         * determined based on other specified options.\n         */\n        mode?: \"direct\" | \"auto_detect\" | \"pac_script\" | \"fixed_servers\" | \"system\";\n        /**\n         * The URL associated with the PAC file.\n         */\n        pacScript?: string;\n        /**\n         * Rules indicating which proxies to use.\n         */\n        proxyRules?: string;\n        /**\n         * Rules indicating which URLs should bypass the proxy settings.\n         */\n        proxyBypassRules?: string;\n    }\n\n    interface ConfigureHostResolverOptions {\n        /**\n         * Whether the built-in host resolver is used in preference to getaddrinfo. When\n         * enabled, the built-in resolver will attempt to use the system's DNS settings to\n         * do DNS lookups itself. Enabled by default on macOS, disabled by default on\n         * Windows and Linux.\n         */\n        enableBuiltInResolver?: boolean;\n        /**\n         * Can be \"off\", \"automatic\" or \"secure\". Configures the DNS-over-HTTP mode. When\n         * \"off\", no DoH lookups will be performed. When \"automatic\", DoH lookups will be\n         * performed first if DoH is available, and insecure DNS lookups will be performed\n         * as a fallback. When \"secure\", only DoH lookups will be performed. Defaults to\n         * \"automatic\".\n         */\n        secureDnsMode?: string;\n        /**\n         * A list of DNS-over-HTTP server templates. See RFC8484 § 3 for details on the\n         * template format. Most servers support the POST method; the template for such\n         * servers is simply a URI. Note that for some DNS providers, the resolver will\n         * automatically upgrade to DoH unless DoH is explicitly disabled, even if there\n         * are no DoH servers provided in this list.\n         */\n        secureDnsServers?: string[];\n        /**\n         * Controls whether additional DNS query types, e.g. HTTPS (DNS type 65) will be\n         * allowed besides the traditional A and AAAA queries when a request is being made\n         * via insecure DNS. Has no effect on Secure DNS which always allows additional\n         * types. Defaults to true.\n         */\n        enableAdditionalDnsQueryTypes?: boolean;\n    }\n\n    interface ConsoleMessageEvent extends DOMEvent {\n        /**\n         * The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and\n         * `error`.\n         */\n        level: number;\n        /**\n         * The actual console message\n         */\n        message: string;\n        /**\n         * The line number of the source that triggered this console message\n         */\n        line: number;\n        sourceId: string;\n    }\n\n    interface ContextMenuEvent extends DOMEvent {\n        params: Params;\n    }\n\n    interface ContextMenuParams {\n        /**\n         * x coordinate.\n         */\n        x: number;\n        /**\n         * y coordinate.\n         */\n        y: number;\n        /**\n         * Frame from which the context menu was invoked.\n         */\n        frame: WebFrameMain;\n        /**\n         * URL of the link that encloses the node the context menu was invoked on.\n         */\n        linkURL: string;\n        /**\n         * Text associated with the link. May be an empty string if the contents of the\n         * link are an image.\n         */\n        linkText: string;\n        /**\n         * URL of the top level page that the context menu was invoked on.\n         */\n        pageURL: string;\n        /**\n         * URL of the subframe that the context menu was invoked on.\n         */\n        frameURL: string;\n        /**\n         * Source URL for the element that the context menu was invoked on. Elements with\n         * source URLs are images, audio and video.\n         */\n        srcURL: string;\n        /**\n         * Type of the node the context menu was invoked on. Can be `none`, `image`,\n         * `audio`, `video`, `canvas`, `file` or `plugin`.\n         */\n        mediaType: \"none\" | \"image\" | \"audio\" | \"video\" | \"canvas\" | \"file\" | \"plugin\";\n        /**\n         * Whether the context menu was invoked on an image which has non-empty contents.\n         */\n        hasImageContents: boolean;\n        /**\n         * Whether the context is editable.\n         */\n        isEditable: boolean;\n        /**\n         * Text of the selection that the context menu was invoked on.\n         */\n        selectionText: string;\n        /**\n         * Title text of the selection that the context menu was invoked on.\n         */\n        titleText: string;\n        /**\n         * Alt text of the selection that the context menu was invoked on.\n         */\n        altText: string;\n        /**\n         * Suggested filename to be used when saving file through 'Save Link As' option of\n         * context menu.\n         */\n        suggestedFilename: string;\n        /**\n         * Rect representing the coordinates in the document space of the selection.\n         */\n        selectionRect: Rectangle;\n        /**\n         * Start position of the selection text.\n         */\n        selectionStartOffset: number;\n        /**\n         * The referrer policy of the frame on which the menu is invoked.\n         */\n        referrerPolicy: Referrer;\n        /**\n         * The misspelled word under the cursor, if any.\n         */\n        misspelledWord: string;\n        /**\n         * An array of suggested words to show the user to replace the `misspelledWord`.\n         * Only available if there is a misspelled word and spellchecker is enabled.\n         */\n        dictionarySuggestions: string[];\n        /**\n         * The character encoding of the frame on which the menu was invoked.\n         */\n        frameCharset: string;\n        /**\n         * If the context menu was invoked on an input field, the type of that field.\n         * Possible values are `none`, `plainText`, `password`, `other`.\n         */\n        inputFieldType: string;\n        /**\n         * If the context is editable, whether or not spellchecking is enabled.\n         */\n        spellcheckEnabled: boolean;\n        /**\n         * Input source that invoked the context menu. Can be `none`, `mouse`, `keyboard`,\n         * `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`,\n         * `adjustSelection`, or `adjustSelectionReset`.\n         */\n        menuSourceType: \"none\" | \"mouse\" | \"keyboard\" | \"touch\" | \"touchMenu\" | \"longPress\" | \"longTap\" | \"touchHandle\" | \"stylus\" | \"adjustSelection\" | \"adjustSelectionReset\";\n        /**\n         * The flags for the media element the context menu was invoked on.\n         */\n        mediaFlags: MediaFlags;\n        /**\n         * These flags indicate whether the renderer believes it is able to perform the\n         * corresponding action.\n         */\n        editFlags: EditFlags;\n    }\n\n    interface ContinueActivityDetails {\n        /**\n         * A string identifying the URL of the webpage accessed by the activity on another\n         * device, if available.\n         */\n        webpageURL?: string;\n    }\n\n    interface CookiesGetFilter {\n        /**\n         * Retrieves cookies which are associated with `url`. Empty implies retrieving\n         * cookies of all URLs.\n         */\n        url?: string;\n        /**\n         * Filters cookies by name.\n         */\n        name?: string;\n        /**\n         * Retrieves cookies whose domains match or are subdomains of `domains`.\n         */\n        domain?: string;\n        /**\n         * Retrieves cookies whose path matches `path`.\n         */\n        path?: string;\n        /**\n         * Filters cookies by their Secure property.\n         */\n        secure?: boolean;\n        /**\n         * Filters out session or persistent cookies.\n         */\n        session?: boolean;\n        /**\n         * Filters cookies by httpOnly.\n         */\n        httpOnly?: boolean;\n    }\n\n    interface CookiesSetDetails {\n        /**\n         * The URL to associate the cookie with. The promise will be rejected if the URL is\n         * invalid.\n         */\n        url: string;\n        /**\n         * The name of the cookie. Empty by default if omitted.\n         */\n        name?: string;\n        /**\n         * The value of the cookie. Empty by default if omitted.\n         */\n        value?: string;\n        /**\n         * The domain of the cookie; this will be normalized with a preceding dot so that\n         * it's also valid for subdomains. Empty by default if omitted.\n         */\n        domain?: string;\n        /**\n         * The path of the cookie. Empty by default if omitted.\n         */\n        path?: string;\n        /**\n         * Whether the cookie should be marked as Secure. Defaults to false unless Same\n         * Site=None attribute is used.\n         */\n        secure?: boolean;\n        /**\n         * Whether the cookie should be marked as HTTP only. Defaults to false.\n         */\n        httpOnly?: boolean;\n        /**\n         * The expiration date of the cookie as the number of seconds since the UNIX epoch.\n         * If omitted then the cookie becomes a session cookie and will not be retained\n         * between sessions.\n         */\n        expirationDate?: number;\n        /**\n         * The Same Site policy to apply to this cookie.  Can be `unspecified`,\n         * `no_restriction`, `lax` or `strict`.  Default is `lax`.\n         */\n        sameSite?: \"unspecified\" | \"no_restriction\" | \"lax\" | \"strict\";\n    }\n\n    interface CrashReporterStartOptions {\n        /**\n         * URL that crash reports will be sent to as POST. Required unless `uploadToServer`\n         * is `false`.\n         */\n        submitURL?: string;\n        /**\n         * Defaults to `app.name`.\n         */\n        productName?: string;\n        /**\n         * Deprecated alias for `{ globalExtra: { _companyName: ... } }`.\n         *\n         * @deprecated\n         */\n        companyName?: string;\n        /**\n         * Whether crash reports should be sent to the server. If false, crash reports will\n         * be collected and stored in the crashes directory, but not uploaded. Default is\n         * `true`.\n         */\n        uploadToServer?: boolean;\n        /**\n         * If true, crashes generated in the main process will not be forwarded to the\n         * system crash handler. Default is `false`.\n         */\n        ignoreSystemCrashHandler?: boolean;\n        /**\n         * If true, limit the number of crashes uploaded to 1/hour. Default is `false`.\n         *\n         * @platform darwin,win32\n         */\n        rateLimit?: boolean;\n        /**\n         * If true, crash reports will be compressed and uploaded with `Content-Encoding:\n         * gzip`. Default is `true`.\n         */\n        compress?: boolean;\n        /**\n         * Extra string key/value annotations that will be sent along with crash reports\n         * that are generated in the main process. Only string values are supported.\n         * Crashes generated in child processes will not contain these extra parameters to\n         * crash reports generated from child processes, call `addExtraParameter` from the\n         * child process.\n         */\n        extra?: Record<string, string>;\n        /**\n         * Extra string key/value annotations that will be sent along with any crash\n         * reports generated in any process. These annotations cannot be changed once the\n         * crash reporter has been started. If a key is present in both the global extra\n         * parameters and the process-specific extra parameters, then the global one will\n         * take precedence. By default, `productName` and the app version are included, as\n         * well as the Electron version.\n         */\n        globalExtra?: Record<string, string>;\n    }\n\n    interface CreateFromBitmapOptions {\n        width: number;\n        height: number;\n        /**\n         * Defaults to 1.0.\n         */\n        scaleFactor?: number;\n    }\n\n    interface CreateFromBufferOptions {\n        /**\n         * Required for bitmap buffers.\n         */\n        width?: number;\n        /**\n         * Required for bitmap buffers.\n         */\n        height?: number;\n        /**\n         * Defaults to 1.0.\n         */\n        scaleFactor?: number;\n    }\n\n    interface CreateInterruptedDownloadOptions {\n        /**\n         * Absolute path of the download.\n         */\n        path: string;\n        /**\n         * Complete URL chain for the download.\n         */\n        urlChain: string[];\n        mimeType?: string;\n        /**\n         * Start range for the download.\n         */\n        offset: number;\n        /**\n         * Total length of the download.\n         */\n        length: number;\n        /**\n         * Last-Modified header value.\n         */\n        lastModified?: string;\n        /**\n         * ETag header value.\n         */\n        eTag?: string;\n        /**\n         * Time when download was started in number of seconds since UNIX epoch.\n         */\n        startTime?: number;\n    }\n\n    interface Data {\n        text?: string;\n        html?: string;\n        image?: NativeImage;\n        rtf?: string;\n        /**\n         * The title of the URL at `text`.\n         */\n        bookmark?: string;\n    }\n\n    interface Details {\n        /**\n         * Process type. One of the following values:\n         */\n        type: \"Utility\" | \"Zygote\" | \"Sandbox helper\" | \"GPU\" | \"Pepper Plugin\" | \"Pepper Plugin Broker\" | \"Unknown\";\n        /**\n         * The reason the child process is gone. Possible values:\n         */\n        reason: \"clean-exit\" | \"abnormal-exit\" | \"killed\" | \"crashed\" | \"oom\" | \"launch-failed\" | \"integrity-failure\";\n        /**\n         * The exit code for the process (e.g. status from waitpid if on posix, from\n         * GetExitCodeProcess on Windows).\n         */\n        exitCode: number;\n        /**\n         * The non-localized name of the process.\n         */\n        serviceName?: string;\n        /**\n         * The name of the process. Examples for utility: `Audio Service`, `Content\n         * Decryption Module Service`, `Network Service`, `Video Capture`, etc.\n         */\n        name?: string;\n    }\n\n    interface DevicePermissionHandlerHandlerDetails {\n        /**\n         * The type of device that permission is being requested on, can be `hid`,\n         * `serial`, or `usb`.\n         */\n        deviceType: \"hid\" | \"serial\" | \"usb\";\n        /**\n         * The origin URL of the device permission check.\n         */\n        origin: string;\n        /**\n         * the device that permission is being requested for.\n         */\n        device: HIDDevice | SerialPort | USBDevice;\n    }\n\n    interface DevtoolsOpenUrlEvent extends DOMEvent {\n        /**\n         * URL of the link that was clicked or selected.\n         */\n        url: string;\n    }\n\n    interface DidChangeThemeColorEvent extends DOMEvent {\n        themeColor: string;\n    }\n\n    interface DidCreateWindowDetails {\n        /**\n         * URL for the created window.\n         */\n        url: string;\n        /**\n         * Name given to the created window in the `window.open()` call.\n         */\n        frameName: string;\n        /**\n         * The options used to create the BrowserWindow. They are merged in increasing\n         * precedence: parsed options from the `features` string from `window.open()`,\n         * security-related webPreferences inherited from the parent, and options given by\n         * `webContents.setWindowOpenHandler`. Unrecognized options are not filtered out.\n         */\n        options: BrowserWindowConstructorOptions;\n        /**\n         * The referrer that will be passed to the new window. May or may not result in the\n         * `Referer` header being sent, depending on the referrer policy.\n         */\n        referrer: Referrer;\n        /**\n         * The post data that will be sent to the new window, along with the appropriate\n         * headers that will be set. If no post data is to be sent, the value will be\n         * `null`. Only defined when the window is being created by a form that set\n         * `target=_blank`.\n         */\n        postBody?: PostBody;\n        /**\n         * Can be `default`, `foreground-tab`, `background-tab`, `new-window` or `other`.\n         */\n        disposition: \"default\" | \"foreground-tab\" | \"background-tab\" | \"new-window\" | \"other\";\n    }\n\n    interface DidFailLoadEvent extends DOMEvent {\n        errorCode: number;\n        errorDescription: string;\n        validatedURL: string;\n        isMainFrame: boolean;\n    }\n\n    interface DidFrameFinishLoadEvent extends DOMEvent {\n        isMainFrame: boolean;\n    }\n\n    interface DidFrameNavigateEvent extends DOMEvent {\n        url: string;\n        /**\n         * -1 for non HTTP navigations\n         */\n        httpResponseCode: number;\n        /**\n         * empty for non HTTP navigations,\n         */\n        httpStatusText: string;\n        isMainFrame: boolean;\n        frameProcessId: number;\n        frameRoutingId: number;\n    }\n\n    interface DidNavigateEvent extends DOMEvent {\n        url: string;\n    }\n\n    interface DidNavigateInPageEvent extends DOMEvent {\n        isMainFrame: boolean;\n        url: string;\n    }\n\n    interface DidRedirectNavigationEvent extends DOMEvent {\n        url: string;\n        isInPlace: boolean;\n        isMainFrame: boolean;\n        frameProcessId: number;\n        frameRoutingId: number;\n    }\n\n    interface DidStartNavigationEvent extends DOMEvent {\n        url: string;\n        isInPlace: boolean;\n        isMainFrame: boolean;\n        frameProcessId: number;\n        frameRoutingId: number;\n    }\n\n    interface DisplayBalloonOptions {\n        /**\n         * Icon to use when `iconType` is `custom`.\n         */\n        icon?: NativeImage | string;\n        /**\n         * Can be `none`, `info`, `warning`, `error` or `custom`. Default is `custom`.\n         */\n        iconType?: \"none\" | \"info\" | \"warning\" | \"error\" | \"custom\";\n        title: string;\n        content: string;\n        /**\n         * The large version of the icon should be used. Default is `true`. Maps to\n         * `NIIF_LARGE_ICON`.\n         */\n        largeIcon?: boolean;\n        /**\n         * Do not play the associated sound. Default is `false`. Maps to `NIIF_NOSOUND`.\n         */\n        noSound?: boolean;\n        /**\n         * Do not display the balloon notification if the current user is in \"quiet time\".\n         * Default is `false`. Maps to `NIIF_RESPECT_QUIET_TIME`.\n         */\n        respectQuietTime?: boolean;\n    }\n\n    interface DisplayMediaRequestHandlerHandlerRequest {\n        /**\n         * Frame that is requesting access to media.\n         */\n        frame: WebFrameMain;\n        /**\n         * Origin of the page making the request.\n         */\n        securityOrigin: string;\n        /**\n         * true if the web content requested a video stream.\n         */\n        videoRequested: boolean;\n        /**\n         * true if the web content requested an audio stream.\n         */\n        audioRequested: boolean;\n        /**\n         * Whether a user gesture was active when this request was triggered.\n         */\n        userGesture: boolean;\n    }\n\n    interface EnableNetworkEmulationOptions {\n        /**\n         * Whether to emulate network outage. Defaults to false.\n         */\n        offline?: boolean;\n        /**\n         * RTT in ms. Defaults to 0 which will disable latency throttling.\n         */\n        latency?: number;\n        /**\n         * Download rate in Bps. Defaults to 0 which will disable download throttling.\n         */\n        downloadThroughput?: number;\n        /**\n         * Upload rate in Bps. Defaults to 0 which will disable upload throttling.\n         */\n        uploadThroughput?: number;\n    }\n\n    interface FeedURLOptions {\n        url: string;\n        /**\n         * HTTP request headers.\n         *\n         * @platform darwin\n         */\n        headers?: Record<string, string>;\n        /**\n         * Can be `json` or `default`, see the Squirrel.Mac README for more information.\n         *\n         * @platform darwin\n         */\n        serverType?: \"json\" | \"default\";\n    }\n\n    interface FileIconOptions {\n        size: \"small\" | \"normal\" | \"large\";\n    }\n\n    interface FindInPageOptions {\n        /**\n         * Whether to search forward or backward, defaults to `true`.\n         */\n        forward?: boolean;\n        /**\n         * Whether to begin a new text finding session with this request. Should be `true`\n         * for initial requests, and `false` for follow-up requests. Defaults to `false`.\n         */\n        findNext?: boolean;\n        /**\n         * Whether search should be case-sensitive, defaults to `false`.\n         */\n        matchCase?: boolean;\n    }\n\n    interface FocusOptions {\n        /**\n         * Make the receiver the active app even if another app is currently active.\n         *\n         * @platform darwin\n         */\n        steal: boolean;\n    }\n\n    interface ForkOptions {\n        /**\n         * Environment key-value pairs. Default is `process.env`.\n         */\n        env?: Env;\n        /**\n         * List of string arguments passed to the executable.\n         */\n        execArgv?: string[];\n        /**\n         * Current working directory of the child process.\n         */\n        cwd?: string;\n        /**\n         * Allows configuring the mode for `stdout` and `stderr` of the child process.\n         * Default is `inherit`. String value can be one of `pipe`, `ignore`, `inherit`,\n         * for more details on these values you can refer to stdio documentation from\n         * Node.js. Currently this option only supports configuring `stdout` and `stderr`\n         * to either `pipe`, `inherit` or `ignore`. Configuring `stdin` is not supported;\n         * `stdin` will always be ignored. For example, the supported values will be\n         * processed as following:\n         */\n        stdio?: Array<\"pipe\" | \"ignore\" | \"inherit\"> | string;\n        /**\n         * Name of the process that will appear in `name` property of `child-process-gone`\n         * event of `app`. Default is `node.mojom.NodeService`.\n         */\n        serviceName?: string;\n        /**\n         * With this flag, the utility process will be launched via the `Electron Helper\n         * (Plugin).app` helper executable on macOS, which can be codesigned with\n         * `com.apple.security.cs.disable-library-validation` and\n         * `com.apple.security.cs.allow-unsigned-executable-memory` entitlements. This will\n         * allow the utility process to load unsigned libraries. Unless you specifically\n         * need this capability, it is best to leave this disabled. Default is `false`.\n         *\n         * @platform darwin\n         */\n        allowLoadingUnsignedLibraries?: boolean;\n    }\n\n    interface FoundInPageEvent extends DOMEvent {\n        result: FoundInPageResult;\n    }\n\n    interface FrameCreatedDetails {\n        frame: WebFrameMain;\n    }\n\n    interface FromPartitionOptions {\n        /**\n         * Whether to enable cache.\n         */\n        cache: boolean;\n    }\n\n    interface FromPathOptions {\n        /**\n         * Whether to enable cache.\n         */\n        cache: boolean;\n    }\n\n    interface HandlerDetails {\n        /**\n         * The _resolved_ version of the URL passed to `window.open()`. e.g. opening a\n         * window with `window.open('foo')` will yield something like\n         * `https://the-origin/the/current/path/foo`.\n         */\n        url: string;\n        /**\n         * Name of the window provided in `window.open()`\n         */\n        frameName: string;\n        /**\n         * Comma separated list of window features provided to `window.open()`.\n         */\n        features: string;\n        /**\n         * Can be `default`, `foreground-tab`, `background-tab`, `new-window` or `other`.\n         */\n        disposition: \"default\" | \"foreground-tab\" | \"background-tab\" | \"new-window\" | \"other\";\n        /**\n         * The referrer that will be passed to the new window. May or may not result in the\n         * `Referer` header being sent, depending on the referrer policy.\n         */\n        referrer: Referrer;\n        /**\n         * The post data that will be sent to the new window, along with the appropriate\n         * headers that will be set. If no post data is to be sent, the value will be\n         * `null`. Only defined when the window is being created by a form that set\n         * `target=_blank`.\n         */\n        postBody?: PostBody;\n    }\n\n    interface HeadersReceivedResponse {\n        cancel?: boolean;\n        /**\n         * When provided, the server is assumed to have responded with these headers.\n         */\n        responseHeaders?: Record<string, string | string[]>;\n        /**\n         * Should be provided when overriding `responseHeaders` to change header status\n         * otherwise original response header's status will be used.\n         */\n        statusLine?: string;\n    }\n\n    interface HeapStatistics {\n        totalHeapSize: number;\n        totalHeapSizeExecutable: number;\n        totalPhysicalSize: number;\n        totalAvailableSize: number;\n        usedHeapSize: number;\n        heapSizeLimit: number;\n        mallocedMemory: number;\n        peakMallocedMemory: number;\n        doesZapGarbage: boolean;\n    }\n\n    interface HidDeviceAddedDetails {\n        device: HIDDevice[];\n        frame: WebFrameMain;\n    }\n\n    interface HidDeviceRemovedDetails {\n        device: HIDDevice[];\n        frame: WebFrameMain;\n    }\n\n    interface HidDeviceRevokedDetails {\n        device: HIDDevice[];\n        /**\n         * The origin that the device has been revoked from.\n         */\n        origin?: string;\n    }\n\n    interface IgnoreMouseEventsOptions {\n        /**\n         * If true, forwards mouse move messages to Chromium, enabling mouse related events\n         * such as `mouseleave`. Only used when `ignore` is true. If `ignore` is false,\n         * forwarding is always disabled regardless of this value.\n         *\n         * @platform darwin,win32\n         */\n        forward?: boolean;\n    }\n\n    interface ImportCertificateOptions {\n        /**\n         * Path for the pkcs12 file.\n         */\n        certificate: string;\n        /**\n         * Passphrase for the certificate.\n         */\n        password: string;\n    }\n\n    interface Info {\n        /**\n         * Security origin for the isolated world.\n         */\n        securityOrigin?: string;\n        /**\n         * Content Security Policy for the isolated world.\n         */\n        csp?: string;\n        /**\n         * Name for isolated world. Useful in devtools.\n         */\n        name?: string;\n    }\n\n    interface Input {\n        /**\n         * Either `keyUp` or `keyDown`.\n         */\n        type: string;\n        /**\n         * Equivalent to KeyboardEvent.key.\n         */\n        key: string;\n        /**\n         * Equivalent to KeyboardEvent.code.\n         */\n        code: string;\n        /**\n         * Equivalent to KeyboardEvent.repeat.\n         */\n        isAutoRepeat: boolean;\n        /**\n         * Equivalent to KeyboardEvent.isComposing.\n         */\n        isComposing: boolean;\n        /**\n         * Equivalent to KeyboardEvent.shiftKey.\n         */\n        shift: boolean;\n        /**\n         * Equivalent to KeyboardEvent.controlKey.\n         */\n        control: boolean;\n        /**\n         * Equivalent to KeyboardEvent.altKey.\n         */\n        alt: boolean;\n        /**\n         * Equivalent to KeyboardEvent.metaKey.\n         */\n        meta: boolean;\n        /**\n         * Equivalent to KeyboardEvent.location.\n         */\n        location: number;\n        /**\n         * See InputEvent.modifiers.\n         */\n        modifiers: string[];\n    }\n\n    interface InsertCSSOptions {\n        /**\n         * Can be either 'user' or 'author'. Sets the cascade origin of the inserted\n         * stylesheet. Default is 'author'.\n         */\n        cssOrigin?: string;\n    }\n\n    interface IpcMessageEvent extends DOMEvent {\n        /**\n         * pair of `[processId, frameId]`.\n         */\n        frameId: [number, number];\n        channel: string;\n        args: any[];\n    }\n\n    interface Item {\n        /**\n         * The path to the file being dragged.\n         */\n        file: string;\n        /**\n         * The paths to the files being dragged. (`files` will override `file` field)\n         */\n        files?: string[];\n        /**\n         * The image must be non-empty on macOS.\n         */\n        icon: NativeImage | string;\n    }\n\n    interface JumpListSettings {\n        /**\n         * The minimum number of items that will be shown in the Jump List (for a more\n         * detailed description of this value see the MSDN docs).\n         */\n        minItems: number;\n        /**\n         * Array of `JumpListItem` objects that correspond to items that the user has\n         * explicitly removed from custom categories in the Jump List. These items must not\n         * be re-added to the Jump List in the **next** call to `app.setJumpList()`,\n         * Windows will not display any custom category that contains any of the removed\n         * items.\n         */\n        removedItems: JumpListItem[];\n    }\n\n    interface LoadCommitEvent extends DOMEvent {\n        url: string;\n        isMainFrame: boolean;\n    }\n\n    interface LoadExtensionOptions {\n        /**\n         * Whether to allow the extension to read local files over `file://` protocol and\n         * inject content scripts into `file://` pages. This is required e.g. for loading\n         * devtools extensions on `file://` URLs. Defaults to false.\n         */\n        allowFileAccess: boolean;\n    }\n\n    interface LoadFileOptions {\n        /**\n         * Passed to `url.format()`.\n         */\n        query?: Record<string, string>;\n        /**\n         * Passed to `url.format()`.\n         */\n        search?: string;\n        /**\n         * Passed to `url.format()`.\n         */\n        hash?: string;\n    }\n\n    interface LoadURLOptions {\n        /**\n         * An HTTP Referrer url.\n         */\n        httpReferrer?: string | Referrer;\n        /**\n         * A user agent originating the request.\n         */\n        userAgent?: string;\n        /**\n         * Extra headers separated by \"\\n\"\n         */\n        extraHeaders?: string;\n        postData?: Array<UploadRawData | UploadFile>;\n        /**\n         * Base url (with trailing path separator) for files to be loaded by the data url.\n         * This is needed only if the specified `url` is a data url and needs to load other\n         * files.\n         */\n        baseURLForDataURL?: string;\n    }\n\n    interface LoginItemSettings {\n        /**\n         * `true` if the app is set to open at login.\n         */\n        openAtLogin: boolean;\n        /**\n         * `true` if the app is set to open as hidden at login. This setting is not\n         * available on MAS builds.\n         *\n         * @platform darwin\n         */\n        openAsHidden: boolean;\n        /**\n         * `true` if the app was opened at login automatically. This setting is not\n         * available on MAS builds.\n         *\n         * @platform darwin\n         */\n        wasOpenedAtLogin: boolean;\n        /**\n         * `true` if the app was opened as a hidden login item. This indicates that the app\n         * should not open any windows at startup. This setting is not available on MAS\n         * builds.\n         *\n         * @platform darwin\n         */\n        wasOpenedAsHidden: boolean;\n        /**\n         * `true` if the app was opened as a login item that should restore the state from\n         * the previous session. This indicates that the app should restore the windows\n         * that were open the last time the app was closed. This setting is not available\n         * on MAS builds.\n         *\n         * @platform darwin\n         */\n        restoreState: boolean;\n        /**\n         * `true` if app is set to open at login and its run key is not deactivated. This\n         * differs from `openAtLogin` as it ignores the `args` option, this property will\n         * be true if the given executable would be launched at login with **any**\n         * arguments.\n         *\n         * @platform win32\n         */\n        executableWillLaunchAtLogin: boolean;\n        launchItems: LaunchItems[];\n    }\n\n    interface LoginItemSettingsOptions {\n        /**\n         * The executable path to compare against. Defaults to `process.execPath`.\n         *\n         * @platform win32\n         */\n        path?: string;\n        /**\n         * The command-line arguments to compare against. Defaults to an empty array.\n         *\n         * @platform win32\n         */\n        args?: string[];\n    }\n\n    interface MenuItemConstructorOptions {\n        /**\n         * Will be called with `click(menuItem, browserWindow, event)` when the menu item\n         * is clicked.\n         */\n        click?: (menuItem: MenuItem, browserWindow: BrowserWindow | undefined, event: KeyboardEvent) => void;\n        /**\n         * Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`,\n         * `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`,\n         * `zoomOut`, `toggleSpellChecker`, `togglefullscreen`, `window`, `minimize`,\n         * `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`,\n         * `showSubstitutions`, `toggleSmartQuotes`, `toggleSmartDashes`,\n         * `toggleTextReplacement`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`,\n         * `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `shareMenu`, `recentDocuments`,\n         * `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`,\n         * `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu` - Define the action\n         * of the menu item, when specified the `click` property will be ignored. See\n         * roles.\n         */\n        role?:\n            | \"undo\"\n            | \"redo\"\n            | \"cut\"\n            | \"copy\"\n            | \"paste\"\n            | \"pasteAndMatchStyle\"\n            | \"delete\"\n            | \"selectAll\"\n            | \"reload\"\n            | \"forceReload\"\n            | \"toggleDevTools\"\n            | \"resetZoom\"\n            | \"zoomIn\"\n            | \"zoomOut\"\n            | \"toggleSpellChecker\"\n            | \"togglefullscreen\"\n            | \"window\"\n            | \"minimize\"\n            | \"close\"\n            | \"help\"\n            | \"about\"\n            | \"services\"\n            | \"hide\"\n            | \"hideOthers\"\n            | \"unhide\"\n            | \"quit\"\n            | \"showSubstitutions\"\n            | \"toggleSmartQuotes\"\n            | \"toggleSmartDashes\"\n            | \"toggleTextReplacement\"\n            | \"startSpeaking\"\n            | \"stopSpeaking\"\n            | \"zoom\"\n            | \"front\"\n            | \"appMenu\"\n            | \"fileMenu\"\n            | \"editMenu\"\n            | \"viewMenu\"\n            | \"shareMenu\"\n            | \"recentDocuments\"\n            | \"toggleTabBar\"\n            | \"selectNextTab\"\n            | \"selectPreviousTab\"\n            | \"mergeAllWindows\"\n            | \"clearRecentDocuments\"\n            | \"moveTabToNewWindow\"\n            | \"windowMenu\";\n        /**\n         * Can be `normal`, `separator`, `submenu`, `checkbox` or `radio`.\n         */\n        type?: \"normal\" | \"separator\" | \"submenu\" | \"checkbox\" | \"radio\";\n        label?: string;\n        sublabel?: string;\n        /**\n         * Hover text for this menu item.\n         *\n         * @platform darwin\n         */\n        toolTip?: string;\n        accelerator?: Accelerator;\n        icon?: NativeImage | string;\n        /**\n         * If false, the menu item will be greyed out and unclickable.\n         */\n        enabled?: boolean;\n        /**\n         * default is `true`, and when `false` will prevent the accelerator from triggering\n         * the item if the item is not visible.\n         *\n         * @platform darwin\n         */\n        acceleratorWorksWhenHidden?: boolean;\n        /**\n         * If false, the menu item will be entirely hidden.\n         */\n        visible?: boolean;\n        /**\n         * Should only be specified for `checkbox` or `radio` type menu items.\n         */\n        checked?: boolean;\n        /**\n         * If false, the accelerator won't be registered with the system, but it will still\n         * be displayed. Defaults to true.\n         *\n         * @platform linux,win32\n         */\n        registerAccelerator?: boolean;\n        /**\n         * The item to share when the `role` is `shareMenu`.\n         *\n         * @platform darwin\n         */\n        sharingItem?: SharingItem;\n        /**\n         * Should be specified for `submenu` type menu items. If `submenu` is specified,\n         * the `type: 'submenu'` can be omitted. If the value is not a `Menu` then it will\n         * be automatically converted to one using `Menu.buildFromTemplate`.\n         */\n        submenu?: MenuItemConstructorOptions[] | Menu;\n        /**\n         * Unique within a single menu. If defined then it can be used as a reference to\n         * this item by the position attribute.\n         */\n        id?: string;\n        /**\n         * Inserts this item before the item with the specified label. If the referenced\n         * item doesn't exist the item will be inserted at the end of  the menu. Also\n         * implies that the menu item in question should be placed in the same “group” as\n         * the item.\n         */\n        before?: string[];\n        /**\n         * Inserts this item after the item with the specified label. If the referenced\n         * item doesn't exist the item will be inserted at the end of the menu.\n         */\n        after?: string[];\n        /**\n         * Provides a means for a single context menu to declare the placement of their\n         * containing group before the containing group of the item with the specified\n         * label.\n         */\n        beforeGroupContaining?: string[];\n        /**\n         * Provides a means for a single context menu to declare the placement of their\n         * containing group after the containing group of the item with the specified\n         * label.\n         */\n        afterGroupContaining?: string[];\n    }\n\n    interface MessageBoxOptions {\n        /**\n         * Content of the message box.\n         */\n        message: string;\n        /**\n         * Can be `none`, `info`, `error`, `question` or `warning`. On Windows, `question`\n         * displays the same icon as `info`, unless you set an icon using the `icon`\n         * option. On macOS, both `warning` and `error` display the same warning icon.\n         */\n        type?: \"none\" | \"info\" | \"error\" | \"question\" | \"warning\";\n        /**\n         * Array of texts for buttons. On Windows, an empty array will result in one button\n         * labeled \"OK\".\n         */\n        buttons?: string[];\n        /**\n         * Index of the button in the buttons array which will be selected by default when\n         * the message box opens.\n         */\n        defaultId?: number;\n        /**\n         * Pass an instance of AbortSignal to optionally close the message box, the message\n         * box will behave as if it was cancelled by the user. On macOS, `signal` does not\n         * work with message boxes that do not have a parent window, since those message\n         * boxes run synchronously due to platform limitations.\n         */\n        signal?: AbortSignal;\n        /**\n         * Title of the message box, some platforms will not show it.\n         */\n        title?: string;\n        /**\n         * Extra information of the message.\n         */\n        detail?: string;\n        /**\n         * If provided, the message box will include a checkbox with the given label.\n         */\n        checkboxLabel?: string;\n        /**\n         * Initial checked state of the checkbox. `false` by default.\n         */\n        checkboxChecked?: boolean;\n        icon?: NativeImage | string;\n        /**\n         * Custom width of the text in the message box.\n         *\n         * @platform darwin\n         */\n        textWidth?: number;\n        /**\n         * The index of the button to be used to cancel the dialog, via the `Esc` key. By\n         * default this is assigned to the first button with \"cancel\" or \"no\" as the label.\n         * If no such labeled buttons exist and this option is not set, `0` will be used as\n         * the return value.\n         */\n        cancelId?: number;\n        /**\n         * On Windows Electron will try to figure out which one of the `buttons` are common\n         * buttons (like \"Cancel\" or \"Yes\"), and show the others as command links in the\n         * dialog. This can make the dialog appear in the style of modern Windows apps. If\n         * you don't like this behavior, you can set `noLink` to `true`.\n         */\n        noLink?: boolean;\n        /**\n         * Normalize the keyboard access keys across platforms. Default is `false`.\n         * Enabling this assumes `&` is used in the button labels for the placement of the\n         * keyboard shortcut access key and labels will be converted so they work correctly\n         * on each platform, `&` characters are removed on macOS, converted to `_` on\n         * Linux, and left untouched on Windows. For example, a button label of `Vie&w`\n         * will be converted to `Vie_w` on Linux and `View` on macOS and can be selected\n         * via `Alt-W` on Windows and Linux.\n         */\n        normalizeAccessKeys?: boolean;\n    }\n\n    interface MessageBoxReturnValue {\n        /**\n         * The index of the clicked button.\n         */\n        response: number;\n        /**\n         * The checked state of the checkbox if `checkboxLabel` was set. Otherwise `false`.\n         */\n        checkboxChecked: boolean;\n    }\n\n    interface MessageBoxSyncOptions {\n        /**\n         * Content of the message box.\n         */\n        message: string;\n        /**\n         * Can be `none`, `info`, `error`, `question` or `warning`. On Windows, `question`\n         * displays the same icon as `info`, unless you set an icon using the `icon`\n         * option. On macOS, both `warning` and `error` display the same warning icon.\n         */\n        type?: \"none\" | \"info\" | \"error\" | \"question\" | \"warning\";\n        /**\n         * Array of texts for buttons. On Windows, an empty array will result in one button\n         * labeled \"OK\".\n         */\n        buttons?: string[];\n        /**\n         * Index of the button in the buttons array which will be selected by default when\n         * the message box opens.\n         */\n        defaultId?: number;\n        /**\n         * Title of the message box, some platforms will not show it.\n         */\n        title?: string;\n        /**\n         * Extra information of the message.\n         */\n        detail?: string;\n        icon?: NativeImage | string;\n        /**\n         * Custom width of the text in the message box.\n         *\n         * @platform darwin\n         */\n        textWidth?: number;\n        /**\n         * The index of the button to be used to cancel the dialog, via the `Esc` key. By\n         * default this is assigned to the first button with \"cancel\" or \"no\" as the label.\n         * If no such labeled buttons exist and this option is not set, `0` will be used as\n         * the return value.\n         */\n        cancelId?: number;\n        /**\n         * On Windows Electron will try to figure out which one of the `buttons` are common\n         * buttons (like \"Cancel\" or \"Yes\"), and show the others as command links in the\n         * dialog. This can make the dialog appear in the style of modern Windows apps. If\n         * you don't like this behavior, you can set `noLink` to `true`.\n         */\n        noLink?: boolean;\n        /**\n         * Normalize the keyboard access keys across platforms. Default is `false`.\n         * Enabling this assumes `&` is used in the button labels for the placement of the\n         * keyboard shortcut access key and labels will be converted so they work correctly\n         * on each platform, `&` characters are removed on macOS, converted to `_` on\n         * Linux, and left untouched on Windows. For example, a button label of `Vie&w`\n         * will be converted to `Vie_w` on Linux and `View` on macOS and can be selected\n         * via `Alt-W` on Windows and Linux.\n         */\n        normalizeAccessKeys?: boolean;\n    }\n\n    interface MessageDetails {\n        /**\n         * The actual console message\n         */\n        message: string;\n        /**\n         * The version ID of the service worker that sent the log message\n         */\n        versionId: number;\n        /**\n         * The type of source for this message.  Can be `javascript`, `xml`, `network`,\n         * `console-api`, `storage`, `rendering`, `security`, `deprecation`, `worker`,\n         * `violation`, `intervention`, `recommendation` or `other`.\n         */\n        source: \"javascript\" | \"xml\" | \"network\" | \"console-api\" | \"storage\" | \"rendering\" | \"security\" | \"deprecation\" | \"worker\" | \"violation\" | \"intervention\" | \"recommendation\" | \"other\";\n        /**\n         * The log level, from 0 to 3. In order it matches `verbose`, `info`, `warning` and\n         * `error`.\n         */\n        level: number;\n        /**\n         * The URL the message came from\n         */\n        sourceUrl: string;\n        /**\n         * The line number of the source that triggered this console message\n         */\n        lineNumber: number;\n    }\n\n    interface MessageEvent {\n        data: any;\n        ports: MessagePortMain[];\n    }\n\n    interface MoveToApplicationsFolderOptions {\n        /**\n         * A handler for potential conflict in move failure.\n         */\n        conflictHandler?: (conflictType: \"exists\" | \"existsAndRunning\") => boolean;\n    }\n\n    interface NotificationConstructorOptions {\n        /**\n         * A title for the notification, which will be displayed at the top of the\n         * notification window when it is shown.\n         */\n        title?: string;\n        /**\n         * A subtitle for the notification, which will be displayed below the title.\n         *\n         * @platform darwin\n         */\n        subtitle?: string;\n        /**\n         * The body text of the notification, which will be displayed below the title or\n         * subtitle.\n         */\n        body?: string;\n        /**\n         * Whether or not to suppress the OS notification noise when showing the\n         * notification.\n         */\n        silent?: boolean;\n        /**\n         * An icon to use in the notification.\n         */\n        icon?: string | NativeImage;\n        /**\n         * Whether or not to add an inline reply option to the notification.\n         *\n         * @platform darwin\n         */\n        hasReply?: boolean;\n        /**\n         * The timeout duration of the notification. Can be 'default' or 'never'.\n         *\n         * @platform linux,win32\n         */\n        timeoutType?: \"default\" | \"never\";\n        /**\n         * The placeholder to write in the inline reply input field.\n         *\n         * @platform darwin\n         */\n        replyPlaceholder?: string;\n        /**\n         * The name of the sound file to play when the notification is shown.\n         *\n         * @platform darwin\n         */\n        sound?: string;\n        /**\n         * The urgency level of the notification. Can be 'normal', 'critical', or 'low'.\n         *\n         * @platform linux\n         */\n        urgency?: \"normal\" | \"critical\" | \"low\";\n        /**\n         * Actions to add to the notification. Please read the available actions and\n         * limitations in the `NotificationAction` documentation.\n         *\n         * @platform darwin\n         */\n        actions?: NotificationAction[];\n        /**\n         * A custom title for the close button of an alert. An empty string will cause the\n         * default localized text to be used.\n         *\n         * @platform darwin\n         */\n        closeButtonText?: string;\n        /**\n         * A custom description of the Notification on Windows superseding all properties\n         * above. Provides full customization of design and behavior of the notification.\n         *\n         * @platform win32\n         */\n        toastXml?: string;\n    }\n\n    interface OnBeforeRedirectListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        redirectURL: string;\n        statusCode: number;\n        statusLine: string;\n        /**\n         * The server IP address that the request was actually sent to.\n         */\n        ip?: string;\n        fromCache: boolean;\n        responseHeaders?: Record<string, string[]>;\n    }\n\n    interface OnBeforeRequestListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        uploadData: UploadData[];\n    }\n\n    interface OnBeforeSendHeadersListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        uploadData?: UploadData[];\n        requestHeaders: Record<string, string>;\n    }\n\n    interface OnCompletedListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        responseHeaders?: Record<string, string[]>;\n        fromCache: boolean;\n        statusCode: number;\n        statusLine: string;\n        error: string;\n    }\n\n    interface OnErrorOccurredListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        fromCache: boolean;\n        /**\n         * The error description.\n         */\n        error: string;\n    }\n\n    interface OnHeadersReceivedListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        statusLine: string;\n        statusCode: number;\n        responseHeaders?: Record<string, string[]>;\n    }\n\n    interface OnResponseStartedListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        responseHeaders?: Record<string, string[]>;\n        /**\n         * Indicates whether the response was fetched from disk cache.\n         */\n        fromCache: boolean;\n        statusCode: number;\n        statusLine: string;\n    }\n\n    interface OnSendHeadersListenerDetails {\n        id: number;\n        url: string;\n        method: string;\n        webContentsId?: number;\n        webContents?: WebContents;\n        frame?: WebFrameMain;\n        /**\n         * Can be `mainFrame`, `subFrame`, `stylesheet`, `script`, `image`, `font`,\n         * `object`, `xhr`, `ping`, `cspReport`, `media`, `webSocket` or `other`.\n         */\n        resourceType: \"mainFrame\" | \"subFrame\" | \"stylesheet\" | \"script\" | \"image\" | \"font\" | \"object\" | \"xhr\" | \"ping\" | \"cspReport\" | \"media\" | \"webSocket\" | \"other\";\n        referrer: string;\n        timestamp: number;\n        requestHeaders: Record<string, string>;\n    }\n\n    interface OpenDevToolsOptions {\n        /**\n         * Opens the devtools with specified dock state, can be `left`, `right`, `bottom`,\n         * `undocked`, `detach`. Defaults to last used dock state. In `undocked` mode it's\n         * possible to dock back. In `detach` mode it's not.\n         */\n        mode: \"left\" | \"right\" | \"bottom\" | \"undocked\" | \"detach\";\n        /**\n         * Whether to bring the opened devtools window to the foreground. The default is\n         * `true`.\n         */\n        activate?: boolean;\n    }\n\n    interface OpenDialogOptions {\n        title?: string;\n        defaultPath?: string;\n        /**\n         * Custom label for the confirmation button, when left empty the default label will\n         * be used.\n         */\n        buttonLabel?: string;\n        filters?: FileFilter[];\n        /**\n         * Contains which features the dialog should use. The following values are\n         * supported:\n         */\n        properties?: Array<\"openFile\" | \"openDirectory\" | \"multiSelections\" | \"showHiddenFiles\" | \"createDirectory\" | \"promptToCreate\" | \"noResolveAliases\" | \"treatPackageAsDirectory\" | \"dontAddToRecent\">;\n        /**\n         * Message to display above input boxes.\n         *\n         * @platform darwin\n         */\n        message?: string;\n        /**\n         * Create security scoped bookmarks when packaged for the Mac App Store.\n         *\n         * @platform darwin,mas\n         */\n        securityScopedBookmarks?: boolean;\n    }\n\n    interface OpenDialogReturnValue {\n        /**\n         * whether or not the dialog was canceled.\n         */\n        canceled: boolean;\n        /**\n         * An array of file paths chosen by the user. If the dialog is cancelled this will\n         * be an empty array.\n         */\n        filePaths: string[];\n        /**\n         * An array matching the `filePaths` array of base64 encoded strings which contains\n         * security scoped bookmark data. `securityScopedBookmarks` must be enabled for\n         * this to be populated. (For return values, see table here.)\n         *\n         * @platform darwin,mas\n         */\n        bookmarks?: string[];\n    }\n\n    interface OpenDialogSyncOptions {\n        title?: string;\n        defaultPath?: string;\n        /**\n         * Custom label for the confirmation button, when left empty the default label will\n         * be used.\n         */\n        buttonLabel?: string;\n        filters?: FileFilter[];\n        /**\n         * Contains which features the dialog should use. The following values are\n         * supported:\n         */\n        properties?: Array<\"openFile\" | \"openDirectory\" | \"multiSelections\" | \"showHiddenFiles\" | \"createDirectory\" | \"promptToCreate\" | \"noResolveAliases\" | \"treatPackageAsDirectory\" | \"dontAddToRecent\">;\n        /**\n         * Message to display above input boxes.\n         *\n         * @platform darwin\n         */\n        message?: string;\n        /**\n         * Create security scoped bookmarks when packaged for the Mac App Store.\n         *\n         * @platform darwin,mas\n         */\n        securityScopedBookmarks?: boolean;\n    }\n\n    interface OpenExternalOptions {\n        /**\n         * `true` to bring the opened application to the foreground. The default is `true`.\n         *\n         * @platform darwin\n         */\n        activate?: boolean;\n        /**\n         * The working directory.\n         *\n         * @platform win32\n         */\n        workingDirectory?: string;\n        /**\n         * Indicates a user initiated launch that enables tracking of frequently used\n         * programs and other behaviors. The default is `false`.\n         *\n         * @platform win32\n         */\n        logUsage?: boolean;\n    }\n\n    type Options = {};\n\n    interface Opts {\n        /**\n         *  Keep the page hidden instead of visible. Default is `false`.\n         */\n        stayHidden?: boolean;\n        /**\n         *  Keep the system awake instead of allowing it to sleep. Default is `false`.\n         */\n        stayAwake?: boolean;\n    }\n\n    interface PageFaviconUpdatedEvent extends DOMEvent {\n        /**\n         * Array of URLs.\n         */\n        favicons: string[];\n    }\n\n    interface PageTitleUpdatedEvent extends DOMEvent {\n        title: string;\n        explicitSet: boolean;\n    }\n\n    interface Parameters {\n        /**\n         * Specify the screen type to emulate (default: `desktop`):\n         */\n        screenPosition: \"desktop\" | \"mobile\";\n        /**\n         * Set the emulated screen size (screenPosition == mobile).\n         */\n        screenSize: Size;\n        /**\n         * Position the view on the screen (screenPosition == mobile) (default: `{ x: 0, y:\n         * 0 }`).\n         */\n        viewPosition: Point;\n        /**\n         * Set the device scale factor (if zero defaults to original device scale factor)\n         * (default: `0`).\n         */\n        deviceScaleFactor: number;\n        /**\n         * Set the emulated view size (empty means no override)\n         */\n        viewSize: Size;\n        /**\n         * Scale of emulated view inside available space (not in fit to view mode)\n         * (default: `1`).\n         */\n        scale: number;\n    }\n\n    interface Payment {\n        /**\n         * The identifier of the purchased product.\n         */\n        productIdentifier: string;\n        /**\n         * The quantity purchased.\n         */\n        quantity: number;\n        /**\n         * An opaque identifier for the user’s account on your system.\n         */\n        applicationUsername: string;\n        /**\n         * The details of the discount offer to apply to the payment.\n         */\n        paymentDiscount?: PaymentDiscount;\n    }\n\n    interface PermissionCheckHandlerHandlerDetails {\n        /**\n         * The origin of the frame embedding the frame that made the permission check.\n         * Only set for cross-origin sub frames making permission checks.\n         */\n        embeddingOrigin?: string;\n        /**\n         * The security origin of the `media` check.\n         */\n        securityOrigin?: string;\n        /**\n         * The type of media access being requested, can be `video`, `audio` or `unknown`\n         */\n        mediaType?: \"video\" | \"audio\" | \"unknown\";\n        /**\n         * The last URL the requesting frame loaded.  This is not provided for cross-origin\n         * sub frames making permission checks.\n         */\n        requestingUrl?: string;\n        /**\n         * Whether the frame making the request is the main frame\n         */\n        isMainFrame: boolean;\n    }\n\n    interface PermissionRequestHandlerHandlerDetails {\n        /**\n         * The url of the `openExternal` request.\n         */\n        externalURL?: string;\n        /**\n         * The security origin of the `media` request.\n         */\n        securityOrigin?: string;\n        /**\n         * The types of media access being requested, elements can be `video` or `audio`\n         */\n        mediaTypes?: Array<\"video\" | \"audio\">;\n        /**\n         * The last URL the requesting frame loaded\n         */\n        requestingUrl: string;\n        /**\n         * Whether the frame making the request is the main frame\n         */\n        isMainFrame: boolean;\n    }\n\n    interface PluginCrashedEvent extends DOMEvent {\n        name: string;\n        version: string;\n    }\n\n    interface PopupOptions {\n        /**\n         * Default is the focused window.\n         */\n        window?: BrowserWindow;\n        /**\n         * Default is the current mouse cursor position. Must be declared if `y` is\n         * declared.\n         */\n        x?: number;\n        /**\n         * Default is the current mouse cursor position. Must be declared if `x` is\n         * declared.\n         */\n        y?: number;\n        /**\n         * The index of the menu item to be positioned under the mouse cursor at the\n         * specified coordinates. Default is -1.\n         *\n         * @platform darwin\n         */\n        positioningItem?: number;\n        /**\n         * Called when menu is closed.\n         */\n        callback?: () => void;\n    }\n\n    interface PreconnectOptions {\n        /**\n         * URL for preconnect. Only the origin is relevant for opening the socket.\n         */\n        url: string;\n        /**\n         * number of sockets to preconnect. Must be between 1 and 6. Defaults to 1.\n         */\n        numSockets?: number;\n    }\n\n    interface PrintToPDFOptions {\n        /**\n         * Paper orientation.`true` for landscape, `false` for portrait. Defaults to false.\n         */\n        landscape?: boolean;\n        /**\n         * Whether to display header and footer. Defaults to false.\n         */\n        displayHeaderFooter?: boolean;\n        /**\n         * Whether to print background graphics. Defaults to false.\n         */\n        printBackground?: boolean;\n        /**\n         * Scale of the webpage rendering. Defaults to 1.\n         */\n        scale?: number;\n        /**\n         * Specify page size of the generated PDF. Can be `A0`, `A1`, `A2`, `A3`, `A4`,\n         * `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`, or an Object containing\n         * `height` and `width` in inches. Defaults to `Letter`.\n         */\n        pageSize?: string | Size;\n        margins?: Margins;\n        /**\n         * Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string,\n         * which means print all pages.\n         */\n        pageRanges?: string;\n        /**\n         * HTML template for the print header. Should be valid HTML markup with following\n         * classes used to inject printing values into them: `date` (formatted print date),\n         * `title` (document title), `url` (document location), `pageNumber` (current page\n         * number) and `totalPages` (total pages in the document). For example, `<span\n         * class=title></span>` would generate span containing the title.\n         */\n        headerTemplate?: string;\n        /**\n         * HTML template for the print footer. Should use the same format as the\n         * `headerTemplate`.\n         */\n        footerTemplate?: string;\n        /**\n         * Whether or not to prefer page size as defined by css. Defaults to false, in\n         * which case the content will be scaled to fit the paper size.\n         */\n        preferCSSPageSize?: boolean;\n    }\n\n    interface Privileges {\n        /**\n         * Default false.\n         */\n        standard?: boolean;\n        /**\n         * Default false.\n         */\n        secure?: boolean;\n        /**\n         * Default false.\n         */\n        bypassCSP?: boolean;\n        /**\n         * Default false.\n         */\n        allowServiceWorkers?: boolean;\n        /**\n         * Default false.\n         */\n        supportFetchAPI?: boolean;\n        /**\n         * Default false.\n         */\n        corsEnabled?: boolean;\n        /**\n         * Default false.\n         */\n        stream?: boolean;\n    }\n\n    interface ProgressBarOptions {\n        /**\n         * Mode for the progress bar. Can be `none`, `normal`, `indeterminate`, `error` or\n         * `paused`.\n         *\n         * @platform win32\n         */\n        mode: \"none\" | \"normal\" | \"indeterminate\" | \"error\" | \"paused\";\n    }\n\n    interface Provider {\n        spellCheck: (words: string[], callback: (misspeltWords: string[]) => void) => void;\n    }\n\n    interface PurchaseProductOpts {\n        /**\n         * The number of items the user wants to purchase.\n         */\n        quantity?: number;\n        /**\n         * The string that associates the transaction with a user account on your service\n         * (applicationUsername).\n         */\n        username?: string;\n    }\n\n    interface ReadBookmark {\n        title: string;\n        url: string;\n    }\n\n    interface RegistrationCompletedDetails {\n        /**\n         * The base URL that a service worker is registered for\n         */\n        scope: string;\n    }\n\n    interface RelaunchOptions {\n        args?: string[];\n        execPath?: string;\n    }\n\n    interface RenderProcessGoneDetails {\n        /**\n         * The reason the render process is gone.  Possible values:\n         */\n        reason: \"clean-exit\" | \"abnormal-exit\" | \"killed\" | \"crashed\" | \"oom\" | \"launch-failed\" | \"integrity-failure\";\n        /**\n         * The exit code of the process, unless `reason` is `launch-failed`, in which case\n         * `exitCode` will be a platform-specific launch failure error code.\n         */\n        exitCode: number;\n    }\n\n    interface Request {\n        hostname: string;\n        certificate: Certificate;\n        validatedCertificate: Certificate;\n        /**\n         * `true` if Chromium recognises the root CA as a standard root. If it isn't then\n         * it's probably the case that this certificate was generated by a MITM proxy whose\n         * root has been installed locally (for example, by a corporate proxy). This should\n         * not be trusted if the `verificationResult` is not `OK`.\n         */\n        isIssuedByKnownRoot: boolean;\n        /**\n         * `OK` if the certificate is trusted, otherwise an error like `CERT_REVOKED`.\n         */\n        verificationResult: string;\n        /**\n         * Error code.\n         */\n        errorCode: number;\n    }\n\n    interface ResizeOptions {\n        /**\n         * Defaults to the image's width.\n         */\n        width?: number;\n        /**\n         * Defaults to the image's height.\n         */\n        height?: number;\n        /**\n         * The desired quality of the resize image. Possible values are `good`, `better`,\n         * or `best`. The default is `best`. These values express a desired quality/speed\n         * tradeoff. They are translated into an algorithm-specific method that depends on\n         * the capabilities (CPU, GPU) of the underlying platform. It is possible for all\n         * three methods to be mapped to the same algorithm on a given platform.\n         */\n        quality?: string;\n    }\n\n    interface ResolveHostOptions {\n        /**\n         * Requested DNS query type. If unspecified, resolver will pick A or AAAA (or both)\n         * based on IPv4/IPv6 settings:\n         */\n        queryType?: \"A\" | \"AAAA\";\n        /**\n         * The source to use for resolved addresses. Default allows the resolver to pick an\n         * appropriate source. Only affects use of big external sources (e.g. calling the\n         * system for resolution or using DNS). Even if a source is specified, results can\n         * still come from cache, resolving \"localhost\" or IP literals, etc. One of the\n         * following values:\n         */\n        source?: \"any\" | \"system\" | \"dns\" | \"mdns\" | \"localOnly\";\n        /**\n         * Indicates what DNS cache entries, if any, can be used to provide a response. One\n         * of the following values:\n         */\n        cacheUsage?: \"allowed\" | \"staleAllowed\" | \"disallowed\";\n        /**\n         * Controls the resolver's Secure DNS behavior for this request. One of the\n         * following values:\n         */\n        secureDnsPolicy?: \"allow\" | \"disable\";\n    }\n\n    interface ResourceUsage {\n        images: MemoryUsageDetails;\n        scripts: MemoryUsageDetails;\n        cssStyleSheets: MemoryUsageDetails;\n        xslStyleSheets: MemoryUsageDetails;\n        fonts: MemoryUsageDetails;\n        other: MemoryUsageDetails;\n    }\n\n    interface Response {\n        /**\n         * `false` should be passed in if the dialog is canceled. If the `pairingKind` is\n         * `confirm` or `confirmPin`, this value should indicate if the pairing is\n         * confirmed.  If the `pairingKind` is `providePin` the value should be `true` when\n         * a value is provided.\n         */\n        confirmed: boolean;\n        /**\n         * When the `pairingKind` is `providePin` this value should be the required pin for\n         * the Bluetooth device.\n         */\n        pin?: string | null;\n    }\n\n    interface Result {\n        requestId: number;\n        /**\n         * Position of the active match.\n         */\n        activeMatchOrdinal: number;\n        /**\n         * Number of Matches.\n         */\n        matches: number;\n        /**\n         * Coordinates of first match region.\n         */\n        selectionArea: Rectangle;\n        finalUpdate: boolean;\n    }\n\n    interface SaveDialogOptions {\n        /**\n         * The dialog title. Cannot be displayed on some _Linux_ desktop environments.\n         */\n        title?: string;\n        /**\n         * Absolute directory path, absolute file path, or file name to use by default.\n         */\n        defaultPath?: string;\n        /**\n         * Custom label for the confirmation button, when left empty the default label will\n         * be used.\n         */\n        buttonLabel?: string;\n        filters?: FileFilter[];\n        /**\n         * Message to display above text fields.\n         *\n         * @platform darwin\n         */\n        message?: string;\n        /**\n         * Custom label for the text displayed in front of the filename text field.\n         *\n         * @platform darwin\n         */\n        nameFieldLabel?: string;\n        /**\n         * Show the tags input box, defaults to `true`.\n         *\n         * @platform darwin\n         */\n        showsTagField?: boolean;\n        properties?: Array<\"showHiddenFiles\" | \"createDirectory\" | \"treatPackageAsDirectory\" | \"showOverwriteConfirmation\" | \"dontAddToRecent\">;\n        /**\n         * Create a security scoped bookmark when packaged for the Mac App Store. If this\n         * option is enabled and the file doesn't already exist a blank file will be\n         * created at the chosen path.\n         *\n         * @platform darwin,mas\n         */\n        securityScopedBookmarks?: boolean;\n    }\n\n    interface SaveDialogReturnValue {\n        /**\n         * whether or not the dialog was canceled.\n         */\n        canceled: boolean;\n        /**\n         * If the dialog is canceled, this will be `undefined`.\n         */\n        filePath?: string;\n        /**\n         * Base64 encoded string which contains the security scoped bookmark data for the\n         * saved file. `securityScopedBookmarks` must be enabled for this to be present.\n         * (For return values, see table here.)\n         *\n         * @platform darwin,mas\n         */\n        bookmark?: string;\n    }\n\n    interface SaveDialogSyncOptions {\n        /**\n         * The dialog title. Cannot be displayed on some _Linux_ desktop environments.\n         */\n        title?: string;\n        /**\n         * Absolute directory path, absolute file path, or file name to use by default.\n         */\n        defaultPath?: string;\n        /**\n         * Custom label for the confirmation button, when left empty the default label will\n         * be used.\n         */\n        buttonLabel?: string;\n        filters?: FileFilter[];\n        /**\n         * Message to display above text fields.\n         *\n         * @platform darwin\n         */\n        message?: string;\n        /**\n         * Custom label for the text displayed in front of the filename text field.\n         *\n         * @platform darwin\n         */\n        nameFieldLabel?: string;\n        /**\n         * Show the tags input box, defaults to `true`.\n         *\n         * @platform darwin\n         */\n        showsTagField?: boolean;\n        properties?: Array<\"showHiddenFiles\" | \"createDirectory\" | \"treatPackageAsDirectory\" | \"showOverwriteConfirmation\" | \"dontAddToRecent\">;\n        /**\n         * Create a security scoped bookmark when packaged for the Mac App Store. If this\n         * option is enabled and the file doesn't already exist a blank file will be\n         * created at the chosen path.\n         *\n         * @platform darwin,mas\n         */\n        securityScopedBookmarks?: boolean;\n    }\n\n    interface SelectHidDeviceDetails {\n        deviceList: HIDDevice[];\n        frame: WebFrameMain;\n    }\n\n    interface SelectUsbDeviceDetails {\n        deviceList: USBDevice[];\n        frame: WebFrameMain;\n    }\n\n    interface SerialPortRevokedDetails {\n        port: SerialPort;\n        frame: WebFrameMain;\n        /**\n         * The origin that the device has been revoked from.\n         */\n        origin: string;\n    }\n\n    interface Settings {\n        /**\n         * `true` to open the app at login, `false` to remove the app as a login item.\n         * Defaults to `false`.\n         */\n        openAtLogin?: boolean;\n        /**\n         * `true` to open the app as hidden. Defaults to `false`. The user can edit this\n         * setting from the System Preferences so\n         * `app.getLoginItemSettings().wasOpenedAsHidden` should be checked when the app is\n         * opened to know the current value. This setting is not available on MAS builds.\n         *\n         * @platform darwin\n         */\n        openAsHidden?: boolean;\n        /**\n         * The executable to launch at login. Defaults to `process.execPath`.\n         *\n         * @platform win32\n         */\n        path?: string;\n        /**\n         * The command-line arguments to pass to the executable. Defaults to an empty\n         * array. Take care to wrap paths in quotes.\n         *\n         * @platform win32\n         */\n        args?: string[];\n        /**\n         * `true` will change the startup approved registry key and `enable / disable` the\n         * App in Task Manager and Windows Settings. Defaults to `true`.\n         *\n         * @platform win32\n         */\n        enabled?: boolean;\n        /**\n         * value name to write into registry. Defaults to the app's AppUserModelId(). Set\n         * the app's login item settings.\n         *\n         * @platform win32\n         */\n        name?: string;\n    }\n\n    interface SourcesOptions {\n        /**\n         * An array of strings that lists the types of desktop sources to be captured,\n         * available types are `screen` and `window`.\n         */\n        types: string[];\n        /**\n         * The size that the media source thumbnail should be scaled to. Default is `150` x\n         * `150`. Set width or height to 0 when you do not need the thumbnails. This will\n         * save the processing time required for capturing the content of each window and\n         * screen.\n         */\n        thumbnailSize?: Size;\n        /**\n         * Set to true to enable fetching window icons. The default value is false. When\n         * false the appIcon property of the sources return null. Same if a source has the\n         * type screen.\n         */\n        fetchWindowIcons?: boolean;\n    }\n\n    interface SSLConfigConfig {\n        /**\n         * Can be `tls1`, `tls1.1`, `tls1.2` or `tls1.3`. The minimum SSL version to allow\n         * when connecting to remote servers. Defaults to `tls1`.\n         */\n        minVersion?: string;\n        /**\n         * Can be `tls1.2` or `tls1.3`. The maximum SSL version to allow when connecting to\n         * remote servers. Defaults to `tls1.3`.\n         */\n        maxVersion?: string;\n        /**\n         * List of cipher suites which should be explicitly prevented from being used in\n         * addition to those disabled by the net built-in policy. Supported literal forms:\n         * 0xAABB, where AA is `cipher_suite[0]` and BB is `cipher_suite[1]`, as defined in\n         * RFC 2246, Section 7.4.1.2. Unrecognized but parsable cipher suites in this form\n         * will not return an error. Ex: To disable TLS_RSA_WITH_RC4_128_MD5, specify\n         * 0x0004, while to disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002. Note\n         * that TLSv1.3 ciphers cannot be disabled using this mechanism.\n         */\n        disabledCipherSuites?: number[];\n    }\n\n    interface StartLoggingOptions {\n        /**\n         * What kinds of data should be captured. By default, only metadata about requests\n         * will be captured. Setting this to `includeSensitive` will include cookies and\n         * authentication data. Setting it to `everything` will include all bytes\n         * transferred on sockets. Can be `default`, `includeSensitive` or `everything`.\n         */\n        captureMode?: \"default\" | \"includeSensitive\" | \"everything\";\n        /**\n         * When the log grows beyond this size, logging will automatically stop. Defaults\n         * to unlimited.\n         */\n        maxFileSize?: number;\n    }\n\n    interface Streams {\n        video?: Video | WebFrameMain;\n        /**\n         * If a string is specified, can be `loopback` or `loopbackWithMute`. Specifying a\n         * loopback device will capture system audio, and is currently only supported on\n         * Windows. If a WebFrameMain is specified, will capture audio from that frame.\n         */\n        audio?: (\"loopback\" | \"loopbackWithMute\") | WebFrameMain;\n        /**\n         * If `audio` is a WebFrameMain and this is set to `true`, then local playback of\n         * audio will not be muted (e.g. using `MediaRecorder` to record `WebFrameMain`\n         * with this flag set to `true` will allow audio to pass through to the speakers\n         * while recording). Default is `false`.\n         */\n        enableLocalEcho?: boolean;\n    }\n\n    interface SystemMemoryInfo {\n        /**\n         * The total amount of physical memory in Kilobytes available to the system.\n         */\n        total: number;\n        /**\n         * The total amount of memory not being used by applications or disk cache.\n         */\n        free: number;\n        /**\n         * The total amount of swap memory in Kilobytes available to the system.\n         *\n         * @platform win32,linux\n         */\n        swapTotal: number;\n        /**\n         * The free amount of swap memory in Kilobytes available to the system.\n         *\n         * @platform win32,linux\n         */\n        swapFree: number;\n    }\n\n    interface TitleBarOverlayOptions {\n        /**\n         * The CSS color of the Window Controls Overlay when enabled.\n         *\n         * @platform win32\n         */\n        color?: string;\n        /**\n         * The CSS color of the symbols on the Window Controls Overlay when enabled.\n         *\n         * @platform win32\n         */\n        symbolColor?: string;\n        /**\n         * The height of the title bar and Window Controls Overlay in pixels.\n         *\n         * @platform win32\n         */\n        height?: number;\n    }\n\n    interface TitleOptions {\n        /**\n         * The font family variant to display, can be `monospaced` or `monospacedDigit`.\n         * `monospaced` is available in macOS 10.15+ When left blank, the title uses the\n         * default system font.\n         */\n        fontType?: \"monospaced\" | \"monospacedDigit\";\n    }\n\n    interface ToBitmapOptions {\n        /**\n         * Defaults to 1.0.\n         */\n        scaleFactor?: number;\n    }\n\n    interface ToDataURLOptions {\n        /**\n         * Defaults to 1.0.\n         */\n        scaleFactor?: number;\n    }\n\n    interface ToPNGOptions {\n        /**\n         * Defaults to 1.0.\n         */\n        scaleFactor?: number;\n    }\n\n    interface TouchBarButtonConstructorOptions {\n        /**\n         * Button text.\n         */\n        label?: string;\n        /**\n         * A short description of the button for use by screenreaders like VoiceOver.\n         */\n        accessibilityLabel?: string;\n        /**\n         * Button background color in hex format, i.e `#ABCDEF`.\n         */\n        backgroundColor?: string;\n        /**\n         * Button icon.\n         */\n        icon?: NativeImage | string;\n        /**\n         * Can be `left`, `right` or `overlay`. Defaults to `overlay`.\n         */\n        iconPosition?: \"left\" | \"right\" | \"overlay\";\n        /**\n         * Function to call when the button is clicked.\n         */\n        click?: () => void;\n        /**\n         * Whether the button is in an enabled state.  Default is `true`.\n         */\n        enabled?: boolean;\n    }\n\n    interface TouchBarColorPickerConstructorOptions {\n        /**\n         * Array of hex color strings to appear as possible colors to select.\n         */\n        availableColors?: string[];\n        /**\n         * The selected hex color in the picker, i.e `#ABCDEF`.\n         */\n        selectedColor?: string;\n        /**\n         * Function to call when a color is selected.\n         */\n        change?: (color: string) => void;\n    }\n\n    interface TouchBarConstructorOptions {\n        items?: Array<TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer>;\n        escapeItem?: TouchBarButton | TouchBarColorPicker | TouchBarGroup | TouchBarLabel | TouchBarPopover | TouchBarScrubber | TouchBarSegmentedControl | TouchBarSlider | TouchBarSpacer | null;\n    }\n\n    interface TouchBarGroupConstructorOptions {\n        /**\n         * Items to display as a group.\n         */\n        items: TouchBar;\n    }\n\n    interface TouchBarLabelConstructorOptions {\n        /**\n         * Text to display.\n         */\n        label?: string;\n        /**\n         * A short description of the button for use by screenreaders like VoiceOver.\n         */\n        accessibilityLabel?: string;\n        /**\n         * Hex color of text, i.e `#ABCDEF`.\n         */\n        textColor?: string;\n    }\n\n    interface TouchBarPopoverConstructorOptions {\n        /**\n         * Popover button text.\n         */\n        label?: string;\n        /**\n         * Popover button icon.\n         */\n        icon?: NativeImage;\n        /**\n         * Items to display in the popover.\n         */\n        items: TouchBar;\n        /**\n         * `true` to display a close button on the left of the popover, `false` to not show\n         * it. Default is `true`.\n         */\n        showCloseButton?: boolean;\n    }\n\n    interface TouchBarScrubberConstructorOptions {\n        /**\n         * An array of items to place in this scrubber.\n         */\n        items: ScrubberItem[];\n        /**\n         * Called when the user taps an item that was not the last tapped item.\n         */\n        select?: (selectedIndex: number) => void;\n        /**\n         * Called when the user taps any item.\n         */\n        highlight?: (highlightedIndex: number) => void;\n        /**\n         * Selected item style. Can be `background`, `outline` or `none`. Defaults to\n         * `none`.\n         */\n        selectedStyle?: \"background\" | \"outline\" | \"none\";\n        /**\n         * Selected overlay item style. Can be `background`, `outline` or `none`. Defaults\n         * to `none`.\n         */\n        overlayStyle?: \"background\" | \"outline\" | \"none\";\n        /**\n         * Whether to show arrow buttons. Defaults to `false` and is only shown if `items`\n         * is non-empty.\n         */\n        showArrowButtons?: boolean;\n        /**\n         * Can be `fixed` or `free`. The default is `free`.\n         */\n        mode?: \"fixed\" | \"free\";\n        /**\n         * Defaults to `true`.\n         */\n        continuous?: boolean;\n    }\n\n    interface TouchBarSegmentedControlConstructorOptions {\n        /**\n         * Style of the segments:\n         */\n        segmentStyle?: \"automatic\" | \"rounded\" | \"textured-rounded\" | \"round-rect\" | \"textured-square\" | \"capsule\" | \"small-square\" | \"separated\";\n        /**\n         * The selection mode of the control:\n         */\n        mode?: \"single\" | \"multiple\" | \"buttons\";\n        /**\n         * An array of segments to place in this control.\n         */\n        segments: SegmentedControlSegment[];\n        /**\n         * The index of the currently selected segment, will update automatically with user\n         * interaction. When the mode is `multiple` it will be the last selected item.\n         */\n        selectedIndex?: number;\n        /**\n         * Called when the user selects a new segment.\n         */\n        change?: (selectedIndex: number, isSelected: boolean) => void;\n    }\n\n    interface TouchBarSliderConstructorOptions {\n        /**\n         * Label text.\n         */\n        label?: string;\n        /**\n         * Selected value.\n         */\n        value?: number;\n        /**\n         * Minimum value.\n         */\n        minValue?: number;\n        /**\n         * Maximum value.\n         */\n        maxValue?: number;\n        /**\n         * Function to call when the slider is changed.\n         */\n        change?: (newValue: number) => void;\n    }\n\n    interface TouchBarSpacerConstructorOptions {\n        /**\n         * Size of spacer, possible values are:\n         */\n        size?: \"small\" | \"large\" | \"flexible\";\n    }\n\n    interface TraceBufferUsageReturnValue {\n        value: number;\n        percentage: number;\n    }\n\n    interface UpdateTargetUrlEvent extends DOMEvent {\n        url: string;\n    }\n\n    interface UploadProgress {\n        /**\n         * Whether the request is currently active. If this is false no other properties\n         * will be set\n         */\n        active: boolean;\n        /**\n         * Whether the upload has started. If this is false both `current` and `total` will\n         * be set to 0.\n         */\n        started: boolean;\n        /**\n         * The number of bytes that have been uploaded so far\n         */\n        current: number;\n        /**\n         * The number of bytes that will be uploaded this request\n         */\n        total: number;\n    }\n\n    interface UsbDeviceRevokedDetails {\n        device: USBDevice;\n        /**\n         * The origin that the device has been revoked from.\n         */\n        origin?: string;\n    }\n\n    interface USBProtectedClassesHandlerHandlerDetails {\n        /**\n         * The current list of protected USB classes. Possible class values are:\n         */\n        protectedClasses: Array<\"audio\" | \"audio-video\" | \"hid\" | \"mass-storage\" | \"smart-card\" | \"video\" | \"wireless\">;\n    }\n\n    interface VisibleOnAllWorkspacesOptions {\n        /**\n         * Sets whether the window should be visible above fullscreen windows.\n         *\n         * @platform darwin\n         */\n        visibleOnFullScreen?: boolean;\n        /**\n         * Calling setVisibleOnAllWorkspaces will by default transform the process type\n         * between UIElementApplication and ForegroundApplication to ensure the correct\n         * behavior. However, this will hide the window and dock for a short time every\n         * time it is called. If your window is already of type UIElementApplication, you\n         * can bypass this transformation by passing true to skipTransformProcessType.\n         *\n         * @platform darwin\n         */\n        skipTransformProcessType?: boolean;\n    }\n\n    interface WebContentsAudioStateChangedEventParams {\n        /**\n         * True if one or more frames or child `webContents` are emitting audio.\n         */\n        audible: boolean;\n    }\n\n    interface WebContentsDidRedirectNavigationEventParams {\n        /**\n         * The URL the frame is navigating to.\n         */\n        url: string;\n        /**\n         * Whether the navigation happened without changing document. Examples of same\n         * document navigations are reference fragment navigations, pushState/replaceState,\n         * and same page history navigation.\n         */\n        isSameDocument: boolean;\n        /**\n         * True if the navigation is taking place in a main frame.\n         */\n        isMainFrame: boolean;\n        /**\n         * The frame to be navigated.\n         */\n        frame: WebFrameMain;\n        /**\n         * The frame which initiated the navigation, which can be a parent frame (e.g. via\n         * `window.open` with a frame's name), or null if the navigation was not initiated\n         * by a frame. This can also be null if the initiating frame was deleted before the\n         * event was emitted.\n         */\n        initiator?: WebFrameMain;\n    }\n\n    interface WebContentsDidStartNavigationEventParams {\n        /**\n         * The URL the frame is navigating to.\n         */\n        url: string;\n        /**\n         * Whether the navigation happened without changing document. Examples of same\n         * document navigations are reference fragment navigations, pushState/replaceState,\n         * and same page history navigation.\n         */\n        isSameDocument: boolean;\n        /**\n         * True if the navigation is taking place in a main frame.\n         */\n        isMainFrame: boolean;\n        /**\n         * The frame to be navigated.\n         */\n        frame: WebFrameMain;\n        /**\n         * The frame which initiated the navigation, which can be a parent frame (e.g. via\n         * `window.open` with a frame's name), or null if the navigation was not initiated\n         * by a frame. This can also be null if the initiating frame was deleted before the\n         * event was emitted.\n         */\n        initiator?: WebFrameMain;\n    }\n\n    interface WebContentsPrintOptions {\n        /**\n         * Don't ask user for print settings. Default is `false`.\n         */\n        silent?: boolean;\n        /**\n         * Prints the background color and image of the web page. Default is `false`.\n         */\n        printBackground?: boolean;\n        /**\n         * Set the printer device name to use. Must be the system-defined name and not the\n         * 'friendly' name, e.g 'Brother_QL_820NWB' and not 'Brother QL-820NWB'.\n         */\n        deviceName?: string;\n        /**\n         * Set whether the printed web page will be in color or grayscale. Default is\n         * `true`.\n         */\n        color?: boolean;\n        margins?: Margins;\n        /**\n         * Whether the web page should be printed in landscape mode. Default is `false`.\n         */\n        landscape?: boolean;\n        /**\n         * The scale factor of the web page.\n         */\n        scaleFactor?: number;\n        /**\n         * The number of pages to print per page sheet.\n         */\n        pagesPerSheet?: number;\n        /**\n         * Whether the web page should be collated.\n         */\n        collate?: boolean;\n        /**\n         * The number of copies of the web page to print.\n         */\n        copies?: number;\n        /**\n         * The page range to print. On macOS, only one range is honored.\n         */\n        pageRanges?: PageRanges[];\n        /**\n         * Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or\n         * `longEdge`.\n         */\n        duplexMode?: \"simplex\" | \"shortEdge\" | \"longEdge\";\n        dpi?: Record<string, number>;\n        /**\n         * string to be printed as page header.\n         */\n        header?: string;\n        /**\n         * string to be printed as page footer.\n         */\n        footer?: string;\n        /**\n         * Specify page size of the printed document. Can be `A0`, `A1`, `A2`, `A3`, `A4`,\n         * `A5`, `A6`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and\n         * `width`.\n         */\n        pageSize?: string | Size;\n    }\n\n    interface WebContentsWillFrameNavigateEventParams {\n        /**\n         * The URL the frame is navigating to.\n         */\n        url: string;\n        /**\n         * True if the navigation is taking place in a main frame.\n         */\n        isMainFrame: boolean;\n        /**\n         * The frame to be navigated.\n         */\n        frame: WebFrameMain;\n        /**\n         * The frame which initiated the navigation, which can be a parent frame (e.g. via\n         * `window.open` with a frame's name), or null if the navigation was not initiated\n         * by a frame. This can also be null if the initiating frame was deleted before the\n         * event was emitted.\n         */\n        initiator?: WebFrameMain;\n    }\n\n    interface WebContentsWillNavigateEventParams {\n        /**\n         * The URL the frame is navigating to.\n         */\n        url: string;\n        /**\n         * Whether the navigation happened without changing document. Examples of same\n         * document navigations are reference fragment navigations, pushState/replaceState,\n         * and same page history navigation.\n         */\n        isSameDocument: boolean;\n        /**\n         * True if the navigation is taking place in a main frame.\n         */\n        isMainFrame: boolean;\n        /**\n         * The frame to be navigated.\n         */\n        frame: WebFrameMain;\n        /**\n         * The frame which initiated the navigation, which can be a parent frame (e.g. via\n         * `window.open` with a frame's name), or null if the navigation was not initiated\n         * by a frame. This can also be null if the initiating frame was deleted before the\n         * event was emitted.\n         */\n        initiator?: WebFrameMain;\n    }\n\n    interface WebContentsWillRedirectEventParams {\n        /**\n         * The URL the frame is navigating to.\n         */\n        url: string;\n        /**\n         * Whether the navigation happened without changing document. Examples of same\n         * document navigations are reference fragment navigations, pushState/replaceState,\n         * and same page history navigation.\n         */\n        isSameDocument: boolean;\n        /**\n         * True if the navigation is taking place in a main frame.\n         */\n        isMainFrame: boolean;\n        /**\n         * The frame to be navigated.\n         */\n        frame: WebFrameMain;\n        /**\n         * The frame which initiated the navigation, which can be a parent frame (e.g. via\n         * `window.open` with a frame's name), or null if the navigation was not initiated\n         * by a frame. This can also be null if the initiating frame was deleted before the\n         * event was emitted.\n         */\n        initiator?: WebFrameMain;\n    }\n\n    interface WebviewTagPrintOptions {\n        /**\n         * Don't ask user for print settings. Default is `false`.\n         */\n        silent?: boolean;\n        /**\n         * Prints the background color and image of the web page. Default is `false`.\n         */\n        printBackground?: boolean;\n        /**\n         * Set the printer device name to use. Must be the system-defined name and not the\n         * 'friendly' name, e.g 'Brother_QL_820NWB' and not 'Brother QL-820NWB'.\n         */\n        deviceName?: string;\n        /**\n         * Set whether the printed web page will be in color or grayscale. Default is\n         * `true`.\n         */\n        color?: boolean;\n        margins?: Margins;\n        /**\n         * Whether the web page should be printed in landscape mode. Default is `false`.\n         */\n        landscape?: boolean;\n        /**\n         * The scale factor of the web page.\n         */\n        scaleFactor?: number;\n        /**\n         * The number of pages to print per page sheet.\n         */\n        pagesPerSheet?: number;\n        /**\n         * Whether the web page should be collated.\n         */\n        collate?: boolean;\n        /**\n         * The number of copies of the web page to print.\n         */\n        copies?: number;\n        /**\n         * The page range to print.\n         */\n        pageRanges?: PageRanges[];\n        /**\n         * Set the duplex mode of the printed web page. Can be `simplex`, `shortEdge`, or\n         * `longEdge`.\n         */\n        duplexMode?: \"simplex\" | \"shortEdge\" | \"longEdge\";\n        dpi?: Record<string, number>;\n        /**\n         * string to be printed as page header.\n         */\n        header?: string;\n        /**\n         * string to be printed as page footer.\n         */\n        footer?: string;\n        /**\n         * Specify page size of the printed document. Can be `A3`, `A4`, `A5`, `Legal`,\n         * `Letter`, `Tabloid` or an Object containing `height` in microns.\n         */\n        pageSize?: string | Size;\n    }\n\n    interface WillFrameNavigateEvent extends DOMEvent {\n        url: string;\n        isMainFrame: boolean;\n        frameProcessId: number;\n        frameRoutingId: number;\n    }\n\n    interface WillNavigateEvent extends DOMEvent {\n        url: string;\n    }\n\n    interface WillResizeDetails {\n        /**\n         * The edge of the window being dragged for resizing. Can be `bottom`, `left`,\n         * `right`, `top-left`, `top-right`, `bottom-left` or `bottom-right`.\n         */\n        edge: \"bottom\" | \"left\" | \"right\" | \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n    }\n\n    interface EditFlags {\n        /**\n         * Whether the renderer believes it can undo.\n         */\n        canUndo: boolean;\n        /**\n         * Whether the renderer believes it can redo.\n         */\n        canRedo: boolean;\n        /**\n         * Whether the renderer believes it can cut.\n         */\n        canCut: boolean;\n        /**\n         * Whether the renderer believes it can copy.\n         */\n        canCopy: boolean;\n        /**\n         * Whether the renderer believes it can paste.\n         */\n        canPaste: boolean;\n        /**\n         * Whether the renderer believes it can delete.\n         */\n        canDelete: boolean;\n        /**\n         * Whether the renderer believes it can select all.\n         */\n        canSelectAll: boolean;\n        /**\n         * Whether the renderer believes it can edit text richly.\n         */\n        canEditRichly: boolean;\n    }\n\n    type Env = {};\n\n    interface FoundInPageResult {\n        requestId: number;\n        /**\n         * Position of the active match.\n         */\n        activeMatchOrdinal: number;\n        /**\n         * Number of Matches.\n         */\n        matches: number;\n        /**\n         * Coordinates of first match region.\n         */\n        selectionArea: Rectangle;\n        finalUpdate: boolean;\n    }\n\n    interface LaunchItems {\n        /**\n         * name value of a registry entry.\n         *\n         * @platform win32\n         */\n        name: string;\n        /**\n         * The executable to an app that corresponds to a registry entry.\n         *\n         * @platform win32\n         */\n        path: string;\n        /**\n         * the command-line arguments to pass to the executable.\n         *\n         * @platform win32\n         */\n        args: string[];\n        /**\n         * one of `user` or `machine`. Indicates whether the registry entry is under\n         * `HKEY_CURRENT USER` or `HKEY_LOCAL_MACHINE`.\n         *\n         * @platform win32\n         */\n        scope: string;\n        /**\n         * `true` if the app registry key is startup approved and therefore shows as\n         * `enabled` in Task Manager and Windows settings.\n         *\n         * @platform win32\n         */\n        enabled: boolean;\n    }\n\n    interface Margins {\n        /**\n         * Can be `default`, `none`, `printableArea`, or `custom`. If `custom` is chosen,\n         * you will also need to specify `top`, `bottom`, `left`, and `right`.\n         */\n        marginType?: \"default\" | \"none\" | \"printableArea\" | \"custom\";\n        /**\n         * The top margin of the printed web page, in pixels.\n         */\n        top?: number;\n        /**\n         * The bottom margin of the printed web page, in pixels.\n         */\n        bottom?: number;\n        /**\n         * The left margin of the printed web page, in pixels.\n         */\n        left?: number;\n        /**\n         * The right margin of the printed web page, in pixels.\n         */\n        right?: number;\n    }\n\n    interface MediaFlags {\n        /**\n         * Whether the media element has crashed.\n         */\n        inError: boolean;\n        /**\n         * Whether the media element is paused.\n         */\n        isPaused: boolean;\n        /**\n         * Whether the media element is muted.\n         */\n        isMuted: boolean;\n        /**\n         * Whether the media element has audio.\n         */\n        hasAudio: boolean;\n        /**\n         * Whether the media element is looping.\n         */\n        isLooping: boolean;\n        /**\n         * Whether the media element's controls are visible.\n         */\n        isControlsVisible: boolean;\n        /**\n         * Whether the media element's controls are toggleable.\n         */\n        canToggleControls: boolean;\n        /**\n         * Whether the media element can be printed.\n         */\n        canPrint: boolean;\n        /**\n         * Whether or not the media element can be downloaded.\n         */\n        canSave: boolean;\n        /**\n         * Whether the media element can show picture-in-picture.\n         */\n        canShowPictureInPicture: boolean;\n        /**\n         * Whether the media element is currently showing picture-in-picture.\n         */\n        isShowingPictureInPicture: boolean;\n        /**\n         * Whether the media element can be rotated.\n         */\n        canRotate: boolean;\n        /**\n         * Whether the media element can be looped.\n         */\n        canLoop: boolean;\n    }\n\n    interface PageRanges {\n        /**\n         * Index of the first page to print (0-based).\n         */\n        from: number;\n        /**\n         * Index of the last page to print (inclusive) (0-based).\n         */\n        to: number;\n    }\n\n    interface Params {\n        /**\n         * x coordinate.\n         */\n        x: number;\n        /**\n         * y coordinate.\n         */\n        y: number;\n        /**\n         * URL of the link that encloses the node the context menu was invoked on.\n         */\n        linkURL: string;\n        /**\n         * Text associated with the link. May be an empty string if the contents of the\n         * link are an image.\n         */\n        linkText: string;\n        /**\n         * URL of the top level page that the context menu was invoked on.\n         */\n        pageURL: string;\n        /**\n         * URL of the subframe that the context menu was invoked on.\n         */\n        frameURL: string;\n        /**\n         * Source URL for the element that the context menu was invoked on. Elements with\n         * source URLs are images, audio and video.\n         */\n        srcURL: string;\n        /**\n         * Type of the node the context menu was invoked on. Can be `none`, `image`,\n         * `audio`, `video`, `canvas`, `file` or `plugin`.\n         */\n        mediaType: \"none\" | \"image\" | \"audio\" | \"video\" | \"canvas\" | \"file\" | \"plugin\";\n        /**\n         * Whether the context menu was invoked on an image which has non-empty contents.\n         */\n        hasImageContents: boolean;\n        /**\n         * Whether the context is editable.\n         */\n        isEditable: boolean;\n        /**\n         * Text of the selection that the context menu was invoked on.\n         */\n        selectionText: string;\n        /**\n         * Title text of the selection that the context menu was invoked on.\n         */\n        titleText: string;\n        /**\n         * Alt text of the selection that the context menu was invoked on.\n         */\n        altText: string;\n        /**\n         * Suggested filename to be used when saving file through 'Save Link As' option of\n         * context menu.\n         */\n        suggestedFilename: string;\n        /**\n         * Rect representing the coordinates in the document space of the selection.\n         */\n        selectionRect: Rectangle;\n        /**\n         * Start position of the selection text.\n         */\n        selectionStartOffset: number;\n        /**\n         * The referrer policy of the frame on which the menu is invoked.\n         */\n        referrerPolicy: Referrer;\n        /**\n         * The misspelled word under the cursor, if any.\n         */\n        misspelledWord: string;\n        /**\n         * An array of suggested words to show the user to replace the `misspelledWord`.\n         * Only available if there is a misspelled word and spellchecker is enabled.\n         */\n        dictionarySuggestions: string[];\n        /**\n         * The character encoding of the frame on which the menu was invoked.\n         */\n        frameCharset: string;\n        /**\n         * If the context menu was invoked on an input field, the type of that field.\n         * Possible values are `none`, `plainText`, `password`, `other`.\n         */\n        inputFieldType: string;\n        /**\n         * If the context is editable, whether or not spellchecking is enabled.\n         */\n        spellcheckEnabled: boolean;\n        /**\n         * Input source that invoked the context menu. Can be `none`, `mouse`, `keyboard`,\n         * `touch`, `touchMenu`, `longPress`, `longTap`, `touchHandle`, `stylus`,\n         * `adjustSelection`, or `adjustSelectionReset`.\n         */\n        menuSourceType: \"none\" | \"mouse\" | \"keyboard\" | \"touch\" | \"touchMenu\" | \"longPress\" | \"longTap\" | \"touchHandle\" | \"stylus\" | \"adjustSelection\" | \"adjustSelectionReset\";\n        /**\n         * The flags for the media element the context menu was invoked on.\n         */\n        mediaFlags: MediaFlags;\n        /**\n         * These flags indicate whether the renderer believes it is able to perform the\n         * corresponding action.\n         */\n        editFlags: EditFlags;\n    }\n\n    interface TitleBarOverlay {\n        /**\n         * The CSS color of the Window Controls Overlay when enabled. Default is the system\n         * color.\n         *\n         * @platform win32\n         */\n        color?: string;\n        /**\n         * The CSS color of the symbols on the Window Controls Overlay when enabled.\n         * Default is the system color.\n         *\n         * @platform win32\n         */\n        symbolColor?: string;\n        /**\n         * The height of the title bar and Window Controls Overlay in pixels. Default is\n         * system height.\n         *\n         * @platform darwin,win32\n         */\n        height?: number;\n    }\n\n    interface Video {\n        /**\n         * The id of the stream being granted. This will usually come from a\n         * DesktopCapturerSource object.\n         */\n        id: string;\n        /**\n         * The name of the stream being granted. This will usually come from a\n         * DesktopCapturerSource object.\n         */\n        name: string;\n    }\n\n    interface WebPreferences {\n        /**\n         * Whether to enable DevTools. If it is set to `false`, can not use\n         * `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`.\n         */\n        devTools?: boolean;\n        /**\n         * Whether node integration is enabled. Default is `false`.\n         */\n        nodeIntegration?: boolean;\n        /**\n         * Whether node integration is enabled in web workers. Default is `false`. More\n         * about this can be found in Multithreading.\n         */\n        nodeIntegrationInWorker?: boolean;\n        /**\n         * Experimental option for enabling Node.js support in sub-frames such as iframes\n         * and child windows. All your preloads will load for every iframe, you can use\n         * `process.isMainFrame` to determine if you are in the main frame or not.\n         */\n        nodeIntegrationInSubFrames?: boolean;\n        /**\n         * Specifies a script that will be loaded before other scripts run in the page.\n         * This script will always have access to node APIs no matter whether node\n         * integration is turned on or off. The value should be the absolute file path to\n         * the script. When node integration is turned off, the preload script can\n         * reintroduce Node global symbols back to the global scope. See example here.\n         */\n        preload?: string;\n        /**\n         * If set, this will sandbox the renderer associated with the window, making it\n         * compatible with the Chromium OS-level sandbox and disabling the Node.js engine.\n         * This is not the same as the `nodeIntegration` option and the APIs available to\n         * the preload script are more limited. Read more about the option here.\n         */\n        sandbox?: boolean;\n        /**\n         * Sets the session used by the page. Instead of passing the Session object\n         * directly, you can also choose to use the `partition` option instead, which\n         * accepts a partition string. When both `session` and `partition` are provided,\n         * `session` will be preferred. Default is the default session.\n         */\n        session?: Session;\n        /**\n         * Sets the session used by the page according to the session's partition string.\n         * If `partition` starts with `persist:`, the page will use a persistent session\n         * available to all pages in the app with the same `partition`. If there is no\n         * `persist:` prefix, the page will use an in-memory session. By assigning the same\n         * `partition`, multiple pages can share the same session. Default is the default\n         * session.\n         */\n        partition?: string;\n        /**\n         * The default zoom factor of the page, `3.0` represents `300%`. Default is `1.0`.\n         */\n        zoomFactor?: number;\n        /**\n         * Enables JavaScript support. Default is `true`.\n         */\n        javascript?: boolean;\n        /**\n         * When `false`, it will disable the same-origin policy (usually using testing\n         * websites by people), and set `allowRunningInsecureContent` to `true` if this\n         * options has not been set by user. Default is `true`.\n         */\n        webSecurity?: boolean;\n        /**\n         * Allow an https page to run JavaScript, CSS or plugins from http URLs. Default is\n         * `false`.\n         */\n        allowRunningInsecureContent?: boolean;\n        /**\n         * Enables image support. Default is `true`.\n         */\n        images?: boolean;\n        /**\n         * Specifies how to run image animations (E.g. GIFs).  Can be `animate`,\n         * `animateOnce` or `noAnimation`.  Default is `animate`.\n         */\n        imageAnimationPolicy?: \"animate\" | \"animateOnce\" | \"noAnimation\";\n        /**\n         * Make TextArea elements resizable. Default is `true`.\n         */\n        textAreasAreResizable?: boolean;\n        /**\n         * Enables WebGL support. Default is `true`.\n         */\n        webgl?: boolean;\n        /**\n         * Whether plugins should be enabled. Default is `false`.\n         */\n        plugins?: boolean;\n        /**\n         * Enables Chromium's experimental features. Default is `false`.\n         */\n        experimentalFeatures?: boolean;\n        /**\n         * Enables scroll bounce (rubber banding) effect on macOS. Default is `false`.\n         *\n         * @platform darwin\n         */\n        scrollBounce?: boolean;\n        /**\n         * A list of feature strings separated by `,`, like `CSSVariables,KeyboardEventKey`\n         * to enable. The full list of supported feature strings can be found in the\n         * RuntimeEnabledFeatures.json5 file.\n         */\n        enableBlinkFeatures?: string;\n        /**\n         * A list of feature strings separated by `,`, like `CSSVariables,KeyboardEventKey`\n         * to disable. The full list of supported feature strings can be found in the\n         * RuntimeEnabledFeatures.json5 file.\n         */\n        disableBlinkFeatures?: string;\n        /**\n         * Sets the default font for the font-family.\n         */\n        defaultFontFamily?: DefaultFontFamily;\n        /**\n         * Defaults to `16`.\n         */\n        defaultFontSize?: number;\n        /**\n         * Defaults to `13`.\n         */\n        defaultMonospaceFontSize?: number;\n        /**\n         * Defaults to `0`.\n         */\n        minimumFontSize?: number;\n        /**\n         * Defaults to `ISO-8859-1`.\n         */\n        defaultEncoding?: string;\n        /**\n         * Whether to throttle animations and timers when the page becomes background. This\n         * also affects the Page Visibility API. Defaults to `true`.\n         */\n        backgroundThrottling?: boolean;\n        /**\n         * Whether to enable offscreen rendering for the browser window. Defaults to\n         * `false`. See the offscreen rendering tutorial for more details.\n         */\n        offscreen?: boolean;\n        /**\n         * Whether to run Electron APIs and the specified `preload` script in a separate\n         * JavaScript context. Defaults to `true`. The context that the `preload` script\n         * runs in will only have access to its own dedicated `document` and `window`\n         * globals, as well as its own set of JavaScript builtins (`Array`, `Object`,\n         * `JSON`, etc.), which are all invisible to the loaded content. The Electron API\n         * will only be available in the `preload` script and not the loaded page. This\n         * option should be used when loading potentially untrusted remote content to\n         * ensure the loaded content cannot tamper with the `preload` script and any\n         * Electron APIs being used.  This option uses the same technique used by Chrome\n         * Content Scripts.  You can access this context in the dev tools by selecting the\n         * 'Electron Isolated Context' entry in the combo box at the top of the Console\n         * tab.\n         */\n        contextIsolation?: boolean;\n        /**\n         * Whether to enable the `<webview>` tag. Defaults to `false`. **Note:** The\n         * `preload` script configured for the `<webview>` will have node integration\n         * enabled when it is executed so you should ensure remote/untrusted content is not\n         * able to create a `<webview>` tag with a possibly malicious `preload` script. You\n         * can use the `will-attach-webview` event on webContents to strip away the\n         * `preload` script and to validate or alter the `<webview>`'s initial settings.\n         */\n        webviewTag?: boolean;\n        /**\n         * A list of strings that will be appended to `process.argv` in the renderer\n         * process of this app.  Useful for passing small bits of data down to renderer\n         * process preload scripts.\n         */\n        additionalArguments?: string[];\n        /**\n         * Whether to enable browser style consecutive dialog protection. Default is\n         * `false`.\n         */\n        safeDialogs?: boolean;\n        /**\n         * The message to display when consecutive dialog protection is triggered. If not\n         * defined the default message would be used, note that currently the default\n         * message is in English and not localized.\n         */\n        safeDialogsMessage?: string;\n        /**\n         * Whether to disable dialogs completely. Overrides `safeDialogs`. Default is\n         * `false`.\n         */\n        disableDialogs?: boolean;\n        /**\n         * Whether dragging and dropping a file or link onto the page causes a navigation.\n         * Default is `false`.\n         */\n        navigateOnDragDrop?: boolean;\n        /**\n         * Autoplay policy to apply to content in the window, can be\n         * `no-user-gesture-required`, `user-gesture-required`,\n         * `document-user-activation-required`. Defaults to `no-user-gesture-required`.\n         */\n        autoplayPolicy?: \"no-user-gesture-required\" | \"user-gesture-required\" | \"document-user-activation-required\";\n        /**\n         * Whether to prevent the window from resizing when entering HTML Fullscreen.\n         * Default is `false`.\n         */\n        disableHtmlFullscreenWindowResize?: boolean;\n        /**\n         * An alternative title string provided only to accessibility tools such as screen\n         * readers. This string is not directly visible to users.\n         */\n        accessibleTitle?: string;\n        /**\n         * Whether to enable the builtin spellchecker. Default is `true`.\n         */\n        spellcheck?: boolean;\n        /**\n         * Whether to enable the WebSQL api. Default is `true`.\n         */\n        enableWebSQL?: boolean;\n        /**\n         * Enforces the v8 code caching policy used by blink. Accepted values are\n         */\n        v8CacheOptions?: \"none\" | \"code\" | \"bypassHeatCheck\" | \"bypassHeatCheckAndEagerCompile\";\n        /**\n         * Whether to enable preferred size mode. The preferred size is the minimum size\n         * needed to contain the layout of the document—without requiring scrolling.\n         * Enabling this will cause the `preferred-size-changed` event to be emitted on the\n         * `WebContents` when the preferred size changes. Default is `false`.\n         */\n        enablePreferredSizeMode?: boolean;\n    }\n\n    interface DefaultFontFamily {\n        /**\n         * Defaults to `Times New Roman`.\n         */\n        standard?: string;\n        /**\n         * Defaults to `Times New Roman`.\n         */\n        serif?: string;\n        /**\n         * Defaults to `Arial`.\n         */\n        sansSerif?: string;\n        /**\n         * Defaults to `Courier New`.\n         */\n        monospace?: string;\n        /**\n         * Defaults to `Script`.\n         */\n        cursive?: string;\n        /**\n         * Defaults to `Impact`.\n         */\n        fantasy?: string;\n    }\n\n    interface RemoteMainInterface {\n        app: App;\n        autoUpdater: AutoUpdater;\n        BrowserView: typeof BrowserView;\n        BrowserWindow: typeof BrowserWindow;\n        clipboard: Clipboard;\n        contentTracing: ContentTracing;\n        crashReporter: CrashReporter;\n        desktopCapturer: DesktopCapturer;\n        dialog: Dialog;\n        globalShortcut: GlobalShortcut;\n        inAppPurchase: InAppPurchase;\n        ipcMain: IpcMain;\n        Menu: typeof Menu;\n        MenuItem: typeof MenuItem;\n        MessageChannelMain: typeof MessageChannelMain;\n        nativeImage: typeof NativeImage;\n        nativeTheme: NativeTheme;\n        net: Net;\n        netLog: NetLog;\n        Notification: typeof Notification;\n        powerMonitor: PowerMonitor;\n        powerSaveBlocker: PowerSaveBlocker;\n        protocol: Protocol;\n        pushNotifications: PushNotifications;\n        safeStorage: SafeStorage;\n        screen: Screen;\n        session: typeof Session;\n        ShareMenu: typeof ShareMenu;\n        shell: Shell;\n        systemPreferences: SystemPreferences;\n        TouchBar: typeof TouchBar;\n        Tray: typeof Tray;\n        utilityProcess: typeof UtilityProcess;\n        webContents: typeof WebContents;\n        webFrameMain: typeof WebFrameMain;\n    }\n\n    namespace Common {\n        type Event<Params extends object = {}> = Electron.Event<Params>;\n        const clipboard: Clipboard;\n        type Clipboard = Electron.Clipboard;\n        const crashReporter: CrashReporter;\n        type CrashReporter = Electron.CrashReporter;\n        const nativeImage: typeof NativeImage;\n        type NativeImage = Electron.NativeImage;\n        const shell: Shell;\n        type Shell = Electron.Shell;\n        type AboutPanelOptionsOptions = Electron.AboutPanelOptionsOptions;\n        type AddRepresentationOptions = Electron.AddRepresentationOptions;\n        type AdjustSelectionOptions = Electron.AdjustSelectionOptions;\n        type AnimationSettings = Electron.AnimationSettings;\n        type AppDetailsOptions = Electron.AppDetailsOptions;\n        type ApplicationInfoForProtocolReturnValue = Electron.ApplicationInfoForProtocolReturnValue;\n        type AuthenticationResponseDetails = Electron.AuthenticationResponseDetails;\n        type AuthInfo = Electron.AuthInfo;\n        type AutoResizeOptions = Electron.AutoResizeOptions;\n        type BeforeSendResponse = Electron.BeforeSendResponse;\n        type BitmapOptions = Electron.BitmapOptions;\n        type BlinkMemoryInfo = Electron.BlinkMemoryInfo;\n        type BluetoothPairingHandlerHandlerDetails = Electron.BluetoothPairingHandlerHandlerDetails;\n        type BrowserViewConstructorOptions = Electron.BrowserViewConstructorOptions;\n        type BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;\n        type CallbackResponse = Electron.CallbackResponse;\n        type CertificateTrustDialogOptions = Electron.CertificateTrustDialogOptions;\n        type ClearCodeCachesOptions = Electron.ClearCodeCachesOptions;\n        type ClearStorageDataOptions = Electron.ClearStorageDataOptions;\n        type ClientRequestConstructorOptions = Electron.ClientRequestConstructorOptions;\n        type CloseOpts = Electron.CloseOpts;\n        type Config = Electron.Config;\n        type ConfigureHostResolverOptions = Electron.ConfigureHostResolverOptions;\n        type ConsoleMessageEvent = Electron.ConsoleMessageEvent;\n        type ContextMenuEvent = Electron.ContextMenuEvent;\n        type ContextMenuParams = Electron.ContextMenuParams;\n        type ContinueActivityDetails = Electron.ContinueActivityDetails;\n        type CookiesGetFilter = Electron.CookiesGetFilter;\n        type CookiesSetDetails = Electron.CookiesSetDetails;\n        type CrashReporterStartOptions = Electron.CrashReporterStartOptions;\n        type CreateFromBitmapOptions = Electron.CreateFromBitmapOptions;\n        type CreateFromBufferOptions = Electron.CreateFromBufferOptions;\n        type CreateInterruptedDownloadOptions = Electron.CreateInterruptedDownloadOptions;\n        type Data = Electron.Data;\n        type Details = Electron.Details;\n        type DevicePermissionHandlerHandlerDetails = Electron.DevicePermissionHandlerHandlerDetails;\n        type DevtoolsOpenUrlEvent = Electron.DevtoolsOpenUrlEvent;\n        type DidChangeThemeColorEvent = Electron.DidChangeThemeColorEvent;\n        type DidCreateWindowDetails = Electron.DidCreateWindowDetails;\n        type DidFailLoadEvent = Electron.DidFailLoadEvent;\n        type DidFrameFinishLoadEvent = Electron.DidFrameFinishLoadEvent;\n        type DidFrameNavigateEvent = Electron.DidFrameNavigateEvent;\n        type DidNavigateEvent = Electron.DidNavigateEvent;\n        type DidNavigateInPageEvent = Electron.DidNavigateInPageEvent;\n        type DidRedirectNavigationEvent = Electron.DidRedirectNavigationEvent;\n        type DidStartNavigationEvent = Electron.DidStartNavigationEvent;\n        type DisplayBalloonOptions = Electron.DisplayBalloonOptions;\n        type DisplayMediaRequestHandlerHandlerRequest = Electron.DisplayMediaRequestHandlerHandlerRequest;\n        type EnableNetworkEmulationOptions = Electron.EnableNetworkEmulationOptions;\n        type FeedURLOptions = Electron.FeedURLOptions;\n        type FileIconOptions = Electron.FileIconOptions;\n        type FindInPageOptions = Electron.FindInPageOptions;\n        type FocusOptions = Electron.FocusOptions;\n        type ForkOptions = Electron.ForkOptions;\n        type FoundInPageEvent = Electron.FoundInPageEvent;\n        type FrameCreatedDetails = Electron.FrameCreatedDetails;\n        type FromPartitionOptions = Electron.FromPartitionOptions;\n        type FromPathOptions = Electron.FromPathOptions;\n        type HandlerDetails = Electron.HandlerDetails;\n        type HeadersReceivedResponse = Electron.HeadersReceivedResponse;\n        type HeapStatistics = Electron.HeapStatistics;\n        type HidDeviceAddedDetails = Electron.HidDeviceAddedDetails;\n        type HidDeviceRemovedDetails = Electron.HidDeviceRemovedDetails;\n        type HidDeviceRevokedDetails = Electron.HidDeviceRevokedDetails;\n        type IgnoreMouseEventsOptions = Electron.IgnoreMouseEventsOptions;\n        type ImportCertificateOptions = Electron.ImportCertificateOptions;\n        type Info = Electron.Info;\n        type Input = Electron.Input;\n        type InsertCSSOptions = Electron.InsertCSSOptions;\n        type IpcMessageEvent = Electron.IpcMessageEvent;\n        type Item = Electron.Item;\n        type JumpListSettings = Electron.JumpListSettings;\n        type LoadCommitEvent = Electron.LoadCommitEvent;\n        type LoadExtensionOptions = Electron.LoadExtensionOptions;\n        type LoadFileOptions = Electron.LoadFileOptions;\n        type LoadURLOptions = Electron.LoadURLOptions;\n        type LoginItemSettings = Electron.LoginItemSettings;\n        type LoginItemSettingsOptions = Electron.LoginItemSettingsOptions;\n        type MenuItemConstructorOptions = Electron.MenuItemConstructorOptions;\n        type MessageBoxOptions = Electron.MessageBoxOptions;\n        type MessageBoxReturnValue = Electron.MessageBoxReturnValue;\n        type MessageBoxSyncOptions = Electron.MessageBoxSyncOptions;\n        type MessageDetails = Electron.MessageDetails;\n        type MessageEvent = Electron.MessageEvent;\n        type MoveToApplicationsFolderOptions = Electron.MoveToApplicationsFolderOptions;\n        type NotificationConstructorOptions = Electron.NotificationConstructorOptions;\n        type OnBeforeRedirectListenerDetails = Electron.OnBeforeRedirectListenerDetails;\n        type OnBeforeRequestListenerDetails = Electron.OnBeforeRequestListenerDetails;\n        type OnBeforeSendHeadersListenerDetails = Electron.OnBeforeSendHeadersListenerDetails;\n        type OnCompletedListenerDetails = Electron.OnCompletedListenerDetails;\n        type OnErrorOccurredListenerDetails = Electron.OnErrorOccurredListenerDetails;\n        type OnHeadersReceivedListenerDetails = Electron.OnHeadersReceivedListenerDetails;\n        type OnResponseStartedListenerDetails = Electron.OnResponseStartedListenerDetails;\n        type OnSendHeadersListenerDetails = Electron.OnSendHeadersListenerDetails;\n        type OpenDevToolsOptions = Electron.OpenDevToolsOptions;\n        type OpenDialogOptions = Electron.OpenDialogOptions;\n        type OpenDialogReturnValue = Electron.OpenDialogReturnValue;\n        type OpenDialogSyncOptions = Electron.OpenDialogSyncOptions;\n        type OpenExternalOptions = Electron.OpenExternalOptions;\n        type Options = Electron.Options;\n        type Opts = Electron.Opts;\n        type PageFaviconUpdatedEvent = Electron.PageFaviconUpdatedEvent;\n        type PageTitleUpdatedEvent = Electron.PageTitleUpdatedEvent;\n        type Parameters = Electron.Parameters;\n        type Payment = Electron.Payment;\n        type PermissionCheckHandlerHandlerDetails = Electron.PermissionCheckHandlerHandlerDetails;\n        type PermissionRequestHandlerHandlerDetails = Electron.PermissionRequestHandlerHandlerDetails;\n        type PluginCrashedEvent = Electron.PluginCrashedEvent;\n        type PopupOptions = Electron.PopupOptions;\n        type PreconnectOptions = Electron.PreconnectOptions;\n        type PrintToPDFOptions = Electron.PrintToPDFOptions;\n        type Privileges = Electron.Privileges;\n        type ProgressBarOptions = Electron.ProgressBarOptions;\n        type Provider = Electron.Provider;\n        type PurchaseProductOpts = Electron.PurchaseProductOpts;\n        type ReadBookmark = Electron.ReadBookmark;\n        type RegistrationCompletedDetails = Electron.RegistrationCompletedDetails;\n        type RelaunchOptions = Electron.RelaunchOptions;\n        type RenderProcessGoneDetails = Electron.RenderProcessGoneDetails;\n        type Request = Electron.Request;\n        type ResizeOptions = Electron.ResizeOptions;\n        type ResolveHostOptions = Electron.ResolveHostOptions;\n        type ResourceUsage = Electron.ResourceUsage;\n        type Response = Electron.Response;\n        type Result = Electron.Result;\n        type SaveDialogOptions = Electron.SaveDialogOptions;\n        type SaveDialogReturnValue = Electron.SaveDialogReturnValue;\n        type SaveDialogSyncOptions = Electron.SaveDialogSyncOptions;\n        type SelectHidDeviceDetails = Electron.SelectHidDeviceDetails;\n        type SelectUsbDeviceDetails = Electron.SelectUsbDeviceDetails;\n        type SerialPortRevokedDetails = Electron.SerialPortRevokedDetails;\n        type Settings = Electron.Settings;\n        type SourcesOptions = Electron.SourcesOptions;\n        type SSLConfigConfig = Electron.SSLConfigConfig;\n        type StartLoggingOptions = Electron.StartLoggingOptions;\n        type Streams = Electron.Streams;\n        type SystemMemoryInfo = Electron.SystemMemoryInfo;\n        type TitleBarOverlayOptions = Electron.TitleBarOverlayOptions;\n        type TitleOptions = Electron.TitleOptions;\n        type ToBitmapOptions = Electron.ToBitmapOptions;\n        type ToDataURLOptions = Electron.ToDataURLOptions;\n        type ToPNGOptions = Electron.ToPNGOptions;\n        type TouchBarButtonConstructorOptions = Electron.TouchBarButtonConstructorOptions;\n        type TouchBarColorPickerConstructorOptions = Electron.TouchBarColorPickerConstructorOptions;\n        type TouchBarConstructorOptions = Electron.TouchBarConstructorOptions;\n        type TouchBarGroupConstructorOptions = Electron.TouchBarGroupConstructorOptions;\n        type TouchBarLabelConstructorOptions = Electron.TouchBarLabelConstructorOptions;\n        type TouchBarPopoverConstructorOptions = Electron.TouchBarPopoverConstructorOptions;\n        type TouchBarScrubberConstructorOptions = Electron.TouchBarScrubberConstructorOptions;\n        type TouchBarSegmentedControlConstructorOptions = Electron.TouchBarSegmentedControlConstructorOptions;\n        type TouchBarSliderConstructorOptions = Electron.TouchBarSliderConstructorOptions;\n        type TouchBarSpacerConstructorOptions = Electron.TouchBarSpacerConstructorOptions;\n        type TraceBufferUsageReturnValue = Electron.TraceBufferUsageReturnValue;\n        type UpdateTargetUrlEvent = Electron.UpdateTargetUrlEvent;\n        type UploadProgress = Electron.UploadProgress;\n        type UsbDeviceRevokedDetails = Electron.UsbDeviceRevokedDetails;\n        type USBProtectedClassesHandlerHandlerDetails = Electron.USBProtectedClassesHandlerHandlerDetails;\n        type VisibleOnAllWorkspacesOptions = Electron.VisibleOnAllWorkspacesOptions;\n        type WebContentsAudioStateChangedEventParams = Electron.WebContentsAudioStateChangedEventParams;\n        type WebContentsDidRedirectNavigationEventParams = Electron.WebContentsDidRedirectNavigationEventParams;\n        type WebContentsDidStartNavigationEventParams = Electron.WebContentsDidStartNavigationEventParams;\n        type WebContentsPrintOptions = Electron.WebContentsPrintOptions;\n        type WebContentsWillFrameNavigateEventParams = Electron.WebContentsWillFrameNavigateEventParams;\n        type WebContentsWillNavigateEventParams = Electron.WebContentsWillNavigateEventParams;\n        type WebContentsWillRedirectEventParams = Electron.WebContentsWillRedirectEventParams;\n        type WebviewTagPrintOptions = Electron.WebviewTagPrintOptions;\n        type WillFrameNavigateEvent = Electron.WillFrameNavigateEvent;\n        type WillNavigateEvent = Electron.WillNavigateEvent;\n        type WillResizeDetails = Electron.WillResizeDetails;\n        type EditFlags = Electron.EditFlags;\n        type Env = Electron.Env;\n        type FoundInPageResult = Electron.FoundInPageResult;\n        type LaunchItems = Electron.LaunchItems;\n        type Margins = Electron.Margins;\n        type MediaFlags = Electron.MediaFlags;\n        type PageRanges = Electron.PageRanges;\n        type Params = Electron.Params;\n        type TitleBarOverlay = Electron.TitleBarOverlay;\n        type Video = Electron.Video;\n        type WebPreferences = Electron.WebPreferences;\n        type DefaultFontFamily = Electron.DefaultFontFamily;\n        type BluetoothDevice = Electron.BluetoothDevice;\n        type Certificate = Electron.Certificate;\n        type CertificatePrincipal = Electron.CertificatePrincipal;\n        type Cookie = Electron.Cookie;\n        type CPUUsage = Electron.CPUUsage;\n        type CrashReport = Electron.CrashReport;\n        type CustomScheme = Electron.CustomScheme;\n        type DesktopCapturerSource = Electron.DesktopCapturerSource;\n        type Display = Electron.Display;\n        type Extension = Electron.Extension;\n        type ExtensionInfo = Electron.ExtensionInfo;\n        type FileFilter = Electron.FileFilter;\n        type FilePathWithHeaders = Electron.FilePathWithHeaders;\n        type GPUFeatureStatus = Electron.GPUFeatureStatus;\n        type HIDDevice = Electron.HIDDevice;\n        type InputEvent = Electron.InputEvent;\n        type IOCounters = Electron.IOCounters;\n        type IpcMainEvent = Electron.IpcMainEvent;\n        type IpcMainInvokeEvent = Electron.IpcMainInvokeEvent;\n        type IpcRendererEvent = Electron.IpcRendererEvent;\n        type JumpListCategory = Electron.JumpListCategory;\n        type JumpListItem = Electron.JumpListItem;\n        type KeyboardEvent = Electron.KeyboardEvent;\n        type KeyboardInputEvent = Electron.KeyboardInputEvent;\n        type MemoryInfo = Electron.MemoryInfo;\n        type MemoryUsageDetails = Electron.MemoryUsageDetails;\n        type MimeTypedBuffer = Electron.MimeTypedBuffer;\n        type MouseInputEvent = Electron.MouseInputEvent;\n        type MouseWheelInputEvent = Electron.MouseWheelInputEvent;\n        type NotificationAction = Electron.NotificationAction;\n        type NotificationResponse = Electron.NotificationResponse;\n        type PaymentDiscount = Electron.PaymentDiscount;\n        type Point = Electron.Point;\n        type PostBody = Electron.PostBody;\n        type PrinterInfo = Electron.PrinterInfo;\n        type ProcessMemoryInfo = Electron.ProcessMemoryInfo;\n        type ProcessMetric = Electron.ProcessMetric;\n        type Product = Electron.Product;\n        type ProductDiscount = Electron.ProductDiscount;\n        type ProductSubscriptionPeriod = Electron.ProductSubscriptionPeriod;\n        type ProtocolRequest = Electron.ProtocolRequest;\n        type ProtocolResponse = Electron.ProtocolResponse;\n        type ProtocolResponseUploadData = Electron.ProtocolResponseUploadData;\n        type Rectangle = Electron.Rectangle;\n        type Referrer = Electron.Referrer;\n        type ResolvedEndpoint = Electron.ResolvedEndpoint;\n        type ResolvedHost = Electron.ResolvedHost;\n        type ScrubberItem = Electron.ScrubberItem;\n        type SegmentedControlSegment = Electron.SegmentedControlSegment;\n        type SerialPort = Electron.SerialPort;\n        type ServiceWorkerInfo = Electron.ServiceWorkerInfo;\n        type SharedWorkerInfo = Electron.SharedWorkerInfo;\n        type SharingItem = Electron.SharingItem;\n        type ShortcutDetails = Electron.ShortcutDetails;\n        type Size = Electron.Size;\n        type Task = Electron.Task;\n        type ThumbarButton = Electron.ThumbarButton;\n        type TraceCategoriesAndOptions = Electron.TraceCategoriesAndOptions;\n        type TraceConfig = Electron.TraceConfig;\n        type Transaction = Electron.Transaction;\n        type UploadData = Electron.UploadData;\n        type UploadFile = Electron.UploadFile;\n        type UploadRawData = Electron.UploadRawData;\n        type USBDevice = Electron.USBDevice;\n        type UserDefaultTypes = Electron.UserDefaultTypes;\n        type WebRequestFilter = Electron.WebRequestFilter;\n        type WebSource = Electron.WebSource;\n    }\n\n    namespace Main {\n        type Event<Params extends object = {}> = Electron.Event<Params>;\n        const app: App;\n        type App = Electron.App;\n        const autoUpdater: AutoUpdater;\n        type AutoUpdater = Electron.AutoUpdater;\n        class BrowserView extends Electron.BrowserView {}\n        class BrowserWindow extends Electron.BrowserWindow {}\n        type ClientRequest = Electron.ClientRequest;\n        type CommandLine = Electron.CommandLine;\n        const contentTracing: ContentTracing;\n        type ContentTracing = Electron.ContentTracing;\n        type Cookies = Electron.Cookies;\n        type Debugger = Electron.Debugger;\n        const desktopCapturer: DesktopCapturer;\n        type DesktopCapturer = Electron.DesktopCapturer;\n        const dialog: Dialog;\n        type Dialog = Electron.Dialog;\n        type Dock = Electron.Dock;\n        type DownloadItem = Electron.DownloadItem;\n        const globalShortcut: GlobalShortcut;\n        type GlobalShortcut = Electron.GlobalShortcut;\n        const inAppPurchase: InAppPurchase;\n        type InAppPurchase = Electron.InAppPurchase;\n        type IncomingMessage = Electron.IncomingMessage;\n        const ipcMain: IpcMain;\n        type IpcMain = Electron.IpcMain;\n        class Menu extends Electron.Menu {}\n        class MenuItem extends Electron.MenuItem {}\n        class MessageChannelMain extends Electron.MessageChannelMain {}\n        type MessagePortMain = Electron.MessagePortMain;\n        const nativeTheme: NativeTheme;\n        type NativeTheme = Electron.NativeTheme;\n        const net: Net;\n        type Net = Electron.Net;\n        const netLog: NetLog;\n        type NetLog = Electron.NetLog;\n        class Notification extends Electron.Notification {}\n        const powerMonitor: PowerMonitor;\n        type PowerMonitor = Electron.PowerMonitor;\n        const powerSaveBlocker: PowerSaveBlocker;\n        type PowerSaveBlocker = Electron.PowerSaveBlocker;\n        const protocol: Protocol;\n        type Protocol = Electron.Protocol;\n        const pushNotifications: PushNotifications;\n        type PushNotifications = Electron.PushNotifications;\n        const safeStorage: SafeStorage;\n        type SafeStorage = Electron.SafeStorage;\n        const screen: Screen;\n        type Screen = Electron.Screen;\n        type ServiceWorkers = Electron.ServiceWorkers;\n        const session: typeof Session;\n        type Session = Electron.Session;\n        class ShareMenu extends Electron.ShareMenu {}\n        const systemPreferences: SystemPreferences;\n        type SystemPreferences = Electron.SystemPreferences;\n        class TouchBar extends Electron.TouchBar {}\n        type TouchBarButton = Electron.TouchBarButton;\n        type TouchBarColorPicker = Electron.TouchBarColorPicker;\n        type TouchBarGroup = Electron.TouchBarGroup;\n        type TouchBarLabel = Electron.TouchBarLabel;\n        type TouchBarOtherItemsProxy = Electron.TouchBarOtherItemsProxy;\n        type TouchBarPopover = Electron.TouchBarPopover;\n        type TouchBarScrubber = Electron.TouchBarScrubber;\n        type TouchBarSegmentedControl = Electron.TouchBarSegmentedControl;\n        type TouchBarSlider = Electron.TouchBarSlider;\n        type TouchBarSpacer = Electron.TouchBarSpacer;\n        class Tray extends Electron.Tray {}\n        const utilityProcess: typeof UtilityProcess;\n        type UtilityProcess = Electron.UtilityProcess;\n        const webContents: typeof WebContents;\n        type WebContents = Electron.WebContents;\n        const webFrameMain: typeof WebFrameMain;\n        type WebFrameMain = Electron.WebFrameMain;\n        type WebRequest = Electron.WebRequest;\n        type AboutPanelOptionsOptions = Electron.AboutPanelOptionsOptions;\n        type AddRepresentationOptions = Electron.AddRepresentationOptions;\n        type AdjustSelectionOptions = Electron.AdjustSelectionOptions;\n        type AnimationSettings = Electron.AnimationSettings;\n        type AppDetailsOptions = Electron.AppDetailsOptions;\n        type ApplicationInfoForProtocolReturnValue = Electron.ApplicationInfoForProtocolReturnValue;\n        type AuthenticationResponseDetails = Electron.AuthenticationResponseDetails;\n        type AuthInfo = Electron.AuthInfo;\n        type AutoResizeOptions = Electron.AutoResizeOptions;\n        type BeforeSendResponse = Electron.BeforeSendResponse;\n        type BitmapOptions = Electron.BitmapOptions;\n        type BlinkMemoryInfo = Electron.BlinkMemoryInfo;\n        type BluetoothPairingHandlerHandlerDetails = Electron.BluetoothPairingHandlerHandlerDetails;\n        type BrowserViewConstructorOptions = Electron.BrowserViewConstructorOptions;\n        type BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;\n        type CallbackResponse = Electron.CallbackResponse;\n        type CertificateTrustDialogOptions = Electron.CertificateTrustDialogOptions;\n        type ClearCodeCachesOptions = Electron.ClearCodeCachesOptions;\n        type ClearStorageDataOptions = Electron.ClearStorageDataOptions;\n        type ClientRequestConstructorOptions = Electron.ClientRequestConstructorOptions;\n        type CloseOpts = Electron.CloseOpts;\n        type Config = Electron.Config;\n        type ConfigureHostResolverOptions = Electron.ConfigureHostResolverOptions;\n        type ConsoleMessageEvent = Electron.ConsoleMessageEvent;\n        type ContextMenuEvent = Electron.ContextMenuEvent;\n        type ContextMenuParams = Electron.ContextMenuParams;\n        type ContinueActivityDetails = Electron.ContinueActivityDetails;\n        type CookiesGetFilter = Electron.CookiesGetFilter;\n        type CookiesSetDetails = Electron.CookiesSetDetails;\n        type CrashReporterStartOptions = Electron.CrashReporterStartOptions;\n        type CreateFromBitmapOptions = Electron.CreateFromBitmapOptions;\n        type CreateFromBufferOptions = Electron.CreateFromBufferOptions;\n        type CreateInterruptedDownloadOptions = Electron.CreateInterruptedDownloadOptions;\n        type Data = Electron.Data;\n        type Details = Electron.Details;\n        type DevicePermissionHandlerHandlerDetails = Electron.DevicePermissionHandlerHandlerDetails;\n        type DevtoolsOpenUrlEvent = Electron.DevtoolsOpenUrlEvent;\n        type DidChangeThemeColorEvent = Electron.DidChangeThemeColorEvent;\n        type DidCreateWindowDetails = Electron.DidCreateWindowDetails;\n        type DidFailLoadEvent = Electron.DidFailLoadEvent;\n        type DidFrameFinishLoadEvent = Electron.DidFrameFinishLoadEvent;\n        type DidFrameNavigateEvent = Electron.DidFrameNavigateEvent;\n        type DidNavigateEvent = Electron.DidNavigateEvent;\n        type DidNavigateInPageEvent = Electron.DidNavigateInPageEvent;\n        type DidRedirectNavigationEvent = Electron.DidRedirectNavigationEvent;\n        type DidStartNavigationEvent = Electron.DidStartNavigationEvent;\n        type DisplayBalloonOptions = Electron.DisplayBalloonOptions;\n        type DisplayMediaRequestHandlerHandlerRequest = Electron.DisplayMediaRequestHandlerHandlerRequest;\n        type EnableNetworkEmulationOptions = Electron.EnableNetworkEmulationOptions;\n        type FeedURLOptions = Electron.FeedURLOptions;\n        type FileIconOptions = Electron.FileIconOptions;\n        type FindInPageOptions = Electron.FindInPageOptions;\n        type FocusOptions = Electron.FocusOptions;\n        type ForkOptions = Electron.ForkOptions;\n        type FoundInPageEvent = Electron.FoundInPageEvent;\n        type FrameCreatedDetails = Electron.FrameCreatedDetails;\n        type FromPartitionOptions = Electron.FromPartitionOptions;\n        type FromPathOptions = Electron.FromPathOptions;\n        type HandlerDetails = Electron.HandlerDetails;\n        type HeadersReceivedResponse = Electron.HeadersReceivedResponse;\n        type HeapStatistics = Electron.HeapStatistics;\n        type HidDeviceAddedDetails = Electron.HidDeviceAddedDetails;\n        type HidDeviceRemovedDetails = Electron.HidDeviceRemovedDetails;\n        type HidDeviceRevokedDetails = Electron.HidDeviceRevokedDetails;\n        type IgnoreMouseEventsOptions = Electron.IgnoreMouseEventsOptions;\n        type ImportCertificateOptions = Electron.ImportCertificateOptions;\n        type Info = Electron.Info;\n        type Input = Electron.Input;\n        type InsertCSSOptions = Electron.InsertCSSOptions;\n        type IpcMessageEvent = Electron.IpcMessageEvent;\n        type Item = Electron.Item;\n        type JumpListSettings = Electron.JumpListSettings;\n        type LoadCommitEvent = Electron.LoadCommitEvent;\n        type LoadExtensionOptions = Electron.LoadExtensionOptions;\n        type LoadFileOptions = Electron.LoadFileOptions;\n        type LoadURLOptions = Electron.LoadURLOptions;\n        type LoginItemSettings = Electron.LoginItemSettings;\n        type LoginItemSettingsOptions = Electron.LoginItemSettingsOptions;\n        type MenuItemConstructorOptions = Electron.MenuItemConstructorOptions;\n        type MessageBoxOptions = Electron.MessageBoxOptions;\n        type MessageBoxReturnValue = Electron.MessageBoxReturnValue;\n        type MessageBoxSyncOptions = Electron.MessageBoxSyncOptions;\n        type MessageDetails = Electron.MessageDetails;\n        type MessageEvent = Electron.MessageEvent;\n        type MoveToApplicationsFolderOptions = Electron.MoveToApplicationsFolderOptions;\n        type NotificationConstructorOptions = Electron.NotificationConstructorOptions;\n        type OnBeforeRedirectListenerDetails = Electron.OnBeforeRedirectListenerDetails;\n        type OnBeforeRequestListenerDetails = Electron.OnBeforeRequestListenerDetails;\n        type OnBeforeSendHeadersListenerDetails = Electron.OnBeforeSendHeadersListenerDetails;\n        type OnCompletedListenerDetails = Electron.OnCompletedListenerDetails;\n        type OnErrorOccurredListenerDetails = Electron.OnErrorOccurredListenerDetails;\n        type OnHeadersReceivedListenerDetails = Electron.OnHeadersReceivedListenerDetails;\n        type OnResponseStartedListenerDetails = Electron.OnResponseStartedListenerDetails;\n        type OnSendHeadersListenerDetails = Electron.OnSendHeadersListenerDetails;\n        type OpenDevToolsOptions = Electron.OpenDevToolsOptions;\n        type OpenDialogOptions = Electron.OpenDialogOptions;\n        type OpenDialogReturnValue = Electron.OpenDialogReturnValue;\n        type OpenDialogSyncOptions = Electron.OpenDialogSyncOptions;\n        type OpenExternalOptions = Electron.OpenExternalOptions;\n        type Options = Electron.Options;\n        type Opts = Electron.Opts;\n        type PageFaviconUpdatedEvent = Electron.PageFaviconUpdatedEvent;\n        type PageTitleUpdatedEvent = Electron.PageTitleUpdatedEvent;\n        type Parameters = Electron.Parameters;\n        type Payment = Electron.Payment;\n        type PermissionCheckHandlerHandlerDetails = Electron.PermissionCheckHandlerHandlerDetails;\n        type PermissionRequestHandlerHandlerDetails = Electron.PermissionRequestHandlerHandlerDetails;\n        type PluginCrashedEvent = Electron.PluginCrashedEvent;\n        type PopupOptions = Electron.PopupOptions;\n        type PreconnectOptions = Electron.PreconnectOptions;\n        type PrintToPDFOptions = Electron.PrintToPDFOptions;\n        type Privileges = Electron.Privileges;\n        type ProgressBarOptions = Electron.ProgressBarOptions;\n        type Provider = Electron.Provider;\n        type PurchaseProductOpts = Electron.PurchaseProductOpts;\n        type ReadBookmark = Electron.ReadBookmark;\n        type RegistrationCompletedDetails = Electron.RegistrationCompletedDetails;\n        type RelaunchOptions = Electron.RelaunchOptions;\n        type RenderProcessGoneDetails = Electron.RenderProcessGoneDetails;\n        type Request = Electron.Request;\n        type ResizeOptions = Electron.ResizeOptions;\n        type ResolveHostOptions = Electron.ResolveHostOptions;\n        type ResourceUsage = Electron.ResourceUsage;\n        type Response = Electron.Response;\n        type Result = Electron.Result;\n        type SaveDialogOptions = Electron.SaveDialogOptions;\n        type SaveDialogReturnValue = Electron.SaveDialogReturnValue;\n        type SaveDialogSyncOptions = Electron.SaveDialogSyncOptions;\n        type SelectHidDeviceDetails = Electron.SelectHidDeviceDetails;\n        type SelectUsbDeviceDetails = Electron.SelectUsbDeviceDetails;\n        type SerialPortRevokedDetails = Electron.SerialPortRevokedDetails;\n        type Settings = Electron.Settings;\n        type SourcesOptions = Electron.SourcesOptions;\n        type SSLConfigConfig = Electron.SSLConfigConfig;\n        type StartLoggingOptions = Electron.StartLoggingOptions;\n        type Streams = Electron.Streams;\n        type SystemMemoryInfo = Electron.SystemMemoryInfo;\n        type TitleBarOverlayOptions = Electron.TitleBarOverlayOptions;\n        type TitleOptions = Electron.TitleOptions;\n        type ToBitmapOptions = Electron.ToBitmapOptions;\n        type ToDataURLOptions = Electron.ToDataURLOptions;\n        type ToPNGOptions = Electron.ToPNGOptions;\n        type TouchBarButtonConstructorOptions = Electron.TouchBarButtonConstructorOptions;\n        type TouchBarColorPickerConstructorOptions = Electron.TouchBarColorPickerConstructorOptions;\n        type TouchBarConstructorOptions = Electron.TouchBarConstructorOptions;\n        type TouchBarGroupConstructorOptions = Electron.TouchBarGroupConstructorOptions;\n        type TouchBarLabelConstructorOptions = Electron.TouchBarLabelConstructorOptions;\n        type TouchBarPopoverConstructorOptions = Electron.TouchBarPopoverConstructorOptions;\n        type TouchBarScrubberConstructorOptions = Electron.TouchBarScrubberConstructorOptions;\n        type TouchBarSegmentedControlConstructorOptions = Electron.TouchBarSegmentedControlConstructorOptions;\n        type TouchBarSliderConstructorOptions = Electron.TouchBarSliderConstructorOptions;\n        type TouchBarSpacerConstructorOptions = Electron.TouchBarSpacerConstructorOptions;\n        type TraceBufferUsageReturnValue = Electron.TraceBufferUsageReturnValue;\n        type UpdateTargetUrlEvent = Electron.UpdateTargetUrlEvent;\n        type UploadProgress = Electron.UploadProgress;\n        type UsbDeviceRevokedDetails = Electron.UsbDeviceRevokedDetails;\n        type USBProtectedClassesHandlerHandlerDetails = Electron.USBProtectedClassesHandlerHandlerDetails;\n        type VisibleOnAllWorkspacesOptions = Electron.VisibleOnAllWorkspacesOptions;\n        type WebContentsAudioStateChangedEventParams = Electron.WebContentsAudioStateChangedEventParams;\n        type WebContentsDidRedirectNavigationEventParams = Electron.WebContentsDidRedirectNavigationEventParams;\n        type WebContentsDidStartNavigationEventParams = Electron.WebContentsDidStartNavigationEventParams;\n        type WebContentsPrintOptions = Electron.WebContentsPrintOptions;\n        type WebContentsWillFrameNavigateEventParams = Electron.WebContentsWillFrameNavigateEventParams;\n        type WebContentsWillNavigateEventParams = Electron.WebContentsWillNavigateEventParams;\n        type WebContentsWillRedirectEventParams = Electron.WebContentsWillRedirectEventParams;\n        type WebviewTagPrintOptions = Electron.WebviewTagPrintOptions;\n        type WillFrameNavigateEvent = Electron.WillFrameNavigateEvent;\n        type WillNavigateEvent = Electron.WillNavigateEvent;\n        type WillResizeDetails = Electron.WillResizeDetails;\n        type EditFlags = Electron.EditFlags;\n        type Env = Electron.Env;\n        type FoundInPageResult = Electron.FoundInPageResult;\n        type LaunchItems = Electron.LaunchItems;\n        type Margins = Electron.Margins;\n        type MediaFlags = Electron.MediaFlags;\n        type PageRanges = Electron.PageRanges;\n        type Params = Electron.Params;\n        type TitleBarOverlay = Electron.TitleBarOverlay;\n        type Video = Electron.Video;\n        type WebPreferences = Electron.WebPreferences;\n        type DefaultFontFamily = Electron.DefaultFontFamily;\n        type BluetoothDevice = Electron.BluetoothDevice;\n        type Certificate = Electron.Certificate;\n        type CertificatePrincipal = Electron.CertificatePrincipal;\n        type Cookie = Electron.Cookie;\n        type CPUUsage = Electron.CPUUsage;\n        type CrashReport = Electron.CrashReport;\n        type CustomScheme = Electron.CustomScheme;\n        type DesktopCapturerSource = Electron.DesktopCapturerSource;\n        type Display = Electron.Display;\n        type Extension = Electron.Extension;\n        type ExtensionInfo = Electron.ExtensionInfo;\n        type FileFilter = Electron.FileFilter;\n        type FilePathWithHeaders = Electron.FilePathWithHeaders;\n        type GPUFeatureStatus = Electron.GPUFeatureStatus;\n        type HIDDevice = Electron.HIDDevice;\n        type InputEvent = Electron.InputEvent;\n        type IOCounters = Electron.IOCounters;\n        type IpcMainEvent = Electron.IpcMainEvent;\n        type IpcMainInvokeEvent = Electron.IpcMainInvokeEvent;\n        type IpcRendererEvent = Electron.IpcRendererEvent;\n        type JumpListCategory = Electron.JumpListCategory;\n        type JumpListItem = Electron.JumpListItem;\n        type KeyboardEvent = Electron.KeyboardEvent;\n        type KeyboardInputEvent = Electron.KeyboardInputEvent;\n        type MemoryInfo = Electron.MemoryInfo;\n        type MemoryUsageDetails = Electron.MemoryUsageDetails;\n        type MimeTypedBuffer = Electron.MimeTypedBuffer;\n        type MouseInputEvent = Electron.MouseInputEvent;\n        type MouseWheelInputEvent = Electron.MouseWheelInputEvent;\n        type NotificationAction = Electron.NotificationAction;\n        type NotificationResponse = Electron.NotificationResponse;\n        type PaymentDiscount = Electron.PaymentDiscount;\n        type Point = Electron.Point;\n        type PostBody = Electron.PostBody;\n        type PrinterInfo = Electron.PrinterInfo;\n        type ProcessMemoryInfo = Electron.ProcessMemoryInfo;\n        type ProcessMetric = Electron.ProcessMetric;\n        type Product = Electron.Product;\n        type ProductDiscount = Electron.ProductDiscount;\n        type ProductSubscriptionPeriod = Electron.ProductSubscriptionPeriod;\n        type ProtocolRequest = Electron.ProtocolRequest;\n        type ProtocolResponse = Electron.ProtocolResponse;\n        type ProtocolResponseUploadData = Electron.ProtocolResponseUploadData;\n        type Rectangle = Electron.Rectangle;\n        type Referrer = Electron.Referrer;\n        type ResolvedEndpoint = Electron.ResolvedEndpoint;\n        type ResolvedHost = Electron.ResolvedHost;\n        type ScrubberItem = Electron.ScrubberItem;\n        type SegmentedControlSegment = Electron.SegmentedControlSegment;\n        type SerialPort = Electron.SerialPort;\n        type ServiceWorkerInfo = Electron.ServiceWorkerInfo;\n        type SharedWorkerInfo = Electron.SharedWorkerInfo;\n        type SharingItem = Electron.SharingItem;\n        type ShortcutDetails = Electron.ShortcutDetails;\n        type Size = Electron.Size;\n        type Task = Electron.Task;\n        type ThumbarButton = Electron.ThumbarButton;\n        type TraceCategoriesAndOptions = Electron.TraceCategoriesAndOptions;\n        type TraceConfig = Electron.TraceConfig;\n        type Transaction = Electron.Transaction;\n        type UploadData = Electron.UploadData;\n        type UploadFile = Electron.UploadFile;\n        type UploadRawData = Electron.UploadRawData;\n        type USBDevice = Electron.USBDevice;\n        type UserDefaultTypes = Electron.UserDefaultTypes;\n        type WebRequestFilter = Electron.WebRequestFilter;\n        type WebSource = Electron.WebSource;\n    }\n\n    namespace Renderer {\n        type Event<Params extends object = {}> = Electron.Event<Params>;\n        const contextBridge: ContextBridge;\n        type ContextBridge = Electron.ContextBridge;\n        const ipcRenderer: IpcRenderer;\n        type IpcRenderer = Electron.IpcRenderer;\n        const webFrame: WebFrame;\n        type WebFrame = Electron.WebFrame;\n        type WebviewTag = Electron.WebviewTag;\n        type AboutPanelOptionsOptions = Electron.AboutPanelOptionsOptions;\n        type AddRepresentationOptions = Electron.AddRepresentationOptions;\n        type AdjustSelectionOptions = Electron.AdjustSelectionOptions;\n        type AnimationSettings = Electron.AnimationSettings;\n        type AppDetailsOptions = Electron.AppDetailsOptions;\n        type ApplicationInfoForProtocolReturnValue = Electron.ApplicationInfoForProtocolReturnValue;\n        type AuthenticationResponseDetails = Electron.AuthenticationResponseDetails;\n        type AuthInfo = Electron.AuthInfo;\n        type AutoResizeOptions = Electron.AutoResizeOptions;\n        type BeforeSendResponse = Electron.BeforeSendResponse;\n        type BitmapOptions = Electron.BitmapOptions;\n        type BlinkMemoryInfo = Electron.BlinkMemoryInfo;\n        type BluetoothPairingHandlerHandlerDetails = Electron.BluetoothPairingHandlerHandlerDetails;\n        type BrowserViewConstructorOptions = Electron.BrowserViewConstructorOptions;\n        type BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;\n        type CallbackResponse = Electron.CallbackResponse;\n        type CertificateTrustDialogOptions = Electron.CertificateTrustDialogOptions;\n        type ClearCodeCachesOptions = Electron.ClearCodeCachesOptions;\n        type ClearStorageDataOptions = Electron.ClearStorageDataOptions;\n        type ClientRequestConstructorOptions = Electron.ClientRequestConstructorOptions;\n        type CloseOpts = Electron.CloseOpts;\n        type Config = Electron.Config;\n        type ConfigureHostResolverOptions = Electron.ConfigureHostResolverOptions;\n        type ConsoleMessageEvent = Electron.ConsoleMessageEvent;\n        type ContextMenuEvent = Electron.ContextMenuEvent;\n        type ContextMenuParams = Electron.ContextMenuParams;\n        type ContinueActivityDetails = Electron.ContinueActivityDetails;\n        type CookiesGetFilter = Electron.CookiesGetFilter;\n        type CookiesSetDetails = Electron.CookiesSetDetails;\n        type CrashReporterStartOptions = Electron.CrashReporterStartOptions;\n        type CreateFromBitmapOptions = Electron.CreateFromBitmapOptions;\n        type CreateFromBufferOptions = Electron.CreateFromBufferOptions;\n        type CreateInterruptedDownloadOptions = Electron.CreateInterruptedDownloadOptions;\n        type Data = Electron.Data;\n        type Details = Electron.Details;\n        type DevicePermissionHandlerHandlerDetails = Electron.DevicePermissionHandlerHandlerDetails;\n        type DevtoolsOpenUrlEvent = Electron.DevtoolsOpenUrlEvent;\n        type DidChangeThemeColorEvent = Electron.DidChangeThemeColorEvent;\n        type DidCreateWindowDetails = Electron.DidCreateWindowDetails;\n        type DidFailLoadEvent = Electron.DidFailLoadEvent;\n        type DidFrameFinishLoadEvent = Electron.DidFrameFinishLoadEvent;\n        type DidFrameNavigateEvent = Electron.DidFrameNavigateEvent;\n        type DidNavigateEvent = Electron.DidNavigateEvent;\n        type DidNavigateInPageEvent = Electron.DidNavigateInPageEvent;\n        type DidRedirectNavigationEvent = Electron.DidRedirectNavigationEvent;\n        type DidStartNavigationEvent = Electron.DidStartNavigationEvent;\n        type DisplayBalloonOptions = Electron.DisplayBalloonOptions;\n        type DisplayMediaRequestHandlerHandlerRequest = Electron.DisplayMediaRequestHandlerHandlerRequest;\n        type EnableNetworkEmulationOptions = Electron.EnableNetworkEmulationOptions;\n        type FeedURLOptions = Electron.FeedURLOptions;\n        type FileIconOptions = Electron.FileIconOptions;\n        type FindInPageOptions = Electron.FindInPageOptions;\n        type FocusOptions = Electron.FocusOptions;\n        type ForkOptions = Electron.ForkOptions;\n        type FoundInPageEvent = Electron.FoundInPageEvent;\n        type FrameCreatedDetails = Electron.FrameCreatedDetails;\n        type FromPartitionOptions = Electron.FromPartitionOptions;\n        type FromPathOptions = Electron.FromPathOptions;\n        type HandlerDetails = Electron.HandlerDetails;\n        type HeadersReceivedResponse = Electron.HeadersReceivedResponse;\n        type HeapStatistics = Electron.HeapStatistics;\n        type HidDeviceAddedDetails = Electron.HidDeviceAddedDetails;\n        type HidDeviceRemovedDetails = Electron.HidDeviceRemovedDetails;\n        type HidDeviceRevokedDetails = Electron.HidDeviceRevokedDetails;\n        type IgnoreMouseEventsOptions = Electron.IgnoreMouseEventsOptions;\n        type ImportCertificateOptions = Electron.ImportCertificateOptions;\n        type Info = Electron.Info;\n        type Input = Electron.Input;\n        type InsertCSSOptions = Electron.InsertCSSOptions;\n        type IpcMessageEvent = Electron.IpcMessageEvent;\n        type Item = Electron.Item;\n        type JumpListSettings = Electron.JumpListSettings;\n        type LoadCommitEvent = Electron.LoadCommitEvent;\n        type LoadExtensionOptions = Electron.LoadExtensionOptions;\n        type LoadFileOptions = Electron.LoadFileOptions;\n        type LoadURLOptions = Electron.LoadURLOptions;\n        type LoginItemSettings = Electron.LoginItemSettings;\n        type LoginItemSettingsOptions = Electron.LoginItemSettingsOptions;\n        type MenuItemConstructorOptions = Electron.MenuItemConstructorOptions;\n        type MessageBoxOptions = Electron.MessageBoxOptions;\n        type MessageBoxReturnValue = Electron.MessageBoxReturnValue;\n        type MessageBoxSyncOptions = Electron.MessageBoxSyncOptions;\n        type MessageDetails = Electron.MessageDetails;\n        type MessageEvent = Electron.MessageEvent;\n        type MoveToApplicationsFolderOptions = Electron.MoveToApplicationsFolderOptions;\n        type NotificationConstructorOptions = Electron.NotificationConstructorOptions;\n        type OnBeforeRedirectListenerDetails = Electron.OnBeforeRedirectListenerDetails;\n        type OnBeforeRequestListenerDetails = Electron.OnBeforeRequestListenerDetails;\n        type OnBeforeSendHeadersListenerDetails = Electron.OnBeforeSendHeadersListenerDetails;\n        type OnCompletedListenerDetails = Electron.OnCompletedListenerDetails;\n        type OnErrorOccurredListenerDetails = Electron.OnErrorOccurredListenerDetails;\n        type OnHeadersReceivedListenerDetails = Electron.OnHeadersReceivedListenerDetails;\n        type OnResponseStartedListenerDetails = Electron.OnResponseStartedListenerDetails;\n        type OnSendHeadersListenerDetails = Electron.OnSendHeadersListenerDetails;\n        type OpenDevToolsOptions = Electron.OpenDevToolsOptions;\n        type OpenDialogOptions = Electron.OpenDialogOptions;\n        type OpenDialogReturnValue = Electron.OpenDialogReturnValue;\n        type OpenDialogSyncOptions = Electron.OpenDialogSyncOptions;\n        type OpenExternalOptions = Electron.OpenExternalOptions;\n        type Options = Electron.Options;\n        type Opts = Electron.Opts;\n        type PageFaviconUpdatedEvent = Electron.PageFaviconUpdatedEvent;\n        type PageTitleUpdatedEvent = Electron.PageTitleUpdatedEvent;\n        type Parameters = Electron.Parameters;\n        type Payment = Electron.Payment;\n        type PermissionCheckHandlerHandlerDetails = Electron.PermissionCheckHandlerHandlerDetails;\n        type PermissionRequestHandlerHandlerDetails = Electron.PermissionRequestHandlerHandlerDetails;\n        type PluginCrashedEvent = Electron.PluginCrashedEvent;\n        type PopupOptions = Electron.PopupOptions;\n        type PreconnectOptions = Electron.PreconnectOptions;\n        type PrintToPDFOptions = Electron.PrintToPDFOptions;\n        type Privileges = Electron.Privileges;\n        type ProgressBarOptions = Electron.ProgressBarOptions;\n        type Provider = Electron.Provider;\n        type PurchaseProductOpts = Electron.PurchaseProductOpts;\n        type ReadBookmark = Electron.ReadBookmark;\n        type RegistrationCompletedDetails = Electron.RegistrationCompletedDetails;\n        type RelaunchOptions = Electron.RelaunchOptions;\n        type RenderProcessGoneDetails = Electron.RenderProcessGoneDetails;\n        type Request = Electron.Request;\n        type ResizeOptions = Electron.ResizeOptions;\n        type ResolveHostOptions = Electron.ResolveHostOptions;\n        type ResourceUsage = Electron.ResourceUsage;\n        type Response = Electron.Response;\n        type Result = Electron.Result;\n        type SaveDialogOptions = Electron.SaveDialogOptions;\n        type SaveDialogReturnValue = Electron.SaveDialogReturnValue;\n        type SaveDialogSyncOptions = Electron.SaveDialogSyncOptions;\n        type SelectHidDeviceDetails = Electron.SelectHidDeviceDetails;\n        type SelectUsbDeviceDetails = Electron.SelectUsbDeviceDetails;\n        type SerialPortRevokedDetails = Electron.SerialPortRevokedDetails;\n        type Settings = Electron.Settings;\n        type SourcesOptions = Electron.SourcesOptions;\n        type SSLConfigConfig = Electron.SSLConfigConfig;\n        type StartLoggingOptions = Electron.StartLoggingOptions;\n        type Streams = Electron.Streams;\n        type SystemMemoryInfo = Electron.SystemMemoryInfo;\n        type TitleBarOverlayOptions = Electron.TitleBarOverlayOptions;\n        type TitleOptions = Electron.TitleOptions;\n        type ToBitmapOptions = Electron.ToBitmapOptions;\n        type ToDataURLOptions = Electron.ToDataURLOptions;\n        type ToPNGOptions = Electron.ToPNGOptions;\n        type TouchBarButtonConstructorOptions = Electron.TouchBarButtonConstructorOptions;\n        type TouchBarColorPickerConstructorOptions = Electron.TouchBarColorPickerConstructorOptions;\n        type TouchBarConstructorOptions = Electron.TouchBarConstructorOptions;\n        type TouchBarGroupConstructorOptions = Electron.TouchBarGroupConstructorOptions;\n        type TouchBarLabelConstructorOptions = Electron.TouchBarLabelConstructorOptions;\n        type TouchBarPopoverConstructorOptions = Electron.TouchBarPopoverConstructorOptions;\n        type TouchBarScrubberConstructorOptions = Electron.TouchBarScrubberConstructorOptions;\n        type TouchBarSegmentedControlConstructorOptions = Electron.TouchBarSegmentedControlConstructorOptions;\n        type TouchBarSliderConstructorOptions = Electron.TouchBarSliderConstructorOptions;\n        type TouchBarSpacerConstructorOptions = Electron.TouchBarSpacerConstructorOptions;\n        type TraceBufferUsageReturnValue = Electron.TraceBufferUsageReturnValue;\n        type UpdateTargetUrlEvent = Electron.UpdateTargetUrlEvent;\n        type UploadProgress = Electron.UploadProgress;\n        type UsbDeviceRevokedDetails = Electron.UsbDeviceRevokedDetails;\n        type USBProtectedClassesHandlerHandlerDetails = Electron.USBProtectedClassesHandlerHandlerDetails;\n        type VisibleOnAllWorkspacesOptions = Electron.VisibleOnAllWorkspacesOptions;\n        type WebContentsAudioStateChangedEventParams = Electron.WebContentsAudioStateChangedEventParams;\n        type WebContentsDidRedirectNavigationEventParams = Electron.WebContentsDidRedirectNavigationEventParams;\n        type WebContentsDidStartNavigationEventParams = Electron.WebContentsDidStartNavigationEventParams;\n        type WebContentsPrintOptions = Electron.WebContentsPrintOptions;\n        type WebContentsWillFrameNavigateEventParams = Electron.WebContentsWillFrameNavigateEventParams;\n        type WebContentsWillNavigateEventParams = Electron.WebContentsWillNavigateEventParams;\n        type WebContentsWillRedirectEventParams = Electron.WebContentsWillRedirectEventParams;\n        type WebviewTagPrintOptions = Electron.WebviewTagPrintOptions;\n        type WillFrameNavigateEvent = Electron.WillFrameNavigateEvent;\n        type WillNavigateEvent = Electron.WillNavigateEvent;\n        type WillResizeDetails = Electron.WillResizeDetails;\n        type EditFlags = Electron.EditFlags;\n        type Env = Electron.Env;\n        type FoundInPageResult = Electron.FoundInPageResult;\n        type LaunchItems = Electron.LaunchItems;\n        type Margins = Electron.Margins;\n        type MediaFlags = Electron.MediaFlags;\n        type PageRanges = Electron.PageRanges;\n        type Params = Electron.Params;\n        type TitleBarOverlay = Electron.TitleBarOverlay;\n        type Video = Electron.Video;\n        type WebPreferences = Electron.WebPreferences;\n        type DefaultFontFamily = Electron.DefaultFontFamily;\n        type BluetoothDevice = Electron.BluetoothDevice;\n        type Certificate = Electron.Certificate;\n        type CertificatePrincipal = Electron.CertificatePrincipal;\n        type Cookie = Electron.Cookie;\n        type CPUUsage = Electron.CPUUsage;\n        type CrashReport = Electron.CrashReport;\n        type CustomScheme = Electron.CustomScheme;\n        type DesktopCapturerSource = Electron.DesktopCapturerSource;\n        type Display = Electron.Display;\n        type Extension = Electron.Extension;\n        type ExtensionInfo = Electron.ExtensionInfo;\n        type FileFilter = Electron.FileFilter;\n        type FilePathWithHeaders = Electron.FilePathWithHeaders;\n        type GPUFeatureStatus = Electron.GPUFeatureStatus;\n        type HIDDevice = Electron.HIDDevice;\n        type InputEvent = Electron.InputEvent;\n        type IOCounters = Electron.IOCounters;\n        type IpcMainEvent = Electron.IpcMainEvent;\n        type IpcMainInvokeEvent = Electron.IpcMainInvokeEvent;\n        type IpcRendererEvent = Electron.IpcRendererEvent;\n        type JumpListCategory = Electron.JumpListCategory;\n        type JumpListItem = Electron.JumpListItem;\n        type KeyboardEvent = Electron.KeyboardEvent;\n        type KeyboardInputEvent = Electron.KeyboardInputEvent;\n        type MemoryInfo = Electron.MemoryInfo;\n        type MemoryUsageDetails = Electron.MemoryUsageDetails;\n        type MimeTypedBuffer = Electron.MimeTypedBuffer;\n        type MouseInputEvent = Electron.MouseInputEvent;\n        type MouseWheelInputEvent = Electron.MouseWheelInputEvent;\n        type NotificationAction = Electron.NotificationAction;\n        type NotificationResponse = Electron.NotificationResponse;\n        type PaymentDiscount = Electron.PaymentDiscount;\n        type Point = Electron.Point;\n        type PostBody = Electron.PostBody;\n        type PrinterInfo = Electron.PrinterInfo;\n        type ProcessMemoryInfo = Electron.ProcessMemoryInfo;\n        type ProcessMetric = Electron.ProcessMetric;\n        type Product = Electron.Product;\n        type ProductDiscount = Electron.ProductDiscount;\n        type ProductSubscriptionPeriod = Electron.ProductSubscriptionPeriod;\n        type ProtocolRequest = Electron.ProtocolRequest;\n        type ProtocolResponse = Electron.ProtocolResponse;\n        type ProtocolResponseUploadData = Electron.ProtocolResponseUploadData;\n        type Rectangle = Electron.Rectangle;\n        type Referrer = Electron.Referrer;\n        type ResolvedEndpoint = Electron.ResolvedEndpoint;\n        type ResolvedHost = Electron.ResolvedHost;\n        type ScrubberItem = Electron.ScrubberItem;\n        type SegmentedControlSegment = Electron.SegmentedControlSegment;\n        type SerialPort = Electron.SerialPort;\n        type ServiceWorkerInfo = Electron.ServiceWorkerInfo;\n        type SharedWorkerInfo = Electron.SharedWorkerInfo;\n        type SharingItem = Electron.SharingItem;\n        type ShortcutDetails = Electron.ShortcutDetails;\n        type Size = Electron.Size;\n        type Task = Electron.Task;\n        type ThumbarButton = Electron.ThumbarButton;\n        type TraceCategoriesAndOptions = Electron.TraceCategoriesAndOptions;\n        type TraceConfig = Electron.TraceConfig;\n        type Transaction = Electron.Transaction;\n        type UploadData = Electron.UploadData;\n        type UploadFile = Electron.UploadFile;\n        type UploadRawData = Electron.UploadRawData;\n        type USBDevice = Electron.USBDevice;\n        type UserDefaultTypes = Electron.UserDefaultTypes;\n        type WebRequestFilter = Electron.WebRequestFilter;\n        type WebSource = Electron.WebSource;\n    }\n\n    namespace CrossProcessExports {\n        type Event<Params extends object = {}> = Electron.Event<Params>;\n        const app: App;\n        type App = Electron.App;\n        const autoUpdater: AutoUpdater;\n        type AutoUpdater = Electron.AutoUpdater;\n        class BrowserView extends Electron.BrowserView {}\n        class BrowserWindow extends Electron.BrowserWindow {}\n        type ClientRequest = Electron.ClientRequest;\n        const clipboard: Clipboard;\n        type Clipboard = Electron.Clipboard;\n        type CommandLine = Electron.CommandLine;\n        const contentTracing: ContentTracing;\n        type ContentTracing = Electron.ContentTracing;\n        const contextBridge: ContextBridge;\n        type ContextBridge = Electron.ContextBridge;\n        type Cookies = Electron.Cookies;\n        const crashReporter: CrashReporter;\n        type CrashReporter = Electron.CrashReporter;\n        type Debugger = Electron.Debugger;\n        const desktopCapturer: DesktopCapturer;\n        type DesktopCapturer = Electron.DesktopCapturer;\n        const dialog: Dialog;\n        type Dialog = Electron.Dialog;\n        type Dock = Electron.Dock;\n        type DownloadItem = Electron.DownloadItem;\n        const globalShortcut: GlobalShortcut;\n        type GlobalShortcut = Electron.GlobalShortcut;\n        const inAppPurchase: InAppPurchase;\n        type InAppPurchase = Electron.InAppPurchase;\n        type IncomingMessage = Electron.IncomingMessage;\n        const ipcMain: IpcMain;\n        type IpcMain = Electron.IpcMain;\n        const ipcRenderer: IpcRenderer;\n        type IpcRenderer = Electron.IpcRenderer;\n        class Menu extends Electron.Menu {}\n        class MenuItem extends Electron.MenuItem {}\n        class MessageChannelMain extends Electron.MessageChannelMain {}\n        type MessagePortMain = Electron.MessagePortMain;\n        const nativeImage: typeof NativeImage;\n        type NativeImage = Electron.NativeImage;\n        const nativeTheme: NativeTheme;\n        type NativeTheme = Electron.NativeTheme;\n        const net: Net;\n        type Net = Electron.Net;\n        const netLog: NetLog;\n        type NetLog = Electron.NetLog;\n        class Notification extends Electron.Notification {}\n        const powerMonitor: PowerMonitor;\n        type PowerMonitor = Electron.PowerMonitor;\n        const powerSaveBlocker: PowerSaveBlocker;\n        type PowerSaveBlocker = Electron.PowerSaveBlocker;\n        const protocol: Protocol;\n        type Protocol = Electron.Protocol;\n        const pushNotifications: PushNotifications;\n        type PushNotifications = Electron.PushNotifications;\n        const safeStorage: SafeStorage;\n        type SafeStorage = Electron.SafeStorage;\n        const screen: Screen;\n        type Screen = Electron.Screen;\n        type ServiceWorkers = Electron.ServiceWorkers;\n        const session: typeof Session;\n        type Session = Electron.Session;\n        class ShareMenu extends Electron.ShareMenu {}\n        const shell: Shell;\n        type Shell = Electron.Shell;\n        const systemPreferences: SystemPreferences;\n        type SystemPreferences = Electron.SystemPreferences;\n        class TouchBar extends Electron.TouchBar {}\n        type TouchBarButton = Electron.TouchBarButton;\n        type TouchBarColorPicker = Electron.TouchBarColorPicker;\n        type TouchBarGroup = Electron.TouchBarGroup;\n        type TouchBarLabel = Electron.TouchBarLabel;\n        type TouchBarOtherItemsProxy = Electron.TouchBarOtherItemsProxy;\n        type TouchBarPopover = Electron.TouchBarPopover;\n        type TouchBarScrubber = Electron.TouchBarScrubber;\n        type TouchBarSegmentedControl = Electron.TouchBarSegmentedControl;\n        type TouchBarSlider = Electron.TouchBarSlider;\n        type TouchBarSpacer = Electron.TouchBarSpacer;\n        class Tray extends Electron.Tray {}\n        const utilityProcess: typeof UtilityProcess;\n        type UtilityProcess = Electron.UtilityProcess;\n        const webContents: typeof WebContents;\n        type WebContents = Electron.WebContents;\n        const webFrame: WebFrame;\n        type WebFrame = Electron.WebFrame;\n        const webFrameMain: typeof WebFrameMain;\n        type WebFrameMain = Electron.WebFrameMain;\n        type WebRequest = Electron.WebRequest;\n        type WebviewTag = Electron.WebviewTag;\n        type AboutPanelOptionsOptions = Electron.AboutPanelOptionsOptions;\n        type AddRepresentationOptions = Electron.AddRepresentationOptions;\n        type AdjustSelectionOptions = Electron.AdjustSelectionOptions;\n        type AnimationSettings = Electron.AnimationSettings;\n        type AppDetailsOptions = Electron.AppDetailsOptions;\n        type ApplicationInfoForProtocolReturnValue = Electron.ApplicationInfoForProtocolReturnValue;\n        type AuthenticationResponseDetails = Electron.AuthenticationResponseDetails;\n        type AuthInfo = Electron.AuthInfo;\n        type AutoResizeOptions = Electron.AutoResizeOptions;\n        type BeforeSendResponse = Electron.BeforeSendResponse;\n        type BitmapOptions = Electron.BitmapOptions;\n        type BlinkMemoryInfo = Electron.BlinkMemoryInfo;\n        type BluetoothPairingHandlerHandlerDetails = Electron.BluetoothPairingHandlerHandlerDetails;\n        type BrowserViewConstructorOptions = Electron.BrowserViewConstructorOptions;\n        type BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;\n        type CallbackResponse = Electron.CallbackResponse;\n        type CertificateTrustDialogOptions = Electron.CertificateTrustDialogOptions;\n        type ClearCodeCachesOptions = Electron.ClearCodeCachesOptions;\n        type ClearStorageDataOptions = Electron.ClearStorageDataOptions;\n        type ClientRequestConstructorOptions = Electron.ClientRequestConstructorOptions;\n        type CloseOpts = Electron.CloseOpts;\n        type Config = Electron.Config;\n        type ConfigureHostResolverOptions = Electron.ConfigureHostResolverOptions;\n        type ConsoleMessageEvent = Electron.ConsoleMessageEvent;\n        type ContextMenuEvent = Electron.ContextMenuEvent;\n        type ContextMenuParams = Electron.ContextMenuParams;\n        type ContinueActivityDetails = Electron.ContinueActivityDetails;\n        type CookiesGetFilter = Electron.CookiesGetFilter;\n        type CookiesSetDetails = Electron.CookiesSetDetails;\n        type CrashReporterStartOptions = Electron.CrashReporterStartOptions;\n        type CreateFromBitmapOptions = Electron.CreateFromBitmapOptions;\n        type CreateFromBufferOptions = Electron.CreateFromBufferOptions;\n        type CreateInterruptedDownloadOptions = Electron.CreateInterruptedDownloadOptions;\n        type Data = Electron.Data;\n        type Details = Electron.Details;\n        type DevicePermissionHandlerHandlerDetails = Electron.DevicePermissionHandlerHandlerDetails;\n        type DevtoolsOpenUrlEvent = Electron.DevtoolsOpenUrlEvent;\n        type DidChangeThemeColorEvent = Electron.DidChangeThemeColorEvent;\n        type DidCreateWindowDetails = Electron.DidCreateWindowDetails;\n        type DidFailLoadEvent = Electron.DidFailLoadEvent;\n        type DidFrameFinishLoadEvent = Electron.DidFrameFinishLoadEvent;\n        type DidFrameNavigateEvent = Electron.DidFrameNavigateEvent;\n        type DidNavigateEvent = Electron.DidNavigateEvent;\n        type DidNavigateInPageEvent = Electron.DidNavigateInPageEvent;\n        type DidRedirectNavigationEvent = Electron.DidRedirectNavigationEvent;\n        type DidStartNavigationEvent = Electron.DidStartNavigationEvent;\n        type DisplayBalloonOptions = Electron.DisplayBalloonOptions;\n        type DisplayMediaRequestHandlerHandlerRequest = Electron.DisplayMediaRequestHandlerHandlerRequest;\n        type EnableNetworkEmulationOptions = Electron.EnableNetworkEmulationOptions;\n        type FeedURLOptions = Electron.FeedURLOptions;\n        type FileIconOptions = Electron.FileIconOptions;\n        type FindInPageOptions = Electron.FindInPageOptions;\n        type FocusOptions = Electron.FocusOptions;\n        type ForkOptions = Electron.ForkOptions;\n        type FoundInPageEvent = Electron.FoundInPageEvent;\n        type FrameCreatedDetails = Electron.FrameCreatedDetails;\n        type FromPartitionOptions = Electron.FromPartitionOptions;\n        type FromPathOptions = Electron.FromPathOptions;\n        type HandlerDetails = Electron.HandlerDetails;\n        type HeadersReceivedResponse = Electron.HeadersReceivedResponse;\n        type HeapStatistics = Electron.HeapStatistics;\n        type HidDeviceAddedDetails = Electron.HidDeviceAddedDetails;\n        type HidDeviceRemovedDetails = Electron.HidDeviceRemovedDetails;\n        type HidDeviceRevokedDetails = Electron.HidDeviceRevokedDetails;\n        type IgnoreMouseEventsOptions = Electron.IgnoreMouseEventsOptions;\n        type ImportCertificateOptions = Electron.ImportCertificateOptions;\n        type Info = Electron.Info;\n        type Input = Electron.Input;\n        type InsertCSSOptions = Electron.InsertCSSOptions;\n        type IpcMessageEvent = Electron.IpcMessageEvent;\n        type Item = Electron.Item;\n        type JumpListSettings = Electron.JumpListSettings;\n        type LoadCommitEvent = Electron.LoadCommitEvent;\n        type LoadExtensionOptions = Electron.LoadExtensionOptions;\n        type LoadFileOptions = Electron.LoadFileOptions;\n        type LoadURLOptions = Electron.LoadURLOptions;\n        type LoginItemSettings = Electron.LoginItemSettings;\n        type LoginItemSettingsOptions = Electron.LoginItemSettingsOptions;\n        type MenuItemConstructorOptions = Electron.MenuItemConstructorOptions;\n        type MessageBoxOptions = Electron.MessageBoxOptions;\n        type MessageBoxReturnValue = Electron.MessageBoxReturnValue;\n        type MessageBoxSyncOptions = Electron.MessageBoxSyncOptions;\n        type MessageDetails = Electron.MessageDetails;\n        type MessageEvent = Electron.MessageEvent;\n        type MoveToApplicationsFolderOptions = Electron.MoveToApplicationsFolderOptions;\n        type NotificationConstructorOptions = Electron.NotificationConstructorOptions;\n        type OnBeforeRedirectListenerDetails = Electron.OnBeforeRedirectListenerDetails;\n        type OnBeforeRequestListenerDetails = Electron.OnBeforeRequestListenerDetails;\n        type OnBeforeSendHeadersListenerDetails = Electron.OnBeforeSendHeadersListenerDetails;\n        type OnCompletedListenerDetails = Electron.OnCompletedListenerDetails;\n        type OnErrorOccurredListenerDetails = Electron.OnErrorOccurredListenerDetails;\n        type OnHeadersReceivedListenerDetails = Electron.OnHeadersReceivedListenerDetails;\n        type OnResponseStartedListenerDetails = Electron.OnResponseStartedListenerDetails;\n        type OnSendHeadersListenerDetails = Electron.OnSendHeadersListenerDetails;\n        type OpenDevToolsOptions = Electron.OpenDevToolsOptions;\n        type OpenDialogOptions = Electron.OpenDialogOptions;\n        type OpenDialogReturnValue = Electron.OpenDialogReturnValue;\n        type OpenDialogSyncOptions = Electron.OpenDialogSyncOptions;\n        type OpenExternalOptions = Electron.OpenExternalOptions;\n        type Options = Electron.Options;\n        type Opts = Electron.Opts;\n        type PageFaviconUpdatedEvent = Electron.PageFaviconUpdatedEvent;\n        type PageTitleUpdatedEvent = Electron.PageTitleUpdatedEvent;\n        type Parameters = Electron.Parameters;\n        type Payment = Electron.Payment;\n        type PermissionCheckHandlerHandlerDetails = Electron.PermissionCheckHandlerHandlerDetails;\n        type PermissionRequestHandlerHandlerDetails = Electron.PermissionRequestHandlerHandlerDetails;\n        type PluginCrashedEvent = Electron.PluginCrashedEvent;\n        type PopupOptions = Electron.PopupOptions;\n        type PreconnectOptions = Electron.PreconnectOptions;\n        type PrintToPDFOptions = Electron.PrintToPDFOptions;\n        type Privileges = Electron.Privileges;\n        type ProgressBarOptions = Electron.ProgressBarOptions;\n        type Provider = Electron.Provider;\n        type PurchaseProductOpts = Electron.PurchaseProductOpts;\n        type ReadBookmark = Electron.ReadBookmark;\n        type RegistrationCompletedDetails = Electron.RegistrationCompletedDetails;\n        type RelaunchOptions = Electron.RelaunchOptions;\n        type RenderProcessGoneDetails = Electron.RenderProcessGoneDetails;\n        type Request = Electron.Request;\n        type ResizeOptions = Electron.ResizeOptions;\n        type ResolveHostOptions = Electron.ResolveHostOptions;\n        type ResourceUsage = Electron.ResourceUsage;\n        type Response = Electron.Response;\n        type Result = Electron.Result;\n        type SaveDialogOptions = Electron.SaveDialogOptions;\n        type SaveDialogReturnValue = Electron.SaveDialogReturnValue;\n        type SaveDialogSyncOptions = Electron.SaveDialogSyncOptions;\n        type SelectHidDeviceDetails = Electron.SelectHidDeviceDetails;\n        type SelectUsbDeviceDetails = Electron.SelectUsbDeviceDetails;\n        type SerialPortRevokedDetails = Electron.SerialPortRevokedDetails;\n        type Settings = Electron.Settings;\n        type SourcesOptions = Electron.SourcesOptions;\n        type SSLConfigConfig = Electron.SSLConfigConfig;\n        type StartLoggingOptions = Electron.StartLoggingOptions;\n        type Streams = Electron.Streams;\n        type SystemMemoryInfo = Electron.SystemMemoryInfo;\n        type TitleBarOverlayOptions = Electron.TitleBarOverlayOptions;\n        type TitleOptions = Electron.TitleOptions;\n        type ToBitmapOptions = Electron.ToBitmapOptions;\n        type ToDataURLOptions = Electron.ToDataURLOptions;\n        type ToPNGOptions = Electron.ToPNGOptions;\n        type TouchBarButtonConstructorOptions = Electron.TouchBarButtonConstructorOptions;\n        type TouchBarColorPickerConstructorOptions = Electron.TouchBarColorPickerConstructorOptions;\n        type TouchBarConstructorOptions = Electron.TouchBarConstructorOptions;\n        type TouchBarGroupConstructorOptions = Electron.TouchBarGroupConstructorOptions;\n        type TouchBarLabelConstructorOptions = Electron.TouchBarLabelConstructorOptions;\n        type TouchBarPopoverConstructorOptions = Electron.TouchBarPopoverConstructorOptions;\n        type TouchBarScrubberConstructorOptions = Electron.TouchBarScrubberConstructorOptions;\n        type TouchBarSegmentedControlConstructorOptions = Electron.TouchBarSegmentedControlConstructorOptions;\n        type TouchBarSliderConstructorOptions = Electron.TouchBarSliderConstructorOptions;\n        type TouchBarSpacerConstructorOptions = Electron.TouchBarSpacerConstructorOptions;\n        type TraceBufferUsageReturnValue = Electron.TraceBufferUsageReturnValue;\n        type UpdateTargetUrlEvent = Electron.UpdateTargetUrlEvent;\n        type UploadProgress = Electron.UploadProgress;\n        type UsbDeviceRevokedDetails = Electron.UsbDeviceRevokedDetails;\n        type USBProtectedClassesHandlerHandlerDetails = Electron.USBProtectedClassesHandlerHandlerDetails;\n        type VisibleOnAllWorkspacesOptions = Electron.VisibleOnAllWorkspacesOptions;\n        type WebContentsAudioStateChangedEventParams = Electron.WebContentsAudioStateChangedEventParams;\n        type WebContentsDidRedirectNavigationEventParams = Electron.WebContentsDidRedirectNavigationEventParams;\n        type WebContentsDidStartNavigationEventParams = Electron.WebContentsDidStartNavigationEventParams;\n        type WebContentsPrintOptions = Electron.WebContentsPrintOptions;\n        type WebContentsWillFrameNavigateEventParams = Electron.WebContentsWillFrameNavigateEventParams;\n        type WebContentsWillNavigateEventParams = Electron.WebContentsWillNavigateEventParams;\n        type WebContentsWillRedirectEventParams = Electron.WebContentsWillRedirectEventParams;\n        type WebviewTagPrintOptions = Electron.WebviewTagPrintOptions;\n        type WillFrameNavigateEvent = Electron.WillFrameNavigateEvent;\n        type WillNavigateEvent = Electron.WillNavigateEvent;\n        type WillResizeDetails = Electron.WillResizeDetails;\n        type EditFlags = Electron.EditFlags;\n        type Env = Electron.Env;\n        type FoundInPageResult = Electron.FoundInPageResult;\n        type LaunchItems = Electron.LaunchItems;\n        type Margins = Electron.Margins;\n        type MediaFlags = Electron.MediaFlags;\n        type PageRanges = Electron.PageRanges;\n        type Params = Electron.Params;\n        type TitleBarOverlay = Electron.TitleBarOverlay;\n        type Video = Electron.Video;\n        type WebPreferences = Electron.WebPreferences;\n        type DefaultFontFamily = Electron.DefaultFontFamily;\n        type BluetoothDevice = Electron.BluetoothDevice;\n        type Certificate = Electron.Certificate;\n        type CertificatePrincipal = Electron.CertificatePrincipal;\n        type Cookie = Electron.Cookie;\n        type CPUUsage = Electron.CPUUsage;\n        type CrashReport = Electron.CrashReport;\n        type CustomScheme = Electron.CustomScheme;\n        type DesktopCapturerSource = Electron.DesktopCapturerSource;\n        type Display = Electron.Display;\n        type Extension = Electron.Extension;\n        type ExtensionInfo = Electron.ExtensionInfo;\n        type FileFilter = Electron.FileFilter;\n        type FilePathWithHeaders = Electron.FilePathWithHeaders;\n        type GPUFeatureStatus = Electron.GPUFeatureStatus;\n        type HIDDevice = Electron.HIDDevice;\n        type InputEvent = Electron.InputEvent;\n        type IOCounters = Electron.IOCounters;\n        type IpcMainEvent = Electron.IpcMainEvent;\n        type IpcMainInvokeEvent = Electron.IpcMainInvokeEvent;\n        type IpcRendererEvent = Electron.IpcRendererEvent;\n        type JumpListCategory = Electron.JumpListCategory;\n        type JumpListItem = Electron.JumpListItem;\n        type KeyboardEvent = Electron.KeyboardEvent;\n        type KeyboardInputEvent = Electron.KeyboardInputEvent;\n        type MemoryInfo = Electron.MemoryInfo;\n        type MemoryUsageDetails = Electron.MemoryUsageDetails;\n        type MimeTypedBuffer = Electron.MimeTypedBuffer;\n        type MouseInputEvent = Electron.MouseInputEvent;\n        type MouseWheelInputEvent = Electron.MouseWheelInputEvent;\n        type NotificationAction = Electron.NotificationAction;\n        type NotificationResponse = Electron.NotificationResponse;\n        type PaymentDiscount = Electron.PaymentDiscount;\n        type Point = Electron.Point;\n        type PostBody = Electron.PostBody;\n        type PrinterInfo = Electron.PrinterInfo;\n        type ProcessMemoryInfo = Electron.ProcessMemoryInfo;\n        type ProcessMetric = Electron.ProcessMetric;\n        type Product = Electron.Product;\n        type ProductDiscount = Electron.ProductDiscount;\n        type ProductSubscriptionPeriod = Electron.ProductSubscriptionPeriod;\n        type ProtocolRequest = Electron.ProtocolRequest;\n        type ProtocolResponse = Electron.ProtocolResponse;\n        type ProtocolResponseUploadData = Electron.ProtocolResponseUploadData;\n        type Rectangle = Electron.Rectangle;\n        type Referrer = Electron.Referrer;\n        type ResolvedEndpoint = Electron.ResolvedEndpoint;\n        type ResolvedHost = Electron.ResolvedHost;\n        type ScrubberItem = Electron.ScrubberItem;\n        type SegmentedControlSegment = Electron.SegmentedControlSegment;\n        type SerialPort = Electron.SerialPort;\n        type ServiceWorkerInfo = Electron.ServiceWorkerInfo;\n        type SharedWorkerInfo = Electron.SharedWorkerInfo;\n        type SharingItem = Electron.SharingItem;\n        type ShortcutDetails = Electron.ShortcutDetails;\n        type Size = Electron.Size;\n        type Task = Electron.Task;\n        type ThumbarButton = Electron.ThumbarButton;\n        type TraceCategoriesAndOptions = Electron.TraceCategoriesAndOptions;\n        type TraceConfig = Electron.TraceConfig;\n        type Transaction = Electron.Transaction;\n        type UploadData = Electron.UploadData;\n        type UploadFile = Electron.UploadFile;\n        type UploadRawData = Electron.UploadRawData;\n        type USBDevice = Electron.USBDevice;\n        type UserDefaultTypes = Electron.UserDefaultTypes;\n        type WebRequestFilter = Electron.WebRequestFilter;\n        type WebSource = Electron.WebSource;\n    }\n\n    const app: App;\n    const autoUpdater: AutoUpdater;\n    const clipboard: Clipboard;\n    const contentTracing: ContentTracing;\n    const contextBridge: ContextBridge;\n    const crashReporter: CrashReporter;\n    const desktopCapturer: DesktopCapturer;\n    const dialog: Dialog;\n    const globalShortcut: GlobalShortcut;\n    const inAppPurchase: InAppPurchase;\n    const ipcMain: IpcMain;\n    const ipcRenderer: IpcRenderer;\n    const nativeImage: typeof NativeImage;\n    const nativeTheme: NativeTheme;\n    const net: Net;\n    const netLog: NetLog;\n    const parentPort: ParentPort;\n    const powerMonitor: PowerMonitor;\n    const powerSaveBlocker: PowerSaveBlocker;\n    const protocol: Protocol;\n    const pushNotifications: PushNotifications;\n    const safeStorage: SafeStorage;\n    const screen: Screen;\n    const session: typeof Session;\n    const shell: Shell;\n    const systemPreferences: SystemPreferences;\n    const utilityProcess: typeof UtilityProcess;\n    const webContents: typeof WebContents;\n    const webFrame: WebFrame;\n    const webFrameMain: typeof WebFrameMain;\n}\n\ndeclare module \"electron\" {\n    export = Electron.CrossProcessExports;\n}\n\ndeclare module \"electron/main\" {\n    export = Electron.Main;\n}\n\ndeclare module \"electron/common\" {\n    export = Electron.Common;\n}\n\ndeclare module \"electron/renderer\" {\n    export = Electron.Renderer;\n}\n\ninterface NodeRequireFunction {\n    (moduleName: \"electron\"): typeof Electron.CrossProcessExports;\n    (moduleName: \"electron/main\"): typeof Electron.Main;\n    (moduleName: \"electron/common\"): typeof Electron.Common;\n    (moduleName: \"electron/renderer\"): typeof Electron.Renderer;\n}\n\ninterface NodeRequire {\n    (moduleName: \"electron\"): typeof Electron.CrossProcessExports;\n    (moduleName: \"electron/main\"): typeof Electron.Main;\n    (moduleName: \"electron/common\"): typeof Electron.Common;\n    (moduleName: \"electron/renderer\"): typeof Electron.Renderer;\n}\n\ninterface File {\n    /**\n     * The real path to the file on the users filesystem\n     */\n    path: string;\n}\n\ndeclare module \"original-fs\" {\n    import * as fs from \"fs\";\n    export = fs;\n}\n\ninterface Document {\n    createElement(tagName: \"webview\"): Electron.WebviewTag;\n}\n\ndeclare namespace NodeJS {\n    interface Process extends NodeJS.EventEmitter {\n        // Docs: https://electronjs.org/docs/api/process\n\n        /**\n         * Emitted when Electron has loaded its internal initialization script and is\n         * beginning to load the web page or the main script.\n         */\n        on(event: \"loaded\", listener: Function): this;\n        once(event: \"loaded\", listener: Function): this;\n        addListener(event: \"loaded\", listener: Function): this;\n        removeListener(event: \"loaded\", listener: Function): this;\n        /**\n         * Causes the main thread of the current process crash.\n         */\n        crash(): void;\n        /**\n         * * `allocated` Integer - Size of all allocated objects in Kilobytes.\n         * * `total` Integer - Total allocated space in Kilobytes.\n         *\n         * Returns an object with Blink memory information. It can be useful for debugging\n         * rendering / DOM related memory issues. Note that all values are reported in\n         * Kilobytes.\n         */\n        getBlinkMemoryInfo(): Electron.BlinkMemoryInfo;\n        getCPUUsage(): Electron.CPUUsage;\n        /**\n         * The number of milliseconds since epoch, or `null` if the information is\n         * unavailable\n         *\n         * Indicates the creation time of the application. The time is represented as\n         * number of milliseconds since epoch. It returns null if it is unable to get the\n         * process creation time.\n         */\n        getCreationTime(): number | null;\n        /**\n         * * `totalHeapSize` Integer\n         * * `totalHeapSizeExecutable` Integer\n         * * `totalPhysicalSize` Integer\n         * * `totalAvailableSize` Integer\n         * * `usedHeapSize` Integer\n         * * `heapSizeLimit` Integer\n         * * `mallocedMemory` Integer\n         * * `peakMallocedMemory` Integer\n         * * `doesZapGarbage` boolean\n         *\n         * Returns an object with V8 heap statistics. Note that all statistics are reported\n         * in Kilobytes.\n         */\n        getHeapStatistics(): Electron.HeapStatistics;\n        /**\n         * @platform win32,linux\n         */\n        getIOCounters(): Electron.IOCounters;\n        /**\n         * Resolves with a ProcessMemoryInfo\n         *\n         * Returns an object giving memory usage statistics about the current process. Note\n         * that all statistics are reported in Kilobytes. This api should be called after\n         * app ready.\n         *\n         * Chromium does not provide `residentSet` value for macOS. This is because macOS\n         * performs in-memory compression of pages that haven't been recently used. As a\n         * result the resident set size value is not what one would expect. `private`\n         * memory is more representative of the actual pre-compression memory usage of the\n         * process on macOS.\n         */\n        getProcessMemoryInfo(): Promise<Electron.ProcessMemoryInfo>;\n        /**\n         * * `total` Integer - The total amount of physical memory in Kilobytes available\n         * to the system.\n         * * `free` Integer - The total amount of memory not being used by applications or\n         * disk cache.\n         * * `swapTotal` Integer _Windows_ _Linux_ - The total amount of swap memory in\n         * Kilobytes available to the system.\n         * * `swapFree` Integer _Windows_ _Linux_ - The free amount of swap memory in\n         * Kilobytes available to the system.\n         *\n         * Returns an object giving memory usage statistics about the entire system. Note\n         * that all statistics are reported in Kilobytes.\n         */\n        getSystemMemoryInfo(): Electron.SystemMemoryInfo;\n        /**\n         * The version of the host operating system.\n         *\n         * Example:\n         *\n         * **Note:** It returns the actual operating system version instead of kernel\n         * version on macOS unlike `os.release()`.\n         */\n        getSystemVersion(): string;\n        /**\n         * Causes the main thread of the current process hang.\n         */\n        hang(): void;\n        /**\n         * Sets the file descriptor soft limit to `maxDescriptors` or the OS hard limit,\n         * whichever is lower for the current process.\n         *\n         * @platform darwin,linux\n         */\n        setFdLimit(maxDescriptors: number): void;\n        /**\n         * Indicates whether the snapshot has been created successfully.\n         *\n         * Takes a V8 heap snapshot and saves it to `filePath`.\n         */\n        takeHeapSnapshot(filePath: string): boolean;\n        /**\n         * A `string` representing Chrome's version string.\n         *\n         */\n        readonly chrome: string;\n        /**\n         * A `string` (optional) representing a globally unique ID of the current\n         * JavaScript context. Each frame has its own JavaScript context. When\n         * contextIsolation is enabled, the isolated world also has a separate JavaScript\n         * context. This property is only available in the renderer process.\n         *\n         */\n        readonly contextId?: string;\n        /**\n         * A `boolean` that indicates whether the current renderer context has\n         * `contextIsolation` enabled. It is `undefined` in the main process.\n         *\n         */\n        readonly contextIsolated: boolean;\n        /**\n         * A `boolean`. When the app is started by being passed as parameter to the default\n         * Electron executable, this property is `true` in the main process, otherwise it\n         * is `undefined`. For example when running the app with `electron .`, it is\n         * `true`, even if the app is packaged (`isPackaged`) is `true`. This can be useful\n         * to determine how many arguments will need to be sliced off from `process.argv`.\n         *\n         */\n        readonly defaultApp: boolean;\n        /**\n         * A `string` representing Electron's version string.\n         *\n         */\n        readonly electron: string;\n        /**\n         * A `boolean`, `true` when the current renderer context is the \"main\" renderer\n         * frame. If you want the ID of the current frame you should use\n         * `webFrame.routingId`.\n         *\n         */\n        readonly isMainFrame: boolean;\n        /**\n         * A `boolean`. For Mac App Store build, this property is `true`, for other builds\n         * it is `undefined`.\n         *\n         */\n        readonly mas: boolean;\n        /**\n         * A `boolean` that controls ASAR support inside your application. Setting this to\n         * `true` will disable the support for `asar` archives in Node's built-in modules.\n         */\n        noAsar: boolean;\n        /**\n         * A `boolean` that controls whether or not deprecation warnings are printed to\n         * `stderr`. Setting this to `true` will silence deprecation warnings. This\n         * property is used instead of the `--no-deprecation` command line flag.\n         */\n        noDeprecation: boolean;\n        /**\n         * A `Electron.ParentPort` property if this is a `UtilityProcess` (or `null`\n         * otherwise) allowing communication with the parent process.\n         */\n        parentPort: Electron.ParentPort;\n        /**\n         * A `string` representing the path to the resources directory.\n         *\n         */\n        readonly resourcesPath: string;\n        /**\n         * A `boolean`. When the renderer process is sandboxed, this property is `true`,\n         * otherwise it is `undefined`.\n         *\n         */\n        readonly sandboxed: boolean;\n        /**\n         * A `boolean` that controls whether or not deprecation warnings will be thrown as\n         * exceptions. Setting this to `true` will throw errors for deprecations. This\n         * property is used instead of the `--throw-deprecation` command line flag.\n         */\n        throwDeprecation: boolean;\n        /**\n         * A `boolean` that controls whether or not deprecations printed to `stderr`\n         * include their stack trace. Setting this to `true` will print stack traces for\n         * deprecations. This property is instead of the `--trace-deprecation` command line\n         * flag.\n         */\n        traceDeprecation: boolean;\n        /**\n         * A `boolean` that controls whether or not process warnings printed to `stderr`\n         * include their stack trace. Setting this to `true` will print stack traces for\n         * process warnings (including deprecations). This property is instead of the\n         * `--trace-warnings` command line flag.\n         */\n        traceProcessWarnings: boolean;\n        /**\n         * A `string` representing the current process's type, can be:\n         *\n         * * `browser` - The main process\n         * * `renderer` - A renderer process\n         * * `worker` - In a web worker\n         * * `utility` - In a node process launched as a service\n         *\n         */\n        readonly type: \"browser\" | \"renderer\" | \"worker\" | \"utility\";\n        /**\n         * A `boolean`. If the app is running as a Windows Store app (appx), this property\n         * is `true`, for otherwise it is `undefined`.\n         *\n         */\n        readonly windowsStore: boolean;\n    }\n    interface ProcessVersions {\n        readonly electron: string;\n        readonly chrome: string;\n    }\n}\n"
  },
  {
    "path": "src/typings/index.d.ts",
    "content": "/// <reference types=\"node\" />\n/// <reference types=\"react\" />\n/// <reference types=\"./electron\" />\n\ndeclare module \"qqntim/main\" {\n    export = QQNTim.API.Main;\n}\n\ndeclare module \"qqntim/renderer\" {\n    export = QQNTim.API.Renderer;\n}\n\ndeclare module \"qqntim-settings\" {\n    export = QQNTim.Settings;\n}\n\ndeclare module \"qqntim-settings/components\" {\n    export = QQNTim.SettingsComponents;\n}\n\ndeclare namespace QQNTim {\n    namespace IPC {\n        type Direction = \"in\" | \"out\";\n        type Type = \"request\" | \"response\";\n        type Response = { errMsg: string; result: number };\n        type Request = any[];\n        type Args<T> = [{ type: string; eventName: string; callbackId: string }, T];\n        interface InterruptIPCOptions {\n            /**\n             * 类型 (`request` 或 `response`)\n             */\n            type?: Type;\n            /**\n             * 事件名称 (如 `ns-ntApi` 或 `ns-fsApi` 等)\n             */\n            eventName?: string;\n            /**\n             * 命令名称\n             */\n            cmdName?: string;\n            /**\n             * 方向 (接收或发送)\n             */\n            direction?: Direction | undefined;\n        }\n        type InterruptFunction = (args: Args<any>, channel: string, sender?: Electron.WebContents) => boolean | void;\n    }\n\n    namespace WindowCreation {\n        type InterruptArgsFunction = (args: Electron.BrowserWindowConstructorOptions) => Electron.BrowserWindowConstructorOptions;\n        type InterruptFunction = (window: Electron.BrowserWindow) => void;\n    }\n\n    interface Configuration {\n        plugins?: {\n            /**\n             * 插件白名单\n             */\n            whitelist?: string[];\n            /**\n             * 插件黑名单\n             */\n            blacklist?: string[];\n            /**\n             * 插件配置\n             */\n            config?: Record<string, object>;\n        };\n        /**\n         * 自定义插件加载器路径\n         */\n        pluginLoaders: string[];\n        /**\n         * 显示详细日志输出\n         * @description 开启后，可以在控制台内查看到 IPC 通信、部分 Electron 对象的成员访问信息等。\n         */\n        verboseLogging?: boolean;\n        /**\n         * 使用原版 DevTools\n         * @description 使用 Chromium DevTools 而不是 chii DevTools (Windows 版 9.8.5 及以上不可用)。\n         */\n        useNativeDevTools?: boolean;\n        /**\n         * 禁用兼容性处理\n         * @description 禁用后，LiteLoader 和 BetterQQNT 可能将不能与 QQNTim 一起使用。\n         */\n        disableCompatibilityProcessing?: boolean;\n    }\n\n    interface Environment {\n        config: Required<Configuration>;\n        path: {\n            /**\n             * 数据目录\n             */\n            dataDir: string;\n            /**\n             * 配置文件 (`qqntim.json`)\n             */\n            configFile: string;\n            /**\n             * 插件目录 (`plugins`)\n             */\n            pluginDir: string;\n            /**\n             * 用户插件目录 (`plugins-user`)\n             */\n            pluginPerUserDir: string;\n        };\n    }\n\n    namespace Entry {\n        class Main {\n            /**\n             * 当插件加载时触发\n             */\n            constructor();\n        }\n        class Renderer {\n            /**\n             * 当插件加载时触发\n             */\n            constructor();\n            /**\n             * 当页面加载完毕时触发\n             */\n            onWindowLoaded?(): void;\n        }\n    }\n\n    interface Plugin {\n        /**\n         * 是否已经加载\n         */\n        loaded: boolean;\n        /**\n         * 当前环境是否满足条件\n         */\n        meetRequirements: boolean;\n        /**\n         * 是否启用\n         */\n        enabled: boolean;\n        /**\n         * 唯一 ID\n         */\n        id: string;\n        /**\n         * 插件所在目录\n         */\n        dir: string;\n        /**\n         * 脚本和样式注入\n         */\n        injections: Plugin.Injection[];\n        /**\n         * 插件清单\n         */\n        manifest: Manifest;\n    }\n    namespace Plugin {\n        interface InjectionMain {\n            type: \"main\";\n            script: string | undefined;\n        }\n        interface InjectionRenderer {\n            type: \"renderer\";\n            page: Manifest.Page[] | undefined;\n            pattern: RegExp | undefined;\n            stylesheet: string | undefined;\n            script: string | undefined;\n        }\n        type Injection = InjectionMain | InjectionRenderer;\n        type AllUsersPlugins = Record<string, UserPlugins>;\n        type UserPlugins = Record<string, Plugin>;\n        type LoadedPlugins = Record<string, Plugin>;\n    }\n\n    namespace API {\n        type DefineModulesFunction = (newModules: Record<string, any>) => void;\n        namespace Main {\n            /**\n             * 所有已经扫描到的插件列表\n             */\n            const allPlugins: Plugin.AllUsersPlugins;\n            /**\n             * 当前的配置数据和配置文件路径\n             */\n            const env: Environment;\n            const interrupt: {\n                /**\n                 * 拦截 IPC 通讯\n                 * @param func 处理函数\n                 * @param options 过滤选项\n                 * @returns\n                 */\n                ipc: (func: IPC.InterruptFunction, options: IPC.InterruptIPCOptions) => void;\n                /**\n                 * 拦截窗口创建并修改 `BrowserWindow` 参数 (在窗口创建前)\n                 * @param func 处理函数\n                 * @returns\n                 */\n                windowArgs: (func: WindowCreation.InterruptArgsFunction) => void;\n                /**\n                 * 拦截 `BrowserWindow` 创建 (在窗口创建后)\n                 * @param func 处理函数\n                 * @returns\n                 */\n                windowCreation: (func: WindowCreation.InterruptFunction) => void;\n            };\n            /**\n             * 定义新模块\n             * @description 定义后，其他插件可通过 require 引入。\n             */\n            const defineModules: DefineModulesFunction;\n            const modules: {\n                fs: typeof import(\"fs-extra\");\n            };\n        }\n        namespace Renderer {\n            /**\n             * 所有已经扫描到的插件列表\n             */\n            const allPlugins: Plugin.AllUsersPlugins;\n            /**\n             * 当前的配置数据和配置文件路径\n             */\n            const env: Environment;\n            const interrupt: {\n                /**\n                 * 拦截 IPC 通讯\n                 * @param func 处理函数\n                 * @param options 过滤选项\n                 * @returns\n                 */\n                ipc(func: IPC.InterruptFunction, options: IPC.InterruptIPCOptions): void;\n            };\n            /**\n             * NT API\n             */\n            const nt: NT;\n            /**\n             * 窗口 API\n             */\n            const browserWindow: BrowserWindowAPI;\n            /**\n             * 应用程序生命周期 API\n             */\n            const app: AppAPI;\n            /**\n             * 对话框 API\n             */\n            const dialog: DialogAPI;\n            const modules: {\n                fs: typeof import(\"fs-extra\");\n            };\n            /**\n             * 定义新模块\n             * @description 定义后，其他插件可通过 require 引入。\n             */\n            const defineModules: DefineModulesFunction;\n            const utils: {\n                /**\n                 * 等待 DOM 元素出现\n                 * @description 当元素出现时，此函数返回的 Promise 会 resolve 一个元素。\n                 * @param selector CSS 选择器\n                 */\n                waitForElement<T extends Element>(selector: string): Promise<T>;\n                /**\n                 * 调用 NT API\n                 * @param eventName 事件名称 (如 `ns-ntApi` 或 `ns-fsApi` 等)\n                 * @param cmd 命令名称\n                 * @param args 参数\n                 */\n                ntCall(eventName: string, cmd: string, args: any[]): Promise<IPC.Response>;\n                /**\n                 * 获取与 DOM 元素相关联的 Vue 组件 ID\n                 * @param element 元素\n                 * @example\n                 * ```html\n                 * <div class=\"xxxxx\" data-vxxxxxx>xxxxx</div>\n                 * ```\n                 * 将会返回 `data-vxxxxxx`。\n                 */\n                getVueId(element: HTMLElement): string | undefined;\n            };\n            /**\n             * @description 当页面加载完毕时，此 Promise 会 resolve。\n             */\n            const windowLoadPromise: WindowLoadPromise;\n\n            type WindowLoadPromise = Promise<void>;\n\n            namespace NT {\n                interface MessageElementBase {\n                    /**\n                     * QQNT 原始数据\n                     */\n                    raw: object;\n                }\n                interface MessageElementText extends MessageElementBase {\n                    type: \"text\";\n                    /**\n                     * 文字数据\n                     */\n                    content: string;\n                }\n                interface MessageElementImage extends MessageElementBase {\n                    type: \"image\";\n                    /**\n                     * 图片文件路径\n                     */\n                    file: string;\n                    /**\n                     * @description 当此图片文件下载完成时此 Promise 会 resolve。\n                     */\n                    downloadedPromise: Promise<void>;\n                }\n                interface MessageElementFace extends MessageElementBase {\n                    type: \"face\";\n                    /**\n                     * 表情 ID\n                     */\n                    faceIndex: number;\n                    /**\n                     * 表情类型\n                     * @description 分别为普通表情、扩展表情、超级表情。当此属性为一个数字时代表此类型未知。\n                     */\n                    faceType: \"normal\" | \"normal-extended\" | \"super\" | number;\n                    /**\n                     * 超级表情 ID\n                     */\n                    faceSuperIndex?: number;\n                }\n                interface MessageElementRaw extends MessageElementBase {\n                    type: \"raw\";\n                }\n                type MessageElement = MessageElementText | MessageElementImage | MessageElementFace | MessageElementRaw;\n                type MessageElementSend = Omit<MessageElementText, \"raw\"> | Omit<MessageElementImage, \"raw\"> | Omit<Omit<MessageElementFace, \"raw\">, \"downloadPromise\"> | MessageElementRaw;\n                interface Message {\n                    /**\n                     * 聊天会话\n                     */\n                    peer: Peer;\n                    /**\n                     * 消息发送者\n                     */\n                    sender: Sender;\n                    /**\n                     * 消息元素\n                     */\n                    elements: MessageElement[];\n                    /**\n                     * @description 当消息内所有媒体文件下载完成时此 Promise 会 resolve。\n                     */\n                    allDownloadedPromise: Promise<void[]>;\n                    /**\n                     * QQNT 原始数据\n                     */\n                    raw: object;\n                }\n                interface Sender {\n                    /**\n                     * 发送者用户 UID\n                     */\n                    uid: string;\n                    /**\n                     * 发送者群昵称\n                     * 只有在群聊中，此属性才不为空。\n                     */\n                    memberName?: string;\n                    /**\n                     * 发送者昵称\n                     */\n                    nickName?: string;\n                }\n                interface Peer {\n                    /**\n                     * 聊天会话类型\n                     */\n                    chatType: \"friend\" | \"group\" | \"others\";\n                    /**\n                     * 对象用户 ID\n                     */\n                    uid: string;\n                    /**\n                     * 聊天会话名称\n                     * 主动提供此对象时，不需要设置此属性。\n                     */\n                    name?: string;\n                }\n                interface User {\n                    /**\n                     * 用户 ID\n                     */\n                    uid: string;\n                    /**\n                     * QQ 号\n                     */\n                    uin: string;\n                    /**\n                     * QID\n                     */\n                    qid: string;\n                    /**\n                     * 群头像 URL\n                     */\n                    avatarUrl: string;\n                    /**\n                     * 昵称\n                     */\n                    nickName: string;\n                    /**\n                     * 个性签名\n                     */\n                    bio: string;\n                    /**\n                     * 性别\n                     */\n                    sex: \"male\" | \"female\" | \"unset\" | \"others\";\n                    /**\n                     * QQNT 原始数据\n                     */\n                    raw: object;\n                }\n                interface Group {\n                    /**\n                     * 用户 ID\n                     */\n                    uid: string;\n                    /**\n                     * 群头像 URL\n                     */\n                    avatarUrl: string;\n                    /**\n                     * 群名称\n                     */\n                    name: string;\n                    /**\n                     * 身份组\n                     */\n                    role: \"master\" | \"moderator\" | \"member\" | \"others\";\n                    /**\n                     * 成员数量上限\n                     */\n                    maxMembers: number;\n                    /**\n                     * 成员数量\n                     */\n                    members: number;\n                    /**\n                     * QQNT 原始数据\n                     */\n                    raw: object;\n                }\n                interface LoginAccount {\n                    /**\n                     * 用户 ID\n                     */\n                    uid: string;\n                    /**\n                     * QQ 号\n                     */\n                    uin: string;\n                }\n\n                type Events = {\n                    /**\n                     * 当收到新消息时触发\n                     * @param messages 新消息\n                     * @returns\n                     */\n                    \"new-messages\": (messages: Message[]) => void;\n                    /**\n                     * 当好友列表更新时触发\n                     * @param list 用户列表\n                     * @returns\n                     */\n                    \"friends-list-updated\": (list: User[]) => void;\n                    /**\n                     * 当群列表更新时触发\n                     * @param list 群列表\n                     * @returns\n                     */\n                    \"groups-list-updated\": (list: Group[]) => void;\n                };\n                type EventEmitter = import(\"typed-emitter\").default<Events>;\n            }\n            interface NT extends NT.EventEmitter {\n                /**\n                 * 获取当前登录的账号\n                 * @returns 当前登录的账号\n                 */\n                getAccountInfo(): Promise<NT.LoginAccount | undefined>;\n                /**\n                 * 获取用户信息\n                 * @param uid 用户 ID\n                 * @returns 用户信息\n                 */\n                getUserInfo(uid: string): Promise<NT.User>;\n                /**\n                 * 撤回一条消息\n                 * @param peer 聊天会话\n                 * @param message 消息 ID\n                 * @returns\n                 */\n                revokeMessage(peer: NT.Peer, message: string): Promise<void>;\n                /**\n                 * 发送一条消息\n                 * @param peer 聊天会话\n                 * @param elements 消息元素\n                 * @returns 消息 ID\n                 */\n                sendMessage(peer: NT.Peer, elements: NT.MessageElement[]): Promise<string>;\n                /**\n                 * 获取好友列表\n                 * @param forced 忽略缓存强制获取\n                 * @returns 用户信息列表\n                 */\n                getFriendsList(forced: boolean): Promise<NT.User[]>;\n                /**\n                 * 获取群列表\n                 * @param forced 忽略缓存强制获取\n                 * @returns 群列表\n                 */\n                getGroupsList(forced: boolean): Promise<NT.Group[]>;\n                /**\n                 * 获取历史聊天记录\n                 * @param peer 聊天会话\n                 * @param count 消息数量\n                 * @param startMsgId 开始位置 (消息 ID)\n                 * @returns 历史消息列表\n                 */\n                getPreviousMessages(peer: NT.Peer, count?: number, startMsgId?: string): Promise<NT.Message[]>;\n            }\n\n            interface BrowserWindowAPI {\n                setSize(width: number, height: number): void;\n                setMinimumSize(width: number, height: number): void;\n            }\n            interface AppAPI {\n                /**\n                 * 重启\n                 */\n                relaunch(): void;\n                /**\n                 * 退出\n                 */\n                quit(): void;\n                /**\n                 * 强行退出\n                 */\n                exit(): void;\n            }\n            interface DialogAPI {\n                /**\n                 * 显示一个询问对话框，等待用户选择 \"确定\" 或 \"取消\" 按钮\n                 * @param message 消息\n                 * @returns 用户是否点击了 \"确定\" 按钮\n                 */\n                confirm(message?: string): Promise<boolean>;\n                /**\n                 * 显示一则消息\n                 * @param message 消息\n                 * @returns\n                 */\n                alert(message?: string): Promise<void>;\n                /**\n                 * 显示消息框\n                 * @param options\n                 * @returns\n                 */\n                messageBox(options: Electron.MessageBoxOptions): Promise<Electron.MessageBoxReturnValue>;\n                /**\n                 * 显示打开文件对话框\n                 * @param options\n                 * @returns\n                 */\n                openDialog(options: Electron.OpenDialogOptions): Promise<Electron.OpenDialogReturnValue>;\n                /**\n                 * 显示保存文件对话框\n                 * @param options\n                 * @returns\n                 */\n                saveDialog(options: Electron.SaveDialogOptions): Promise<Electron.SaveDialogReturnValue>;\n            }\n        }\n    }\n\n    /**\n     * @example\n     * {\n     *    \"manifestVersion\": \"2.0\",\n     *    \"id\": \"my-plugin\",\n     *    \"name\": \"我的插件\",\n     *    \"author\": \"Flysoft\",\n     *    \"requirements\": {\n     *        \"os\": [\n     *            {\n     *                \"platform\": \"win32\",\n     *                \"lte\": \"10.0.22621\",\n     *                \"gte\": \"6.1.0\"\n     *            }\n     *        ]\n     *    },\n     *    \"injections\": [\n     *        {\n     *            \"type\": \"main\",\n     *            \"script\": \"main.js\"\n     *        },\n     *        {\n     *            \"type\": \"renderer\",\n     *            \"page\": [\"main\", \"chat\"],\n     *            \"script\": \"main.js\",\n     *            \"stylesheet\": \"style.css\"\n     *        }\n     *    ]\n     *}\n     */\n    interface Manifest {\n        /**\n         * 插件规范版本\n         */\n        manifestVersion: Manifest.ManifestVersion;\n        /**\n         * 唯一 ID\n         */\n        id: string;\n        /**\n         * 显示名称\n         */\n        name: string;\n        /**\n         * 插件自身版本\n         */\n        version?: string;\n        /**\n         * 说明\n         */\n        description?: string;\n        /**\n         * 作者\n         */\n        author?: string;\n        /**\n         * 脚本和样式注入\n         */\n        injections: Manifest.Injection[];\n        /**\n         * 加载条件\n         */\n        requirements?: Manifest.Requirements;\n    }\n    namespace Manifest {\n        /**\n         * 分别表示登录页面、主界面、独立聊天窗口、设置界面和其他\n         */\n        type Page = \"login\" | \"main\" | \"chat\" | \"settings\" | \"others\";\n        type PageWithAbout = Page | \"about\";\n        /**\n         * 注入主进程\n         */\n        interface InjectionMain {\n            /**\n             * 向主进程注入脚本时，此项必须置为 \"main\"\n             */\n            type: \"main\";\n            /**\n             * 注入的脚本文件 (*.js)\n             */\n            script?: string;\n        }\n        /**\n         * 注入渲染进程\n         */\n        interface InjectionRenderer {\n            /**\n             * 向渲染进程注入脚本时，此项必须置为 \"renderer\"\n             */\n            type: \"renderer\";\n            /**\n             * 指定此注入生效的页面\n             */\n            page?: Page[];\n            /**\n             * 指定此注入生效的页面 (正则表达式匹配)\n             */\n            pattern?: string;\n            /**\n             * 注入的样式文件 (*.css) (相对路径)\n             */\n            stylesheet?: string;\n            /**\n             * 注入的脚本文件 (*.js) (相对路径)\n             */\n            script?: string;\n        }\n        interface RequirementsOS {\n            /**\n             * 支持的操作系统类型\n             */\n            platform: \"win32\" | \"linux\" | \"darwin\";\n            /**\n             * `x` 须小于等于当前的操作系统版本\n             */\n            lte?: string;\n            /**\n             * `x` 须小于当前的操作系统版本\n             */\n            lt?: string;\n            /**\n             * `x` 须大于等于当前的操作系统版本\n             */\n            gte?: string;\n            /**\n             * `x` 须大于当前的操作系统版本\n             */\n            gt?: string;\n            /**\n             * `x` 须等于当前的操作系统版本\n             */\n            eq?: string;\n        }\n        type Injection = InjectionMain | InjectionRenderer;\n        interface Requirements {\n            /**\n             * 加载插件的操作系统要求\n             * 可以使用多个属性来指定一个版本区间。\n             * @example\n             * {\n             *     \"platform\": \"win32\",\n             *     \"lte\": \"10.0.22621\",\n             *     \"gte\": \"6.1.0\"\n             * }\n             * // 此示例代表满足 Windows 7 <= 当前系统版本 <= Windows 11 22H2 (6.1 <= 当前系统版本 <= 10.0.22621) 时加载插件。\n             */\n            os?: RequirementsOS[];\n        }\n        /**\n         * 插件规范版本\n         */\n        type ManifestVersion = \"1.0\" | \"2.0\" | \"3.0\";\n    }\n\n    namespace Settings {\n        type Panel = (props: PanelProps) => React.JSX.Element;\n\n        interface PanelProps {\n            config: Record<string, object>;\n            setConfig: React.Dispatch<React.SetStateAction<Record<string, object>>>;\n        }\n\n        const defineSettingsPanels: (...newSettingsPanels: [string, Panel, string | undefined][]) => void;\n    }\n    namespace SettingsComponents {\n        const SettingsSection: (props: { title: string; children: React.ReactNode; buttons?: React.ReactNode }) => React.JSX.Element;\n        const SettingsBox: (props: {\n            children: React.ReactNode;\n        }) => React.JSX.Element;\n        const SettingsBoxItem: (props: { title: string; description?: string[]; children?: React.ReactNode; isLast?: boolean }) => React.JSX.Element;\n        const Switch: (props: { checked: boolean; onToggle: (checked: boolean) => void }) => React.JSX.Element;\n        const Input: (props: { value: string; onChange: (value: string) => void }) => React.JSX.Element;\n        const Dropdown: <T>(props: { items: [T, string][]; selected: T; onChange: (id: T) => void; width: string }) => React.JSX.Element;\n        const Button: (props: { onClick: () => void; primary: boolean; small: boolean; children: React.ReactNode }) => React.JSX.Element;\n    }\n}\n\ndeclare namespace NodeJS {\n    interface ProcessVersions {\n        readonly qqntim: string;\n        readonly qqnt: string;\n    }\n}\n\ninterface HTMLElement {\n    __VUE__?: any[];\n}\n"
  },
  {
    "path": "src/typings/package.json",
    "content": "{\n    \"name\": \"@flysoftbeta/qqntim-typings\",\n    \"version\": \"3.1.3\",\n    \"license\": \"LGPL-3.0-or-later\",\n    \"publishConfig\": {\n        \"access\": \"public\"\n    },\n    \"dependencies\": {\n        \"@types/fs-extra\": \"^11.0.1\",\n        \"@types/node\": \"^20.6.2\",\n        \"@types/react\": \"^18.2.21\",\n        \"@types/react-dom\": \"^18.2.7\",\n        \"typed-emitter\": \"^2.1.0\"\n    },\n    \"devDependencies\": {\n        \"typescript\": \"^5.2.2\"\n    }\n}\n"
  },
  {
    "path": "src/typings/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"module\": \"CommonJS\",\n        \"moduleResolution\": \"Node\",\n        \"target\": \"ESNext\",\n        \"resolveJsonModule\": true,\n        \"strictNullChecks\": true,\n        \"strictFunctionTypes\": true,\n        \"noEmit\": true\n    },\n    \"include\": [\"index.d.ts\",\"electron.d.ts\"],\n    \"exclude\": [\"node_modules\", \"**/node_modules/*\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"jsx\": \"react-jsx\",\n        \"module\": \"CommonJS\",\n        \"moduleResolution\": \"Node\",\n        \"target\": \"ESNext\",\n        \"resolveJsonModule\": true,\n        \"strictNullChecks\": true,\n        \"strictFunctionTypes\": true,\n        \"noEmit\": true\n    },\n    \"include\": [\"src\"],\n    \"exclude\": [\"node_modules\", \"**/node_modules/*\",\"src/typings\"]\n}\n"
  }
]