{"version":3,"sources":["jsdelivr-header.js","webpack:///webpack/bootstrap","webpack:///node_modules/debug/src/browser.js","webpack:///node_modules/debug/src/common.js","webpack:///node_modules/debug/src/index.js","webpack:///node_modules/debug/src/node.js","webpack:///node_modules/has-flag/index.js","webpack:///node_modules/ms/index.js","webpack:///node_modules/supports-color/index.js","webpack:///src/browser/api/browser-action.ts","webpack:///src/browser/api/commands.ts","webpack:///src/browser/api/common.ts","webpack:///src/browser/api/context-menus.ts","webpack:///src/browser/api/cookies.ts","webpack:///src/browser/api/notifications.ts","webpack:///src/browser/api/runtime.ts","webpack:///src/browser/api/tabs.ts","webpack:///src/browser/api/web-navigation.ts","webpack:///src/browser/api/windows.ts","webpack:///src/browser/index.ts","webpack:///src/browser/popup.ts","webpack:///src/browser/router.ts","webpack:///src/browser/store.ts","webpack:///src/index.ts","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"electron\"","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"events\"","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"fs\"","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"os\"","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"path\"","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"tty\"","/npm/nestbrowser-chrome-extensions@1.0.4/dist/webpack:/external \"util\""],"names":[],"mappings":"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","file":"/npm/nestbrowser-chrome-extensions@1.0.4/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/nestbrowser-chrome-extensions@1.0.4/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/index.ts\");\n","/* eslint-env browser */\n\n/**\n * This is the web browser implementation of `debug()`.\n */\n\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.storage = localstorage();\nexports.destroy = (() => {\n\tlet warned = false;\n\n\treturn () => {\n\t\tif (!warned) {\n\t\t\twarned = true;\n\t\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t\t}\n\t};\n})();\n\n/**\n * Colors.\n */\n\nexports.colors = [\n\t'#0000CC',\n\t'#0000FF',\n\t'#0033CC',\n\t'#0033FF',\n\t'#0066CC',\n\t'#0066FF',\n\t'#0099CC',\n\t'#0099FF',\n\t'#00CC00',\n\t'#00CC33',\n\t'#00CC66',\n\t'#00CC99',\n\t'#00CCCC',\n\t'#00CCFF',\n\t'#3300CC',\n\t'#3300FF',\n\t'#3333CC',\n\t'#3333FF',\n\t'#3366CC',\n\t'#3366FF',\n\t'#3399CC',\n\t'#3399FF',\n\t'#33CC00',\n\t'#33CC33',\n\t'#33CC66',\n\t'#33CC99',\n\t'#33CCCC',\n\t'#33CCFF',\n\t'#6600CC',\n\t'#6600FF',\n\t'#6633CC',\n\t'#6633FF',\n\t'#66CC00',\n\t'#66CC33',\n\t'#9900CC',\n\t'#9900FF',\n\t'#9933CC',\n\t'#9933FF',\n\t'#99CC00',\n\t'#99CC33',\n\t'#CC0000',\n\t'#CC0033',\n\t'#CC0066',\n\t'#CC0099',\n\t'#CC00CC',\n\t'#CC00FF',\n\t'#CC3300',\n\t'#CC3333',\n\t'#CC3366',\n\t'#CC3399',\n\t'#CC33CC',\n\t'#CC33FF',\n\t'#CC6600',\n\t'#CC6633',\n\t'#CC9900',\n\t'#CC9933',\n\t'#CCCC00',\n\t'#CCCC33',\n\t'#FF0000',\n\t'#FF0033',\n\t'#FF0066',\n\t'#FF0099',\n\t'#FF00CC',\n\t'#FF00FF',\n\t'#FF3300',\n\t'#FF3333',\n\t'#FF3366',\n\t'#FF3399',\n\t'#FF33CC',\n\t'#FF33FF',\n\t'#FF6600',\n\t'#FF6633',\n\t'#FF9900',\n\t'#FF9933',\n\t'#FFCC00',\n\t'#FFCC33'\n];\n\n/**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n// eslint-disable-next-line complexity\nfunction useColors() {\n\t// NB: In an Electron preload script, document will be defined but not fully\n\t// initialized. Since we know we're in Chrome, we'll just detect this case\n\t// explicitly\n\tif (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {\n\t\treturn true;\n\t}\n\n\t// Internet Explorer and Edge do not support colors.\n\tif (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\\/(\\d+)/)) {\n\t\treturn false;\n\t}\n\n\t// Is webkit? http://stackoverflow.com/a/16459606/376773\n\t// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632\n\treturn (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||\n\t\t// Is firebug? http://stackoverflow.com/a/398120/376773\n\t\t(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||\n\t\t// Is firefox >= v31?\n\t\t// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||\n\t\t// Double check webkit in userAgent just in case we are in a worker\n\t\t(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\\/(\\d+)/));\n}\n\n/**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\targs[0] = (this.useColors ? '%c' : '') +\n\t\tthis.namespace +\n\t\t(this.useColors ? ' %c' : ' ') +\n\t\targs[0] +\n\t\t(this.useColors ? '%c ' : ' ') +\n\t\t'+' + module.exports.humanize(this.diff);\n\n\tif (!this.useColors) {\n\t\treturn;\n\t}\n\n\tconst c = 'color: ' + this.color;\n\targs.splice(1, 0, c, 'color: inherit');\n\n\t// The final \"%c\" is somewhat tricky, because there could be other\n\t// arguments passed either before or after the %c, so we need to\n\t// figure out the correct index to insert the CSS into\n\tlet index = 0;\n\tlet lastC = 0;\n\targs[0].replace(/%[a-zA-Z%]/g, match => {\n\t\tif (match === '%%') {\n\t\t\treturn;\n\t\t}\n\t\tindex++;\n\t\tif (match === '%c') {\n\t\t\t// We only are interested in the *last* %c\n\t\t\t// (the user may have provided their own)\n\t\t\tlastC = index;\n\t\t}\n\t});\n\n\targs.splice(lastC, 0, c);\n}\n\n/**\n * Invokes `console.debug()` when available.\n * No-op when `console.debug` is not a \"function\".\n * If `console.debug` is not available, falls back\n * to `console.log`.\n *\n * @api public\n */\nexports.log = console.debug || console.log || (() => {});\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\ttry {\n\t\tif (namespaces) {\n\t\t\texports.storage.setItem('debug', namespaces);\n\t\t} else {\n\t\t\texports.storage.removeItem('debug');\n\t\t}\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\nfunction load() {\n\tlet r;\n\ttry {\n\t\tr = exports.storage.getItem('debug');\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n\n\t// If debug isn't set in LS, and we're in Electron, try to load $DEBUG\n\tif (!r && typeof process !== 'undefined' && 'env' in process) {\n\t\tr = process.env.DEBUG;\n\t}\n\n\treturn r;\n}\n\n/**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\nfunction localstorage() {\n\ttry {\n\t\t// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context\n\t\t// The Browser also has localStorage in the global context.\n\t\treturn localStorage;\n\t} catch (error) {\n\t\t// Swallow\n\t\t// XXX (@Qix-) should we be logging these?\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\nformatters.j = function (v) {\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch (error) {\n\t\treturn '[UnexpectedJSONParseError]: ' + error.message;\n\t}\n};\n","\n/**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n */\n\nfunction setup(env) {\n\tcreateDebug.debug = createDebug;\n\tcreateDebug.default = createDebug;\n\tcreateDebug.coerce = coerce;\n\tcreateDebug.disable = disable;\n\tcreateDebug.enable = enable;\n\tcreateDebug.enabled = enabled;\n\tcreateDebug.humanize = require('ms');\n\tcreateDebug.destroy = destroy;\n\n\tObject.keys(env).forEach(key => {\n\t\tcreateDebug[key] = env[key];\n\t});\n\n\t/**\n\t* The currently active debug mode names, and names to skip.\n\t*/\n\n\tcreateDebug.names = [];\n\tcreateDebug.skips = [];\n\n\t/**\n\t* Map of special \"%n\" handling functions, for the debug \"format\" argument.\n\t*\n\t* Valid key names are a single, lower or upper-case letter, i.e. \"n\" and \"N\".\n\t*/\n\tcreateDebug.formatters = {};\n\n\t/**\n\t* Selects a color for a debug namespace\n\t* @param {String} namespace The namespace string for the debug instance to be colored\n\t* @return {Number|String} An ANSI color code for the given namespace\n\t* @api private\n\t*/\n\tfunction selectColor(namespace) {\n\t\tlet hash = 0;\n\n\t\tfor (let i = 0; i < namespace.length; i++) {\n\t\t\thash = ((hash << 5) - hash) + namespace.charCodeAt(i);\n\t\t\thash |= 0; // Convert to 32bit integer\n\t\t}\n\n\t\treturn createDebug.colors[Math.abs(hash) % createDebug.colors.length];\n\t}\n\tcreateDebug.selectColor = selectColor;\n\n\t/**\n\t* Create a debugger with the given `namespace`.\n\t*\n\t* @param {String} namespace\n\t* @return {Function}\n\t* @api public\n\t*/\n\tfunction createDebug(namespace) {\n\t\tlet prevTime;\n\t\tlet enableOverride = null;\n\t\tlet namespacesCache;\n\t\tlet enabledCache;\n\n\t\tfunction debug(...args) {\n\t\t\t// Disabled?\n\t\t\tif (!debug.enabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst self = debug;\n\n\t\t\t// Set `diff` timestamp\n\t\t\tconst curr = Number(new Date());\n\t\t\tconst ms = curr - (prevTime || curr);\n\t\t\tself.diff = ms;\n\t\t\tself.prev = prevTime;\n\t\t\tself.curr = curr;\n\t\t\tprevTime = curr;\n\n\t\t\targs[0] = createDebug.coerce(args[0]);\n\n\t\t\tif (typeof args[0] !== 'string') {\n\t\t\t\t// Anything else let's inspect with %O\n\t\t\t\targs.unshift('%O');\n\t\t\t}\n\n\t\t\t// Apply any `formatters` transformations\n\t\t\tlet index = 0;\n\t\t\targs[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {\n\t\t\t\t// If we encounter an escaped % then don't increase the array index\n\t\t\t\tif (match === '%%') {\n\t\t\t\t\treturn '%';\n\t\t\t\t}\n\t\t\t\tindex++;\n\t\t\t\tconst formatter = createDebug.formatters[format];\n\t\t\t\tif (typeof formatter === 'function') {\n\t\t\t\t\tconst val = args[index];\n\t\t\t\t\tmatch = formatter.call(self, val);\n\n\t\t\t\t\t// Now we need to remove `args[index]` since it's inlined in the `format`\n\t\t\t\t\targs.splice(index, 1);\n\t\t\t\t\tindex--;\n\t\t\t\t}\n\t\t\t\treturn match;\n\t\t\t});\n\n\t\t\t// Apply env-specific formatting (colors, etc.)\n\t\t\tcreateDebug.formatArgs.call(self, args);\n\n\t\t\tconst logFn = self.log || createDebug.log;\n\t\t\tlogFn.apply(self, args);\n\t\t}\n\n\t\tdebug.namespace = namespace;\n\t\tdebug.useColors = createDebug.useColors();\n\t\tdebug.color = createDebug.selectColor(namespace);\n\t\tdebug.extend = extend;\n\t\tdebug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.\n\n\t\tObject.defineProperty(debug, 'enabled', {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t\tget: () => {\n\t\t\t\tif (enableOverride !== null) {\n\t\t\t\t\treturn enableOverride;\n\t\t\t\t}\n\t\t\t\tif (namespacesCache !== createDebug.namespaces) {\n\t\t\t\t\tnamespacesCache = createDebug.namespaces;\n\t\t\t\t\tenabledCache = createDebug.enabled(namespace);\n\t\t\t\t}\n\n\t\t\t\treturn enabledCache;\n\t\t\t},\n\t\t\tset: v => {\n\t\t\t\tenableOverride = v;\n\t\t\t}\n\t\t});\n\n\t\t// Env-specific initialization logic for debug instances\n\t\tif (typeof createDebug.init === 'function') {\n\t\t\tcreateDebug.init(debug);\n\t\t}\n\n\t\treturn debug;\n\t}\n\n\tfunction extend(namespace, delimiter) {\n\t\tconst newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);\n\t\tnewDebug.log = this.log;\n\t\treturn newDebug;\n\t}\n\n\t/**\n\t* Enables a debug mode by namespaces. This can include modes\n\t* separated by a colon and wildcards.\n\t*\n\t* @param {String} namespaces\n\t* @api public\n\t*/\n\tfunction enable(namespaces) {\n\t\tcreateDebug.save(namespaces);\n\t\tcreateDebug.namespaces = namespaces;\n\n\t\tcreateDebug.names = [];\n\t\tcreateDebug.skips = [];\n\n\t\tlet i;\n\t\tconst split = (typeof namespaces === 'string' ? namespaces : '').split(/[\\s,]+/);\n\t\tconst len = split.length;\n\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tif (!split[i]) {\n\t\t\t\t// ignore empty strings\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tnamespaces = split[i].replace(/\\*/g, '.*?');\n\n\t\t\tif (namespaces[0] === '-') {\n\t\t\t\tcreateDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));\n\t\t\t} else {\n\t\t\t\tcreateDebug.names.push(new RegExp('^' + namespaces + '$'));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t* Disable debug output.\n\t*\n\t* @return {String} namespaces\n\t* @api public\n\t*/\n\tfunction disable() {\n\t\tconst namespaces = [\n\t\t\t...createDebug.names.map(toNamespace),\n\t\t\t...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)\n\t\t].join(',');\n\t\tcreateDebug.enable('');\n\t\treturn namespaces;\n\t}\n\n\t/**\n\t* Returns true if the given mode name is enabled, false otherwise.\n\t*\n\t* @param {String} name\n\t* @return {Boolean}\n\t* @api public\n\t*/\n\tfunction enabled(name) {\n\t\tif (name[name.length - 1] === '*') {\n\t\t\treturn true;\n\t\t}\n\n\t\tlet i;\n\t\tlet len;\n\n\t\tfor (i = 0, len = createDebug.skips.length; i < len; i++) {\n\t\t\tif (createDebug.skips[i].test(name)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0, len = createDebug.names.length; i < len; i++) {\n\t\t\tif (createDebug.names[i].test(name)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t* Convert regexp to namespace\n\t*\n\t* @param {RegExp} regxep\n\t* @return {String} namespace\n\t* @api private\n\t*/\n\tfunction toNamespace(regexp) {\n\t\treturn regexp.toString()\n\t\t\t.substring(2, regexp.toString().length - 2)\n\t\t\t.replace(/\\.\\*\\?$/, '*');\n\t}\n\n\t/**\n\t* Coerce `val`.\n\t*\n\t* @param {Mixed} val\n\t* @return {Mixed}\n\t* @api private\n\t*/\n\tfunction coerce(val) {\n\t\tif (val instanceof Error) {\n\t\t\treturn val.stack || val.message;\n\t\t}\n\t\treturn val;\n\t}\n\n\t/**\n\t* XXX DO NOT USE. This is a temporary stub function.\n\t* XXX It WILL be removed in the next major release.\n\t*/\n\tfunction destroy() {\n\t\tconsole.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');\n\t}\n\n\tcreateDebug.enable(createDebug.load());\n\n\treturn createDebug;\n}\n\nmodule.exports = setup;\n","/**\n * Detect Electron renderer / nwjs process, which is node, but we should\n * treat as a browser.\n */\n\nif (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {\n\tmodule.exports = require('./browser.js');\n} else {\n\tmodule.exports = require('./node.js');\n}\n","/**\n * Module dependencies.\n */\n\nconst tty = require('tty');\nconst util = require('util');\n\n/**\n * This is the Node.js implementation of `debug()`.\n */\n\nexports.init = init;\nexports.log = log;\nexports.formatArgs = formatArgs;\nexports.save = save;\nexports.load = load;\nexports.useColors = useColors;\nexports.destroy = util.deprecate(\n\t() => {},\n\t'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'\n);\n\n/**\n * Colors.\n */\n\nexports.colors = [6, 2, 3, 4, 5, 1];\n\ntry {\n\t// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)\n\t// eslint-disable-next-line import/no-extraneous-dependencies\n\tconst supportsColor = require('supports-color');\n\n\tif (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {\n\t\texports.colors = [\n\t\t\t20,\n\t\t\t21,\n\t\t\t26,\n\t\t\t27,\n\t\t\t32,\n\t\t\t33,\n\t\t\t38,\n\t\t\t39,\n\t\t\t40,\n\t\t\t41,\n\t\t\t42,\n\t\t\t43,\n\t\t\t44,\n\t\t\t45,\n\t\t\t56,\n\t\t\t57,\n\t\t\t62,\n\t\t\t63,\n\t\t\t68,\n\t\t\t69,\n\t\t\t74,\n\t\t\t75,\n\t\t\t76,\n\t\t\t77,\n\t\t\t78,\n\t\t\t79,\n\t\t\t80,\n\t\t\t81,\n\t\t\t92,\n\t\t\t93,\n\t\t\t98,\n\t\t\t99,\n\t\t\t112,\n\t\t\t113,\n\t\t\t128,\n\t\t\t129,\n\t\t\t134,\n\t\t\t135,\n\t\t\t148,\n\t\t\t149,\n\t\t\t160,\n\t\t\t161,\n\t\t\t162,\n\t\t\t163,\n\t\t\t164,\n\t\t\t165,\n\t\t\t166,\n\t\t\t167,\n\t\t\t168,\n\t\t\t169,\n\t\t\t170,\n\t\t\t171,\n\t\t\t172,\n\t\t\t173,\n\t\t\t178,\n\t\t\t179,\n\t\t\t184,\n\t\t\t185,\n\t\t\t196,\n\t\t\t197,\n\t\t\t198,\n\t\t\t199,\n\t\t\t200,\n\t\t\t201,\n\t\t\t202,\n\t\t\t203,\n\t\t\t204,\n\t\t\t205,\n\t\t\t206,\n\t\t\t207,\n\t\t\t208,\n\t\t\t209,\n\t\t\t214,\n\t\t\t215,\n\t\t\t220,\n\t\t\t221\n\t\t];\n\t}\n} catch (error) {\n\t// Swallow - we only care if `supports-color` is available; it doesn't have to be.\n}\n\n/**\n * Build up the default `inspectOpts` object from the environment variables.\n *\n *   $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js\n */\n\nexports.inspectOpts = Object.keys(process.env).filter(key => {\n\treturn /^debug_/i.test(key);\n}).reduce((obj, key) => {\n\t// Camel-case\n\tconst prop = key\n\t\t.substring(6)\n\t\t.toLowerCase()\n\t\t.replace(/_([a-z])/g, (_, k) => {\n\t\t\treturn k.toUpperCase();\n\t\t});\n\n\t// Coerce string value into JS value\n\tlet val = process.env[key];\n\tif (/^(yes|on|true|enabled)$/i.test(val)) {\n\t\tval = true;\n\t} else if (/^(no|off|false|disabled)$/i.test(val)) {\n\t\tval = false;\n\t} else if (val === 'null') {\n\t\tval = null;\n\t} else {\n\t\tval = Number(val);\n\t}\n\n\tobj[prop] = val;\n\treturn obj;\n}, {});\n\n/**\n * Is stdout a TTY? Colored output is enabled when `true`.\n */\n\nfunction useColors() {\n\treturn 'colors' in exports.inspectOpts ?\n\t\tBoolean(exports.inspectOpts.colors) :\n\t\ttty.isatty(process.stderr.fd);\n}\n\n/**\n * Adds ANSI color escape codes if enabled.\n *\n * @api public\n */\n\nfunction formatArgs(args) {\n\tconst {namespace: name, useColors} = this;\n\n\tif (useColors) {\n\t\tconst c = this.color;\n\t\tconst colorCode = '\\u001B[3' + (c < 8 ? c : '8;5;' + c);\n\t\tconst prefix = `  ${colorCode};1m${name} \\u001B[0m`;\n\n\t\targs[0] = prefix + args[0].split('\\n').join('\\n' + prefix);\n\t\targs.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\\u001B[0m');\n\t} else {\n\t\targs[0] = getDate() + name + ' ' + args[0];\n\t}\n}\n\nfunction getDate() {\n\tif (exports.inspectOpts.hideDate) {\n\t\treturn '';\n\t}\n\treturn new Date().toISOString() + ' ';\n}\n\n/**\n * Invokes `util.format()` with the specified arguments and writes to stderr.\n */\n\nfunction log(...args) {\n\treturn process.stderr.write(util.format(...args) + '\\n');\n}\n\n/**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\nfunction save(namespaces) {\n\tif (namespaces) {\n\t\tprocess.env.DEBUG = namespaces;\n\t} else {\n\t\t// If you set a process.env field to null or undefined, it gets cast to the\n\t\t// string 'null' or 'undefined'. Just delete instead.\n\t\tdelete process.env.DEBUG;\n\t}\n}\n\n/**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\nfunction load() {\n\treturn process.env.DEBUG;\n}\n\n/**\n * Init logic for `debug` instances.\n *\n * Create a new `inspectOpts` object in case `useColors` is set\n * differently for a particular `debug` instance.\n */\n\nfunction init(debug) {\n\tdebug.inspectOpts = {};\n\n\tconst keys = Object.keys(exports.inspectOpts);\n\tfor (let i = 0; i < keys.length; i++) {\n\t\tdebug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];\n\t}\n}\n\nmodule.exports = require('./common')(exports);\n\nconst {formatters} = module.exports;\n\n/**\n * Map %o to `util.inspect()`, all on a single line.\n */\n\nformatters.o = function (v) {\n\tthis.inspectOpts.colors = this.useColors;\n\treturn util.inspect(v, this.inspectOpts)\n\t\t.split('\\n')\n\t\t.map(str => str.trim())\n\t\t.join(' ');\n};\n\n/**\n * Map %O to `util.inspect()`, allowing multiple lines if needed.\n */\n\nformatters.O = function (v) {\n\tthis.inspectOpts.colors = this.useColors;\n\treturn util.inspect(v, this.inspectOpts);\n};\n","'use strict';\nmodule.exports = (flag, argv) => {\n\targv = argv || process.argv;\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst pos = argv.indexOf(prefix + flag);\n\tconst terminatorPos = argv.indexOf('--');\n\treturn pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);\n};\n","/**\n * Helpers.\n */\n\nvar s = 1000;\nvar m = s * 60;\nvar h = m * 60;\nvar d = h * 24;\nvar w = d * 7;\nvar y = d * 365.25;\n\n/**\n * Parse or format the given `val`.\n *\n * Options:\n *\n *  - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} [options]\n * @throws {Error} throw an error if val is not a non-empty string or a number\n * @return {String|Number}\n * @api public\n */\n\nmodule.exports = function(val, options) {\n  options = options || {};\n  var type = typeof val;\n  if (type === 'string' && val.length > 0) {\n    return parse(val);\n  } else if (type === 'number' && isFinite(val)) {\n    return options.long ? fmtLong(val) : fmtShort(val);\n  }\n  throw new Error(\n    'val is not a non-empty string or a valid number. val=' +\n      JSON.stringify(val)\n  );\n};\n\n/**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\nfunction parse(str) {\n  str = String(str);\n  if (str.length > 100) {\n    return;\n  }\n  var match = /^(-?(?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(\n    str\n  );\n  if (!match) {\n    return;\n  }\n  var n = parseFloat(match[1]);\n  var type = (match[2] || 'ms').toLowerCase();\n  switch (type) {\n    case 'years':\n    case 'year':\n    case 'yrs':\n    case 'yr':\n    case 'y':\n      return n * y;\n    case 'weeks':\n    case 'week':\n    case 'w':\n      return n * w;\n    case 'days':\n    case 'day':\n    case 'd':\n      return n * d;\n    case 'hours':\n    case 'hour':\n    case 'hrs':\n    case 'hr':\n    case 'h':\n      return n * h;\n    case 'minutes':\n    case 'minute':\n    case 'mins':\n    case 'min':\n    case 'm':\n      return n * m;\n    case 'seconds':\n    case 'second':\n    case 'secs':\n    case 'sec':\n    case 's':\n      return n * s;\n    case 'milliseconds':\n    case 'millisecond':\n    case 'msecs':\n    case 'msec':\n    case 'ms':\n      return n;\n    default:\n      return undefined;\n  }\n}\n\n/**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtShort(ms) {\n  var msAbs = Math.abs(ms);\n  if (msAbs >= d) {\n    return Math.round(ms / d) + 'd';\n  }\n  if (msAbs >= h) {\n    return Math.round(ms / h) + 'h';\n  }\n  if (msAbs >= m) {\n    return Math.round(ms / m) + 'm';\n  }\n  if (msAbs >= s) {\n    return Math.round(ms / s) + 's';\n  }\n  return ms + 'ms';\n}\n\n/**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\nfunction fmtLong(ms) {\n  var msAbs = Math.abs(ms);\n  if (msAbs >= d) {\n    return plural(ms, msAbs, d, 'day');\n  }\n  if (msAbs >= h) {\n    return plural(ms, msAbs, h, 'hour');\n  }\n  if (msAbs >= m) {\n    return plural(ms, msAbs, m, 'minute');\n  }\n  if (msAbs >= s) {\n    return plural(ms, msAbs, s, 'second');\n  }\n  return ms + ' ms';\n}\n\n/**\n * Pluralization helper.\n */\n\nfunction plural(ms, msAbs, n, name) {\n  var isPlural = msAbs >= n * 1.5;\n  return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');\n}\n","'use strict';\nconst os = require('os');\nconst hasFlag = require('has-flag');\n\nconst env = process.env;\n\nlet forceColor;\nif (hasFlag('no-color') ||\n\thasFlag('no-colors') ||\n\thasFlag('color=false')) {\n\tforceColor = false;\n} else if (hasFlag('color') ||\n\thasFlag('colors') ||\n\thasFlag('color=true') ||\n\thasFlag('color=always')) {\n\tforceColor = true;\n}\nif ('FORCE_COLOR' in env) {\n\tforceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3\n\t};\n}\n\nfunction supportsColor(stream) {\n\tif (forceColor === false) {\n\t\treturn 0;\n\t}\n\n\tif (hasFlag('color=16m') ||\n\t\thasFlag('color=full') ||\n\t\thasFlag('color=truecolor')) {\n\t\treturn 3;\n\t}\n\n\tif (hasFlag('color=256')) {\n\t\treturn 2;\n\t}\n\n\tif (stream && !stream.isTTY && forceColor !== true) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor ? 1 : 0;\n\n\tif (process.platform === 'win32') {\n\t\t// Node.js 7.5.0 is the first version of Node.js to include a patch to\n\t\t// libuv that enables 256 color output on Windows. Anything earlier and it\n\t\t// won't work. However, here we target Node.js 8 at minimum as it is an LTS\n\t\t// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows\n\t\t// release that supports 256 colors. Windows 10 build 14931 is the first release\n\t\t// that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(process.versions.node.split('.')[0]) >= 8 &&\n\t\t\tNumber(osRelease[0]) >= 10 &&\n\t\t\tNumber(osRelease[2]) >= 10586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app':\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\tcase 'Apple_Terminal':\n\t\t\t\treturn 2;\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\treturn min;\n}\n\nfunction getSupportLevel(stream) {\n\tconst level = supportsColor(stream);\n\treturn translateLevel(level);\n}\n\nmodule.exports = {\n\tsupportsColor: getSupportLevel,\n\tstdout: getSupportLevel(process.stdout),\n\tstderr: getSupportLevel(process.stderr)\n};\n","import { Menu, MenuItem, protocol, nativeImage, app } from 'electron'\r\nimport { ExtensionContext } from '../context'\r\nimport { PopupView } from '../popup'\r\nimport { ExtensionEvent } from '../router'\r\nimport {\r\n  getExtensionUrl,\r\n  getExtensionManifest,\r\n  getIconPath,\r\n  resolveExtensionPath,\r\n  matchSize,\r\n  ResizeType,\r\n} from './common'\r\n\r\nconst debug = require('debug')('electron-chrome-extensions:browserAction')\r\n\r\nif (!app.isReady()) {\r\n  protocol.registerSchemesAsPrivileged([{ scheme: 'crx', privileges: { bypassCSP: true } }])\r\n}\r\n\r\ninterface ExtensionAction {\r\n  color?: string\r\n  text?: string\r\n  title?: string\r\n  icon?: chrome.browserAction.TabIconDetails\r\n  popup?: string\r\n  /** Last modified date for icon. */\r\n  iconModified?: number\r\n}\r\n\r\ntype ExtensionActionKey = keyof ExtensionAction\r\n\r\ninterface ActivateDetails {\r\n  eventType: string\r\n  extensionId: string\r\n  tabId: number\r\n  anchorRect: { x: number; y: number; width: number; height: number }\r\n}\r\n\r\nconst getBrowserActionDefaults = (extension: Electron.Extension): ExtensionAction | undefined => {\r\n  const manifest = getExtensionManifest(extension)\r\n  const { browser_action } = manifest\r\n  if (typeof browser_action === 'object') {\r\n    const action: ExtensionAction = {}\r\n\r\n    action.title = browser_action.default_title || manifest.name\r\n\r\n    const iconPath = getIconPath(extension)\r\n    if (iconPath) action.icon = { path: iconPath }\r\n\r\n    if (browser_action.default_popup) {\r\n      action.popup = browser_action.default_popup\r\n    }\r\n\r\n    return action\r\n  }\r\n}\r\n\r\ninterface ExtensionActionStore extends Partial<ExtensionAction> {\r\n  tabs: { [key: string]: ExtensionAction }\r\n}\r\n\r\nexport class BrowserActionAPI {\r\n  private actionMap = new Map</* extensionId */ string, ExtensionActionStore>()\r\n  private popup?: PopupView\r\n\r\n  private observers: Set<Electron.WebContents> = new Set()\r\n  private queuedUpdate: boolean = false\r\n\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n\r\n    const getter =\r\n      (propName: ExtensionActionKey) =>\r\n      ({ extension }: ExtensionEvent, details: chrome.browserAction.TabDetails = {}) => {\r\n        const { tabId } = details\r\n        const action = this.getAction(extension.id)\r\n\r\n        let result\r\n\r\n        if (tabId) {\r\n          if (action.tabs[tabId]) {\r\n            result = action.tabs[tabId][propName]\r\n          } else {\r\n            result = action[propName]\r\n          }\r\n        } else {\r\n          result = action[propName]\r\n        }\r\n\r\n        return result\r\n      }\r\n\r\n    const setDetails = (\r\n      { extension }: ExtensionEvent,\r\n      details: any,\r\n      propName: ExtensionActionKey\r\n    ) => {\r\n      const { tabId } = details\r\n      let value = (details as any)[propName] || undefined\r\n\r\n      if (typeof value === 'undefined') {\r\n        const defaults = getBrowserActionDefaults(extension)\r\n        value = defaults ? defaults[propName] : value\r\n      }\r\n\r\n      const valueObj = { [propName]: value }\r\n      const action = this.getAction(extension.id)\r\n\r\n      if (tabId) {\r\n        const tabAction = action.tabs[tabId] || (action.tabs[tabId] = {})\r\n        Object.assign(tabAction, valueObj)\r\n      } else {\r\n        Object.assign(action, valueObj)\r\n      }\r\n\r\n      this.onUpdate()\r\n    }\r\n\r\n    const setter =\r\n      (propName: ExtensionActionKey) =>\r\n      (event: ExtensionEvent, details: chrome.browserAction.TabDetails) =>\r\n        setDetails(event, details, propName)\r\n\r\n    const handleProp = (prop: string, key: ExtensionActionKey) => {\r\n      handle(`browserAction.get${prop}`, getter(key))\r\n      handle(`browserAction.set${prop}`, setter(key))\r\n    }\r\n\r\n    handleProp('BadgeBackgroundColor', 'color')\r\n    handleProp('BadgeText', 'text')\r\n    handleProp('Title', 'title')\r\n    handleProp('Popup', 'popup')\r\n\r\n    // setIcon is unique in that it can pass in a variety of properties. Here we normalize them\r\n    // to use 'icon'.\r\n    handle(\r\n      'browserAction.setIcon',\r\n      (event, { tabId, ...details }: chrome.browserAction.TabIconDetails) => {\r\n        setDetails(event, { tabId, icon: details }, 'icon')\r\n        setDetails(event, { tabId, iconModified: Date.now() }, 'iconModified')\r\n      }\r\n    )\r\n\r\n    // browserAction preload API\r\n    const preloadOpts = { allowRemote: true, extensionContext: false }\r\n    handle('browserAction.getState', this.getState.bind(this), preloadOpts)\r\n    handle('browserAction.activate', this.activate.bind(this), preloadOpts)\r\n    handle(\r\n      'browserAction.addObserver',\r\n      (event) => {\r\n        const { sender: webContents } = event\r\n        this.observers.add(webContents)\r\n        webContents.once('destroyed', () => {\r\n          this.observers.delete(webContents)\r\n        })\r\n      },\r\n      preloadOpts\r\n    )\r\n    handle(\r\n      'browserAction.removeObserver',\r\n      (event) => {\r\n        const { sender: webContents } = event\r\n        this.observers.delete(webContents)\r\n      },\r\n      preloadOpts\r\n    )\r\n\r\n    this.ctx.store.on('active-tab-changed', () => {\r\n      this.onUpdate()\r\n    })\r\n\r\n    // Clear out tab details when removed\r\n    this.ctx.store.on('tab-removed', (tabId: number) => {\r\n      for (const [, actionDetails] of this.actionMap) {\r\n        if (actionDetails.tabs[tabId]) {\r\n          delete actionDetails.tabs[tabId]\r\n        }\r\n      }\r\n      this.onUpdate()\r\n    })\r\n\r\n    this.setupSession(this.ctx.session)\r\n  }\r\n\r\n  private setupSession(session: Electron.Session) {\r\n    session.on('extension-loaded', (event, extension) => {\r\n      this.processExtension(extension)\r\n    })\r\n\r\n    session.on('extension-unloaded', (event, extension) => {\r\n      this.removeActions(extension.id)\r\n    })\r\n\r\n    session.protocol.registerBufferProtocol('crx', this.handleCrxRequest)\r\n  }\r\n\r\n  private handleCrxRequest = (\r\n    request: Electron.ProtocolRequest,\r\n    callback: (response: Electron.ProtocolResponse) => void\r\n  ) => {\r\n    debug('%s', request.url)\r\n\r\n    let response: Electron.ProtocolResponse\r\n\r\n    try {\r\n      const url = new URL(request.url)\r\n      const { hostname: requestType } = url\r\n\r\n      switch (requestType) {\r\n        case 'extension-icon': {\r\n          const tabId = url.searchParams.get('tabId')\r\n\r\n          const fragments = url.pathname.split('/')\r\n          const extensionId = fragments[1]\r\n          const imageSize = parseInt(fragments[2], 10)\r\n          const resizeType = parseInt(fragments[3], 10) || ResizeType.Up\r\n\r\n          const extension = this.ctx.session.getExtension(extensionId)\r\n\r\n          let iconDetails: chrome.browserAction.TabIconDetails | undefined\r\n\r\n          const action = this.actionMap.get(extensionId)\r\n          if (action) {\r\n            iconDetails = (tabId && action.tabs[tabId]?.icon) || action.icon\r\n          }\r\n\r\n          let iconImage\r\n\r\n          if (extension && iconDetails) {\r\n            if (typeof iconDetails.path === 'string') {\r\n              const iconAbsPath = resolveExtensionPath(extension, iconDetails.path)\r\n              if (iconAbsPath) iconImage = nativeImage.createFromPath(iconAbsPath)\r\n            } else if (typeof iconDetails.path === 'object') {\r\n              const imagePath = matchSize(iconDetails.path, imageSize, resizeType)\r\n              const iconAbsPath = imagePath && resolveExtensionPath(extension, imagePath)\r\n              if (iconAbsPath) iconImage = nativeImage.createFromPath(iconAbsPath)\r\n            } else if (typeof iconDetails.imageData === 'string') {\r\n              iconImage = nativeImage.createFromDataURL(iconDetails.imageData)\r\n            } else if (typeof iconDetails.imageData === 'object') {\r\n              const imageData = matchSize(iconDetails.imageData as any, imageSize, resizeType)\r\n              iconImage = imageData ? nativeImage.createFromDataURL(imageData) : undefined\r\n            }\r\n          }\r\n\r\n          if (iconImage) {\r\n            response = {\r\n              statusCode: 200,\r\n              mimeType: 'image/png',\r\n              data: iconImage.toPNG(),\r\n            }\r\n          } else {\r\n            response = { statusCode: 400 }\r\n          }\r\n\r\n          break\r\n        }\r\n        default: {\r\n          response = { statusCode: 400 }\r\n        }\r\n      }\r\n    } catch (e) {\r\n      console.error(e)\r\n\r\n      response = {\r\n        statusCode: 500,\r\n      }\r\n    }\r\n\r\n    callback(response)\r\n  }\r\n\r\n  private getAction(extensionId: string) {\r\n    let action = this.actionMap.get(extensionId)\r\n    if (!action) {\r\n      action = { tabs: {} }\r\n      this.actionMap.set(extensionId, action)\r\n      this.onUpdate()\r\n    }\r\n\r\n    return action\r\n  }\r\n\r\n  // TODO: Make private for v4 major release.\r\n  removeActions(extensionId: string) {\r\n    if (this.actionMap.has(extensionId)) {\r\n      this.actionMap.delete(extensionId)\r\n    }\r\n\r\n    this.onUpdate()\r\n  }\r\n\r\n  private getPopupUrl(extensionId: string, tabId: number) {\r\n    const action = this.getAction(extensionId)\r\n    const popupPath = action.tabs[tabId]?.popup || action.popup || undefined\r\n    return popupPath && `chrome-extension://${extensionId}/${popupPath}`\r\n  }\r\n\r\n  // TODO: Make private for v4 major release.\r\n  processExtension(extension: Electron.Extension) {\r\n    const defaultAction = getBrowserActionDefaults(extension)\r\n    if (defaultAction) {\r\n      const action = this.getAction(extension.id)\r\n      Object.assign(action, defaultAction)\r\n    }\r\n  }\r\n\r\n  private getState() {\r\n    // Get state without icon data.\r\n    const actions = Array.from(this.actionMap.entries()).map(([id, details]) => {\r\n      const { icon, tabs, ...rest } = details\r\n\r\n      const tabsInfo: { [key: string]: any } = {}\r\n\r\n      for (const tabId of Object.keys(tabs)) {\r\n        const { icon, ...rest } = tabs[tabId]\r\n        tabsInfo[tabId] = rest\r\n      }\r\n\r\n      return {\r\n        id,\r\n        tabs: tabsInfo,\r\n        ...rest,\r\n      }\r\n    })\r\n\r\n    const activeTab = this.ctx.store.getActiveTabOfCurrentWindow()\r\n    return { activeTabId: activeTab?.id, actions }\r\n  }\r\n\r\n  private activate({ sender }: ExtensionEvent, details: ActivateDetails) {\r\n    const { eventType, extensionId, tabId } = details\r\n\r\n    debug(\r\n      `activate [eventType: ${eventType}, extensionId: '${extensionId}', tabId: ${tabId}, senderId: ${sender.id}]`\r\n    )\r\n\r\n    switch (eventType) {\r\n      case 'click':\r\n        this.activateClick(details)\r\n        break\r\n      case 'contextmenu':\r\n        this.activateContextMenu(details)\r\n        break\r\n      default:\r\n        console.debug(`Ignoring unknown browserAction.activate event '${eventType}'`)\r\n    }\r\n  }\r\n\r\n  private activateClick(details: ActivateDetails) {\r\n    const { extensionId, tabId, anchorRect } = details\r\n\r\n    if (this.popup) {\r\n      const toggleExtension = !this.popup.isDestroyed() && this.popup.extensionId === extensionId\r\n      this.popup.destroy()\r\n      this.popup = undefined\r\n      if (toggleExtension) {\r\n        debug('skipping activate to close popup')\r\n        return\r\n      }\r\n    }\r\n\r\n    const tab =\r\n      tabId >= 0 ? this.ctx.store.getTabById(tabId) : this.ctx.store.getActiveTabOfCurrentWindow()\r\n    if (!tab) {\r\n      throw new Error(`Unable to get active tab`)\r\n    }\r\n\r\n    const popupUrl = this.getPopupUrl(extensionId, tab.id)\r\n\r\n    if (popupUrl) {\r\n      const win = this.ctx.store.tabToWindow.get(tab)\r\n      if (!win) {\r\n        throw new Error('Unable to get BrowserWindow from active tab')\r\n      }\r\n\r\n      this.popup = new PopupView({\r\n        extensionId,\r\n        session: this.ctx.session,\r\n        parent: win,\r\n        url: popupUrl,\r\n        anchorRect,\r\n      })\r\n\r\n      debug(`opened popup: ${popupUrl}`)\r\n\r\n      this.ctx.emit('browser-action-popup-created', this.popup)\r\n    } else {\r\n      debug(`dispatching onClicked for ${extensionId}`)\r\n\r\n      const tabDetails = this.ctx.store.tabDetailsCache.get(tab.id)\r\n      this.ctx.router.sendEvent(extensionId, 'browserAction.onClicked', tabDetails)\r\n    }\r\n  }\r\n\r\n  private activateContextMenu(details: ActivateDetails) {\r\n    const { extensionId, anchorRect } = details\r\n\r\n    const extension = this.ctx.session.getExtension(extensionId)\r\n    if (!extension) {\r\n      throw new Error(`Unregistered extension '${extensionId}'`)\r\n    }\r\n\r\n    const manifest = getExtensionManifest(extension)\r\n    const menu = new Menu()\r\n    const append = (opts: Electron.MenuItemConstructorOptions) => menu.append(new MenuItem(opts))\r\n    const appendSeparator = () => menu.append(new MenuItem({ type: 'separator' }))\r\n\r\n    append({\r\n      label: extension.name,\r\n      click: () => {\r\n        const homePageUrl =\r\n          manifest.homepage_url || `https://chrome.google.com/webstore/detail/${extension.id}`\r\n        this.ctx.store.createTab({ url: homePageUrl })\r\n      },\r\n    })\r\n\r\n    appendSeparator()\r\n\r\n    const contextMenuItems: MenuItem[] = this.ctx.store.buildMenuItems(\r\n      extensionId,\r\n      'browser_action'\r\n    )\r\n    if (contextMenuItems.length > 0) {\r\n      contextMenuItems.forEach((item) => menu.append(item))\r\n      appendSeparator()\r\n    }\r\n\r\n    const optionsPage = manifest.options_page || manifest.options_ui?.page\r\n    const optionsPageUrl = optionsPage ? getExtensionUrl(extension, optionsPage) : undefined\r\n\r\n    append({\r\n      label: 'Options',\r\n      enabled: typeof optionsPageUrl === 'string',\r\n      click: () => {\r\n        this.ctx.store.createTab({ url: optionsPageUrl })\r\n      },\r\n    })\r\n\r\n    menu.popup({\r\n      x: Math.floor(anchorRect.x),\r\n      y: Math.floor(anchorRect.y + anchorRect.height),\r\n    })\r\n  }\r\n\r\n  private onUpdate() {\r\n    if (this.queuedUpdate) return\r\n    this.queuedUpdate = true\r\n    queueMicrotask(() => {\r\n      this.queuedUpdate = false\r\n      debug(`dispatching update to ${this.observers.size} observer(s)`)\r\n      Array.from(this.observers).forEach((observer) => {\r\n        if (!observer.isDestroyed()) {\r\n          observer.send('browserAction.update')\r\n        }\r\n      })\r\n    })\r\n  }\r\n}\r\n","import { ExtensionContext } from '../context'\r\n\r\n/**\r\n * Stub implementation for chrome.commands API.\r\n */\r\nexport class CommandsAPI {\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('commands.getAll', this.getAll)\r\n  }\r\n\r\n  getAll() {\r\n    return []\r\n  }\r\n}\r\n","import { promises as fs } from 'fs'\r\nimport * as path from 'path'\r\nimport { nativeImage } from 'electron'\r\n\r\nexport interface TabContents extends Electron.WebContents {\r\n  favicon?: string\r\n}\r\n\r\nexport type ContextMenuType =\r\n  | 'all'\r\n  | 'page'\r\n  | 'frame'\r\n  | 'selection'\r\n  | 'link'\r\n  | 'editable'\r\n  | 'image'\r\n  | 'video'\r\n  | 'audio'\r\n  | 'launcher'\r\n  | 'browser_action'\r\n  | 'page_action'\r\n  | 'action'\r\n\r\n/**\r\n * Get the extension's properly typed Manifest.\r\n *\r\n * I can't seem to get TS's merged type declarations working so I'm using this\r\n * instead for now.\r\n */\r\nexport const getExtensionManifest = (extension: Electron.Extension): chrome.runtime.Manifest =>\r\n  extension.manifest\r\n\r\nexport const getExtensionUrl = (extension: Electron.Extension, uri: string) => {\r\n  try {\r\n    return new URL(uri, extension.url).href\r\n  } catch {}\r\n}\r\n\r\nexport const resolveExtensionPath = (extension: Electron.Extension, uri: string) => {\r\n  const resPath = path.join(extension.path, uri)\r\n\r\n  // prevent any parent traversals\r\n  if (!resPath.startsWith(extension.path)) return\r\n\r\n  return resPath\r\n}\r\n\r\nexport const validateExtensionResource = async (extension: Electron.Extension, uri: string) => {\r\n  const resPath = resolveExtensionPath(extension, uri)\r\n  if (!resPath) return\r\n\r\n  try {\r\n    await fs.stat(resPath)\r\n  } catch {\r\n    return // doesn't exist\r\n  }\r\n\r\n  return resPath\r\n}\r\n\r\nexport enum ResizeType {\r\n  Exact,\r\n  Up,\r\n  Down,\r\n}\r\n\r\nexport const matchSize = (\r\n  imageSet: { [key: number]: string },\r\n  size: number,\r\n  match: ResizeType\r\n): string | undefined => {\r\n  // TODO: match based on size\r\n  const first = parseInt(Object.keys(imageSet).pop()!, 10)\r\n  return imageSet[first]\r\n}\r\n\r\n/** Gets the relative path to the extension's default icon. */\r\nexport const getIconPath = (\r\n  extension: Electron.Extension,\r\n  iconSize: number = 32,\r\n  resizeType = ResizeType.Up\r\n) => {\r\n  const { browser_action, icons } = getExtensionManifest(extension)\r\n  const { default_icon } = browser_action || {}\r\n\r\n  if (typeof default_icon === 'string') {\r\n    const iconPath = default_icon\r\n    return iconPath\r\n  } else if (typeof default_icon === 'object') {\r\n    const iconPath = matchSize(default_icon, iconSize, resizeType)\r\n    return iconPath\r\n  } else if (typeof icons === 'object') {\r\n    const iconPath = matchSize(icons, iconSize, resizeType)\r\n    return iconPath\r\n  }\r\n}\r\n\r\nexport const getIconImage = (extension: Electron.Extension) => {\r\n  const iconPath = getIconPath(extension)\r\n  const iconAbsolutePath = iconPath && resolveExtensionPath(extension, iconPath)\r\n  return iconAbsolutePath ? nativeImage.createFromPath(iconAbsolutePath) : undefined\r\n}\r\n\r\nconst escapePattern = (pattern: string) => pattern.replace(/[\\\\^$+?.()|[\\]{}]/g, '\\\\$&')\r\n\r\n/**\r\n * @see https://developer.chrome.com/extensions/match_patterns\r\n */\r\nexport const matchesPattern = (pattern: string, url: string) => {\r\n  if (pattern === '<all_urls>') return true\r\n  const regexp = new RegExp(`^${pattern.split('*').map(escapePattern).join('.*')}$`)\r\n  return url.match(regexp)\r\n}\r\n","import { Menu, MenuItem } from 'electron'\r\nimport { MenuItemConstructorOptions } from 'electron/main'\r\nimport { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\nimport { ContextMenuType, getIconImage, matchesPattern } from './common'\r\n\r\ntype ContextItemProps = chrome.contextMenus.CreateProperties & { id: string }\r\n\r\ntype ContextItemConstructorOptions = {\r\n  extension: Electron.Extension\r\n  props: ContextItemProps\r\n  webContents: Electron.WebContents\r\n  params?: Electron.ContextMenuParams\r\n  showIcon?: boolean\r\n}\r\n\r\nconst DEFAULT_CONTEXTS = ['page']\r\n\r\nconst getContextTypesFromParams = (params: Electron.ContextMenuParams): Set<ContextMenuType> => {\r\n  const contexts = new Set<ContextMenuType>(['all'])\r\n\r\n  switch (params.mediaType) {\r\n    case 'audio':\r\n    case 'video':\r\n    case 'image':\r\n      contexts.add(params.mediaType)\r\n  }\r\n\r\n  if (params.pageURL) contexts.add('page')\r\n  if (params.linkURL) contexts.add('link')\r\n  if (params.frameURL) contexts.add('frame')\r\n  if (params.selectionText) contexts.add('selection')\r\n  if (params.isEditable) contexts.add('editable')\r\n\r\n  return contexts\r\n}\r\n\r\nconst formatTitle = (title: string, params: Electron.ContextMenuParams) => {\r\n  if (params.selectionText && title.includes('%s')) {\r\n    title = title.split('%s').join(params.selectionText)\r\n  }\r\n  return title\r\n}\r\n\r\nconst matchesConditions = (\r\n  props: ContextItemProps,\r\n  conditions: {\r\n    contextTypes: Set<ContextMenuType>\r\n    targetUrl?: string\r\n    documentUrl?: string\r\n  }\r\n) => {\r\n  if (props.visible === false) return false\r\n\r\n  const { contextTypes, targetUrl, documentUrl } = conditions\r\n\r\n  const contexts = props.contexts || DEFAULT_CONTEXTS\r\n  const inContext = contexts.some((context) => contextTypes.has(context as ContextMenuType))\r\n  if (!inContext) return false\r\n\r\n  if (props.targetUrlPatterns && props.targetUrlPatterns.length > 0 && targetUrl) {\r\n    if (!props.targetUrlPatterns.some((pattern) => matchesPattern(pattern, targetUrl))) {\r\n      return false\r\n    }\r\n  }\r\n\r\n  if (props.documentUrlPatterns && props.documentUrlPatterns.length > 0 && documentUrl) {\r\n    if (!props.documentUrlPatterns.some((pattern) => matchesPattern(pattern, documentUrl))) {\r\n      return false\r\n    }\r\n  }\r\n\r\n  return true\r\n}\r\n\r\nexport class ContextMenusAPI {\r\n  private menus = new Map<\r\n    /* extensionId */ string,\r\n    Map</* menuItemId */ string, ContextItemProps>\r\n  >()\r\n\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('contextMenus.create', this.create)\r\n    handle('contextMenus.remove', this.remove)\r\n    handle('contextMenus.removeAll', this.removeAll)\r\n\r\n    this.ctx.session.on('extension-unloaded', (event, extension) => {\r\n      if (this.menus.has(extension.id)) {\r\n        this.menus.delete(extension.id)\r\n      }\r\n    })\r\n\r\n    this.ctx.store.buildMenuItems = this.buildMenuItemsForExtension.bind(this)\r\n  }\r\n\r\n  private addContextItem(extensionId: string, props: ContextItemProps) {\r\n    let contextItems = this.menus.get(extensionId)\r\n    if (!contextItems) {\r\n      contextItems = new Map()\r\n      this.menus.set(extensionId, contextItems)\r\n    }\r\n    contextItems.set(props.id, props)\r\n  }\r\n\r\n  private buildMenuItem = (opts: ContextItemConstructorOptions) => {\r\n    const { extension, props, webContents, params } = opts\r\n\r\n    // TODO: try to get the appropriately sized image before resizing\r\n    let icon = opts.showIcon ? getIconImage(extension) : undefined\r\n    if (icon) {\r\n      icon = icon.resize({ width: 16, height: 16 })\r\n    }\r\n\r\n    const menuItemOptions: MenuItemConstructorOptions = {\r\n      id: props.id,\r\n      type: props.type as any,\r\n      label: params ? formatTitle(props.title || '', params) : props.title || '',\r\n      icon,\r\n      enabled: props.enabled,\r\n      click: () => {\r\n        this.onClicked(extension.id, props.id, webContents, params)\r\n      },\r\n    }\r\n\r\n    return menuItemOptions\r\n  }\r\n\r\n  private buildMenuItemsFromTemplate = (menuItemTemplates: ContextItemConstructorOptions[]) => {\r\n    const itemMap = new Map<string, MenuItemConstructorOptions>()\r\n\r\n    // Group by ID\r\n    for (const item of menuItemTemplates) {\r\n      const menuItem = this.buildMenuItem(item)\r\n      itemMap.set(item.props.id, menuItem)\r\n    }\r\n\r\n    // Organize in tree\r\n    for (const item of menuItemTemplates) {\r\n      const menuItem = itemMap.get(item.props.id)\r\n      if (item.props.parentId) {\r\n        const parentMenuItem = itemMap.get(item.props.parentId)\r\n        if (parentMenuItem) {\r\n          const submenu = (parentMenuItem.submenu || []) as Electron.MenuItemConstructorOptions[]\r\n          submenu.push(menuItem!)\r\n          parentMenuItem.submenu = submenu\r\n        }\r\n      }\r\n    }\r\n\r\n    const menuItems: Electron.MenuItem[] = []\r\n\r\n    const buildFromTemplate = (opts: Electron.MenuItemConstructorOptions) => {\r\n      if (Array.isArray(opts.submenu)) {\r\n        const submenu = new Menu()\r\n        opts.submenu.forEach((item) => submenu.append(buildFromTemplate(item)))\r\n        opts.submenu = submenu\r\n      }\r\n      return new MenuItem(opts)\r\n    }\r\n\r\n    // Build all final MenuItems in-order\r\n    for (const item of menuItemTemplates) {\r\n      // Items with parents will be handled recursively\r\n      if (item.props.parentId) continue\r\n\r\n      const menuItem = itemMap.get(item.props.id)!\r\n      menuItems.push(buildFromTemplate(menuItem))\r\n    }\r\n\r\n    return menuItems\r\n  }\r\n\r\n  buildMenuItemsForParams(\r\n    webContents: Electron.WebContents,\r\n    params: Electron.ContextMenuParams\r\n  ): Electron.MenuItem[] {\r\n    if (webContents.session !== this.ctx.session) return []\r\n\r\n    const menuItemOptions = []\r\n\r\n    const conditions = {\r\n      contextTypes: getContextTypesFromParams(params),\r\n      targetUrl: params.srcURL || params.linkURL,\r\n      documentUrl: params.frameURL || params.pageURL,\r\n    }\r\n\r\n    for (const [extensionId, propItems] of this.menus) {\r\n      const extension = this.ctx.session.getExtension(extensionId)\r\n      if (!extension) continue\r\n\r\n      for (const [, props] of propItems) {\r\n        if (matchesConditions(props, conditions)) {\r\n          const menuItem = {\r\n            extension,\r\n            props,\r\n            webContents,\r\n            params,\r\n            showIcon: true,\r\n          }\r\n          menuItemOptions.push(menuItem)\r\n        }\r\n      }\r\n    }\r\n\r\n    return this.buildMenuItemsFromTemplate(menuItemOptions)\r\n  }\r\n\r\n  private buildMenuItemsForExtension(\r\n    extensionId: string,\r\n    menuType: ContextMenuType\r\n  ): Electron.MenuItem[] {\r\n    const extensionItems = this.menus.get(extensionId)\r\n    const extension = this.ctx.session.getExtension(extensionId)\r\n    const activeTab = this.ctx.store.getActiveTabOfCurrentWindow()\r\n\r\n    const menuItemOptions = []\r\n\r\n    if (extensionItems && extension && activeTab) {\r\n      const conditions = {\r\n        contextTypes: new Set<ContextMenuType>(['all', menuType]),\r\n      }\r\n\r\n      for (const [, props] of extensionItems) {\r\n        if (matchesConditions(props, conditions)) {\r\n          const menuItem = { extension, props, webContents: activeTab }\r\n          menuItemOptions.push(menuItem)\r\n        }\r\n      }\r\n    }\r\n\r\n    return this.buildMenuItemsFromTemplate(menuItemOptions)\r\n  }\r\n\r\n  private create = ({ extension }: ExtensionEvent, createProperties: ContextItemProps) => {\r\n    const { id, type, title } = createProperties\r\n\r\n    if (this.menus.has(id)) {\r\n      // TODO: duplicate error\r\n      return\r\n    }\r\n\r\n    if (!title && type !== 'separator') {\r\n      // TODO: error\r\n      return\r\n    }\r\n\r\n    this.addContextItem(extension.id, createProperties)\r\n  }\r\n\r\n  private remove = ({ extension }: ExtensionEvent, menuItemId: string) => {\r\n    const items = this.menus.get(extension.id)\r\n    if (items && items.has(menuItemId)) {\r\n      items.delete(menuItemId)\r\n      if (items.size === 0) {\r\n        this.menus.delete(extension.id)\r\n      }\r\n    }\r\n  }\r\n\r\n  private removeAll = ({ extension }: ExtensionEvent) => {\r\n    this.menus.delete(extension.id)\r\n  }\r\n\r\n  private onClicked(\r\n    extensionId: string,\r\n    menuItemId: string,\r\n    webContents: Electron.WebContents,\r\n    params?: Electron.ContextMenuParams\r\n  ) {\r\n    if (webContents.isDestroyed()) return\r\n\r\n    const tab = this.ctx.store.tabDetailsCache.get(webContents.id)\r\n    if (!tab) {\r\n      console.error(`[Extensions] Unable to find tab for id=${webContents.id}`)\r\n      return\r\n    }\r\n\r\n    const data: chrome.contextMenus.OnClickData = {\r\n      selectionText: params?.selectionText,\r\n      checked: false, // TODO\r\n      menuItemId,\r\n      frameId: -1, // TODO: match frameURL with webFrameMain in Electron 12\r\n      frameUrl: params?.frameURL,\r\n      editable: params?.isEditable || false,\r\n      mediaType: params?.mediaType,\r\n      wasChecked: false, // TODO\r\n      pageUrl: params?.pageURL as any, // types are inaccurate\r\n      linkUrl: params?.linkURL,\r\n      parentMenuItemId: -1, // TODO\r\n      srcUrl: params?.srcURL,\r\n    }\r\n\r\n    this.ctx.router.sendEvent(extensionId, 'contextMenus.onClicked', data, tab)\r\n  }\r\n}\r\n","import { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\n\r\nenum CookieStoreID {\r\n  Default = '0',\r\n  Incognito = '1',\r\n}\r\n\r\nconst onChangedCauseTranslation: { [key: string]: string } = {\r\n  'expired-overwrite': 'expired_overwrite',\r\n}\r\n\r\nconst createCookieDetails = (cookie: Electron.Cookie): chrome.cookies.Cookie => ({\r\n  ...cookie,\r\n  domain: cookie.domain || '',\r\n  hostOnly: Boolean(cookie.hostOnly),\r\n  session: Boolean(cookie.session),\r\n  path: cookie.path || '',\r\n  httpOnly: Boolean(cookie.httpOnly),\r\n  secure: Boolean(cookie.secure),\r\n  storeId: CookieStoreID.Default,\r\n})\r\n\r\nexport class CookiesAPI {\r\n  private get cookies() {\r\n    return this.ctx.session.cookies\r\n  }\r\n\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('cookies.get', this.get.bind(this))\r\n    handle('cookies.getAll', this.getAll.bind(this))\r\n    handle('cookies.set', this.set.bind(this))\r\n    handle('cookies.remove', this.remove.bind(this))\r\n    handle('cookies.getAllCookieStores', this.getAllCookieStores.bind(this))\r\n\r\n    this.cookies.addListener('changed', this.onChanged)\r\n  }\r\n\r\n  private async get(\r\n    event: ExtensionEvent,\r\n    details: chrome.cookies.Details\r\n  ): Promise<chrome.cookies.Cookie | null> {\r\n    // TODO: storeId\r\n    const cookies = await this.cookies.get({\r\n      url: details.url,\r\n      name: details.name,\r\n    })\r\n\r\n    // TODO: If more than one cookie of the same name exists for the given URL,\r\n    // the one with the longest path will be returned. For cookies with the\r\n    // same path length, the cookie with the earliest creation time will be returned.\r\n    return cookies.length > 0 ? createCookieDetails(cookies[0]) : null\r\n  }\r\n\r\n  private async getAll(\r\n    event: ExtensionEvent,\r\n    details: chrome.cookies.GetAllDetails\r\n  ): Promise<chrome.cookies.Cookie[]> {\r\n    // TODO: storeId\r\n    const cookies = await this.cookies.get({\r\n      url: details.url,\r\n      name: details.name,\r\n      domain: details.domain,\r\n      path: details.path,\r\n      secure: details.secure,\r\n      session: details.session,\r\n    })\r\n\r\n    return cookies.map(createCookieDetails)\r\n  }\r\n\r\n  private async set(\r\n    event: ExtensionEvent,\r\n    details: chrome.cookies.SetDetails\r\n  ): Promise<chrome.cookies.Cookie | null> {\r\n    await this.cookies.set(details)\r\n    const cookies = await this.cookies.get(details)\r\n    return cookies.length > 0 ? createCookieDetails(cookies[0]) : null\r\n  }\r\n\r\n  private async remove(\r\n    event: ExtensionEvent,\r\n    details: chrome.cookies.Details\r\n  ): Promise<chrome.cookies.Details | null> {\r\n    try {\r\n      await this.cookies.remove(details.url, details.name)\r\n    } catch {\r\n      return null\r\n    }\r\n    return details\r\n  }\r\n\r\n  private async getAllCookieStores(event: ExtensionEvent): Promise<chrome.cookies.CookieStore[]> {\r\n    const tabIds = Array.from(this.ctx.store.tabs)\r\n      .map((tab) => (tab.isDestroyed() ? undefined : tab.id))\r\n      .filter(Boolean) as number[]\r\n    return [{ id: CookieStoreID.Default, tabIds }]\r\n  }\r\n\r\n  private onChanged = (event: Event, cookie: Electron.Cookie, cause: string, removed: boolean) => {\r\n    const changeInfo: chrome.cookies.CookieChangeInfo = {\r\n      cause: onChangedCauseTranslation[cause] || cause,\r\n      cookie: createCookieDetails(cookie),\r\n      removed,\r\n    }\r\n\r\n    this.ctx.router.broadcastEvent('cookies.onChanged', changeInfo)\r\n  }\r\n}\r\n","import { app, Extension, Notification } from 'electron'\r\nimport { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\nimport { validateExtensionResource } from './common'\r\n\r\nenum TemplateType {\r\n  Basic = 'basic',\r\n  Image = 'image',\r\n  List = 'list',\r\n  Progress = 'progress',\r\n}\r\n\r\nconst getBody = (opts: chrome.notifications.NotificationOptions) => {\r\n  const { type = TemplateType.Basic } = opts\r\n\r\n  switch (type) {\r\n    case TemplateType.List: {\r\n      if (!Array.isArray(opts.items)) {\r\n        throw new Error('List items must be provided for list type')\r\n      }\r\n      return opts.items.map((item) => `${item.title} - ${item.message}`).join('\\n')\r\n    }\r\n    default:\r\n      return opts.message || ''\r\n  }\r\n}\r\n\r\nconst getUrgency = (\r\n  priority?: number\r\n): Required<Electron.NotificationConstructorOptions>['urgency'] => {\r\n  if (typeof priority !== 'number') {\r\n    return 'normal'\r\n  } else if (priority >= 2) {\r\n    return 'critical'\r\n  } else if (priority < 0) {\r\n    return 'low'\r\n  } else {\r\n    return 'normal'\r\n  }\r\n}\r\n\r\nconst createScopedIdentifier = (extension: Extension, id: string) => `${extension.id}-${id}`\r\nconst stripScopeFromIdentifier = (id: string) => {\r\n  const index = id.indexOf('-')\r\n  return id.substr(index + 1)\r\n}\r\n\r\nexport class NotificationsAPI {\r\n  private registry = new Map<string, Notification>()\r\n\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('notifications.clear', this.clear)\r\n    handle('notifications.create', this.create)\r\n    handle('notifications.getAll', this.getAll)\r\n    handle('notifications.getPermissionLevel', this.getPermissionLevel)\r\n    handle('notifications.update', this.update)\r\n\r\n    this.ctx.session.on('extension-unloaded', (event, extension) => {\r\n      for (const [key, notification] of this.registry) {\r\n        if (key.startsWith(extension.id)) {\r\n          notification.close()\r\n        }\r\n      }\r\n    })\r\n  }\r\n\r\n  private clear = ({ extension }: ExtensionEvent, id: string) => {\r\n    const notificationId = createScopedIdentifier(extension, id)\r\n    if (this.registry.has(notificationId)) {\r\n      this.registry.get(notificationId)?.close()\r\n    }\r\n  }\r\n\r\n  private create = async ({ extension }: ExtensionEvent, arg1: unknown, arg2?: unknown) => {\r\n    let id: string\r\n    let opts: chrome.notifications.NotificationOptions\r\n\r\n    if (typeof arg1 === 'object') {\r\n      id = 'guid' // TODO: generate uuid\r\n      opts = arg1 as chrome.notifications.NotificationOptions\r\n    } else if (typeof arg1 === 'string') {\r\n      id = arg1\r\n      opts = arg2 as chrome.notifications.NotificationOptions\r\n    } else {\r\n      throw new Error('Invalid arguments')\r\n    }\r\n\r\n    if (typeof opts !== 'object' || !opts.type || !opts.iconUrl || !opts.title || !opts.message) {\r\n      throw new Error('Missing required notification options')\r\n    }\r\n\r\n    const notificationId = createScopedIdentifier(extension, id)\r\n\r\n    if (this.registry.has(notificationId)) {\r\n      this.registry.get(notificationId)?.close()\r\n    }\r\n\r\n    let icon\r\n\r\n    if (opts.iconUrl) {\r\n      let url\r\n      try {\r\n        url = new URL(opts.iconUrl)\r\n      } catch {}\r\n\r\n      if (url?.protocol === 'data:') {\r\n        icon = opts.iconUrl\r\n      } else {\r\n        icon = await validateExtensionResource(extension, opts.iconUrl)\r\n      }\r\n\r\n      if (!icon) {\r\n        throw new Error('Invalid iconUrl')\r\n      }\r\n    }\r\n\r\n    // TODO: buttons, template types\r\n\r\n    const notification = new Notification({\r\n      title: opts.title,\r\n      subtitle: app.name,\r\n      body: getBody(opts),\r\n      silent: opts.silent,\r\n      icon,\r\n      urgency: getUrgency(opts.priority),\r\n      timeoutType: opts.requireInteraction ? 'never' : 'default',\r\n    })\r\n\r\n    this.registry.set(notificationId, notification)\r\n\r\n    notification.on('click', () => {\r\n      this.ctx.router.sendEvent(extension.id, 'notifications.onClicked', id)\r\n    })\r\n\r\n    notification.once('close', () => {\r\n      const byUser = true // TODO\r\n      this.ctx.router.sendEvent(extension.id, 'notifications.onClosed', id, byUser)\r\n      this.registry.delete(notificationId)\r\n    })\r\n\r\n    notification.show()\r\n\r\n    return id\r\n  }\r\n\r\n  private getAll = ({ extension }: ExtensionEvent) => {\r\n    return Array.from(this.registry.keys())\r\n      .filter((key) => key.startsWith(extension.id))\r\n      .map(stripScopeFromIdentifier)\r\n  }\r\n\r\n  private getPermissionLevel = (event: ExtensionEvent) => {\r\n    return Notification.isSupported() ? 'granted' : 'denied'\r\n  }\r\n\r\n  private update = (\r\n    { extension }: ExtensionEvent,\r\n    id: string,\r\n    opts: chrome.notifications.NotificationOptions\r\n  ) => {\r\n    const notificationId = createScopedIdentifier(extension, id)\r\n\r\n    const notification = this.registry.get(notificationId)\r\n\r\n    if (!notification) {\r\n      return false\r\n    }\r\n\r\n    // TODO: remaining opts\r\n\r\n    if (opts.priority) notification.urgency = getUrgency(opts.priority)\r\n    if (opts.silent) notification.silent = opts.silent\r\n  }\r\n}\r\n","import { EventEmitter } from 'events'\r\nimport { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\nimport { getExtensionManifest } from './common'\r\n\r\nexport class RuntimeAPI extends EventEmitter {\r\n  constructor(private ctx: ExtensionContext) {\r\n    super()\r\n\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('runtime.openOptionsPage', this.openOptionsPage)\r\n  }\r\n\r\n  private openOptionsPage = async ({ extension }: ExtensionEvent) => {\r\n    // TODO: options page shouldn't appear in Tabs API\r\n    // https://developer.chrome.com/extensions/options#tabs-api\r\n\r\n    const manifest = getExtensionManifest(extension)\r\n\r\n    if (manifest.options_ui) {\r\n      // Embedded option not support (!options_ui.open_in_new_tab)\r\n      const url = `chrome-extension://${extension.id}/${manifest.options_ui.page}`\r\n      await this.ctx.store.createTab({ url, active: true })\r\n    } else if (manifest.options_page) {\r\n      const url = `chrome-extension://${extension.id}/${manifest.options_page}`\r\n      await this.ctx.store.createTab({ url, active: true })\r\n    }\r\n  }\r\n}\r\n","import { BrowserWindow } from 'electron'\r\nimport { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\nimport { TabContents } from './common'\r\nimport { WindowsAPI } from './windows'\r\n\r\nconst debug = require('debug')('electron-chrome-extensions:tabs')\r\n\r\nexport class TabsAPI {\r\n  static TAB_ID_NONE = -1\r\n  static WINDOW_ID_NONE = -1\r\n  static WINDOW_ID_CURRENT = -2\r\n\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('tabs.get', this.get.bind(this))\r\n    handle('tabs.getAllInWindow', this.getAllInWindow.bind(this))\r\n    handle('tabs.getCurrent', this.getCurrent.bind(this))\r\n    handle('tabs.create', this.create.bind(this))\r\n    handle('tabs.insertCSS', this.insertCSS.bind(this))\r\n    handle('tabs.query', this.query.bind(this))\r\n    handle('tabs.reload', this.reload.bind(this))\r\n    handle('tabs.update', this.update.bind(this))\r\n    handle('tabs.remove', this.remove.bind(this))\r\n    handle('tabs.goForward', this.goForward.bind(this))\r\n    handle('tabs.goBack', this.goBack.bind(this))\r\n\r\n    handle('tabs.getSelected', this.getSelected.bind(this))\r\n\r\n    //handle('tabs.sendRequest', this.sendRequest.bind(this))\r\n\r\n    this.ctx.store.on('tab-added', this.observeTab.bind(this))\r\n  }\r\n\r\n  private observeTab(tab: TabContents) {\r\n    const tabId = tab.id\r\n\r\n    const updateEvents = [\r\n      'page-title-updated', // title\r\n      'did-start-loading', // status\r\n      'did-stop-loading', // status\r\n      'media-started-playing', // audible\r\n      'media-paused', // audible\r\n      'did-start-navigation', // url\r\n      'did-redirect-navigation', // url\r\n      'did-navigate-in-page', // url\r\n    ]\r\n\r\n    const updateHandler = () => {\r\n      this.onUpdated(tabId)\r\n    }\r\n\r\n    updateEvents.forEach((eventName) => {\r\n      tab.on(eventName as any, updateHandler)\r\n    })\r\n\r\n    const faviconHandler = (event: Electron.Event, favicons: string[]) => {\r\n      ;(tab as TabContents).favicon = favicons[0]\r\n      this.onUpdated(tabId)\r\n    }\r\n    tab.on('page-favicon-updated', faviconHandler)\r\n\r\n    tab.once('destroyed', () => {\r\n      updateEvents.forEach((eventName) => {\r\n        tab.off(eventName as any, updateHandler)\r\n      })\r\n      tab.off('page-favicon-updated', faviconHandler)\r\n\r\n      this.ctx.store.removeTab(tab)\r\n      this.onRemoved(tabId)\r\n    })\r\n\r\n    this.onCreated(tabId)\r\n    this.onActivated(tabId)\r\n\r\n    debug(`Observing tab[${tabId}][${tab.getType()}] ${tab.getURL()}`)\r\n  }\r\n\r\n  private createTabDetails(tab: TabContents) {\r\n    const tabId = tab.id\r\n    const activeTab = this.ctx.store.getActiveTabFromWebContents(tab)\r\n    let win = this.ctx.store.tabToWindow.get(tab)\r\n    if (win?.isDestroyed()) win = undefined\r\n    const [width = 0, height = 0] = win ? win.getSize() : []\r\n\r\n    const details: chrome.tabs.Tab = {\r\n      active: activeTab?.id === tabId,\r\n      audible: tab.isCurrentlyAudible(),\r\n      autoDiscardable: true,\r\n      discarded: false,\r\n      favIconUrl: tab.favicon || undefined,\r\n      height,\r\n      highlighted: false,\r\n      id: tabId,\r\n      incognito: false,\r\n      index: -1, // TODO\r\n      mutedInfo: { muted: tab.audioMuted },\r\n      pinned: false,\r\n      selected: true,\r\n      status: tab.isLoading() ? 'loading' : 'complete',\r\n      title: tab.getTitle(),\r\n      url: tab.getURL(), // TODO: tab.mainFrame.url (Electron 12)\r\n      width,\r\n      windowId: win ? win.id : -1,\r\n    }\r\n\r\n    if (typeof this.ctx.store.impl.assignTabDetails === 'function') {\r\n      this.ctx.store.impl.assignTabDetails(details, tab)\r\n    }\r\n\r\n    this.ctx.store.tabDetailsCache.set(tab.id, details)\r\n    return details\r\n  }\r\n\r\n  private getTabDetails(tab: TabContents) {\r\n    if (this.ctx.store.tabDetailsCache.has(tab.id)) {\r\n      return this.ctx.store.tabDetailsCache.get(tab.id)\r\n    }\r\n    const details = this.createTabDetails(tab)\r\n    return details\r\n  }\r\n\r\n  private get(event: ExtensionEvent, tabId: number) {\r\n    const tab = this.ctx.store.getTabById(tabId)\r\n    if (!tab) return { id: TabsAPI.TAB_ID_NONE }\r\n    return this.getTabDetails(tab)\r\n  }\r\n\r\n  private getAllInWindow(event: ExtensionEvent, windowId: number = TabsAPI.WINDOW_ID_CURRENT) {\r\n    if (windowId === TabsAPI.WINDOW_ID_CURRENT) windowId = this.ctx.store.lastFocusedWindowId!\r\n\r\n    const tabs = Array.from(this.ctx.store.tabs).filter((tab) => {\r\n      if (tab.isDestroyed()) return false\r\n\r\n      const browserWindow = this.ctx.store.tabToWindow.get(tab)\r\n      if (!browserWindow || browserWindow.isDestroyed()) return\r\n\r\n      return browserWindow.id === windowId\r\n    })\r\n\r\n    return tabs.map(this.getTabDetails.bind(this))\r\n  }\r\n\r\n  private sendRequest(event: ExtensionEvent) {\r\n    //const tab = this.ctx.store.getActiveTabOfCurrentWindow()\r\n    //return tab ? this.getTabDetails(tab) : undefined\r\n  }\r\n\r\n  private getSelected(event: ExtensionEvent) {\r\n    const tab = this.ctx.store.getActiveTabOfCurrentWindow()\r\n    return tab ? this.getTabDetails(tab) : undefined\r\n  }\r\n\r\n  private getCurrent(event: ExtensionEvent) {\r\n    const tab = this.ctx.store.getActiveTabFromWebContents(event.sender)\r\n    return tab ? this.getTabDetails(tab) : undefined\r\n  }\r\n\r\n  private async create(event: ExtensionEvent, details: chrome.tabs.CreateProperties = {}) {\r\n    if(details.url && details.url.indexOf('://') < 0){\r\n      details.url = event.extension.url + details.url;\r\n    } \r\n    const tab = await this.ctx.store.createTab(details)\r\n    const tabDetails = this.getTabDetails(tab)\r\n    if (details.active) {\r\n      queueMicrotask(() => this.onActivated(tab.id))\r\n    }\r\n    return tabDetails\r\n  }\r\n\r\n  private insertCSS(event: ExtensionEvent, tabId: number, details: chrome.tabs.InjectDetails) {\r\n    const tab = this.ctx.store.getTabById(tabId)\r\n    if (!tab) return\r\n\r\n    // TODO: move to webFrame in renderer?\r\n    if (details.code) {\r\n      tab.insertCSS(details.code)\r\n    }\r\n  }\r\n\r\n  private query(event: ExtensionEvent, info: chrome.tabs.QueryInfo = {}) {\r\n    const isSet = (value: any) => typeof value !== 'undefined'\r\n\r\n    const filteredTabs = Array.from(this.ctx.store.tabs)\r\n      .map(this.getTabDetails.bind(this))\r\n      .filter((tab) => {\r\n        if (!tab) return false\r\n        if (isSet(info.active) && info.active !== tab.active) return false\r\n        if (isSet(info.pinned) && info.pinned !== tab.pinned) return false\r\n        if (isSet(info.audible) && info.audible !== tab.audible) return false\r\n        if (isSet(info.muted) && info.muted !== tab.mutedInfo?.muted) return false\r\n        if (isSet(info.highlighted) && info.highlighted !== tab.highlighted) return false\r\n        if (isSet(info.discarded) && info.discarded !== tab.discarded) return false\r\n        if (isSet(info.autoDiscardable) && info.autoDiscardable !== tab.autoDiscardable)\r\n          return false\r\n        // if (isSet(info.currentWindow)) return false\r\n        // if (isSet(info.lastFocusedWindow)) return false\r\n        if (isSet(info.status) && info.status !== tab.status) return false\r\n        if (isSet(info.title) && info.title !== tab.title) return false // TODO: pattern match\r\n        if (isSet(info.url) && info.url !== tab.url) return false // TODO: match URL pattern\r\n        if (isSet(info.windowId)) {\r\n          if (info.windowId === TabsAPI.WINDOW_ID_CURRENT) {\r\n            if (this.ctx.store.lastFocusedWindowId !== tab.windowId) return false\r\n          } else if (info.windowId !== tab.windowId) {\r\n            return false\r\n          }\r\n        }\r\n        // if (isSet(info.windowType) && info.windowType !== tab.windowType) return false\r\n        // if (isSet(info.index) && info.index !== tab.index) return false\r\n        return true\r\n      })\r\n      .map((tab, index) => {\r\n        if (tab) {\r\n          tab.index = index\r\n        }\r\n        return tab\r\n      })\r\n    return filteredTabs\r\n  }\r\n\r\n  private reload(event: ExtensionEvent, arg1?: unknown, arg2?: unknown) {\r\n    const tabId: number | undefined = typeof arg1 === 'number' ? arg1 : undefined\r\n    const reloadProperties: chrome.tabs.ReloadProperties | null =\r\n      typeof arg1 === 'object' ? arg1 : typeof arg2 === 'object' ? arg2 : {}\r\n\r\n    const tab = tabId\r\n      ? this.ctx.store.getTabById(tabId)\r\n      : this.ctx.store.getActiveTabFromWebContents(event.sender)\r\n\r\n    if (!tab) return\r\n\r\n    if (reloadProperties?.bypassCache) {\r\n      tab.reloadIgnoringCache()\r\n    } else {\r\n      tab.reload()\r\n    }\r\n  }\r\n\r\n  private async update(event: ExtensionEvent, arg1?: unknown, arg2?: unknown) {\r\n    let tabId = typeof arg1 === 'number' ? arg1 : undefined\r\n    const updateProperties: chrome.tabs.UpdateProperties =\r\n      (typeof arg1 === 'object' ? (arg1 as any) : (arg2 as any)) || {}\r\n\r\n    const tab = tabId\r\n      ? this.ctx.store.getTabById(tabId)\r\n      : this.ctx.store.getActiveTabFromWebContents(event.sender)\r\n    if (!tab) return\r\n\r\n    tabId = tab.id\r\n\r\n    const props = updateProperties\r\n\r\n    // TODO: validate URL, prevent 'javascript:'\r\n    if (props.url) await tab.loadURL(props.url)\r\n\r\n    if (typeof props.muted === 'boolean') tab.setAudioMuted(props.muted)\r\n\r\n    if (props.active) this.onActivated(tabId)\r\n\r\n    this.onUpdated(tabId)\r\n\r\n    return this.createTabDetails(tab)\r\n  }\r\n\r\n  private remove(event: ExtensionEvent, id: number | number[]) {\r\n    const ids = Array.isArray(id) ? id : [id]\r\n\r\n    ids.forEach((tabId) => {\r\n      const tab = this.ctx.store.getTabById(tabId)\r\n      if (tab) this.ctx.store.removeTab(tab)\r\n      this.onRemoved(tabId)\r\n    })\r\n  }\r\n\r\n  private goForward(event: ExtensionEvent, arg1?: unknown) {\r\n    const tabId = typeof arg1 === 'number' ? arg1 : undefined\r\n    const tab = tabId\r\n      ? this.ctx.store.getTabById(tabId)\r\n      : this.ctx.store.getActiveTabFromWebContents(event.sender)\r\n    if (!tab) return\r\n    tab.goForward()\r\n  }\r\n\r\n  private goBack(event: ExtensionEvent, arg1?: unknown) {\r\n    const tabId = typeof arg1 === 'number' ? arg1 : undefined\r\n    const tab = tabId\r\n      ? this.ctx.store.getTabById(tabId)\r\n      : this.ctx.store.getActiveTabFromWebContents(event.sender)\r\n    if (!tab) return\r\n    tab.goBack()\r\n  }\r\n\r\n  onCreated(tabId: number) {\r\n    const tab = this.ctx.store.getTabById(tabId)\r\n    if (!tab) return\r\n    const tabDetails = this.getTabDetails(tab)\r\n    this.ctx.router.broadcastEvent('tabs.onCreated', tabDetails)\r\n  }\r\n\r\n  onUpdated(tabId: number) {\r\n    const tab = this.ctx.store.getTabById(tabId)\r\n    if (!tab) return\r\n\r\n    let prevDetails\r\n    if (this.ctx.store.tabDetailsCache.has(tab.id)) {\r\n      prevDetails = this.ctx.store.tabDetailsCache.get(tab.id)\r\n    }\r\n    if (!prevDetails) return\r\n\r\n    const details = this.createTabDetails(tab)\r\n\r\n    const compareProps: (keyof chrome.tabs.Tab)[] = [\r\n      'status',\r\n      'url',\r\n      'pinned',\r\n      'audible',\r\n      'discarded',\r\n      'autoDiscardable',\r\n      'mutedInfo',\r\n      'favIconUrl',\r\n      'title',\r\n    ]\r\n\r\n    let didUpdate = false\r\n    const changeInfo: chrome.tabs.TabChangeInfo = {}\r\n\r\n    for (const prop of compareProps) {\r\n      if (details[prop] !== prevDetails[prop]) {\r\n        ;(changeInfo as any)[prop] = details[prop]\r\n        didUpdate = true\r\n      }\r\n    }\r\n\r\n    if (!didUpdate) return\r\n\r\n    this.ctx.router.broadcastEvent('tabs.onUpdated', tab.id, changeInfo, details)\r\n  }\r\n\r\n  onRemoved(tabId: number) {\r\n    const details = this.ctx.store.tabDetailsCache.has(tabId)\r\n      ? this.ctx.store.tabDetailsCache.get(tabId)\r\n      : null\r\n    this.ctx.store.tabDetailsCache.delete(tabId)\r\n\r\n    const windowId = details ? details.windowId : WindowsAPI.WINDOW_ID_NONE\r\n    const win =\r\n      typeof windowId !== 'undefined' && windowId > -1\r\n        ? BrowserWindow.getAllWindows().find((win) => win.id === windowId)\r\n        : null\r\n\r\n    this.ctx.router.broadcastEvent('tabs.onRemoved', tabId, {\r\n      windowId,\r\n      isWindowClosing: win ? win.isDestroyed() : false,\r\n    })\r\n  }\r\n\r\n  onActivated(tabId: number) {\r\n    const tab = this.ctx.store.getTabById(tabId)\r\n    if (!tab) return\r\n\r\n    const activeTab = this.ctx.store.getActiveTabFromWebContents(tab)\r\n    const activeChanged = activeTab?.id !== tabId\r\n    if (!activeChanged) return\r\n\r\n    const win = this.ctx.store.tabToWindow.get(tab)\r\n\r\n    this.ctx.store.setActiveTab(tab)\r\n\r\n    // invalidate cache since 'active' has changed\r\n    this.ctx.store.tabDetailsCache.forEach((tabInfo, cacheTabId) => {\r\n      tabInfo.active = tabId === cacheTabId\r\n    })\r\n\r\n    this.ctx.router.broadcastEvent('tabs.onActivated', {\r\n      tabId,\r\n      windowId: win?.id,\r\n    })\r\n  }\r\n}\r\n","import * as electron from 'electron'\r\nimport { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\n\r\nconst debug = require('debug')('electron-chrome-extensions:webNavigation')\r\n\r\n// https://github.com/electron/electron/pull/25464\r\nconst getFrame = (frameProcessId: number, frameRoutingId: number) => {\r\n  return (\r\n    ('webFrameMain' in electron &&\r\n      (electron as any).webFrameMain.fromId(frameProcessId, frameRoutingId)) ||\r\n    null\r\n  )\r\n}\r\n\r\nconst getFrameId = (frame: any) =>\r\n  'webFrameMain' in electron ? (frame === frame.top ? 0 : frame.frameTreeNodeId) : -1\r\n\r\nconst getParentFrameId = (frame: any) => {\r\n  const parentFrame = frame?.parent\r\n  return parentFrame ? getFrameId(parentFrame) : -1\r\n}\r\n\r\nconst getFrameDetails = (frame: any) => ({\r\n  errorOccurred: false, // TODO\r\n  processId: frame.processId,\r\n  frameId: getFrameId(frame),\r\n  parentFrameId: getParentFrameId(frame),\r\n  url: frame.url,\r\n})\r\n\r\nexport class WebNavigationAPI {\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('webNavigation.getFrame', this.getFrame.bind(this))\r\n    handle('webNavigation.getAllFrames', this.getAllFrames.bind(this))\r\n\r\n    this.ctx.store.on('tab-added', this.observeTab.bind(this))\r\n  }\r\n\r\n  private observeTab(tab: Electron.WebContents) {\r\n    tab.once('will-navigate', this.onCreatedNavigationTarget as any)\r\n    tab.on('did-start-navigation', this.onBeforeNavigate as any)\r\n    tab.on('did-frame-finish-load', this.onFinishLoad as any)\r\n    tab.on('did-frame-navigate', this.onCommitted as any)\r\n    tab.on('did-navigate-in-page', this.onHistoryStateUpdated as any)\r\n\r\n    tab.on('frame-created', (e, { frame }) => {\r\n      if (frame.top === frame) return\r\n\r\n      frame.on('dom-ready', () => {\r\n        this.onDOMContentLoaded(tab, frame)\r\n      })\r\n    })\r\n\r\n    // Main frame dom-ready event\r\n    tab.on('dom-ready', () => {\r\n      if ('mainFrame' in tab) {\r\n        this.onDOMContentLoaded(tab, tab.mainFrame)\r\n      }\r\n    })\r\n  }\r\n\r\n  private getFrame(\r\n    event: ExtensionEvent,\r\n    details: chrome.webNavigation.GetFrameDetails\r\n  ): chrome.webNavigation.GetFrameResultDetails | null {\r\n    const tab = this.ctx.store.getTabById(details.tabId)\r\n    if (!tab) return null\r\n\r\n    let targetFrame: any\r\n\r\n    if (typeof details.frameId === 'number') {\r\n      // https://github.com/electron/electron/pull/25464\r\n      if ('mainFrame' in tab) {\r\n        const mainFrame = (tab as any).mainFrame\r\n        targetFrame = mainFrame.framesInSubtree.find((frame: any) => {\r\n          const isMainFrame = frame === frame.top\r\n          return isMainFrame ? details.frameId === 0 : details.frameId === frame.frameTreeNodeId\r\n        })\r\n      }\r\n    }\r\n\r\n    return targetFrame ? getFrameDetails(targetFrame) : null\r\n  }\r\n\r\n  private getAllFrames(\r\n    event: ExtensionEvent,\r\n    details: chrome.webNavigation.GetFrameDetails\r\n  ): chrome.webNavigation.GetAllFrameResultDetails[] | null {\r\n    const tab = this.ctx.store.getTabById(details.tabId)\r\n    if (!tab || !('mainFrame' in tab)) return []\r\n    return (tab as any).mainFrame.framesInSubtree.map(getFrameDetails)\r\n  }\r\n\r\n  private sendNavigationEvent = (eventName: string, details: { url: string }) => {\r\n    debug(`${eventName} [url: ${details.url}]`)\r\n    this.ctx.router.broadcastEvent(`webNavigation.${eventName}`, details)\r\n  }\r\n\r\n  private onCreatedNavigationTarget = (\r\n    event: Electron.IpcMainEvent,\r\n    url: string,\r\n    isInPlace: boolean,\r\n    isMainFrame: boolean,\r\n    frameProcessId: number,\r\n    frameRoutingId: number\r\n  ) => {\r\n    const frame = getFrame(frameProcessId, frameRoutingId)\r\n    const tab = event.sender\r\n    const details: chrome.webNavigation.WebNavigationSourceCallbackDetails = {\r\n      sourceTabId: tab.id,\r\n      sourceProcessId: frameProcessId,\r\n      sourceFrameId: getFrameId(frame),\r\n      url,\r\n      tabId: tab.id,\r\n      timeStamp: Date.now(),\r\n    }\r\n    this.sendNavigationEvent('onCreatedNavigationTarget', details)\r\n  }\r\n\r\n  private onBeforeNavigate = (\r\n    event: Electron.IpcMainEvent,\r\n    url: string,\r\n    isInPlace: number,\r\n    isMainFrame: boolean,\r\n    frameProcessId: number,\r\n    frameRoutingId: number\r\n  ) => {\r\n    if (isInPlace) return\r\n\r\n    const frame = getFrame(frameProcessId, frameRoutingId)\r\n    const tab = event.sender\r\n    const details: chrome.webNavigation.WebNavigationParentedCallbackDetails = {\r\n      frameId: getFrameId(frame),\r\n      parentFrameId: getParentFrameId(frame),\r\n      processId: frameProcessId,\r\n      tabId: tab.id,\r\n      timeStamp: Date.now(),\r\n      url,\r\n    }\r\n\r\n    this.sendNavigationEvent('onBeforeNavigate', details)\r\n  }\r\n\r\n  private onCommitted = (\r\n    event: Electron.IpcMainEvent,\r\n    url: string,\r\n    httpResponseCode: number,\r\n    httpStatusText: string,\r\n    isMainFrame: boolean,\r\n    frameProcessId: number,\r\n    frameRoutingId: number\r\n  ) => {\r\n    const frame = getFrame(frameProcessId, frameRoutingId)\r\n    const tab = event.sender\r\n    const details: chrome.webNavigation.WebNavigationParentedCallbackDetails = {\r\n      frameId: getFrameId(frame),\r\n      parentFrameId: getParentFrameId(frame),\r\n      processId: frameProcessId,\r\n      tabId: tab.id,\r\n      timeStamp: Date.now(),\r\n      url,\r\n    }\r\n    this.sendNavigationEvent('onCommitted', details)\r\n  }\r\n\r\n  private onHistoryStateUpdated = (\r\n    event: Electron.IpcMainEvent,\r\n    url: string,\r\n    isMainFrame: boolean,\r\n    frameProcessId: number,\r\n    frameRoutingId: number\r\n  ) => {\r\n    const frame = getFrame(frameProcessId, frameRoutingId)\r\n    const tab = event.sender\r\n    const details: chrome.webNavigation.WebNavigationTransitionCallbackDetails & {\r\n      parentFrameId: number\r\n    } = {\r\n      transitionType: '', // TODO\r\n      transitionQualifiers: [], // TODO\r\n      frameId: getFrameId(frame),\r\n      parentFrameId: getParentFrameId(frame),\r\n      processId: frameProcessId,\r\n      tabId: tab.id,\r\n      timeStamp: Date.now(),\r\n      url,\r\n    }\r\n    this.sendNavigationEvent('onHistoryStateUpdated', details)\r\n  }\r\n\r\n  private onDOMContentLoaded = (tab: Electron.WebContents, frame: Electron.WebFrameMain) => {\r\n    const details: chrome.webNavigation.WebNavigationParentedCallbackDetails = {\r\n      frameId: getFrameId(frame),\r\n      parentFrameId: getParentFrameId(frame),\r\n      processId: frame.processId,\r\n      tabId: tab.id,\r\n      timeStamp: Date.now(),\r\n      url: frame.url,\r\n    }\r\n    this.sendNavigationEvent('onDOMContentLoaded', details)\r\n\r\n    if (!tab.isLoadingMainFrame()) {\r\n      this.sendNavigationEvent('onCompleted', details)\r\n    }\r\n  }\r\n\r\n  private onFinishLoad = (\r\n    event: Electron.IpcMainEvent,\r\n    isMainFrame: boolean,\r\n    frameProcessId: number,\r\n    frameRoutingId: number\r\n  ) => {\r\n    const frame = getFrame(frameProcessId, frameRoutingId)\r\n    const tab = event.sender\r\n    const url = tab.getURL()\r\n    const details: chrome.webNavigation.WebNavigationParentedCallbackDetails = {\r\n      frameId: getFrameId(frame),\r\n      parentFrameId: getParentFrameId(frame),\r\n      processId: frameProcessId,\r\n      tabId: tab.id,\r\n      timeStamp: Date.now(),\r\n      url,\r\n    }\r\n    this.sendNavigationEvent('onCompleted', details)\r\n  }\r\n}\r\n","import { BrowserWindow } from 'electron'\r\nimport { ExtensionContext } from '../context'\r\nimport { ExtensionEvent } from '../router'\r\n\r\nconst debug = require('debug')('electron-chrome-extensions:windows')\r\n\r\nconst getWindowState = (win: BrowserWindow): chrome.windows.Window['state'] => {\r\n  if (win.isMaximized()) return 'maximized'\r\n  if (win.isMinimized()) return 'minimized'\r\n  if (win.isFullScreen()) return 'fullscreen'\r\n  return 'normal'\r\n}\r\n\r\nexport class WindowsAPI {\r\n  static WINDOW_ID_NONE = -1\r\n  static WINDOW_ID_CURRENT = -2\r\n\r\n  constructor(private ctx: ExtensionContext) {\r\n    const handle = this.ctx.router.apiHandler()\r\n    handle('windows.get', this.get.bind(this))\r\n    // TODO: how does getCurrent differ from getLastFocused?\r\n    handle('windows.getCurrent', this.getCurrent.bind(this))\r\n    handle('windows.getLastFocused', this.getLastFocused.bind(this))\r\n    handle('windows.getAll', this.getAll.bind(this))\r\n    handle('windows.create', this.create.bind(this))\r\n    handle('windows.update', this.update.bind(this))\r\n    handle('windows.remove', this.remove.bind(this))\r\n\r\n    this.ctx.store.on('window-added', this.observeWindow.bind(this))\r\n  }\r\n\r\n  private observeWindow(window: Electron.BrowserWindow) {\r\n    const windowId = window.id\r\n\r\n    window.on('focus', () => {\r\n      this.onFocusChanged(windowId)\r\n    })\r\n\r\n    window.once('closed', () => {\r\n      this.ctx.store.windowDetailsCache.delete(windowId)\r\n      this.ctx.store.removeWindow(window)\r\n      this.onRemoved(windowId)\r\n    })\r\n\r\n    this.onCreated(windowId)\r\n\r\n    debug(`Observing window[${windowId}]`)\r\n  }\r\n\r\n  private createWindowDetails(win: BrowserWindow) {\r\n    const details: Partial<chrome.windows.Window> = {\r\n      id: win.id,\r\n      focused: win.isFocused(),\r\n      top: win.getPosition()[1],\r\n      left: win.getPosition()[0],\r\n      width: win.getSize()[0],\r\n      height: win.getSize()[1],\r\n      tabs: Array.from(this.ctx.store.tabs)\r\n        .filter((tab) => {\r\n          const ownerWindow = this.ctx.store.tabToWindow.get(tab)\r\n          return ownerWindow?.isDestroyed() ? false : ownerWindow?.id === win.id\r\n        })\r\n        .map((tab) => this.ctx.store.tabDetailsCache.get(tab.id) as chrome.tabs.Tab)\r\n        .filter(Boolean),\r\n      incognito: !win.webContents.session.isPersistent(),\r\n      type: 'normal', // TODO\r\n      state: getWindowState(win),\r\n      alwaysOnTop: win.isAlwaysOnTop(),\r\n      sessionId: 'default', // TODO\r\n    }\r\n\r\n    this.ctx.store.windowDetailsCache.set(win.id, details)\r\n    return details\r\n  }\r\n\r\n  private getWindowDetails(win: BrowserWindow) {\r\n    if (this.ctx.store.windowDetailsCache.has(win.id)) {\r\n      return this.ctx.store.windowDetailsCache.get(win.id)\r\n    }\r\n    const details = this.createWindowDetails(win)\r\n    return details\r\n  }\r\n\r\n  private getWindowFromId(id: number) {\r\n    if (id === WindowsAPI.WINDOW_ID_CURRENT) {\r\n      return this.ctx.store.getCurrentWindow()\r\n    } else {\r\n      return this.ctx.store.getWindowById(id)\r\n    }\r\n  }\r\n\r\n  private get(event: ExtensionEvent, windowId: number) {\r\n    const win = this.getWindowFromId(windowId)\r\n    if (!win) return { id: WindowsAPI.WINDOW_ID_NONE }\r\n    return this.getWindowDetails(win)\r\n  }\r\n\r\n  private getCurrent(event: ExtensionEvent) {\r\n    const win = this.ctx.store.getWindowByWebContents(event.sender)\r\n    return win ? this.getWindowDetails(win) : null\r\n  }\r\n\r\n  private getLastFocused(event: ExtensionEvent) {\r\n    const win = this.ctx.store.getLastFocusedWindow()\r\n    return win ? this.getWindowDetails(win) : null\r\n  }\r\n\r\n  private getAll(event: ExtensionEvent) {\r\n    return Array.from(this.ctx.store.windows).map(this.getWindowDetails.bind(this))\r\n  }\r\n\r\n  private async create(event: ExtensionEvent, details: chrome.windows.CreateData) {\r\n    if(details.url){\r\n      const scheme = event.extension.url;\r\n      if(typeof details.url == 'string'){\r\n        if(details.url.indexOf('://') < 0){\r\n          details.url = scheme + details.url;\r\n        }\r\n      } else {\r\n        details.url.forEach((value, index) => {\r\n          if(value.indexOf('://') < 0){\r\n            (details.url as string[]) [index] = scheme + value;\r\n          }\r\n        });\r\n      }\r\n    }\r\n    const win = await this.ctx.store.createWindow(event, details)\r\n    return this.getWindowDetails(win)\r\n  }\r\n\r\n  private async update(\r\n    event: ExtensionEvent,\r\n    windowId: number,\r\n    updateProperties: chrome.windows.UpdateInfo = {}\r\n  ) {\r\n    const win = this.getWindowFromId(windowId)\r\n    if (!win) return\r\n\r\n    const props = updateProperties\r\n\r\n    if (props.state) {\r\n      switch (props.state) {\r\n        case 'maximized':\r\n          win.maximize()\r\n          break\r\n        case 'minimized':\r\n          win.minimize()\r\n          break\r\n        case 'normal': {\r\n          if (win.isMinimized() || win.isMaximized()) {\r\n            win.restore()\r\n          }\r\n          break\r\n        }\r\n      }\r\n    }\r\n\r\n    return this.createWindowDetails(win)\r\n  }\r\n\r\n  private async remove(event: ExtensionEvent, windowId: number = WindowsAPI.WINDOW_ID_CURRENT) {\r\n    const win = this.getWindowFromId(windowId)\r\n    if (!win) return\r\n    const removedWindowId = win.id\r\n    await this.ctx.store.removeWindow(win)\r\n    this.onRemoved(removedWindowId)\r\n  }\r\n\r\n  onCreated(windowId: number) {\r\n    const window = this.ctx.store.getWindowById(windowId)\r\n    if (!window) return\r\n    const windowDetails = this.getWindowDetails(window)\r\n    this.ctx.router.broadcastEvent('windows.onCreated', windowDetails)\r\n  }\r\n\r\n  onRemoved(windowId: number) {\r\n    this.ctx.router.broadcastEvent('windows.onRemoved', windowId)\r\n  }\r\n\r\n  onFocusChanged(windowId: number) {\r\n    if (this.ctx.store.lastFocusedWindowId === windowId) return\r\n\r\n    this.ctx.store.lastFocusedWindowId = windowId\r\n    this.ctx.router.broadcastEvent('windows.onFocusChanged', windowId)\r\n  }\r\n}\r\n","import { app, session as electronSession } from 'electron'\r\nimport { EventEmitter } from 'events'\r\nimport path from 'path'\r\nimport { promises as fs } from 'fs'\r\n\r\nimport { BrowserActionAPI } from './api/browser-action'\r\nimport { TabsAPI } from './api/tabs'\r\nimport { WindowsAPI } from './api/windows'\r\nimport { WebNavigationAPI } from './api/web-navigation'\r\nimport { ExtensionStore } from './store'\r\nimport { ContextMenusAPI } from './api/context-menus'\r\nimport { RuntimeAPI } from './api/runtime'\r\nimport { CookiesAPI } from './api/cookies'\r\nimport { NotificationsAPI } from './api/notifications'\r\nimport { ChromeExtensionImpl } from './impl'\r\nimport { CommandsAPI } from './api/commands'\r\nimport { ExtensionContext } from './context'\r\nimport { ExtensionRouter } from './router'\r\n\r\nexport interface ChromeExtensionOptions extends ChromeExtensionImpl {\r\n  session?: Electron.Session\r\n\r\n  /**\r\n   * Path to electron-chrome-extensions module files. Might be needed if\r\n   * JavaScript bundlers like Webpack are used in your build process.\r\n   */\r\n  modulePath?: string\r\n}\r\n\r\nconst sessionMap = new WeakMap<Electron.Session, ElectronChromeExtensions>()\r\n\r\n/**\r\n * Provides an implementation of various Chrome extension APIs to a session.\r\n */\r\nexport class ElectronChromeExtensions extends EventEmitter {\r\n  /** Retrieve an instance of this class associated with the given session. */\r\n  static fromSession(session: Electron.Session) {\r\n    return sessionMap.get(session)\r\n  }\r\n\r\n  private ctx: ExtensionContext\r\n  private modulePath: string\r\n\r\n  private api: {\r\n    browserAction: BrowserActionAPI\r\n    contextMenus: ContextMenusAPI\r\n    commands: CommandsAPI\r\n    cookies: CookiesAPI\r\n    notifications: NotificationsAPI\r\n    runtime: RuntimeAPI\r\n    tabs: TabsAPI\r\n    webNavigation: WebNavigationAPI\r\n    windows: WindowsAPI\r\n  }\r\n\r\n  constructor(opts?: ChromeExtensionOptions) {\r\n    super()\r\n\r\n    const { session = electronSession.defaultSession, modulePath, ...impl } = opts || {}\r\n\r\n    if (sessionMap.has(session)) {\r\n      throw new Error(`Extensions instance already exists for the given session`)\r\n    }\r\n\r\n    sessionMap.set(session, this)\r\n\r\n    const router = new ExtensionRouter(session)\r\n    const store = new ExtensionStore(impl)\r\n\r\n    this.ctx = {\r\n      emit: this.emit.bind(this),\r\n      router,\r\n      session,\r\n      store,\r\n    }\r\n\r\n    this.modulePath = modulePath || path.join(__dirname, '..')\r\n\r\n    this.api = {\r\n      browserAction: new BrowserActionAPI(this.ctx),\r\n      contextMenus: new ContextMenusAPI(this.ctx),\r\n      commands: new CommandsAPI(this.ctx),\r\n      cookies: new CookiesAPI(this.ctx),\r\n      notifications: new NotificationsAPI(this.ctx),\r\n      runtime: new RuntimeAPI(this.ctx),\r\n      tabs: new TabsAPI(this.ctx),\r\n      webNavigation: new WebNavigationAPI(this.ctx),\r\n      windows: new WindowsAPI(this.ctx),\r\n    }\r\n\r\n    this.prependPreload()\r\n  }\r\n\r\n  private async prependPreload() {\r\n    const { session } = this.ctx\r\n    let preloads = session.getPreloads()\r\n\r\n    const preloadPath = path.join(this.modulePath, 'dist/preload.js')\r\n\r\n    const preloadIndex = preloads.indexOf(preloadPath)\r\n    if (preloadIndex > -1) {\r\n      preloads.splice(preloadIndex, 1)\r\n    }\r\n\r\n    preloads = [preloadPath, ...preloads]\r\n    session.setPreloads(preloads)\r\n\r\n    let preloadExists = false\r\n    try {\r\n      const stat = await fs.stat(preloadPath)\r\n      preloadExists = stat.isFile()\r\n    } catch {}\r\n\r\n    if (!preloadExists) {\r\n      console.error(\r\n        `Unable to access electron-chrome-extensions preload file (${preloadPath}). Consider configuring the 'modulePath' constructor option.`\r\n      )\r\n    }\r\n  }\r\n\r\n  /** Add webContents to be tracked as a tab. */\r\n  addTab(tab: Electron.WebContents, window: Electron.BrowserWindow) {\r\n    this.ctx.store.addTab(tab, window)\r\n  }\r\n\r\n  /** Notify extension system that the active tab has changed. */\r\n  selectTab(tab: Electron.WebContents) {\r\n    if (this.ctx.store.tabs.has(tab)) {\r\n      this.api.tabs.onActivated(tab.id)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Add webContents to be tracked as an extension host which will receive\r\n   * extension events when a chrome-extension:// resource is loaded.\r\n   *\r\n   * This is usually reserved for extension background pages and popups, but\r\n   * can also be used in other special cases.\r\n   *\r\n   * @deprecated Extension hosts are now tracked lazily when they send\r\n   * extension IPCs to the main process.\r\n   */\r\n  addExtensionHost(host: Electron.WebContents) {\r\n    console.warn('ElectronChromeExtensions.addExtensionHost() is deprecated')\r\n  }\r\n\r\n  /**\r\n   * Get collection of menu items managed by the `chrome.contextMenus` API.\r\n   * @see https://developer.chrome.com/extensions/contextMenus\r\n   */\r\n  getContextMenuItems(webContents: Electron.WebContents, params: Electron.ContextMenuParams) {\r\n    return this.api.contextMenus.buildMenuItemsForParams(webContents, params)\r\n  }\r\n\r\n  /**\r\n   * Add extensions to be visible as an extension action button.\r\n   *\r\n   * @deprecated Not needed in Electron >=12.\r\n   */\r\n  addExtension(extension: Electron.Extension) {\r\n    console.warn('ElectronChromeExtensions.addExtension() is deprecated')\r\n    this.api.browserAction.processExtension(extension)\r\n  }\r\n\r\n  /**\r\n   * Remove extensions from the list of visible extension action buttons.\r\n   *\r\n   * @deprecated Not needed in Electron >=12.\r\n   */\r\n  removeExtension(extension: Electron.Extension) {\r\n    console.warn('ElectronChromeExtensions.removeExtension() is deprecated')\r\n    this.api.browserAction.removeActions(extension.id)\r\n  }\r\n}\r\n\r\n/**\r\n * @deprecated Use `ElectronChromeExtensions` instead.\r\n */\r\nexport const Extensions = ElectronChromeExtensions\r\n","import { BrowserWindow, Session } from 'electron'\r\n\r\nconst debug = require('debug')('electron-chrome-extensions:popup')\r\n\r\nexport interface PopupAnchorRect {\r\n  x: number\r\n  y: number\r\n  width: number\r\n  height: number\r\n}\r\n\r\ninterface PopupViewOptions {\r\n  extensionId: string\r\n  session: Session\r\n  parent: BrowserWindow\r\n  url: string\r\n  anchorRect: PopupAnchorRect\r\n}\r\n\r\nexport class PopupView {\r\n  static POSITION_PADDING = 5\r\n\r\n  static BOUNDS = {\r\n    minWidth: 25,\r\n    minHeight: 25,\r\n    maxWidth: 800,\r\n    maxHeight: 600,\r\n  }\r\n\r\n  browserWindow?: BrowserWindow\r\n  parent?: BrowserWindow\r\n  extensionId: string\r\n\r\n  private anchorRect: PopupAnchorRect\r\n  private destroyed: boolean = false\r\n\r\n  /** Preferred size changes are only received in Electron v12+ */\r\n  private usingPreferredSize = false\r\n\r\n  private readyPromise: Promise<void>\r\n\r\n  constructor(opts: PopupViewOptions) {\r\n    this.parent = opts.parent\r\n    this.extensionId = opts.extensionId\r\n    this.anchorRect = opts.anchorRect\r\n\r\n    this.browserWindow = new BrowserWindow({\r\n      show: false,\r\n      frame: false,\r\n      parent: opts.parent,\r\n      movable: false,\r\n      maximizable: false,\r\n      minimizable: false,\r\n      resizable: false,\r\n      skipTaskbar: true,\r\n      backgroundColor: '#ffffff',\r\n      webPreferences: {\r\n        session: opts.session,\r\n        sandbox: true,\r\n        nodeIntegration: false,\r\n        nodeIntegrationInWorker: false,\r\n        nativeWindowOpen: true,\r\n        worldSafeExecuteJavaScript: true,\r\n        contextIsolation: true,\r\n        ...({\r\n          enablePreferredSizeMode: true,\r\n        } as any),\r\n      },\r\n    })\r\n\r\n    const untypedWebContents = this.browserWindow.webContents as any\r\n    untypedWebContents.on('preferred-size-changed', this.updatePreferredSize)\r\n\r\n    this.browserWindow.webContents.on('devtools-closed', this.maybeClose)\r\n    this.browserWindow.on('blur', this.maybeClose)\r\n    this.browserWindow.on('closed', this.destroy)\r\n    this.parent.once('closed', this.destroy)\r\n\r\n    this.readyPromise = this.load(opts.url)\r\n  }\r\n\r\n  private async load(url: string): Promise<void> {\r\n    const win = this.browserWindow!\r\n\r\n    try {\r\n      await win.webContents.loadURL(url)\r\n    } catch (e) {\r\n      console.error(e)\r\n    }\r\n\r\n    if (this.destroyed) return\r\n\r\n    if (!this.usingPreferredSize) {\r\n      // Set large initial size to avoid overflow\r\n      this.setSize({ width: PopupView.BOUNDS.maxWidth, height: PopupView.BOUNDS.maxHeight })\r\n\r\n      // Wait for content and layout to load\r\n      await new Promise((resolve) => setTimeout(resolve, 100))\r\n      if (this.destroyed) return\r\n\r\n      await this.queryPreferredSize()\r\n      if (this.destroyed) return\r\n    }\r\n\r\n    win.show()\r\n  }\r\n\r\n  destroy = () => {\r\n    if (this.destroyed) return\r\n\r\n    this.destroyed = true\r\n\r\n    debug(`destroying ${this.extensionId}`)\r\n\r\n    if (this.parent) {\r\n      if (!this.parent.isDestroyed()) {\r\n        this.parent.off('closed', this.destroy)\r\n      }\r\n      this.parent = undefined\r\n    }\r\n\r\n    if (this.browserWindow) {\r\n      if (!this.browserWindow.isDestroyed()) {\r\n        const { webContents } = this.browserWindow\r\n\r\n        if(!webContents.isDestroyed()){\r\n          if(webContents.isDevToolsOpened()){\r\n            webContents.closeDevTools()\r\n          }\r\n          (webContents as any).destroy()\r\n        }\r\n\r\n        this.browserWindow.off('closed', this.destroy)\r\n        this.browserWindow.destroy()\r\n      }\r\n\r\n      this.browserWindow = undefined\r\n    }\r\n  }\r\n\r\n  isDestroyed() {\r\n    return this.destroyed\r\n  }\r\n\r\n  /** Resolves when the popup finishes loading. */\r\n  whenReady() {\r\n    return this.readyPromise\r\n  }\r\n\r\n  setSize(rect: Partial<Electron.Rectangle>) {\r\n    if (!this.browserWindow || !this.parent) return\r\n\r\n    const width = Math.floor(\r\n      Math.min(PopupView.BOUNDS.maxWidth, Math.max(rect.width || 0, PopupView.BOUNDS.minWidth))\r\n    )\r\n\r\n    const height = Math.floor(\r\n      Math.min(PopupView.BOUNDS.maxHeight, Math.max(rect.height || 0, PopupView.BOUNDS.minHeight))\r\n    )\r\n\r\n    debug(`setSize`, { width, height })\r\n\r\n    this.browserWindow?.setBounds({\r\n      ...this.browserWindow.getBounds(),\r\n      width,\r\n      height,\r\n    })\r\n  }\r\n\r\n  private maybeClose = () => {\r\n    // Keep open if webContents is being inspected\r\n    if (!this.browserWindow?.isDestroyed() && this.browserWindow?.webContents.isDevToolsOpened()) {\r\n      debug('preventing close due to DevTools being open')\r\n      return\r\n    }\r\n\r\n    // For extension popups with a login form, the user may need to access a\r\n    // program outside of the app. Closing the popup would then add\r\n    // inconvenience.\r\n    if (!BrowserWindow.getFocusedWindow()) {\r\n      debug('preventing close due to focus residing outside of the app')\r\n      return\r\n    }\r\n\r\n    this.destroy()\r\n  }\r\n\r\n  private updatePosition() {\r\n    if (!this.browserWindow || !this.parent) return\r\n\r\n    const winBounds = this.parent.getBounds()\r\n    const viewBounds = this.browserWindow.getBounds()\r\n\r\n    // TODO: support more orientations than just top-right\r\n    let x = winBounds.x + this.anchorRect.x + this.anchorRect.width - viewBounds.width\r\n    let y = winBounds.y + this.anchorRect.y + this.anchorRect.height + PopupView.POSITION_PADDING\r\n\r\n    // Convert to ints\r\n    x = Math.floor(x)\r\n    y = Math.floor(y)\r\n\r\n    debug(`updatePosition`, { x, y })\r\n\r\n    this.browserWindow.setBounds({\r\n      ...this.browserWindow.getBounds(),\r\n      x,\r\n      y,\r\n    })\r\n  }\r\n\r\n  /** Backwards compat for Electron <12 */\r\n  private async queryPreferredSize() {\r\n    if (this.usingPreferredSize || this.destroyed) return\r\n\r\n    const rect = await this.browserWindow!.webContents.executeJavaScript(\r\n      `((${() => {\r\n        const rect = document.body.getBoundingClientRect()\r\n        return { width: rect.width, height: rect.height }\r\n      }})())`\r\n    )\r\n\r\n    if (this.destroyed) return\r\n\r\n    this.setSize({ width: rect.width, height: rect.height })\r\n    this.updatePosition()\r\n  }\r\n\r\n  private updatePreferredSize = (event: Electron.Event, size: Electron.Size) => {\r\n    debug('updatePreferredSize', size)\r\n    this.usingPreferredSize = true\r\n    this.setSize(size)\r\n    this.updatePosition()\r\n  }\r\n}\r\n","import { app, Extension, ipcMain, session, Session, WebContents } from 'electron'\r\n\r\nconst createDebug = require('debug')\r\n\r\n// Shorten base64 encoded icons\r\nconst shortenValues = (k: string, v: any) =>\r\n  typeof v === 'string' && v.length > 128 ? v.substr(0, 128) + '...' : v\r\n\r\ncreateDebug.formatters.r = (value: any) => {\r\n  return value ? JSON.stringify(value, shortenValues, '  ') : value\r\n}\r\n\r\nconst debug = createDebug('electron-chrome-extensions:router')\r\n\r\nconst DEFAULT_SESSION = '_self'\r\n\r\ninterface RoutingDelegateObserver {\r\n  session: Electron.Session\r\n  onExtensionMessage(\r\n    event: Electron.IpcMainInvokeEvent,\r\n    extensionId: string | undefined,\r\n    handlerName: string,\r\n    ...args: any[]\r\n  ): Promise<void>\r\n  addListener(listener: EventListener, extensionId: string, eventName: string): void\r\n  removeListener(listener: EventListener, extensionId: string, eventName: string): void\r\n}\r\n\r\nlet gRoutingDelegate: RoutingDelegate\r\n\r\n/**\r\n * Handles event routing IPCs and delivers them to the observer with the\r\n * associated session.\r\n */\r\nclass RoutingDelegate {\r\n  static get() {\r\n    return gRoutingDelegate || (gRoutingDelegate = new RoutingDelegate())\r\n  }\r\n\r\n  private sessionMap: WeakMap<Session, RoutingDelegateObserver> = new WeakMap()\r\n\r\n  private constructor() {\r\n    ipcMain.handle('crx-msg', this.onRouterMessage)\r\n    ipcMain.handle('crx-msg-remote', this.onRemoteMessage)\r\n    ipcMain.on('crx-add-listener', this.onAddListener)\r\n    ipcMain.on('crx-remove-listener', this.onRemoveListener)\r\n  }\r\n\r\n  addObserver(observer: RoutingDelegateObserver) {\r\n    this.sessionMap.set(observer.session, observer)\r\n  }\r\n\r\n  private onRouterMessage = async (\r\n    event: Electron.IpcMainInvokeEvent,\r\n    extensionId: string,\r\n    handlerName: string,\r\n    ...args: any[]\r\n  ) => {\r\n    debug(`received '${handlerName}'`, args)\r\n\r\n    const observer = this.sessionMap.get(event.sender.session)\r\n\r\n    return observer?.onExtensionMessage(event, extensionId, handlerName, ...args)\r\n  }\r\n\r\n  private onRemoteMessage = async (\r\n    event: Electron.IpcMainInvokeEvent,\r\n    sessionPartition: string,\r\n    handlerName: string,\r\n    ...args: any[]\r\n  ) => {\r\n    debug(`received remote '${handlerName}' for '${sessionPartition}'`, args)\r\n\r\n    const ses =\r\n      sessionPartition === DEFAULT_SESSION\r\n        ? event.sender.session\r\n        : session.fromPartition(sessionPartition)\r\n\r\n    const observer = this.sessionMap.get(ses)\r\n\r\n    return observer?.onExtensionMessage(event, undefined, handlerName, ...args)\r\n  }\r\n\r\n  private onAddListener = (\r\n    event: Electron.IpcMainInvokeEvent,\r\n    extensionId: string,\r\n    eventName: string\r\n  ) => {\r\n    const observer = this.sessionMap.get(event.sender.session)\r\n    const listener: EventListener = { host: event.sender, extensionId }\r\n    return observer?.addListener(listener, extensionId, eventName)\r\n  }\r\n\r\n  private onRemoveListener = (\r\n    event: Electron.IpcMainInvokeEvent,\r\n    extensionId: string,\r\n    eventName: string\r\n  ) => {\r\n    const observer = this.sessionMap.get(event.sender.session)\r\n    const listener: EventListener = { host: event.sender, extensionId }\r\n    return observer?.removeListener(listener, extensionId, eventName)\r\n  }\r\n}\r\n\r\nexport interface ExtensionEvent {\r\n  sender: WebContents\r\n  extension: Extension\r\n}\r\n\r\nexport type HandlerCallback = (event: ExtensionEvent, ...args: any[]) => any\r\n\r\nexport interface HandlerOptions {\r\n  /** Whether the handler can be invoked on behalf of a different session. */\r\n  allowRemote?: boolean\r\n  /** Whether an extension context is required to invoke the handler. */\r\n  extensionContext: boolean\r\n}\r\n\r\ninterface Handler extends HandlerOptions {\r\n  callback: HandlerCallback\r\n}\r\n\r\n/** e.g. 'tabs.query' */\r\ntype EventName = string\r\n\r\ntype HandlerMap = Map<EventName, Handler>\r\n\r\ninterface EventListener {\r\n  host: Electron.WebContents\r\n  extensionId: string\r\n}\r\n\r\nconst eventListenerEquals = (eventListener: EventListener) => (other: EventListener) =>\r\n  other.host === eventListener.host && other.extensionId === eventListener.extensionId\r\n\r\nexport class ExtensionRouter {\r\n  private handlers: HandlerMap = new Map()\r\n  private listeners: Map<EventName, EventListener[]> = new Map()\r\n\r\n  /**\r\n   * Collection of all extension hosts in the session.\r\n   *\r\n   * Currently the router has no ability to wake up non-persistent background\r\n   * scripts to deliver events. For now we just hold a reference to them to\r\n   * prevent them from being terminated.\r\n   */\r\n  private extensionHosts: Set<Electron.WebContents> = new Set()\r\n\r\n  constructor(\r\n    public session: Electron.Session,\r\n    private delegate: RoutingDelegate = RoutingDelegate.get()\r\n  ) {\r\n    this.delegate.addObserver(this)\r\n\r\n    session.on('extension-unloaded', (event, extension) => {\r\n      this.filterListeners((listener) => listener.extensionId !== extension.id)\r\n    })\r\n\r\n    app.on('web-contents-created', (event, webContents) => {\r\n      if (webContents.session === this.session && webContents.getType() === 'backgroundPage') {\r\n        debug(`storing reference to background host [url:'${webContents.getURL()}']`)\r\n        this.extensionHosts.add(webContents)\r\n      }\r\n    })\r\n  }\r\n\r\n  private filterListeners(predicate: (listener: EventListener) => boolean) {\r\n    for (const [eventName, listeners] of this.listeners) {\r\n      const filteredListeners = listeners.filter(predicate)\r\n      const delta = listeners.length - filteredListeners.length\r\n\r\n      if (filteredListeners.length > 0) {\r\n        this.listeners.set(eventName, filteredListeners)\r\n      } else {\r\n        this.listeners.delete(eventName)\r\n      }\r\n\r\n      if (delta > 0) {\r\n        debug(`removed ${delta} listener(s) for '${eventName}'`)\r\n      }\r\n    }\r\n  }\r\n\r\n  private observeListenerHost(host: Electron.WebContents) {\r\n    debug(`observing listener [id:${host.id}, url:'${host.getURL()}']`)\r\n    host.once('destroyed', () => {\r\n      debug(`extension host destroyed [id:${host.id}]`)\r\n      this.filterListeners((listener) => listener.host !== host)\r\n    })\r\n  }\r\n\r\n  addListener(listener: EventListener, extensionId: string, eventName: string) {\r\n    const { listeners, session } = this\r\n\r\n    const extension = session.getExtension(extensionId)\r\n    if (!extension) {\r\n      throw new Error(`extension not registered in session [extensionId:${extensionId}]`)\r\n    }\r\n\r\n    if (!listeners.has(eventName)) {\r\n      listeners.set(eventName, [])\r\n    }\r\n\r\n    const eventListeners = listeners.get(eventName)!\r\n    const existingEventListener = eventListeners.find(eventListenerEquals(listener))\r\n\r\n    if (existingEventListener) {\r\n      debug(`ignoring existing '${eventName}' event listener for ${extensionId}`)\r\n    } else {\r\n      debug(`adding '${eventName}' event listener for ${extensionId}`)\r\n      eventListeners.push(listener)\r\n      this.observeListenerHost(listener.host)\r\n    }\r\n  }\r\n\r\n  removeListener(listener: EventListener, extensionId: string, eventName: string) {\r\n    const { listeners } = this\r\n\r\n    const eventListeners = listeners.get(eventName)\r\n    if (!eventListeners) {\r\n      console.error(`event listener not registered for '${eventName}'`)\r\n      return\r\n    }\r\n\r\n    const index = eventListeners.findIndex(eventListenerEquals(listener))\r\n\r\n    if (index >= 0) {\r\n      debug(`removing '${eventName}' event listener for ${extensionId}`)\r\n      eventListeners.splice(index, 1)\r\n    }\r\n\r\n    if (eventListeners.length === 0) {\r\n      listeners.delete(eventName)\r\n    }\r\n  }\r\n\r\n  private getHandler(handlerName: string) {\r\n    const handler = this.handlers.get(handlerName)\r\n    if (!handler) {\r\n      throw new Error(`${handlerName} is not a registered handler`)\r\n    }\r\n\r\n    return handler\r\n  }\r\n\r\n  async onExtensionMessage(\r\n    event: Electron.IpcMainInvokeEvent,\r\n    extensionId: string | undefined,\r\n    handlerName: string,\r\n    ...args: any[]\r\n  ) {\r\n    const { session } = this\r\n    const { sender } = event\r\n    const handler = this.getHandler(handlerName)\r\n\r\n    if (sender.session !== session && !handler.allowRemote) {\r\n      throw new Error(`${handlerName} does not support calling from a remote session`)\r\n    }\r\n\r\n    const extension = extensionId ? sender.session.getExtension(extensionId) : undefined\r\n    if (!extension && handler.extensionContext) {\r\n      throw new Error(`${handlerName} was sent from an unknown extension context`)\r\n    }\r\n\r\n    const extEvent = {\r\n      sender,\r\n      extension: extension!,\r\n    }\r\n\r\n    const result = await handler.callback(extEvent, ...args)\r\n\r\n    debug(`${handlerName} result: %r`, result)\r\n\r\n    return result\r\n  }\r\n\r\n  private handle(name: string, callback: HandlerCallback, opts?: HandlerOptions): void {\r\n    this.handlers.set(name, {\r\n      callback,\r\n      extensionContext: typeof opts?.extensionContext === 'boolean' ? opts.extensionContext : true,\r\n      allowRemote: typeof opts?.allowRemote === 'boolean' ? opts.allowRemote : false,\r\n    })\r\n  }\r\n\r\n  /** Returns a callback to register API handlers for the given context. */\r\n  apiHandler() {\r\n    return (name: string, callback: HandlerCallback, opts?: HandlerOptions) => {\r\n      this.handle(name, callback, opts)\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Sends extension event to the host for the given extension ID if it\r\n   * registered a listener for it.\r\n   */\r\n  sendEvent(extensionId: string | undefined, eventName: string, ...args: any[]) {\r\n    const { listeners } = this\r\n\r\n    let eventListeners = listeners.get(eventName)\r\n\r\n    if (extensionId) {\r\n      // TODO: extension permissions check\r\n\r\n      eventListeners = eventListeners?.filter((el) => el.extensionId === extensionId)\r\n    }\r\n\r\n    if (!eventListeners || eventListeners.length === 0) {\r\n      //debug(`ignoring '${eventName}' event with no listeners`)\r\n      return\r\n    }\r\n\r\n    for (const { host } of eventListeners) {\r\n      // TODO: may need to wake lazy extension context\r\n      if (host.isDestroyed()) {\r\n        console.error(`Unable to send '${eventName}' to extension host for ${extensionId}`)\r\n        continue\r\n      }\r\n\r\n      const ipcName = `crx-${eventName}`\r\n      host.send(ipcName, ...args)\r\n    }\r\n  }\r\n\r\n  /** Broadcasts extension event to all extension hosts listening for it. */\r\n  broadcastEvent(eventName: string, ...args: any[]) {\r\n    this.sendEvent(undefined, eventName, ...args)\r\n  }\r\n}\r\n","import { BrowserWindow, webContents } from 'electron'\r\nimport { EventEmitter } from 'events'\r\nimport { ContextMenuType } from './api/common'\r\nimport { ChromeExtensionImpl } from './impl'\r\nimport { ExtensionEvent } from './router'\r\n\r\nconst debug = require('debug')('electron-chrome-extensions:store')\r\n\r\nexport class ExtensionStore extends EventEmitter {\r\n  /** Tabs observed by the extensions system. */\r\n  tabs = new Set<Electron.WebContents>()\r\n\r\n  /** Windows observed by the extensions system. */\r\n  windows = new Set<Electron.BrowserWindow>()\r\n\r\n  lastFocusedWindowId?: number\r\n\r\n  /**\r\n   * Map of tabs to their parent window.\r\n   *\r\n   * It's not possible to access the parent of a BrowserView so we must manage\r\n   * this ourselves.\r\n   */\r\n  tabToWindow = new WeakMap<Electron.WebContents, Electron.BrowserWindow>()\r\n\r\n  /** Map of windows to their active tab. */\r\n  private windowToActiveTab = new WeakMap<Electron.BrowserWindow, Electron.WebContents>()\r\n\r\n  tabDetailsCache = new Map<number, Partial<chrome.tabs.Tab>>()\r\n  windowDetailsCache = new Map<number, Partial<chrome.windows.Window>>()\r\n\r\n  constructor(public impl: ChromeExtensionImpl) {\r\n    super()\r\n  }\r\n\r\n  getWindowById(windowId: number) {\r\n    return Array.from(this.windows).find(\r\n      (window) => !window.isDestroyed() && window.id === windowId\r\n    )\r\n  }\r\n\r\n  getWindowByWebContents(wc: Electron.WebContents){\r\n    return this.tabToWindow.get(wc)\r\n  }\r\n\r\n  getLastFocusedWindow() {\r\n    return this.lastFocusedWindowId ? this.getWindowById(this.lastFocusedWindowId) : null\r\n  }\r\n\r\n  getCurrentWindow() {\r\n    return this.getLastFocusedWindow()\r\n  }\r\n\r\n  addWindow(window: Electron.BrowserWindow) {\r\n    if (this.windows.has(window)) return\r\n\r\n    this.windows.add(window)\r\n\r\n    if (typeof this.lastFocusedWindowId !== 'number') {\r\n      this.lastFocusedWindowId = window.id\r\n    }\r\n\r\n    this.emit('window-added', window)\r\n  }\r\n\r\n  async createWindow(event: ExtensionEvent, details: chrome.windows.CreateData) {\r\n    if (typeof this.impl.createWindow !== 'function') {\r\n      throw new Error('createWindow is not implemented')\r\n    }\r\n\r\n    const win = await this.impl.createWindow(details)\r\n\r\n    this.addWindow(win)\r\n\r\n    return win\r\n  }\r\n\r\n  async removeWindow(window: Electron.BrowserWindow) {\r\n    if (!this.windows.has(window)) return\r\n\r\n    this.windows.delete(window)\r\n\r\n    if (typeof this.impl.removeWindow === 'function') {\r\n      await this.impl.removeWindow(window)\r\n    } else {\r\n      window.destroy()\r\n    }\r\n  }\r\n\r\n  getTabById(tabId: number) {\r\n    return Array.from(this.tabs).find((tab) => !tab.isDestroyed() && tab.id === tabId)\r\n  }\r\n\r\n  addTab(tab: Electron.WebContents, window: Electron.BrowserWindow) {\r\n    if (this.tabs.has(tab)) return\r\n\r\n    this.tabs.add(tab)\r\n    this.tabToWindow.set(tab, window)\r\n    this.addWindow(window)\r\n\r\n    const activeTab = this.getActiveTabFromWebContents(tab)\r\n    if (!activeTab) {\r\n      this.setActiveTab(tab)\r\n    }\r\n\r\n    this.emit('tab-added', tab)\r\n  }\r\n\r\n  removeTab(tab: Electron.WebContents) {\r\n    if (!this.tabs.has(tab)) return\r\n\r\n    const tabId = tab.id\r\n    const win = this.tabToWindow.get(tab)!\r\n\r\n    this.tabs.delete(tab)\r\n    this.tabToWindow.delete(tab)\r\n\r\n    // TODO: clear active tab\r\n\r\n    // Clear window if it has no remaining tabs\r\n    const windowHasTabs = Array.from(this.tabs).find((tab) => this.tabToWindow.get(tab) === win)\r\n    if (!windowHasTabs) {\r\n      this.windows.delete(win)\r\n    }\r\n\r\n    if (typeof this.impl.removeTab === 'function') {\r\n      this.impl.removeTab(tab, win)\r\n    }\r\n\r\n    this.emit('tab-removed', tabId)\r\n  }\r\n\r\n  async createTab(details: chrome.tabs.CreateProperties) {\r\n    if (typeof this.impl.createTab !== 'function') {\r\n      throw new Error('createTab is not implemented')\r\n    }\r\n\r\n    // Fallback to current window\r\n    if (!details.windowId) {\r\n      details.windowId = this.lastFocusedWindowId\r\n    }\r\n\r\n    const result = await this.impl.createTab(details)\r\n\r\n    if (!Array.isArray(result)) {\r\n      throw new Error('createTab must return an array of [tab, window]')\r\n    }\r\n\r\n    const [tab, window] = result\r\n\r\n    if (typeof tab !== 'object' || !webContents.fromId(tab.id)) {\r\n      throw new Error('createTab must return a WebContents')\r\n    } else if (typeof window !== 'object') {\r\n      throw new Error('createTab must return a BrowserWindow')\r\n    }\r\n\r\n    this.addTab(tab, window)\r\n\r\n    return tab\r\n  }\r\n\r\n  getActiveTabFromWindow(win: Electron.BrowserWindow) {\r\n    const activeTab = win && !win.isDestroyed() && this.windowToActiveTab.get(win)\r\n    return (activeTab && !activeTab.isDestroyed() && activeTab) || undefined\r\n  }\r\n\r\n  getActiveTabFromWebContents(wc: Electron.WebContents): Electron.WebContents | undefined {\r\n    const win = this.tabToWindow.get(wc) || BrowserWindow.fromWebContents(wc)\r\n    return win ? this.getActiveTabFromWindow(win) : undefined\r\n  }\r\n\r\n  getActiveTabOfCurrentWindow() {\r\n    const win = this.getCurrentWindow()\r\n    return win ? this.getActiveTabFromWindow(win) : undefined\r\n  }\r\n\r\n  setActiveTab(tab: Electron.WebContents) {\r\n    const win = this.tabToWindow.get(tab)\r\n    if (!win) {\r\n      throw new Error('Active tab has no parent window')\r\n    }\r\n\r\n    const prevActiveTab = this.getActiveTabFromWebContents(tab)\r\n\r\n    this.windowToActiveTab.set(win, tab)\r\n\r\n    if (tab.id !== prevActiveTab?.id) {\r\n      this.emit('active-tab-changed', tab, win)\r\n\r\n      if (typeof this.impl.selectTab === 'function') {\r\n        this.impl.selectTab(tab, win)\r\n      }\r\n    }\r\n  }\r\n\r\n  buildMenuItems(extensionId: string, menuType: ContextMenuType): Electron.MenuItem[] {\r\n    // This function is overwritten by ContextMenusAPI\r\n    return []\r\n  }\r\n}\r\n","export * from './browser'\r\n",null,null,null,null,null,null,null]}