{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://json.schemastore.org/webextension.json",
  "title": "JSON schema for WebExtensions manifest files",
  "description": "The manifest.json file is the only file that every extension using WebExtension APIs must contain.\n\nUsing manifest.json, you specify basic metadata about your extension such as the name and version, and can also specify aspects of your extension's functionality (such as background scripts, content scripts, and browser actions).\n\nIt is a JSON-formatted file, with one exception: it is allowed to contain \"//\"-style comments.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json",
  "required": ["manifest_version", "name", "version"],
  "type": "object",
  "additionalProperties": true,
  "if": {
    "properties": {
      "manifest_version": {
        "const": 2
      }
    }
  },
  "then": {
    "properties": {
      "browser_action": {
        "$ref": "#/definitions/action",
        "description": "A browser action is a button that your extension adds to the browser's toolbar. The button has an icon, and may optionally have a popup whose content is specified using HTML, CSS, and JavaScript.\n\nThis key is replaced by action in Manifest V3 extensions.\n\nIf you supply a popup, then the popup is opened when the user clicks the button, and your JavaScript running in the popup can handle the user's interaction with it. If you don't supply a popup, then a click event is dispatched to your extension's background scripts when the user clicks the button.\n\nYou can also create and manipulate browser actions programmatically using the browserAction API.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action"
      },
      "options_ui": {
        "properties": {
          "browser_style": {
            "description": "Use this to include a stylesheet in your page that will make it look consistent with the browser's UI and with other add-ons that use the browser_style property.",
            "type": "boolean",
            "default": true
          }
        }
      }
    },
    "definitions": {
      "common_action": {
        "properties": {
          "browser_style": {
            "description": "Your extension can include user interface elements - browser and page action popups, sidebars, and options pages - that are specified by:\n1. creating an HTML file defining the structure of the UI element.\n2. adding a manifest.json key (action, browser_action, page_action, sidebar_action, or options_ui) pointing to that HTML file.\n\nYou can style these elements to match the browser's style. The manifest.json keys include an optional property to help with this: browser_style. If this is included and set to true, your document gets one or more extra stylesheets that help make it look consistent with the browser's UI and with other extensions that use the browser_style property.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles",
            "type": "boolean",
            "default": false
          }
        }
      },
      "sidebar_action": {
        "properties": {
          "browser_style": {
            "description": "In Firefox, the stylesheet can be seen at chrome://browser/content/extension.css or chrome://browser/content/extension-mac.css on macOS.",
            "type": "boolean",
            "default": true
          }
        }
      }
    }
  },
  "else": {
    "properties": {
      "action": {
        "$ref": "#/definitions/action",
        "description": "An action is a button that your extension adds to the browser's toolbar. The button has an icon, and may optionally have a popup whose content is specified using HTML, CSS, and JavaScript.\n\nThis key replaces browser_action in Manifest V3 extensions.\n\nYou must specify this key to include a browser toolbar button in your extension. When specified, you can manipulate the button programmatically using the action API.\n\nIf you supply a popup, then the popup is opened when the user clicks the button, and your JavaScript running in the popup can handle the user's interaction with it. If you don't supply a popup, then a click event is dispatched to your extension's background scripts when the user clicks the button."
      },
      "background": {
        "properties": {
          "persistent": {
            "const": false
          }
        }
      },
      "host_permissions": {
        "type": "array",
        "items": {
          "$ref": "#/definitions/match_pattern",
          "description": "Use the host_permissions key to request access for the APIs in your extension that read or modify host data, such as cookies, webRequest, and tabs. This key is an array of strings, and each string is a request for a permission. Users can grant or revoke host permissions on an ad hoc basis. Therefore., most browsers treat host_permissions as optional.\n\nThe extra privileges include:\nXMLHttpRequest and fetch access to those origins without cross-origin restrictions (though not for requests from content scripts, as was the case in Manifest V2).\nthe ability to read tab-specific metadata without the \"tabs\" permission, such as the url, title, and favIconUrl properties of tabs.Tab objects.\nthe ability to inject scripts programmatically (using tabs.executeScript()) into pages served from those origins.\nthe ability to receive events from the webRequest API for these hosts.\nthe ability to access cookies for that host using the cookies API, as long as the \"cookies\" API permission is also included.\nbypassing tracking protection for extension pages where a host is specified as a full domain or with wildcards.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/host_permissions"
        }
      }
    },
    "definitions": {
      "browser_style": {
        "const": false
      }
    }
  },
  "properties": {
    "author": {
      "description": "The extension's author, intended for display in the browser's user interface. If the developer key is supplied and it contains the \"name`\" property, it will override the author key. There's no way to specify multiple authors.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/author",
      "type": "string"
    },
    "background": {
      "title": "background script inclusions",
      "description": "Use the background key to include one or more background scripts, a background page, or a Service worker in your extension.\n\nBackground scripts are the place to put code that needs to maintain a long-term state or perform long-term operations independently of the lifetime of any particular web pages or browser windows.\n\nBackground scripts are loaded as soon as the extension is loaded and stay loaded until the extension is disabled or uninstalled unless persistent is specified as false. You can use any WebExtension APIs in the script if you have requested the necessary permissions.\n\nSee Background scripts for some more details.\n\nThe background key is an object that must have one of these properties (for more information on how these properties are supported, see Browser support)\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "page": {
          "description": " If you need specific content in the background page, you can define a page using the page property. This is a String representing a path relative to the manifest.json file to an HTML document included in your extension bundle.\n\nIf you use this property, you can not specify background scripts using scripts, but you can include scripts from the page, just like a normal web page.",
          "type": "string"
        },
        "scripts": {
          "description": " An Array of Strings, each of which is a path to a JavaScript source. The path is relative to the manifest.json file itself. These are the scripts that are executed in the extension's background page.\nThe scripts share the same window global context.\nThe scripts are loaded in the order they appear in the array.\nIf you specify scripts, an empty page is created where your scripts run.\nNote: If you want to fetch a script from a remote location with the <script> tag (e.g., <script src = \"https://code.jquery.com/jquery-3.6.0.min.js\">), you have to change the content_security_policy key in the manifest.json file of your extension.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "service_worker": {
          "description": "Specify a JavaScript file as the extension service worker. A service worker is a background script that acts as the extension's main event handler.",
          "type": "string"
        },
        "persistent": {
          "description": "If omitted, this property defaults to true in Manifest V2 and false in Manifest V3. Setting to true in Manifest V3 results in an error.\n\n`true` indicates the background page is to be kept in memory from when the extension is loaded or the browser starts until the extension is unloaded or disabled, or the browser is closed (that is, the background page is persistent).\n`false` indicates the background page may be unloaded from memory when idle and recreated when needed. Such background pages are often called Event Pages, because they are loaded into memory to allow the background page to handle the events to which it has added listeners. Registration of listeners is persistent when the page is unloaded from memory, but other values are not persistent. If you want to store data persistently in an event page, then you should use the storage API.",
          "type": "boolean"
        },
        "type": {
          "description": "Determines whether the scripts specified in \"scripts\" are loaded as ES modules.\n\n`classic` indicates the background scripts or service workers are not included as an ES Module.\n\nIf omitted, this property defaults to classic.",
          "type": "string",
          "enum": ["classic", "module"]
        }
      }
    },
    "browser_specific_settings": {
      "title": "browser specific settings",
      "description": "The browser_specific_settings key contains keys that are specific to a particular host application.",
      "type": "object",
      "additionalProperties": true,
      "properties": {
        "gecko": {
          "$ref": "#/definitions/gecko_version_support",
          "title": "gecko specific settings",
          "type": "object",
          "properties": {
            "id": {
              "description": "id is the extension ID",
              "type": "string",
              "pattern": "^\\{[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}\\}$|^[A-Za-z0-9-._]*@[A-Za-z0-9-._]+$"
            },
            "update_url": {
              "description": "Link to an add-on update manifest. (Requires Gecko 45)",
              "type": "string",
              "format": "uri"
            }
          }
        },
        "gecko_android": {
          "$ref": "#/definitions/gecko_version_support",
          "title": "gecko Android specific settings",
          "description": "When not defined, it falls back to `gecko`",
          "type": "object"
        },
        "safari": {
          "$ref": "#/definitions/gecko_version_support",
          "title": "safari specific settings",
          "description": "Specific for Safari and Safari on IOS",
          "type": "object"
        }
      }
    },
    "chrome_settings_overrides": {
      "title": "browser home page",
      "description": "Use the chrome_settings_overrides key to override the browser's home page and add a new search engine.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_settings_overrides",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "homepage": {
          "description": "Defines the page to be used as the browser's homepage.\n\nThe replacement is given as a URL. The URL may:\n- point to a file bundled with the extension, in which case it is given as a URL relative to the manifest.json file\n- be a remote URL, such as \"https://developer.mozilla.org/\".\n\nIf two or more extensions both set this value, then the setting from the most recently installed one will take precedence.\n\nTo override new tabs, use \"chrome_url_overrides\" instead.\n\nThis is a localizable property.",
          "type": "string",
          "format": "uri-reference"
        },
        "search_provider": {
          "title": "search providers",
          "description": "Defines a search provider to add to the browser.\n\nIn the URLs you supply, use \"{searchTerms}\" to interpolate the search term into the URL, like: https://www.discogs.com/search/?q={searchTerms}. You can also provide POST parameters to be sent along with the search.\n\nThe search provider will be presented to the user alongside the built-in providers.\n\nAll string properties are localizable.",
          "type": "object",
          "additionalProperties": false,
          "required": ["name", "search_url"],
          "properties": {
            "name": {
              "description": "The search engine's name, displayed to the user.",
              "type": "string"
            },
            "search_url": {
              "description": "URL used by the search engine. This must be an HTTPS URL.",
              "type": "string",
              "format": "url"
            },
            "is_default": {
              "description": "True if the search engine should be the default choice. On Firefox, this is opt-in and the user will only be asked the first time the extension is installed. They will not be asked again if a search engine is added later.",
              "type": "boolean"
            },
            "alternate_urls": {
              "description": "An array of alternative URLs that can be used instead of search_url.",
              "type": "array",
              "items": {
                "type": "string",
                "format": "url"
              }
            },
            "encoding": {
              "description": "Encoding of the search term, specified as a standard character encoding name, such as \"UTF-8\".",
              "type": "string"
            },
            "favicon_url": {
              "description": "URL pointing to an icon for the search engine. This must be an absolute HTTP or HTTPS URL.",
              "type": "string",
              "format": "url"
            },
            "image_url": {
              "description": "URL used for image search.",
              "type": "string",
              "format": "url"
            },
            "image_url_post_params": {
              "description": "POST parameters to send to image_url.",
              "type": "string"
            },
            "instant_url": {
              "description": "URL used for instant search.",
              "type": "string",
              "format": "url"
            },
            "instant_url_post_params": {
              "description": "POST parameters to send to instant_url.",
              "type": "string"
            },
            "keyword": {
              "description": "Address bar keyword for the search engine.",
              "type": "string"
            },
            "prepopulated_id": {
              "description": "The ID of a built-in search engine to use.",
              "type": "string"
            },
            "search_url_post_params": {
              "description": "POST parameters to send to search_url.",
              "type": "string"
            },
            "suggest_url": {
              "description": "URL used for search suggestions. This must be an HTTPS URL.",
              "type": "string",
              "format": "url"
            },
            "suggest_url_post_params": {
              "description": "POST parameters to send to suggest_url.",
              "type": "string"
            }
          }
        }
      }
    },
    "chrome_url_overrides": {
      "title": "custom special pages",
      "description": "Use the chrome_url_overrides key to provide a custom replacement for the documents loaded into various special pages usually provided by the browser itself.\n\nThe replacements are given as a URL to an HTML file. The file must be bundled with the extension: you can't specify a remote URL here. You can specify it relative to the extension's root folder, like: \"path/to/newtab.html\".\n\nThe document can load CSS and JavaScript, just like a normal web page. JavaScript running in the page gets access to the same privileged \"browser.*\" APIs as the extension's background script.\n\nIf two or more extensions both define custom new tab pages, then the last one to be installed or enabled gets to use its value.\n\nAll properties are localizable.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "bookmarks": {
          "description": "Provide a replacement for the page that shows the bookmarks.",
          "type": "string",
          "format": "uri-reference"
        },
        "history": {
          "description": "Provide a replacement for the page that shows the browsing history.",
          "type": "string",
          "format": "uri-reference"
        },
        "newtab": {
          "description": "Provide a replacement for the document that's shown in the \"new tab\" page",
          "type": "string",
          "format": "uri-reference"
        }
      }
    },
    "commands": {
      "title": "keyboard shortcuts",
      "description": "Use the commands key to define one or more keyboard shortcuts for your extension.\n\nEach keyboard shortcut is defined with a name, a combination of keys, and a description. Once you've defined commands in your extension's manifest.json, you can listen for their associated key combinations with the commands JavaScript API.\n\nThe properties' name is the name of the shortcut.\n\nThere are these 4 special shortcuts with default actions for which the commands.onCommand event does not fire\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands",
      "type": "object",
      "properties": {
        "_execute_browser_action": {
          "$ref": "#/definitions/command",
          "description": "Works like a click on a toolbar button created with browserAction or specified in the browser_action key in the manifest.json key."
        },
        "_execute_page_action": {
          "$ref": "#/definitions/command",
          "description": "Works like a click on an address bar button created with pageAction or specified in the page_action key in the manifest.json key."
        },
        "_execute_sidebar_action": {
          "$ref": "#/definitions/command",
          "description": "Opens the extension's sidebar specified in the sidebar_action manifest.json key."
        }
      },
      "additionalProperties": {
        "$ref": "#/definitions/command",
        "description": "A custom command"
      }
    },
    "content_scripts": {
      "description": "Instructs the browser to load content scripts into web pages whose URL matches a given pattern.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts",
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "title": "content script",
        "type": "object",
        "required": ["matches"],
        "additionalProperties": false,
        "properties": {
          "matches": {
            "description": "Specifies which pages this content script will be injected into.<br>There are other optional keys including and excluding.<br>In summary: Match the `matches` property, AND match the `include_globs` property, if present, AND NOT match the `exclude_matches` property, if present, AND NOT match the `exclude_globs` property, if present",
            "type": "array",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/match_pattern"
            }
          },
          "exclude_matches": {
            "description": "Excludes pages that this content script would otherwise be injected into.",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/match_pattern"
            }
          },
          "css": {
            "description": " An array of paths, relative to manifest.json, referencing CSS files that will be injected into matching pages.<br>Files are injected in the order given, and at the time specified by run_at.<br>Note: Firefox resolves URLs in injected CSS files relative to the CSS file itself, rather than to the page it's injected into.",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "format": "uri-reference"
            }
          },
          "js": {
            "$ref": "#/definitions/scripts",
            "description": " An array of paths, relative to manifest.json, referencing JavaScript files that will be injected into matching pages.<br>Files are injected in the order given. This means that, injected scripts cab utilize scripts included prior to them.<br>The files are injected after any files in `css`, and at the time specified by `run_at`."
          },
          "run_at": {
            "description": " This option determines when the files specified in css and js are injected. You can supply one of three strings here, each of which identifies a state in the process of loading a document. The states directly correspond to Document.readyState:<br>\"document_start\": Corresponds to loading. The DOM is still loading.<br>\"document_end\": Corresponds to interactive. The DOM has finished loading, but resources such as scripts and images may still be loading.<br>\"document_idle\": Corresponds to complete. The document and all its resources have finished loading.",
            "type": "string",
            "enum": ["document_start", "document_end", "document_idle"],
            "default": "document_idle"
          },
          "all_frames": {
            "description": "`true`: Inject the scripts specified in `js` and `css` into all frames matching the specified URL requirements, even if the frame is not the topmost frame in a tab. This does not inject into child frames where only their parent matches the URL requirements and the child frame does not match the URL requirements. The URL requirements are checked for each frame independently.<br>Note: This also applies to any tracker or ad that uses iframes, which means that enabling this could make your content script get called dozens of times on some pages.<br><br>false`: Inject only into frames matching the URL requirements which are the topmost frame in a tab.",
            "type": "boolean",
            "default": false
          },
          "include_globs": {
            "description": "Applied after matches to include only those URLs that also match this glob.",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/glob_pattern"
            }
          },
          "exclude_globs": {
            "description": "Applied after matches to exclude URLs that match this glob.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts#matching_url_patterns",
            "type": "array",
            "uniqueItems": true,
            "items": {
              "$ref": "#/definitions/glob_pattern"
            }
          },
          "match_about_blank": {
            "description": " Insert the content scripts into pages whose URL is \"about:blank\" or \"about:srcdoc\", if the URL of the page that opened or created this page matches the patterns specified in the rest of the content_scripts key.<br>This is especially useful to run scripts in empty iframes, whose URL is \"about:blank\". To do this you should also set the all_frames key.",
            "type": "boolean",
            "default": false
          },
          "world": {
            "description": "The JavaScript world the script executes in.<br>\"ISOLATED\": The default content scripts execution environment. This environment is isolated from the page's context: while they share the same document, the global scopes and available APIs differ.<br>\"MAIN\": The web page's execution environment. This environment is shared with the web page without isolation. Scripts in this environment don't have any access to the APIs that are only available to content scripts.<br><br>Warning: Due to the lack of isolation, the web page can detect and interfere with the executed code. Do not use the MAIN world unless it is acceptable for web pages to read, access, or modify the logic or data that flows through the executed code. world, and therefore \"MAIN\", is not supported in Firefox (although it is planned, and the work to introduce it is tracked by Bug 1736575). In the meantime, JavaScript code running in the isolated content script sandbox can use the Firefox \"Xray vision\" feature, as described in Share objects with page scripts.",
            "type": "string",
            "enum": ["ISOLATED", "MAIN"]
          }
        }
      }
    },
    "content_security_policy": {
      "description": "Extensions have a content security policy (CSP) applied to them by default. The default policy restricts the sources from which extensions can load code (such as <script> resources) and disallows potentially unsafe practices such as the use of eval().<br>You can use this key to loosen or tighten the default policy. This key is specified in the same way as the Content-Security-Policy HTTP header.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy",
      "type": "string",
      "default": "default-src 'self'"
    },
    "declarative_net_request": {
      "title": "declarative net request rulesets",
      "description": "Specify static rulesets for use with declarativeNetRequest.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/declarative_net_request",
      "type": "object",
      "additionalProperties": false,
      "required": ["rule_resources"],
      "properties": {
        "rule_resources": {
          "description": "An array of rulesets",
          "type": "array",
          "uniqueItems": true,
          "items": {
            "title": "ruleset",
            "description": "Definition of a ruleset",
            "type": "object",
            "additionalProperties": false,
            "required": ["id", "enabled", "path"],
            "properties": {
              "id": {
                "description": "A non-empty string uniquely identifying the ruleset. IDs beginning with '_' are reserved for internal use.",
                "type": "string",
                "pattern": ".+"
              },
              "enabled": {
                "description": "Whether the ruleset is enabled by default. The declarativeNetRequest.updateEnabledRulesets method can be used to enable or disable a ruleset at runtime.",
                "type": "boolean"
              },
              "path": {
                "description": "The path of the JSON ruleset relative to the extension directory. See the Rules section of the declarativeNetRequest API for information on the content of the ruleset JSON file.",
                "type": "string",
                "format": "uri-reference"
              }
            }
          }
        }
      }
    },
    "default_locale": {
      "description": "This key must be present if the extension contains the _locales directory, and must be absent otherwise. It identifies a subdirectory of _locales, and this subdirectory will be used to find the default strings for your extension.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale",
      "type": "string",
      "default": "en"
    },
    "description": {
      "description": "A short description of the extension, intended for display in the browser's user interface. In Firefox and Chrome this value can be up to 132 characters. The limit in other browsers may differ.<br>This is a localizable property.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/description",
      "type": "string"
    },
    "developer": {
      "title": "developer information",
      "description": "The name of the extension's developer and their homepage URL, intended for display in the browser's user interface.<br>This object only allows for a single developer name and URL to be specified.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/developer",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "name": {
          "description": "Overrides the `author` key",
          "type": "string"
        },
        "url": {
          "description": "Overrides the `homepage_url` key",
          "type": "string",
          "format": "uri"
        }
      }
    },
    "devtools_page": {
      "description": "Use this key to enable your extension to extend the browser's built-in devtools.<br>This key is defined as a URL to an HTML file. The HTML file must be bundled with the extension, and the URL is relative to the extension's root.<br>The use of this manifest key triggers an install-time permission warning about devtools. To avoid an install-time permission warning, mark the feature as optional by listing the \"devtools\" permission in the optional_permissions manifest key.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/devtools_page",
      "type": "string",
      "format": "uri-reference"
    },
    "dictionaries": {
      "title": "localization",
      "description": "The dictionaries key specifies the locale_code for which your extension supplies a dictionary (like `en-US`).<br>If you use the dictionaries key, you must also set an ID for your extension using the browser_specific_settings manifest.json key.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/dictionaries",
      "type": "object",
      "additionalProperties": false,
      "propertyNames": {
        "description": "Although the dictionary consists of two files, one with a .dic and one with an .aff file extension, only the one with the .dic extension is referenced. The reference is relative to the manifest.json",
        "type": "string",
        "format": "uri-reference"
      }
    },
    "externally_connectable": {
      "title": "external extension API",
      "description": "Externally connectable controls which other extensions and web pages can communicate with an extension using runtime.connect() and runtime.sendMessage() message passing. If externally_connectable is not specified, all extensions can communicate with each other but not with web pages.<br><br>Note: For communication with web pages:<br>In Chrome, chrome.runtime.connect and chrome.runtime.sendMessage are used. These methods are only available when there is at least one extension listening for messages, see chrome.runtime will no longer be defined unconditionally in Chrome 106 for more details.<br>In Safari, browser.runtime.connect and browser.runtime.sendMessage are used.<br>In Firefox, neither API is supported. See Firefox bug 1319168.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/externally_connectable",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "ids": {
          "description": "Enables communication between this extension and other installed extensions specified by extension identifiers. Use the pattern \"*\" to communicate with all extensions.",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "matches": {
          "description": "A list of regular expressions that enables communication between an extension and the web pages that match the expression.<br><br>Note: If `externally_connectable` is not specified, communication among extensions is allowed as if `externally_connectable` specified `{\"ids\": [\"*\"] }`. Therefore, if you specify `externally_connectable.matches`, don't forget to add `ids` if you want to communicate with other extensions.",
          "type": "array",
          "items": {
            "type": "string",
            "format": "regex"
          }
        }
      }
    },
    "homepage_url": {
      "description": "URL for the extension's home page.<br>If a developer key containing the \"url\" property and \"homepage_url\" are defined, Firefox uses \"developer.url\" while Opera uses \"homepage_url\". Chrome and Safari do not support the \"developer\" key.<br>This is a localizable property.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url",
      "type": "string",
      "format": "uri"
    },
    "icons": {
      "description": "The icons key specifies icons for your extension. Those icons will be used to represent the extension in components such as the Add-ons Manager.<br>It consists of key-value pairs of image size in px and image path relative to the root directory of the extension.<br>If icons is not supplied, a standard extension icon will be used by default.<br>You should supply at least a main extension icon, ideally 48x48 px in size. This is the default icon that will be used in the Add-ons Manager.<br>You can use SVG and the browser will scale your icon appropriately. There are currently two caveats though.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons",
      "additionalProperties": false,
      "patternProperties": {
        "^[1-9]\\d*$": {
          "type": "string"
        }
      }
    },
    "incognito": {
      "description": "Use the incognito key to control how the extension works with private browsing windows.<br><br>Note: By default, extensions do not run in private browsing windows. Whether an extension can access private browsing windows is under user control. For details, see Extensions in Private Browsing. Your extension can check whether it can access private browsing windows using extension.isAllowedIncognitoAccess.<br><br>This is a string that can take any of these values:<br>\"spanning\" (the default): the extension will see events from private and non-private windows and tabs. Windows and tabs will get an incognito property in the `Window` or `Tab` that represents them. This property indicates whether or not the object is private<br>\"split\": the extension will be split between private and non-private windows. There are effectively two copies of the extension running: one sees only non-private windows, the other sees only private windows. Each copy has isolated access to Web APIs (so, for example, localStorage is not shared). However, the WebExtension API storage.local is shared. (Note: this setting is not supported by Firefox.)<br>\"not_allowed\": private tabs and windows are invisible to the extension.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/incognito",
      "type": "string",
      "enum": ["spanning", "split", "not_allowed"],
      "default": "spanning"
    },
    "manifest_version": {
      "description": "This key specifies the version of manifest.json used by this extension.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version",
      "type": "integer",
      "enum": [2, 3]
    },
    "name": {
      "description": "Name of the extension. This is used to identify the extension in the browser's user interface and on sites like addons.mozilla.org.<br>It's good practice to keep the name short enough to display in the UI. Also, the length of the name of a published extension may be limited.<br>These restrictions do not apply to self-hosted extensions or extensions distributed outside the stores.<br>This is a localizable property.<br><br>https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/name",
      "type": "string"
    },
    "offline_enabled": {
      "description": "Whether the app or extension is expected to work offline. When Chrome detects that it is offline, apps with this field set to true will be highlighted on the New Tab page.\n\nAs of Chrome 35, apps (ChromeOS only from 2018) are assumed to be offline enabled and the default value of \"offline_enabled\" is true unless \"webview\" permission is requested. In this case, network connectivity is assumed to be required and \"offline_enabled\" defaults to false.\n\nThe \"offline_enabled\" value is also used to determine whether a network connectivity check will be performed when launching an app in ChromeOS kiosk mode. A network connectivity check will be performed when apps are not offline enabled, and app launching put on hold until the device obtains connectivity to the Internet. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/offline_enabled",
      "type": "boolean",
      "default": true
    },
    "omnibox": {
      "title": "keywords",
      "description": "Use the omnibox key to define an omnibox keyword for your extension.\n\nWhen the user types this keyword into the browser's address bar, followed by a space, then any subsequent characters will be sent to the extension using the omnibox API. The extension will then be able to populate the address bar's drop-down suggestions list with its own suggestions.\n\nIf two or more extensions define the same keyword, then the extension that was installed last gets to control the keyword. Any previously installed extensions that defined the same keyword will no longer be able to use the omnibox API.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/omnibox",
      "type": "object",
      "additionalProperties": false,
      "required": ["keyword"],
      "properties": {
        "keyword": {
          "description": "The keyword that will trigger your extension.",
          "type": "string"
        }
      }
    },
    "optional_permissions": {
      "description": "Use the optional_permissions key to list permissions which you want to ask for at runtime, after your add-on has been installed.\nThe key can contain two kinds of permissions: host permissions and API permissions.\nNot all permissions are compatible with all browsers\nSome are granted silently, without user prompt\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "activeTab",
              "background",
              "bookmarks",
              "browserSettings",
              "browsingData",
              "clipboardRead",
              "clipboardWrite",
              "contentSettings",
              "contextMenus",
              "cookies",
              "debugger",
              "declarativeNetRequest",
              "declarativeNetRequestFeedback",
              "declarativeNetRequestWithHostAccess",
              "devtools",
              "downloads",
              "downloads.open",
              "find",
              "geolocation",
              "history",
              "idle",
              "management",
              "nativeMessaging",
              "notifications",
              "pageCapture",
              "pkcs11",
              "privacy",
              "proxy",
              "scripting",
              "search",
              "sessions",
              "tabHide",
              "tabs",
              "topSites",
              "webNavigation",
              "webRequest",
              "webRequestBlocking",
              "webRequestFilterResponse",
              "webRequestFilterResponse.serviceWorkerScript"
            ]
          }
        ]
      }
    },
    "options_page": {
      "description": "Use the options_page key to define an options page for your extension.\n\nThe options page contains settings for the extension. The user can access it from the browser's add-ons manager, and you can open it from within your extension using runtime.openOptionsPage().\n\nUnlike options pages specified using the newer options_ui key, options pages specified using the deprecated options_page key don't receive browser styles and always open in a normal browser tab.\n\nWARNING: This manifest key has been deprecated. Use `options_ui` instead.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_page#browser_compatibility",
      "type": "string",
      "format": "uri-reference"
    },
    "options_ui": {
      "title": "options page",
      "description": "Use the options_ui key to define an options page for your extension.\n\nThe options page contains settings for the extension. The user can access it from the browser's add-ons manager, and you can open it from within your extension using runtime.openOptionsPage().\n\nYou specify options_ui as a path to an HTML file packaged with your extension. The HTML file can include CSS and JavaScript files, just like a normal web page. Unlike a normal page, though, the JavaScript can use all the WebExtension APIs that the extension has permissions for. However, it runs in a different scope than your background scripts.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/options_ui",
      "type": "object",
      "additionalProperties": false,
      "required": ["page"],
      "properties": {
        "page": {
          "description": "The path to an HTML file containing the specification of your options page.\n\nThe path is relative to the location of manifest.json itself.",
          "type": "string",
          "format": "uri-reference"
        },
        "browser_style": {
          "$ref": "#/definitions/browser_style"
        },
        "open_in_tab": {
          "default": false,
          "type": "boolean",
          "description": "If true, the options page will open in a normal browser tab, rather than being integrated into the browser's add-ons manager."
        }
      }
    },
    "page_action": {
      "$ref": "#/definitions/common_action",
      "title": "Page popup",
      "description": "A page action is an icon that your extension adds inside the browser's URL bar.\n\nYour extension may optionally also supply an associated popup whose content is specified using HTML, CSS, and JavaScript.\n\nIf you supply a popup, then the popup is opened when the user clicks the icon, and your JavaScript running in the popup can handle the user's interaction with it. If you don't supply a popup, then a click event is dispatched to your extension's background scripts when the user clicks the icon.\n\nPage actions are like browser actions, except that they are associated with particular web pages rather than with the browser as a whole. If an action is only relevant on certain pages, then you should use a page action and display it only on relevant pages. If an action is relevant to all pages or to the browser itself, use a browser action.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/page_action",
      "type": "object",
      "properties": {
        "hide_matches": {
          "type": "array",
          "description": "Hide the page action by default for pages whose URLs match any of the given match patterns.\n\nNote that page actions are always hidden by default unless show_matches is given. Therefore, it only makes sense to include this property if show_matches is also given, and will override the patterns in show_matches.",
          "items": {
            "$ref": "#/definitions/match_pattern_strict"
          }
        },
        "show_matches": {
          "description": "Show the page action by default for pages whose URLs match any of the given patterns.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/match_pattern"
          }
        },
        "pinned": {
          "type": "boolean",
          "description": "Controls whether or not the page action should appear in the location bar by default when the user installs the extension.",
          "default": true
        }
      }
    },
    "permissions": {
      "description": "Use the permissions key to request special powers for your extension. This key is an array of strings, and each string is a request for a permission.\n\nIf you request permissions using this key, then the browser may inform the user at install time that the extension is requesting certain privileges, and ask them to confirm that they are happy to grant these privileges.\n\nThe key can contain three kinds of permissions:\n - host permissions: Specified as match patterns, and each pattern identifies a group of URLs for which the extension is requesting extra privileges. For example, a host permission could be \"*://developer.mozilla.org/*\".\n- API permissions: Specified as keywords, and each keyword names a WebExtension API that the extension would like to use.\n- activeTab: This permission is specified as \"activeTab\". If an extension has the activeTab permission, then when the user interacts with the extension, the extension is granted extra privileges for the active tab only.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions",
      "type": "array",
      "uniqueItems": true,
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "enum": [
              "<all_urls>",
              "activeTab",
              "alarms",
              "background",
              "bookmarks",
              "browserSettings",
              "browsingData",
              "captivePortal",
              "clipboardRead",
              "clipboardWrite",
              "contentSettings",
              "contextMenus",
              "contextualIdentities",
              "cookies",
              "debugger",
              "declarativeNetRequest",
              "declarativeNetRequestFeedback",
              "declarativeNetRequestWithHostAccess",
              "devtools ",
              "dns",
              "downloads",
              "downloads.open",
              "find",
              "geolocation",
              "history",
              "identity",
              "idle",
              "management",
              "menus",
              "menus.overrideContext",
              "nativeMessaging",
              "notifications",
              "pageCapture",
              "pkcs11",
              "privacy",
              "proxy",
              "scripting",
              "search",
              "sessions",
              "storage",
              "tabHide",
              "tabs",
              "theme",
              "topSites",
              "unlimitedStorage",
              "webNavigation",
              "webRequest",
              "webRequestBlocking",
              "webRequestFilterResponse",
              "webRequestFilterResponse.serviceWorkerScript"
            ]
          }
        ]
      }
    },
    "protocol_handlers": {
      "description": "Use this key to register one or more web-based protocol handlers.\n\nA protocol handler is an application that knows how to handle particular types of links: for example, a mail client is a protocol handler for \"mailto:\" links. When the user clicks a \"mailto:\" link, the browser opens the application selected as the handler for the \"mailto:\" protocol (or offers them a choice of handlers, depending on their settings).\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/protocol_handlers",
      "type": "array",
      "items": {
        "title": "protocol handler",
        "description": "A protocol handler specification",
        "type": "object",
        "additionalProperties": false,
        "required": ["protocol", "name", "uriTemplate"],
        "properties": {
          "protocol": {
            "description": "A string defining the protocol. It can either be one of the predefined protocols, or a custom name prefixed with \"web+\" or \"ext+\". For example: \"web+foo\" or \"ext+foo\". The custom name must consist only of lower-case ASCII characters. It's recommended that extensions use the \"ext+\" form.",
            "anyOf": [
              {
                "description": "A custom-named protocol. These MUST be prefixed with 'web+' or 'ext+', followed by a string consisting of only lower-case ASCII characters.",
                "type": "string",
                "pattern": "^(ext|web)\\+[a-z]+"
              },
              {
                "description": "A pre-existing protocol allowed for use with WebExtensions.",
                "enum": [
                  "bitcoin",
                  "dat",
                  "dweb",
                  "ftp",
                  "geo",
                  "gopher",
                  "im",
                  "ipfs",
                  "ipns",
                  "irc",
                  "ircs",
                  "magnet",
                  "mailto",
                  "matrix",
                  "mms",
                  "news",
                  "nntp",
                  "sip",
                  "sms",
                  "smsto",
                  "ssb",
                  "ssh",
                  "tel",
                  "urn",
                  "webcal",
                  "wtai",
                  "xmpp"
                ]
              }
            ]
          },
          "name": {
            "description": "A string representing the name of the protocol handler. This will be displayed to the user when they are being asked if they want this handler to open the link.",
            "type": "string"
          },
          "uriTemplate": {
            "description": "A string representing the URL of the handler. This string must include \"%s\" as a placeholder: this will be replaced with the escaped URL of the document to be handled. This URL might be a true URL, or it could be a phone number, email address, or so forth. This is a localizable property.",
            "pattern": "%s"
          }
        }
      }
    },
    "short_name": {
      "description": "Short name for the extension. If given, this will be used in contexts where the name field is too long. It's recommended that the short name should not exceed 12 characters. If the short name field is not included in manifest.json, then name will be used instead and may be truncated.\n\nThis is a localizable property.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/short_name",
      "type": "string"
    },
    "sidebar_action": {
      "title": "sidebar page",
      "description": "A sidebar is a pane that is displayed at the left-hand side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/sidebar_action",
      "type": "object",
      "additionalProperties": false,
      "required": ["default_panel"],
      "properties": {
        "default_icon": {
          "$ref": "#/definitions/icon"
        },
        "default_panel": {
          "description": "The path to an HTML file that specifies the sidebar's contents.\n\nUnlike a normal web page, JavaScript running in the panel can access all the WebExtension APIs (subject, of course, to the extension having the appropriate permissions).\n\nThis is a localizable property.",
          "type": "string"
        },
        "default_title": {
          "description": " Title for the sidebar. This is used in the browser UI for listing and opening sidebars, and is displayed at the top of the sidebar when it is open.\n\nThis property is optional: if it is omitted, the sidebar's title is the extension's name.\n\nThis is a localizable property.",
          "type": "string"
        },
        "open_at_install": {
          "description": "Determines whether the sidebar should open on install. The default behavior is to open the sidebar when installation is completed.",
          "type": "boolean",
          "default": true
        },
        "browser_style": {
          "$ref": "#/definitions/browser_style"
        }
      }
    },
    "storage": {
      "title": "storage policies",
      "description": "Use the storage key to specify the name of the schema file that defines the structure of data in managed storage.\n\nManaged data declares the enterprise policies supported by the app. Policies are analogous to options but are configured by a system administrator instead of the user, enabling the app to be configured for all users of an organization.\n\nAfter declaring the policies, they are read from the storage.managed API. However, if a policy value does not conform to the schema, then it is not published by the storage.managed API. It's up to the app to enforce the policies configured by the administrator.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/storage",
      "type": "object",
      "additionalProperties": false,
      "required": ["managed_schema"],
      "properties": {
        "managed_schema": {
          "description": "The full path of the file within the extension that defines the schema of the manage storage.",
          "type": "string",
          "format": "uri-reference"
        }
      }
    },
    "theme": {
      "title": "theme",
      "description": "Use the theme key to define a static theme to apply to Firefox.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/theme",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "images": {
          "title": "images",
          "description": "Represents the images to display in various parts of the browser.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "theme_frame": {
              "description": "The URL of a foreground image to be added to the header area and anchored to the upper right corner of the header area.",
              "type": "string"
            },
            "additional_backgrounds": {
              "description": "An array of URLs for additional background images to be added to the header area and displayed behind the \"theme_frame\": image. These images layer the first image in the array on top, the last image in the array at the bottom.",
              "type": "array",
              "items": {
                "description": "URL for an additional background image",
                "type": "string",
                "format": "uri-reference"
              }
            }
          }
        },
        "colors": {
          "title": "colors",
          "description": "Represents the colors of various parts of the browser.\n\nThese properties define the colors used for different parts of the browser. How these properties affect the Firefox UI can be seen at https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/theme#colors.\n\nAll these properties can be specified as either a string containing any valid CSS color string including hexadecimal (see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value), or an RGB array\n\nNote: Where a component is affected by multiple color properties, the properties are listed in order of precedence.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "bookmark_text": {
              "$ref": "#/definitions/color",
              "description": "The color of text and icons in the bookmark and find bars. Also, if tab_text isn't defined it sets the color of the active tab text and if icons isn't defined the color of the toolbar icons. Provided as Chrome compatible alias for toolbar_text."
            },
            "button_background_active": {
              "$ref": "#/definitions/color",
              "description": "The color of the background of the pressed toolbar buttons."
            },
            "button_background_hover": {
              "$ref": "#/definitions/color",
              "description": "The color of the background of the toolbar buttons on hover."
            },
            "icons": {
              "$ref": "#/definitions/color",
              "description": "The color of toolbar icons, excluding those in the find toolbar."
            },
            "icons_attention": {
              "$ref": "#/definitions/color",
              "description": "The color of toolbar icons in attention state such as the starred bookmark icon or finished download icon."
            },
            "frame": {
              "$ref": "#/definitions/color",
              "description": "The color of the header area background, displayed in the part of the header not covered or visible through the images specified in \"theme_frame\" and \"additional_backgrounds\"."
            },
            "frame_inactive": {
              "$ref": "#/definitions/color",
              "description": "The color of the header area background when the browser window is inactive, displayed in the part of the header not covered or visible through the images specified in \"theme_frame\" and \"additional_backgrounds\"."
            },
            "ntp_background": {
              "$ref": "#/definitions/color",
              "description": "The new tab page background color."
            },
            "ntp_card_background": {
              "$ref": "#/definitions/color",
              "description": "The new tab page card background color."
            },
            "ntp_text": {
              "$ref": "#/definitions/color",
              "description": "The new tab page text color."
            },
            "popup": {
              "$ref": "#/definitions/color",
              "description": "The background color of popups (such as the URL bar dropdown and the arrow panels)."
            },
            "popup_border": {
              "$ref": "#/definitions/color",
              "description": "The border color of popups."
            },
            "popup_highlight": {
              "$ref": "#/definitions/color",
              "description": "The background color of items highlighted using the keyboard inside popups (such as the selected URL bar dropdown item)."
            },
            "popup_highlight_text": {
              "$ref": "#/definitions/color",
              "description": "The text color of items highlighted inside popups."
            },
            "popup_text": {
              "$ref": "#/definitions/color",
              "description": "The text color of popups."
            },
            "sidebar": {
              "$ref": "#/definitions/color",
              "description": "The background color of the sidebar."
            },
            "sidebar_border": {
              "$ref": "#/definitions/color",
              "description": "The border and splitter color of the browser sidebar"
            },
            "sidebar_highlight": {
              "$ref": "#/definitions/color",
              "description": "The background color of highlighted rows in built-in sidebars"
            },
            "sidebar_highlight_text": {
              "$ref": "#/definitions/color",
              "description": "The text color of highlighted rows in sidebars."
            },
            "sidebar_text": {
              "$ref": "#/definitions/color",
              "description": "The text color of sidebars."
            },
            "tab_background_separator": {
              "$ref": "#/definitions/color",
              "description": "The color of the vertical separator of the background tabs.\n\nDEPRECATED"
            },
            "tab_background_text": {
              "$ref": "#/definitions/color",
              "description": "The color of the text displayed in the inactive page tabs. If tab_text or bookmark_text isn't specified, applies to the active tab text."
            },
            "tab_line": {
              "$ref": "#/definitions/color",
              "description": "The color of the selected tab line."
            },
            "tab_loading": {
              "$ref": "#/definitions/color",
              "description": "The color of the tab loading indicator and the tab loading burst."
            },
            "tab_selected": {
              "$ref": "#/definitions/color",
              "description": "The background color of the selected tab. When not in use selected tab color is set by frame and the frame_inactive."
            },
            "tab_text": {
              "$ref": "#/definitions/color",
              "description": "Represents the text color for the selected tab. If tab_line isn't specified, it also defines the color of the selected tab line."
            },
            "toolbar": {
              "$ref": "#/definitions/color",
              "description": "The background color for the navigation bar, the bookmarks bar, and the selected tab.\n\nThis also sets the background color of the \"Find\" bar."
            },
            "toolbar_bottom_separator": {
              "$ref": "#/definitions/color",
              "description": "The color of the line separating the bottom of the toolbar from the region below."
            },
            "toolbar_field": {
              "$ref": "#/definitions/color",
              "description": "The background color for fields in the toolbar, such as the URL bar.\n\nThis also sets the background color of the Find in page field. "
            },
            "toolbar_field_border": {
              "$ref": "#/definitions/color",
              "description": "The border color for fields in the toolbar.\n\nThis also sets the border color of the Find in page field. "
            },
            "toolbar_field_border_focus": {
              "$ref": "#/definitions/color",
              "description": "The focused border color for fields in the toolbar."
            },
            "toolbar_field_focus": {
              "$ref": "#/definitions/color",
              "description": "The focused background color for fields in the toolbar, such as the URL bar."
            },
            "toolbar_field_highlight": {
              "$ref": "#/definitions/color",
              "description": "The background color used to indicate the current selection of text in the URL bar (and the search bar, if it's configured to be separate)."
            },
            "toolbar_field_highlight_text": {
              "$ref": "#/definitions/color",
              "description": "The color used to draw text that's currently selected in the URL bar (and the search bar, if it's configured to be separate box)."
            },
            "toolbar_field_separator": {
              "$ref": "#/definitions/color",
              "description": "The color of separators inside the URL bar. In Firefox 58 this was implemented as toolbar_vertical_separator.\n\nDEPRECATED"
            },
            "toolbar_field_text": {
              "$ref": "#/definitions/color",
              "description": "The color of text in fields in the toolbar, such as the URL bar. This also sets the color of text in the Find in page field."
            },
            "toolbar_field_text_focus": {
              "$ref": "#/definitions/color",
              "description": "The color of text in focused fields in the toolbar, such as the URL bar."
            },
            "toolbar_text": {
              "$ref": "#/definitions/color",
              "description": "The color of toolbar text. This also sets the color of text in the \"Find\" bar."
            },
            "toolbar_top_separator": {
              "$ref": "#/definitions/color",
              "description": "The color of the line separating the top of the toolbar from the region above."
            },
            "toolbar_vertical_separator": {
              "$ref": "#/definitions/color",
              "description": "The color of the separator in the bookmarks toolbar."
            }
          }
        },
        "properties": {
          "title": "properties",
          "description": "Affects how the \"additional_backgrounds\" images are displayed and color schemes are applied.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "additional_backgrounds_alignment": {
              "description": "An array of enumeration values defining the alignment of the corresponding \"additional_backgrounds\": array item.",
              "type": "array",
              "items": {
                "type": "string",
                "default": "right top",
                "enum": [
                  "bottom",
                  "center",
                  "left",
                  "right",
                  "top",
                  "center bottom",
                  "center center",
                  "center top",
                  "left bottom",
                  "left center",
                  "left top",
                  "right bottom",
                  "right center",
                  "right top"
                ]
              }
            },
            "additional_backgrounds_tiling": {
              "description": "Defines how the corresponding \"additional_backgrounds\": array item repeats.",
              "type": "array",
              "items": {
                "type": "string",
                "default": "no-repeat",
                "enum": ["no-repeat", "repeat", "repeat-x", "repeat-y"]
              }
            },
            "color_scheme": {
              "description": "Determines which color scheme is applied to the chrome (for example, context menus) and content (for example, built-in pages and the preferred color scheme for web pages).",
              "type": "array",
              "items": {
                "type": "string",
                "default": "auto",
                "enum": ["auto", "light", "dark", "system"]
              }
            },
            "content_color_scheme": {
              "description": "Determines which color scheme is applied to the content (for example, built-in pages and preferred color scheme for web pages). Overrides color_scheme.",
              "type": "array",
              "items": {
                "type": "string",
                "default": "auto",
                "enum": ["auto", "light", "dark", "system"]
              }
            }
          }
        }
      }
    },
    "user_scripts": {
      "title": "user scripts",
      "description": "Instructs the browser to load a script packaged in the extension, known as the API script, this script is used to export a set of custom API methods for use in user scripts.\n\nNote: The user_script key is required for the userScripts API to function, even if no API script is specified.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/user_scripts",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "api_script": {
          "description": "The API script:\n- runs in the content processes.\n- has access to the window and document globals related to the webpage it is attached to.\n- has access to the same subset of WebExtension APIs usually available in a content script.\n\nThe script executes automatically on any webpage defined in matches by userScripts.register. However, this is before the user script sandbox object is created and the custom API methods can be exported.\n\nTo export the custom API methods, the script listens for userScripts.onBeforeScript and then export the custom API methods.\n\nNot every user script may need to consume all of the custom API methods. You can, therefore, include details of the APIs needed in scriptMetadata when running userScripts.register. The API script then accesses the scriptMetadata through the script parameter received by the userScripts.onBeforeScript listener (as script.metadata).",
          "type": "string",
          "format": "uri-reference"
        }
      }
    },
    "version": {
      "description": "The version string for the extension.\n\nThe version string consists of 1 to 4 numbers separated by dots, for example, 1.2.3.4. Non-zero numbers must not include a leading zero.\n\nExtension stores and browsers may enforce or warn if the version string doesn't comply with this format. They may also apply restrictions to the range of numbers available.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version",
      "type": "string",
      "pattern": "^(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*)){0,3}$"
    },
    "version_name": {
      "description": "In addition to the version field, which is used for update purposes, version_name can be set to a descriptive version string and will be used for display purposes if present.\n\nIf no version_name is present, the version field will be used for display purposes as well.https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version_name",
      "type": "string"
    },
    "web_accessible_resources": {
      "$ref": "#/definitions/scripts",
      "description": "Sometimes you want to package resources—for example, images, HTML, CSS, or JavaScript—with your extension and make them available to web pages and other extensions.\n\nWith the web_accessible_resources key, you list all the packaged resources that you want to make available to web pages. You specify them as paths relative to the manifest.json file.\n\nNote that content scripts don't need to be listed as web accessible resources.\n\nIf an extension wants to use webRequest or declarativeNetRequest to redirect a public URL (e.g., HTTPS) to a page that's packaged in the extension, then the extension must list the page in the web_accessible_resources key.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources"
    }
  },
  "definitions": {
    "action": {
      "$ref": "#/definitions/common_action",
      "title": "extension button",
      "type": "object",
      "properties": {
        "default_area": {
          "description": "Defines the part of the browser in which the button is initially placed.\n\nThis property is only supported in Firefox.",
          "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"],
          "default": "menupanel"
        },
        "theme_icons": {
          "description": "This property enables you to specify different icons for themes depending on whether Firefox detects that the theme uses dark or light text.",
          "type": "array",
          "items": {
            "title": "theme icon",
            "type": "object",
            "additionalProperties": false,
            "required": ["dark", "light", "size"],
            "properties": {
              "dark": {
                "description": "A URL pointing to an icon. This icon displays when a theme using dark text is active (such as the Firefox Light theme, and the Default theme if no default_icon is specified).\n\nIcons are specified as URLs relative to the manifest.json file.",
                "type": "string",
                "format": "uri-reference"
              },
              "light": {
                "description": "A URL pointing to an icon. This icon displays when a theme using light text is active (such as the Firefox Dark theme).\n\nIcons are specified as URLs relative to the manifest.json file.",
                "type": "string",
                "format": "uri-reference"
              },
              "size": {
                "description": "The size of the two icons in pixels.",
                "type": "integer",
                "enum": [16, 32]
              }
            }
          }
        }
      }
    },
    "browser_style": {
      "deprecated": true,
      "description": "Do not set browser_style to true: its not support in Manifest V3 from Firefox 118. See Manifest V3 migration for browser_style.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_styles#manifest_v3_migration"
    },
    "color": {
      "oneOf": [
        {
          "description": "CSS color string.\n\nhttps://developer.mozilla.org/en-US/docs/Web/CSS/color_value",
          "type": "string"
        },
        {
          "description": "RGB array",
          "type": "array",
          "minItems": 3,
          "maxItems": 3,
          "items": {
            "description": "RGB color component",
            "type": "integer",
            "minimum": 0,
            "maximum": 255
          }
        }
      ]
    },
    "command": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "description": {
          "description": "A description of the shortcut; i.e. what it does",
          "type": "string"
        },
        "suggested_key": {
          "description": "The value of each property is the keyboard shortcut for the command on that platform, as a string containing keys separated by \"+\". The value for \"default\" is used on all platforms that are not explicitly listed.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "default": {
              "$ref": "#/definitions/command_shortcut"
            },
            "mac": {
              "$ref": "#/definitions/command_shortcut"
            },
            "linux": {
              "$ref": "#/definitions/command_shortcut"
            },
            "windows": {
              "$ref": "#/definitions/command_shortcut"
            },
            "chromeos": {
              "$ref": "#/definitions/command_shortcut"
            },
            "android": {
              "$ref": "#/definitions/command_shortcut"
            },
            "ios": {
              "$ref": "#/definitions/command_shortcut"
            }
          }
        }
      }
    },
    "command_shortcut": {
      "$comment": "The two modifiers cannot be the same, but that is not validated due to it being inherently obvious and for the sake of the readability of the regex",
      "description": "There are two valid formats for shortcut keys: as a key combination or as a media key.\n\nKey combinations must consist of 2 or 3 keys (<modifier>+[<secondary_modifier>]+<key>), e.g.: \"Ctrl+Shift+Z\"\n\nIf a key combination is already used by the browser (like \"Ctrl+P\") or by an existing add-on, then you can't override it. You can define it, but your event handler will not be called when the user presses the key combination.\n\nhttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/commands#shortcut_values",
      "type": "string",
      "pattern": "^(MediaNextTrack|MediaPlayPause|MediaPrevTrack|MediaStop|F(\\d|1[0-2])|((Ctrl|Alt|Command|MacCtrl)\\+((Shift|Ctrl|Alt|Command|MacCtrl)\\+)?(Comma|Period|Home|End|PageUp|PageDown|Space|Insert|Delete|Up|Down|Left|Right|[A-Z0-9]|F(\\d|1[0-2]|))))$"
    },
    "common_action": {
      "properties": {
        "default_icon": {
          "$ref": "#/definitions/icon",
          "description": " Use this to specify one or more icons for the browser action. The icon is shown in the browser toolbar by default.\n\nIcons are specified as URLs relative to the manifest.json file itself.\n\nYou can specify a single icon file by supplying a string here\n\nTo specify multiple icons in different sizes, specify an object here. The name of each property is the icon's height in pixels, and must be convertible to an integer. The value is the URL."
        },
        "default_popup": {
          "description": "The path to an HTML file containing the specification of the popup.\n\nThe HTML file may include CSS and JavaScript files using <link> and <script> elements, just like a normal web page. However, <script> must have src attribute to load a file. Don't use <script> with embedded code, because you'll get a confusing Content Violation Policy error.\n\nUnlike a normal web page, JavaScript running in the popup can access all the WebExtension APIs (subject, of course, to the extension having the appropriate permissions).\n\nThis is a localizable property.",
          "type": "string",
          "format": "uri-reference"
        },
        "default_title": {
          "description": "Tooltip for the button, displayed when the user moves their mouse over it. If the button is added to the browser's menu panel, this is also shown under the app icon.\n\nThis is a localizable property.",
          "type": "string"
        },
        "browser_style": {
          "$ref": "#/definitions/browser_style"
        }
      }
    },
    "gecko_version_support": {
      "properties": {
        "strict_min_version": {
          "description": "Minimum version of Gecko to support. If the Browser version on which the extension is being installed or run is below this version, the extension is not installed or not run. If not provided, all versions earlier than strict_max_version are supported. \"*\" is not valid in this field.\n\nSee the list of valid Gecko versions: https://addons.mozilla.org/api/v5/applications/firefox/",
          "type": "string",
          "default": "42a1"
        },
        "strict_max_version": {
          "description": "Maximum version of Gecko to support. If the Browser version on which the extension is being installed or run is above this version, the extension is not installed or not run. Defaults to \"*\", which disables checking for a maximum version.\n\nSee the list of valid Gecko versions: https://addons.mozilla.org/api/v5/applications/firefox/",
          "type": "string",
          "default": "*"
        }
      }
    },
    "glob_pattern": {
      "type": "string"
    },
    "icon": {
      "type": ["string", "object"],
      "additionalProperties": false,
      "patternProperties": {
        "^[1-9]\\d+$": {
          "type": "string",
          "format": "uri-reference"
        }
      },
      "format": "uri-reference"
    },
    "match_pattern": {
      "type": "string",
      "pattern": "^(<all_urls>|(\\*|http|https|ws|wss|ftp|data|file|ftp|(chrome-)?extension):\\/\\/(\\*|\\*\\.[^\\/\\*]+|[^\\/\\*]+)?(\\/.*))$"
    },
    "match_pattern_strict": {
      "type": "string",
      "pattern": "^(\\*|http|https|ws|wss|ftp|data|file|ftp|(chrome-)?extension):\\/\\/(\\*|\\*\\.[^\\/\\*]+|[^\\/\\*]+)?(\\/.*)$"
    },
    "scripts": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "format": "uri-reference"
      }
    }
  }
}
