11648 lines
496 KiB
JavaScript
11648 lines
496 KiB
JavaScript
|
/******/ (() => { // webpackBootstrap
|
||
|
/******/ var __webpack_modules__ = ([
|
||
|
/* 0 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
__webpack_require__(1);
|
||
|
const fs_1 = __importDefault(__webpack_require__(15));
|
||
|
const path = __importStar(__webpack_require__(14));
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const electron_dl_1 = __importDefault(__webpack_require__(18));
|
||
|
const loginWindow_1 = __webpack_require__(32);
|
||
|
const mainWindow_1 = __webpack_require__(36);
|
||
|
const trayIcon_1 = __webpack_require__(69);
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const inferFlash_1 = __webpack_require__(70);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const playwrightHelpers_1 = __webpack_require__(35);
|
||
|
// Entrypoint for Squirrel, a windows update framework. See https://github.com/nativefier/nativefier/pull/744
|
||
|
if (__webpack_require__(71)) {
|
||
|
electron_1.app.exit();
|
||
|
}
|
||
|
if (process.argv.indexOf('--verbose') > -1 || (0, playwrightHelpers_1.safeGetEnv)('VERBOSE') === '1') {
|
||
|
log.setLevel('DEBUG');
|
||
|
process.traceDeprecation = true;
|
||
|
process.traceProcessWarnings = true;
|
||
|
process.argv.slice(1);
|
||
|
}
|
||
|
let mainWindow;
|
||
|
const appArgs = playwrightHelpers_1.IS_PLAYWRIGHT && playwrightHelpers_1.PLAYWRIGHT_CONFIG
|
||
|
? JSON.parse(playwrightHelpers_1.PLAYWRIGHT_CONFIG)
|
||
|
: JSON.parse(fs_1.default.readFileSync(mainWindow_1.APP_ARGS_FILE_PATH, 'utf8'));
|
||
|
log.debug('appArgs', appArgs);
|
||
|
// Do this relatively early so that we can start storing appData with the app
|
||
|
if (appArgs.portable) {
|
||
|
log.debug('App was built as portable; setting appData and userData to the app folder: ', path.resolve(path.join(__dirname, '..', 'appData')));
|
||
|
electron_1.app.setPath('appData', path.join(__dirname, '..', 'appData'));
|
||
|
electron_1.app.setPath('userData', path.join(__dirname, '..', 'appData'));
|
||
|
}
|
||
|
if (!appArgs.userAgentHonest) {
|
||
|
if (appArgs.userAgent) {
|
||
|
electron_1.app.userAgentFallback = appArgs.userAgent;
|
||
|
}
|
||
|
else {
|
||
|
electron_1.app.userAgentFallback = (0, helpers_1.removeUserAgentSpecifics)(electron_1.app.userAgentFallback, electron_1.app.getName(), electron_1.app.getVersion());
|
||
|
}
|
||
|
}
|
||
|
// this step is required to allow app names to be displayed correctly in notifications on windows
|
||
|
// https://www.electronjs.org/docs/latest/api/app#appsetappusermodelidid-windows
|
||
|
// https://www.electronjs.org/docs/latest/tutorial/notifications#windows
|
||
|
if ((0, helpers_1.isWindows)()) {
|
||
|
electron_1.app.setAppUserModelId(electron_1.app.getName());
|
||
|
}
|
||
|
const urlArgv = process.argv.filter((a) => a.startsWith('http'));
|
||
|
// Take in a URL on the command line as an override
|
||
|
if (urlArgv.length > 0) {
|
||
|
const maybeUrl = urlArgv[0];
|
||
|
try {
|
||
|
new URL(maybeUrl);
|
||
|
appArgs.targetUrl = maybeUrl;
|
||
|
log.info('Loading override URL passed as argument:', maybeUrl);
|
||
|
}
|
||
|
catch (err) {
|
||
|
log.error('Not loading override URL passed as argument, because failed to parse:', maybeUrl, err);
|
||
|
}
|
||
|
}
|
||
|
// Nativefier is a browser, and an old browser is an insecure / badly-performant one.
|
||
|
// Given our builder/app design, we currently don't have an easy way to offer
|
||
|
// upgrades from the app themselves (like browsers do).
|
||
|
// As a workaround, we ask for a manual upgrade & re-build if the build is old.
|
||
|
// The period in days is chosen to be not too small to be exceedingly annoying,
|
||
|
// but not too large to be exceedingly insecure.
|
||
|
const OLD_BUILD_WARNING_THRESHOLD_DAYS = 90;
|
||
|
const OLD_BUILD_WARNING_THRESHOLD_MS = OLD_BUILD_WARNING_THRESHOLD_DAYS * 24 * 60 * 60 * 1000;
|
||
|
const fileDownloadOptions = { ...appArgs.fileDownloadOptions };
|
||
|
(0, electron_dl_1.default)(fileDownloadOptions);
|
||
|
if (appArgs.processEnvs) {
|
||
|
let processEnvs = appArgs.processEnvs;
|
||
|
// This is compatibility if just a string was passed.
|
||
|
if (typeof appArgs.processEnvs === 'string') {
|
||
|
try {
|
||
|
processEnvs = JSON.parse(appArgs.processEnvs);
|
||
|
}
|
||
|
catch (_a) {
|
||
|
// This wasn't JSON. Fall back to the old code
|
||
|
processEnvs = {};
|
||
|
process.env.processEnvs = appArgs.processEnvs;
|
||
|
}
|
||
|
}
|
||
|
Object.keys(processEnvs)
|
||
|
.filter((key) => key !== undefined)
|
||
|
.forEach((key) => {
|
||
|
process.env[key] = processEnvs[key];
|
||
|
});
|
||
|
}
|
||
|
if (typeof appArgs.flashPluginDir === 'string') {
|
||
|
electron_1.app.commandLine.appendSwitch('ppapi-flash-path', appArgs.flashPluginDir);
|
||
|
}
|
||
|
else if (appArgs.flashPluginDir) {
|
||
|
const flashPath = (0, inferFlash_1.inferFlashPath)();
|
||
|
electron_1.app.commandLine.appendSwitch('ppapi-flash-path', flashPath);
|
||
|
}
|
||
|
if (appArgs.ignoreCertificate) {
|
||
|
electron_1.app.commandLine.appendSwitch('ignore-certificate-errors');
|
||
|
}
|
||
|
if (appArgs.disableGpu) {
|
||
|
electron_1.app.disableHardwareAcceleration();
|
||
|
}
|
||
|
if (appArgs.ignoreGpuBlacklist) {
|
||
|
electron_1.app.commandLine.appendSwitch('ignore-gpu-blacklist');
|
||
|
}
|
||
|
if (appArgs.enableEs3Apis) {
|
||
|
electron_1.app.commandLine.appendSwitch('enable-es3-apis');
|
||
|
}
|
||
|
if (appArgs.diskCacheSize) {
|
||
|
electron_1.app.commandLine.appendSwitch('disk-cache-size', appArgs.diskCacheSize.toString());
|
||
|
}
|
||
|
if (appArgs.basicAuthUsername) {
|
||
|
electron_1.app.commandLine.appendSwitch('basic-auth-username', appArgs.basicAuthUsername);
|
||
|
}
|
||
|
if (appArgs.basicAuthPassword) {
|
||
|
electron_1.app.commandLine.appendSwitch('basic-auth-password', appArgs.basicAuthPassword);
|
||
|
}
|
||
|
if (appArgs.lang) {
|
||
|
const langParts = appArgs.lang.split(',');
|
||
|
// Convert locales to languages, because for some reason locales don't work. Stupid Chromium
|
||
|
const langPartsParsed = Array.from(
|
||
|
// Convert to set to dedupe in case something like "en-GB,en-US" was passed
|
||
|
new Set(langParts.map((l) => l.split('-')[0])));
|
||
|
const langFlag = langPartsParsed.join(',');
|
||
|
log.debug('Setting --lang flag to', langFlag);
|
||
|
electron_1.app.commandLine.appendSwitch('--lang', langFlag);
|
||
|
}
|
||
|
let currentBadgeCount = 0;
|
||
|
const setDockBadge = (0, helpers_1.isOSX)()
|
||
|
? (count, bounce = false) => {
|
||
|
if (count !== undefined) {
|
||
|
electron_1.app.dock.setBadge(count.toString());
|
||
|
if (bounce && count > currentBadgeCount)
|
||
|
electron_1.app.dock.bounce();
|
||
|
currentBadgeCount = typeof count === 'number' ? count : 0;
|
||
|
}
|
||
|
}
|
||
|
: () => undefined;
|
||
|
electron_1.app.on('window-all-closed', () => {
|
||
|
log.debug('app.window-all-closed');
|
||
|
if (!(0, helpers_1.isOSX)() || appArgs.fastQuit || playwrightHelpers_1.IS_PLAYWRIGHT) {
|
||
|
electron_1.app.quit();
|
||
|
}
|
||
|
});
|
||
|
electron_1.app.on('before-quit', () => {
|
||
|
log.debug('app.before-quit');
|
||
|
// not fired when the close button on the window is clicked
|
||
|
if ((0, helpers_1.isOSX)()) {
|
||
|
// need to force a quit as a workaround here to simulate the osx app hiding behaviour
|
||
|
// Somehow sokution at https://github.com/atom/electron/issues/444#issuecomment-76492576 does not work,
|
||
|
// e.prevent default appears to persist
|
||
|
// might cause issues in the future as before-quit and will-quit events are not called
|
||
|
electron_1.app.exit(0);
|
||
|
}
|
||
|
});
|
||
|
electron_1.app.on('will-quit', (event) => {
|
||
|
log.debug('app.will-quit', event);
|
||
|
});
|
||
|
electron_1.app.on('quit', (event, exitCode) => {
|
||
|
log.debug('app.quit', { event, exitCode });
|
||
|
});
|
||
|
electron_1.app.on('will-finish-launching', () => {
|
||
|
log.debug('app.will-finish-launching');
|
||
|
});
|
||
|
electron_1.app.on('open-url', (event, url) => {
|
||
|
log.debug('app.open-url', { event, url });
|
||
|
event.preventDefault();
|
||
|
if (mainWindow) {
|
||
|
mainWindow.webContents.send('open-url', url);
|
||
|
}
|
||
|
});
|
||
|
if (appArgs.widevine) {
|
||
|
// @ts-expect-error This event only appears on the widevine version of electron, which we'd see at runtime
|
||
|
electron_1.app.on('widevine-ready', (version, lastVersion) => {
|
||
|
log.debug('app.widevine-ready', { version, lastVersion });
|
||
|
onReady().catch((err) => log.error('onReady ERROR', err));
|
||
|
});
|
||
|
electron_1.app.on(
|
||
|
// @ts-expect-error This event only appears on the widevine version of electron, which we'd see at runtime
|
||
|
'widevine-update-pending', (currentVersion, pendingVersion) => {
|
||
|
log.debug('app.widevine-update-pending', {
|
||
|
currentVersion,
|
||
|
pendingVersion,
|
||
|
});
|
||
|
});
|
||
|
// @ts-expect-error This event only appears on the widevine version of electron, which we'd see at runtime
|
||
|
electron_1.app.on('widevine-error', (error) => {
|
||
|
log.error('app.widevine-error', error);
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
electron_1.app.on('ready', () => {
|
||
|
log.debug('ready');
|
||
|
onReady().catch((err) => log.error('onReady ERROR', err));
|
||
|
});
|
||
|
}
|
||
|
electron_1.app.on('activate', (event, hasVisibleWindows) => {
|
||
|
log.debug('app.activate', { event, hasVisibleWindows });
|
||
|
if ((0, helpers_1.isOSX)() && !playwrightHelpers_1.IS_PLAYWRIGHT) {
|
||
|
// this is called when the dock is clicked
|
||
|
if (!hasVisibleWindows) {
|
||
|
mainWindow.show();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
// quit if singleInstance mode and there's already another instance running
|
||
|
const shouldQuit = appArgs.singleInstance && !electron_1.app.requestSingleInstanceLock();
|
||
|
if (shouldQuit) {
|
||
|
electron_1.app.quit();
|
||
|
}
|
||
|
else {
|
||
|
electron_1.app.on('second-instance', () => {
|
||
|
log.debug('app.second-instance');
|
||
|
if (mainWindow) {
|
||
|
if (!mainWindow.isVisible()) {
|
||
|
// try
|
||
|
mainWindow.show();
|
||
|
}
|
||
|
if (mainWindow.isMinimized()) {
|
||
|
// minimized
|
||
|
mainWindow.restore();
|
||
|
}
|
||
|
mainWindow.focus();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
electron_1.app.on('new-window-for-tab', () => {
|
||
|
log.debug('app.new-window-for-tab');
|
||
|
if (mainWindow) {
|
||
|
mainWindow.emit('new-tab');
|
||
|
}
|
||
|
});
|
||
|
electron_1.app.on('login', (event, webContents, request, authInfo, callback) => {
|
||
|
log.debug('app.login', { event, request });
|
||
|
// for http authentication
|
||
|
event.preventDefault();
|
||
|
if (appArgs.basicAuthUsername && appArgs.basicAuthPassword) {
|
||
|
callback(appArgs.basicAuthUsername, appArgs.basicAuthPassword);
|
||
|
}
|
||
|
else {
|
||
|
(0, loginWindow_1.createLoginWindow)(callback, mainWindow).catch((err) => log.error('createLoginWindow ERROR', err));
|
||
|
}
|
||
|
});
|
||
|
async function onReady() {
|
||
|
// Warning: `mainWindow` below is the *global* unique `mainWindow`, created at init time
|
||
|
mainWindow = await (0, mainWindow_1.createMainWindow)(appArgs, setDockBadge);
|
||
|
(0, trayIcon_1.createTrayIcon)(appArgs, mainWindow);
|
||
|
// Register global shortcuts
|
||
|
if (appArgs.globalShortcuts) {
|
||
|
appArgs.globalShortcuts.forEach((shortcut) => {
|
||
|
electron_1.globalShortcut.register(shortcut.key, () => {
|
||
|
shortcut.inputEvents.forEach((inputEvent) => {
|
||
|
// @ts-expect-error without including electron in our models, these will never match
|
||
|
mainWindow.webContents.sendInputEvent(inputEvent);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
if ((0, helpers_1.isOSX)() && appArgs.accessibilityPrompt) {
|
||
|
const mediaKeys = [
|
||
|
'MediaPlayPause',
|
||
|
'MediaNextTrack',
|
||
|
'MediaPreviousTrack',
|
||
|
'MediaStop',
|
||
|
];
|
||
|
const globalShortcutsKeys = appArgs.globalShortcuts.map((g) => g.key);
|
||
|
const mediaKeyWasSet = globalShortcutsKeys.find((g) => mediaKeys.includes(g));
|
||
|
if (mediaKeyWasSet &&
|
||
|
!electron_1.systemPreferences.isTrustedAccessibilityClient(false)) {
|
||
|
// Since we're trying to set global keyboard shortcuts for media keys, we need to prompt
|
||
|
// the user for permission on Mac.
|
||
|
// For reference:
|
||
|
// https://www.electronjs.org/docs/api/global-shortcut?q=MediaPlayPause#globalshortcutregisteraccelerator-callback
|
||
|
const accessibilityPromptResult = electron_1.dialog.showMessageBoxSync(mainWindow, {
|
||
|
type: 'question',
|
||
|
message: 'Accessibility Permissions Needed',
|
||
|
buttons: ['Yes', 'No', 'No and never ask again'],
|
||
|
defaultId: 0,
|
||
|
detail: `${appArgs.name} would like to use one or more of your keyboard's media keys (start, stop, next track, or previous track) to control it.\n\n` +
|
||
|
`Would you like Mac OS to ask for your permission to do so?\n\n` +
|
||
|
`If so, you will need to restart ${appArgs.name} after granting permissions for these keyboard shortcuts to begin working.`,
|
||
|
});
|
||
|
switch (accessibilityPromptResult) {
|
||
|
// User clicked Yes, prompt for accessibility
|
||
|
case 0:
|
||
|
electron_1.systemPreferences.isTrustedAccessibilityClient(true);
|
||
|
break;
|
||
|
// User cliecked Never Ask Me Again, save that info
|
||
|
case 2:
|
||
|
appArgs.accessibilityPrompt = false;
|
||
|
(0, mainWindow_1.saveAppArgs)(appArgs);
|
||
|
break;
|
||
|
// User clicked No
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!appArgs.disableOldBuildWarning &&
|
||
|
new Date().getTime() - appArgs.buildDate > OLD_BUILD_WARNING_THRESHOLD_MS) {
|
||
|
const oldBuildWarningText = appArgs.oldBuildWarningText ||
|
||
|
'This app was built a long time ago. Nativefier uses the Chrome browser (through Electron), and it is insecure to keep using an old version of it. Please upgrade Nativefier and rebuild this app.';
|
||
|
electron_1.dialog
|
||
|
.showMessageBox(mainWindow, {
|
||
|
type: 'warning',
|
||
|
message: 'Old build detected',
|
||
|
detail: oldBuildWarningText,
|
||
|
})
|
||
|
.catch((err) => log.error('dialog.showMessageBox ERROR', err));
|
||
|
}
|
||
|
if (appArgs.targetUrl) {
|
||
|
await mainWindow.loadURL(appArgs.targetUrl);
|
||
|
}
|
||
|
}
|
||
|
electron_1.app.on('accessibility-support-changed', (event, accessibilitySupportEnabled) => {
|
||
|
log.debug('app.accessibility-support-changed', {
|
||
|
event,
|
||
|
accessibilitySupportEnabled,
|
||
|
});
|
||
|
});
|
||
|
electron_1.app.on('activity-was-continued', (event, type, userInfo) => {
|
||
|
log.debug('app.activity-was-continued', { event, type, userInfo });
|
||
|
});
|
||
|
electron_1.app.on('browser-window-blur', () => {
|
||
|
log.debug('app.browser-window-blur');
|
||
|
});
|
||
|
electron_1.app.on('browser-window-created', () => {
|
||
|
log.debug('app.browser-window-created');
|
||
|
});
|
||
|
electron_1.app.on('browser-window-focus', () => {
|
||
|
log.debug('app.browser-window-focus');
|
||
|
});
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 1 */
|
||
|
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
(__webpack_require__(2).install)();
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 2 */
|
||
|
/***/ ((module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* module decorator */ module = __webpack_require__.nmd(module);
|
||
|
var SourceMapConsumer = (__webpack_require__(3).SourceMapConsumer);
|
||
|
var path = __webpack_require__(14);
|
||
|
|
||
|
var fs;
|
||
|
try {
|
||
|
fs = __webpack_require__(15);
|
||
|
if (!fs.existsSync || !fs.readFileSync) {
|
||
|
// fs doesn't have all methods we need
|
||
|
fs = null;
|
||
|
}
|
||
|
} catch (err) {
|
||
|
/* nop */
|
||
|
}
|
||
|
|
||
|
var bufferFrom = __webpack_require__(16);
|
||
|
|
||
|
/**
|
||
|
* Requires a module which is protected against bundler minification.
|
||
|
*
|
||
|
* @param {NodeModule} mod
|
||
|
* @param {string} request
|
||
|
*/
|
||
|
function dynamicRequire(mod, request) {
|
||
|
return mod.require(request);
|
||
|
}
|
||
|
|
||
|
// Only install once if called multiple times
|
||
|
var errorFormatterInstalled = false;
|
||
|
var uncaughtShimInstalled = false;
|
||
|
|
||
|
// If true, the caches are reset before a stack trace formatting operation
|
||
|
var emptyCacheBetweenOperations = false;
|
||
|
|
||
|
// Supports {browser, node, auto}
|
||
|
var environment = "auto";
|
||
|
|
||
|
// Maps a file path to a string containing the file contents
|
||
|
var fileContentsCache = {};
|
||
|
|
||
|
// Maps a file path to a source map for that file
|
||
|
var sourceMapCache = {};
|
||
|
|
||
|
// Regex for detecting source maps
|
||
|
var reSourceMap = /^data:application\/json[^,]+base64,/;
|
||
|
|
||
|
// Priority list of retrieve handlers
|
||
|
var retrieveFileHandlers = [];
|
||
|
var retrieveMapHandlers = [];
|
||
|
|
||
|
function isInBrowser() {
|
||
|
if (environment === "browser")
|
||
|
return true;
|
||
|
if (environment === "node")
|
||
|
return false;
|
||
|
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
|
||
|
}
|
||
|
|
||
|
function hasGlobalProcessEventEmitter() {
|
||
|
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
|
||
|
}
|
||
|
|
||
|
function globalProcessVersion() {
|
||
|
if ((typeof process === 'object') && (process !== null)) {
|
||
|
return process.version;
|
||
|
} else {
|
||
|
return '';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function globalProcessStderr() {
|
||
|
if ((typeof process === 'object') && (process !== null)) {
|
||
|
return process.stderr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function globalProcessExit(code) {
|
||
|
if ((typeof process === 'object') && (process !== null) && (typeof process.exit === 'function')) {
|
||
|
return process.exit(code);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function handlerExec(list) {
|
||
|
return function(arg) {
|
||
|
for (var i = 0; i < list.length; i++) {
|
||
|
var ret = list[i](arg);
|
||
|
if (ret) {
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
var retrieveFile = handlerExec(retrieveFileHandlers);
|
||
|
|
||
|
retrieveFileHandlers.push(function(path) {
|
||
|
// Trim the path to make sure there is no extra whitespace.
|
||
|
path = path.trim();
|
||
|
if (/^file:/.test(path)) {
|
||
|
// existsSync/readFileSync can't handle file protocol, but once stripped, it works
|
||
|
path = path.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
|
||
|
return drive ?
|
||
|
'' : // file:///C:/dir/file -> C:/dir/file
|
||
|
'/'; // file:///root-dir/file -> /root-dir/file
|
||
|
});
|
||
|
}
|
||
|
if (path in fileContentsCache) {
|
||
|
return fileContentsCache[path];
|
||
|
}
|
||
|
|
||
|
var contents = '';
|
||
|
try {
|
||
|
if (!fs) {
|
||
|
// Use SJAX if we are in the browser
|
||
|
var xhr = new XMLHttpRequest();
|
||
|
xhr.open('GET', path, /** async */ false);
|
||
|
xhr.send(null);
|
||
|
if (xhr.readyState === 4 && xhr.status === 200) {
|
||
|
contents = xhr.responseText;
|
||
|
}
|
||
|
} else if (fs.existsSync(path)) {
|
||
|
// Otherwise, use the filesystem
|
||
|
contents = fs.readFileSync(path, 'utf8');
|
||
|
}
|
||
|
} catch (er) {
|
||
|
/* ignore any errors */
|
||
|
}
|
||
|
|
||
|
return fileContentsCache[path] = contents;
|
||
|
});
|
||
|
|
||
|
// Support URLs relative to a directory, but be careful about a protocol prefix
|
||
|
// in case we are in the browser (i.e. directories may start with "http://" or "file:///")
|
||
|
function supportRelativeURL(file, url) {
|
||
|
if (!file) return url;
|
||
|
var dir = path.dirname(file);
|
||
|
var match = /^\w+:\/\/[^\/]*/.exec(dir);
|
||
|
var protocol = match ? match[0] : '';
|
||
|
var startPath = dir.slice(protocol.length);
|
||
|
if (protocol && /^\/\w\:/.test(startPath)) {
|
||
|
// handle file:///C:/ paths
|
||
|
protocol += '/';
|
||
|
return protocol + path.resolve(dir.slice(protocol.length), url).replace(/\\/g, '/');
|
||
|
}
|
||
|
return protocol + path.resolve(dir.slice(protocol.length), url);
|
||
|
}
|
||
|
|
||
|
function retrieveSourceMapURL(source) {
|
||
|
var fileData;
|
||
|
|
||
|
if (isInBrowser()) {
|
||
|
try {
|
||
|
var xhr = new XMLHttpRequest();
|
||
|
xhr.open('GET', source, false);
|
||
|
xhr.send(null);
|
||
|
fileData = xhr.readyState === 4 ? xhr.responseText : null;
|
||
|
|
||
|
// Support providing a sourceMappingURL via the SourceMap header
|
||
|
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
|
||
|
xhr.getResponseHeader("X-SourceMap");
|
||
|
if (sourceMapHeader) {
|
||
|
return sourceMapHeader;
|
||
|
}
|
||
|
} catch (e) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Get the URL of the source map
|
||
|
fileData = retrieveFile(source);
|
||
|
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
|
||
|
// Keep executing the search to find the *last* sourceMappingURL to avoid
|
||
|
// picking up sourceMappingURLs from comments, strings, etc.
|
||
|
var lastMatch, match;
|
||
|
while (match = re.exec(fileData)) lastMatch = match;
|
||
|
if (!lastMatch) return null;
|
||
|
return lastMatch[1];
|
||
|
};
|
||
|
|
||
|
// Can be overridden by the retrieveSourceMap option to install. Takes a
|
||
|
// generated source filename; returns a {map, optional url} object, or null if
|
||
|
// there is no source map. The map field may be either a string or the parsed
|
||
|
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
|
||
|
// constructor).
|
||
|
var retrieveSourceMap = handlerExec(retrieveMapHandlers);
|
||
|
retrieveMapHandlers.push(function(source) {
|
||
|
var sourceMappingURL = retrieveSourceMapURL(source);
|
||
|
if (!sourceMappingURL) return null;
|
||
|
|
||
|
// Read the contents of the source map
|
||
|
var sourceMapData;
|
||
|
if (reSourceMap.test(sourceMappingURL)) {
|
||
|
// Support source map URL as a data url
|
||
|
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
|
||
|
sourceMapData = bufferFrom(rawData, "base64").toString();
|
||
|
sourceMappingURL = source;
|
||
|
} else {
|
||
|
// Support source map URLs relative to the source URL
|
||
|
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
|
||
|
sourceMapData = retrieveFile(sourceMappingURL);
|
||
|
}
|
||
|
|
||
|
if (!sourceMapData) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
url: sourceMappingURL,
|
||
|
map: sourceMapData
|
||
|
};
|
||
|
});
|
||
|
|
||
|
function mapSourcePosition(position) {
|
||
|
var sourceMap = sourceMapCache[position.source];
|
||
|
if (!sourceMap) {
|
||
|
// Call the (overrideable) retrieveSourceMap function to get the source map.
|
||
|
var urlAndMap = retrieveSourceMap(position.source);
|
||
|
if (urlAndMap) {
|
||
|
sourceMap = sourceMapCache[position.source] = {
|
||
|
url: urlAndMap.url,
|
||
|
map: new SourceMapConsumer(urlAndMap.map)
|
||
|
};
|
||
|
|
||
|
// Load all sources stored inline with the source map into the file cache
|
||
|
// to pretend like they are already loaded. They may not exist on disk.
|
||
|
if (sourceMap.map.sourcesContent) {
|
||
|
sourceMap.map.sources.forEach(function(source, i) {
|
||
|
var contents = sourceMap.map.sourcesContent[i];
|
||
|
if (contents) {
|
||
|
var url = supportRelativeURL(sourceMap.url, source);
|
||
|
fileContentsCache[url] = contents;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
sourceMap = sourceMapCache[position.source] = {
|
||
|
url: null,
|
||
|
map: null
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Resolve the source URL relative to the URL of the source map
|
||
|
if (sourceMap && sourceMap.map && typeof sourceMap.map.originalPositionFor === 'function') {
|
||
|
var originalPosition = sourceMap.map.originalPositionFor(position);
|
||
|
|
||
|
// Only return the original position if a matching line was found. If no
|
||
|
// matching line is found then we return position instead, which will cause
|
||
|
// the stack trace to print the path and line for the compiled file. It is
|
||
|
// better to give a precise location in the compiled file than a vague
|
||
|
// location in the original file.
|
||
|
if (originalPosition.source !== null) {
|
||
|
originalPosition.source = supportRelativeURL(
|
||
|
sourceMap.url, originalPosition.source);
|
||
|
return originalPosition;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return position;
|
||
|
}
|
||
|
|
||
|
// Parses code generated by FormatEvalOrigin(), a function inside V8:
|
||
|
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
||
|
function mapEvalOrigin(origin) {
|
||
|
// Most eval() calls are in this format
|
||
|
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
|
||
|
if (match) {
|
||
|
var position = mapSourcePosition({
|
||
|
source: match[2],
|
||
|
line: +match[3],
|
||
|
column: match[4] - 1
|
||
|
});
|
||
|
return 'eval at ' + match[1] + ' (' + position.source + ':' +
|
||
|
position.line + ':' + (position.column + 1) + ')';
|
||
|
}
|
||
|
|
||
|
// Parse nested eval() calls using recursion
|
||
|
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
|
||
|
if (match) {
|
||
|
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
|
||
|
}
|
||
|
|
||
|
// Make sure we still return useful information if we didn't find anything
|
||
|
return origin;
|
||
|
}
|
||
|
|
||
|
// This is copied almost verbatim from the V8 source code at
|
||
|
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The
|
||
|
// implementation of wrapCallSite() used to just forward to the actual source
|
||
|
// code of CallSite.prototype.toString but unfortunately a new release of V8
|
||
|
// did something to the prototype chain and broke the shim. The only fix I
|
||
|
// could find was copy/paste.
|
||
|
function CallSiteToString() {
|
||
|
var fileName;
|
||
|
var fileLocation = "";
|
||
|
if (this.isNative()) {
|
||
|
fileLocation = "native";
|
||
|
} else {
|
||
|
fileName = this.getScriptNameOrSourceURL();
|
||
|
if (!fileName && this.isEval()) {
|
||
|
fileLocation = this.getEvalOrigin();
|
||
|
fileLocation += ", "; // Expecting source position to follow.
|
||
|
}
|
||
|
|
||
|
if (fileName) {
|
||
|
fileLocation += fileName;
|
||
|
} else {
|
||
|
// Source code does not originate from a file and is not native, but we
|
||
|
// can still get the source position inside the source string, e.g. in
|
||
|
// an eval string.
|
||
|
fileLocation += "<anonymous>";
|
||
|
}
|
||
|
var lineNumber = this.getLineNumber();
|
||
|
if (lineNumber != null) {
|
||
|
fileLocation += ":" + lineNumber;
|
||
|
var columnNumber = this.getColumnNumber();
|
||
|
if (columnNumber) {
|
||
|
fileLocation += ":" + columnNumber;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var line = "";
|
||
|
var functionName = this.getFunctionName();
|
||
|
var addSuffix = true;
|
||
|
var isConstructor = this.isConstructor();
|
||
|
var isMethodCall = !(this.isToplevel() || isConstructor);
|
||
|
if (isMethodCall) {
|
||
|
var typeName = this.getTypeName();
|
||
|
// Fixes shim to be backward compatable with Node v0 to v4
|
||
|
if (typeName === "[object Object]") {
|
||
|
typeName = "null";
|
||
|
}
|
||
|
var methodName = this.getMethodName();
|
||
|
if (functionName) {
|
||
|
if (typeName && functionName.indexOf(typeName) != 0) {
|
||
|
line += typeName + ".";
|
||
|
}
|
||
|
line += functionName;
|
||
|
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
|
||
|
line += " [as " + methodName + "]";
|
||
|
}
|
||
|
} else {
|
||
|
line += typeName + "." + (methodName || "<anonymous>");
|
||
|
}
|
||
|
} else if (isConstructor) {
|
||
|
line += "new " + (functionName || "<anonymous>");
|
||
|
} else if (functionName) {
|
||
|
line += functionName;
|
||
|
} else {
|
||
|
line += fileLocation;
|
||
|
addSuffix = false;
|
||
|
}
|
||
|
if (addSuffix) {
|
||
|
line += " (" + fileLocation + ")";
|
||
|
}
|
||
|
return line;
|
||
|
}
|
||
|
|
||
|
function cloneCallSite(frame) {
|
||
|
var object = {};
|
||
|
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
|
||
|
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
|
||
|
});
|
||
|
object.toString = CallSiteToString;
|
||
|
return object;
|
||
|
}
|
||
|
|
||
|
function wrapCallSite(frame, state) {
|
||
|
// provides interface backward compatibility
|
||
|
if (state === undefined) {
|
||
|
state = { nextPosition: null, curPosition: null }
|
||
|
}
|
||
|
if(frame.isNative()) {
|
||
|
state.curPosition = null;
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
// Most call sites will return the source file from getFileName(), but code
|
||
|
// passed to eval() ending in "//# sourceURL=..." will return the source file
|
||
|
// from getScriptNameOrSourceURL() instead
|
||
|
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
|
||
|
if (source) {
|
||
|
var line = frame.getLineNumber();
|
||
|
var column = frame.getColumnNumber() - 1;
|
||
|
|
||
|
// Fix position in Node where some (internal) code is prepended.
|
||
|
// See https://github.com/evanw/node-source-map-support/issues/36
|
||
|
// Header removed in node at ^10.16 || >=11.11.0
|
||
|
// v11 is not an LTS candidate, we can just test the one version with it.
|
||
|
// Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11
|
||
|
var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
|
||
|
var headerLength = noHeader.test(globalProcessVersion()) ? 0 : 62;
|
||
|
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
|
||
|
column -= headerLength;
|
||
|
}
|
||
|
|
||
|
var position = mapSourcePosition({
|
||
|
source: source,
|
||
|
line: line,
|
||
|
column: column
|
||
|
});
|
||
|
state.curPosition = position;
|
||
|
frame = cloneCallSite(frame);
|
||
|
var originalFunctionName = frame.getFunctionName;
|
||
|
frame.getFunctionName = function() {
|
||
|
if (state.nextPosition == null) {
|
||
|
return originalFunctionName();
|
||
|
}
|
||
|
return state.nextPosition.name || originalFunctionName();
|
||
|
};
|
||
|
frame.getFileName = function() { return position.source; };
|
||
|
frame.getLineNumber = function() { return position.line; };
|
||
|
frame.getColumnNumber = function() { return position.column + 1; };
|
||
|
frame.getScriptNameOrSourceURL = function() { return position.source; };
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
// Code called using eval() needs special handling
|
||
|
var origin = frame.isEval() && frame.getEvalOrigin();
|
||
|
if (origin) {
|
||
|
origin = mapEvalOrigin(origin);
|
||
|
frame = cloneCallSite(frame);
|
||
|
frame.getEvalOrigin = function() { return origin; };
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
// If we get here then we were unable to change the source position
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
// This function is part of the V8 stack trace API, for more info see:
|
||
|
// https://v8.dev/docs/stack-trace-api
|
||
|
function prepareStackTrace(error, stack) {
|
||
|
if (emptyCacheBetweenOperations) {
|
||
|
fileContentsCache = {};
|
||
|
sourceMapCache = {};
|
||
|
}
|
||
|
|
||
|
var name = error.name || 'Error';
|
||
|
var message = error.message || '';
|
||
|
var errorString = name + ": " + message;
|
||
|
|
||
|
var state = { nextPosition: null, curPosition: null };
|
||
|
var processedStack = [];
|
||
|
for (var i = stack.length - 1; i >= 0; i--) {
|
||
|
processedStack.push('\n at ' + wrapCallSite(stack[i], state));
|
||
|
state.nextPosition = state.curPosition;
|
||
|
}
|
||
|
state.curPosition = state.nextPosition = null;
|
||
|
return errorString + processedStack.reverse().join('');
|
||
|
}
|
||
|
|
||
|
// Generate position and snippet of original source with pointer
|
||
|
function getErrorSource(error) {
|
||
|
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
|
||
|
if (match) {
|
||
|
var source = match[1];
|
||
|
var line = +match[2];
|
||
|
var column = +match[3];
|
||
|
|
||
|
// Support the inline sourceContents inside the source map
|
||
|
var contents = fileContentsCache[source];
|
||
|
|
||
|
// Support files on disk
|
||
|
if (!contents && fs && fs.existsSync(source)) {
|
||
|
try {
|
||
|
contents = fs.readFileSync(source, 'utf8');
|
||
|
} catch (er) {
|
||
|
contents = '';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Format the line from the original source code like node does
|
||
|
if (contents) {
|
||
|
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
|
||
|
if (code) {
|
||
|
return source + ':' + line + '\n' + code + '\n' +
|
||
|
new Array(column).join(' ') + '^';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
function printErrorAndExit (error) {
|
||
|
var source = getErrorSource(error);
|
||
|
|
||
|
// Ensure error is printed synchronously and not truncated
|
||
|
var stderr = globalProcessStderr();
|
||
|
if (stderr && stderr._handle && stderr._handle.setBlocking) {
|
||
|
stderr._handle.setBlocking(true);
|
||
|
}
|
||
|
|
||
|
if (source) {
|
||
|
console.error();
|
||
|
console.error(source);
|
||
|
}
|
||
|
|
||
|
console.error(error.stack);
|
||
|
globalProcessExit(1);
|
||
|
}
|
||
|
|
||
|
function shimEmitUncaughtException () {
|
||
|
var origEmit = process.emit;
|
||
|
|
||
|
process.emit = function (type) {
|
||
|
if (type === 'uncaughtException') {
|
||
|
var hasStack = (arguments[1] && arguments[1].stack);
|
||
|
var hasListeners = (this.listeners(type).length > 0);
|
||
|
|
||
|
if (hasStack && !hasListeners) {
|
||
|
return printErrorAndExit(arguments[1]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return origEmit.apply(this, arguments);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
var originalRetrieveFileHandlers = retrieveFileHandlers.slice(0);
|
||
|
var originalRetrieveMapHandlers = retrieveMapHandlers.slice(0);
|
||
|
|
||
|
exports.wrapCallSite = wrapCallSite;
|
||
|
exports.getErrorSource = getErrorSource;
|
||
|
exports.mapSourcePosition = mapSourcePosition;
|
||
|
exports.retrieveSourceMap = retrieveSourceMap;
|
||
|
|
||
|
exports.install = function(options) {
|
||
|
options = options || {};
|
||
|
|
||
|
if (options.environment) {
|
||
|
environment = options.environment;
|
||
|
if (["node", "browser", "auto"].indexOf(environment) === -1) {
|
||
|
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Allow sources to be found by methods other than reading the files
|
||
|
// directly from disk.
|
||
|
if (options.retrieveFile) {
|
||
|
if (options.overrideRetrieveFile) {
|
||
|
retrieveFileHandlers.length = 0;
|
||
|
}
|
||
|
|
||
|
retrieveFileHandlers.unshift(options.retrieveFile);
|
||
|
}
|
||
|
|
||
|
// Allow source maps to be found by methods other than reading the files
|
||
|
// directly from disk.
|
||
|
if (options.retrieveSourceMap) {
|
||
|
if (options.overrideRetrieveSourceMap) {
|
||
|
retrieveMapHandlers.length = 0;
|
||
|
}
|
||
|
|
||
|
retrieveMapHandlers.unshift(options.retrieveSourceMap);
|
||
|
}
|
||
|
|
||
|
// Support runtime transpilers that include inline source maps
|
||
|
if (options.hookRequire && !isInBrowser()) {
|
||
|
// Use dynamicRequire to avoid including in browser bundles
|
||
|
var Module = dynamicRequire(module, 'module');
|
||
|
var $compile = Module.prototype._compile;
|
||
|
|
||
|
if (!$compile.__sourceMapSupport) {
|
||
|
Module.prototype._compile = function(content, filename) {
|
||
|
fileContentsCache[filename] = content;
|
||
|
sourceMapCache[filename] = undefined;
|
||
|
return $compile.call(this, content, filename);
|
||
|
};
|
||
|
|
||
|
Module.prototype._compile.__sourceMapSupport = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Configure options
|
||
|
if (!emptyCacheBetweenOperations) {
|
||
|
emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
|
||
|
options.emptyCacheBetweenOperations : false;
|
||
|
}
|
||
|
|
||
|
// Install the error reformatter
|
||
|
if (!errorFormatterInstalled) {
|
||
|
errorFormatterInstalled = true;
|
||
|
Error.prepareStackTrace = prepareStackTrace;
|
||
|
}
|
||
|
|
||
|
if (!uncaughtShimInstalled) {
|
||
|
var installHandler = 'handleUncaughtExceptions' in options ?
|
||
|
options.handleUncaughtExceptions : true;
|
||
|
|
||
|
// Do not override 'uncaughtException' with our own handler in Node.js
|
||
|
// Worker threads. Workers pass the error to the main thread as an event,
|
||
|
// rather than printing something to stderr and exiting.
|
||
|
try {
|
||
|
// We need to use `dynamicRequire` because `require` on it's own will be optimized by WebPack/Browserify.
|
||
|
var worker_threads = dynamicRequire(module, 'worker_threads');
|
||
|
if (worker_threads.isMainThread === false) {
|
||
|
installHandler = false;
|
||
|
}
|
||
|
} catch(e) {}
|
||
|
|
||
|
// Provide the option to not install the uncaught exception handler. This is
|
||
|
// to support other uncaught exception handlers (in test frameworks, for
|
||
|
// example). If this handler is not installed and there are no other uncaught
|
||
|
// exception handlers, uncaught exceptions will be caught by node's built-in
|
||
|
// exception handler and the process will still be terminated. However, the
|
||
|
// generated JavaScript code will be shown above the stack trace instead of
|
||
|
// the original source code.
|
||
|
if (installHandler && hasGlobalProcessEventEmitter()) {
|
||
|
uncaughtShimInstalled = true;
|
||
|
shimEmitUncaughtException();
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
exports.resetRetrieveHandlers = function() {
|
||
|
retrieveFileHandlers.length = 0;
|
||
|
retrieveMapHandlers.length = 0;
|
||
|
|
||
|
retrieveFileHandlers = originalRetrieveFileHandlers.slice(0);
|
||
|
retrieveMapHandlers = originalRetrieveMapHandlers.slice(0);
|
||
|
|
||
|
retrieveSourceMap = handlerExec(retrieveMapHandlers);
|
||
|
retrieveFile = handlerExec(retrieveFileHandlers);
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 3 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/*
|
||
|
* Copyright 2009-2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE.txt or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
exports.SourceMapGenerator = __webpack_require__(4).SourceMapGenerator;
|
||
|
exports.SourceMapConsumer = __webpack_require__(10).SourceMapConsumer;
|
||
|
exports.SourceNode = __webpack_require__(13).SourceNode;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 4 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
var base64VLQ = __webpack_require__(5);
|
||
|
var util = __webpack_require__(7);
|
||
|
var ArraySet = (__webpack_require__(8).ArraySet);
|
||
|
var MappingList = (__webpack_require__(9).MappingList);
|
||
|
|
||
|
/**
|
||
|
* An instance of the SourceMapGenerator represents a source map which is
|
||
|
* being built incrementally. You may pass an object with the following
|
||
|
* properties:
|
||
|
*
|
||
|
* - file: The filename of the generated source.
|
||
|
* - sourceRoot: A root for all relative URLs in this source map.
|
||
|
*/
|
||
|
function SourceMapGenerator(aArgs) {
|
||
|
if (!aArgs) {
|
||
|
aArgs = {};
|
||
|
}
|
||
|
this._file = util.getArg(aArgs, 'file', null);
|
||
|
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
|
||
|
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
|
||
|
this._sources = new ArraySet();
|
||
|
this._names = new ArraySet();
|
||
|
this._mappings = new MappingList();
|
||
|
this._sourcesContents = null;
|
||
|
}
|
||
|
|
||
|
SourceMapGenerator.prototype._version = 3;
|
||
|
|
||
|
/**
|
||
|
* Creates a new SourceMapGenerator based on a SourceMapConsumer
|
||
|
*
|
||
|
* @param aSourceMapConsumer The SourceMap.
|
||
|
*/
|
||
|
SourceMapGenerator.fromSourceMap =
|
||
|
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
|
||
|
var sourceRoot = aSourceMapConsumer.sourceRoot;
|
||
|
var generator = new SourceMapGenerator({
|
||
|
file: aSourceMapConsumer.file,
|
||
|
sourceRoot: sourceRoot
|
||
|
});
|
||
|
aSourceMapConsumer.eachMapping(function (mapping) {
|
||
|
var newMapping = {
|
||
|
generated: {
|
||
|
line: mapping.generatedLine,
|
||
|
column: mapping.generatedColumn
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (mapping.source != null) {
|
||
|
newMapping.source = mapping.source;
|
||
|
if (sourceRoot != null) {
|
||
|
newMapping.source = util.relative(sourceRoot, newMapping.source);
|
||
|
}
|
||
|
|
||
|
newMapping.original = {
|
||
|
line: mapping.originalLine,
|
||
|
column: mapping.originalColumn
|
||
|
};
|
||
|
|
||
|
if (mapping.name != null) {
|
||
|
newMapping.name = mapping.name;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
generator.addMapping(newMapping);
|
||
|
});
|
||
|
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||
|
var sourceRelative = sourceFile;
|
||
|
if (sourceRoot !== null) {
|
||
|
sourceRelative = util.relative(sourceRoot, sourceFile);
|
||
|
}
|
||
|
|
||
|
if (!generator._sources.has(sourceRelative)) {
|
||
|
generator._sources.add(sourceRelative);
|
||
|
}
|
||
|
|
||
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||
|
if (content != null) {
|
||
|
generator.setSourceContent(sourceFile, content);
|
||
|
}
|
||
|
});
|
||
|
return generator;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Add a single mapping from original source line and column to the generated
|
||
|
* source's line and column for this source map being created. The mapping
|
||
|
* object should have the following properties:
|
||
|
*
|
||
|
* - generated: An object with the generated line and column positions.
|
||
|
* - original: An object with the original line and column positions.
|
||
|
* - source: The original source file (relative to the sourceRoot).
|
||
|
* - name: An optional original token name for this mapping.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype.addMapping =
|
||
|
function SourceMapGenerator_addMapping(aArgs) {
|
||
|
var generated = util.getArg(aArgs, 'generated');
|
||
|
var original = util.getArg(aArgs, 'original', null);
|
||
|
var source = util.getArg(aArgs, 'source', null);
|
||
|
var name = util.getArg(aArgs, 'name', null);
|
||
|
|
||
|
if (!this._skipValidation) {
|
||
|
this._validateMapping(generated, original, source, name);
|
||
|
}
|
||
|
|
||
|
if (source != null) {
|
||
|
source = String(source);
|
||
|
if (!this._sources.has(source)) {
|
||
|
this._sources.add(source);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (name != null) {
|
||
|
name = String(name);
|
||
|
if (!this._names.has(name)) {
|
||
|
this._names.add(name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this._mappings.add({
|
||
|
generatedLine: generated.line,
|
||
|
generatedColumn: generated.column,
|
||
|
originalLine: original != null && original.line,
|
||
|
originalColumn: original != null && original.column,
|
||
|
source: source,
|
||
|
name: name
|
||
|
});
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set the source content for a source file.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype.setSourceContent =
|
||
|
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
|
||
|
var source = aSourceFile;
|
||
|
if (this._sourceRoot != null) {
|
||
|
source = util.relative(this._sourceRoot, source);
|
||
|
}
|
||
|
|
||
|
if (aSourceContent != null) {
|
||
|
// Add the source content to the _sourcesContents map.
|
||
|
// Create a new _sourcesContents map if the property is null.
|
||
|
if (!this._sourcesContents) {
|
||
|
this._sourcesContents = Object.create(null);
|
||
|
}
|
||
|
this._sourcesContents[util.toSetString(source)] = aSourceContent;
|
||
|
} else if (this._sourcesContents) {
|
||
|
// Remove the source file from the _sourcesContents map.
|
||
|
// If the _sourcesContents map is empty, set the property to null.
|
||
|
delete this._sourcesContents[util.toSetString(source)];
|
||
|
if (Object.keys(this._sourcesContents).length === 0) {
|
||
|
this._sourcesContents = null;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Applies the mappings of a sub-source-map for a specific source file to the
|
||
|
* source map being generated. Each mapping to the supplied source file is
|
||
|
* rewritten using the supplied source map. Note: The resolution for the
|
||
|
* resulting mappings is the minimium of this map and the supplied map.
|
||
|
*
|
||
|
* @param aSourceMapConsumer The source map to be applied.
|
||
|
* @param aSourceFile Optional. The filename of the source file.
|
||
|
* If omitted, SourceMapConsumer's file property will be used.
|
||
|
* @param aSourceMapPath Optional. The dirname of the path to the source map
|
||
|
* to be applied. If relative, it is relative to the SourceMapConsumer.
|
||
|
* This parameter is needed when the two source maps aren't in the same
|
||
|
* directory, and the source map to be applied contains relative source
|
||
|
* paths. If so, those relative source paths need to be rewritten
|
||
|
* relative to the SourceMapGenerator.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype.applySourceMap =
|
||
|
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
|
||
|
var sourceFile = aSourceFile;
|
||
|
// If aSourceFile is omitted, we will use the file property of the SourceMap
|
||
|
if (aSourceFile == null) {
|
||
|
if (aSourceMapConsumer.file == null) {
|
||
|
throw new Error(
|
||
|
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
|
||
|
'or the source map\'s "file" property. Both were omitted.'
|
||
|
);
|
||
|
}
|
||
|
sourceFile = aSourceMapConsumer.file;
|
||
|
}
|
||
|
var sourceRoot = this._sourceRoot;
|
||
|
// Make "sourceFile" relative if an absolute Url is passed.
|
||
|
if (sourceRoot != null) {
|
||
|
sourceFile = util.relative(sourceRoot, sourceFile);
|
||
|
}
|
||
|
// Applying the SourceMap can add and remove items from the sources and
|
||
|
// the names array.
|
||
|
var newSources = new ArraySet();
|
||
|
var newNames = new ArraySet();
|
||
|
|
||
|
// Find mappings for the "sourceFile"
|
||
|
this._mappings.unsortedForEach(function (mapping) {
|
||
|
if (mapping.source === sourceFile && mapping.originalLine != null) {
|
||
|
// Check if it can be mapped by the source map, then update the mapping.
|
||
|
var original = aSourceMapConsumer.originalPositionFor({
|
||
|
line: mapping.originalLine,
|
||
|
column: mapping.originalColumn
|
||
|
});
|
||
|
if (original.source != null) {
|
||
|
// Copy mapping
|
||
|
mapping.source = original.source;
|
||
|
if (aSourceMapPath != null) {
|
||
|
mapping.source = util.join(aSourceMapPath, mapping.source)
|
||
|
}
|
||
|
if (sourceRoot != null) {
|
||
|
mapping.source = util.relative(sourceRoot, mapping.source);
|
||
|
}
|
||
|
mapping.originalLine = original.line;
|
||
|
mapping.originalColumn = original.column;
|
||
|
if (original.name != null) {
|
||
|
mapping.name = original.name;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var source = mapping.source;
|
||
|
if (source != null && !newSources.has(source)) {
|
||
|
newSources.add(source);
|
||
|
}
|
||
|
|
||
|
var name = mapping.name;
|
||
|
if (name != null && !newNames.has(name)) {
|
||
|
newNames.add(name);
|
||
|
}
|
||
|
|
||
|
}, this);
|
||
|
this._sources = newSources;
|
||
|
this._names = newNames;
|
||
|
|
||
|
// Copy sourcesContents of applied map.
|
||
|
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||
|
if (content != null) {
|
||
|
if (aSourceMapPath != null) {
|
||
|
sourceFile = util.join(aSourceMapPath, sourceFile);
|
||
|
}
|
||
|
if (sourceRoot != null) {
|
||
|
sourceFile = util.relative(sourceRoot, sourceFile);
|
||
|
}
|
||
|
this.setSourceContent(sourceFile, content);
|
||
|
}
|
||
|
}, this);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* A mapping can have one of the three levels of data:
|
||
|
*
|
||
|
* 1. Just the generated position.
|
||
|
* 2. The Generated position, original position, and original source.
|
||
|
* 3. Generated and original position, original source, as well as a name
|
||
|
* token.
|
||
|
*
|
||
|
* To maintain consistency, we validate that any new mapping being added falls
|
||
|
* in to one of these categories.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype._validateMapping =
|
||
|
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
|
||
|
aName) {
|
||
|
// When aOriginal is truthy but has empty values for .line and .column,
|
||
|
// it is most likely a programmer error. In this case we throw a very
|
||
|
// specific error message to try to guide them the right way.
|
||
|
// For example: https://github.com/Polymer/polymer-bundler/pull/519
|
||
|
if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
|
||
|
throw new Error(
|
||
|
'original.line and original.column are not numbers -- you probably meant to omit ' +
|
||
|
'the original mapping entirely and only map the generated position. If so, pass ' +
|
||
|
'null for the original mapping instead of an object with empty or null values.'
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
||
|
&& aGenerated.line > 0 && aGenerated.column >= 0
|
||
|
&& !aOriginal && !aSource && !aName) {
|
||
|
// Case 1.
|
||
|
return;
|
||
|
}
|
||
|
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
|
||
|
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
|
||
|
&& aGenerated.line > 0 && aGenerated.column >= 0
|
||
|
&& aOriginal.line > 0 && aOriginal.column >= 0
|
||
|
&& aSource) {
|
||
|
// Cases 2 and 3.
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
throw new Error('Invalid mapping: ' + JSON.stringify({
|
||
|
generated: aGenerated,
|
||
|
source: aSource,
|
||
|
original: aOriginal,
|
||
|
name: aName
|
||
|
}));
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Serialize the accumulated mappings in to the stream of base 64 VLQs
|
||
|
* specified by the source map format.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype._serializeMappings =
|
||
|
function SourceMapGenerator_serializeMappings() {
|
||
|
var previousGeneratedColumn = 0;
|
||
|
var previousGeneratedLine = 1;
|
||
|
var previousOriginalColumn = 0;
|
||
|
var previousOriginalLine = 0;
|
||
|
var previousName = 0;
|
||
|
var previousSource = 0;
|
||
|
var result = '';
|
||
|
var next;
|
||
|
var mapping;
|
||
|
var nameIdx;
|
||
|
var sourceIdx;
|
||
|
|
||
|
var mappings = this._mappings.toArray();
|
||
|
for (var i = 0, len = mappings.length; i < len; i++) {
|
||
|
mapping = mappings[i];
|
||
|
next = ''
|
||
|
|
||
|
if (mapping.generatedLine !== previousGeneratedLine) {
|
||
|
previousGeneratedColumn = 0;
|
||
|
while (mapping.generatedLine !== previousGeneratedLine) {
|
||
|
next += ';';
|
||
|
previousGeneratedLine++;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (i > 0) {
|
||
|
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
|
||
|
continue;
|
||
|
}
|
||
|
next += ',';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
next += base64VLQ.encode(mapping.generatedColumn
|
||
|
- previousGeneratedColumn);
|
||
|
previousGeneratedColumn = mapping.generatedColumn;
|
||
|
|
||
|
if (mapping.source != null) {
|
||
|
sourceIdx = this._sources.indexOf(mapping.source);
|
||
|
next += base64VLQ.encode(sourceIdx - previousSource);
|
||
|
previousSource = sourceIdx;
|
||
|
|
||
|
// lines are stored 0-based in SourceMap spec version 3
|
||
|
next += base64VLQ.encode(mapping.originalLine - 1
|
||
|
- previousOriginalLine);
|
||
|
previousOriginalLine = mapping.originalLine - 1;
|
||
|
|
||
|
next += base64VLQ.encode(mapping.originalColumn
|
||
|
- previousOriginalColumn);
|
||
|
previousOriginalColumn = mapping.originalColumn;
|
||
|
|
||
|
if (mapping.name != null) {
|
||
|
nameIdx = this._names.indexOf(mapping.name);
|
||
|
next += base64VLQ.encode(nameIdx - previousName);
|
||
|
previousName = nameIdx;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
result += next;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
SourceMapGenerator.prototype._generateSourcesContent =
|
||
|
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
|
||
|
return aSources.map(function (source) {
|
||
|
if (!this._sourcesContents) {
|
||
|
return null;
|
||
|
}
|
||
|
if (aSourceRoot != null) {
|
||
|
source = util.relative(aSourceRoot, source);
|
||
|
}
|
||
|
var key = util.toSetString(source);
|
||
|
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
|
||
|
? this._sourcesContents[key]
|
||
|
: null;
|
||
|
}, this);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Externalize the source map.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype.toJSON =
|
||
|
function SourceMapGenerator_toJSON() {
|
||
|
var map = {
|
||
|
version: this._version,
|
||
|
sources: this._sources.toArray(),
|
||
|
names: this._names.toArray(),
|
||
|
mappings: this._serializeMappings()
|
||
|
};
|
||
|
if (this._file != null) {
|
||
|
map.file = this._file;
|
||
|
}
|
||
|
if (this._sourceRoot != null) {
|
||
|
map.sourceRoot = this._sourceRoot;
|
||
|
}
|
||
|
if (this._sourcesContents) {
|
||
|
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
|
||
|
}
|
||
|
|
||
|
return map;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Render the source map being generated to a string.
|
||
|
*/
|
||
|
SourceMapGenerator.prototype.toString =
|
||
|
function SourceMapGenerator_toString() {
|
||
|
return JSON.stringify(this.toJSON());
|
||
|
};
|
||
|
|
||
|
exports.SourceMapGenerator = SourceMapGenerator;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 5 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*
|
||
|
* Based on the Base 64 VLQ implementation in Closure Compiler:
|
||
|
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
|
||
|
*
|
||
|
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are
|
||
|
* met:
|
||
|
*
|
||
|
* * Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* * Redistributions in binary form must reproduce the above
|
||
|
* copyright notice, this list of conditions and the following
|
||
|
* disclaimer in the documentation and/or other materials provided
|
||
|
* with the distribution.
|
||
|
* * Neither the name of Google Inc. nor the names of its
|
||
|
* contributors may be used to endorse or promote products derived
|
||
|
* from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
|
||
|
var base64 = __webpack_require__(6);
|
||
|
|
||
|
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
|
||
|
// length quantities we use in the source map spec, the first bit is the sign,
|
||
|
// the next four bits are the actual value, and the 6th bit is the
|
||
|
// continuation bit. The continuation bit tells us whether there are more
|
||
|
// digits in this value following this digit.
|
||
|
//
|
||
|
// Continuation
|
||
|
// | Sign
|
||
|
// | |
|
||
|
// V V
|
||
|
// 101011
|
||
|
|
||
|
var VLQ_BASE_SHIFT = 5;
|
||
|
|
||
|
// binary: 100000
|
||
|
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
|
||
|
|
||
|
// binary: 011111
|
||
|
var VLQ_BASE_MASK = VLQ_BASE - 1;
|
||
|
|
||
|
// binary: 100000
|
||
|
var VLQ_CONTINUATION_BIT = VLQ_BASE;
|
||
|
|
||
|
/**
|
||
|
* Converts from a two-complement value to a value where the sign bit is
|
||
|
* placed in the least significant bit. For example, as decimals:
|
||
|
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
|
||
|
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
|
||
|
*/
|
||
|
function toVLQSigned(aValue) {
|
||
|
return aValue < 0
|
||
|
? ((-aValue) << 1) + 1
|
||
|
: (aValue << 1) + 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Converts to a two-complement value from a value where the sign bit is
|
||
|
* placed in the least significant bit. For example, as decimals:
|
||
|
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
|
||
|
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
|
||
|
*/
|
||
|
function fromVLQSigned(aValue) {
|
||
|
var isNegative = (aValue & 1) === 1;
|
||
|
var shifted = aValue >> 1;
|
||
|
return isNegative
|
||
|
? -shifted
|
||
|
: shifted;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the base 64 VLQ encoded value.
|
||
|
*/
|
||
|
exports.encode = function base64VLQ_encode(aValue) {
|
||
|
var encoded = "";
|
||
|
var digit;
|
||
|
|
||
|
var vlq = toVLQSigned(aValue);
|
||
|
|
||
|
do {
|
||
|
digit = vlq & VLQ_BASE_MASK;
|
||
|
vlq >>>= VLQ_BASE_SHIFT;
|
||
|
if (vlq > 0) {
|
||
|
// There are still more digits in this value, so we must make sure the
|
||
|
// continuation bit is marked.
|
||
|
digit |= VLQ_CONTINUATION_BIT;
|
||
|
}
|
||
|
encoded += base64.encode(digit);
|
||
|
} while (vlq > 0);
|
||
|
|
||
|
return encoded;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Decodes the next base 64 VLQ value from the given string and returns the
|
||
|
* value and the rest of the string via the out parameter.
|
||
|
*/
|
||
|
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
|
||
|
var strLen = aStr.length;
|
||
|
var result = 0;
|
||
|
var shift = 0;
|
||
|
var continuation, digit;
|
||
|
|
||
|
do {
|
||
|
if (aIndex >= strLen) {
|
||
|
throw new Error("Expected more digits in base 64 VLQ value.");
|
||
|
}
|
||
|
|
||
|
digit = base64.decode(aStr.charCodeAt(aIndex++));
|
||
|
if (digit === -1) {
|
||
|
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
|
||
|
}
|
||
|
|
||
|
continuation = !!(digit & VLQ_CONTINUATION_BIT);
|
||
|
digit &= VLQ_BASE_MASK;
|
||
|
result = result + (digit << shift);
|
||
|
shift += VLQ_BASE_SHIFT;
|
||
|
} while (continuation);
|
||
|
|
||
|
aOutParam.value = fromVLQSigned(result);
|
||
|
aOutParam.rest = aIndex;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 6 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
|
||
|
|
||
|
/**
|
||
|
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
|
||
|
*/
|
||
|
exports.encode = function (number) {
|
||
|
if (0 <= number && number < intToCharMap.length) {
|
||
|
return intToCharMap[number];
|
||
|
}
|
||
|
throw new TypeError("Must be between 0 and 63: " + number);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Decode a single base 64 character code digit to an integer. Returns -1 on
|
||
|
* failure.
|
||
|
*/
|
||
|
exports.decode = function (charCode) {
|
||
|
var bigA = 65; // 'A'
|
||
|
var bigZ = 90; // 'Z'
|
||
|
|
||
|
var littleA = 97; // 'a'
|
||
|
var littleZ = 122; // 'z'
|
||
|
|
||
|
var zero = 48; // '0'
|
||
|
var nine = 57; // '9'
|
||
|
|
||
|
var plus = 43; // '+'
|
||
|
var slash = 47; // '/'
|
||
|
|
||
|
var littleOffset = 26;
|
||
|
var numberOffset = 52;
|
||
|
|
||
|
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||
|
if (bigA <= charCode && charCode <= bigZ) {
|
||
|
return (charCode - bigA);
|
||
|
}
|
||
|
|
||
|
// 26 - 51: abcdefghijklmnopqrstuvwxyz
|
||
|
if (littleA <= charCode && charCode <= littleZ) {
|
||
|
return (charCode - littleA + littleOffset);
|
||
|
}
|
||
|
|
||
|
// 52 - 61: 0123456789
|
||
|
if (zero <= charCode && charCode <= nine) {
|
||
|
return (charCode - zero + numberOffset);
|
||
|
}
|
||
|
|
||
|
// 62: +
|
||
|
if (charCode == plus) {
|
||
|
return 62;
|
||
|
}
|
||
|
|
||
|
// 63: /
|
||
|
if (charCode == slash) {
|
||
|
return 63;
|
||
|
}
|
||
|
|
||
|
// Invalid base64 digit.
|
||
|
return -1;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 7 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* This is a helper function for getting values from parameter/options
|
||
|
* objects.
|
||
|
*
|
||
|
* @param args The object we are extracting values from
|
||
|
* @param name The name of the property we are getting.
|
||
|
* @param defaultValue An optional value to return if the property is missing
|
||
|
* from the object. If this is not specified and the property is missing, an
|
||
|
* error will be thrown.
|
||
|
*/
|
||
|
function getArg(aArgs, aName, aDefaultValue) {
|
||
|
if (aName in aArgs) {
|
||
|
return aArgs[aName];
|
||
|
} else if (arguments.length === 3) {
|
||
|
return aDefaultValue;
|
||
|
} else {
|
||
|
throw new Error('"' + aName + '" is a required argument.');
|
||
|
}
|
||
|
}
|
||
|
exports.getArg = getArg;
|
||
|
|
||
|
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
|
||
|
var dataUrlRegexp = /^data:.+\,.+$/;
|
||
|
|
||
|
function urlParse(aUrl) {
|
||
|
var match = aUrl.match(urlRegexp);
|
||
|
if (!match) {
|
||
|
return null;
|
||
|
}
|
||
|
return {
|
||
|
scheme: match[1],
|
||
|
auth: match[2],
|
||
|
host: match[3],
|
||
|
port: match[4],
|
||
|
path: match[5]
|
||
|
};
|
||
|
}
|
||
|
exports.urlParse = urlParse;
|
||
|
|
||
|
function urlGenerate(aParsedUrl) {
|
||
|
var url = '';
|
||
|
if (aParsedUrl.scheme) {
|
||
|
url += aParsedUrl.scheme + ':';
|
||
|
}
|
||
|
url += '//';
|
||
|
if (aParsedUrl.auth) {
|
||
|
url += aParsedUrl.auth + '@';
|
||
|
}
|
||
|
if (aParsedUrl.host) {
|
||
|
url += aParsedUrl.host;
|
||
|
}
|
||
|
if (aParsedUrl.port) {
|
||
|
url += ":" + aParsedUrl.port
|
||
|
}
|
||
|
if (aParsedUrl.path) {
|
||
|
url += aParsedUrl.path;
|
||
|
}
|
||
|
return url;
|
||
|
}
|
||
|
exports.urlGenerate = urlGenerate;
|
||
|
|
||
|
/**
|
||
|
* Normalizes a path, or the path portion of a URL:
|
||
|
*
|
||
|
* - Replaces consecutive slashes with one slash.
|
||
|
* - Removes unnecessary '.' parts.
|
||
|
* - Removes unnecessary '<dir>/..' parts.
|
||
|
*
|
||
|
* Based on code in the Node.js 'path' core module.
|
||
|
*
|
||
|
* @param aPath The path or url to normalize.
|
||
|
*/
|
||
|
function normalize(aPath) {
|
||
|
var path = aPath;
|
||
|
var url = urlParse(aPath);
|
||
|
if (url) {
|
||
|
if (!url.path) {
|
||
|
return aPath;
|
||
|
}
|
||
|
path = url.path;
|
||
|
}
|
||
|
var isAbsolute = exports.isAbsolute(path);
|
||
|
|
||
|
var parts = path.split(/\/+/);
|
||
|
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
|
||
|
part = parts[i];
|
||
|
if (part === '.') {
|
||
|
parts.splice(i, 1);
|
||
|
} else if (part === '..') {
|
||
|
up++;
|
||
|
} else if (up > 0) {
|
||
|
if (part === '') {
|
||
|
// The first part is blank if the path is absolute. Trying to go
|
||
|
// above the root is a no-op. Therefore we can remove all '..' parts
|
||
|
// directly after the root.
|
||
|
parts.splice(i + 1, up);
|
||
|
up = 0;
|
||
|
} else {
|
||
|
parts.splice(i, 2);
|
||
|
up--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
path = parts.join('/');
|
||
|
|
||
|
if (path === '') {
|
||
|
path = isAbsolute ? '/' : '.';
|
||
|
}
|
||
|
|
||
|
if (url) {
|
||
|
url.path = path;
|
||
|
return urlGenerate(url);
|
||
|
}
|
||
|
return path;
|
||
|
}
|
||
|
exports.normalize = normalize;
|
||
|
|
||
|
/**
|
||
|
* Joins two paths/URLs.
|
||
|
*
|
||
|
* @param aRoot The root path or URL.
|
||
|
* @param aPath The path or URL to be joined with the root.
|
||
|
*
|
||
|
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
|
||
|
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
|
||
|
* first.
|
||
|
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
|
||
|
* is updated with the result and aRoot is returned. Otherwise the result
|
||
|
* is returned.
|
||
|
* - If aPath is absolute, the result is aPath.
|
||
|
* - Otherwise the two paths are joined with a slash.
|
||
|
* - Joining for example 'http://' and 'www.example.com' is also supported.
|
||
|
*/
|
||
|
function join(aRoot, aPath) {
|
||
|
if (aRoot === "") {
|
||
|
aRoot = ".";
|
||
|
}
|
||
|
if (aPath === "") {
|
||
|
aPath = ".";
|
||
|
}
|
||
|
var aPathUrl = urlParse(aPath);
|
||
|
var aRootUrl = urlParse(aRoot);
|
||
|
if (aRootUrl) {
|
||
|
aRoot = aRootUrl.path || '/';
|
||
|
}
|
||
|
|
||
|
// `join(foo, '//www.example.org')`
|
||
|
if (aPathUrl && !aPathUrl.scheme) {
|
||
|
if (aRootUrl) {
|
||
|
aPathUrl.scheme = aRootUrl.scheme;
|
||
|
}
|
||
|
return urlGenerate(aPathUrl);
|
||
|
}
|
||
|
|
||
|
if (aPathUrl || aPath.match(dataUrlRegexp)) {
|
||
|
return aPath;
|
||
|
}
|
||
|
|
||
|
// `join('http://', 'www.example.com')`
|
||
|
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
|
||
|
aRootUrl.host = aPath;
|
||
|
return urlGenerate(aRootUrl);
|
||
|
}
|
||
|
|
||
|
var joined = aPath.charAt(0) === '/'
|
||
|
? aPath
|
||
|
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
|
||
|
|
||
|
if (aRootUrl) {
|
||
|
aRootUrl.path = joined;
|
||
|
return urlGenerate(aRootUrl);
|
||
|
}
|
||
|
return joined;
|
||
|
}
|
||
|
exports.join = join;
|
||
|
|
||
|
exports.isAbsolute = function (aPath) {
|
||
|
return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Make a path relative to a URL or another path.
|
||
|
*
|
||
|
* @param aRoot The root path or URL.
|
||
|
* @param aPath The path or URL to be made relative to aRoot.
|
||
|
*/
|
||
|
function relative(aRoot, aPath) {
|
||
|
if (aRoot === "") {
|
||
|
aRoot = ".";
|
||
|
}
|
||
|
|
||
|
aRoot = aRoot.replace(/\/$/, '');
|
||
|
|
||
|
// It is possible for the path to be above the root. In this case, simply
|
||
|
// checking whether the root is a prefix of the path won't work. Instead, we
|
||
|
// need to remove components from the root one by one, until either we find
|
||
|
// a prefix that fits, or we run out of components to remove.
|
||
|
var level = 0;
|
||
|
while (aPath.indexOf(aRoot + '/') !== 0) {
|
||
|
var index = aRoot.lastIndexOf("/");
|
||
|
if (index < 0) {
|
||
|
return aPath;
|
||
|
}
|
||
|
|
||
|
// If the only part of the root that is left is the scheme (i.e. http://,
|
||
|
// file:///, etc.), one or more slashes (/), or simply nothing at all, we
|
||
|
// have exhausted all components, so the path is not relative to the root.
|
||
|
aRoot = aRoot.slice(0, index);
|
||
|
if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
|
||
|
return aPath;
|
||
|
}
|
||
|
|
||
|
++level;
|
||
|
}
|
||
|
|
||
|
// Make sure we add a "../" for each component we removed from the root.
|
||
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
||
|
}
|
||
|
exports.relative = relative;
|
||
|
|
||
|
var supportsNullProto = (function () {
|
||
|
var obj = Object.create(null);
|
||
|
return !('__proto__' in obj);
|
||
|
}());
|
||
|
|
||
|
function identity (s) {
|
||
|
return s;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Because behavior goes wacky when you set `__proto__` on objects, we
|
||
|
* have to prefix all the strings in our set with an arbitrary character.
|
||
|
*
|
||
|
* See https://github.com/mozilla/source-map/pull/31 and
|
||
|
* https://github.com/mozilla/source-map/issues/30
|
||
|
*
|
||
|
* @param String aStr
|
||
|
*/
|
||
|
function toSetString(aStr) {
|
||
|
if (isProtoString(aStr)) {
|
||
|
return '$' + aStr;
|
||
|
}
|
||
|
|
||
|
return aStr;
|
||
|
}
|
||
|
exports.toSetString = supportsNullProto ? identity : toSetString;
|
||
|
|
||
|
function fromSetString(aStr) {
|
||
|
if (isProtoString(aStr)) {
|
||
|
return aStr.slice(1);
|
||
|
}
|
||
|
|
||
|
return aStr;
|
||
|
}
|
||
|
exports.fromSetString = supportsNullProto ? identity : fromSetString;
|
||
|
|
||
|
function isProtoString(s) {
|
||
|
if (!s) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
var length = s.length;
|
||
|
|
||
|
if (length < 9 /* "__proto__".length */) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
|
||
|
s.charCodeAt(length - 2) !== 95 /* '_' */ ||
|
||
|
s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
|
||
|
s.charCodeAt(length - 4) !== 116 /* 't' */ ||
|
||
|
s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
|
||
|
s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
|
||
|
s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
|
||
|
s.charCodeAt(length - 8) !== 95 /* '_' */ ||
|
||
|
s.charCodeAt(length - 9) !== 95 /* '_' */) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
for (var i = length - 10; i >= 0; i--) {
|
||
|
if (s.charCodeAt(i) !== 36 /* '$' */) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Comparator between two mappings where the original positions are compared.
|
||
|
*
|
||
|
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
||
|
* mappings with the same original source/line/column, but different generated
|
||
|
* line and column the same. Useful when searching for a mapping with a
|
||
|
* stubbed out mapping.
|
||
|
*/
|
||
|
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
|
||
|
var cmp = strcmp(mappingA.source, mappingB.source);
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.originalLine - mappingB.originalLine;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||
|
if (cmp !== 0 || onlyCompareOriginal) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
return strcmp(mappingA.name, mappingB.name);
|
||
|
}
|
||
|
exports.compareByOriginalPositions = compareByOriginalPositions;
|
||
|
|
||
|
/**
|
||
|
* Comparator between two mappings with deflated source and name indices where
|
||
|
* the generated positions are compared.
|
||
|
*
|
||
|
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
|
||
|
* mappings with the same generated line and column, but different
|
||
|
* source/name/original line and column the same. Useful when searching for a
|
||
|
* mapping with a stubbed out mapping.
|
||
|
*/
|
||
|
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
|
||
|
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||
|
if (cmp !== 0 || onlyCompareGenerated) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = strcmp(mappingA.source, mappingB.source);
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.originalLine - mappingB.originalLine;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
return strcmp(mappingA.name, mappingB.name);
|
||
|
}
|
||
|
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
|
||
|
|
||
|
function strcmp(aStr1, aStr2) {
|
||
|
if (aStr1 === aStr2) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (aStr1 === null) {
|
||
|
return 1; // aStr2 !== null
|
||
|
}
|
||
|
|
||
|
if (aStr2 === null) {
|
||
|
return -1; // aStr1 !== null
|
||
|
}
|
||
|
|
||
|
if (aStr1 > aStr2) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Comparator between two mappings with inflated source and name strings where
|
||
|
* the generated positions are compared.
|
||
|
*/
|
||
|
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
|
||
|
var cmp = mappingA.generatedLine - mappingB.generatedLine;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = strcmp(mappingA.source, mappingB.source);
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.originalLine - mappingB.originalLine;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
cmp = mappingA.originalColumn - mappingB.originalColumn;
|
||
|
if (cmp !== 0) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
return strcmp(mappingA.name, mappingB.name);
|
||
|
}
|
||
|
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
|
||
|
|
||
|
/**
|
||
|
* Strip any JSON XSSI avoidance prefix from the string (as documented
|
||
|
* in the source maps specification), and then parse the string as
|
||
|
* JSON.
|
||
|
*/
|
||
|
function parseSourceMapInput(str) {
|
||
|
return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
|
||
|
}
|
||
|
exports.parseSourceMapInput = parseSourceMapInput;
|
||
|
|
||
|
/**
|
||
|
* Compute the URL of a source given the the source root, the source's
|
||
|
* URL, and the source map's URL.
|
||
|
*/
|
||
|
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
|
||
|
sourceURL = sourceURL || '';
|
||
|
|
||
|
if (sourceRoot) {
|
||
|
// This follows what Chrome does.
|
||
|
if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
|
||
|
sourceRoot += '/';
|
||
|
}
|
||
|
// The spec says:
|
||
|
// Line 4: An optional source root, useful for relocating source
|
||
|
// files on a server or removing repeated values in the
|
||
|
// “sources” entry. This value is prepended to the individual
|
||
|
// entries in the “source” field.
|
||
|
sourceURL = sourceRoot + sourceURL;
|
||
|
}
|
||
|
|
||
|
// Historically, SourceMapConsumer did not take the sourceMapURL as
|
||
|
// a parameter. This mode is still somewhat supported, which is why
|
||
|
// this code block is conditional. However, it's preferable to pass
|
||
|
// the source map URL to SourceMapConsumer, so that this function
|
||
|
// can implement the source URL resolution algorithm as outlined in
|
||
|
// the spec. This block is basically the equivalent of:
|
||
|
// new URL(sourceURL, sourceMapURL).toString()
|
||
|
// ... except it avoids using URL, which wasn't available in the
|
||
|
// older releases of node still supported by this library.
|
||
|
//
|
||
|
// The spec says:
|
||
|
// If the sources are not absolute URLs after prepending of the
|
||
|
// “sourceRoot”, the sources are resolved relative to the
|
||
|
// SourceMap (like resolving script src in a html document).
|
||
|
if (sourceMapURL) {
|
||
|
var parsed = urlParse(sourceMapURL);
|
||
|
if (!parsed) {
|
||
|
throw new Error("sourceMapURL could not be parsed");
|
||
|
}
|
||
|
if (parsed.path) {
|
||
|
// Strip the last path component, but keep the "/".
|
||
|
var index = parsed.path.lastIndexOf('/');
|
||
|
if (index >= 0) {
|
||
|
parsed.path = parsed.path.substring(0, index + 1);
|
||
|
}
|
||
|
}
|
||
|
sourceURL = join(urlGenerate(parsed), sourceURL);
|
||
|
}
|
||
|
|
||
|
return normalize(sourceURL);
|
||
|
}
|
||
|
exports.computeSourceURL = computeSourceURL;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 8 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
var util = __webpack_require__(7);
|
||
|
var has = Object.prototype.hasOwnProperty;
|
||
|
var hasNativeMap = typeof Map !== "undefined";
|
||
|
|
||
|
/**
|
||
|
* A data structure which is a combination of an array and a set. Adding a new
|
||
|
* member is O(1), testing for membership is O(1), and finding the index of an
|
||
|
* element is O(1). Removing elements from the set is not supported. Only
|
||
|
* strings are supported for membership.
|
||
|
*/
|
||
|
function ArraySet() {
|
||
|
this._array = [];
|
||
|
this._set = hasNativeMap ? new Map() : Object.create(null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Static method for creating ArraySet instances from an existing array.
|
||
|
*/
|
||
|
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
|
||
|
var set = new ArraySet();
|
||
|
for (var i = 0, len = aArray.length; i < len; i++) {
|
||
|
set.add(aArray[i], aAllowDuplicates);
|
||
|
}
|
||
|
return set;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return how many unique items are in this ArraySet. If duplicates have been
|
||
|
* added, than those do not count towards the size.
|
||
|
*
|
||
|
* @returns Number
|
||
|
*/
|
||
|
ArraySet.prototype.size = function ArraySet_size() {
|
||
|
return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Add the given string to this set.
|
||
|
*
|
||
|
* @param String aStr
|
||
|
*/
|
||
|
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
|
||
|
var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
|
||
|
var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
|
||
|
var idx = this._array.length;
|
||
|
if (!isDuplicate || aAllowDuplicates) {
|
||
|
this._array.push(aStr);
|
||
|
}
|
||
|
if (!isDuplicate) {
|
||
|
if (hasNativeMap) {
|
||
|
this._set.set(aStr, idx);
|
||
|
} else {
|
||
|
this._set[sStr] = idx;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Is the given string a member of this set?
|
||
|
*
|
||
|
* @param String aStr
|
||
|
*/
|
||
|
ArraySet.prototype.has = function ArraySet_has(aStr) {
|
||
|
if (hasNativeMap) {
|
||
|
return this._set.has(aStr);
|
||
|
} else {
|
||
|
var sStr = util.toSetString(aStr);
|
||
|
return has.call(this._set, sStr);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* What is the index of the given string in the array?
|
||
|
*
|
||
|
* @param String aStr
|
||
|
*/
|
||
|
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
|
||
|
if (hasNativeMap) {
|
||
|
var idx = this._set.get(aStr);
|
||
|
if (idx >= 0) {
|
||
|
return idx;
|
||
|
}
|
||
|
} else {
|
||
|
var sStr = util.toSetString(aStr);
|
||
|
if (has.call(this._set, sStr)) {
|
||
|
return this._set[sStr];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
throw new Error('"' + aStr + '" is not in the set.');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* What is the element at the given index?
|
||
|
*
|
||
|
* @param Number aIdx
|
||
|
*/
|
||
|
ArraySet.prototype.at = function ArraySet_at(aIdx) {
|
||
|
if (aIdx >= 0 && aIdx < this._array.length) {
|
||
|
return this._array[aIdx];
|
||
|
}
|
||
|
throw new Error('No element indexed by ' + aIdx);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the array representation of this set (which has the proper indices
|
||
|
* indicated by indexOf). Note that this is a copy of the internal array used
|
||
|
* for storing the members so that no one can mess with internal state.
|
||
|
*/
|
||
|
ArraySet.prototype.toArray = function ArraySet_toArray() {
|
||
|
return this._array.slice();
|
||
|
};
|
||
|
|
||
|
exports.ArraySet = ArraySet;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 9 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2014 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
var util = __webpack_require__(7);
|
||
|
|
||
|
/**
|
||
|
* Determine whether mappingB is after mappingA with respect to generated
|
||
|
* position.
|
||
|
*/
|
||
|
function generatedPositionAfter(mappingA, mappingB) {
|
||
|
// Optimized for most common case
|
||
|
var lineA = mappingA.generatedLine;
|
||
|
var lineB = mappingB.generatedLine;
|
||
|
var columnA = mappingA.generatedColumn;
|
||
|
var columnB = mappingB.generatedColumn;
|
||
|
return lineB > lineA || lineB == lineA && columnB >= columnA ||
|
||
|
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* A data structure to provide a sorted view of accumulated mappings in a
|
||
|
* performance conscious manner. It trades a neglibable overhead in general
|
||
|
* case for a large speedup in case of mappings being added in order.
|
||
|
*/
|
||
|
function MappingList() {
|
||
|
this._array = [];
|
||
|
this._sorted = true;
|
||
|
// Serves as infimum
|
||
|
this._last = {generatedLine: -1, generatedColumn: 0};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Iterate through internal items. This method takes the same arguments that
|
||
|
* `Array.prototype.forEach` takes.
|
||
|
*
|
||
|
* NOTE: The order of the mappings is NOT guaranteed.
|
||
|
*/
|
||
|
MappingList.prototype.unsortedForEach =
|
||
|
function MappingList_forEach(aCallback, aThisArg) {
|
||
|
this._array.forEach(aCallback, aThisArg);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Add the given source mapping.
|
||
|
*
|
||
|
* @param Object aMapping
|
||
|
*/
|
||
|
MappingList.prototype.add = function MappingList_add(aMapping) {
|
||
|
if (generatedPositionAfter(this._last, aMapping)) {
|
||
|
this._last = aMapping;
|
||
|
this._array.push(aMapping);
|
||
|
} else {
|
||
|
this._sorted = false;
|
||
|
this._array.push(aMapping);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the flat, sorted array of mappings. The mappings are sorted by
|
||
|
* generated position.
|
||
|
*
|
||
|
* WARNING: This method returns internal data without copying, for
|
||
|
* performance. The return value must NOT be mutated, and should be treated as
|
||
|
* an immutable borrow. If you want to take ownership, you must make your own
|
||
|
* copy.
|
||
|
*/
|
||
|
MappingList.prototype.toArray = function MappingList_toArray() {
|
||
|
if (!this._sorted) {
|
||
|
this._array.sort(util.compareByGeneratedPositionsInflated);
|
||
|
this._sorted = true;
|
||
|
}
|
||
|
return this._array;
|
||
|
};
|
||
|
|
||
|
exports.MappingList = MappingList;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 10 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
var util = __webpack_require__(7);
|
||
|
var binarySearch = __webpack_require__(11);
|
||
|
var ArraySet = (__webpack_require__(8).ArraySet);
|
||
|
var base64VLQ = __webpack_require__(5);
|
||
|
var quickSort = (__webpack_require__(12).quickSort);
|
||
|
|
||
|
function SourceMapConsumer(aSourceMap, aSourceMapURL) {
|
||
|
var sourceMap = aSourceMap;
|
||
|
if (typeof aSourceMap === 'string') {
|
||
|
sourceMap = util.parseSourceMapInput(aSourceMap);
|
||
|
}
|
||
|
|
||
|
return sourceMap.sections != null
|
||
|
? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
|
||
|
: new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
|
||
|
}
|
||
|
|
||
|
SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {
|
||
|
return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The version of the source mapping spec that we are consuming.
|
||
|
*/
|
||
|
SourceMapConsumer.prototype._version = 3;
|
||
|
|
||
|
// `__generatedMappings` and `__originalMappings` are arrays that hold the
|
||
|
// parsed mapping coordinates from the source map's "mappings" attribute. They
|
||
|
// are lazily instantiated, accessed via the `_generatedMappings` and
|
||
|
// `_originalMappings` getters respectively, and we only parse the mappings
|
||
|
// and create these arrays once queried for a source location. We jump through
|
||
|
// these hoops because there can be many thousands of mappings, and parsing
|
||
|
// them is expensive, so we only want to do it if we must.
|
||
|
//
|
||
|
// Each object in the arrays is of the form:
|
||
|
//
|
||
|
// {
|
||
|
// generatedLine: The line number in the generated code,
|
||
|
// generatedColumn: The column number in the generated code,
|
||
|
// source: The path to the original source file that generated this
|
||
|
// chunk of code,
|
||
|
// originalLine: The line number in the original source that
|
||
|
// corresponds to this chunk of generated code,
|
||
|
// originalColumn: The column number in the original source that
|
||
|
// corresponds to this chunk of generated code,
|
||
|
// name: The name of the original symbol which generated this chunk of
|
||
|
// code.
|
||
|
// }
|
||
|
//
|
||
|
// All properties except for `generatedLine` and `generatedColumn` can be
|
||
|
// `null`.
|
||
|
//
|
||
|
// `_generatedMappings` is ordered by the generated positions.
|
||
|
//
|
||
|
// `_originalMappings` is ordered by the original positions.
|
||
|
|
||
|
SourceMapConsumer.prototype.__generatedMappings = null;
|
||
|
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
|
||
|
configurable: true,
|
||
|
enumerable: true,
|
||
|
get: function () {
|
||
|
if (!this.__generatedMappings) {
|
||
|
this._parseMappings(this._mappings, this.sourceRoot);
|
||
|
}
|
||
|
|
||
|
return this.__generatedMappings;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
SourceMapConsumer.prototype.__originalMappings = null;
|
||
|
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
|
||
|
configurable: true,
|
||
|
enumerable: true,
|
||
|
get: function () {
|
||
|
if (!this.__originalMappings) {
|
||
|
this._parseMappings(this._mappings, this.sourceRoot);
|
||
|
}
|
||
|
|
||
|
return this.__originalMappings;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
SourceMapConsumer.prototype._charIsMappingSeparator =
|
||
|
function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
|
||
|
var c = aStr.charAt(index);
|
||
|
return c === ";" || c === ",";
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parse the mappings in a string in to a data structure which we can easily
|
||
|
* query (the ordered arrays in the `this.__generatedMappings` and
|
||
|
* `this.__originalMappings` properties).
|
||
|
*/
|
||
|
SourceMapConsumer.prototype._parseMappings =
|
||
|
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
||
|
throw new Error("Subclasses must implement _parseMappings");
|
||
|
};
|
||
|
|
||
|
SourceMapConsumer.GENERATED_ORDER = 1;
|
||
|
SourceMapConsumer.ORIGINAL_ORDER = 2;
|
||
|
|
||
|
SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
|
||
|
SourceMapConsumer.LEAST_UPPER_BOUND = 2;
|
||
|
|
||
|
/**
|
||
|
* Iterate over each mapping between an original source/line/column and a
|
||
|
* generated line/column in this source map.
|
||
|
*
|
||
|
* @param Function aCallback
|
||
|
* The function that is called with each mapping.
|
||
|
* @param Object aContext
|
||
|
* Optional. If specified, this object will be the value of `this` every
|
||
|
* time that `aCallback` is called.
|
||
|
* @param aOrder
|
||
|
* Either `SourceMapConsumer.GENERATED_ORDER` or
|
||
|
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
|
||
|
* iterate over the mappings sorted by the generated file's line/column
|
||
|
* order or the original's source/line/column order, respectively. Defaults to
|
||
|
* `SourceMapConsumer.GENERATED_ORDER`.
|
||
|
*/
|
||
|
SourceMapConsumer.prototype.eachMapping =
|
||
|
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
|
||
|
var context = aContext || null;
|
||
|
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
|
||
|
|
||
|
var mappings;
|
||
|
switch (order) {
|
||
|
case SourceMapConsumer.GENERATED_ORDER:
|
||
|
mappings = this._generatedMappings;
|
||
|
break;
|
||
|
case SourceMapConsumer.ORIGINAL_ORDER:
|
||
|
mappings = this._originalMappings;
|
||
|
break;
|
||
|
default:
|
||
|
throw new Error("Unknown order of iteration.");
|
||
|
}
|
||
|
|
||
|
var sourceRoot = this.sourceRoot;
|
||
|
mappings.map(function (mapping) {
|
||
|
var source = mapping.source === null ? null : this._sources.at(mapping.source);
|
||
|
source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
|
||
|
return {
|
||
|
source: source,
|
||
|
generatedLine: mapping.generatedLine,
|
||
|
generatedColumn: mapping.generatedColumn,
|
||
|
originalLine: mapping.originalLine,
|
||
|
originalColumn: mapping.originalColumn,
|
||
|
name: mapping.name === null ? null : this._names.at(mapping.name)
|
||
|
};
|
||
|
}, this).forEach(aCallback, context);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns all generated line and column information for the original source,
|
||
|
* line, and column provided. If no column is provided, returns all mappings
|
||
|
* corresponding to a either the line we are searching for or the next
|
||
|
* closest line that has any mappings. Otherwise, returns all mappings
|
||
|
* corresponding to the given line and either the column we are searching for
|
||
|
* or the next closest column that has any offsets.
|
||
|
*
|
||
|
* The only argument is an object with the following properties:
|
||
|
*
|
||
|
* - source: The filename of the original source.
|
||
|
* - line: The line number in the original source. The line number is 1-based.
|
||
|
* - column: Optional. the column number in the original source.
|
||
|
* The column number is 0-based.
|
||
|
*
|
||
|
* and an array of objects is returned, each with the following properties:
|
||
|
*
|
||
|
* - line: The line number in the generated source, or null. The
|
||
|
* line number is 1-based.
|
||
|
* - column: The column number in the generated source, or null.
|
||
|
* The column number is 0-based.
|
||
|
*/
|
||
|
SourceMapConsumer.prototype.allGeneratedPositionsFor =
|
||
|
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
|
||
|
var line = util.getArg(aArgs, 'line');
|
||
|
|
||
|
// When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
|
||
|
// returns the index of the closest mapping less than the needle. By
|
||
|
// setting needle.originalColumn to 0, we thus find the last mapping for
|
||
|
// the given line, provided such a mapping exists.
|
||
|
var needle = {
|
||
|
source: util.getArg(aArgs, 'source'),
|
||
|
originalLine: line,
|
||
|
originalColumn: util.getArg(aArgs, 'column', 0)
|
||
|
};
|
||
|
|
||
|
needle.source = this._findSourceIndex(needle.source);
|
||
|
if (needle.source < 0) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
var mappings = [];
|
||
|
|
||
|
var index = this._findMapping(needle,
|
||
|
this._originalMappings,
|
||
|
"originalLine",
|
||
|
"originalColumn",
|
||
|
util.compareByOriginalPositions,
|
||
|
binarySearch.LEAST_UPPER_BOUND);
|
||
|
if (index >= 0) {
|
||
|
var mapping = this._originalMappings[index];
|
||
|
|
||
|
if (aArgs.column === undefined) {
|
||
|
var originalLine = mapping.originalLine;
|
||
|
|
||
|
// Iterate until either we run out of mappings, or we run into
|
||
|
// a mapping for a different line than the one we found. Since
|
||
|
// mappings are sorted, this is guaranteed to find all mappings for
|
||
|
// the line we found.
|
||
|
while (mapping && mapping.originalLine === originalLine) {
|
||
|
mappings.push({
|
||
|
line: util.getArg(mapping, 'generatedLine', null),
|
||
|
column: util.getArg(mapping, 'generatedColumn', null),
|
||
|
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
||
|
});
|
||
|
|
||
|
mapping = this._originalMappings[++index];
|
||
|
}
|
||
|
} else {
|
||
|
var originalColumn = mapping.originalColumn;
|
||
|
|
||
|
// Iterate until either we run out of mappings, or we run into
|
||
|
// a mapping for a different line than the one we were searching for.
|
||
|
// Since mappings are sorted, this is guaranteed to find all mappings for
|
||
|
// the line we are searching for.
|
||
|
while (mapping &&
|
||
|
mapping.originalLine === line &&
|
||
|
mapping.originalColumn == originalColumn) {
|
||
|
mappings.push({
|
||
|
line: util.getArg(mapping, 'generatedLine', null),
|
||
|
column: util.getArg(mapping, 'generatedColumn', null),
|
||
|
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
||
|
});
|
||
|
|
||
|
mapping = this._originalMappings[++index];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return mappings;
|
||
|
};
|
||
|
|
||
|
exports.SourceMapConsumer = SourceMapConsumer;
|
||
|
|
||
|
/**
|
||
|
* A BasicSourceMapConsumer instance represents a parsed source map which we can
|
||
|
* query for information about the original file positions by giving it a file
|
||
|
* position in the generated source.
|
||
|
*
|
||
|
* The first parameter is the raw source map (either as a JSON string, or
|
||
|
* already parsed to an object). According to the spec, source maps have the
|
||
|
* following attributes:
|
||
|
*
|
||
|
* - version: Which version of the source map spec this map is following.
|
||
|
* - sources: An array of URLs to the original source files.
|
||
|
* - names: An array of identifiers which can be referrenced by individual mappings.
|
||
|
* - sourceRoot: Optional. The URL root from which all sources are relative.
|
||
|
* - sourcesContent: Optional. An array of contents of the original source files.
|
||
|
* - mappings: A string of base64 VLQs which contain the actual mappings.
|
||
|
* - file: Optional. The generated file this source map is associated with.
|
||
|
*
|
||
|
* Here is an example source map, taken from the source map spec[0]:
|
||
|
*
|
||
|
* {
|
||
|
* version : 3,
|
||
|
* file: "out.js",
|
||
|
* sourceRoot : "",
|
||
|
* sources: ["foo.js", "bar.js"],
|
||
|
* names: ["src", "maps", "are", "fun"],
|
||
|
* mappings: "AA,AB;;ABCDE;"
|
||
|
* }
|
||
|
*
|
||
|
* The second parameter, if given, is a string whose value is the URL
|
||
|
* at which the source map was found. This URL is used to compute the
|
||
|
* sources array.
|
||
|
*
|
||
|
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
|
||
|
*/
|
||
|
function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
||
|
var sourceMap = aSourceMap;
|
||
|
if (typeof aSourceMap === 'string') {
|
||
|
sourceMap = util.parseSourceMapInput(aSourceMap);
|
||
|
}
|
||
|
|
||
|
var version = util.getArg(sourceMap, 'version');
|
||
|
var sources = util.getArg(sourceMap, 'sources');
|
||
|
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
|
||
|
// requires the array) to play nice here.
|
||
|
var names = util.getArg(sourceMap, 'names', []);
|
||
|
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
|
||
|
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
|
||
|
var mappings = util.getArg(sourceMap, 'mappings');
|
||
|
var file = util.getArg(sourceMap, 'file', null);
|
||
|
|
||
|
// Once again, Sass deviates from the spec and supplies the version as a
|
||
|
// string rather than a number, so we use loose equality checking here.
|
||
|
if (version != this._version) {
|
||
|
throw new Error('Unsupported version: ' + version);
|
||
|
}
|
||
|
|
||
|
if (sourceRoot) {
|
||
|
sourceRoot = util.normalize(sourceRoot);
|
||
|
}
|
||
|
|
||
|
sources = sources
|
||
|
.map(String)
|
||
|
// Some source maps produce relative source paths like "./foo.js" instead of
|
||
|
// "foo.js". Normalize these first so that future comparisons will succeed.
|
||
|
// See bugzil.la/1090768.
|
||
|
.map(util.normalize)
|
||
|
// Always ensure that absolute sources are internally stored relative to
|
||
|
// the source root, if the source root is absolute. Not doing this would
|
||
|
// be particularly problematic when the source root is a prefix of the
|
||
|
// source (valid, but why??). See github issue #199 and bugzil.la/1188982.
|
||
|
.map(function (source) {
|
||
|
return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
|
||
|
? util.relative(sourceRoot, source)
|
||
|
: source;
|
||
|
});
|
||
|
|
||
|
// Pass `true` below to allow duplicate names and sources. While source maps
|
||
|
// are intended to be compressed and deduplicated, the TypeScript compiler
|
||
|
// sometimes generates source maps with duplicates in them. See Github issue
|
||
|
// #72 and bugzil.la/889492.
|
||
|
this._names = ArraySet.fromArray(names.map(String), true);
|
||
|
this._sources = ArraySet.fromArray(sources, true);
|
||
|
|
||
|
this._absoluteSources = this._sources.toArray().map(function (s) {
|
||
|
return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
|
||
|
});
|
||
|
|
||
|
this.sourceRoot = sourceRoot;
|
||
|
this.sourcesContent = sourcesContent;
|
||
|
this._mappings = mappings;
|
||
|
this._sourceMapURL = aSourceMapURL;
|
||
|
this.file = file;
|
||
|
}
|
||
|
|
||
|
BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
||
|
BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
|
||
|
|
||
|
/**
|
||
|
* Utility function to find the index of a source. Returns -1 if not
|
||
|
* found.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {
|
||
|
var relativeSource = aSource;
|
||
|
if (this.sourceRoot != null) {
|
||
|
relativeSource = util.relative(this.sourceRoot, relativeSource);
|
||
|
}
|
||
|
|
||
|
if (this._sources.has(relativeSource)) {
|
||
|
return this._sources.indexOf(relativeSource);
|
||
|
}
|
||
|
|
||
|
// Maybe aSource is an absolute URL as returned by |sources|. In
|
||
|
// this case we can't simply undo the transform.
|
||
|
var i;
|
||
|
for (i = 0; i < this._absoluteSources.length; ++i) {
|
||
|
if (this._absoluteSources[i] == aSource) {
|
||
|
return i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Create a BasicSourceMapConsumer from a SourceMapGenerator.
|
||
|
*
|
||
|
* @param SourceMapGenerator aSourceMap
|
||
|
* The source map that will be consumed.
|
||
|
* @param String aSourceMapURL
|
||
|
* The URL at which the source map can be found (optional)
|
||
|
* @returns BasicSourceMapConsumer
|
||
|
*/
|
||
|
BasicSourceMapConsumer.fromSourceMap =
|
||
|
function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
|
||
|
var smc = Object.create(BasicSourceMapConsumer.prototype);
|
||
|
|
||
|
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
|
||
|
var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
|
||
|
smc.sourceRoot = aSourceMap._sourceRoot;
|
||
|
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
|
||
|
smc.sourceRoot);
|
||
|
smc.file = aSourceMap._file;
|
||
|
smc._sourceMapURL = aSourceMapURL;
|
||
|
smc._absoluteSources = smc._sources.toArray().map(function (s) {
|
||
|
return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);
|
||
|
});
|
||
|
|
||
|
// Because we are modifying the entries (by converting string sources and
|
||
|
// names to indices into the sources and names ArraySets), we have to make
|
||
|
// a copy of the entry or else bad things happen. Shared mutable state
|
||
|
// strikes again! See github issue #191.
|
||
|
|
||
|
var generatedMappings = aSourceMap._mappings.toArray().slice();
|
||
|
var destGeneratedMappings = smc.__generatedMappings = [];
|
||
|
var destOriginalMappings = smc.__originalMappings = [];
|
||
|
|
||
|
for (var i = 0, length = generatedMappings.length; i < length; i++) {
|
||
|
var srcMapping = generatedMappings[i];
|
||
|
var destMapping = new Mapping;
|
||
|
destMapping.generatedLine = srcMapping.generatedLine;
|
||
|
destMapping.generatedColumn = srcMapping.generatedColumn;
|
||
|
|
||
|
if (srcMapping.source) {
|
||
|
destMapping.source = sources.indexOf(srcMapping.source);
|
||
|
destMapping.originalLine = srcMapping.originalLine;
|
||
|
destMapping.originalColumn = srcMapping.originalColumn;
|
||
|
|
||
|
if (srcMapping.name) {
|
||
|
destMapping.name = names.indexOf(srcMapping.name);
|
||
|
}
|
||
|
|
||
|
destOriginalMappings.push(destMapping);
|
||
|
}
|
||
|
|
||
|
destGeneratedMappings.push(destMapping);
|
||
|
}
|
||
|
|
||
|
quickSort(smc.__originalMappings, util.compareByOriginalPositions);
|
||
|
|
||
|
return smc;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* The version of the source mapping spec that we are consuming.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype._version = 3;
|
||
|
|
||
|
/**
|
||
|
* The list of original sources.
|
||
|
*/
|
||
|
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
|
||
|
get: function () {
|
||
|
return this._absoluteSources.slice();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Provide the JIT with a nice shape / hidden class.
|
||
|
*/
|
||
|
function Mapping() {
|
||
|
this.generatedLine = 0;
|
||
|
this.generatedColumn = 0;
|
||
|
this.source = null;
|
||
|
this.originalLine = null;
|
||
|
this.originalColumn = null;
|
||
|
this.name = null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Parse the mappings in a string in to a data structure which we can easily
|
||
|
* query (the ordered arrays in the `this.__generatedMappings` and
|
||
|
* `this.__originalMappings` properties).
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype._parseMappings =
|
||
|
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
||
|
var generatedLine = 1;
|
||
|
var previousGeneratedColumn = 0;
|
||
|
var previousOriginalLine = 0;
|
||
|
var previousOriginalColumn = 0;
|
||
|
var previousSource = 0;
|
||
|
var previousName = 0;
|
||
|
var length = aStr.length;
|
||
|
var index = 0;
|
||
|
var cachedSegments = {};
|
||
|
var temp = {};
|
||
|
var originalMappings = [];
|
||
|
var generatedMappings = [];
|
||
|
var mapping, str, segment, end, value;
|
||
|
|
||
|
while (index < length) {
|
||
|
if (aStr.charAt(index) === ';') {
|
||
|
generatedLine++;
|
||
|
index++;
|
||
|
previousGeneratedColumn = 0;
|
||
|
}
|
||
|
else if (aStr.charAt(index) === ',') {
|
||
|
index++;
|
||
|
}
|
||
|
else {
|
||
|
mapping = new Mapping();
|
||
|
mapping.generatedLine = generatedLine;
|
||
|
|
||
|
// Because each offset is encoded relative to the previous one,
|
||
|
// many segments often have the same encoding. We can exploit this
|
||
|
// fact by caching the parsed variable length fields of each segment,
|
||
|
// allowing us to avoid a second parse if we encounter the same
|
||
|
// segment again.
|
||
|
for (end = index; end < length; end++) {
|
||
|
if (this._charIsMappingSeparator(aStr, end)) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
str = aStr.slice(index, end);
|
||
|
|
||
|
segment = cachedSegments[str];
|
||
|
if (segment) {
|
||
|
index += str.length;
|
||
|
} else {
|
||
|
segment = [];
|
||
|
while (index < end) {
|
||
|
base64VLQ.decode(aStr, index, temp);
|
||
|
value = temp.value;
|
||
|
index = temp.rest;
|
||
|
segment.push(value);
|
||
|
}
|
||
|
|
||
|
if (segment.length === 2) {
|
||
|
throw new Error('Found a source, but no line and column');
|
||
|
}
|
||
|
|
||
|
if (segment.length === 3) {
|
||
|
throw new Error('Found a source and line, but no column');
|
||
|
}
|
||
|
|
||
|
cachedSegments[str] = segment;
|
||
|
}
|
||
|
|
||
|
// Generated column.
|
||
|
mapping.generatedColumn = previousGeneratedColumn + segment[0];
|
||
|
previousGeneratedColumn = mapping.generatedColumn;
|
||
|
|
||
|
if (segment.length > 1) {
|
||
|
// Original source.
|
||
|
mapping.source = previousSource + segment[1];
|
||
|
previousSource += segment[1];
|
||
|
|
||
|
// Original line.
|
||
|
mapping.originalLine = previousOriginalLine + segment[2];
|
||
|
previousOriginalLine = mapping.originalLine;
|
||
|
// Lines are stored 0-based
|
||
|
mapping.originalLine += 1;
|
||
|
|
||
|
// Original column.
|
||
|
mapping.originalColumn = previousOriginalColumn + segment[3];
|
||
|
previousOriginalColumn = mapping.originalColumn;
|
||
|
|
||
|
if (segment.length > 4) {
|
||
|
// Original name.
|
||
|
mapping.name = previousName + segment[4];
|
||
|
previousName += segment[4];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
generatedMappings.push(mapping);
|
||
|
if (typeof mapping.originalLine === 'number') {
|
||
|
originalMappings.push(mapping);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
|
||
|
this.__generatedMappings = generatedMappings;
|
||
|
|
||
|
quickSort(originalMappings, util.compareByOriginalPositions);
|
||
|
this.__originalMappings = originalMappings;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Find the mapping that best matches the hypothetical "needle" mapping that
|
||
|
* we are searching for in the given "haystack" of mappings.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype._findMapping =
|
||
|
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
|
||
|
aColumnName, aComparator, aBias) {
|
||
|
// To return the position we are searching for, we must first find the
|
||
|
// mapping for the given position and then return the opposite position it
|
||
|
// points to. Because the mappings are sorted, we can use binary search to
|
||
|
// find the best mapping.
|
||
|
|
||
|
if (aNeedle[aLineName] <= 0) {
|
||
|
throw new TypeError('Line must be greater than or equal to 1, got '
|
||
|
+ aNeedle[aLineName]);
|
||
|
}
|
||
|
if (aNeedle[aColumnName] < 0) {
|
||
|
throw new TypeError('Column must be greater than or equal to 0, got '
|
||
|
+ aNeedle[aColumnName]);
|
||
|
}
|
||
|
|
||
|
return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Compute the last column for each generated mapping. The last column is
|
||
|
* inclusive.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype.computeColumnSpans =
|
||
|
function SourceMapConsumer_computeColumnSpans() {
|
||
|
for (var index = 0; index < this._generatedMappings.length; ++index) {
|
||
|
var mapping = this._generatedMappings[index];
|
||
|
|
||
|
// Mappings do not contain a field for the last generated columnt. We
|
||
|
// can come up with an optimistic estimate, however, by assuming that
|
||
|
// mappings are contiguous (i.e. given two consecutive mappings, the
|
||
|
// first mapping ends where the second one starts).
|
||
|
if (index + 1 < this._generatedMappings.length) {
|
||
|
var nextMapping = this._generatedMappings[index + 1];
|
||
|
|
||
|
if (mapping.generatedLine === nextMapping.generatedLine) {
|
||
|
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// The last mapping for each line spans the entire line.
|
||
|
mapping.lastGeneratedColumn = Infinity;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the original source, line, and column information for the generated
|
||
|
* source's line and column positions provided. The only argument is an object
|
||
|
* with the following properties:
|
||
|
*
|
||
|
* - line: The line number in the generated source. The line number
|
||
|
* is 1-based.
|
||
|
* - column: The column number in the generated source. The column
|
||
|
* number is 0-based.
|
||
|
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
|
||
|
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||
|
* closest element that is smaller than or greater than the one we are
|
||
|
* searching for, respectively, if the exact element cannot be found.
|
||
|
* Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
|
||
|
*
|
||
|
* and an object is returned with the following properties:
|
||
|
*
|
||
|
* - source: The original source file, or null.
|
||
|
* - line: The line number in the original source, or null. The
|
||
|
* line number is 1-based.
|
||
|
* - column: The column number in the original source, or null. The
|
||
|
* column number is 0-based.
|
||
|
* - name: The original identifier, or null.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype.originalPositionFor =
|
||
|
function SourceMapConsumer_originalPositionFor(aArgs) {
|
||
|
var needle = {
|
||
|
generatedLine: util.getArg(aArgs, 'line'),
|
||
|
generatedColumn: util.getArg(aArgs, 'column')
|
||
|
};
|
||
|
|
||
|
var index = this._findMapping(
|
||
|
needle,
|
||
|
this._generatedMappings,
|
||
|
"generatedLine",
|
||
|
"generatedColumn",
|
||
|
util.compareByGeneratedPositionsDeflated,
|
||
|
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
|
||
|
);
|
||
|
|
||
|
if (index >= 0) {
|
||
|
var mapping = this._generatedMappings[index];
|
||
|
|
||
|
if (mapping.generatedLine === needle.generatedLine) {
|
||
|
var source = util.getArg(mapping, 'source', null);
|
||
|
if (source !== null) {
|
||
|
source = this._sources.at(source);
|
||
|
source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
|
||
|
}
|
||
|
var name = util.getArg(mapping, 'name', null);
|
||
|
if (name !== null) {
|
||
|
name = this._names.at(name);
|
||
|
}
|
||
|
return {
|
||
|
source: source,
|
||
|
line: util.getArg(mapping, 'originalLine', null),
|
||
|
column: util.getArg(mapping, 'originalColumn', null),
|
||
|
name: name
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
source: null,
|
||
|
line: null,
|
||
|
column: null,
|
||
|
name: null
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return true if we have the source content for every source in the source
|
||
|
* map, false otherwise.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype.hasContentsOfAllSources =
|
||
|
function BasicSourceMapConsumer_hasContentsOfAllSources() {
|
||
|
if (!this.sourcesContent) {
|
||
|
return false;
|
||
|
}
|
||
|
return this.sourcesContent.length >= this._sources.size() &&
|
||
|
!this.sourcesContent.some(function (sc) { return sc == null; });
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the original source content. The only argument is the url of the
|
||
|
* original source file. Returns null if no original source content is
|
||
|
* available.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype.sourceContentFor =
|
||
|
function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
||
|
if (!this.sourcesContent) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
var index = this._findSourceIndex(aSource);
|
||
|
if (index >= 0) {
|
||
|
return this.sourcesContent[index];
|
||
|
}
|
||
|
|
||
|
var relativeSource = aSource;
|
||
|
if (this.sourceRoot != null) {
|
||
|
relativeSource = util.relative(this.sourceRoot, relativeSource);
|
||
|
}
|
||
|
|
||
|
var url;
|
||
|
if (this.sourceRoot != null
|
||
|
&& (url = util.urlParse(this.sourceRoot))) {
|
||
|
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
|
||
|
// many users. We can help them out when they expect file:// URIs to
|
||
|
// behave like it would if they were running a local HTTP server. See
|
||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
|
||
|
var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
|
||
|
if (url.scheme == "file"
|
||
|
&& this._sources.has(fileUriAbsPath)) {
|
||
|
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
|
||
|
}
|
||
|
|
||
|
if ((!url.path || url.path == "/")
|
||
|
&& this._sources.has("/" + relativeSource)) {
|
||
|
return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This function is used recursively from
|
||
|
// IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
|
||
|
// don't want to throw if we can't find the source - we just want to
|
||
|
// return null, so we provide a flag to exit gracefully.
|
||
|
if (nullOnMissing) {
|
||
|
return null;
|
||
|
}
|
||
|
else {
|
||
|
throw new Error('"' + relativeSource + '" is not in the SourceMap.');
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the generated line and column information for the original source,
|
||
|
* line, and column positions provided. The only argument is an object with
|
||
|
* the following properties:
|
||
|
*
|
||
|
* - source: The filename of the original source.
|
||
|
* - line: The line number in the original source. The line number
|
||
|
* is 1-based.
|
||
|
* - column: The column number in the original source. The column
|
||
|
* number is 0-based.
|
||
|
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
|
||
|
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||
|
* closest element that is smaller than or greater than the one we are
|
||
|
* searching for, respectively, if the exact element cannot be found.
|
||
|
* Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
|
||
|
*
|
||
|
* and an object is returned with the following properties:
|
||
|
*
|
||
|
* - line: The line number in the generated source, or null. The
|
||
|
* line number is 1-based.
|
||
|
* - column: The column number in the generated source, or null.
|
||
|
* The column number is 0-based.
|
||
|
*/
|
||
|
BasicSourceMapConsumer.prototype.generatedPositionFor =
|
||
|
function SourceMapConsumer_generatedPositionFor(aArgs) {
|
||
|
var source = util.getArg(aArgs, 'source');
|
||
|
source = this._findSourceIndex(source);
|
||
|
if (source < 0) {
|
||
|
return {
|
||
|
line: null,
|
||
|
column: null,
|
||
|
lastColumn: null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
var needle = {
|
||
|
source: source,
|
||
|
originalLine: util.getArg(aArgs, 'line'),
|
||
|
originalColumn: util.getArg(aArgs, 'column')
|
||
|
};
|
||
|
|
||
|
var index = this._findMapping(
|
||
|
needle,
|
||
|
this._originalMappings,
|
||
|
"originalLine",
|
||
|
"originalColumn",
|
||
|
util.compareByOriginalPositions,
|
||
|
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
|
||
|
);
|
||
|
|
||
|
if (index >= 0) {
|
||
|
var mapping = this._originalMappings[index];
|
||
|
|
||
|
if (mapping.source === needle.source) {
|
||
|
return {
|
||
|
line: util.getArg(mapping, 'generatedLine', null),
|
||
|
column: util.getArg(mapping, 'generatedColumn', null),
|
||
|
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
line: null,
|
||
|
column: null,
|
||
|
lastColumn: null
|
||
|
};
|
||
|
};
|
||
|
|
||
|
exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
|
||
|
|
||
|
/**
|
||
|
* An IndexedSourceMapConsumer instance represents a parsed source map which
|
||
|
* we can query for information. It differs from BasicSourceMapConsumer in
|
||
|
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
|
||
|
* input.
|
||
|
*
|
||
|
* The first parameter is a raw source map (either as a JSON string, or already
|
||
|
* parsed to an object). According to the spec for indexed source maps, they
|
||
|
* have the following attributes:
|
||
|
*
|
||
|
* - version: Which version of the source map spec this map is following.
|
||
|
* - file: Optional. The generated file this source map is associated with.
|
||
|
* - sections: A list of section definitions.
|
||
|
*
|
||
|
* Each value under the "sections" field has two fields:
|
||
|
* - offset: The offset into the original specified at which this section
|
||
|
* begins to apply, defined as an object with a "line" and "column"
|
||
|
* field.
|
||
|
* - map: A source map definition. This source map could also be indexed,
|
||
|
* but doesn't have to be.
|
||
|
*
|
||
|
* Instead of the "map" field, it's also possible to have a "url" field
|
||
|
* specifying a URL to retrieve a source map from, but that's currently
|
||
|
* unsupported.
|
||
|
*
|
||
|
* Here's an example source map, taken from the source map spec[0], but
|
||
|
* modified to omit a section which uses the "url" field.
|
||
|
*
|
||
|
* {
|
||
|
* version : 3,
|
||
|
* file: "app.js",
|
||
|
* sections: [{
|
||
|
* offset: {line:100, column:10},
|
||
|
* map: {
|
||
|
* version : 3,
|
||
|
* file: "section.js",
|
||
|
* sources: ["foo.js", "bar.js"],
|
||
|
* names: ["src", "maps", "are", "fun"],
|
||
|
* mappings: "AAAA,E;;ABCDE;"
|
||
|
* }
|
||
|
* }],
|
||
|
* }
|
||
|
*
|
||
|
* The second parameter, if given, is a string whose value is the URL
|
||
|
* at which the source map was found. This URL is used to compute the
|
||
|
* sources array.
|
||
|
*
|
||
|
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
|
||
|
*/
|
||
|
function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
|
||
|
var sourceMap = aSourceMap;
|
||
|
if (typeof aSourceMap === 'string') {
|
||
|
sourceMap = util.parseSourceMapInput(aSourceMap);
|
||
|
}
|
||
|
|
||
|
var version = util.getArg(sourceMap, 'version');
|
||
|
var sections = util.getArg(sourceMap, 'sections');
|
||
|
|
||
|
if (version != this._version) {
|
||
|
throw new Error('Unsupported version: ' + version);
|
||
|
}
|
||
|
|
||
|
this._sources = new ArraySet();
|
||
|
this._names = new ArraySet();
|
||
|
|
||
|
var lastOffset = {
|
||
|
line: -1,
|
||
|
column: 0
|
||
|
};
|
||
|
this._sections = sections.map(function (s) {
|
||
|
if (s.url) {
|
||
|
// The url field will require support for asynchronicity.
|
||
|
// See https://github.com/mozilla/source-map/issues/16
|
||
|
throw new Error('Support for url field in sections not implemented.');
|
||
|
}
|
||
|
var offset = util.getArg(s, 'offset');
|
||
|
var offsetLine = util.getArg(offset, 'line');
|
||
|
var offsetColumn = util.getArg(offset, 'column');
|
||
|
|
||
|
if (offsetLine < lastOffset.line ||
|
||
|
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
|
||
|
throw new Error('Section offsets must be ordered and non-overlapping.');
|
||
|
}
|
||
|
lastOffset = offset;
|
||
|
|
||
|
return {
|
||
|
generatedOffset: {
|
||
|
// The offset fields are 0-based, but we use 1-based indices when
|
||
|
// encoding/decoding from VLQ.
|
||
|
generatedLine: offsetLine + 1,
|
||
|
generatedColumn: offsetColumn + 1
|
||
|
},
|
||
|
consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
|
||
|
IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
|
||
|
|
||
|
/**
|
||
|
* The version of the source mapping spec that we are consuming.
|
||
|
*/
|
||
|
IndexedSourceMapConsumer.prototype._version = 3;
|
||
|
|
||
|
/**
|
||
|
* The list of original sources.
|
||
|
*/
|
||
|
Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
|
||
|
get: function () {
|
||
|
var sources = [];
|
||
|
for (var i = 0; i < this._sections.length; i++) {
|
||
|
for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
|
||
|
sources.push(this._sections[i].consumer.sources[j]);
|
||
|
}
|
||
|
}
|
||
|
return sources;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* Returns the original source, line, and column information for the generated
|
||
|
* source's line and column positions provided. The only argument is an object
|
||
|
* with the following properties:
|
||
|
*
|
||
|
* - line: The line number in the generated source. The line number
|
||
|
* is 1-based.
|
||
|
* - column: The column number in the generated source. The column
|
||
|
* number is 0-based.
|
||
|
*
|
||
|
* and an object is returned with the following properties:
|
||
|
*
|
||
|
* - source: The original source file, or null.
|
||
|
* - line: The line number in the original source, or null. The
|
||
|
* line number is 1-based.
|
||
|
* - column: The column number in the original source, or null. The
|
||
|
* column number is 0-based.
|
||
|
* - name: The original identifier, or null.
|
||
|
*/
|
||
|
IndexedSourceMapConsumer.prototype.originalPositionFor =
|
||
|
function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
|
||
|
var needle = {
|
||
|
generatedLine: util.getArg(aArgs, 'line'),
|
||
|
generatedColumn: util.getArg(aArgs, 'column')
|
||
|
};
|
||
|
|
||
|
// Find the section containing the generated position we're trying to map
|
||
|
// to an original position.
|
||
|
var sectionIndex = binarySearch.search(needle, this._sections,
|
||
|
function(needle, section) {
|
||
|
var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
|
||
|
if (cmp) {
|
||
|
return cmp;
|
||
|
}
|
||
|
|
||
|
return (needle.generatedColumn -
|
||
|
section.generatedOffset.generatedColumn);
|
||
|
});
|
||
|
var section = this._sections[sectionIndex];
|
||
|
|
||
|
if (!section) {
|
||
|
return {
|
||
|
source: null,
|
||
|
line: null,
|
||
|
column: null,
|
||
|
name: null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return section.consumer.originalPositionFor({
|
||
|
line: needle.generatedLine -
|
||
|
(section.generatedOffset.generatedLine - 1),
|
||
|
column: needle.generatedColumn -
|
||
|
(section.generatedOffset.generatedLine === needle.generatedLine
|
||
|
? section.generatedOffset.generatedColumn - 1
|
||
|
: 0),
|
||
|
bias: aArgs.bias
|
||
|
});
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return true if we have the source content for every source in the source
|
||
|
* map, false otherwise.
|
||
|
*/
|
||
|
IndexedSourceMapConsumer.prototype.hasContentsOfAllSources =
|
||
|
function IndexedSourceMapConsumer_hasContentsOfAllSources() {
|
||
|
return this._sections.every(function (s) {
|
||
|
return s.consumer.hasContentsOfAllSources();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the original source content. The only argument is the url of the
|
||
|
* original source file. Returns null if no original source content is
|
||
|
* available.
|
||
|
*/
|
||
|
IndexedSourceMapConsumer.prototype.sourceContentFor =
|
||
|
function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
|
||
|
for (var i = 0; i < this._sections.length; i++) {
|
||
|
var section = this._sections[i];
|
||
|
|
||
|
var content = section.consumer.sourceContentFor(aSource, true);
|
||
|
if (content) {
|
||
|
return content;
|
||
|
}
|
||
|
}
|
||
|
if (nullOnMissing) {
|
||
|
return null;
|
||
|
}
|
||
|
else {
|
||
|
throw new Error('"' + aSource + '" is not in the SourceMap.');
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the generated line and column information for the original source,
|
||
|
* line, and column positions provided. The only argument is an object with
|
||
|
* the following properties:
|
||
|
*
|
||
|
* - source: The filename of the original source.
|
||
|
* - line: The line number in the original source. The line number
|
||
|
* is 1-based.
|
||
|
* - column: The column number in the original source. The column
|
||
|
* number is 0-based.
|
||
|
*
|
||
|
* and an object is returned with the following properties:
|
||
|
*
|
||
|
* - line: The line number in the generated source, or null. The
|
||
|
* line number is 1-based.
|
||
|
* - column: The column number in the generated source, or null.
|
||
|
* The column number is 0-based.
|
||
|
*/
|
||
|
IndexedSourceMapConsumer.prototype.generatedPositionFor =
|
||
|
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
|
||
|
for (var i = 0; i < this._sections.length; i++) {
|
||
|
var section = this._sections[i];
|
||
|
|
||
|
// Only consider this section if the requested source is in the list of
|
||
|
// sources of the consumer.
|
||
|
if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) {
|
||
|
continue;
|
||
|
}
|
||
|
var generatedPosition = section.consumer.generatedPositionFor(aArgs);
|
||
|
if (generatedPosition) {
|
||
|
var ret = {
|
||
|
line: generatedPosition.line +
|
||
|
(section.generatedOffset.generatedLine - 1),
|
||
|
column: generatedPosition.column +
|
||
|
(section.generatedOffset.generatedLine === generatedPosition.line
|
||
|
? section.generatedOffset.generatedColumn - 1
|
||
|
: 0)
|
||
|
};
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
line: null,
|
||
|
column: null
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parse the mappings in a string in to a data structure which we can easily
|
||
|
* query (the ordered arrays in the `this.__generatedMappings` and
|
||
|
* `this.__originalMappings` properties).
|
||
|
*/
|
||
|
IndexedSourceMapConsumer.prototype._parseMappings =
|
||
|
function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
|
||
|
this.__generatedMappings = [];
|
||
|
this.__originalMappings = [];
|
||
|
for (var i = 0; i < this._sections.length; i++) {
|
||
|
var section = this._sections[i];
|
||
|
var sectionMappings = section.consumer._generatedMappings;
|
||
|
for (var j = 0; j < sectionMappings.length; j++) {
|
||
|
var mapping = sectionMappings[j];
|
||
|
|
||
|
var source = section.consumer._sources.at(mapping.source);
|
||
|
source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
|
||
|
this._sources.add(source);
|
||
|
source = this._sources.indexOf(source);
|
||
|
|
||
|
var name = null;
|
||
|
if (mapping.name) {
|
||
|
name = section.consumer._names.at(mapping.name);
|
||
|
this._names.add(name);
|
||
|
name = this._names.indexOf(name);
|
||
|
}
|
||
|
|
||
|
// The mappings coming from the consumer for the section have
|
||
|
// generated positions relative to the start of the section, so we
|
||
|
// need to offset them to be relative to the start of the concatenated
|
||
|
// generated file.
|
||
|
var adjustedMapping = {
|
||
|
source: source,
|
||
|
generatedLine: mapping.generatedLine +
|
||
|
(section.generatedOffset.generatedLine - 1),
|
||
|
generatedColumn: mapping.generatedColumn +
|
||
|
(section.generatedOffset.generatedLine === mapping.generatedLine
|
||
|
? section.generatedOffset.generatedColumn - 1
|
||
|
: 0),
|
||
|
originalLine: mapping.originalLine,
|
||
|
originalColumn: mapping.originalColumn,
|
||
|
name: name
|
||
|
};
|
||
|
|
||
|
this.__generatedMappings.push(adjustedMapping);
|
||
|
if (typeof adjustedMapping.originalLine === 'number') {
|
||
|
this.__originalMappings.push(adjustedMapping);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
|
||
|
quickSort(this.__originalMappings, util.compareByOriginalPositions);
|
||
|
};
|
||
|
|
||
|
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 11 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
exports.GREATEST_LOWER_BOUND = 1;
|
||
|
exports.LEAST_UPPER_BOUND = 2;
|
||
|
|
||
|
/**
|
||
|
* Recursive implementation of binary search.
|
||
|
*
|
||
|
* @param aLow Indices here and lower do not contain the needle.
|
||
|
* @param aHigh Indices here and higher do not contain the needle.
|
||
|
* @param aNeedle The element being searched for.
|
||
|
* @param aHaystack The non-empty array being searched.
|
||
|
* @param aCompare Function which takes two elements and returns -1, 0, or 1.
|
||
|
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
||
|
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||
|
* closest element that is smaller than or greater than the one we are
|
||
|
* searching for, respectively, if the exact element cannot be found.
|
||
|
*/
|
||
|
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
|
||
|
// This function terminates when one of the following is true:
|
||
|
//
|
||
|
// 1. We find the exact element we are looking for.
|
||
|
//
|
||
|
// 2. We did not find the exact element, but we can return the index of
|
||
|
// the next-closest element.
|
||
|
//
|
||
|
// 3. We did not find the exact element, and there is no next-closest
|
||
|
// element than the one we are searching for, so we return -1.
|
||
|
var mid = Math.floor((aHigh - aLow) / 2) + aLow;
|
||
|
var cmp = aCompare(aNeedle, aHaystack[mid], true);
|
||
|
if (cmp === 0) {
|
||
|
// Found the element we are looking for.
|
||
|
return mid;
|
||
|
}
|
||
|
else if (cmp > 0) {
|
||
|
// Our needle is greater than aHaystack[mid].
|
||
|
if (aHigh - mid > 1) {
|
||
|
// The element is in the upper half.
|
||
|
return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
|
||
|
}
|
||
|
|
||
|
// The exact needle element was not found in this haystack. Determine if
|
||
|
// we are in termination case (3) or (2) and return the appropriate thing.
|
||
|
if (aBias == exports.LEAST_UPPER_BOUND) {
|
||
|
return aHigh < aHaystack.length ? aHigh : -1;
|
||
|
} else {
|
||
|
return mid;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// Our needle is less than aHaystack[mid].
|
||
|
if (mid - aLow > 1) {
|
||
|
// The element is in the lower half.
|
||
|
return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
|
||
|
}
|
||
|
|
||
|
// we are in termination case (3) or (2) and return the appropriate thing.
|
||
|
if (aBias == exports.LEAST_UPPER_BOUND) {
|
||
|
return mid;
|
||
|
} else {
|
||
|
return aLow < 0 ? -1 : aLow;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This is an implementation of binary search which will always try and return
|
||
|
* the index of the closest element if there is no exact hit. This is because
|
||
|
* mappings between original and generated line/col pairs are single points,
|
||
|
* and there is an implicit region between each of them, so a miss just means
|
||
|
* that you aren't on the very start of a region.
|
||
|
*
|
||
|
* @param aNeedle The element you are looking for.
|
||
|
* @param aHaystack The array that is being searched.
|
||
|
* @param aCompare A function which takes the needle and an element in the
|
||
|
* array and returns -1, 0, or 1 depending on whether the needle is less
|
||
|
* than, equal to, or greater than the element, respectively.
|
||
|
* @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
|
||
|
* 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
|
||
|
* closest element that is smaller than or greater than the one we are
|
||
|
* searching for, respectively, if the exact element cannot be found.
|
||
|
* Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
|
||
|
*/
|
||
|
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
|
||
|
if (aHaystack.length === 0) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
|
||
|
aCompare, aBias || exports.GREATEST_LOWER_BOUND);
|
||
|
if (index < 0) {
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// We have found either the exact element, or the next-closest element than
|
||
|
// the one we are searching for. However, there may be more than one such
|
||
|
// element. Make sure we always return the smallest of these.
|
||
|
while (index - 1 >= 0) {
|
||
|
if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
|
||
|
break;
|
||
|
}
|
||
|
--index;
|
||
|
}
|
||
|
|
||
|
return index;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 12 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
// It turns out that some (most?) JavaScript engines don't self-host
|
||
|
// `Array.prototype.sort`. This makes sense because C++ will likely remain
|
||
|
// faster than JS when doing raw CPU-intensive sorting. However, when using a
|
||
|
// custom comparator function, calling back and forth between the VM's C++ and
|
||
|
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
|
||
|
// worse generated code for the comparator function than would be optimal. In
|
||
|
// fact, when sorting with a comparator, these costs outweigh the benefits of
|
||
|
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
|
||
|
// a ~3500ms mean speed-up in `bench/bench.html`.
|
||
|
|
||
|
/**
|
||
|
* Swap the elements indexed by `x` and `y` in the array `ary`.
|
||
|
*
|
||
|
* @param {Array} ary
|
||
|
* The array.
|
||
|
* @param {Number} x
|
||
|
* The index of the first item.
|
||
|
* @param {Number} y
|
||
|
* The index of the second item.
|
||
|
*/
|
||
|
function swap(ary, x, y) {
|
||
|
var temp = ary[x];
|
||
|
ary[x] = ary[y];
|
||
|
ary[y] = temp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a random integer within the range `low .. high` inclusive.
|
||
|
*
|
||
|
* @param {Number} low
|
||
|
* The lower bound on the range.
|
||
|
* @param {Number} high
|
||
|
* The upper bound on the range.
|
||
|
*/
|
||
|
function randomIntInRange(low, high) {
|
||
|
return Math.round(low + (Math.random() * (high - low)));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The Quick Sort algorithm.
|
||
|
*
|
||
|
* @param {Array} ary
|
||
|
* An array to sort.
|
||
|
* @param {function} comparator
|
||
|
* Function to use to compare two items.
|
||
|
* @param {Number} p
|
||
|
* Start index of the array
|
||
|
* @param {Number} r
|
||
|
* End index of the array
|
||
|
*/
|
||
|
function doQuickSort(ary, comparator, p, r) {
|
||
|
// If our lower bound is less than our upper bound, we (1) partition the
|
||
|
// array into two pieces and (2) recurse on each half. If it is not, this is
|
||
|
// the empty array and our base case.
|
||
|
|
||
|
if (p < r) {
|
||
|
// (1) Partitioning.
|
||
|
//
|
||
|
// The partitioning chooses a pivot between `p` and `r` and moves all
|
||
|
// elements that are less than or equal to the pivot to the before it, and
|
||
|
// all the elements that are greater than it after it. The effect is that
|
||
|
// once partition is done, the pivot is in the exact place it will be when
|
||
|
// the array is put in sorted order, and it will not need to be moved
|
||
|
// again. This runs in O(n) time.
|
||
|
|
||
|
// Always choose a random pivot so that an input array which is reverse
|
||
|
// sorted does not cause O(n^2) running time.
|
||
|
var pivotIndex = randomIntInRange(p, r);
|
||
|
var i = p - 1;
|
||
|
|
||
|
swap(ary, pivotIndex, r);
|
||
|
var pivot = ary[r];
|
||
|
|
||
|
// Immediately after `j` is incremented in this loop, the following hold
|
||
|
// true:
|
||
|
//
|
||
|
// * Every element in `ary[p .. i]` is less than or equal to the pivot.
|
||
|
//
|
||
|
// * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
|
||
|
for (var j = p; j < r; j++) {
|
||
|
if (comparator(ary[j], pivot) <= 0) {
|
||
|
i += 1;
|
||
|
swap(ary, i, j);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
swap(ary, i + 1, j);
|
||
|
var q = i + 1;
|
||
|
|
||
|
// (2) Recurse on each half.
|
||
|
|
||
|
doQuickSort(ary, comparator, p, q - 1);
|
||
|
doQuickSort(ary, comparator, q + 1, r);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sort the given array in-place with the given comparator function.
|
||
|
*
|
||
|
* @param {Array} ary
|
||
|
* An array to sort.
|
||
|
* @param {function} comparator
|
||
|
* Function to use to compare two items.
|
||
|
*/
|
||
|
exports.quickSort = function (ary, comparator) {
|
||
|
doQuickSort(ary, comparator, 0, ary.length - 1);
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 13 */
|
||
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
||
|
|
||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||
|
/*
|
||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||
|
* Licensed under the New BSD license. See LICENSE or:
|
||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
var SourceMapGenerator = (__webpack_require__(4).SourceMapGenerator);
|
||
|
var util = __webpack_require__(7);
|
||
|
|
||
|
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
|
||
|
// operating systems these days (capturing the result).
|
||
|
var REGEX_NEWLINE = /(\r?\n)/;
|
||
|
|
||
|
// Newline character code for charCodeAt() comparisons
|
||
|
var NEWLINE_CODE = 10;
|
||
|
|
||
|
// Private symbol for identifying `SourceNode`s when multiple versions of
|
||
|
// the source-map library are loaded. This MUST NOT CHANGE across
|
||
|
// versions!
|
||
|
var isSourceNode = "$$$isSourceNode$$$";
|
||
|
|
||
|
/**
|
||
|
* SourceNodes provide a way to abstract over interpolating/concatenating
|
||
|
* snippets of generated JavaScript source code while maintaining the line and
|
||
|
* column information associated with the original source code.
|
||
|
*
|
||
|
* @param aLine The original line number.
|
||
|
* @param aColumn The original column number.
|
||
|
* @param aSource The original source's filename.
|
||
|
* @param aChunks Optional. An array of strings which are snippets of
|
||
|
* generated JS, or other SourceNodes.
|
||
|
* @param aName The original identifier.
|
||
|
*/
|
||
|
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
|
||
|
this.children = [];
|
||
|
this.sourceContents = {};
|
||
|
this.line = aLine == null ? null : aLine;
|
||
|
this.column = aColumn == null ? null : aColumn;
|
||
|
this.source = aSource == null ? null : aSource;
|
||
|
this.name = aName == null ? null : aName;
|
||
|
this[isSourceNode] = true;
|
||
|
if (aChunks != null) this.add(aChunks);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates a SourceNode from generated code and a SourceMapConsumer.
|
||
|
*
|
||
|
* @param aGeneratedCode The generated code
|
||
|
* @param aSourceMapConsumer The SourceMap for the generated code
|
||
|
* @param aRelativePath Optional. The path that relative sources in the
|
||
|
* SourceMapConsumer should be relative to.
|
||
|
*/
|
||
|
SourceNode.fromStringWithSourceMap =
|
||
|
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
|
||
|
// The SourceNode we want to fill with the generated code
|
||
|
// and the SourceMap
|
||
|
var node = new SourceNode();
|
||
|
|
||
|
// All even indices of this array are one line of the generated code,
|
||
|
// while all odd indices are the newlines between two adjacent lines
|
||
|
// (since `REGEX_NEWLINE` captures its match).
|
||
|
// Processed fragments are accessed by calling `shiftNextLine`.
|
||
|
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
|
||
|
var remainingLinesIndex = 0;
|
||
|
var shiftNextLine = function() {
|
||
|
var lineContents = getNextLine();
|
||
|
// The last line of a file might not have a newline.
|
||
|
var newLine = getNextLine() || "";
|
||
|
return lineContents + newLine;
|
||
|
|
||
|
function getNextLine() {
|
||
|
return remainingLinesIndex < remainingLines.length ?
|
||
|
remainingLines[remainingLinesIndex++] : undefined;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// We need to remember the position of "remainingLines"
|
||
|
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
|
||
|
|
||
|
// The generate SourceNodes we need a code range.
|
||
|
// To extract it current and last mapping is used.
|
||
|
// Here we store the last mapping.
|
||
|
var lastMapping = null;
|
||
|
|
||
|
aSourceMapConsumer.eachMapping(function (mapping) {
|
||
|
if (lastMapping !== null) {
|
||
|
// We add the code from "lastMapping" to "mapping":
|
||
|
// First check if there is a new line in between.
|
||
|
if (lastGeneratedLine < mapping.generatedLine) {
|
||
|
// Associate first line with "lastMapping"
|
||
|
addMappingWithCode(lastMapping, shiftNextLine());
|
||
|
lastGeneratedLine++;
|
||
|
lastGeneratedColumn = 0;
|
||
|
// The remaining code is added without mapping
|
||
|
} else {
|
||
|
// There is no new line in between.
|
||
|
// Associate the code between "lastGeneratedColumn" and
|
||
|
// "mapping.generatedColumn" with "lastMapping"
|
||
|
var nextLine = remainingLines[remainingLinesIndex] || '';
|
||
|
var code = nextLine.substr(0, mapping.generatedColumn -
|
||
|
lastGeneratedColumn);
|
||
|
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
|
||
|
lastGeneratedColumn);
|
||
|
lastGeneratedColumn = mapping.generatedColumn;
|
||
|
addMappingWithCode(lastMapping, code);
|
||
|
// No more remaining code, continue
|
||
|
lastMapping = mapping;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
// We add the generated code until the first mapping
|
||
|
// to the SourceNode without any mapping.
|
||
|
// Each line is added as separate string.
|
||
|
while (lastGeneratedLine < mapping.generatedLine) {
|
||
|
node.add(shiftNextLine());
|
||
|
lastGeneratedLine++;
|
||
|
}
|
||
|
if (lastGeneratedColumn < mapping.generatedColumn) {
|
||
|
var nextLine = remainingLines[remainingLinesIndex] || '';
|
||
|
node.add(nextLine.substr(0, mapping.generatedColumn));
|
||
|
remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
|
||
|
lastGeneratedColumn = mapping.generatedColumn;
|
||
|
}
|
||
|
lastMapping = mapping;
|
||
|
}, this);
|
||
|
// We have processed all mappings.
|
||
|
if (remainingLinesIndex < remainingLines.length) {
|
||
|
if (lastMapping) {
|
||
|
// Associate the remaining code in the current line with "lastMapping"
|
||
|
addMappingWithCode(lastMapping, shiftNextLine());
|
||
|
}
|
||
|
// and add the remaining lines without any mapping
|
||
|
node.add(remainingLines.splice(remainingLinesIndex).join(""));
|
||
|
}
|
||
|
|
||
|
// Copy sourcesContent into SourceNode
|
||
|
aSourceMapConsumer.sources.forEach(function (sourceFile) {
|
||
|
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
|
||
|
if (content != null) {
|
||
|
if (aRelativePath != null) {
|
||
|
sourceFile = util.join(aRelativePath, sourceFile);
|
||
|
}
|
||
|
node.setSourceContent(sourceFile, content);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return node;
|
||
|
|
||
|
function addMappingWithCode(mapping, code) {
|
||
|
if (mapping === null || mapping.source === undefined) {
|
||
|
node.add(code);
|
||
|
} else {
|
||
|
var source = aRelativePath
|
||
|
? util.join(aRelativePath, mapping.source)
|
||
|
: mapping.source;
|
||
|
node.add(new SourceNode(mapping.originalLine,
|
||
|
mapping.originalColumn,
|
||
|
source,
|
||
|
code,
|
||
|
mapping.name));
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Add a chunk of generated JS to this source node.
|
||
|
*
|
||
|
* @param aChunk A string snippet of generated JS code, another instance of
|
||
|
* SourceNode, or an array where each member is one of those things.
|
||
|
*/
|
||
|
SourceNode.prototype.add = function SourceNode_add(aChunk) {
|
||
|
if (Array.isArray(aChunk)) {
|
||
|
aChunk.forEach(function (chunk) {
|
||
|
this.add(chunk);
|
||
|
}, this);
|
||
|
}
|
||
|
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
||
|
if (aChunk) {
|
||
|
this.children.push(aChunk);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
throw new TypeError(
|
||
|
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
||
|
);
|
||
|
}
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Add a chunk of generated JS to the beginning of this source node.
|
||
|
*
|
||
|
* @param aChunk A string snippet of generated JS code, another instance of
|
||
|
* SourceNode, or an array where each member is one of those things.
|
||
|
*/
|
||
|
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
|
||
|
if (Array.isArray(aChunk)) {
|
||
|
for (var i = aChunk.length-1; i >= 0; i--) {
|
||
|
this.prepend(aChunk[i]);
|
||
|
}
|
||
|
}
|
||
|
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
|
||
|
this.children.unshift(aChunk);
|
||
|
}
|
||
|
else {
|
||
|
throw new TypeError(
|
||
|
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
|
||
|
);
|
||
|
}
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Walk over the tree of JS snippets in this node and its children. The
|
||
|
* walking function is called once for each snippet of JS and is passed that
|
||
|
* snippet and the its original associated source's line/column location.
|
||
|
*
|
||
|
* @param aFn The traversal function.
|
||
|
*/
|
||
|
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
|
||
|
var chunk;
|
||
|
for (var i = 0, len = this.children.length; i < len; i++) {
|
||
|
chunk = this.children[i];
|
||
|
if (chunk[isSourceNode]) {
|
||
|
chunk.walk(aFn);
|
||
|
}
|
||
|
else {
|
||
|
if (chunk !== '') {
|
||
|
aFn(chunk, { source: this.source,
|
||
|
line: this.line,
|
||
|
column: this.column,
|
||
|
name: this.name });
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
|
||
|
* each of `this.children`.
|
||
|
*
|
||
|
* @param aSep The separator.
|
||
|
*/
|
||
|
SourceNode.prototype.join = function SourceNode_join(aSep) {
|
||
|
var newChildren;
|
||
|
var i;
|
||
|
var len = this.children.length;
|
||
|
if (len > 0) {
|
||
|
newChildren = [];
|
||
|
for (i = 0; i < len-1; i++) {
|
||
|
newChildren.push(this.children[i]);
|
||
|
newChildren.push(aSep);
|
||
|
}
|
||
|
newChildren.push(this.children[i]);
|
||
|
this.children = newChildren;
|
||
|
}
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Call String.prototype.replace on the very right-most source snippet. Useful
|
||
|
* for trimming whitespace from the end of a source node, etc.
|
||
|
*
|
||
|
* @param aPattern The pattern to replace.
|
||
|
* @param aReplacement The thing to replace the pattern with.
|
||
|
*/
|
||
|
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
|
||
|
var lastChild = this.children[this.children.length - 1];
|
||
|
if (lastChild[isSourceNode]) {
|
||
|
lastChild.replaceRight(aPattern, aReplacement);
|
||
|
}
|
||
|
else if (typeof lastChild === 'string') {
|
||
|
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
|
||
|
}
|
||
|
else {
|
||
|
this.children.push(''.replace(aPattern, aReplacement));
|
||
|
}
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Set the source content for a source file. This will be added to the SourceMapGenerator
|
||
|
* in the sourcesContent field.
|
||
|
*
|
||
|
* @param aSourceFile The filename of the source file
|
||
|
* @param aSourceContent The content of the source file
|
||
|
*/
|
||
|
SourceNode.prototype.setSourceContent =
|
||
|
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
|
||
|
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Walk over the tree of SourceNodes. The walking function is called for each
|
||
|
* source file content and is passed the filename and source content.
|
||
|
*
|
||
|
* @param aFn The traversal function.
|
||
|
*/
|
||
|
SourceNode.prototype.walkSourceContents =
|
||
|
function SourceNode_walkSourceContents(aFn) {
|
||
|
for (var i = 0, len = this.children.length; i < len; i++) {
|
||
|
if (this.children[i][isSourceNode]) {
|
||
|
this.children[i].walkSourceContents(aFn);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var sources = Object.keys(this.sourceContents);
|
||
|
for (var i = 0, len = sources.length; i < len; i++) {
|
||
|
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Return the string representation of this source node. Walks over the tree
|
||
|
* and concatenates all the various snippets together to one string.
|
||
|
*/
|
||
|
SourceNode.prototype.toString = function SourceNode_toString() {
|
||
|
var str = "";
|
||
|
this.walk(function (chunk) {
|
||
|
str += chunk;
|
||
|
});
|
||
|
return str;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Returns the string representation of this source node along with a source
|
||
|
* map.
|
||
|
*/
|
||
|
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
|
||
|
var generated = {
|
||
|
code: "",
|
||
|
line: 1,
|
||
|
column: 0
|
||
|
};
|
||
|
var map = new SourceMapGenerator(aArgs);
|
||
|
var sourceMappingActive = false;
|
||
|
var lastOriginalSource = null;
|
||
|
var lastOriginalLine = null;
|
||
|
var lastOriginalColumn = null;
|
||
|
var lastOriginalName = null;
|
||
|
this.walk(function (chunk, original) {
|
||
|
generated.code += chunk;
|
||
|
if (original.source !== null
|
||
|
&& original.line !== null
|
||
|
&& original.column !== null) {
|
||
|
if(lastOriginalSource !== original.source
|
||
|
|| lastOriginalLine !== original.line
|
||
|
|| lastOriginalColumn !== original.column
|
||
|
|| lastOriginalName !== original.name) {
|
||
|
map.addMapping({
|
||
|
source: original.source,
|
||
|
original: {
|
||
|
line: original.line,
|
||
|
column: original.column
|
||
|
},
|
||
|
generated: {
|
||
|
line: generated.line,
|
||
|
column: generated.column
|
||
|
},
|
||
|
name: original.name
|
||
|
});
|
||
|
}
|
||
|
lastOriginalSource = original.source;
|
||
|
lastOriginalLine = original.line;
|
||
|
lastOriginalColumn = original.column;
|
||
|
lastOriginalName = original.name;
|
||
|
sourceMappingActive = true;
|
||
|
} else if (sourceMappingActive) {
|
||
|
map.addMapping({
|
||
|
generated: {
|
||
|
line: generated.line,
|
||
|
column: generated.column
|
||
|
}
|
||
|
});
|
||
|
lastOriginalSource = null;
|
||
|
sourceMappingActive = false;
|
||
|
}
|
||
|
for (var idx = 0, length = chunk.length; idx < length; idx++) {
|
||
|
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
|
||
|
generated.line++;
|
||
|
generated.column = 0;
|
||
|
// Mappings end at eol
|
||
|
if (idx + 1 === length) {
|
||
|
lastOriginalSource = null;
|
||
|
sourceMappingActive = false;
|
||
|
} else if (sourceMappingActive) {
|
||
|
map.addMapping({
|
||
|
source: original.source,
|
||
|
original: {
|
||
|
line: original.line,
|
||
|
column: original.column
|
||
|
},
|
||
|
generated: {
|
||
|
line: generated.line,
|
||
|
column: generated.column
|
||
|
},
|
||
|
name: original.name
|
||
|
});
|
||
|
}
|
||
|
} else {
|
||
|
generated.column++;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
this.walkSourceContents(function (sourceFile, sourceContent) {
|
||
|
map.setSourceContent(sourceFile, sourceContent);
|
||
|
});
|
||
|
|
||
|
return { code: generated.code, map: map };
|
||
|
};
|
||
|
|
||
|
exports.SourceNode = SourceNode;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 14 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("path");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 15 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("fs");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 16 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
/* eslint-disable node/no-deprecated-api */
|
||
|
|
||
|
var toString = Object.prototype.toString
|
||
|
|
||
|
var isModern = (
|
||
|
typeof Buffer !== 'undefined' &&
|
||
|
typeof Buffer.alloc === 'function' &&
|
||
|
typeof Buffer.allocUnsafe === 'function' &&
|
||
|
typeof Buffer.from === 'function'
|
||
|
)
|
||
|
|
||
|
function isArrayBuffer (input) {
|
||
|
return toString.call(input).slice(8, -1) === 'ArrayBuffer'
|
||
|
}
|
||
|
|
||
|
function fromArrayBuffer (obj, byteOffset, length) {
|
||
|
byteOffset >>>= 0
|
||
|
|
||
|
var maxLength = obj.byteLength - byteOffset
|
||
|
|
||
|
if (maxLength < 0) {
|
||
|
throw new RangeError("'offset' is out of bounds")
|
||
|
}
|
||
|
|
||
|
if (length === undefined) {
|
||
|
length = maxLength
|
||
|
} else {
|
||
|
length >>>= 0
|
||
|
|
||
|
if (length > maxLength) {
|
||
|
throw new RangeError("'length' is out of bounds")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return isModern
|
||
|
? Buffer.from(obj.slice(byteOffset, byteOffset + length))
|
||
|
: new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length)))
|
||
|
}
|
||
|
|
||
|
function fromString (string, encoding) {
|
||
|
if (typeof encoding !== 'string' || encoding === '') {
|
||
|
encoding = 'utf8'
|
||
|
}
|
||
|
|
||
|
if (!Buffer.isEncoding(encoding)) {
|
||
|
throw new TypeError('"encoding" must be a valid string encoding')
|
||
|
}
|
||
|
|
||
|
return isModern
|
||
|
? Buffer.from(string, encoding)
|
||
|
: new Buffer(string, encoding)
|
||
|
}
|
||
|
|
||
|
function bufferFrom (value, encodingOrOffset, length) {
|
||
|
if (typeof value === 'number') {
|
||
|
throw new TypeError('"value" argument must not be a number')
|
||
|
}
|
||
|
|
||
|
if (isArrayBuffer(value)) {
|
||
|
return fromArrayBuffer(value, encodingOrOffset, length)
|
||
|
}
|
||
|
|
||
|
if (typeof value === 'string') {
|
||
|
return fromString(value, encodingOrOffset)
|
||
|
}
|
||
|
|
||
|
return isModern
|
||
|
? Buffer.from(value)
|
||
|
: new Buffer(value)
|
||
|
}
|
||
|
|
||
|
module.exports = bufferFrom
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 17 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("electron");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 18 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const path = __webpack_require__(14);
|
||
|
const {app, BrowserWindow, shell, dialog} = __webpack_require__(17);
|
||
|
const unusedFilename = __webpack_require__(19);
|
||
|
const pupa = __webpack_require__(23);
|
||
|
const extName = __webpack_require__(25);
|
||
|
|
||
|
const getFilenameFromMime = (name, mime) => {
|
||
|
const extensions = extName.mime(mime);
|
||
|
|
||
|
if (extensions.length !== 1) {
|
||
|
return name;
|
||
|
}
|
||
|
|
||
|
return `${name}.${extensions[0].ext}`;
|
||
|
};
|
||
|
|
||
|
const majorElectronVersion = () => {
|
||
|
const version = process.versions.electron.split('.');
|
||
|
return Number.parseInt(version[0], 10);
|
||
|
};
|
||
|
|
||
|
const getWindowFromBrowserView = webContents => {
|
||
|
for (const currentWindow of BrowserWindow.getAllWindows()) {
|
||
|
for (const currentBrowserView of currentWindow.getBrowserViews()) {
|
||
|
if (currentBrowserView.webContents.id === webContents.id) {
|
||
|
return currentWindow;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const getWindowFromWebContents = webContents => {
|
||
|
let window_;
|
||
|
const webContentsType = webContents.getType();
|
||
|
switch (webContentsType) {
|
||
|
case 'webview':
|
||
|
window_ = BrowserWindow.fromWebContents(webContents.hostWebContents);
|
||
|
break;
|
||
|
case 'browserView':
|
||
|
window_ = getWindowFromBrowserView(webContents);
|
||
|
break;
|
||
|
default:
|
||
|
window_ = BrowserWindow.fromWebContents(webContents);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return window_;
|
||
|
};
|
||
|
|
||
|
function registerListener(session, options, callback = () => {}) {
|
||
|
const downloadItems = new Set();
|
||
|
let receivedBytes = 0;
|
||
|
let completedBytes = 0;
|
||
|
let totalBytes = 0;
|
||
|
const activeDownloadItems = () => downloadItems.size;
|
||
|
const progressDownloadItems = () => receivedBytes / totalBytes;
|
||
|
|
||
|
options = {
|
||
|
showBadge: true,
|
||
|
showProgressBar: true,
|
||
|
...options
|
||
|
};
|
||
|
|
||
|
const listener = (event, item, webContents) => {
|
||
|
downloadItems.add(item);
|
||
|
totalBytes += item.getTotalBytes();
|
||
|
|
||
|
const window_ = majorElectronVersion() >= 12 ? BrowserWindow.fromWebContents(webContents) : getWindowFromWebContents(webContents);
|
||
|
|
||
|
if (options.directory && !path.isAbsolute(options.directory)) {
|
||
|
throw new Error('The `directory` option must be an absolute path');
|
||
|
}
|
||
|
|
||
|
const directory = options.directory || app.getPath('downloads');
|
||
|
|
||
|
let filePath;
|
||
|
if (options.filename) {
|
||
|
filePath = path.join(directory, options.filename);
|
||
|
} else {
|
||
|
const filename = item.getFilename();
|
||
|
const name = path.extname(filename) ? filename : getFilenameFromMime(filename, item.getMimeType());
|
||
|
|
||
|
filePath = options.overwrite ? path.join(directory, name) : unusedFilename.sync(path.join(directory, name));
|
||
|
}
|
||
|
|
||
|
const errorMessage = options.errorMessage || 'The download of {filename} was interrupted';
|
||
|
|
||
|
if (options.saveAs) {
|
||
|
item.setSaveDialogOptions({defaultPath: filePath});
|
||
|
} else {
|
||
|
item.setSavePath(filePath);
|
||
|
}
|
||
|
|
||
|
if (typeof options.onStarted === 'function') {
|
||
|
options.onStarted(item);
|
||
|
}
|
||
|
|
||
|
item.on('updated', () => {
|
||
|
receivedBytes = completedBytes;
|
||
|
for (const item of downloadItems) {
|
||
|
receivedBytes += item.getReceivedBytes();
|
||
|
}
|
||
|
|
||
|
if (options.showBadge && ['darwin', 'linux'].includes(process.platform)) {
|
||
|
app.badgeCount = activeDownloadItems();
|
||
|
}
|
||
|
|
||
|
if (!window_.isDestroyed() && options.showProgressBar) {
|
||
|
window_.setProgressBar(progressDownloadItems());
|
||
|
}
|
||
|
|
||
|
if (typeof options.onProgress === 'function') {
|
||
|
const itemTransferredBytes = item.getReceivedBytes();
|
||
|
const itemTotalBytes = item.getTotalBytes();
|
||
|
|
||
|
options.onProgress({
|
||
|
percent: itemTotalBytes ? itemTransferredBytes / itemTotalBytes : 0,
|
||
|
transferredBytes: itemTransferredBytes,
|
||
|
totalBytes: itemTotalBytes
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (typeof options.onTotalProgress === 'function') {
|
||
|
options.onTotalProgress({
|
||
|
percent: progressDownloadItems(),
|
||
|
transferredBytes: receivedBytes,
|
||
|
totalBytes
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
item.on('done', (event, state) => {
|
||
|
completedBytes += item.getTotalBytes();
|
||
|
downloadItems.delete(item);
|
||
|
|
||
|
if (options.showBadge && ['darwin', 'linux'].includes(process.platform)) {
|
||
|
app.badgeCount = activeDownloadItems();
|
||
|
}
|
||
|
|
||
|
if (!window_.isDestroyed() && !activeDownloadItems()) {
|
||
|
window_.setProgressBar(-1);
|
||
|
receivedBytes = 0;
|
||
|
completedBytes = 0;
|
||
|
totalBytes = 0;
|
||
|
}
|
||
|
|
||
|
if (options.unregisterWhenDone) {
|
||
|
session.removeListener('will-download', listener);
|
||
|
}
|
||
|
|
||
|
// eslint-disable-next-line unicorn/prefer-switch
|
||
|
if (state === 'cancelled') {
|
||
|
if (typeof options.onCancel === 'function') {
|
||
|
options.onCancel(item);
|
||
|
}
|
||
|
} else if (state === 'interrupted') {
|
||
|
const message = pupa(errorMessage, {filename: path.basename(filePath)});
|
||
|
callback(new Error(message));
|
||
|
} else if (state === 'completed') {
|
||
|
const savePath = item.getSavePath();
|
||
|
|
||
|
if (process.platform === 'darwin') {
|
||
|
app.dock.downloadFinished(savePath);
|
||
|
}
|
||
|
|
||
|
if (options.openFolderWhenDone) {
|
||
|
shell.showItemInFolder(savePath);
|
||
|
}
|
||
|
|
||
|
if (typeof options.onCompleted === 'function') {
|
||
|
options.onCompleted({
|
||
|
fileName: item.getFilename(), // Just for backwards compatibility. TODO: Remove in the next major version.
|
||
|
filename: item.getFilename(),
|
||
|
path: savePath,
|
||
|
fileSize: item.getReceivedBytes(),
|
||
|
mimeType: item.getMimeType(),
|
||
|
url: item.getURL()
|
||
|
});
|
||
|
}
|
||
|
|
||
|
callback(null, item);
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
|
||
|
session.on('will-download', listener);
|
||
|
}
|
||
|
|
||
|
module.exports = (options = {}) => {
|
||
|
app.on('session-created', session => {
|
||
|
registerListener(session, options, (error, _) => {
|
||
|
if (error) {
|
||
|
const errorTitle = options.errorTitle || 'Download Error';
|
||
|
dialog.showErrorBox(errorTitle, error.message);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
|
||
|
module.exports.download = (window_, url, options) => new Promise((resolve, reject) => {
|
||
|
options = {
|
||
|
...options,
|
||
|
unregisterWhenDone: true
|
||
|
};
|
||
|
|
||
|
registerListener(window_.webContents.session, options, (error, item) => {
|
||
|
if (error) {
|
||
|
reject(error);
|
||
|
} else {
|
||
|
resolve(item);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
window_.webContents.downloadURL(url);
|
||
|
});
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 19 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const pathExists = __webpack_require__(20);
|
||
|
const modifyFilename = __webpack_require__(22);
|
||
|
|
||
|
const incrementer = filePath => {
|
||
|
let counter = 0;
|
||
|
return () => modifyFilename(filePath, (filename, extension) => `${filename} (${++counter})${extension}`);
|
||
|
};
|
||
|
|
||
|
const unusedFilename = filePath => {
|
||
|
const getFilePath = incrementer(filePath);
|
||
|
const find = async newFilePath => await pathExists(newFilePath) ? find(getFilePath()) : newFilePath;
|
||
|
return find(filePath);
|
||
|
};
|
||
|
|
||
|
module.exports = unusedFilename;
|
||
|
// TODO: Remove this for the next major release
|
||
|
module.exports["default"] = unusedFilename;
|
||
|
|
||
|
module.exports.sync = filePath => {
|
||
|
const getFilePath = incrementer(filePath);
|
||
|
const find = newFilePath => pathExists.sync(newFilePath) ? find(getFilePath()) : newFilePath;
|
||
|
return find(filePath);
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 20 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const fs = __webpack_require__(15);
|
||
|
const {promisify} = __webpack_require__(21);
|
||
|
|
||
|
const pAccess = promisify(fs.access);
|
||
|
|
||
|
module.exports = async path => {
|
||
|
try {
|
||
|
await pAccess(path);
|
||
|
return true;
|
||
|
} catch (_) {
|
||
|
return false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
module.exports.sync = path => {
|
||
|
try {
|
||
|
fs.accessSync(path);
|
||
|
return true;
|
||
|
} catch (_) {
|
||
|
return false;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 21 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("util");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 22 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var path = __webpack_require__(14);
|
||
|
|
||
|
module.exports = function modifyFilename(pth, modifier) {
|
||
|
if (arguments.length !== 2) {
|
||
|
throw new Error('`path` and `modifier` required');
|
||
|
}
|
||
|
|
||
|
if (Array.isArray(pth)) {
|
||
|
return pth.map(function (el) {
|
||
|
return modifyFilename(el, modifier);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var ext = path.extname(pth);
|
||
|
return path.join(path.dirname(pth), modifier(path.basename(pth, ext), ext));
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 23 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const {htmlEscape} = __webpack_require__(24);
|
||
|
|
||
|
module.exports = (template, data) => {
|
||
|
if (typeof template !== 'string') {
|
||
|
throw new TypeError(`Expected a \`string\` in the first argument, got \`${typeof template}\``);
|
||
|
}
|
||
|
|
||
|
if (typeof data !== 'object') {
|
||
|
throw new TypeError(`Expected an \`object\` or \`Array\` in the second argument, got \`${typeof data}\``);
|
||
|
}
|
||
|
|
||
|
// The regex tries to match either a number inside `{{ }}` or a valid JS identifier or key path.
|
||
|
const doubleBraceRegex = /{{(\d+|[a-z$_][a-z\d$_]*?(?:\.[a-z\d$_]*?)*?)}}/gi;
|
||
|
|
||
|
if (doubleBraceRegex.test(template)) {
|
||
|
template = template.replace(doubleBraceRegex, (_, key) => {
|
||
|
let result = data;
|
||
|
|
||
|
for (const property of key.split('.')) {
|
||
|
result = result ? result[property] : '';
|
||
|
}
|
||
|
|
||
|
return htmlEscape(String(result));
|
||
|
});
|
||
|
}
|
||
|
|
||
|
const braceRegex = /{(\d+|[a-z$_][a-z\d$_]*?(?:\.[a-z\d$_]*?)*?)}/gi;
|
||
|
|
||
|
return template.replace(braceRegex, (_, key) => {
|
||
|
let result = data;
|
||
|
|
||
|
for (const property of key.split('.')) {
|
||
|
result = result ? result[property] : '';
|
||
|
}
|
||
|
|
||
|
return String(result);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 24 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
exports.htmlEscape = string => string
|
||
|
.replace(/&/g, '&')
|
||
|
.replace(/"/g, '"')
|
||
|
.replace(/'/g, ''')
|
||
|
.replace(/</g, '<')
|
||
|
.replace(/>/g, '>');
|
||
|
|
||
|
exports.htmlUnescape = htmlString => htmlString
|
||
|
.replace(/>/g, '>')
|
||
|
.replace(/</g, '<')
|
||
|
.replace(/�?39;/g, '\'')
|
||
|
.replace(/"/g, '"')
|
||
|
.replace(/&/g, '&');
|
||
|
|
||
|
exports.htmlEscapeTag = (strings, ...values) => {
|
||
|
let output = strings[0];
|
||
|
for (let i = 0; i < values.length; i++) {
|
||
|
output = output + exports.htmlEscape(String(values[i])) + strings[i + 1];
|
||
|
}
|
||
|
|
||
|
return output;
|
||
|
};
|
||
|
|
||
|
exports.htmlUnescapeTag = (strings, ...values) => {
|
||
|
let output = strings[0];
|
||
|
for (let i = 0; i < values.length; i++) {
|
||
|
output = output + exports.htmlUnescape(String(values[i])) + strings[i + 1];
|
||
|
}
|
||
|
|
||
|
return output;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 25 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const extList = __webpack_require__(26);
|
||
|
const sortKeysLength = __webpack_require__(29);
|
||
|
|
||
|
module.exports = str => {
|
||
|
const obj = sortKeysLength.desc(extList());
|
||
|
const exts = Object.keys(obj).filter(x => str.endsWith(x));
|
||
|
|
||
|
if (exts.length === 0) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
return exts.map(x => ({
|
||
|
ext: x,
|
||
|
mime: obj[x]
|
||
|
}));
|
||
|
};
|
||
|
|
||
|
module.exports.mime = str => {
|
||
|
const obj = sortKeysLength.desc(extList());
|
||
|
const exts = Object.keys(obj).filter(x => obj[x] === str);
|
||
|
|
||
|
if (exts.length === 0) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
return exts.map(x => ({
|
||
|
ext: x,
|
||
|
mime: obj[x]
|
||
|
}));
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 26 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var mimeDb = __webpack_require__(27);
|
||
|
|
||
|
module.exports = function () {
|
||
|
var ret = {};
|
||
|
|
||
|
Object.keys(mimeDb).forEach(function (x) {
|
||
|
var val = mimeDb[x];
|
||
|
|
||
|
if (val.extensions && val.extensions.length > 0) {
|
||
|
val.extensions.forEach(function (y) {
|
||
|
ret[y] = x;
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return ret;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 27 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
/*!
|
||
|
* mime-db
|
||
|
* Copyright(c) 2014 Jonathan Ong
|
||
|
* Copyright(c) 2015-2022 Douglas Christopher Wilson
|
||
|
* MIT Licensed
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Module exports.
|
||
|
*/
|
||
|
|
||
|
module.exports = __webpack_require__(28)
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 28 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = JSON.parse('{"application/1d-interleaved-parityfec":{"source":"iana"},"application/3gpdash-qoe-report+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/3gpp-ims+xml":{"source":"iana","compressible":true},"application/3gpphal+json":{"source":"iana","compressible":true},"application/3gpphalforms+json":{"source":"iana","compressible":true},"application/a2l":{"source":"iana"},"application/ace+cbor":{"source":"iana"},"application/activemessage":{"source":"iana"},"application/activity+json":{"source":"iana","compressible":true},"application/alto-costmap+json":{"source":"iana","compressible":true},"application/alto-costmapfilter+json":{"source":"iana","compressible":true},"application/alto-directory+json":{"source":"iana","compressible":true},"application/alto-endpointcost+json":{"source":"iana","compressible":true},"application/alto-endpointcostparams+json":{"source":"iana","compressible":true},"application/alto-endpointprop+json":{"source":"iana","compressible":true},"application/alto-endpointpropparams+json":{"source":"iana","compressible":true},"application/alto-error+json":{"source":"iana","compressible":true},"application/alto-networkmap+json":{"source":"iana","compressible":true},"application/alto-networkmapfilter+json":{"source":"iana","compressible":true},"application/alto-updatestreamcontrol+json":{"source":"iana","compressible":true},"application/alto-updatestreamparams+json":{"source":"iana","compressible":true},"application/aml":{"source":"iana"},"application/andrew-inset":{"source":"iana","extensions":["ez"]},"application/applefile":{"source":"iana"},"application/applixware":{"source":"apache","extensions":["aw"]},"application/at+jwt":{"source":"iana"},"application/atf":{"source":"iana"},"application/atfx":{"source":"iana"},"application/atom+xml":{"source":"iana","compressible":true,"extensions":["atom"]},"application/atomcat+xml":{"source":"iana","compressible":true,"extensions":["atomcat"]},"application/atomdeleted+xml":{"source":"iana","compressible":true,"extensions":["atomdeleted"]},"application/atomicmail":{"source":"iana"},"application/atomsvc+xml":{"source":"iana","compressible":true,"extensions":["atomsvc"]},"application/atsc-dwd+xml":{"source":"iana","compressible":true,"extensions":["dwd"]},"application/atsc-dynamic-event-message":{"source":"iana"},"application/atsc-held+xml":{"source":"iana","compressible":true,"extensions":["held"]},"application/atsc-rdt+json":{"source":"iana","compressible":true},"application/atsc-rsat+xml":{"source":"iana","compressible":true,"extensions":["rsat"]},"application/atxml":{"source":"iana"},"application/auth-policy+xml":{"source":"iana","compressible":true},"application/bacnet-xdd+zip":{"source":"iana","compressible":false},"application/batch-smtp":{"source":"iana"},"application/bdoc":{"compressible":false,"extensions":["bdoc"]},"application/beep+xml":{"source":"iana","charset":"UTF-8","compressible":true},"application/calendar+json":{"source":"iana","compressible":true},"application/calendar+xml":{"source":"iana","compressible":true,"extensions":["xcs"]},"application/call-completion":{"source":"iana"},"application/cals-1840":{"source":"iana"},"application/captive+json":{"source":"iana","compressible":true},"application/cbor":{"source":"iana"},"application/cbor-seq":{"source":"iana"},"application/cccex":{"source":"iana"},"application/ccmp+xml":{"source":"iana","compressible":true},"application/ccxml+xml":{"source":"iana","compressible":true,"extensions":["ccxml"]},"application/cdfx+xml":{"source":"iana","compressible":true,"extensions":["cdfx"]},"application/cdmi-capability":{"source":"iana","extensions":["cdmia"]},"application/cdmi-container":{"source":"iana","extensions":["cdmic"]},"application/cdmi-domain":{"source":"iana","extensions":["cdmid"]},"application/cdmi-object":{"source":"iana","extensions":["cdmio"]},"application/cdmi-queue":{"source":"iana","extensions":["cdmiq"]},"application/cdni":{"source":"iana"},"application/cea":{"source":"iana"},"application/cea-2018+xml":{"source":"iana","compressible":true},"application/c
|
||
|
|
||
|
/***/ }),
|
||
|
/* 29 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
var sortKeys = __webpack_require__(30);
|
||
|
|
||
|
/**
|
||
|
* Sort object keys by length
|
||
|
*
|
||
|
* @param obj
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
module.exports.desc = function (obj) {
|
||
|
return sortKeys(obj, function (a, b) {
|
||
|
return b.length - a.length;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
module.exports.asc = function (obj) {
|
||
|
return sortKeys(obj, function (a, b) {
|
||
|
return a.length - b.length;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 30 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var isPlainObj = __webpack_require__(31);
|
||
|
|
||
|
module.exports = function (obj, opts) {
|
||
|
if (!isPlainObj(obj)) {
|
||
|
throw new TypeError('Expected a plain object');
|
||
|
}
|
||
|
|
||
|
opts = opts || {};
|
||
|
|
||
|
// DEPRECATED
|
||
|
if (typeof opts === 'function') {
|
||
|
opts = {compare: opts};
|
||
|
}
|
||
|
|
||
|
var deep = opts.deep;
|
||
|
var seenInput = [];
|
||
|
var seenOutput = [];
|
||
|
|
||
|
var sortKeys = function (x) {
|
||
|
var seenIndex = seenInput.indexOf(x);
|
||
|
|
||
|
if (seenIndex !== -1) {
|
||
|
return seenOutput[seenIndex];
|
||
|
}
|
||
|
|
||
|
var ret = {};
|
||
|
var keys = Object.keys(x).sort(opts.compare);
|
||
|
|
||
|
seenInput.push(x);
|
||
|
seenOutput.push(ret);
|
||
|
|
||
|
for (var i = 0; i < keys.length; i++) {
|
||
|
var key = keys[i];
|
||
|
var val = x[key];
|
||
|
|
||
|
ret[key] = deep && isPlainObj(val) ? sortKeys(val) : val;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
};
|
||
|
|
||
|
return sortKeys(obj);
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 31 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var toString = Object.prototype.toString;
|
||
|
|
||
|
module.exports = function (x) {
|
||
|
var prototype;
|
||
|
return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({}));
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 32 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.createLoginWindow = void 0;
|
||
|
const path = __importStar(__webpack_require__(14));
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
async function createLoginWindow(loginCallback, parent) {
|
||
|
log.debug('createLoginWindow', { loginCallback, parent });
|
||
|
const loginWindow = new electron_1.BrowserWindow({
|
||
|
parent,
|
||
|
width: 300,
|
||
|
height: 400,
|
||
|
frame: false,
|
||
|
resizable: false,
|
||
|
webPreferences: {
|
||
|
nodeIntegration: true,
|
||
|
contextIsolation: false, // https://github.com/electron/electron/issues/28017
|
||
|
},
|
||
|
});
|
||
|
await loginWindow.loadURL(`file://${path.join(__dirname, 'static/login.html')}`);
|
||
|
electron_1.ipcMain.once('login-message', (event, usernameAndPassword) => {
|
||
|
log.debug('login-message', { event, username: usernameAndPassword[0] });
|
||
|
loginCallback(usernameAndPassword[0], usernameAndPassword[1]);
|
||
|
loginWindow.close();
|
||
|
});
|
||
|
return loginWindow;
|
||
|
}
|
||
|
exports.createLoginWindow = createLoginWindow;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 33 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
// This helper allows logs to either be printed to the console as they would normally or if
|
||
|
// the USE_LOG_FILE environment variable is set (such as through our playwright tests), then
|
||
|
// the logs can be diverted from the command line to a log file, so that they can be displayed
|
||
|
// later (such as at the end of a playwright test run to help diagnose potential failures).
|
||
|
// Use this instead of loglevel whenever logging messages inside the app.
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
var _a;
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.warn = exports.trace = exports.setLevel = exports.log = exports.info = exports.error = exports.debug = void 0;
|
||
|
const fs = __importStar(__webpack_require__(15));
|
||
|
const path = __importStar(__webpack_require__(14));
|
||
|
const loglevel_1 = __importDefault(__webpack_require__(34));
|
||
|
const playwrightHelpers_1 = __webpack_require__(35);
|
||
|
const USE_LOG_FILE = (0, playwrightHelpers_1.safeGetEnv)('USE_LOG_FILE') === '1';
|
||
|
const LOG_FILE_DIR = (_a = (0, playwrightHelpers_1.safeGetEnv)('LOG_FILE_DIR')) !== null && _a !== void 0 ? _a : process.cwd();
|
||
|
const LOG_FILENAME = path.join(LOG_FILE_DIR, `${new Date().getTime()}.log`);
|
||
|
const logLevelNames = ['TRACE', 'DEBUG', 'INFO ', 'WARN ', 'ERROR'];
|
||
|
function _logger(logFunc, level, ...args) {
|
||
|
var _a, _b;
|
||
|
if (USE_LOG_FILE && loglevel_1.default.getLevel() >= level) {
|
||
|
for (const arg of args) {
|
||
|
try {
|
||
|
const lines =
|
||
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||
|
(_b = (_a = JSON.stringify(arg, null, 2)) === null || _a === void 0 ? void 0 : _a.split('\n')) !== null && _b !== void 0 ? _b : `${arg}`.split('\n');
|
||
|
for (const line of lines) {
|
||
|
fs.appendFileSync(LOG_FILENAME, `${new Date().getTime()} ${logLevelNames[level]} ${line}\n`);
|
||
|
}
|
||
|
}
|
||
|
catch (_c) {
|
||
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||
|
fs.appendFileSync(LOG_FILENAME, `${logLevelNames[level]} ${arg}\n`);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
logFunc(...args);
|
||
|
}
|
||
|
}
|
||
|
function debug(...args) {
|
||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||
|
_logger(loglevel_1.default.debug, loglevel_1.default.levels.DEBUG, ...args);
|
||
|
}
|
||
|
exports.debug = debug;
|
||
|
function error(...args) {
|
||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||
|
_logger(loglevel_1.default.error, loglevel_1.default.levels.ERROR, ...args);
|
||
|
}
|
||
|
exports.error = error;
|
||
|
function info(...args) {
|
||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||
|
_logger(loglevel_1.default.info, loglevel_1.default.levels.INFO, ...args);
|
||
|
}
|
||
|
exports.info = info;
|
||
|
function log(...args) {
|
||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||
|
_logger(loglevel_1.default.info, loglevel_1.default.levels.INFO, ...args);
|
||
|
}
|
||
|
exports.log = log;
|
||
|
function setLevel(level, persist) {
|
||
|
loglevel_1.default.setLevel(level, persist);
|
||
|
}
|
||
|
exports.setLevel = setLevel;
|
||
|
function trace(...args) {
|
||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||
|
_logger(loglevel_1.default.trace, loglevel_1.default.levels.TRACE, ...args);
|
||
|
}
|
||
|
exports.trace = trace;
|
||
|
function warn(...args) {
|
||
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||
|
_logger(loglevel_1.default.warn, loglevel_1.default.levels.WARN, ...args);
|
||
|
}
|
||
|
exports.warn = warn;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 34 */
|
||
|
/***/ (function(module, exports, __webpack_require__) {
|
||
|
|
||
|
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*
|
||
|
* loglevel - https://github.com/pimterry/loglevel
|
||
|
*
|
||
|
* Copyright (c) 2013 Tim Perry
|
||
|
* Licensed under the MIT license.
|
||
|
*/
|
||
|
(function (root, definition) {
|
||
|
"use strict";
|
||
|
if (true) {
|
||
|
!(__WEBPACK_AMD_DEFINE_FACTORY__ = (definition),
|
||
|
__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
|
||
|
(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
|
||
|
__WEBPACK_AMD_DEFINE_FACTORY__),
|
||
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||
|
} else {}
|
||
|
}(this, function () {
|
||
|
"use strict";
|
||
|
|
||
|
// Slightly dubious tricks to cut down minimized file size
|
||
|
var noop = function() {};
|
||
|
var undefinedType = "undefined";
|
||
|
var isIE = (typeof window !== undefinedType) && (typeof window.navigator !== undefinedType) && (
|
||
|
/Trident\/|MSIE /.test(window.navigator.userAgent)
|
||
|
);
|
||
|
|
||
|
var logMethods = [
|
||
|
"trace",
|
||
|
"debug",
|
||
|
"info",
|
||
|
"warn",
|
||
|
"error"
|
||
|
];
|
||
|
|
||
|
// Cross-browser bind equivalent that works at least back to IE6
|
||
|
function bindMethod(obj, methodName) {
|
||
|
var method = obj[methodName];
|
||
|
if (typeof method.bind === 'function') {
|
||
|
return method.bind(obj);
|
||
|
} else {
|
||
|
try {
|
||
|
return Function.prototype.bind.call(method, obj);
|
||
|
} catch (e) {
|
||
|
// Missing bind shim or IE8 + Modernizr, fallback to wrapping
|
||
|
return function() {
|
||
|
return Function.prototype.apply.apply(method, [obj, arguments]);
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Trace() doesn't print the message in IE, so for that case we need to wrap it
|
||
|
function traceForIE() {
|
||
|
if (console.log) {
|
||
|
if (console.log.apply) {
|
||
|
console.log.apply(console, arguments);
|
||
|
} else {
|
||
|
// In old IE, native console methods themselves don't have apply().
|
||
|
Function.prototype.apply.apply(console.log, [console, arguments]);
|
||
|
}
|
||
|
}
|
||
|
if (console.trace) console.trace();
|
||
|
}
|
||
|
|
||
|
// Build the best logging method possible for this env
|
||
|
// Wherever possible we want to bind, not wrap, to preserve stack traces
|
||
|
function realMethod(methodName) {
|
||
|
if (methodName === 'debug') {
|
||
|
methodName = 'log';
|
||
|
}
|
||
|
|
||
|
if (typeof console === undefinedType) {
|
||
|
return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives
|
||
|
} else if (methodName === 'trace' && isIE) {
|
||
|
return traceForIE;
|
||
|
} else if (console[methodName] !== undefined) {
|
||
|
return bindMethod(console, methodName);
|
||
|
} else if (console.log !== undefined) {
|
||
|
return bindMethod(console, 'log');
|
||
|
} else {
|
||
|
return noop;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// These private functions always need `this` to be set properly
|
||
|
|
||
|
function replaceLoggingMethods(level, loggerName) {
|
||
|
/*jshint validthis:true */
|
||
|
for (var i = 0; i < logMethods.length; i++) {
|
||
|
var methodName = logMethods[i];
|
||
|
this[methodName] = (i < level) ?
|
||
|
noop :
|
||
|
this.methodFactory(methodName, level, loggerName);
|
||
|
}
|
||
|
|
||
|
// Define log.log as an alias for log.debug
|
||
|
this.log = this.debug;
|
||
|
}
|
||
|
|
||
|
// In old IE versions, the console isn't present until you first open it.
|
||
|
// We build realMethod() replacements here that regenerate logging methods
|
||
|
function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {
|
||
|
return function () {
|
||
|
if (typeof console !== undefinedType) {
|
||
|
replaceLoggingMethods.call(this, level, loggerName);
|
||
|
this[methodName].apply(this, arguments);
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// By default, we use closely bound real methods wherever possible, and
|
||
|
// otherwise we wait for a console to appear, and then try again.
|
||
|
function defaultMethodFactory(methodName, level, loggerName) {
|
||
|
/*jshint validthis:true */
|
||
|
return realMethod(methodName) ||
|
||
|
enableLoggingWhenConsoleArrives.apply(this, arguments);
|
||
|
}
|
||
|
|
||
|
function Logger(name, defaultLevel, factory) {
|
||
|
var self = this;
|
||
|
var currentLevel;
|
||
|
defaultLevel = defaultLevel == null ? "WARN" : defaultLevel;
|
||
|
|
||
|
var storageKey = "loglevel";
|
||
|
if (typeof name === "string") {
|
||
|
storageKey += ":" + name;
|
||
|
} else if (typeof name === "symbol") {
|
||
|
storageKey = undefined;
|
||
|
}
|
||
|
|
||
|
function persistLevelIfPossible(levelNum) {
|
||
|
var levelName = (logMethods[levelNum] || 'silent').toUpperCase();
|
||
|
|
||
|
if (typeof window === undefinedType || !storageKey) return;
|
||
|
|
||
|
// Use localStorage if available
|
||
|
try {
|
||
|
window.localStorage[storageKey] = levelName;
|
||
|
return;
|
||
|
} catch (ignore) {}
|
||
|
|
||
|
// Use session cookie as fallback
|
||
|
try {
|
||
|
window.document.cookie =
|
||
|
encodeURIComponent(storageKey) + "=" + levelName + ";";
|
||
|
} catch (ignore) {}
|
||
|
}
|
||
|
|
||
|
function getPersistedLevel() {
|
||
|
var storedLevel;
|
||
|
|
||
|
if (typeof window === undefinedType || !storageKey) return;
|
||
|
|
||
|
try {
|
||
|
storedLevel = window.localStorage[storageKey];
|
||
|
} catch (ignore) {}
|
||
|
|
||
|
// Fallback to cookies if local storage gives us nothing
|
||
|
if (typeof storedLevel === undefinedType) {
|
||
|
try {
|
||
|
var cookie = window.document.cookie;
|
||
|
var location = cookie.indexOf(
|
||
|
encodeURIComponent(storageKey) + "=");
|
||
|
if (location !== -1) {
|
||
|
storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
|
||
|
}
|
||
|
} catch (ignore) {}
|
||
|
}
|
||
|
|
||
|
// If the stored level is not valid, treat it as if nothing was stored.
|
||
|
if (self.levels[storedLevel] === undefined) {
|
||
|
storedLevel = undefined;
|
||
|
}
|
||
|
|
||
|
return storedLevel;
|
||
|
}
|
||
|
|
||
|
function clearPersistedLevel() {
|
||
|
if (typeof window === undefinedType || !storageKey) return;
|
||
|
|
||
|
// Use localStorage if available
|
||
|
try {
|
||
|
window.localStorage.removeItem(storageKey);
|
||
|
return;
|
||
|
} catch (ignore) {}
|
||
|
|
||
|
// Use session cookie as fallback
|
||
|
try {
|
||
|
window.document.cookie =
|
||
|
encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
|
||
|
} catch (ignore) {}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
*
|
||
|
* Public logger API - see https://github.com/pimterry/loglevel for details
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
self.name = name;
|
||
|
|
||
|
self.levels = { "TRACE": 0, "DEBUG": 1, "INFO": 2, "WARN": 3,
|
||
|
"ERROR": 4, "SILENT": 5};
|
||
|
|
||
|
self.methodFactory = factory || defaultMethodFactory;
|
||
|
|
||
|
self.getLevel = function () {
|
||
|
return currentLevel;
|
||
|
};
|
||
|
|
||
|
self.setLevel = function (level, persist) {
|
||
|
if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
|
||
|
level = self.levels[level.toUpperCase()];
|
||
|
}
|
||
|
if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
|
||
|
currentLevel = level;
|
||
|
if (persist !== false) { // defaults to true
|
||
|
persistLevelIfPossible(level);
|
||
|
}
|
||
|
replaceLoggingMethods.call(self, level, name);
|
||
|
if (typeof console === undefinedType && level < self.levels.SILENT) {
|
||
|
return "No console available for logging";
|
||
|
}
|
||
|
} else {
|
||
|
throw "log.setLevel() called with invalid level: " + level;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
self.setDefaultLevel = function (level) {
|
||
|
defaultLevel = level;
|
||
|
if (!getPersistedLevel()) {
|
||
|
self.setLevel(level, false);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
self.resetLevel = function () {
|
||
|
self.setLevel(defaultLevel, false);
|
||
|
clearPersistedLevel();
|
||
|
};
|
||
|
|
||
|
self.enableAll = function(persist) {
|
||
|
self.setLevel(self.levels.TRACE, persist);
|
||
|
};
|
||
|
|
||
|
self.disableAll = function(persist) {
|
||
|
self.setLevel(self.levels.SILENT, persist);
|
||
|
};
|
||
|
|
||
|
// Initialize with the right level
|
||
|
var initialLevel = getPersistedLevel();
|
||
|
if (initialLevel == null) {
|
||
|
initialLevel = defaultLevel;
|
||
|
}
|
||
|
self.setLevel(initialLevel, false);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
*
|
||
|
* Top-level API
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
var defaultLogger = new Logger();
|
||
|
|
||
|
var _loggersByName = {};
|
||
|
defaultLogger.getLogger = function getLogger(name) {
|
||
|
if ((typeof name !== "symbol" && typeof name !== "string") || name === "") {
|
||
|
throw new TypeError("You must supply a name when creating a logger.");
|
||
|
}
|
||
|
|
||
|
var logger = _loggersByName[name];
|
||
|
if (!logger) {
|
||
|
logger = _loggersByName[name] = new Logger(
|
||
|
name, defaultLogger.getLevel(), defaultLogger.methodFactory);
|
||
|
}
|
||
|
return logger;
|
||
|
};
|
||
|
|
||
|
// Grab the current global log variable in case of overwrite
|
||
|
var _log = (typeof window !== undefinedType) ? window.log : undefined;
|
||
|
defaultLogger.noConflict = function() {
|
||
|
if (typeof window !== undefinedType &&
|
||
|
window.log === defaultLogger) {
|
||
|
window.log = _log;
|
||
|
}
|
||
|
|
||
|
return defaultLogger;
|
||
|
};
|
||
|
|
||
|
defaultLogger.getLoggers = function getLoggers() {
|
||
|
return _loggersByName;
|
||
|
};
|
||
|
|
||
|
// ES6 default export, for compatibility
|
||
|
defaultLogger['default'] = defaultLogger;
|
||
|
|
||
|
return defaultLogger;
|
||
|
}));
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 35 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.safeGetEnv = exports.PLAYWRIGHT_CONFIG = exports.IS_PLAYWRIGHT = void 0;
|
||
|
exports.IS_PLAYWRIGHT = safeGetEnv('PLAYWRIGHT_TEST') === '1';
|
||
|
exports.PLAYWRIGHT_CONFIG = safeGetEnv('PLAYWRIGHT_CONFIG');
|
||
|
function safeGetEnv(key) {
|
||
|
return key in process.env ? process.env[key] : undefined;
|
||
|
}
|
||
|
exports.safeGetEnv = safeGetEnv;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 36 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.saveAppArgs = exports.createMainWindow = exports.APP_ARGS_FILE_PATH = void 0;
|
||
|
const fs = __importStar(__webpack_require__(15));
|
||
|
const path = __importStar(__webpack_require__(14));
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const electron_window_state_1 = __importDefault(__webpack_require__(37));
|
||
|
const contextMenu_1 = __webpack_require__(47);
|
||
|
const menu_1 = __webpack_require__(68);
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const playwrightHelpers_1 = __webpack_require__(35);
|
||
|
const windowEvents_1 = __webpack_require__(66);
|
||
|
const windowHelpers_1 = __webpack_require__(65);
|
||
|
const model_1 = __webpack_require__(67);
|
||
|
exports.APP_ARGS_FILE_PATH = path.join(__dirname, '..', 'nativefier.json');
|
||
|
/**
|
||
|
* @param {{}} nativefierOptions AppArgs from nativefier.json
|
||
|
* @param {function} setDockBadge
|
||
|
*/
|
||
|
async function createMainWindow(nativefierOptions, setDockBadge) {
|
||
|
var _a;
|
||
|
const options = { ...nativefierOptions };
|
||
|
const mainWindowState = (0, electron_window_state_1.default)({
|
||
|
defaultWidth: options.width || 1280,
|
||
|
defaultHeight: options.height || 800,
|
||
|
});
|
||
|
const mainWindow = new electron_1.BrowserWindow({
|
||
|
frame: !options.hideWindowFrame,
|
||
|
width: mainWindowState.width,
|
||
|
height: mainWindowState.height,
|
||
|
minWidth: options.minWidth,
|
||
|
minHeight: options.minHeight,
|
||
|
maxWidth: options.maxWidth,
|
||
|
maxHeight: options.maxHeight,
|
||
|
x: options.x,
|
||
|
y: options.y,
|
||
|
autoHideMenuBar: !options.showMenuBar,
|
||
|
icon: (0, helpers_1.getAppIcon)(),
|
||
|
fullscreen: options.fullScreen,
|
||
|
// Whether the window should always stay on top of other windows. Default is false.
|
||
|
alwaysOnTop: options.alwaysOnTop,
|
||
|
titleBarStyle: (_a = options.titleBarStyle) !== null && _a !== void 0 ? _a : 'default',
|
||
|
// Maximize window visual glitch on Windows fix
|
||
|
// We want a consistent behavior on all OSes, but Windows needs help to not glitch.
|
||
|
// So, we manually mainWindow.show() later, see a few lines below
|
||
|
show: options.tray !== 'start-in-tray' && process.platform !== 'win32',
|
||
|
backgroundColor: options.backgroundColor,
|
||
|
...(0, windowHelpers_1.getDefaultWindowOptions)((0, model_1.outputOptionsToWindowOptions)(options)),
|
||
|
});
|
||
|
// Just load about:blank to start, gives playwright something to latch onto initially for testing.
|
||
|
if (playwrightHelpers_1.IS_PLAYWRIGHT) {
|
||
|
await mainWindow.loadURL('about:blank');
|
||
|
}
|
||
|
mainWindowState.manage(mainWindow);
|
||
|
// after first run, no longer force maximize to be true
|
||
|
if (options.maximize) {
|
||
|
mainWindow.maximize();
|
||
|
options.maximize = undefined;
|
||
|
saveAppArgs(options);
|
||
|
}
|
||
|
if (options.tray === 'start-in-tray') {
|
||
|
mainWindow.hide();
|
||
|
}
|
||
|
else if (process.platform === 'win32') {
|
||
|
// See other "Maximize window visual glitch on Windows fix" comment above.
|
||
|
mainWindow.show();
|
||
|
}
|
||
|
const windowOptions = (0, model_1.outputOptionsToWindowOptions)(options);
|
||
|
(0, menu_1.createMenu)(options, mainWindow);
|
||
|
createContextMenu(options, mainWindow);
|
||
|
(0, windowEvents_1.setupNativefierWindow)(windowOptions, mainWindow);
|
||
|
// .on('new-window', ...) is deprected in favor of setWindowOpenHandler(...)
|
||
|
// We can't quite cut over to that yet for a few reasons:
|
||
|
// 1. Our version of Electron does not yet support a parameter to
|
||
|
// setWindowOpenHandler that contains `disposition', which we need.
|
||
|
// See https://github.com/electron/electron/issues/28380
|
||
|
// 2. setWindowOpenHandler doesn't support newGuest as well
|
||
|
// Though at this point, 'new-window' bugs seem to be coming up and downstream
|
||
|
// users are being pointed to use setWindowOpenHandler.
|
||
|
// E.g., https://github.com/electron/electron/issues/28374
|
||
|
// Note it is important to add these handlers only to the *main* window,
|
||
|
// else we run into weird behavior like opening tabs twice
|
||
|
mainWindow.webContents.on('new-window', (event, url, frameName, disposition) => {
|
||
|
(0, windowEvents_1.onNewWindow)(windowOptions, windowEvents_1.setupNativefierWindow, event, url, frameName, disposition).catch((err) => log.error('onNewWindow ERROR', err));
|
||
|
});
|
||
|
// @ts-expect-error new-tab isn't in the type definition, but it does exist
|
||
|
mainWindow.on('new-tab', () => {
|
||
|
(0, windowHelpers_1.createNewTab)(windowOptions, windowEvents_1.setupNativefierWindow, options.targetUrl, true, mainWindow);
|
||
|
});
|
||
|
if (options.counter) {
|
||
|
setupCounter(options, mainWindow, setDockBadge);
|
||
|
}
|
||
|
else {
|
||
|
setupNotificationBadge(options, mainWindow, setDockBadge);
|
||
|
}
|
||
|
electron_1.ipcMain.on('notification-click', () => {
|
||
|
log.debug('ipcMain.notification-click');
|
||
|
mainWindow.show();
|
||
|
});
|
||
|
setupSessionInteraction(options, mainWindow);
|
||
|
if (options.clearCache) {
|
||
|
await (0, windowHelpers_1.clearCache)(mainWindow);
|
||
|
}
|
||
|
setupCloseEvent(options, mainWindow);
|
||
|
return mainWindow;
|
||
|
}
|
||
|
exports.createMainWindow = createMainWindow;
|
||
|
function createContextMenu(options, window) {
|
||
|
if (!options.disableContextMenu) {
|
||
|
(0, contextMenu_1.initContextMenu)(options, window);
|
||
|
}
|
||
|
}
|
||
|
function saveAppArgs(newAppArgs) {
|
||
|
try {
|
||
|
fs.writeFileSync(exports.APP_ARGS_FILE_PATH, JSON.stringify(newAppArgs, null, 2));
|
||
|
}
|
||
|
catch (err) {
|
||
|
log.warn(`WARNING: Ignored nativefier.json rewrital (${err.message})`);
|
||
|
}
|
||
|
}
|
||
|
exports.saveAppArgs = saveAppArgs;
|
||
|
function setupCloseEvent(options, window) {
|
||
|
window.on('close', (event) => {
|
||
|
var _a, _b;
|
||
|
log.debug('mainWindow.close', event);
|
||
|
if (window.isFullScreen()) {
|
||
|
if ((0, helpers_1.nativeTabsSupported)()) {
|
||
|
window.moveTabToNewWindow();
|
||
|
}
|
||
|
window.setFullScreen(false);
|
||
|
window.once('leave-full-screen', (event) => {
|
||
|
var _a, _b;
|
||
|
return (0, windowHelpers_1.hideWindow)(window, event, (_a = options.fastQuit) !== null && _a !== void 0 ? _a : false, (_b = options.tray) !== null && _b !== void 0 ? _b : 'false');
|
||
|
});
|
||
|
}
|
||
|
(0, windowHelpers_1.hideWindow)(window, event, (_a = options.fastQuit) !== null && _a !== void 0 ? _a : false, (_b = options.tray) !== null && _b !== void 0 ? _b : 'false');
|
||
|
if (options.clearCache) {
|
||
|
(0, windowHelpers_1.clearCache)(window).catch((err) => log.error('clearCache ERROR', err));
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
function setupCounter(options, window, setDockBadge) {
|
||
|
window.on('page-title-updated', (event, title) => {
|
||
|
log.debug('mainWindow.page-title-updated', { event, title });
|
||
|
const counterValue = (0, helpers_1.getCounterValue)(title);
|
||
|
if (counterValue) {
|
||
|
setDockBadge(counterValue, options.bounce);
|
||
|
}
|
||
|
else {
|
||
|
setDockBadge('');
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
function setupNotificationBadge(options, window, setDockBadge) {
|
||
|
electron_1.ipcMain.on('notification', () => {
|
||
|
log.debug('ipcMain.notification');
|
||
|
if (!(0, helpers_1.isOSX)() || window.isFocused()) {
|
||
|
return;
|
||
|
}
|
||
|
setDockBadge('•', options.bounce);
|
||
|
});
|
||
|
window.on('focus', () => {
|
||
|
log.debug('mainWindow.focus');
|
||
|
setDockBadge('');
|
||
|
});
|
||
|
}
|
||
|
function setupSessionInteraction(options, window) {
|
||
|
// See API.md / "Accessing The Electron Session"
|
||
|
electron_1.ipcMain.on('session-interaction', (event, request) => {
|
||
|
log.debug('ipcMain.session-interaction', { event, request });
|
||
|
const result = { id: request.id };
|
||
|
let awaitingPromise = false;
|
||
|
try {
|
||
|
if (request.func !== undefined) {
|
||
|
// If no funcArgs provided, we'll just use an empty array
|
||
|
if (request.funcArgs === undefined || request.funcArgs === null) {
|
||
|
request.funcArgs = [];
|
||
|
}
|
||
|
// If funcArgs isn't an array, we'll be nice and make it a single item array
|
||
|
if (typeof request.funcArgs[Symbol.iterator] !== 'function') {
|
||
|
request.funcArgs = [request.funcArgs];
|
||
|
}
|
||
|
// Call func with funcArgs
|
||
|
// @ts-expect-error accessing a func by string name
|
||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||
|
result.value = window.webContents.session[request.func](...request.funcArgs);
|
||
|
if (result.value !== undefined && result.value instanceof Promise) {
|
||
|
// This is a promise. We'll resolve it here otherwise it will blow up trying to serialize it in the reply
|
||
|
result.value
|
||
|
.then((trueResultValue) => {
|
||
|
result.value = trueResultValue;
|
||
|
log.debug('ipcMain.session-interaction:result', result);
|
||
|
event.reply('session-interaction-reply', result);
|
||
|
})
|
||
|
.catch((err) => log.error('session-interaction ERROR', request, err));
|
||
|
awaitingPromise = true;
|
||
|
}
|
||
|
}
|
||
|
else if (request.property !== undefined) {
|
||
|
if (request.propertyValue !== undefined) {
|
||
|
// Set the property
|
||
|
// @ts-expect-error setting a property by string name
|
||
|
window.webContents.session[request.property] =
|
||
|
request.propertyValue;
|
||
|
}
|
||
|
// Get the property value
|
||
|
// @ts-expect-error accessing a property by string name
|
||
|
result.value = window.webContents.session[request.property];
|
||
|
}
|
||
|
else {
|
||
|
// Why even send the event if you're going to do this? You're just wasting time! ;)
|
||
|
throw new Error('Received neither a func nor a property in the request. Unable to process.');
|
||
|
}
|
||
|
// If we are awaiting a promise, that will return the reply instead, else
|
||
|
if (!awaitingPromise) {
|
||
|
log.debug('session-interaction:result', result);
|
||
|
event.reply('session-interaction-reply', result);
|
||
|
}
|
||
|
}
|
||
|
catch (err) {
|
||
|
log.error('session-interaction:error', err, event, request);
|
||
|
result.error = err;
|
||
|
result.value = undefined; // Clear out the value in case serializing the value is what got us into this mess in the first place
|
||
|
event.reply('session-interaction-reply', result);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 37 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
const path = __webpack_require__(14);
|
||
|
const electron = __webpack_require__(17);
|
||
|
const jsonfile = __webpack_require__(38);
|
||
|
const mkdirp = __webpack_require__(46);
|
||
|
|
||
|
module.exports = function (options) {
|
||
|
const app = electron.app || electron.remote.app;
|
||
|
const screen = electron.screen || electron.remote.screen;
|
||
|
let state;
|
||
|
let winRef;
|
||
|
let stateChangeTimer;
|
||
|
const eventHandlingDelay = 100;
|
||
|
const config = Object.assign({
|
||
|
file: 'window-state.json',
|
||
|
path: app.getPath('userData'),
|
||
|
maximize: true,
|
||
|
fullScreen: true
|
||
|
}, options);
|
||
|
const fullStoreFileName = path.join(config.path, config.file);
|
||
|
|
||
|
function isNormal(win) {
|
||
|
return !win.isMaximized() && !win.isMinimized() && !win.isFullScreen();
|
||
|
}
|
||
|
|
||
|
function hasBounds() {
|
||
|
return state &&
|
||
|
Number.isInteger(state.x) &&
|
||
|
Number.isInteger(state.y) &&
|
||
|
Number.isInteger(state.width) && state.width > 0 &&
|
||
|
Number.isInteger(state.height) && state.height > 0;
|
||
|
}
|
||
|
|
||
|
function resetStateToDefault() {
|
||
|
const displayBounds = screen.getPrimaryDisplay().bounds;
|
||
|
|
||
|
// Reset state to default values on the primary display
|
||
|
state = {
|
||
|
width: config.defaultWidth || 800,
|
||
|
height: config.defaultHeight || 600,
|
||
|
x: 0,
|
||
|
y: 0,
|
||
|
displayBounds
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function windowWithinBounds(bounds) {
|
||
|
return (
|
||
|
state.x >= bounds.x &&
|
||
|
state.y >= bounds.y &&
|
||
|
state.x + state.width <= bounds.x + bounds.width &&
|
||
|
state.y + state.height <= bounds.y + bounds.height
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function ensureWindowVisibleOnSomeDisplay() {
|
||
|
const visible = screen.getAllDisplays().some(display => {
|
||
|
return windowWithinBounds(display.bounds);
|
||
|
});
|
||
|
|
||
|
if (!visible) {
|
||
|
// Window is partially or fully not visible now.
|
||
|
// Reset it to safe defaults.
|
||
|
return resetStateToDefault();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function validateState() {
|
||
|
const isValid = state && (hasBounds() || state.isMaximized || state.isFullScreen);
|
||
|
if (!isValid) {
|
||
|
state = null;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (hasBounds() && state.displayBounds) {
|
||
|
ensureWindowVisibleOnSomeDisplay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function updateState(win) {
|
||
|
win = win || winRef;
|
||
|
if (!win) {
|
||
|
return;
|
||
|
}
|
||
|
// Don't throw an error when window was closed
|
||
|
try {
|
||
|
const winBounds = win.getBounds();
|
||
|
if (isNormal(win)) {
|
||
|
state.x = winBounds.x;
|
||
|
state.y = winBounds.y;
|
||
|
state.width = winBounds.width;
|
||
|
state.height = winBounds.height;
|
||
|
}
|
||
|
state.isMaximized = win.isMaximized();
|
||
|
state.isFullScreen = win.isFullScreen();
|
||
|
state.displayBounds = screen.getDisplayMatching(winBounds).bounds;
|
||
|
} catch (err) {}
|
||
|
}
|
||
|
|
||
|
function saveState(win) {
|
||
|
// Update window state only if it was provided
|
||
|
if (win) {
|
||
|
updateState(win);
|
||
|
}
|
||
|
|
||
|
// Save state
|
||
|
try {
|
||
|
mkdirp.sync(path.dirname(fullStoreFileName));
|
||
|
jsonfile.writeFileSync(fullStoreFileName, state);
|
||
|
} catch (err) {
|
||
|
// Don't care
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function stateChangeHandler() {
|
||
|
// Handles both 'resize' and 'move'
|
||
|
clearTimeout(stateChangeTimer);
|
||
|
stateChangeTimer = setTimeout(updateState, eventHandlingDelay);
|
||
|
}
|
||
|
|
||
|
function closeHandler() {
|
||
|
updateState();
|
||
|
}
|
||
|
|
||
|
function closedHandler() {
|
||
|
// Unregister listeners and save state
|
||
|
unmanage();
|
||
|
saveState();
|
||
|
}
|
||
|
|
||
|
function manage(win) {
|
||
|
if (config.maximize && state.isMaximized) {
|
||
|
win.maximize();
|
||
|
}
|
||
|
if (config.fullScreen && state.isFullScreen) {
|
||
|
win.setFullScreen(true);
|
||
|
}
|
||
|
win.on('resize', stateChangeHandler);
|
||
|
win.on('move', stateChangeHandler);
|
||
|
win.on('close', closeHandler);
|
||
|
win.on('closed', closedHandler);
|
||
|
winRef = win;
|
||
|
}
|
||
|
|
||
|
function unmanage() {
|
||
|
if (winRef) {
|
||
|
winRef.removeListener('resize', stateChangeHandler);
|
||
|
winRef.removeListener('move', stateChangeHandler);
|
||
|
clearTimeout(stateChangeTimer);
|
||
|
winRef.removeListener('close', closeHandler);
|
||
|
winRef.removeListener('closed', closedHandler);
|
||
|
winRef = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Load previous state
|
||
|
try {
|
||
|
state = jsonfile.readFileSync(fullStoreFileName);
|
||
|
} catch (err) {
|
||
|
// Don't care
|
||
|
}
|
||
|
|
||
|
// Check state validity
|
||
|
validateState();
|
||
|
|
||
|
// Set state fallback values
|
||
|
state = Object.assign({
|
||
|
width: config.defaultWidth || 800,
|
||
|
height: config.defaultHeight || 600
|
||
|
}, state);
|
||
|
|
||
|
return {
|
||
|
get x() { return state.x; },
|
||
|
get y() { return state.y; },
|
||
|
get width() { return state.width; },
|
||
|
get height() { return state.height; },
|
||
|
get displayBounds() { return state.displayBounds; },
|
||
|
get isMaximized() { return state.isMaximized; },
|
||
|
get isFullScreen() { return state.isFullScreen; },
|
||
|
saveState,
|
||
|
unmanage,
|
||
|
manage,
|
||
|
resetStateToDefault
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 38 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
var _fs
|
||
|
try {
|
||
|
_fs = __webpack_require__(39)
|
||
|
} catch (_) {
|
||
|
_fs = __webpack_require__(15)
|
||
|
}
|
||
|
|
||
|
function readFile (file, options, callback) {
|
||
|
if (callback == null) {
|
||
|
callback = options
|
||
|
options = {}
|
||
|
}
|
||
|
|
||
|
if (typeof options === 'string') {
|
||
|
options = {encoding: options}
|
||
|
}
|
||
|
|
||
|
options = options || {}
|
||
|
var fs = options.fs || _fs
|
||
|
|
||
|
var shouldThrow = true
|
||
|
if ('throws' in options) {
|
||
|
shouldThrow = options.throws
|
||
|
}
|
||
|
|
||
|
fs.readFile(file, options, function (err, data) {
|
||
|
if (err) return callback(err)
|
||
|
|
||
|
data = stripBom(data)
|
||
|
|
||
|
var obj
|
||
|
try {
|
||
|
obj = JSON.parse(data, options ? options.reviver : null)
|
||
|
} catch (err2) {
|
||
|
if (shouldThrow) {
|
||
|
err2.message = file + ': ' + err2.message
|
||
|
return callback(err2)
|
||
|
} else {
|
||
|
return callback(null, null)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
callback(null, obj)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function readFileSync (file, options) {
|
||
|
options = options || {}
|
||
|
if (typeof options === 'string') {
|
||
|
options = {encoding: options}
|
||
|
}
|
||
|
|
||
|
var fs = options.fs || _fs
|
||
|
|
||
|
var shouldThrow = true
|
||
|
if ('throws' in options) {
|
||
|
shouldThrow = options.throws
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
var content = fs.readFileSync(file, options)
|
||
|
content = stripBom(content)
|
||
|
return JSON.parse(content, options.reviver)
|
||
|
} catch (err) {
|
||
|
if (shouldThrow) {
|
||
|
err.message = file + ': ' + err.message
|
||
|
throw err
|
||
|
} else {
|
||
|
return null
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function stringify (obj, options) {
|
||
|
var spaces
|
||
|
var EOL = '\n'
|
||
|
if (typeof options === 'object' && options !== null) {
|
||
|
if (options.spaces) {
|
||
|
spaces = options.spaces
|
||
|
}
|
||
|
if (options.EOL) {
|
||
|
EOL = options.EOL
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var str = JSON.stringify(obj, options ? options.replacer : null, spaces)
|
||
|
|
||
|
return str.replace(/\n/g, EOL) + EOL
|
||
|
}
|
||
|
|
||
|
function writeFile (file, obj, options, callback) {
|
||
|
if (callback == null) {
|
||
|
callback = options
|
||
|
options = {}
|
||
|
}
|
||
|
options = options || {}
|
||
|
var fs = options.fs || _fs
|
||
|
|
||
|
var str = ''
|
||
|
try {
|
||
|
str = stringify(obj, options)
|
||
|
} catch (err) {
|
||
|
// Need to return whether a callback was passed or not
|
||
|
if (callback) callback(err, null)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
fs.writeFile(file, str, options, callback)
|
||
|
}
|
||
|
|
||
|
function writeFileSync (file, obj, options) {
|
||
|
options = options || {}
|
||
|
var fs = options.fs || _fs
|
||
|
|
||
|
var str = stringify(obj, options)
|
||
|
// not sure if fs.writeFileSync returns anything, but just in case
|
||
|
return fs.writeFileSync(file, str, options)
|
||
|
}
|
||
|
|
||
|
function stripBom (content) {
|
||
|
// we do this because JSON.parse would convert it to a utf8 string if encoding wasn't specified
|
||
|
if (Buffer.isBuffer(content)) content = content.toString('utf8')
|
||
|
content = content.replace(/^\uFEFF/, '')
|
||
|
return content
|
||
|
}
|
||
|
|
||
|
var jsonfile = {
|
||
|
readFile: readFile,
|
||
|
readFileSync: readFileSync,
|
||
|
writeFile: writeFile,
|
||
|
writeFileSync: writeFileSync
|
||
|
}
|
||
|
|
||
|
module.exports = jsonfile
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 39 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
var fs = __webpack_require__(15)
|
||
|
var polyfills = __webpack_require__(40)
|
||
|
var legacy = __webpack_require__(42)
|
||
|
var clone = __webpack_require__(44)
|
||
|
|
||
|
var util = __webpack_require__(21)
|
||
|
|
||
|
/* istanbul ignore next - node 0.x polyfill */
|
||
|
var gracefulQueue
|
||
|
var previousSymbol
|
||
|
|
||
|
/* istanbul ignore else - node 0.x polyfill */
|
||
|
if (typeof Symbol === 'function' && typeof Symbol.for === 'function') {
|
||
|
gracefulQueue = Symbol.for('graceful-fs.queue')
|
||
|
// This is used in testing by future versions
|
||
|
previousSymbol = Symbol.for('graceful-fs.previous')
|
||
|
} else {
|
||
|
gracefulQueue = '___graceful-fs.queue'
|
||
|
previousSymbol = '___graceful-fs.previous'
|
||
|
}
|
||
|
|
||
|
function noop () {}
|
||
|
|
||
|
function publishQueue(context, queue) {
|
||
|
Object.defineProperty(context, gracefulQueue, {
|
||
|
get: function() {
|
||
|
return queue
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
var debug = noop
|
||
|
if (util.debuglog)
|
||
|
debug = util.debuglog('gfs4')
|
||
|
else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ''))
|
||
|
debug = function() {
|
||
|
var m = util.format.apply(util, arguments)
|
||
|
m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ')
|
||
|
console.error(m)
|
||
|
}
|
||
|
|
||
|
// Once time initialization
|
||
|
if (!fs[gracefulQueue]) {
|
||
|
// This queue can be shared by multiple loaded instances
|
||
|
var queue = global[gracefulQueue] || []
|
||
|
publishQueue(fs, queue)
|
||
|
|
||
|
// Patch fs.close/closeSync to shared queue version, because we need
|
||
|
// to retry() whenever a close happens *anywhere* in the program.
|
||
|
// This is essential when multiple graceful-fs instances are
|
||
|
// in play at the same time.
|
||
|
fs.close = (function (fs$close) {
|
||
|
function close (fd, cb) {
|
||
|
return fs$close.call(fs, fd, function (err) {
|
||
|
// This function uses the graceful-fs shared queue
|
||
|
if (!err) {
|
||
|
resetQueue()
|
||
|
}
|
||
|
|
||
|
if (typeof cb === 'function')
|
||
|
cb.apply(this, arguments)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
Object.defineProperty(close, previousSymbol, {
|
||
|
value: fs$close
|
||
|
})
|
||
|
return close
|
||
|
})(fs.close)
|
||
|
|
||
|
fs.closeSync = (function (fs$closeSync) {
|
||
|
function closeSync (fd) {
|
||
|
// This function uses the graceful-fs shared queue
|
||
|
fs$closeSync.apply(fs, arguments)
|
||
|
resetQueue()
|
||
|
}
|
||
|
|
||
|
Object.defineProperty(closeSync, previousSymbol, {
|
||
|
value: fs$closeSync
|
||
|
})
|
||
|
return closeSync
|
||
|
})(fs.closeSync)
|
||
|
|
||
|
if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
|
||
|
process.on('exit', function() {
|
||
|
debug(fs[gracefulQueue])
|
||
|
__webpack_require__(45).equal(fs[gracefulQueue].length, 0)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!global[gracefulQueue]) {
|
||
|
publishQueue(global, fs[gracefulQueue]);
|
||
|
}
|
||
|
|
||
|
module.exports = patch(clone(fs))
|
||
|
if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) {
|
||
|
module.exports = patch(fs)
|
||
|
fs.__patched = true;
|
||
|
}
|
||
|
|
||
|
function patch (fs) {
|
||
|
// Everything that references the open() function needs to be in here
|
||
|
polyfills(fs)
|
||
|
fs.gracefulify = patch
|
||
|
|
||
|
fs.createReadStream = createReadStream
|
||
|
fs.createWriteStream = createWriteStream
|
||
|
var fs$readFile = fs.readFile
|
||
|
fs.readFile = readFile
|
||
|
function readFile (path, options, cb) {
|
||
|
if (typeof options === 'function')
|
||
|
cb = options, options = null
|
||
|
|
||
|
return go$readFile(path, options, cb)
|
||
|
|
||
|
function go$readFile (path, options, cb, startTime) {
|
||
|
return fs$readFile(path, options, function (err) {
|
||
|
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
|
||
|
enqueue([go$readFile, [path, options, cb], err, startTime || Date.now(), Date.now()])
|
||
|
else {
|
||
|
if (typeof cb === 'function')
|
||
|
cb.apply(this, arguments)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var fs$writeFile = fs.writeFile
|
||
|
fs.writeFile = writeFile
|
||
|
function writeFile (path, data, options, cb) {
|
||
|
if (typeof options === 'function')
|
||
|
cb = options, options = null
|
||
|
|
||
|
return go$writeFile(path, data, options, cb)
|
||
|
|
||
|
function go$writeFile (path, data, options, cb, startTime) {
|
||
|
return fs$writeFile(path, data, options, function (err) {
|
||
|
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
|
||
|
enqueue([go$writeFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()])
|
||
|
else {
|
||
|
if (typeof cb === 'function')
|
||
|
cb.apply(this, arguments)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var fs$appendFile = fs.appendFile
|
||
|
if (fs$appendFile)
|
||
|
fs.appendFile = appendFile
|
||
|
function appendFile (path, data, options, cb) {
|
||
|
if (typeof options === 'function')
|
||
|
cb = options, options = null
|
||
|
|
||
|
return go$appendFile(path, data, options, cb)
|
||
|
|
||
|
function go$appendFile (path, data, options, cb, startTime) {
|
||
|
return fs$appendFile(path, data, options, function (err) {
|
||
|
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
|
||
|
enqueue([go$appendFile, [path, data, options, cb], err, startTime || Date.now(), Date.now()])
|
||
|
else {
|
||
|
if (typeof cb === 'function')
|
||
|
cb.apply(this, arguments)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var fs$copyFile = fs.copyFile
|
||
|
if (fs$copyFile)
|
||
|
fs.copyFile = copyFile
|
||
|
function copyFile (src, dest, flags, cb) {
|
||
|
if (typeof flags === 'function') {
|
||
|
cb = flags
|
||
|
flags = 0
|
||
|
}
|
||
|
return go$copyFile(src, dest, flags, cb)
|
||
|
|
||
|
function go$copyFile (src, dest, flags, cb, startTime) {
|
||
|
return fs$copyFile(src, dest, flags, function (err) {
|
||
|
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
|
||
|
enqueue([go$copyFile, [src, dest, flags, cb], err, startTime || Date.now(), Date.now()])
|
||
|
else {
|
||
|
if (typeof cb === 'function')
|
||
|
cb.apply(this, arguments)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var fs$readdir = fs.readdir
|
||
|
fs.readdir = readdir
|
||
|
var noReaddirOptionVersions = /^v[0-5]\./
|
||
|
function readdir (path, options, cb) {
|
||
|
if (typeof options === 'function')
|
||
|
cb = options, options = null
|
||
|
|
||
|
var go$readdir = noReaddirOptionVersions.test(process.version)
|
||
|
? function go$readdir (path, options, cb, startTime) {
|
||
|
return fs$readdir(path, fs$readdirCallback(
|
||
|
path, options, cb, startTime
|
||
|
))
|
||
|
}
|
||
|
: function go$readdir (path, options, cb, startTime) {
|
||
|
return fs$readdir(path, options, fs$readdirCallback(
|
||
|
path, options, cb, startTime
|
||
|
))
|
||
|
}
|
||
|
|
||
|
return go$readdir(path, options, cb)
|
||
|
|
||
|
function fs$readdirCallback (path, options, cb, startTime) {
|
||
|
return function (err, files) {
|
||
|
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
|
||
|
enqueue([
|
||
|
go$readdir,
|
||
|
[path, options, cb],
|
||
|
err,
|
||
|
startTime || Date.now(),
|
||
|
Date.now()
|
||
|
])
|
||
|
else {
|
||
|
if (files && files.sort)
|
||
|
files.sort()
|
||
|
|
||
|
if (typeof cb === 'function')
|
||
|
cb.call(this, err, files)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (process.version.substr(0, 4) === 'v0.8') {
|
||
|
var legStreams = legacy(fs)
|
||
|
ReadStream = legStreams.ReadStream
|
||
|
WriteStream = legStreams.WriteStream
|
||
|
}
|
||
|
|
||
|
var fs$ReadStream = fs.ReadStream
|
||
|
if (fs$ReadStream) {
|
||
|
ReadStream.prototype = Object.create(fs$ReadStream.prototype)
|
||
|
ReadStream.prototype.open = ReadStream$open
|
||
|
}
|
||
|
|
||
|
var fs$WriteStream = fs.WriteStream
|
||
|
if (fs$WriteStream) {
|
||
|
WriteStream.prototype = Object.create(fs$WriteStream.prototype)
|
||
|
WriteStream.prototype.open = WriteStream$open
|
||
|
}
|
||
|
|
||
|
Object.defineProperty(fs, 'ReadStream', {
|
||
|
get: function () {
|
||
|
return ReadStream
|
||
|
},
|
||
|
set: function (val) {
|
||
|
ReadStream = val
|
||
|
},
|
||
|
enumerable: true,
|
||
|
configurable: true
|
||
|
})
|
||
|
Object.defineProperty(fs, 'WriteStream', {
|
||
|
get: function () {
|
||
|
return WriteStream
|
||
|
},
|
||
|
set: function (val) {
|
||
|
WriteStream = val
|
||
|
},
|
||
|
enumerable: true,
|
||
|
configurable: true
|
||
|
})
|
||
|
|
||
|
// legacy names
|
||
|
var FileReadStream = ReadStream
|
||
|
Object.defineProperty(fs, 'FileReadStream', {
|
||
|
get: function () {
|
||
|
return FileReadStream
|
||
|
},
|
||
|
set: function (val) {
|
||
|
FileReadStream = val
|
||
|
},
|
||
|
enumerable: true,
|
||
|
configurable: true
|
||
|
})
|
||
|
var FileWriteStream = WriteStream
|
||
|
Object.defineProperty(fs, 'FileWriteStream', {
|
||
|
get: function () {
|
||
|
return FileWriteStream
|
||
|
},
|
||
|
set: function (val) {
|
||
|
FileWriteStream = val
|
||
|
},
|
||
|
enumerable: true,
|
||
|
configurable: true
|
||
|
})
|
||
|
|
||
|
function ReadStream (path, options) {
|
||
|
if (this instanceof ReadStream)
|
||
|
return fs$ReadStream.apply(this, arguments), this
|
||
|
else
|
||
|
return ReadStream.apply(Object.create(ReadStream.prototype), arguments)
|
||
|
}
|
||
|
|
||
|
function ReadStream$open () {
|
||
|
var that = this
|
||
|
open(that.path, that.flags, that.mode, function (err, fd) {
|
||
|
if (err) {
|
||
|
if (that.autoClose)
|
||
|
that.destroy()
|
||
|
|
||
|
that.emit('error', err)
|
||
|
} else {
|
||
|
that.fd = fd
|
||
|
that.emit('open', fd)
|
||
|
that.read()
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function WriteStream (path, options) {
|
||
|
if (this instanceof WriteStream)
|
||
|
return fs$WriteStream.apply(this, arguments), this
|
||
|
else
|
||
|
return WriteStream.apply(Object.create(WriteStream.prototype), arguments)
|
||
|
}
|
||
|
|
||
|
function WriteStream$open () {
|
||
|
var that = this
|
||
|
open(that.path, that.flags, that.mode, function (err, fd) {
|
||
|
if (err) {
|
||
|
that.destroy()
|
||
|
that.emit('error', err)
|
||
|
} else {
|
||
|
that.fd = fd
|
||
|
that.emit('open', fd)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function createReadStream (path, options) {
|
||
|
return new fs.ReadStream(path, options)
|
||
|
}
|
||
|
|
||
|
function createWriteStream (path, options) {
|
||
|
return new fs.WriteStream(path, options)
|
||
|
}
|
||
|
|
||
|
var fs$open = fs.open
|
||
|
fs.open = open
|
||
|
function open (path, flags, mode, cb) {
|
||
|
if (typeof mode === 'function')
|
||
|
cb = mode, mode = null
|
||
|
|
||
|
return go$open(path, flags, mode, cb)
|
||
|
|
||
|
function go$open (path, flags, mode, cb, startTime) {
|
||
|
return fs$open(path, flags, mode, function (err, fd) {
|
||
|
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
|
||
|
enqueue([go$open, [path, flags, mode, cb], err, startTime || Date.now(), Date.now()])
|
||
|
else {
|
||
|
if (typeof cb === 'function')
|
||
|
cb.apply(this, arguments)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fs
|
||
|
}
|
||
|
|
||
|
function enqueue (elem) {
|
||
|
debug('ENQUEUE', elem[0].name, elem[1])
|
||
|
fs[gracefulQueue].push(elem)
|
||
|
retry()
|
||
|
}
|
||
|
|
||
|
// keep track of the timeout between retry() calls
|
||
|
var retryTimer
|
||
|
|
||
|
// reset the startTime and lastTime to now
|
||
|
// this resets the start of the 60 second overall timeout as well as the
|
||
|
// delay between attempts so that we'll retry these jobs sooner
|
||
|
function resetQueue () {
|
||
|
var now = Date.now()
|
||
|
for (var i = 0; i < fs[gracefulQueue].length; ++i) {
|
||
|
// entries that are only a length of 2 are from an older version, don't
|
||
|
// bother modifying those since they'll be retried anyway.
|
||
|
if (fs[gracefulQueue][i].length > 2) {
|
||
|
fs[gracefulQueue][i][3] = now // startTime
|
||
|
fs[gracefulQueue][i][4] = now // lastTime
|
||
|
}
|
||
|
}
|
||
|
// call retry to make sure we're actively processing the queue
|
||
|
retry()
|
||
|
}
|
||
|
|
||
|
function retry () {
|
||
|
// clear the timer and remove it to help prevent unintended concurrency
|
||
|
clearTimeout(retryTimer)
|
||
|
retryTimer = undefined
|
||
|
|
||
|
if (fs[gracefulQueue].length === 0)
|
||
|
return
|
||
|
|
||
|
var elem = fs[gracefulQueue].shift()
|
||
|
var fn = elem[0]
|
||
|
var args = elem[1]
|
||
|
// these items may be unset if they were added by an older graceful-fs
|
||
|
var err = elem[2]
|
||
|
var startTime = elem[3]
|
||
|
var lastTime = elem[4]
|
||
|
|
||
|
// if we don't have a startTime we have no way of knowing if we've waited
|
||
|
// long enough, so go ahead and retry this item now
|
||
|
if (startTime === undefined) {
|
||
|
debug('RETRY', fn.name, args)
|
||
|
fn.apply(null, args)
|
||
|
} else if (Date.now() - startTime >= 60000) {
|
||
|
// it's been more than 60 seconds total, bail now
|
||
|
debug('TIMEOUT', fn.name, args)
|
||
|
var cb = args.pop()
|
||
|
if (typeof cb === 'function')
|
||
|
cb.call(null, err)
|
||
|
} else {
|
||
|
// the amount of time between the last attempt and right now
|
||
|
var sinceAttempt = Date.now() - lastTime
|
||
|
// the amount of time between when we first tried, and when we last tried
|
||
|
// rounded up to at least 1
|
||
|
var sinceStart = Math.max(lastTime - startTime, 1)
|
||
|
// backoff. wait longer than the total time we've been retrying, but only
|
||
|
// up to a maximum of 100ms
|
||
|
var desiredDelay = Math.min(sinceStart * 1.2, 100)
|
||
|
// it's been long enough since the last retry, do it again
|
||
|
if (sinceAttempt >= desiredDelay) {
|
||
|
debug('RETRY', fn.name, args)
|
||
|
fn.apply(null, args.concat([startTime]))
|
||
|
} else {
|
||
|
// if we can't do this job yet, push it to the end of the queue
|
||
|
// and let the next iteration check again
|
||
|
fs[gracefulQueue].push(elem)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// schedule our next run if one isn't already scheduled
|
||
|
if (retryTimer === undefined) {
|
||
|
retryTimer = setTimeout(retry, 0)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 40 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
var constants = __webpack_require__(41)
|
||
|
|
||
|
var origCwd = process.cwd
|
||
|
var cwd = null
|
||
|
|
||
|
var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform
|
||
|
|
||
|
process.cwd = function() {
|
||
|
if (!cwd)
|
||
|
cwd = origCwd.call(process)
|
||
|
return cwd
|
||
|
}
|
||
|
try {
|
||
|
process.cwd()
|
||
|
} catch (er) {}
|
||
|
|
||
|
// This check is needed until node.js 12 is required
|
||
|
if (typeof process.chdir === 'function') {
|
||
|
var chdir = process.chdir
|
||
|
process.chdir = function (d) {
|
||
|
cwd = null
|
||
|
chdir.call(process, d)
|
||
|
}
|
||
|
if (Object.setPrototypeOf) Object.setPrototypeOf(process.chdir, chdir)
|
||
|
}
|
||
|
|
||
|
module.exports = patch
|
||
|
|
||
|
function patch (fs) {
|
||
|
// (re-)implement some things that are known busted or missing.
|
||
|
|
||
|
// lchmod, broken prior to 0.6.2
|
||
|
// back-port the fix here.
|
||
|
if (constants.hasOwnProperty('O_SYMLINK') &&
|
||
|
process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
|
||
|
patchLchmod(fs)
|
||
|
}
|
||
|
|
||
|
// lutimes implementation, or no-op
|
||
|
if (!fs.lutimes) {
|
||
|
patchLutimes(fs)
|
||
|
}
|
||
|
|
||
|
// https://github.com/isaacs/node-graceful-fs/issues/4
|
||
|
// Chown should not fail on einval or eperm if non-root.
|
||
|
// It should not fail on enosys ever, as this just indicates
|
||
|
// that a fs doesn't support the intended operation.
|
||
|
|
||
|
fs.chown = chownFix(fs.chown)
|
||
|
fs.fchown = chownFix(fs.fchown)
|
||
|
fs.lchown = chownFix(fs.lchown)
|
||
|
|
||
|
fs.chmod = chmodFix(fs.chmod)
|
||
|
fs.fchmod = chmodFix(fs.fchmod)
|
||
|
fs.lchmod = chmodFix(fs.lchmod)
|
||
|
|
||
|
fs.chownSync = chownFixSync(fs.chownSync)
|
||
|
fs.fchownSync = chownFixSync(fs.fchownSync)
|
||
|
fs.lchownSync = chownFixSync(fs.lchownSync)
|
||
|
|
||
|
fs.chmodSync = chmodFixSync(fs.chmodSync)
|
||
|
fs.fchmodSync = chmodFixSync(fs.fchmodSync)
|
||
|
fs.lchmodSync = chmodFixSync(fs.lchmodSync)
|
||
|
|
||
|
fs.stat = statFix(fs.stat)
|
||
|
fs.fstat = statFix(fs.fstat)
|
||
|
fs.lstat = statFix(fs.lstat)
|
||
|
|
||
|
fs.statSync = statFixSync(fs.statSync)
|
||
|
fs.fstatSync = statFixSync(fs.fstatSync)
|
||
|
fs.lstatSync = statFixSync(fs.lstatSync)
|
||
|
|
||
|
// if lchmod/lchown do not exist, then make them no-ops
|
||
|
if (fs.chmod && !fs.lchmod) {
|
||
|
fs.lchmod = function (path, mode, cb) {
|
||
|
if (cb) process.nextTick(cb)
|
||
|
}
|
||
|
fs.lchmodSync = function () {}
|
||
|
}
|
||
|
if (fs.chown && !fs.lchown) {
|
||
|
fs.lchown = function (path, uid, gid, cb) {
|
||
|
if (cb) process.nextTick(cb)
|
||
|
}
|
||
|
fs.lchownSync = function () {}
|
||
|
}
|
||
|
|
||
|
// on Windows, A/V software can lock the directory, causing this
|
||
|
// to fail with an EACCES or EPERM if the directory contains newly
|
||
|
// created files. Try again on failure, for up to 60 seconds.
|
||
|
|
||
|
// Set the timeout this long because some Windows Anti-Virus, such as Parity
|
||
|
// bit9, may lock files for up to a minute, causing npm package install
|
||
|
// failures. Also, take care to yield the scheduler. Windows scheduling gives
|
||
|
// CPU to a busy looping process, which can cause the program causing the lock
|
||
|
// contention to be starved of CPU by node, so the contention doesn't resolve.
|
||
|
if (platform === "win32") {
|
||
|
fs.rename = typeof fs.rename !== 'function' ? fs.rename
|
||
|
: (function (fs$rename) {
|
||
|
function rename (from, to, cb) {
|
||
|
var start = Date.now()
|
||
|
var backoff = 0;
|
||
|
fs$rename(from, to, function CB (er) {
|
||
|
if (er
|
||
|
&& (er.code === "EACCES" || er.code === "EPERM")
|
||
|
&& Date.now() - start < 60000) {
|
||
|
setTimeout(function() {
|
||
|
fs.stat(to, function (stater, st) {
|
||
|
if (stater && stater.code === "ENOENT")
|
||
|
fs$rename(from, to, CB);
|
||
|
else
|
||
|
cb(er)
|
||
|
})
|
||
|
}, backoff)
|
||
|
if (backoff < 100)
|
||
|
backoff += 10;
|
||
|
return;
|
||
|
}
|
||
|
if (cb) cb(er)
|
||
|
})
|
||
|
}
|
||
|
if (Object.setPrototypeOf) Object.setPrototypeOf(rename, fs$rename)
|
||
|
return rename
|
||
|
})(fs.rename)
|
||
|
}
|
||
|
|
||
|
// if read() returns EAGAIN, then just try it again.
|
||
|
fs.read = typeof fs.read !== 'function' ? fs.read
|
||
|
: (function (fs$read) {
|
||
|
function read (fd, buffer, offset, length, position, callback_) {
|
||
|
var callback
|
||
|
if (callback_ && typeof callback_ === 'function') {
|
||
|
var eagCounter = 0
|
||
|
callback = function (er, _, __) {
|
||
|
if (er && er.code === 'EAGAIN' && eagCounter < 10) {
|
||
|
eagCounter ++
|
||
|
return fs$read.call(fs, fd, buffer, offset, length, position, callback)
|
||
|
}
|
||
|
callback_.apply(this, arguments)
|
||
|
}
|
||
|
}
|
||
|
return fs$read.call(fs, fd, buffer, offset, length, position, callback)
|
||
|
}
|
||
|
|
||
|
// This ensures `util.promisify` works as it does for native `fs.read`.
|
||
|
if (Object.setPrototypeOf) Object.setPrototypeOf(read, fs$read)
|
||
|
return read
|
||
|
})(fs.read)
|
||
|
|
||
|
fs.readSync = typeof fs.readSync !== 'function' ? fs.readSync
|
||
|
: (function (fs$readSync) { return function (fd, buffer, offset, length, position) {
|
||
|
var eagCounter = 0
|
||
|
while (true) {
|
||
|
try {
|
||
|
return fs$readSync.call(fs, fd, buffer, offset, length, position)
|
||
|
} catch (er) {
|
||
|
if (er.code === 'EAGAIN' && eagCounter < 10) {
|
||
|
eagCounter ++
|
||
|
continue
|
||
|
}
|
||
|
throw er
|
||
|
}
|
||
|
}
|
||
|
}})(fs.readSync)
|
||
|
|
||
|
function patchLchmod (fs) {
|
||
|
fs.lchmod = function (path, mode, callback) {
|
||
|
fs.open( path
|
||
|
, constants.O_WRONLY | constants.O_SYMLINK
|
||
|
, mode
|
||
|
, function (err, fd) {
|
||
|
if (err) {
|
||
|
if (callback) callback(err)
|
||
|
return
|
||
|
}
|
||
|
// prefer to return the chmod error, if one occurs,
|
||
|
// but still try to close, and report closing errors if they occur.
|
||
|
fs.fchmod(fd, mode, function (err) {
|
||
|
fs.close(fd, function(err2) {
|
||
|
if (callback) callback(err || err2)
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
fs.lchmodSync = function (path, mode) {
|
||
|
var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
|
||
|
|
||
|
// prefer to return the chmod error, if one occurs,
|
||
|
// but still try to close, and report closing errors if they occur.
|
||
|
var threw = true
|
||
|
var ret
|
||
|
try {
|
||
|
ret = fs.fchmodSync(fd, mode)
|
||
|
threw = false
|
||
|
} finally {
|
||
|
if (threw) {
|
||
|
try {
|
||
|
fs.closeSync(fd)
|
||
|
} catch (er) {}
|
||
|
} else {
|
||
|
fs.closeSync(fd)
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function patchLutimes (fs) {
|
||
|
if (constants.hasOwnProperty("O_SYMLINK") && fs.futimes) {
|
||
|
fs.lutimes = function (path, at, mt, cb) {
|
||
|
fs.open(path, constants.O_SYMLINK, function (er, fd) {
|
||
|
if (er) {
|
||
|
if (cb) cb(er)
|
||
|
return
|
||
|
}
|
||
|
fs.futimes(fd, at, mt, function (er) {
|
||
|
fs.close(fd, function (er2) {
|
||
|
if (cb) cb(er || er2)
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
fs.lutimesSync = function (path, at, mt) {
|
||
|
var fd = fs.openSync(path, constants.O_SYMLINK)
|
||
|
var ret
|
||
|
var threw = true
|
||
|
try {
|
||
|
ret = fs.futimesSync(fd, at, mt)
|
||
|
threw = false
|
||
|
} finally {
|
||
|
if (threw) {
|
||
|
try {
|
||
|
fs.closeSync(fd)
|
||
|
} catch (er) {}
|
||
|
} else {
|
||
|
fs.closeSync(fd)
|
||
|
}
|
||
|
}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
} else if (fs.futimes) {
|
||
|
fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) }
|
||
|
fs.lutimesSync = function () {}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function chmodFix (orig) {
|
||
|
if (!orig) return orig
|
||
|
return function (target, mode, cb) {
|
||
|
return orig.call(fs, target, mode, function (er) {
|
||
|
if (chownErOk(er)) er = null
|
||
|
if (cb) cb.apply(this, arguments)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function chmodFixSync (orig) {
|
||
|
if (!orig) return orig
|
||
|
return function (target, mode) {
|
||
|
try {
|
||
|
return orig.call(fs, target, mode)
|
||
|
} catch (er) {
|
||
|
if (!chownErOk(er)) throw er
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
function chownFix (orig) {
|
||
|
if (!orig) return orig
|
||
|
return function (target, uid, gid, cb) {
|
||
|
return orig.call(fs, target, uid, gid, function (er) {
|
||
|
if (chownErOk(er)) er = null
|
||
|
if (cb) cb.apply(this, arguments)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function chownFixSync (orig) {
|
||
|
if (!orig) return orig
|
||
|
return function (target, uid, gid) {
|
||
|
try {
|
||
|
return orig.call(fs, target, uid, gid)
|
||
|
} catch (er) {
|
||
|
if (!chownErOk(er)) throw er
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function statFix (orig) {
|
||
|
if (!orig) return orig
|
||
|
// Older versions of Node erroneously returned signed integers for
|
||
|
// uid + gid.
|
||
|
return function (target, options, cb) {
|
||
|
if (typeof options === 'function') {
|
||
|
cb = options
|
||
|
options = null
|
||
|
}
|
||
|
function callback (er, stats) {
|
||
|
if (stats) {
|
||
|
if (stats.uid < 0) stats.uid += 0x100000000
|
||
|
if (stats.gid < 0) stats.gid += 0x100000000
|
||
|
}
|
||
|
if (cb) cb.apply(this, arguments)
|
||
|
}
|
||
|
return options ? orig.call(fs, target, options, callback)
|
||
|
: orig.call(fs, target, callback)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function statFixSync (orig) {
|
||
|
if (!orig) return orig
|
||
|
// Older versions of Node erroneously returned signed integers for
|
||
|
// uid + gid.
|
||
|
return function (target, options) {
|
||
|
var stats = options ? orig.call(fs, target, options)
|
||
|
: orig.call(fs, target)
|
||
|
if (stats) {
|
||
|
if (stats.uid < 0) stats.uid += 0x100000000
|
||
|
if (stats.gid < 0) stats.gid += 0x100000000
|
||
|
}
|
||
|
return stats;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ENOSYS means that the fs doesn't support the op. Just ignore
|
||
|
// that, because it doesn't matter.
|
||
|
//
|
||
|
// if there's no getuid, or if getuid() is something other
|
||
|
// than 0, and the error is EINVAL or EPERM, then just ignore
|
||
|
// it.
|
||
|
//
|
||
|
// This specific case is a silent failure in cp, install, tar,
|
||
|
// and most other unix tools that manage permissions.
|
||
|
//
|
||
|
// When running as root, or if other types of errors are
|
||
|
// encountered, then it's strict.
|
||
|
function chownErOk (er) {
|
||
|
if (!er)
|
||
|
return true
|
||
|
|
||
|
if (er.code === "ENOSYS")
|
||
|
return true
|
||
|
|
||
|
var nonroot = !process.getuid || process.getuid() !== 0
|
||
|
if (nonroot) {
|
||
|
if (er.code === "EINVAL" || er.code === "EPERM")
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 41 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("constants");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 42 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
var Stream = (__webpack_require__(43).Stream)
|
||
|
|
||
|
module.exports = legacy
|
||
|
|
||
|
function legacy (fs) {
|
||
|
return {
|
||
|
ReadStream: ReadStream,
|
||
|
WriteStream: WriteStream
|
||
|
}
|
||
|
|
||
|
function ReadStream (path, options) {
|
||
|
if (!(this instanceof ReadStream)) return new ReadStream(path, options);
|
||
|
|
||
|
Stream.call(this);
|
||
|
|
||
|
var self = this;
|
||
|
|
||
|
this.path = path;
|
||
|
this.fd = null;
|
||
|
this.readable = true;
|
||
|
this.paused = false;
|
||
|
|
||
|
this.flags = 'r';
|
||
|
this.mode = 438; /*=0666*/
|
||
|
this.bufferSize = 64 * 1024;
|
||
|
|
||
|
options = options || {};
|
||
|
|
||
|
// Mixin options into this
|
||
|
var keys = Object.keys(options);
|
||
|
for (var index = 0, length = keys.length; index < length; index++) {
|
||
|
var key = keys[index];
|
||
|
this[key] = options[key];
|
||
|
}
|
||
|
|
||
|
if (this.encoding) this.setEncoding(this.encoding);
|
||
|
|
||
|
if (this.start !== undefined) {
|
||
|
if ('number' !== typeof this.start) {
|
||
|
throw TypeError('start must be a Number');
|
||
|
}
|
||
|
if (this.end === undefined) {
|
||
|
this.end = Infinity;
|
||
|
} else if ('number' !== typeof this.end) {
|
||
|
throw TypeError('end must be a Number');
|
||
|
}
|
||
|
|
||
|
if (this.start > this.end) {
|
||
|
throw new Error('start must be <= end');
|
||
|
}
|
||
|
|
||
|
this.pos = this.start;
|
||
|
}
|
||
|
|
||
|
if (this.fd !== null) {
|
||
|
process.nextTick(function() {
|
||
|
self._read();
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
fs.open(this.path, this.flags, this.mode, function (err, fd) {
|
||
|
if (err) {
|
||
|
self.emit('error', err);
|
||
|
self.readable = false;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
self.fd = fd;
|
||
|
self.emit('open', fd);
|
||
|
self._read();
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function WriteStream (path, options) {
|
||
|
if (!(this instanceof WriteStream)) return new WriteStream(path, options);
|
||
|
|
||
|
Stream.call(this);
|
||
|
|
||
|
this.path = path;
|
||
|
this.fd = null;
|
||
|
this.writable = true;
|
||
|
|
||
|
this.flags = 'w';
|
||
|
this.encoding = 'binary';
|
||
|
this.mode = 438; /*=0666*/
|
||
|
this.bytesWritten = 0;
|
||
|
|
||
|
options = options || {};
|
||
|
|
||
|
// Mixin options into this
|
||
|
var keys = Object.keys(options);
|
||
|
for (var index = 0, length = keys.length; index < length; index++) {
|
||
|
var key = keys[index];
|
||
|
this[key] = options[key];
|
||
|
}
|
||
|
|
||
|
if (this.start !== undefined) {
|
||
|
if ('number' !== typeof this.start) {
|
||
|
throw TypeError('start must be a Number');
|
||
|
}
|
||
|
if (this.start < 0) {
|
||
|
throw new Error('start must be >= zero');
|
||
|
}
|
||
|
|
||
|
this.pos = this.start;
|
||
|
}
|
||
|
|
||
|
this.busy = false;
|
||
|
this._queue = [];
|
||
|
|
||
|
if (this.fd === null) {
|
||
|
this._open = fs.open;
|
||
|
this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
|
||
|
this.flush();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 43 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("stream");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 44 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
module.exports = clone
|
||
|
|
||
|
var getPrototypeOf = Object.getPrototypeOf || function (obj) {
|
||
|
return obj.__proto__
|
||
|
}
|
||
|
|
||
|
function clone (obj) {
|
||
|
if (obj === null || typeof obj !== 'object')
|
||
|
return obj
|
||
|
|
||
|
if (obj instanceof Object)
|
||
|
var copy = { __proto__: getPrototypeOf(obj) }
|
||
|
else
|
||
|
var copy = Object.create(null)
|
||
|
|
||
|
Object.getOwnPropertyNames(obj).forEach(function (key) {
|
||
|
Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key))
|
||
|
})
|
||
|
|
||
|
return copy
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 45 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("assert");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 46 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
var path = __webpack_require__(14);
|
||
|
var fs = __webpack_require__(15);
|
||
|
var _0777 = parseInt('0777', 8);
|
||
|
|
||
|
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
|
||
|
|
||
|
function mkdirP (p, opts, f, made) {
|
||
|
if (typeof opts === 'function') {
|
||
|
f = opts;
|
||
|
opts = {};
|
||
|
}
|
||
|
else if (!opts || typeof opts !== 'object') {
|
||
|
opts = { mode: opts };
|
||
|
}
|
||
|
|
||
|
var mode = opts.mode;
|
||
|
var xfs = opts.fs || fs;
|
||
|
|
||
|
if (mode === undefined) {
|
||
|
mode = _0777
|
||
|
}
|
||
|
if (!made) made = null;
|
||
|
|
||
|
var cb = f || /* istanbul ignore next */ function () {};
|
||
|
p = path.resolve(p);
|
||
|
|
||
|
xfs.mkdir(p, mode, function (er) {
|
||
|
if (!er) {
|
||
|
made = made || p;
|
||
|
return cb(null, made);
|
||
|
}
|
||
|
switch (er.code) {
|
||
|
case 'ENOENT':
|
||
|
/* istanbul ignore if */
|
||
|
if (path.dirname(p) === p) return cb(er);
|
||
|
mkdirP(path.dirname(p), opts, function (er, made) {
|
||
|
/* istanbul ignore if */
|
||
|
if (er) cb(er, made);
|
||
|
else mkdirP(p, opts, cb, made);
|
||
|
});
|
||
|
break;
|
||
|
|
||
|
// In the case of any other error, just see if there's a dir
|
||
|
// there already. If so, then hooray! If not, then something
|
||
|
// is borked.
|
||
|
default:
|
||
|
xfs.stat(p, function (er2, stat) {
|
||
|
// if the stat fails, then that's super weird.
|
||
|
// let the original error be the failure reason.
|
||
|
if (er2 || !stat.isDirectory()) cb(er, made)
|
||
|
else cb(null, made);
|
||
|
});
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
mkdirP.sync = function sync (p, opts, made) {
|
||
|
if (!opts || typeof opts !== 'object') {
|
||
|
opts = { mode: opts };
|
||
|
}
|
||
|
|
||
|
var mode = opts.mode;
|
||
|
var xfs = opts.fs || fs;
|
||
|
|
||
|
if (mode === undefined) {
|
||
|
mode = _0777
|
||
|
}
|
||
|
if (!made) made = null;
|
||
|
|
||
|
p = path.resolve(p);
|
||
|
|
||
|
try {
|
||
|
xfs.mkdirSync(p, mode);
|
||
|
made = made || p;
|
||
|
}
|
||
|
catch (err0) {
|
||
|
switch (err0.code) {
|
||
|
case 'ENOENT' :
|
||
|
made = sync(path.dirname(p), opts, made);
|
||
|
sync(p, opts, made);
|
||
|
break;
|
||
|
|
||
|
// In the case of any other error, just see if there's a dir
|
||
|
// there already. If so, then hooray! If not, then something
|
||
|
// is borked.
|
||
|
default:
|
||
|
var stat;
|
||
|
try {
|
||
|
stat = xfs.statSync(p);
|
||
|
}
|
||
|
catch (err1) /* istanbul ignore next */ {
|
||
|
throw err0;
|
||
|
}
|
||
|
/* istanbul ignore if */
|
||
|
if (!stat.isDirectory()) throw err0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return made;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 47 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.initContextMenu = void 0;
|
||
|
const electron_context_menu_1 = __importDefault(__webpack_require__(48));
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const windowEvents_1 = __webpack_require__(66);
|
||
|
const windowHelpers_1 = __webpack_require__(65);
|
||
|
const model_1 = __webpack_require__(67);
|
||
|
function initContextMenu(options, window) {
|
||
|
log.debug('initContextMenu');
|
||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||
|
(0, electron_context_menu_1.default)({
|
||
|
prepend: (actions, params) => {
|
||
|
log.debug('contextMenu.prepend', { actions, params });
|
||
|
const items = [];
|
||
|
if (params.linkURL) {
|
||
|
items.push({
|
||
|
label: 'Open Link in Default Browser',
|
||
|
click: () => {
|
||
|
(0, helpers_1.openExternal)(params.linkURL).catch((err) => log.error('contextMenu Open Link in Default Browser ERROR', err));
|
||
|
},
|
||
|
});
|
||
|
items.push({
|
||
|
label: 'Open Link in New Window',
|
||
|
click: () => (0, windowHelpers_1.createNewWindow)((0, model_1.outputOptionsToWindowOptions)(options), windowEvents_1.setupNativefierWindow, params.linkURL, window),
|
||
|
});
|
||
|
if ((0, helpers_1.nativeTabsSupported)()) {
|
||
|
items.push({
|
||
|
label: 'Open Link in New Tab',
|
||
|
click: () => {
|
||
|
var _a;
|
||
|
// Fire a new window event for a foreground tab
|
||
|
// Previously we called createNewTab directly, but it had incosistent and buggy behavior
|
||
|
// as it was mostly designed for running off of events. So this will create a new event
|
||
|
// for a foreground-tab for the event handler to grab and take care of instead.
|
||
|
return window.webContents.emit(
|
||
|
// event name
|
||
|
'new-window',
|
||
|
// event object
|
||
|
{
|
||
|
// Leave to the default for a NewWindowWebContentsEvent
|
||
|
newGuest: undefined,
|
||
|
...new Event('new-window'),
|
||
|
},
|
||
|
// url
|
||
|
params.linkURL,
|
||
|
// frameName
|
||
|
(_a = window === null || window === void 0 ? void 0 : window.webContents.mainFrame.name) !== null && _a !== void 0 ? _a : '',
|
||
|
// disposition
|
||
|
'foreground-tab');
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
return items;
|
||
|
},
|
||
|
showCopyImage: true,
|
||
|
showCopyImageAddress: true,
|
||
|
showSaveImage: true,
|
||
|
});
|
||
|
}
|
||
|
exports.initContextMenu = initContextMenu;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 48 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const electron = __webpack_require__(17);
|
||
|
const cliTruncate = __webpack_require__(49);
|
||
|
const {download} = __webpack_require__(18);
|
||
|
const isDev = __webpack_require__(62);
|
||
|
|
||
|
const webContents = win => win.webContents || (win.id && win);
|
||
|
|
||
|
const decorateMenuItem = menuItem => {
|
||
|
return (options = {}) => {
|
||
|
if (options.transform && !options.click) {
|
||
|
menuItem.transform = options.transform;
|
||
|
}
|
||
|
|
||
|
return menuItem;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
const removeUnusedMenuItems = menuTemplate => {
|
||
|
let notDeletedPreviousElement;
|
||
|
|
||
|
return menuTemplate
|
||
|
.filter(menuItem => menuItem !== undefined && menuItem !== false && menuItem.visible !== false && menuItem.visible !== '')
|
||
|
.filter((menuItem, index, array) => {
|
||
|
const toDelete = menuItem.type === 'separator' && (!notDeletedPreviousElement || index === array.length - 1 || array[index + 1].type === 'separator');
|
||
|
notDeletedPreviousElement = toDelete ? notDeletedPreviousElement : menuItem;
|
||
|
return !toDelete;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const create = (win, options) => {
|
||
|
const handleContextMenu = (event, props) => {
|
||
|
if (typeof options.shouldShowMenu === 'function' && options.shouldShowMenu(event, props) === false) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const {editFlags} = props;
|
||
|
const hasText = props.selectionText.length > 0;
|
||
|
const isLink = Boolean(props.linkURL);
|
||
|
const can = type => editFlags[`can${type}`] && hasText;
|
||
|
|
||
|
const defaultActions = {
|
||
|
separator: () => ({type: 'separator'}),
|
||
|
learnSpelling: decorateMenuItem({
|
||
|
id: 'learnSpelling',
|
||
|
label: '&Learn Spelling',
|
||
|
visible: Boolean(props.isEditable && hasText && props.misspelledWord),
|
||
|
click() {
|
||
|
const target = webContents(win);
|
||
|
target.session.addWordToSpellCheckerDictionary(props.misspelledWord);
|
||
|
}
|
||
|
}),
|
||
|
lookUpSelection: decorateMenuItem({
|
||
|
id: 'lookUpSelection',
|
||
|
label: 'Look Up “{selection}”',
|
||
|
visible: process.platform === 'darwin' && hasText && !isLink,
|
||
|
click() {
|
||
|
if (process.platform === 'darwin') {
|
||
|
webContents(win).showDefinitionForSelection();
|
||
|
}
|
||
|
}
|
||
|
}),
|
||
|
searchWithGoogle: decorateMenuItem({
|
||
|
id: 'searchWithGoogle',
|
||
|
label: '&Search with Google',
|
||
|
visible: hasText,
|
||
|
click() {
|
||
|
const url = new URL('https://www.google.com/search');
|
||
|
url.searchParams.set('q', props.selectionText);
|
||
|
electron.shell.openExternal(url.toString());
|
||
|
}
|
||
|
}),
|
||
|
cut: decorateMenuItem({
|
||
|
id: 'cut',
|
||
|
label: 'Cu&t',
|
||
|
enabled: can('Cut'),
|
||
|
visible: props.isEditable,
|
||
|
click(menuItem) {
|
||
|
const target = webContents(win);
|
||
|
|
||
|
if (!menuItem.transform && target) {
|
||
|
target.cut();
|
||
|
} else {
|
||
|
props.selectionText = menuItem.transform ? menuItem.transform(props.selectionText) : props.selectionText;
|
||
|
electron.clipboard.writeText(props.selectionText);
|
||
|
}
|
||
|
}
|
||
|
}),
|
||
|
copy: decorateMenuItem({
|
||
|
id: 'copy',
|
||
|
label: '&Copy',
|
||
|
enabled: can('Copy'),
|
||
|
visible: props.isEditable || hasText,
|
||
|
click(menuItem) {
|
||
|
const target = webContents(win);
|
||
|
|
||
|
if (!menuItem.transform && target) {
|
||
|
target.copy();
|
||
|
} else {
|
||
|
props.selectionText = menuItem.transform ? menuItem.transform(props.selectionText) : props.selectionText;
|
||
|
electron.clipboard.writeText(props.selectionText);
|
||
|
}
|
||
|
}
|
||
|
}),
|
||
|
paste: decorateMenuItem({
|
||
|
id: 'paste',
|
||
|
label: '&Paste',
|
||
|
enabled: editFlags.canPaste,
|
||
|
visible: props.isEditable,
|
||
|
click(menuItem) {
|
||
|
const target = webContents(win);
|
||
|
|
||
|
if (menuItem.transform) {
|
||
|
let clipboardContent = electron.clipboard.readText(props.selectionText);
|
||
|
clipboardContent = menuItem.transform ? menuItem.transform(clipboardContent) : clipboardContent;
|
||
|
target.insertText(clipboardContent);
|
||
|
} else {
|
||
|
target.paste();
|
||
|
}
|
||
|
}
|
||
|
}),
|
||
|
selectAll: decorateMenuItem({
|
||
|
id: 'selectAll',
|
||
|
label: 'Select &All',
|
||
|
click() {
|
||
|
webContents(win).selectAll();
|
||
|
}
|
||
|
}),
|
||
|
saveImage: decorateMenuItem({
|
||
|
id: 'saveImage',
|
||
|
label: 'Save I&mage',
|
||
|
visible: props.mediaType === 'image',
|
||
|
click(menuItem) {
|
||
|
props.srcURL = menuItem.transform ? menuItem.transform(props.srcURL) : props.srcURL;
|
||
|
download(win, props.srcURL);
|
||
|
}
|
||
|
}),
|
||
|
saveImageAs: decorateMenuItem({
|
||
|
id: 'saveImageAs',
|
||
|
label: 'Sa&ve Image As…',
|
||
|
visible: props.mediaType === 'image',
|
||
|
click(menuItem) {
|
||
|
props.srcURL = menuItem.transform ? menuItem.transform(props.srcURL) : props.srcURL;
|
||
|
download(win, props.srcURL, {saveAs: true});
|
||
|
}
|
||
|
}),
|
||
|
saveVideo: decorateMenuItem({
|
||
|
id: 'saveVideo',
|
||
|
label: 'Save Vide&o',
|
||
|
visible: props.mediaType === 'video',
|
||
|
click(menuItem) {
|
||
|
props.srcURL = menuItem.transform ? menuItem.transform(props.srcURL) : props.srcURL;
|
||
|
download(win, props.srcURL);
|
||
|
}
|
||
|
}),
|
||
|
saveVideoAs: decorateMenuItem({
|
||
|
id: 'saveVideoAs',
|
||
|
label: 'Save Video& As…',
|
||
|
visible: props.mediaType === 'video',
|
||
|
click(menuItem) {
|
||
|
props.srcURL = menuItem.transform ? menuItem.transform(props.srcURL) : props.srcURL;
|
||
|
download(win, props.srcURL, {saveAs: true});
|
||
|
}
|
||
|
}),
|
||
|
copyLink: decorateMenuItem({
|
||
|
id: 'copyLink',
|
||
|
label: 'Copy Lin&k',
|
||
|
visible: props.linkURL.length > 0 && props.mediaType === 'none',
|
||
|
click(menuItem) {
|
||
|
props.linkURL = menuItem.transform ? menuItem.transform(props.linkURL) : props.linkURL;
|
||
|
|
||
|
electron.clipboard.write({
|
||
|
bookmark: props.linkText,
|
||
|
text: props.linkURL
|
||
|
});
|
||
|
}
|
||
|
}),
|
||
|
saveLinkAs: decorateMenuItem({
|
||
|
id: 'saveLinkAs',
|
||
|
label: 'Save Link As…',
|
||
|
visible: props.linkURL.length > 0 && props.mediaType === 'none',
|
||
|
click(menuItem) {
|
||
|
props.linkURL = menuItem.transform ? menuItem.transform(props.linkURL) : props.linkURL;
|
||
|
download(win, props.linkURL, {saveAs: true});
|
||
|
}
|
||
|
}),
|
||
|
copyImage: decorateMenuItem({
|
||
|
id: 'copyImage',
|
||
|
label: 'Cop&y Image',
|
||
|
visible: props.mediaType === 'image',
|
||
|
click() {
|
||
|
webContents(win).copyImageAt(props.x, props.y);
|
||
|
}
|
||
|
}),
|
||
|
copyImageAddress: decorateMenuItem({
|
||
|
id: 'copyImageAddress',
|
||
|
label: 'C&opy Image Address',
|
||
|
visible: props.mediaType === 'image',
|
||
|
click(menuItem) {
|
||
|
props.srcURL = menuItem.transform ? menuItem.transform(props.srcURL) : props.srcURL;
|
||
|
|
||
|
electron.clipboard.write({
|
||
|
bookmark: props.srcURL,
|
||
|
text: props.srcURL
|
||
|
});
|
||
|
}
|
||
|
}),
|
||
|
copyVideoAddress: decorateMenuItem({
|
||
|
id: 'copyVideoAddress',
|
||
|
label: 'Copy Video Ad&dress',
|
||
|
visible: props.mediaType === 'video',
|
||
|
click(menuItem) {
|
||
|
props.srcURL = menuItem.transform ? menuItem.transform(props.srcURL) : props.srcURL;
|
||
|
|
||
|
electron.clipboard.write({
|
||
|
bookmark: props.srcURL,
|
||
|
text: props.srcURL
|
||
|
});
|
||
|
}
|
||
|
}),
|
||
|
inspect: () => ({
|
||
|
id: 'inspect',
|
||
|
label: 'I&nspect Element',
|
||
|
click() {
|
||
|
win.inspectElement(props.x, props.y);
|
||
|
|
||
|
if (webContents(win).isDevToolsOpened()) {
|
||
|
webContents(win).devToolsWebContents.focus();
|
||
|
}
|
||
|
}
|
||
|
}),
|
||
|
services: () => ({
|
||
|
id: 'services',
|
||
|
label: 'Services',
|
||
|
role: 'services',
|
||
|
visible: process.platform === 'darwin' && (props.isEditable || hasText)
|
||
|
})
|
||
|
};
|
||
|
|
||
|
const shouldShowInspectElement = typeof options.showInspectElement === 'boolean' ? options.showInspectElement : isDev;
|
||
|
const shouldShowSelectAll = options.showSelectAll || (options.showSelectAll !== false && process.platform !== 'darwin');
|
||
|
|
||
|
function word(suggestion) {
|
||
|
return {
|
||
|
id: 'dictionarySuggestions',
|
||
|
label: suggestion,
|
||
|
visible: Boolean(props.isEditable && hasText && props.misspelledWord),
|
||
|
click(menuItem) {
|
||
|
const target = webContents(win);
|
||
|
target.replaceMisspelling(menuItem.label);
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
let dictionarySuggestions = [];
|
||
|
if (hasText && props.misspelledWord && props.dictionarySuggestions.length > 0) {
|
||
|
dictionarySuggestions = props.dictionarySuggestions.map(suggestion => word(suggestion));
|
||
|
} else {
|
||
|
dictionarySuggestions.push(
|
||
|
{
|
||
|
id: 'dictionarySuggestions',
|
||
|
label: 'No Guesses Found',
|
||
|
visible: Boolean(hasText && props.misspelledWord),
|
||
|
enabled: false
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
|
||
|
let menuTemplate = [
|
||
|
dictionarySuggestions.length > 0 && defaultActions.separator(),
|
||
|
...dictionarySuggestions,
|
||
|
defaultActions.separator(),
|
||
|
options.showLearnSpelling !== false && defaultActions.learnSpelling(),
|
||
|
defaultActions.separator(),
|
||
|
options.showLookUpSelection !== false && defaultActions.lookUpSelection(),
|
||
|
defaultActions.separator(),
|
||
|
options.showSearchWithGoogle !== false && defaultActions.searchWithGoogle(),
|
||
|
defaultActions.separator(),
|
||
|
defaultActions.cut(),
|
||
|
defaultActions.copy(),
|
||
|
defaultActions.paste(),
|
||
|
shouldShowSelectAll && defaultActions.selectAll(),
|
||
|
defaultActions.separator(),
|
||
|
options.showSaveImage && defaultActions.saveImage(),
|
||
|
options.showSaveImageAs && defaultActions.saveImageAs(),
|
||
|
options.showCopyImage !== false && defaultActions.copyImage(),
|
||
|
options.showCopyImageAddress && defaultActions.copyImageAddress(),
|
||
|
options.showSaveVideo && defaultActions.saveVideo(),
|
||
|
options.showSaveVideoAs && defaultActions.saveVideoAs(),
|
||
|
options.showCopyVideoAddress && defaultActions.copyVideoAddress(),
|
||
|
defaultActions.separator(),
|
||
|
options.showCopyLink !== false && defaultActions.copyLink(),
|
||
|
options.showSaveLinkAs && defaultActions.saveLinkAs(),
|
||
|
defaultActions.separator(),
|
||
|
shouldShowInspectElement && defaultActions.inspect(),
|
||
|
options.showServices && defaultActions.services(),
|
||
|
defaultActions.separator()
|
||
|
];
|
||
|
|
||
|
if (options.menu) {
|
||
|
menuTemplate = options.menu(defaultActions, props, win, dictionarySuggestions, event);
|
||
|
}
|
||
|
|
||
|
if (options.prepend) {
|
||
|
const result = options.prepend(defaultActions, props, win, event);
|
||
|
|
||
|
if (Array.isArray(result)) {
|
||
|
menuTemplate.unshift(...result);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (options.append) {
|
||
|
const result = options.append(defaultActions, props, win, event);
|
||
|
|
||
|
if (Array.isArray(result)) {
|
||
|
menuTemplate.push(...result);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Filter out leading/trailing separators
|
||
|
// TODO: https://github.com/electron/electron/issues/5869
|
||
|
menuTemplate = removeUnusedMenuItems(menuTemplate);
|
||
|
|
||
|
for (const menuItem of menuTemplate) {
|
||
|
// Apply custom labels for default menu items
|
||
|
if (options.labels && options.labels[menuItem.id]) {
|
||
|
menuItem.label = options.labels[menuItem.id];
|
||
|
}
|
||
|
|
||
|
// Replace placeholders in menu item labels
|
||
|
if (typeof menuItem.label === 'string' && menuItem.label.includes('{selection}')) {
|
||
|
const selectionString = typeof props.selectionText === 'string' ? props.selectionText.trim() : '';
|
||
|
menuItem.label = menuItem.label.replace('{selection}', cliTruncate(selectionString, 25).replace(/&/g, '&&'));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (menuTemplate.length > 0) {
|
||
|
const menu = electron.Menu.buildFromTemplate(menuTemplate);
|
||
|
|
||
|
if (typeof options.onShow === 'function') {
|
||
|
menu.on('menu-will-show', options.onShow);
|
||
|
}
|
||
|
|
||
|
if (typeof options.onClose === 'function') {
|
||
|
menu.on('menu-will-close', options.onClose);
|
||
|
}
|
||
|
|
||
|
menu.popup(win);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
webContents(win).on('context-menu', handleContextMenu);
|
||
|
|
||
|
return () => {
|
||
|
if (win.isDestroyed()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
webContents(win).removeListener('context-menu', handleContextMenu);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
module.exports = (options = {}) => {
|
||
|
if (process.type === 'renderer') {
|
||
|
throw new Error('Cannot use electron-context-menu in the renderer process!');
|
||
|
}
|
||
|
|
||
|
let isDisposed = false;
|
||
|
const disposables = [];
|
||
|
|
||
|
const init = win => {
|
||
|
if (isDisposed) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const disposeMenu = create(win, options);
|
||
|
|
||
|
disposables.push(disposeMenu);
|
||
|
const removeDisposable = () => {
|
||
|
const index = disposables.indexOf(disposeMenu);
|
||
|
if (index !== -1) {
|
||
|
disposables.splice(index, 1);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
if (typeof win.once !== 'undefined') { // Support for BrowserView
|
||
|
win.once('closed', removeDisposable);
|
||
|
}
|
||
|
|
||
|
disposables.push(() => {
|
||
|
win.off('closed', removeDisposable);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const dispose = () => {
|
||
|
for (const dispose of disposables) {
|
||
|
dispose();
|
||
|
}
|
||
|
|
||
|
disposables.length = 0;
|
||
|
isDisposed = true;
|
||
|
};
|
||
|
|
||
|
if (options.window) {
|
||
|
const win = options.window;
|
||
|
|
||
|
// When window is a webview that has not yet finished loading webContents is not available
|
||
|
if (webContents(win) === undefined) {
|
||
|
const onDomReady = () => {
|
||
|
init(win);
|
||
|
};
|
||
|
|
||
|
const listenerFunction = win.addEventListener || win.addListener;
|
||
|
listenerFunction('dom-ready', onDomReady, {once: true});
|
||
|
|
||
|
disposables.push(() => {
|
||
|
win.removeEventListener('dom-ready', onDomReady, {once: true});
|
||
|
});
|
||
|
|
||
|
return dispose;
|
||
|
}
|
||
|
|
||
|
init(win);
|
||
|
|
||
|
return dispose;
|
||
|
}
|
||
|
|
||
|
for (const win of electron.BrowserWindow.getAllWindows()) {
|
||
|
init(win);
|
||
|
}
|
||
|
|
||
|
const onWindowCreated = (event, win) => {
|
||
|
init(win);
|
||
|
};
|
||
|
|
||
|
electron.app.on('browser-window-created', onWindowCreated);
|
||
|
disposables.push(() => {
|
||
|
electron.app.removeListener('browser-window-created', onWindowCreated);
|
||
|
});
|
||
|
|
||
|
return dispose;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 49 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const sliceAnsi = __webpack_require__(50);
|
||
|
const stringWidth = __webpack_require__(58);
|
||
|
|
||
|
function getIndexOfNearestSpace(string, index, shouldSearchRight) {
|
||
|
if (string.charAt(index) === ' ') {
|
||
|
return index;
|
||
|
}
|
||
|
|
||
|
for (let i = 1; i <= 3; i++) {
|
||
|
if (shouldSearchRight) {
|
||
|
if (string.charAt(index + i) === ' ') {
|
||
|
return index + i;
|
||
|
}
|
||
|
} else if (string.charAt(index - i) === ' ') {
|
||
|
return index - i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return index;
|
||
|
}
|
||
|
|
||
|
module.exports = (text, columns, options) => {
|
||
|
options = {
|
||
|
position: 'end',
|
||
|
preferTruncationOnSpace: false,
|
||
|
...options
|
||
|
};
|
||
|
|
||
|
const {position, space, preferTruncationOnSpace} = options;
|
||
|
let ellipsis = '…';
|
||
|
let ellipsisWidth = 1;
|
||
|
|
||
|
if (typeof text !== 'string') {
|
||
|
throw new TypeError(`Expected \`input\` to be a string, got ${typeof text}`);
|
||
|
}
|
||
|
|
||
|
if (typeof columns !== 'number') {
|
||
|
throw new TypeError(`Expected \`columns\` to be a number, got ${typeof columns}`);
|
||
|
}
|
||
|
|
||
|
if (columns < 1) {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
if (columns === 1) {
|
||
|
return ellipsis;
|
||
|
}
|
||
|
|
||
|
const length = stringWidth(text);
|
||
|
|
||
|
if (length <= columns) {
|
||
|
return text;
|
||
|
}
|
||
|
|
||
|
if (position === 'start') {
|
||
|
if (preferTruncationOnSpace) {
|
||
|
const nearestSpace = getIndexOfNearestSpace(text, length - columns + 1, true);
|
||
|
return ellipsis + sliceAnsi(text, nearestSpace, length).trim();
|
||
|
}
|
||
|
|
||
|
if (space === true) {
|
||
|
ellipsis += ' ';
|
||
|
ellipsisWidth = 2;
|
||
|
}
|
||
|
|
||
|
return ellipsis + sliceAnsi(text, length - columns + ellipsisWidth, length);
|
||
|
}
|
||
|
|
||
|
if (position === 'middle') {
|
||
|
if (space === true) {
|
||
|
ellipsis = ' ' + ellipsis + ' ';
|
||
|
ellipsisWidth = 3;
|
||
|
}
|
||
|
|
||
|
const half = Math.floor(columns / 2);
|
||
|
|
||
|
if (preferTruncationOnSpace) {
|
||
|
const spaceNearFirstBreakPoint = getIndexOfNearestSpace(text, half);
|
||
|
const spaceNearSecondBreakPoint = getIndexOfNearestSpace(text, length - (columns - half) + 1, true);
|
||
|
return sliceAnsi(text, 0, spaceNearFirstBreakPoint) + ellipsis + sliceAnsi(text, spaceNearSecondBreakPoint, length).trim();
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
sliceAnsi(text, 0, half) +
|
||
|
ellipsis +
|
||
|
sliceAnsi(text, length - (columns - half) + ellipsisWidth, length)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if (position === 'end') {
|
||
|
if (preferTruncationOnSpace) {
|
||
|
const nearestSpace = getIndexOfNearestSpace(text, columns - 1);
|
||
|
return sliceAnsi(text, 0, nearestSpace) + ellipsis;
|
||
|
}
|
||
|
|
||
|
if (space === true) {
|
||
|
ellipsis = ' ' + ellipsis;
|
||
|
ellipsisWidth = 2;
|
||
|
}
|
||
|
|
||
|
return sliceAnsi(text, 0, columns - ellipsisWidth) + ellipsis;
|
||
|
}
|
||
|
|
||
|
throw new Error(`Expected \`options.position\` to be either \`start\`, \`middle\` or \`end\`, got ${position}`);
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 50 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const isFullwidthCodePoint = __webpack_require__(51);
|
||
|
const astralRegex = __webpack_require__(52);
|
||
|
const ansiStyles = __webpack_require__(53);
|
||
|
|
||
|
const ESCAPES = [
|
||
|
'\u001B',
|
||
|
'\u009B'
|
||
|
];
|
||
|
|
||
|
const wrapAnsi = code => `${ESCAPES[0]}[${code}m`;
|
||
|
|
||
|
const checkAnsi = (ansiCodes, isEscapes, endAnsiCode) => {
|
||
|
let output = [];
|
||
|
ansiCodes = [...ansiCodes];
|
||
|
|
||
|
for (let ansiCode of ansiCodes) {
|
||
|
const ansiCodeOrigin = ansiCode;
|
||
|
if (ansiCode.match(';')) {
|
||
|
ansiCode = ansiCode.split(';')[0][0] + '0';
|
||
|
}
|
||
|
|
||
|
const item = ansiStyles.codes.get(parseInt(ansiCode, 10));
|
||
|
if (item) {
|
||
|
const indexEscape = ansiCodes.indexOf(item.toString());
|
||
|
if (indexEscape >= 0) {
|
||
|
ansiCodes.splice(indexEscape, 1);
|
||
|
} else {
|
||
|
output.push(wrapAnsi(isEscapes ? item : ansiCodeOrigin));
|
||
|
}
|
||
|
} else if (isEscapes) {
|
||
|
output.push(wrapAnsi(0));
|
||
|
break;
|
||
|
} else {
|
||
|
output.push(wrapAnsi(ansiCodeOrigin));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (isEscapes) {
|
||
|
output = output.filter((element, index) => output.indexOf(element) === index);
|
||
|
if (endAnsiCode !== undefined) {
|
||
|
const fistEscapeCode = wrapAnsi(ansiStyles.codes.get(parseInt(endAnsiCode, 10)));
|
||
|
output = output.reduce((current, next) => next === fistEscapeCode ? [next, ...current] : [...current, next], []);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return output.join('');
|
||
|
};
|
||
|
|
||
|
module.exports = (string, begin, end) => {
|
||
|
const characters = [...string.normalize()];
|
||
|
const ansiCodes = [];
|
||
|
|
||
|
end = typeof end === 'number' ? end : characters.length;
|
||
|
|
||
|
let isInsideEscape = false;
|
||
|
let ansiCode;
|
||
|
let visible = 0;
|
||
|
let output = '';
|
||
|
|
||
|
for (const [index, character] of characters.entries()) {
|
||
|
let leftEscape = false;
|
||
|
|
||
|
if (ESCAPES.includes(character)) {
|
||
|
const code = /\d[^m]*/.exec(string.slice(index, index + 18));
|
||
|
ansiCode = code && code.length > 0 ? code[0] : undefined;
|
||
|
if (visible < end) {
|
||
|
isInsideEscape = true;
|
||
|
if (ansiCode !== undefined) {
|
||
|
ansiCodes.push(ansiCode);
|
||
|
}
|
||
|
}
|
||
|
} else if (isInsideEscape && character === 'm') {
|
||
|
isInsideEscape = false;
|
||
|
leftEscape = true;
|
||
|
}
|
||
|
|
||
|
if (!isInsideEscape && !leftEscape) {
|
||
|
++visible;
|
||
|
}
|
||
|
|
||
|
if (!astralRegex({exact: true}).test(character) && isFullwidthCodePoint(character.codePointAt())) {
|
||
|
++visible;
|
||
|
}
|
||
|
|
||
|
if (visible > begin && visible <= end) {
|
||
|
output += character;
|
||
|
} else if (visible === begin && !isInsideEscape && ansiCode !== undefined) {
|
||
|
output = checkAnsi(ansiCodes);
|
||
|
} else if (visible >= end) {
|
||
|
output += checkAnsi(ansiCodes, true, ansiCode);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return output;
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 51 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
/* eslint-disable yoda */
|
||
|
|
||
|
|
||
|
const isFullwidthCodePoint = codePoint => {
|
||
|
if (Number.isNaN(codePoint)) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Code points are derived from:
|
||
|
// http://www.unix.org/Public/UNIDATA/EastAsianWidth.txt
|
||
|
if (
|
||
|
codePoint >= 0x1100 && (
|
||
|
codePoint <= 0x115F || // Hangul Jamo
|
||
|
codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET
|
||
|
codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET
|
||
|
// CJK Radicals Supplement .. Enclosed CJK Letters and Months
|
||
|
(0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) ||
|
||
|
// Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A
|
||
|
(0x3250 <= codePoint && codePoint <= 0x4DBF) ||
|
||
|
// CJK Unified Ideographs .. Yi Radicals
|
||
|
(0x4E00 <= codePoint && codePoint <= 0xA4C6) ||
|
||
|
// Hangul Jamo Extended-A
|
||
|
(0xA960 <= codePoint && codePoint <= 0xA97C) ||
|
||
|
// Hangul Syllables
|
||
|
(0xAC00 <= codePoint && codePoint <= 0xD7A3) ||
|
||
|
// CJK Compatibility Ideographs
|
||
|
(0xF900 <= codePoint && codePoint <= 0xFAFF) ||
|
||
|
// Vertical Forms
|
||
|
(0xFE10 <= codePoint && codePoint <= 0xFE19) ||
|
||
|
// CJK Compatibility Forms .. Small Form Variants
|
||
|
(0xFE30 <= codePoint && codePoint <= 0xFE6B) ||
|
||
|
// Halfwidth and Fullwidth Forms
|
||
|
(0xFF01 <= codePoint && codePoint <= 0xFF60) ||
|
||
|
(0xFFE0 <= codePoint && codePoint <= 0xFFE6) ||
|
||
|
// Kana Supplement
|
||
|
(0x1B000 <= codePoint && codePoint <= 0x1B001) ||
|
||
|
// Enclosed Ideographic Supplement
|
||
|
(0x1F200 <= codePoint && codePoint <= 0x1F251) ||
|
||
|
// CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane
|
||
|
(0x20000 <= codePoint && codePoint <= 0x3FFFD)
|
||
|
)
|
||
|
) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
module.exports = isFullwidthCodePoint;
|
||
|
module.exports["default"] = isFullwidthCodePoint;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 52 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const regex = '[\uD800-\uDBFF][\uDC00-\uDFFF]';
|
||
|
|
||
|
const astralRegex = options => options && options.exact ? new RegExp(`^${regex}$`) : new RegExp(regex, 'g');
|
||
|
|
||
|
module.exports = astralRegex;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 53 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
/* module decorator */ module = __webpack_require__.nmd(module);
|
||
|
|
||
|
|
||
|
const wrapAnsi16 = (fn, offset) => (...args) => {
|
||
|
const code = fn(...args);
|
||
|
return `\u001B[${code + offset}m`;
|
||
|
};
|
||
|
|
||
|
const wrapAnsi256 = (fn, offset) => (...args) => {
|
||
|
const code = fn(...args);
|
||
|
return `\u001B[${38 + offset};5;${code}m`;
|
||
|
};
|
||
|
|
||
|
const wrapAnsi16m = (fn, offset) => (...args) => {
|
||
|
const rgb = fn(...args);
|
||
|
return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
|
||
|
};
|
||
|
|
||
|
const ansi2ansi = n => n;
|
||
|
const rgb2rgb = (r, g, b) => [r, g, b];
|
||
|
|
||
|
const setLazyProperty = (object, property, get) => {
|
||
|
Object.defineProperty(object, property, {
|
||
|
get: () => {
|
||
|
const value = get();
|
||
|
|
||
|
Object.defineProperty(object, property, {
|
||
|
value,
|
||
|
enumerable: true,
|
||
|
configurable: true
|
||
|
});
|
||
|
|
||
|
return value;
|
||
|
},
|
||
|
enumerable: true,
|
||
|
configurable: true
|
||
|
});
|
||
|
};
|
||
|
|
||
|
/** @type {typeof import('color-convert')} */
|
||
|
let colorConvert;
|
||
|
const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
|
||
|
if (colorConvert === undefined) {
|
||
|
colorConvert = __webpack_require__(54);
|
||
|
}
|
||
|
|
||
|
const offset = isBackground ? 10 : 0;
|
||
|
const styles = {};
|
||
|
|
||
|
for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
|
||
|
const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace;
|
||
|
if (sourceSpace === targetSpace) {
|
||
|
styles[name] = wrap(identity, offset);
|
||
|
} else if (typeof suite === 'object') {
|
||
|
styles[name] = wrap(suite[targetSpace], offset);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return styles;
|
||
|
};
|
||
|
|
||
|
function assembleStyles() {
|
||
|
const codes = new Map();
|
||
|
const styles = {
|
||
|
modifier: {
|
||
|
reset: [0, 0],
|
||
|
// 21 isn't widely supported and 22 does the same thing
|
||
|
bold: [1, 22],
|
||
|
dim: [2, 22],
|
||
|
italic: [3, 23],
|
||
|
underline: [4, 24],
|
||
|
inverse: [7, 27],
|
||
|
hidden: [8, 28],
|
||
|
strikethrough: [9, 29]
|
||
|
},
|
||
|
color: {
|
||
|
black: [30, 39],
|
||
|
red: [31, 39],
|
||
|
green: [32, 39],
|
||
|
yellow: [33, 39],
|
||
|
blue: [34, 39],
|
||
|
magenta: [35, 39],
|
||
|
cyan: [36, 39],
|
||
|
white: [37, 39],
|
||
|
|
||
|
// Bright color
|
||
|
blackBright: [90, 39],
|
||
|
redBright: [91, 39],
|
||
|
greenBright: [92, 39],
|
||
|
yellowBright: [93, 39],
|
||
|
blueBright: [94, 39],
|
||
|
magentaBright: [95, 39],
|
||
|
cyanBright: [96, 39],
|
||
|
whiteBright: [97, 39]
|
||
|
},
|
||
|
bgColor: {
|
||
|
bgBlack: [40, 49],
|
||
|
bgRed: [41, 49],
|
||
|
bgGreen: [42, 49],
|
||
|
bgYellow: [43, 49],
|
||
|
bgBlue: [44, 49],
|
||
|
bgMagenta: [45, 49],
|
||
|
bgCyan: [46, 49],
|
||
|
bgWhite: [47, 49],
|
||
|
|
||
|
// Bright color
|
||
|
bgBlackBright: [100, 49],
|
||
|
bgRedBright: [101, 49],
|
||
|
bgGreenBright: [102, 49],
|
||
|
bgYellowBright: [103, 49],
|
||
|
bgBlueBright: [104, 49],
|
||
|
bgMagentaBright: [105, 49],
|
||
|
bgCyanBright: [106, 49],
|
||
|
bgWhiteBright: [107, 49]
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Alias bright black as gray (and grey)
|
||
|
styles.color.gray = styles.color.blackBright;
|
||
|
styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
|
||
|
styles.color.grey = styles.color.blackBright;
|
||
|
styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;
|
||
|
|
||
|
for (const [groupName, group] of Object.entries(styles)) {
|
||
|
for (const [styleName, style] of Object.entries(group)) {
|
||
|
styles[styleName] = {
|
||
|
open: `\u001B[${style[0]}m`,
|
||
|
close: `\u001B[${style[1]}m`
|
||
|
};
|
||
|
|
||
|
group[styleName] = styles[styleName];
|
||
|
|
||
|
codes.set(style[0], style[1]);
|
||
|
}
|
||
|
|
||
|
Object.defineProperty(styles, groupName, {
|
||
|
value: group,
|
||
|
enumerable: false
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Object.defineProperty(styles, 'codes', {
|
||
|
value: codes,
|
||
|
enumerable: false
|
||
|
});
|
||
|
|
||
|
styles.color.close = '\u001B[39m';
|
||
|
styles.bgColor.close = '\u001B[49m';
|
||
|
|
||
|
setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false));
|
||
|
setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false));
|
||
|
setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false));
|
||
|
setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true));
|
||
|
setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true));
|
||
|
setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true));
|
||
|
|
||
|
return styles;
|
||
|
}
|
||
|
|
||
|
// Make the export immutable
|
||
|
Object.defineProperty(module, 'exports', {
|
||
|
enumerable: true,
|
||
|
get: assembleStyles
|
||
|
});
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 54 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
const conversions = __webpack_require__(55);
|
||
|
const route = __webpack_require__(57);
|
||
|
|
||
|
const convert = {};
|
||
|
|
||
|
const models = Object.keys(conversions);
|
||
|
|
||
|
function wrapRaw(fn) {
|
||
|
const wrappedFn = function (...args) {
|
||
|
const arg0 = args[0];
|
||
|
if (arg0 === undefined || arg0 === null) {
|
||
|
return arg0;
|
||
|
}
|
||
|
|
||
|
if (arg0.length > 1) {
|
||
|
args = arg0;
|
||
|
}
|
||
|
|
||
|
return fn(args);
|
||
|
};
|
||
|
|
||
|
// Preserve .conversion property if there is one
|
||
|
if ('conversion' in fn) {
|
||
|
wrappedFn.conversion = fn.conversion;
|
||
|
}
|
||
|
|
||
|
return wrappedFn;
|
||
|
}
|
||
|
|
||
|
function wrapRounded(fn) {
|
||
|
const wrappedFn = function (...args) {
|
||
|
const arg0 = args[0];
|
||
|
|
||
|
if (arg0 === undefined || arg0 === null) {
|
||
|
return arg0;
|
||
|
}
|
||
|
|
||
|
if (arg0.length > 1) {
|
||
|
args = arg0;
|
||
|
}
|
||
|
|
||
|
const result = fn(args);
|
||
|
|
||
|
// We're assuming the result is an array here.
|
||
|
// see notice in conversions.js; don't use box types
|
||
|
// in conversion functions.
|
||
|
if (typeof result === 'object') {
|
||
|
for (let len = result.length, i = 0; i < len; i++) {
|
||
|
result[i] = Math.round(result[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
};
|
||
|
|
||
|
// Preserve .conversion property if there is one
|
||
|
if ('conversion' in fn) {
|
||
|
wrappedFn.conversion = fn.conversion;
|
||
|
}
|
||
|
|
||
|
return wrappedFn;
|
||
|
}
|
||
|
|
||
|
models.forEach(fromModel => {
|
||
|
convert[fromModel] = {};
|
||
|
|
||
|
Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
|
||
|
Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
|
||
|
|
||
|
const routes = route(fromModel);
|
||
|
const routeModels = Object.keys(routes);
|
||
|
|
||
|
routeModels.forEach(toModel => {
|
||
|
const fn = routes[toModel];
|
||
|
|
||
|
convert[fromModel][toModel] = wrapRounded(fn);
|
||
|
convert[fromModel][toModel].raw = wrapRaw(fn);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
module.exports = convert;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 55 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
/* MIT license */
|
||
|
/* eslint-disable no-mixed-operators */
|
||
|
const cssKeywords = __webpack_require__(56);
|
||
|
|
||
|
// NOTE: conversions should only return primitive values (i.e. arrays, or
|
||
|
// values that give correct `typeof` results).
|
||
|
// do not use box values types (i.e. Number(), String(), etc.)
|
||
|
|
||
|
const reverseKeywords = {};
|
||
|
for (const key of Object.keys(cssKeywords)) {
|
||
|
reverseKeywords[cssKeywords[key]] = key;
|
||
|
}
|
||
|
|
||
|
const convert = {
|
||
|
rgb: {channels: 3, labels: 'rgb'},
|
||
|
hsl: {channels: 3, labels: 'hsl'},
|
||
|
hsv: {channels: 3, labels: 'hsv'},
|
||
|
hwb: {channels: 3, labels: 'hwb'},
|
||
|
cmyk: {channels: 4, labels: 'cmyk'},
|
||
|
xyz: {channels: 3, labels: 'xyz'},
|
||
|
lab: {channels: 3, labels: 'lab'},
|
||
|
lch: {channels: 3, labels: 'lch'},
|
||
|
hex: {channels: 1, labels: ['hex']},
|
||
|
keyword: {channels: 1, labels: ['keyword']},
|
||
|
ansi16: {channels: 1, labels: ['ansi16']},
|
||
|
ansi256: {channels: 1, labels: ['ansi256']},
|
||
|
hcg: {channels: 3, labels: ['h', 'c', 'g']},
|
||
|
apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
|
||
|
gray: {channels: 1, labels: ['gray']}
|
||
|
};
|
||
|
|
||
|
module.exports = convert;
|
||
|
|
||
|
// Hide .channels and .labels properties
|
||
|
for (const model of Object.keys(convert)) {
|
||
|
if (!('channels' in convert[model])) {
|
||
|
throw new Error('missing channels property: ' + model);
|
||
|
}
|
||
|
|
||
|
if (!('labels' in convert[model])) {
|
||
|
throw new Error('missing channel labels property: ' + model);
|
||
|
}
|
||
|
|
||
|
if (convert[model].labels.length !== convert[model].channels) {
|
||
|
throw new Error('channel and label counts mismatch: ' + model);
|
||
|
}
|
||
|
|
||
|
const {channels, labels} = convert[model];
|
||
|
delete convert[model].channels;
|
||
|
delete convert[model].labels;
|
||
|
Object.defineProperty(convert[model], 'channels', {value: channels});
|
||
|
Object.defineProperty(convert[model], 'labels', {value: labels});
|
||
|
}
|
||
|
|
||
|
convert.rgb.hsl = function (rgb) {
|
||
|
const r = rgb[0] / 255;
|
||
|
const g = rgb[1] / 255;
|
||
|
const b = rgb[2] / 255;
|
||
|
const min = Math.min(r, g, b);
|
||
|
const max = Math.max(r, g, b);
|
||
|
const delta = max - min;
|
||
|
let h;
|
||
|
let s;
|
||
|
|
||
|
if (max === min) {
|
||
|
h = 0;
|
||
|
} else if (r === max) {
|
||
|
h = (g - b) / delta;
|
||
|
} else if (g === max) {
|
||
|
h = 2 + (b - r) / delta;
|
||
|
} else if (b === max) {
|
||
|
h = 4 + (r - g) / delta;
|
||
|
}
|
||
|
|
||
|
h = Math.min(h * 60, 360);
|
||
|
|
||
|
if (h < 0) {
|
||
|
h += 360;
|
||
|
}
|
||
|
|
||
|
const l = (min + max) / 2;
|
||
|
|
||
|
if (max === min) {
|
||
|
s = 0;
|
||
|
} else if (l <= 0.5) {
|
||
|
s = delta / (max + min);
|
||
|
} else {
|
||
|
s = delta / (2 - max - min);
|
||
|
}
|
||
|
|
||
|
return [h, s * 100, l * 100];
|
||
|
};
|
||
|
|
||
|
convert.rgb.hsv = function (rgb) {
|
||
|
let rdif;
|
||
|
let gdif;
|
||
|
let bdif;
|
||
|
let h;
|
||
|
let s;
|
||
|
|
||
|
const r = rgb[0] / 255;
|
||
|
const g = rgb[1] / 255;
|
||
|
const b = rgb[2] / 255;
|
||
|
const v = Math.max(r, g, b);
|
||
|
const diff = v - Math.min(r, g, b);
|
||
|
const diffc = function (c) {
|
||
|
return (v - c) / 6 / diff + 1 / 2;
|
||
|
};
|
||
|
|
||
|
if (diff === 0) {
|
||
|
h = 0;
|
||
|
s = 0;
|
||
|
} else {
|
||
|
s = diff / v;
|
||
|
rdif = diffc(r);
|
||
|
gdif = diffc(g);
|
||
|
bdif = diffc(b);
|
||
|
|
||
|
if (r === v) {
|
||
|
h = bdif - gdif;
|
||
|
} else if (g === v) {
|
||
|
h = (1 / 3) + rdif - bdif;
|
||
|
} else if (b === v) {
|
||
|
h = (2 / 3) + gdif - rdif;
|
||
|
}
|
||
|
|
||
|
if (h < 0) {
|
||
|
h += 1;
|
||
|
} else if (h > 1) {
|
||
|
h -= 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return [
|
||
|
h * 360,
|
||
|
s * 100,
|
||
|
v * 100
|
||
|
];
|
||
|
};
|
||
|
|
||
|
convert.rgb.hwb = function (rgb) {
|
||
|
const r = rgb[0];
|
||
|
const g = rgb[1];
|
||
|
let b = rgb[2];
|
||
|
const h = convert.rgb.hsl(rgb)[0];
|
||
|
const w = 1 / 255 * Math.min(r, Math.min(g, b));
|
||
|
|
||
|
b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
|
||
|
|
||
|
return [h, w * 100, b * 100];
|
||
|
};
|
||
|
|
||
|
convert.rgb.cmyk = function (rgb) {
|
||
|
const r = rgb[0] / 255;
|
||
|
const g = rgb[1] / 255;
|
||
|
const b = rgb[2] / 255;
|
||
|
|
||
|
const k = Math.min(1 - r, 1 - g, 1 - b);
|
||
|
const c = (1 - r - k) / (1 - k) || 0;
|
||
|
const m = (1 - g - k) / (1 - k) || 0;
|
||
|
const y = (1 - b - k) / (1 - k) || 0;
|
||
|
|
||
|
return [c * 100, m * 100, y * 100, k * 100];
|
||
|
};
|
||
|
|
||
|
function comparativeDistance(x, y) {
|
||
|
/*
|
||
|
See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
|
||
|
*/
|
||
|
return (
|
||
|
((x[0] - y[0]) ** 2) +
|
||
|
((x[1] - y[1]) ** 2) +
|
||
|
((x[2] - y[2]) ** 2)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
convert.rgb.keyword = function (rgb) {
|
||
|
const reversed = reverseKeywords[rgb];
|
||
|
if (reversed) {
|
||
|
return reversed;
|
||
|
}
|
||
|
|
||
|
let currentClosestDistance = Infinity;
|
||
|
let currentClosestKeyword;
|
||
|
|
||
|
for (const keyword of Object.keys(cssKeywords)) {
|
||
|
const value = cssKeywords[keyword];
|
||
|
|
||
|
// Compute comparative distance
|
||
|
const distance = comparativeDistance(rgb, value);
|
||
|
|
||
|
// Check if its less, if so set as closest
|
||
|
if (distance < currentClosestDistance) {
|
||
|
currentClosestDistance = distance;
|
||
|
currentClosestKeyword = keyword;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return currentClosestKeyword;
|
||
|
};
|
||
|
|
||
|
convert.keyword.rgb = function (keyword) {
|
||
|
return cssKeywords[keyword];
|
||
|
};
|
||
|
|
||
|
convert.rgb.xyz = function (rgb) {
|
||
|
let r = rgb[0] / 255;
|
||
|
let g = rgb[1] / 255;
|
||
|
let b = rgb[2] / 255;
|
||
|
|
||
|
// Assume sRGB
|
||
|
r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92);
|
||
|
g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92);
|
||
|
b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92);
|
||
|
|
||
|
const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
|
||
|
const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
|
||
|
const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
|
||
|
|
||
|
return [x * 100, y * 100, z * 100];
|
||
|
};
|
||
|
|
||
|
convert.rgb.lab = function (rgb) {
|
||
|
const xyz = convert.rgb.xyz(rgb);
|
||
|
let x = xyz[0];
|
||
|
let y = xyz[1];
|
||
|
let z = xyz[2];
|
||
|
|
||
|
x /= 95.047;
|
||
|
y /= 100;
|
||
|
z /= 108.883;
|
||
|
|
||
|
x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);
|
||
|
y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);
|
||
|
z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);
|
||
|
|
||
|
const l = (116 * y) - 16;
|
||
|
const a = 500 * (x - y);
|
||
|
const b = 200 * (y - z);
|
||
|
|
||
|
return [l, a, b];
|
||
|
};
|
||
|
|
||
|
convert.hsl.rgb = function (hsl) {
|
||
|
const h = hsl[0] / 360;
|
||
|
const s = hsl[1] / 100;
|
||
|
const l = hsl[2] / 100;
|
||
|
let t2;
|
||
|
let t3;
|
||
|
let val;
|
||
|
|
||
|
if (s === 0) {
|
||
|
val = l * 255;
|
||
|
return [val, val, val];
|
||
|
}
|
||
|
|
||
|
if (l < 0.5) {
|
||
|
t2 = l * (1 + s);
|
||
|
} else {
|
||
|
t2 = l + s - l * s;
|
||
|
}
|
||
|
|
||
|
const t1 = 2 * l - t2;
|
||
|
|
||
|
const rgb = [0, 0, 0];
|
||
|
for (let i = 0; i < 3; i++) {
|
||
|
t3 = h + 1 / 3 * -(i - 1);
|
||
|
if (t3 < 0) {
|
||
|
t3++;
|
||
|
}
|
||
|
|
||
|
if (t3 > 1) {
|
||
|
t3--;
|
||
|
}
|
||
|
|
||
|
if (6 * t3 < 1) {
|
||
|
val = t1 + (t2 - t1) * 6 * t3;
|
||
|
} else if (2 * t3 < 1) {
|
||
|
val = t2;
|
||
|
} else if (3 * t3 < 2) {
|
||
|
val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
|
||
|
} else {
|
||
|
val = t1;
|
||
|
}
|
||
|
|
||
|
rgb[i] = val * 255;
|
||
|
}
|
||
|
|
||
|
return rgb;
|
||
|
};
|
||
|
|
||
|
convert.hsl.hsv = function (hsl) {
|
||
|
const h = hsl[0];
|
||
|
let s = hsl[1] / 100;
|
||
|
let l = hsl[2] / 100;
|
||
|
let smin = s;
|
||
|
const lmin = Math.max(l, 0.01);
|
||
|
|
||
|
l *= 2;
|
||
|
s *= (l <= 1) ? l : 2 - l;
|
||
|
smin *= lmin <= 1 ? lmin : 2 - lmin;
|
||
|
const v = (l + s) / 2;
|
||
|
const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
|
||
|
|
||
|
return [h, sv * 100, v * 100];
|
||
|
};
|
||
|
|
||
|
convert.hsv.rgb = function (hsv) {
|
||
|
const h = hsv[0] / 60;
|
||
|
const s = hsv[1] / 100;
|
||
|
let v = hsv[2] / 100;
|
||
|
const hi = Math.floor(h) % 6;
|
||
|
|
||
|
const f = h - Math.floor(h);
|
||
|
const p = 255 * v * (1 - s);
|
||
|
const q = 255 * v * (1 - (s * f));
|
||
|
const t = 255 * v * (1 - (s * (1 - f)));
|
||
|
v *= 255;
|
||
|
|
||
|
switch (hi) {
|
||
|
case 0:
|
||
|
return [v, t, p];
|
||
|
case 1:
|
||
|
return [q, v, p];
|
||
|
case 2:
|
||
|
return [p, v, t];
|
||
|
case 3:
|
||
|
return [p, q, v];
|
||
|
case 4:
|
||
|
return [t, p, v];
|
||
|
case 5:
|
||
|
return [v, p, q];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
convert.hsv.hsl = function (hsv) {
|
||
|
const h = hsv[0];
|
||
|
const s = hsv[1] / 100;
|
||
|
const v = hsv[2] / 100;
|
||
|
const vmin = Math.max(v, 0.01);
|
||
|
let sl;
|
||
|
let l;
|
||
|
|
||
|
l = (2 - s) * v;
|
||
|
const lmin = (2 - s) * vmin;
|
||
|
sl = s * vmin;
|
||
|
sl /= (lmin <= 1) ? lmin : 2 - lmin;
|
||
|
sl = sl || 0;
|
||
|
l /= 2;
|
||
|
|
||
|
return [h, sl * 100, l * 100];
|
||
|
};
|
||
|
|
||
|
// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
|
||
|
convert.hwb.rgb = function (hwb) {
|
||
|
const h = hwb[0] / 360;
|
||
|
let wh = hwb[1] / 100;
|
||
|
let bl = hwb[2] / 100;
|
||
|
const ratio = wh + bl;
|
||
|
let f;
|
||
|
|
||
|
// Wh + bl cant be > 1
|
||
|
if (ratio > 1) {
|
||
|
wh /= ratio;
|
||
|
bl /= ratio;
|
||
|
}
|
||
|
|
||
|
const i = Math.floor(6 * h);
|
||
|
const v = 1 - bl;
|
||
|
f = 6 * h - i;
|
||
|
|
||
|
if ((i & 0x01) !== 0) {
|
||
|
f = 1 - f;
|
||
|
}
|
||
|
|
||
|
const n = wh + f * (v - wh); // Linear interpolation
|
||
|
|
||
|
let r;
|
||
|
let g;
|
||
|
let b;
|
||
|
/* eslint-disable max-statements-per-line,no-multi-spaces */
|
||
|
switch (i) {
|
||
|
default:
|
||
|
case 6:
|
||
|
case 0: r = v; g = n; b = wh; break;
|
||
|
case 1: r = n; g = v; b = wh; break;
|
||
|
case 2: r = wh; g = v; b = n; break;
|
||
|
case 3: r = wh; g = n; b = v; break;
|
||
|
case 4: r = n; g = wh; b = v; break;
|
||
|
case 5: r = v; g = wh; b = n; break;
|
||
|
}
|
||
|
/* eslint-enable max-statements-per-line,no-multi-spaces */
|
||
|
|
||
|
return [r * 255, g * 255, b * 255];
|
||
|
};
|
||
|
|
||
|
convert.cmyk.rgb = function (cmyk) {
|
||
|
const c = cmyk[0] / 100;
|
||
|
const m = cmyk[1] / 100;
|
||
|
const y = cmyk[2] / 100;
|
||
|
const k = cmyk[3] / 100;
|
||
|
|
||
|
const r = 1 - Math.min(1, c * (1 - k) + k);
|
||
|
const g = 1 - Math.min(1, m * (1 - k) + k);
|
||
|
const b = 1 - Math.min(1, y * (1 - k) + k);
|
||
|
|
||
|
return [r * 255, g * 255, b * 255];
|
||
|
};
|
||
|
|
||
|
convert.xyz.rgb = function (xyz) {
|
||
|
const x = xyz[0] / 100;
|
||
|
const y = xyz[1] / 100;
|
||
|
const z = xyz[2] / 100;
|
||
|
let r;
|
||
|
let g;
|
||
|
let b;
|
||
|
|
||
|
r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
|
||
|
g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
|
||
|
b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
|
||
|
|
||
|
// Assume sRGB
|
||
|
r = r > 0.0031308
|
||
|
? ((1.055 * (r ** (1.0 / 2.4))) - 0.055)
|
||
|
: r * 12.92;
|
||
|
|
||
|
g = g > 0.0031308
|
||
|
? ((1.055 * (g ** (1.0 / 2.4))) - 0.055)
|
||
|
: g * 12.92;
|
||
|
|
||
|
b = b > 0.0031308
|
||
|
? ((1.055 * (b ** (1.0 / 2.4))) - 0.055)
|
||
|
: b * 12.92;
|
||
|
|
||
|
r = Math.min(Math.max(0, r), 1);
|
||
|
g = Math.min(Math.max(0, g), 1);
|
||
|
b = Math.min(Math.max(0, b), 1);
|
||
|
|
||
|
return [r * 255, g * 255, b * 255];
|
||
|
};
|
||
|
|
||
|
convert.xyz.lab = function (xyz) {
|
||
|
let x = xyz[0];
|
||
|
let y = xyz[1];
|
||
|
let z = xyz[2];
|
||
|
|
||
|
x /= 95.047;
|
||
|
y /= 100;
|
||
|
z /= 108.883;
|
||
|
|
||
|
x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116);
|
||
|
y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116);
|
||
|
z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116);
|
||
|
|
||
|
const l = (116 * y) - 16;
|
||
|
const a = 500 * (x - y);
|
||
|
const b = 200 * (y - z);
|
||
|
|
||
|
return [l, a, b];
|
||
|
};
|
||
|
|
||
|
convert.lab.xyz = function (lab) {
|
||
|
const l = lab[0];
|
||
|
const a = lab[1];
|
||
|
const b = lab[2];
|
||
|
let x;
|
||
|
let y;
|
||
|
let z;
|
||
|
|
||
|
y = (l + 16) / 116;
|
||
|
x = a / 500 + y;
|
||
|
z = y - b / 200;
|
||
|
|
||
|
const y2 = y ** 3;
|
||
|
const x2 = x ** 3;
|
||
|
const z2 = z ** 3;
|
||
|
y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
|
||
|
x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
|
||
|
z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
|
||
|
|
||
|
x *= 95.047;
|
||
|
y *= 100;
|
||
|
z *= 108.883;
|
||
|
|
||
|
return [x, y, z];
|
||
|
};
|
||
|
|
||
|
convert.lab.lch = function (lab) {
|
||
|
const l = lab[0];
|
||
|
const a = lab[1];
|
||
|
const b = lab[2];
|
||
|
let h;
|
||
|
|
||
|
const hr = Math.atan2(b, a);
|
||
|
h = hr * 360 / 2 / Math.PI;
|
||
|
|
||
|
if (h < 0) {
|
||
|
h += 360;
|
||
|
}
|
||
|
|
||
|
const c = Math.sqrt(a * a + b * b);
|
||
|
|
||
|
return [l, c, h];
|
||
|
};
|
||
|
|
||
|
convert.lch.lab = function (lch) {
|
||
|
const l = lch[0];
|
||
|
const c = lch[1];
|
||
|
const h = lch[2];
|
||
|
|
||
|
const hr = h / 360 * 2 * Math.PI;
|
||
|
const a = c * Math.cos(hr);
|
||
|
const b = c * Math.sin(hr);
|
||
|
|
||
|
return [l, a, b];
|
||
|
};
|
||
|
|
||
|
convert.rgb.ansi16 = function (args, saturation = null) {
|
||
|
const [r, g, b] = args;
|
||
|
let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization
|
||
|
|
||
|
value = Math.round(value / 50);
|
||
|
|
||
|
if (value === 0) {
|
||
|
return 30;
|
||
|
}
|
||
|
|
||
|
let ansi = 30
|
||
|
+ ((Math.round(b / 255) << 2)
|
||
|
| (Math.round(g / 255) << 1)
|
||
|
| Math.round(r / 255));
|
||
|
|
||
|
if (value === 2) {
|
||
|
ansi += 60;
|
||
|
}
|
||
|
|
||
|
return ansi;
|
||
|
};
|
||
|
|
||
|
convert.hsv.ansi16 = function (args) {
|
||
|
// Optimization here; we already know the value and don't need to get
|
||
|
// it converted for us.
|
||
|
return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
|
||
|
};
|
||
|
|
||
|
convert.rgb.ansi256 = function (args) {
|
||
|
const r = args[0];
|
||
|
const g = args[1];
|
||
|
const b = args[2];
|
||
|
|
||
|
// We use the extended greyscale palette here, with the exception of
|
||
|
// black and white. normal palette only has 4 greyscale shades.
|
||
|
if (r === g && g === b) {
|
||
|
if (r < 8) {
|
||
|
return 16;
|
||
|
}
|
||
|
|
||
|
if (r > 248) {
|
||
|
return 231;
|
||
|
}
|
||
|
|
||
|
return Math.round(((r - 8) / 247) * 24) + 232;
|
||
|
}
|
||
|
|
||
|
const ansi = 16
|
||
|
+ (36 * Math.round(r / 255 * 5))
|
||
|
+ (6 * Math.round(g / 255 * 5))
|
||
|
+ Math.round(b / 255 * 5);
|
||
|
|
||
|
return ansi;
|
||
|
};
|
||
|
|
||
|
convert.ansi16.rgb = function (args) {
|
||
|
let color = args % 10;
|
||
|
|
||
|
// Handle greyscale
|
||
|
if (color === 0 || color === 7) {
|
||
|
if (args > 50) {
|
||
|
color += 3.5;
|
||
|
}
|
||
|
|
||
|
color = color / 10.5 * 255;
|
||
|
|
||
|
return [color, color, color];
|
||
|
}
|
||
|
|
||
|
const mult = (~~(args > 50) + 1) * 0.5;
|
||
|
const r = ((color & 1) * mult) * 255;
|
||
|
const g = (((color >> 1) & 1) * mult) * 255;
|
||
|
const b = (((color >> 2) & 1) * mult) * 255;
|
||
|
|
||
|
return [r, g, b];
|
||
|
};
|
||
|
|
||
|
convert.ansi256.rgb = function (args) {
|
||
|
// Handle greyscale
|
||
|
if (args >= 232) {
|
||
|
const c = (args - 232) * 10 + 8;
|
||
|
return [c, c, c];
|
||
|
}
|
||
|
|
||
|
args -= 16;
|
||
|
|
||
|
let rem;
|
||
|
const r = Math.floor(args / 36) / 5 * 255;
|
||
|
const g = Math.floor((rem = args % 36) / 6) / 5 * 255;
|
||
|
const b = (rem % 6) / 5 * 255;
|
||
|
|
||
|
return [r, g, b];
|
||
|
};
|
||
|
|
||
|
convert.rgb.hex = function (args) {
|
||
|
const integer = ((Math.round(args[0]) & 0xFF) << 16)
|
||
|
+ ((Math.round(args[1]) & 0xFF) << 8)
|
||
|
+ (Math.round(args[2]) & 0xFF);
|
||
|
|
||
|
const string = integer.toString(16).toUpperCase();
|
||
|
return '000000'.substring(string.length) + string;
|
||
|
};
|
||
|
|
||
|
convert.hex.rgb = function (args) {
|
||
|
const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
|
||
|
if (!match) {
|
||
|
return [0, 0, 0];
|
||
|
}
|
||
|
|
||
|
let colorString = match[0];
|
||
|
|
||
|
if (match[0].length === 3) {
|
||
|
colorString = colorString.split('').map(char => {
|
||
|
return char + char;
|
||
|
}).join('');
|
||
|
}
|
||
|
|
||
|
const integer = parseInt(colorString, 16);
|
||
|
const r = (integer >> 16) & 0xFF;
|
||
|
const g = (integer >> 8) & 0xFF;
|
||
|
const b = integer & 0xFF;
|
||
|
|
||
|
return [r, g, b];
|
||
|
};
|
||
|
|
||
|
convert.rgb.hcg = function (rgb) {
|
||
|
const r = rgb[0] / 255;
|
||
|
const g = rgb[1] / 255;
|
||
|
const b = rgb[2] / 255;
|
||
|
const max = Math.max(Math.max(r, g), b);
|
||
|
const min = Math.min(Math.min(r, g), b);
|
||
|
const chroma = (max - min);
|
||
|
let grayscale;
|
||
|
let hue;
|
||
|
|
||
|
if (chroma < 1) {
|
||
|
grayscale = min / (1 - chroma);
|
||
|
} else {
|
||
|
grayscale = 0;
|
||
|
}
|
||
|
|
||
|
if (chroma <= 0) {
|
||
|
hue = 0;
|
||
|
} else
|
||
|
if (max === r) {
|
||
|
hue = ((g - b) / chroma) % 6;
|
||
|
} else
|
||
|
if (max === g) {
|
||
|
hue = 2 + (b - r) / chroma;
|
||
|
} else {
|
||
|
hue = 4 + (r - g) / chroma;
|
||
|
}
|
||
|
|
||
|
hue /= 6;
|
||
|
hue %= 1;
|
||
|
|
||
|
return [hue * 360, chroma * 100, grayscale * 100];
|
||
|
};
|
||
|
|
||
|
convert.hsl.hcg = function (hsl) {
|
||
|
const s = hsl[1] / 100;
|
||
|
const l = hsl[2] / 100;
|
||
|
|
||
|
const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l));
|
||
|
|
||
|
let f = 0;
|
||
|
if (c < 1.0) {
|
||
|
f = (l - 0.5 * c) / (1.0 - c);
|
||
|
}
|
||
|
|
||
|
return [hsl[0], c * 100, f * 100];
|
||
|
};
|
||
|
|
||
|
convert.hsv.hcg = function (hsv) {
|
||
|
const s = hsv[1] / 100;
|
||
|
const v = hsv[2] / 100;
|
||
|
|
||
|
const c = s * v;
|
||
|
let f = 0;
|
||
|
|
||
|
if (c < 1.0) {
|
||
|
f = (v - c) / (1 - c);
|
||
|
}
|
||
|
|
||
|
return [hsv[0], c * 100, f * 100];
|
||
|
};
|
||
|
|
||
|
convert.hcg.rgb = function (hcg) {
|
||
|
const h = hcg[0] / 360;
|
||
|
const c = hcg[1] / 100;
|
||
|
const g = hcg[2] / 100;
|
||
|
|
||
|
if (c === 0.0) {
|
||
|
return [g * 255, g * 255, g * 255];
|
||
|
}
|
||
|
|
||
|
const pure = [0, 0, 0];
|
||
|
const hi = (h % 1) * 6;
|
||
|
const v = hi % 1;
|
||
|
const w = 1 - v;
|
||
|
let mg = 0;
|
||
|
|
||
|
/* eslint-disable max-statements-per-line */
|
||
|
switch (Math.floor(hi)) {
|
||
|
case 0:
|
||
|
pure[0] = 1; pure[1] = v; pure[2] = 0; break;
|
||
|
case 1:
|
||
|
pure[0] = w; pure[1] = 1; pure[2] = 0; break;
|
||
|
case 2:
|
||
|
pure[0] = 0; pure[1] = 1; pure[2] = v; break;
|
||
|
case 3:
|
||
|
pure[0] = 0; pure[1] = w; pure[2] = 1; break;
|
||
|
case 4:
|
||
|
pure[0] = v; pure[1] = 0; pure[2] = 1; break;
|
||
|
default:
|
||
|
pure[0] = 1; pure[1] = 0; pure[2] = w;
|
||
|
}
|
||
|
/* eslint-enable max-statements-per-line */
|
||
|
|
||
|
mg = (1.0 - c) * g;
|
||
|
|
||
|
return [
|
||
|
(c * pure[0] + mg) * 255,
|
||
|
(c * pure[1] + mg) * 255,
|
||
|
(c * pure[2] + mg) * 255
|
||
|
];
|
||
|
};
|
||
|
|
||
|
convert.hcg.hsv = function (hcg) {
|
||
|
const c = hcg[1] / 100;
|
||
|
const g = hcg[2] / 100;
|
||
|
|
||
|
const v = c + g * (1.0 - c);
|
||
|
let f = 0;
|
||
|
|
||
|
if (v > 0.0) {
|
||
|
f = c / v;
|
||
|
}
|
||
|
|
||
|
return [hcg[0], f * 100, v * 100];
|
||
|
};
|
||
|
|
||
|
convert.hcg.hsl = function (hcg) {
|
||
|
const c = hcg[1] / 100;
|
||
|
const g = hcg[2] / 100;
|
||
|
|
||
|
const l = g * (1.0 - c) + 0.5 * c;
|
||
|
let s = 0;
|
||
|
|
||
|
if (l > 0.0 && l < 0.5) {
|
||
|
s = c / (2 * l);
|
||
|
} else
|
||
|
if (l >= 0.5 && l < 1.0) {
|
||
|
s = c / (2 * (1 - l));
|
||
|
}
|
||
|
|
||
|
return [hcg[0], s * 100, l * 100];
|
||
|
};
|
||
|
|
||
|
convert.hcg.hwb = function (hcg) {
|
||
|
const c = hcg[1] / 100;
|
||
|
const g = hcg[2] / 100;
|
||
|
const v = c + g * (1.0 - c);
|
||
|
return [hcg[0], (v - c) * 100, (1 - v) * 100];
|
||
|
};
|
||
|
|
||
|
convert.hwb.hcg = function (hwb) {
|
||
|
const w = hwb[1] / 100;
|
||
|
const b = hwb[2] / 100;
|
||
|
const v = 1 - b;
|
||
|
const c = v - w;
|
||
|
let g = 0;
|
||
|
|
||
|
if (c < 1) {
|
||
|
g = (v - c) / (1 - c);
|
||
|
}
|
||
|
|
||
|
return [hwb[0], c * 100, g * 100];
|
||
|
};
|
||
|
|
||
|
convert.apple.rgb = function (apple) {
|
||
|
return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
|
||
|
};
|
||
|
|
||
|
convert.rgb.apple = function (rgb) {
|
||
|
return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
|
||
|
};
|
||
|
|
||
|
convert.gray.rgb = function (args) {
|
||
|
return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
|
||
|
};
|
||
|
|
||
|
convert.gray.hsl = function (args) {
|
||
|
return [0, 0, args[0]];
|
||
|
};
|
||
|
|
||
|
convert.gray.hsv = convert.gray.hsl;
|
||
|
|
||
|
convert.gray.hwb = function (gray) {
|
||
|
return [0, 100, gray[0]];
|
||
|
};
|
||
|
|
||
|
convert.gray.cmyk = function (gray) {
|
||
|
return [0, 0, 0, gray[0]];
|
||
|
};
|
||
|
|
||
|
convert.gray.lab = function (gray) {
|
||
|
return [gray[0], 0, 0];
|
||
|
};
|
||
|
|
||
|
convert.gray.hex = function (gray) {
|
||
|
const val = Math.round(gray[0] / 100 * 255) & 0xFF;
|
||
|
const integer = (val << 16) + (val << 8) + val;
|
||
|
|
||
|
const string = integer.toString(16).toUpperCase();
|
||
|
return '000000'.substring(string.length) + string;
|
||
|
};
|
||
|
|
||
|
convert.rgb.gray = function (rgb) {
|
||
|
const val = (rgb[0] + rgb[1] + rgb[2]) / 3;
|
||
|
return [val / 255 * 100];
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 56 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
module.exports = {
|
||
|
"aliceblue": [240, 248, 255],
|
||
|
"antiquewhite": [250, 235, 215],
|
||
|
"aqua": [0, 255, 255],
|
||
|
"aquamarine": [127, 255, 212],
|
||
|
"azure": [240, 255, 255],
|
||
|
"beige": [245, 245, 220],
|
||
|
"bisque": [255, 228, 196],
|
||
|
"black": [0, 0, 0],
|
||
|
"blanchedalmond": [255, 235, 205],
|
||
|
"blue": [0, 0, 255],
|
||
|
"blueviolet": [138, 43, 226],
|
||
|
"brown": [165, 42, 42],
|
||
|
"burlywood": [222, 184, 135],
|
||
|
"cadetblue": [95, 158, 160],
|
||
|
"chartreuse": [127, 255, 0],
|
||
|
"chocolate": [210, 105, 30],
|
||
|
"coral": [255, 127, 80],
|
||
|
"cornflowerblue": [100, 149, 237],
|
||
|
"cornsilk": [255, 248, 220],
|
||
|
"crimson": [220, 20, 60],
|
||
|
"cyan": [0, 255, 255],
|
||
|
"darkblue": [0, 0, 139],
|
||
|
"darkcyan": [0, 139, 139],
|
||
|
"darkgoldenrod": [184, 134, 11],
|
||
|
"darkgray": [169, 169, 169],
|
||
|
"darkgreen": [0, 100, 0],
|
||
|
"darkgrey": [169, 169, 169],
|
||
|
"darkkhaki": [189, 183, 107],
|
||
|
"darkmagenta": [139, 0, 139],
|
||
|
"darkolivegreen": [85, 107, 47],
|
||
|
"darkorange": [255, 140, 0],
|
||
|
"darkorchid": [153, 50, 204],
|
||
|
"darkred": [139, 0, 0],
|
||
|
"darksalmon": [233, 150, 122],
|
||
|
"darkseagreen": [143, 188, 143],
|
||
|
"darkslateblue": [72, 61, 139],
|
||
|
"darkslategray": [47, 79, 79],
|
||
|
"darkslategrey": [47, 79, 79],
|
||
|
"darkturquoise": [0, 206, 209],
|
||
|
"darkviolet": [148, 0, 211],
|
||
|
"deeppink": [255, 20, 147],
|
||
|
"deepskyblue": [0, 191, 255],
|
||
|
"dimgray": [105, 105, 105],
|
||
|
"dimgrey": [105, 105, 105],
|
||
|
"dodgerblue": [30, 144, 255],
|
||
|
"firebrick": [178, 34, 34],
|
||
|
"floralwhite": [255, 250, 240],
|
||
|
"forestgreen": [34, 139, 34],
|
||
|
"fuchsia": [255, 0, 255],
|
||
|
"gainsboro": [220, 220, 220],
|
||
|
"ghostwhite": [248, 248, 255],
|
||
|
"gold": [255, 215, 0],
|
||
|
"goldenrod": [218, 165, 32],
|
||
|
"gray": [128, 128, 128],
|
||
|
"green": [0, 128, 0],
|
||
|
"greenyellow": [173, 255, 47],
|
||
|
"grey": [128, 128, 128],
|
||
|
"honeydew": [240, 255, 240],
|
||
|
"hotpink": [255, 105, 180],
|
||
|
"indianred": [205, 92, 92],
|
||
|
"indigo": [75, 0, 130],
|
||
|
"ivory": [255, 255, 240],
|
||
|
"khaki": [240, 230, 140],
|
||
|
"lavender": [230, 230, 250],
|
||
|
"lavenderblush": [255, 240, 245],
|
||
|
"lawngreen": [124, 252, 0],
|
||
|
"lemonchiffon": [255, 250, 205],
|
||
|
"lightblue": [173, 216, 230],
|
||
|
"lightcoral": [240, 128, 128],
|
||
|
"lightcyan": [224, 255, 255],
|
||
|
"lightgoldenrodyellow": [250, 250, 210],
|
||
|
"lightgray": [211, 211, 211],
|
||
|
"lightgreen": [144, 238, 144],
|
||
|
"lightgrey": [211, 211, 211],
|
||
|
"lightpink": [255, 182, 193],
|
||
|
"lightsalmon": [255, 160, 122],
|
||
|
"lightseagreen": [32, 178, 170],
|
||
|
"lightskyblue": [135, 206, 250],
|
||
|
"lightslategray": [119, 136, 153],
|
||
|
"lightslategrey": [119, 136, 153],
|
||
|
"lightsteelblue": [176, 196, 222],
|
||
|
"lightyellow": [255, 255, 224],
|
||
|
"lime": [0, 255, 0],
|
||
|
"limegreen": [50, 205, 50],
|
||
|
"linen": [250, 240, 230],
|
||
|
"magenta": [255, 0, 255],
|
||
|
"maroon": [128, 0, 0],
|
||
|
"mediumaquamarine": [102, 205, 170],
|
||
|
"mediumblue": [0, 0, 205],
|
||
|
"mediumorchid": [186, 85, 211],
|
||
|
"mediumpurple": [147, 112, 219],
|
||
|
"mediumseagreen": [60, 179, 113],
|
||
|
"mediumslateblue": [123, 104, 238],
|
||
|
"mediumspringgreen": [0, 250, 154],
|
||
|
"mediumturquoise": [72, 209, 204],
|
||
|
"mediumvioletred": [199, 21, 133],
|
||
|
"midnightblue": [25, 25, 112],
|
||
|
"mintcream": [245, 255, 250],
|
||
|
"mistyrose": [255, 228, 225],
|
||
|
"moccasin": [255, 228, 181],
|
||
|
"navajowhite": [255, 222, 173],
|
||
|
"navy": [0, 0, 128],
|
||
|
"oldlace": [253, 245, 230],
|
||
|
"olive": [128, 128, 0],
|
||
|
"olivedrab": [107, 142, 35],
|
||
|
"orange": [255, 165, 0],
|
||
|
"orangered": [255, 69, 0],
|
||
|
"orchid": [218, 112, 214],
|
||
|
"palegoldenrod": [238, 232, 170],
|
||
|
"palegreen": [152, 251, 152],
|
||
|
"paleturquoise": [175, 238, 238],
|
||
|
"palevioletred": [219, 112, 147],
|
||
|
"papayawhip": [255, 239, 213],
|
||
|
"peachpuff": [255, 218, 185],
|
||
|
"peru": [205, 133, 63],
|
||
|
"pink": [255, 192, 203],
|
||
|
"plum": [221, 160, 221],
|
||
|
"powderblue": [176, 224, 230],
|
||
|
"purple": [128, 0, 128],
|
||
|
"rebeccapurple": [102, 51, 153],
|
||
|
"red": [255, 0, 0],
|
||
|
"rosybrown": [188, 143, 143],
|
||
|
"royalblue": [65, 105, 225],
|
||
|
"saddlebrown": [139, 69, 19],
|
||
|
"salmon": [250, 128, 114],
|
||
|
"sandybrown": [244, 164, 96],
|
||
|
"seagreen": [46, 139, 87],
|
||
|
"seashell": [255, 245, 238],
|
||
|
"sienna": [160, 82, 45],
|
||
|
"silver": [192, 192, 192],
|
||
|
"skyblue": [135, 206, 235],
|
||
|
"slateblue": [106, 90, 205],
|
||
|
"slategray": [112, 128, 144],
|
||
|
"slategrey": [112, 128, 144],
|
||
|
"snow": [255, 250, 250],
|
||
|
"springgreen": [0, 255, 127],
|
||
|
"steelblue": [70, 130, 180],
|
||
|
"tan": [210, 180, 140],
|
||
|
"teal": [0, 128, 128],
|
||
|
"thistle": [216, 191, 216],
|
||
|
"tomato": [255, 99, 71],
|
||
|
"turquoise": [64, 224, 208],
|
||
|
"violet": [238, 130, 238],
|
||
|
"wheat": [245, 222, 179],
|
||
|
"white": [255, 255, 255],
|
||
|
"whitesmoke": [245, 245, 245],
|
||
|
"yellow": [255, 255, 0],
|
||
|
"yellowgreen": [154, 205, 50]
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 57 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
const conversions = __webpack_require__(55);
|
||
|
|
||
|
/*
|
||
|
This function routes a model to all other models.
|
||
|
|
||
|
all functions that are routed have a property `.conversion` attached
|
||
|
to the returned synthetic function. This property is an array
|
||
|
of strings, each with the steps in between the 'from' and 'to'
|
||
|
color models (inclusive).
|
||
|
|
||
|
conversions that are not possible simply are not included.
|
||
|
*/
|
||
|
|
||
|
function buildGraph() {
|
||
|
const graph = {};
|
||
|
// https://jsperf.com/object-keys-vs-for-in-with-closure/3
|
||
|
const models = Object.keys(conversions);
|
||
|
|
||
|
for (let len = models.length, i = 0; i < len; i++) {
|
||
|
graph[models[i]] = {
|
||
|
// http://jsperf.com/1-vs-infinity
|
||
|
// micro-opt, but this is simple.
|
||
|
distance: -1,
|
||
|
parent: null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return graph;
|
||
|
}
|
||
|
|
||
|
// https://en.wikipedia.org/wiki/Breadth-first_search
|
||
|
function deriveBFS(fromModel) {
|
||
|
const graph = buildGraph();
|
||
|
const queue = [fromModel]; // Unshift -> queue -> pop
|
||
|
|
||
|
graph[fromModel].distance = 0;
|
||
|
|
||
|
while (queue.length) {
|
||
|
const current = queue.pop();
|
||
|
const adjacents = Object.keys(conversions[current]);
|
||
|
|
||
|
for (let len = adjacents.length, i = 0; i < len; i++) {
|
||
|
const adjacent = adjacents[i];
|
||
|
const node = graph[adjacent];
|
||
|
|
||
|
if (node.distance === -1) {
|
||
|
node.distance = graph[current].distance + 1;
|
||
|
node.parent = current;
|
||
|
queue.unshift(adjacent);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return graph;
|
||
|
}
|
||
|
|
||
|
function link(from, to) {
|
||
|
return function (args) {
|
||
|
return to(from(args));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function wrapConversion(toModel, graph) {
|
||
|
const path = [graph[toModel].parent, toModel];
|
||
|
let fn = conversions[graph[toModel].parent][toModel];
|
||
|
|
||
|
let cur = graph[toModel].parent;
|
||
|
while (graph[cur].parent) {
|
||
|
path.unshift(graph[cur].parent);
|
||
|
fn = link(conversions[graph[cur].parent][cur], fn);
|
||
|
cur = graph[cur].parent;
|
||
|
}
|
||
|
|
||
|
fn.conversion = path;
|
||
|
return fn;
|
||
|
}
|
||
|
|
||
|
module.exports = function (fromModel) {
|
||
|
const graph = deriveBFS(fromModel);
|
||
|
const conversion = {};
|
||
|
|
||
|
const models = Object.keys(graph);
|
||
|
for (let len = models.length, i = 0; i < len; i++) {
|
||
|
const toModel = models[i];
|
||
|
const node = graph[toModel];
|
||
|
|
||
|
if (node.parent === null) {
|
||
|
// No possible conversion, or this node is the source model.
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
conversion[toModel] = wrapConversion(toModel, graph);
|
||
|
}
|
||
|
|
||
|
return conversion;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 58 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const stripAnsi = __webpack_require__(59);
|
||
|
const isFullwidthCodePoint = __webpack_require__(51);
|
||
|
const emojiRegex = __webpack_require__(61);
|
||
|
|
||
|
const stringWidth = string => {
|
||
|
if (typeof string !== 'string' || string.length === 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
string = stripAnsi(string);
|
||
|
|
||
|
if (string.length === 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
string = string.replace(emojiRegex(), ' ');
|
||
|
|
||
|
let width = 0;
|
||
|
|
||
|
for (let i = 0; i < string.length; i++) {
|
||
|
const code = string.codePointAt(i);
|
||
|
|
||
|
// Ignore control characters
|
||
|
if (code <= 0x1F || (code >= 0x7F && code <= 0x9F)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Ignore combining characters
|
||
|
if (code >= 0x300 && code <= 0x36F) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Surrogates
|
||
|
if (code > 0xFFFF) {
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
width += isFullwidthCodePoint(code) ? 2 : 1;
|
||
|
}
|
||
|
|
||
|
return width;
|
||
|
};
|
||
|
|
||
|
module.exports = stringWidth;
|
||
|
// TODO: remove this in the next major version
|
||
|
module.exports["default"] = stringWidth;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 59 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const ansiRegex = __webpack_require__(60);
|
||
|
|
||
|
module.exports = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 60 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
module.exports = ({onlyFirst = false} = {}) => {
|
||
|
const pattern = [
|
||
|
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
|
||
|
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))'
|
||
|
].join('|');
|
||
|
|
||
|
return new RegExp(pattern, onlyFirst ? undefined : 'g');
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 61 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
|
||
|
module.exports = function () {
|
||
|
// https://mths.be/emoji
|
||
|
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\
|
||
|
};
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 62 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
const electron = __webpack_require__(17);
|
||
|
|
||
|
if (typeof electron === 'string') {
|
||
|
throw new TypeError('Not running in an Electron environment!');
|
||
|
}
|
||
|
|
||
|
const isEnvSet = 'ELECTRON_IS_DEV' in process.env;
|
||
|
const getFromEnv = Number.parseInt(process.env.ELECTRON_IS_DEV, 10) === 1;
|
||
|
|
||
|
module.exports = isEnvSet ? getFromEnv : !electron.app.isPackaged;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 63 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.cleanupPlainText = exports.removeUserAgentSpecifics = exports.openExternal = exports.nativeTabsSupported = exports.linkIsInternal = exports.isWindows = exports.isLinux = exports.isOSX = exports.getCSSToInject = exports.getCounterValue = exports.getAppIcon = exports.debugLog = exports.isUrlShellSafe = exports.INJECT_DIR = void 0;
|
||
|
const fs = __importStar(__webpack_require__(15));
|
||
|
const os = __importStar(__webpack_require__(64));
|
||
|
const path = __importStar(__webpack_require__(14));
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const windowHelpers_1 = __webpack_require__(65);
|
||
|
exports.INJECT_DIR = path.join(__dirname, '..', 'inject');
|
||
|
/**
|
||
|
* Firefox's list of protocols for which opening an external handler is allowed without confirmation.
|
||
|
* Taken from Firefox's. Location might vary in codebase, search for one of them, e.g.
|
||
|
* https://searchfox.org/mozilla-central/search?q=%22xmpp%22&path=&case=false®exp=false
|
||
|
*/
|
||
|
const URL_PROTOCOLS_NOCONFIRMATION_FIREFOX = [
|
||
|
'bitcoin:',
|
||
|
'ftp:',
|
||
|
'ftps:',
|
||
|
'geo:',
|
||
|
'im:',
|
||
|
'irc:',
|
||
|
'ircs:',
|
||
|
'magnet:',
|
||
|
'mailto:',
|
||
|
'matrix:',
|
||
|
'mms:',
|
||
|
'news:',
|
||
|
'nntp:',
|
||
|
'openpgp4fpr:',
|
||
|
'sftp:',
|
||
|
'sip:',
|
||
|
'sms:',
|
||
|
'smsto:',
|
||
|
'ssh:',
|
||
|
'tel:',
|
||
|
'urn:',
|
||
|
'webcal:',
|
||
|
'wtai:',
|
||
|
'xmpp:',
|
||
|
];
|
||
|
/**
|
||
|
* Our extension to Firefox's list. If extending this list too much, we should
|
||
|
* really add a confirmation modal (for now we just block), like browsers do.
|
||
|
* But for now, since nobody shouts at us for bluntly blocking anything else,
|
||
|
* let's keep rolling with it.
|
||
|
*/
|
||
|
const URL_PROTOCOLS_NOCONFIRMATION_EXTRA = ['zoommtg:'];
|
||
|
/**
|
||
|
* List of protocols for which opening an external handler is allowed without confirmation.
|
||
|
* Note: "without confirmation" is currently a lie. It was implemented this way
|
||
|
* as a way to know from user feedback what protocols would cause users to shout,
|
||
|
* but there wasn't much shouting happening, so we currently don't have a confirmation
|
||
|
* mechanism, we just bluntly block. That might need to change at some point.
|
||
|
*/
|
||
|
const URL_PROTOCOLS_NOCONFIRMATION = [
|
||
|
'http:',
|
||
|
'https:',
|
||
|
...URL_PROTOCOLS_NOCONFIRMATION_FIREFOX,
|
||
|
...URL_PROTOCOLS_NOCONFIRMATION_EXTRA,
|
||
|
];
|
||
|
const SHELL_SAFETY_FEEDBACK_STR = 'If you believe this URL should open, you might be right, and our validation might be excessive.' +
|
||
|
'Please share this error & URL at https://github.com/nativefier/nativefier/issues/1459';
|
||
|
function isUrlShellSafe(urlToGo) {
|
||
|
let url;
|
||
|
try {
|
||
|
url = new URL(urlToGo.toLowerCase());
|
||
|
}
|
||
|
catch (err) {
|
||
|
return {
|
||
|
blocked: true,
|
||
|
reason: `URL appears malformed. ${SHELL_SAFETY_FEEDBACK_STR}`,
|
||
|
};
|
||
|
}
|
||
|
if (!URL_PROTOCOLS_NOCONFIRMATION.includes(url.protocol)) {
|
||
|
return {
|
||
|
blocked: true,
|
||
|
reason: `URL protocol is disallowed. ${SHELL_SAFETY_FEEDBACK_STR}`,
|
||
|
};
|
||
|
}
|
||
|
// https://cwe.mitre.org/data/definitions/177.html
|
||
|
if (urlToGo.includes('%00') ||
|
||
|
urlToGo.includes('%0a') ||
|
||
|
urlToGo.includes('%2e') ||
|
||
|
urlToGo.includes('%2f') ||
|
||
|
urlToGo.includes('%5c')) {
|
||
|
return {
|
||
|
blocked: true,
|
||
|
reason: `URL might be malicious. ${SHELL_SAFETY_FEEDBACK_STR}`,
|
||
|
};
|
||
|
}
|
||
|
return { blocked: false };
|
||
|
}
|
||
|
exports.isUrlShellSafe = isUrlShellSafe;
|
||
|
/**
|
||
|
* Helper to print debug messages from the main process in the browser window
|
||
|
*/
|
||
|
function debugLog(browserWindow, message) {
|
||
|
// Need a delay, as it takes time for the preloaded js to be loaded by the window
|
||
|
setTimeout(() => {
|
||
|
browserWindow.webContents.send('debug', message);
|
||
|
}, 3000);
|
||
|
log.debug(message);
|
||
|
}
|
||
|
exports.debugLog = debugLog;
|
||
|
/**
|
||
|
* Helper to determine domain-ish equality for many cases, the trivial ones
|
||
|
* and the trickier ones, e.g. `blog.foo.com` and `shop.foo.com`,
|
||
|
* in a way that is "good enough", and doesn't need a list of SLDs.
|
||
|
* See chat at https://github.com/nativefier/nativefier/pull/1171#pullrequestreview-649132523
|
||
|
*/
|
||
|
function domainify(url) {
|
||
|
// So here's what we're doing here:
|
||
|
// Get the hostname from the url
|
||
|
const hostname = new URL(url).hostname;
|
||
|
// Drop the first section if the domain
|
||
|
const domain = hostname.split('.').slice(1).join('.');
|
||
|
// Check the length, if it's too short, the hostname was probably the domain
|
||
|
// Or if the domain doesn't have a . in it we went too far
|
||
|
if (domain.length < 6 || domain.split('.').length === 0) {
|
||
|
return hostname;
|
||
|
}
|
||
|
// This SHOULD be the domain, but nothing is 100% guaranteed
|
||
|
return domain;
|
||
|
}
|
||
|
function getAppIcon() {
|
||
|
// Prefer ICO under Windows, see
|
||
|
// https://www.electronjs.org/docs/api/browser-window#new-browserwindowoptions
|
||
|
// https://www.electronjs.org/docs/api/native-image#supported-formats
|
||
|
if (isWindows()) {
|
||
|
const ico = path.join(__dirname, '..', 'icon.ico');
|
||
|
if (fs.existsSync(ico)) {
|
||
|
return ico;
|
||
|
}
|
||
|
}
|
||
|
const png = path.join(__dirname, '..', 'icon.png');
|
||
|
if (fs.existsSync(png)) {
|
||
|
return png;
|
||
|
}
|
||
|
}
|
||
|
exports.getAppIcon = getAppIcon;
|
||
|
function getCounterValue(title) {
|
||
|
const itemCountRegex = /[([{]([\d.,:]*)\+?[}\])]/;
|
||
|
const match = itemCountRegex.exec(title);
|
||
|
return match ? match[1] : undefined;
|
||
|
}
|
||
|
exports.getCounterValue = getCounterValue;
|
||
|
function getCSSToInject() {
|
||
|
let cssToInject = '';
|
||
|
const cssFiles = fs
|
||
|
.readdirSync(exports.INJECT_DIR, { withFileTypes: true })
|
||
|
.filter((injectFile) => injectFile.isFile() && injectFile.name.endsWith('.css'))
|
||
|
.map((cssFileStat) => path.resolve(path.join(exports.INJECT_DIR, cssFileStat.name)));
|
||
|
for (const cssFile of cssFiles) {
|
||
|
log.debug('Injecting CSS file', cssFile);
|
||
|
const cssFileData = fs.readFileSync(cssFile);
|
||
|
cssToInject += `/* ${cssFile} */\n\n ${cssFileData.toString()}\n\n`;
|
||
|
}
|
||
|
return cssToInject;
|
||
|
}
|
||
|
exports.getCSSToInject = getCSSToInject;
|
||
|
function isOSX() {
|
||
|
return os.platform() === 'darwin';
|
||
|
}
|
||
|
exports.isOSX = isOSX;
|
||
|
function isLinux() {
|
||
|
return os.platform() === 'linux';
|
||
|
}
|
||
|
exports.isLinux = isLinux;
|
||
|
function isWindows() {
|
||
|
return os.platform() === 'win32';
|
||
|
}
|
||
|
exports.isWindows = isWindows;
|
||
|
function isInternalLoginPage(url) {
|
||
|
// Making changes? Remember to update the tests in helpers.test.ts and in API.md
|
||
|
const internalLoginPagesArray = [
|
||
|
'amazon\\.[a-zA-Z\\.]*/[a-zA-Z\\/]*signin',
|
||
|
`facebook\\.[a-zA-Z\\.]*\\/login`,
|
||
|
'github\\.[a-zA-Z\\.]*\\/(?:login|session)',
|
||
|
'accounts\\.google\\.[a-zA-Z\\.]*',
|
||
|
'mail\\.google\\.[a-zA-Z\\.]*\\/accounts/SetOSID',
|
||
|
'linkedin\\.[a-zA-Z\\.]*/uas/login',
|
||
|
'login\\.live\\.[a-zA-Z\\.]*',
|
||
|
'login\\.microsoftonline\\.[a-zA-Z\\.]*',
|
||
|
'okta\\.[a-zA-Z\\.]*',
|
||
|
'twitter\\.[a-zA-Z\\.]*/oauth/authenticate',
|
||
|
'appleid\\.apple\\.com/auth/authorize',
|
||
|
'(?:id|auth)\\.atlassian\\.[a-zA-Z]+',
|
||
|
'.*\\.workspaceair\\.com',
|
||
|
'.*\\.securid\\.com', // SecurID for VMWare Workspace One SSO
|
||
|
];
|
||
|
// Making changes? Remember to update the tests in helpers.test.ts and in API.md
|
||
|
const regex = RegExp(internalLoginPagesArray.join('|'));
|
||
|
return regex.test(url);
|
||
|
}
|
||
|
function linkIsInternal(currentUrl, newUrl, internalUrlRegex, isStrictInternalUrlsEnabled) {
|
||
|
log.debug('linkIsInternal', { currentUrl, newUrl, internalUrlRegex });
|
||
|
if (newUrl.split('#')[0] === 'about:blank') {
|
||
|
return true;
|
||
|
}
|
||
|
if (isInternalLoginPage(newUrl)) {
|
||
|
return true;
|
||
|
}
|
||
|
if (internalUrlRegex) {
|
||
|
const regex = RegExp(internalUrlRegex);
|
||
|
if (regex.test(newUrl)) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
if (isStrictInternalUrlsEnabled) {
|
||
|
return currentUrl == newUrl;
|
||
|
}
|
||
|
try {
|
||
|
// Consider as "same domain-ish", without TLD/SLD list:
|
||
|
// 1. app.foo.com and foo.com
|
||
|
// 2. www.foo.com and foo.com
|
||
|
// 3. www.foo.com and app.foo.com
|
||
|
// Only use the tld and the main domain for domain-ish test
|
||
|
// Enables domain-ish equality for blog.foo.com and shop.foo.com
|
||
|
return domainify(currentUrl) === domainify(newUrl);
|
||
|
}
|
||
|
catch (err) {
|
||
|
log.error('Failed to parse domains as determining if link is internal. From:', currentUrl, 'To:', newUrl, err);
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
exports.linkIsInternal = linkIsInternal;
|
||
|
function nativeTabsSupported() {
|
||
|
return isOSX();
|
||
|
}
|
||
|
exports.nativeTabsSupported = nativeTabsSupported;
|
||
|
/**
|
||
|
* Open the given external protocol URL in the desktop's default manner
|
||
|
* (e.g. `mailto:` URLs in the user's default mail agent), with extra validation.
|
||
|
*/
|
||
|
function openExternal(url, options) {
|
||
|
const urlShellSafety = isUrlShellSafe(url);
|
||
|
log.debug('openExternal', { url, options, urlShellSafety });
|
||
|
if (urlShellSafety.blocked) {
|
||
|
return new Promise((resolve) => {
|
||
|
(0, windowHelpers_1.showNavigationBlockedMessage)(`Navigation blocked to ${url}\n\n${urlShellSafety.reason}`)
|
||
|
.then(() => resolve())
|
||
|
.catch((err) => {
|
||
|
throw err;
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
return electron_1.shell.openExternal(url, options);
|
||
|
}
|
||
|
exports.openExternal = openExternal;
|
||
|
function removeUserAgentSpecifics(userAgentFallback, appName, appVersion) {
|
||
|
// Electron userAgentFallback is the user agent used if none is specified when creating a window.
|
||
|
// For our purposes, it's useful because its format is similar enough to a real Chrome's user agent to not need
|
||
|
// to infer the userAgent. userAgentFallback normally looks like this:
|
||
|
// Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) app-nativefier-804458/1.0.0 Chrome/89.0.4389.128 Electron/12.0.7 Safari/537.36
|
||
|
// We just need to strip out the appName/1.0.0 and Electron/electronVersion
|
||
|
return userAgentFallback
|
||
|
.replace(`Electron/${process.versions.electron} `, '')
|
||
|
.replace(`${appName}/${appVersion} `, '');
|
||
|
}
|
||
|
exports.removeUserAgentSpecifics = removeUserAgentSpecifics;
|
||
|
/** Removes extra spaces from a text */
|
||
|
function cleanupPlainText(text) {
|
||
|
return text.trim().replace(/\s+/g, ' ');
|
||
|
}
|
||
|
exports.cleanupPlainText = cleanupPlainText;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 64 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("os");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 65 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.zoomIn = exports.zoomReset = exports.zoomOut = exports.withFocusedWindow = exports.setProxyRules = exports.sendParamsOnDidFinishLoad = exports.injectCSS = exports.hideWindow = exports.goToURL = exports.goForward = exports.goBack = exports.getDefaultWindowOptions = exports.getCurrentURL = exports.createNewWindow = exports.createNewTab = exports.createAboutBlankWindow = exports.clearCache = exports.clearAppData = exports.showNavigationBlockedMessage = exports.adjustWindowZoom = void 0;
|
||
|
const path_1 = __importDefault(__webpack_require__(14));
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const ZOOM_INTERVAL = 0.1;
|
||
|
function adjustWindowZoom(adjustment) {
|
||
|
withFocusedWindow((focusedWindow) => {
|
||
|
focusedWindow.webContents.zoomFactor =
|
||
|
focusedWindow.webContents.zoomFactor + adjustment;
|
||
|
});
|
||
|
}
|
||
|
exports.adjustWindowZoom = adjustWindowZoom;
|
||
|
function showNavigationBlockedMessage(message) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
withFocusedWindow((focusedWindow) => {
|
||
|
electron_1.dialog
|
||
|
.showMessageBox(focusedWindow, {
|
||
|
message,
|
||
|
type: 'error',
|
||
|
title: 'Navigation blocked',
|
||
|
})
|
||
|
.then((result) => resolve(result))
|
||
|
.catch((err) => {
|
||
|
reject(err);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
exports.showNavigationBlockedMessage = showNavigationBlockedMessage;
|
||
|
async function clearAppData(window) {
|
||
|
const response = await electron_1.dialog.showMessageBox(window, {
|
||
|
type: 'warning',
|
||
|
buttons: ['Yes', 'Cancel'],
|
||
|
defaultId: 1,
|
||
|
title: 'Clear cache confirmation',
|
||
|
message: 'This will clear all data (cookies, local storage etc) from this app. Are you sure you wish to proceed?',
|
||
|
});
|
||
|
if (response.response !== 0) {
|
||
|
return;
|
||
|
}
|
||
|
await clearCache(window);
|
||
|
}
|
||
|
exports.clearAppData = clearAppData;
|
||
|
async function clearCache(window) {
|
||
|
const { session } = window.webContents;
|
||
|
await session.clearStorageData();
|
||
|
await session.clearCache();
|
||
|
}
|
||
|
exports.clearCache = clearCache;
|
||
|
function createAboutBlankWindow(options, setupWindow, parent) {
|
||
|
const window = createNewWindow({ ...options, show: false }, setupWindow, 'about:blank', parent);
|
||
|
window.webContents.once('did-stop-loading', () => {
|
||
|
if (window.webContents.getURL() === 'about:blank') {
|
||
|
window.close();
|
||
|
}
|
||
|
else {
|
||
|
window.show();
|
||
|
}
|
||
|
});
|
||
|
return window;
|
||
|
}
|
||
|
exports.createAboutBlankWindow = createAboutBlankWindow;
|
||
|
function createNewTab(options, setupWindow, url, foreground, parent) {
|
||
|
log.debug('createNewTab', { url, foreground, parent });
|
||
|
return withFocusedWindow((focusedWindow) => {
|
||
|
const newTab = createNewWindow(options, setupWindow, url, parent);
|
||
|
focusedWindow.addTabbedWindow(newTab);
|
||
|
if (!foreground) {
|
||
|
focusedWindow.focus();
|
||
|
}
|
||
|
return newTab;
|
||
|
});
|
||
|
}
|
||
|
exports.createNewTab = createNewTab;
|
||
|
function createNewWindow(options, setupWindow, url, parent) {
|
||
|
log.debug('createNewWindow', { url, parent });
|
||
|
const window = new electron_1.BrowserWindow({
|
||
|
parent,
|
||
|
...getDefaultWindowOptions(options),
|
||
|
});
|
||
|
setupWindow(options, window);
|
||
|
window.loadURL(url).catch((err) => log.error('window.loadURL ERROR', err));
|
||
|
return window;
|
||
|
}
|
||
|
exports.createNewWindow = createNewWindow;
|
||
|
function getCurrentURL() {
|
||
|
return withFocusedWindow((focusedWindow) => focusedWindow.webContents.getURL());
|
||
|
}
|
||
|
exports.getCurrentURL = getCurrentURL;
|
||
|
function getDefaultWindowOptions(options) {
|
||
|
var _a, _b;
|
||
|
const browserwindowOptions = {
|
||
|
...options.browserwindowOptions,
|
||
|
};
|
||
|
// We're going to remove this and merge it separately into DEFAULT_WINDOW_OPTIONS.webPreferences
|
||
|
// Otherwise the browserwindowOptions.webPreferences object will completely replace the
|
||
|
// webPreferences specified in the DEFAULT_WINDOW_OPTIONS with itself
|
||
|
delete browserwindowOptions.webPreferences;
|
||
|
const webPreferences = {
|
||
|
...((_b = (_a = options.browserwindowOptions) === null || _a === void 0 ? void 0 : _a.webPreferences) !== null && _b !== void 0 ? _b : {}),
|
||
|
};
|
||
|
const defaultOptions = {
|
||
|
fullscreenable: true,
|
||
|
tabbingIdentifier: (0, helpers_1.nativeTabsSupported)() ? options.name : undefined,
|
||
|
title: options.name,
|
||
|
webPreferences: {
|
||
|
javascript: true,
|
||
|
nodeIntegration: false,
|
||
|
preload: path_1.default.join(__dirname, 'preload.js'),
|
||
|
plugins: true,
|
||
|
webSecurity: !options.insecure,
|
||
|
zoomFactor: options.zoom,
|
||
|
// `contextIsolation` was switched to true in Electron 12, which:
|
||
|
// 1. Breaks access to global variables in `--inject`-ed scripts:
|
||
|
// https://github.com/nativefier/nativefier/issues/1269
|
||
|
// 2. Might break notifications under Windows, although this was refuted:
|
||
|
// https://github.com/nativefier/nativefier/issues/1292
|
||
|
// So, it was flipped to false in https://github.com/nativefier/nativefier/pull/1308
|
||
|
//
|
||
|
// If attempting to set it back to `true` (for security),
|
||
|
// do test exhaustively these two areas, and more.
|
||
|
contextIsolation: false,
|
||
|
...webPreferences,
|
||
|
},
|
||
|
...browserwindowOptions,
|
||
|
};
|
||
|
log.debug('getDefaultWindowOptions', {
|
||
|
options,
|
||
|
webPreferences,
|
||
|
defaultOptions,
|
||
|
});
|
||
|
return defaultOptions;
|
||
|
}
|
||
|
exports.getDefaultWindowOptions = getDefaultWindowOptions;
|
||
|
function goBack() {
|
||
|
log.debug('onGoBack');
|
||
|
withFocusedWindow((focusedWindow) => {
|
||
|
focusedWindow.webContents.goBack();
|
||
|
});
|
||
|
}
|
||
|
exports.goBack = goBack;
|
||
|
function goForward() {
|
||
|
log.debug('onGoForward');
|
||
|
withFocusedWindow((focusedWindow) => {
|
||
|
focusedWindow.webContents.goForward();
|
||
|
});
|
||
|
}
|
||
|
exports.goForward = goForward;
|
||
|
function goToURL(url) {
|
||
|
return withFocusedWindow((focusedWindow) => focusedWindow.loadURL(url));
|
||
|
}
|
||
|
exports.goToURL = goToURL;
|
||
|
function hideWindow(window, event, fastQuit, tray) {
|
||
|
if ((0, helpers_1.isOSX)() && !fastQuit) {
|
||
|
// this is called when exiting from clicking the cross button on the window
|
||
|
event.preventDefault();
|
||
|
window.hide();
|
||
|
}
|
||
|
else if (!fastQuit && tray !== 'false') {
|
||
|
event.preventDefault();
|
||
|
window.hide();
|
||
|
}
|
||
|
// will close the window on other platforms
|
||
|
}
|
||
|
exports.hideWindow = hideWindow;
|
||
|
function injectCSS(browserWindow) {
|
||
|
const cssToInject = (0, helpers_1.getCSSToInject)();
|
||
|
if (!cssToInject) {
|
||
|
return;
|
||
|
}
|
||
|
browserWindow.webContents.on('did-navigate', () => {
|
||
|
log.debug('browserWindow.webContents.did-navigate', browserWindow.webContents.getURL());
|
||
|
browserWindow.webContents
|
||
|
.insertCSS(cssToInject)
|
||
|
.catch((err) => log.error('browserWindow.webContents.insertCSS', err));
|
||
|
// We must inject css early enough; so onResponseStarted is a good place.
|
||
|
browserWindow.webContents.session.webRequest.onResponseStarted({ urls: [] }, // Pass an empty filter list; null will not match _any_ urls
|
||
|
(details) => {
|
||
|
log.debug('onResponseStarted', {
|
||
|
resourceType: details.resourceType,
|
||
|
url: details.url,
|
||
|
});
|
||
|
injectCSSIntoResponse(details, cssToInject).catch((err) => {
|
||
|
log.error('injectCSSIntoResponse ERROR', err);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
exports.injectCSS = injectCSS;
|
||
|
function injectCSSIntoResponse(details, cssToInject) {
|
||
|
var _a;
|
||
|
const contentType = details.responseHeaders && 'content-type' in details.responseHeaders
|
||
|
? details.responseHeaders['content-type'][0]
|
||
|
: undefined;
|
||
|
log.debug('injectCSSIntoResponse', { details, cssToInject, contentType });
|
||
|
// We go with a denylist rather than a whitelist (e.g. only text/html)
|
||
|
// to avoid "whoops I didn't think this should have been CSS-injected" cases
|
||
|
const nonInjectableContentTypes = [
|
||
|
/application\/.*/,
|
||
|
/font\/.*/,
|
||
|
/image\/.*/,
|
||
|
];
|
||
|
const nonInjectableResourceTypes = ['image', 'script', 'stylesheet', 'xhr'];
|
||
|
if ((contentType &&
|
||
|
((_a = nonInjectableContentTypes.filter((x) => {
|
||
|
const matches = x.exec(contentType);
|
||
|
return matches && (matches === null || matches === void 0 ? void 0 : matches.length) > 0;
|
||
|
})) === null || _a === void 0 ? void 0 : _a.length) > 0) ||
|
||
|
nonInjectableResourceTypes.includes(details.resourceType) ||
|
||
|
!details.webContents) {
|
||
|
log.debug(`Skipping CSS injection for:\n${details.url}\nwith resourceType ${details.resourceType} and content-type ${contentType}`);
|
||
|
return Promise.resolve(undefined);
|
||
|
}
|
||
|
log.debug(`Injecting CSS for:\n${details.url}\nwith resourceType ${details.resourceType} and content-type ${contentType}`);
|
||
|
return details.webContents.insertCSS(cssToInject);
|
||
|
}
|
||
|
function sendParamsOnDidFinishLoad(options, window) {
|
||
|
window.webContents.on('did-finish-load', () => {
|
||
|
log.debug('sendParamsOnDidFinishLoad.window.webContents.did-finish-load', window.webContents.getURL());
|
||
|
// In children windows too: Restore pinch-to-zoom, disabled by default in recent Electron.
|
||
|
// See https://github.com/nativefier/nativefier/issues/379#issuecomment-598612128
|
||
|
// and https://github.com/electron/electron/pull/12679
|
||
|
window.webContents
|
||
|
.setVisualZoomLevelLimits(1, 3)
|
||
|
.catch((err) => log.error('webContents.setVisualZoomLevelLimits', err));
|
||
|
window.webContents.send('params', JSON.stringify(options));
|
||
|
});
|
||
|
}
|
||
|
exports.sendParamsOnDidFinishLoad = sendParamsOnDidFinishLoad;
|
||
|
function setProxyRules(window, proxyRules) {
|
||
|
window.webContents.session
|
||
|
.setProxy({
|
||
|
proxyRules,
|
||
|
pacScript: '',
|
||
|
proxyBypassRules: '',
|
||
|
})
|
||
|
.catch((err) => log.error('session.setProxy ERROR', err));
|
||
|
}
|
||
|
exports.setProxyRules = setProxyRules;
|
||
|
function withFocusedWindow(block) {
|
||
|
const focusedWindow = electron_1.BrowserWindow.getFocusedWindow();
|
||
|
if (focusedWindow) {
|
||
|
return block(focusedWindow);
|
||
|
}
|
||
|
return undefined;
|
||
|
}
|
||
|
exports.withFocusedWindow = withFocusedWindow;
|
||
|
function zoomOut() {
|
||
|
log.debug('zoomOut');
|
||
|
adjustWindowZoom(-ZOOM_INTERVAL);
|
||
|
}
|
||
|
exports.zoomOut = zoomOut;
|
||
|
function zoomReset(options) {
|
||
|
log.debug('zoomReset');
|
||
|
withFocusedWindow((focusedWindow) => {
|
||
|
var _a;
|
||
|
focusedWindow.webContents.zoomFactor = (_a = options.zoom) !== null && _a !== void 0 ? _a : 1.0;
|
||
|
});
|
||
|
}
|
||
|
exports.zoomReset = zoomReset;
|
||
|
function zoomIn() {
|
||
|
log.debug('zoomIn');
|
||
|
adjustWindowZoom(ZOOM_INTERVAL);
|
||
|
}
|
||
|
exports.zoomIn = zoomIn;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 66 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.setupNativefierWindow = exports.onWillPreventUnload = exports.onWillNavigate = exports.onNewWindowHelper = exports.onNewWindow = void 0;
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const windowHelpers_1 = __webpack_require__(65);
|
||
|
function onNewWindow(options, setupWindow, event, urlToGo, frameName, disposition, parent) {
|
||
|
log.debug('onNewWindow', {
|
||
|
event,
|
||
|
urlToGo,
|
||
|
frameName,
|
||
|
disposition,
|
||
|
parent,
|
||
|
});
|
||
|
const preventDefault = (newGuest) => {
|
||
|
log.debug('onNewWindow.preventDefault', { newGuest, event });
|
||
|
if (event.preventDefault) {
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
if (newGuest) {
|
||
|
event.newGuest = newGuest;
|
||
|
}
|
||
|
};
|
||
|
return onNewWindowHelper(options, setupWindow, urlToGo, disposition, preventDefault, parent);
|
||
|
}
|
||
|
exports.onNewWindow = onNewWindow;
|
||
|
function onNewWindowHelper(options, setupWindow, urlToGo, disposition, preventDefault, parent) {
|
||
|
log.debug('onNewWindowHelper', {
|
||
|
options,
|
||
|
urlToGo,
|
||
|
disposition,
|
||
|
preventDefault,
|
||
|
parent,
|
||
|
});
|
||
|
try {
|
||
|
if (!(0, helpers_1.linkIsInternal)(options.targetUrl, urlToGo, options.internalUrls, options.strictInternalUrls)) {
|
||
|
preventDefault();
|
||
|
if (options.blockExternalUrls) {
|
||
|
return new Promise((resolve) => {
|
||
|
(0, windowHelpers_1.showNavigationBlockedMessage)(`Navigation to external URL blocked by options: ${urlToGo}`)
|
||
|
.then(() => resolve())
|
||
|
.catch((err) => {
|
||
|
throw err;
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
return (0, helpers_1.openExternal)(urlToGo);
|
||
|
}
|
||
|
}
|
||
|
// Normally the following would be:
|
||
|
// if (urlToGo.startsWith('about:blank'))...
|
||
|
// But due to a bug we resolved in https://github.com/nativefier/nativefier/issues/1197
|
||
|
// Some sites use about:blank#something to use as placeholder windows to fill
|
||
|
// with content via JavaScript. So we'll stay specific for now...
|
||
|
else if (['about:blank', 'about:blank#blocked'].includes(urlToGo)) {
|
||
|
return Promise.resolve(preventDefault((0, windowHelpers_1.createAboutBlankWindow)(options, setupWindow, parent)));
|
||
|
}
|
||
|
else if ((0, helpers_1.nativeTabsSupported)()) {
|
||
|
return Promise.resolve(preventDefault((0, windowHelpers_1.createNewTab)(options, setupWindow, urlToGo, disposition === 'foreground-tab', parent)));
|
||
|
}
|
||
|
return Promise.resolve(undefined);
|
||
|
}
|
||
|
catch (err) {
|
||
|
return Promise.reject(err);
|
||
|
}
|
||
|
}
|
||
|
exports.onNewWindowHelper = onNewWindowHelper;
|
||
|
function onWillNavigate(options, event, urlToGo) {
|
||
|
log.debug('onWillNavigate', urlToGo);
|
||
|
if (!(0, helpers_1.linkIsInternal)(options.targetUrl, urlToGo, options.internalUrls, options.strictInternalUrls)) {
|
||
|
event.preventDefault();
|
||
|
if (options.blockExternalUrls) {
|
||
|
return new Promise((resolve) => {
|
||
|
(0, windowHelpers_1.showNavigationBlockedMessage)(`Navigation to external URL blocked by options: ${urlToGo}`)
|
||
|
.then(() => resolve())
|
||
|
.catch((err) => {
|
||
|
throw err;
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
return (0, helpers_1.openExternal)(urlToGo);
|
||
|
}
|
||
|
}
|
||
|
return Promise.resolve(undefined);
|
||
|
}
|
||
|
exports.onWillNavigate = onWillNavigate;
|
||
|
function onWillPreventUnload(event) {
|
||
|
var _a;
|
||
|
log.debug('onWillPreventUnload', event);
|
||
|
const webContents = event.sender;
|
||
|
if (!webContents) {
|
||
|
return;
|
||
|
}
|
||
|
const browserWindow = (_a = electron_1.BrowserWindow.fromWebContents(webContents)) !== null && _a !== void 0 ? _a : electron_1.BrowserWindow.getFocusedWindow();
|
||
|
if (browserWindow) {
|
||
|
const choice = electron_1.dialog.showMessageBoxSync(browserWindow, {
|
||
|
type: 'question',
|
||
|
buttons: ['Proceed', 'Stay'],
|
||
|
message: 'You may have unsaved changes, are you sure you want to proceed?',
|
||
|
title: 'Changes you made may not be saved.',
|
||
|
defaultId: 0,
|
||
|
cancelId: 1,
|
||
|
});
|
||
|
if (choice === 0) {
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
exports.onWillPreventUnload = onWillPreventUnload;
|
||
|
function setupNativefierWindow(options, window) {
|
||
|
if (options.proxyRules) {
|
||
|
(0, windowHelpers_1.setProxyRules)(window, options.proxyRules);
|
||
|
}
|
||
|
(0, windowHelpers_1.injectCSS)(window);
|
||
|
window.webContents.on('will-navigate', (event, url) => {
|
||
|
onWillNavigate(options, event, url).catch((err) => {
|
||
|
log.error('window.webContents.on.will-navigate ERROR', err);
|
||
|
event.preventDefault();
|
||
|
});
|
||
|
});
|
||
|
window.webContents.on('will-prevent-unload', onWillPreventUnload);
|
||
|
(0, windowHelpers_1.sendParamsOnDidFinishLoad)(options, window);
|
||
|
}
|
||
|
exports.setupNativefierWindow = setupNativefierWindow;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 67 */
|
||
|
/***/ ((__unused_webpack_module, exports) => {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.outputOptionsToWindowOptions = void 0;
|
||
|
function outputOptionsToWindowOptions(options) {
|
||
|
var _a, _b;
|
||
|
return {
|
||
|
...options,
|
||
|
insecure: (_a = options.insecure) !== null && _a !== void 0 ? _a : false,
|
||
|
zoom: (_b = options.zoom) !== null && _b !== void 0 ? _b : 1.0,
|
||
|
};
|
||
|
}
|
||
|
exports.outputOptionsToWindowOptions = outputOptionsToWindowOptions;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 68 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.generateMenu = exports.createMenu = void 0;
|
||
|
const fs = __importStar(__webpack_require__(15));
|
||
|
const path_1 = __importDefault(__webpack_require__(14));
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
const windowHelpers_1 = __webpack_require__(65);
|
||
|
function createMenu(options, mainWindow) {
|
||
|
log.debug('createMenu', { options });
|
||
|
const menuTemplate = generateMenu(options, mainWindow);
|
||
|
injectBookmarks(menuTemplate);
|
||
|
const menu = electron_1.Menu.buildFromTemplate(menuTemplate);
|
||
|
electron_1.Menu.setApplicationMenu(menu);
|
||
|
}
|
||
|
exports.createMenu = createMenu;
|
||
|
function generateMenu(options, mainWindow) {
|
||
|
const { nativefierVersion, zoom, disableDevTools } = options;
|
||
|
const zoomResetLabel = !zoom || zoom === 1.0
|
||
|
? 'Reset Zoom'
|
||
|
: `Reset Zoom (to ${(zoom * 100).toFixed(1)}%, set at build time)`;
|
||
|
const editMenu = {
|
||
|
label: '&Edit',
|
||
|
submenu: [
|
||
|
{
|
||
|
label: 'Undo',
|
||
|
accelerator: 'CmdOrCtrl+Z',
|
||
|
role: 'undo',
|
||
|
},
|
||
|
{
|
||
|
label: 'Redo',
|
||
|
accelerator: 'Shift+CmdOrCtrl+Z',
|
||
|
role: 'redo',
|
||
|
},
|
||
|
{
|
||
|
type: 'separator',
|
||
|
},
|
||
|
{
|
||
|
label: 'Cut',
|
||
|
accelerator: 'CmdOrCtrl+X',
|
||
|
role: 'cut',
|
||
|
},
|
||
|
{
|
||
|
label: 'Copy',
|
||
|
accelerator: 'CmdOrCtrl+C',
|
||
|
role: 'copy',
|
||
|
},
|
||
|
{
|
||
|
label: 'Copy as Plain Text',
|
||
|
accelerator: 'CmdOrCtrl+Shift+C',
|
||
|
click: () => {
|
||
|
// We use clipboard.readText to strip down formatting
|
||
|
const text = electron_1.clipboard.readText('selection');
|
||
|
electron_1.clipboard.writeText((0, helpers_1.cleanupPlainText)(text), 'clipboard');
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
label: 'Copy Current URL',
|
||
|
accelerator: 'CmdOrCtrl+L',
|
||
|
click: () => electron_1.clipboard.writeText((0, windowHelpers_1.getCurrentURL)()),
|
||
|
},
|
||
|
{
|
||
|
label: 'Paste',
|
||
|
accelerator: 'CmdOrCtrl+V',
|
||
|
role: 'paste',
|
||
|
},
|
||
|
{
|
||
|
label: 'Paste and Match Style',
|
||
|
// https://github.com/nativefier/nativefier/issues/404
|
||
|
// Apple's HIG lists this shortcut for paste and match style
|
||
|
// https://support.apple.com/en-us/HT209651
|
||
|
accelerator: (0, helpers_1.isOSX)() ? 'Option+Shift+Cmd+V' : 'Ctrl+Shift+V',
|
||
|
role: 'pasteAndMatchStyle',
|
||
|
},
|
||
|
{
|
||
|
label: 'Select All',
|
||
|
accelerator: 'CmdOrCtrl+A',
|
||
|
role: 'selectAll',
|
||
|
},
|
||
|
{
|
||
|
label: 'Clear App Data',
|
||
|
click: (item, focusedWindow) => {
|
||
|
log.debug('Clear App Data.click', {
|
||
|
item,
|
||
|
focusedWindow,
|
||
|
mainWindow,
|
||
|
});
|
||
|
if (!focusedWindow) {
|
||
|
focusedWindow = mainWindow;
|
||
|
}
|
||
|
(0, windowHelpers_1.clearAppData)(focusedWindow).catch((err) => log.error('clearAppData ERROR', err));
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
const viewMenu = {
|
||
|
label: '&View',
|
||
|
submenu: [
|
||
|
{
|
||
|
label: 'Back',
|
||
|
accelerator: (0, helpers_1.isOSX)() ? 'Cmd+Left' : 'Alt+Left',
|
||
|
click: windowHelpers_1.goBack,
|
||
|
},
|
||
|
{
|
||
|
label: 'BackAdditionalShortcut',
|
||
|
visible: false,
|
||
|
acceleratorWorksWhenHidden: true,
|
||
|
accelerator: 'CmdOrCtrl+[',
|
||
|
click: windowHelpers_1.goBack,
|
||
|
},
|
||
|
{
|
||
|
label: 'Forward',
|
||
|
accelerator: (0, helpers_1.isOSX)() ? 'Cmd+Right' : 'Alt+Right',
|
||
|
click: windowHelpers_1.goForward,
|
||
|
},
|
||
|
{
|
||
|
label: 'ForwardAdditionalShortcut',
|
||
|
visible: false,
|
||
|
acceleratorWorksWhenHidden: true,
|
||
|
accelerator: 'CmdOrCtrl+]',
|
||
|
click: windowHelpers_1.goForward,
|
||
|
},
|
||
|
{
|
||
|
label: 'Reload',
|
||
|
role: 'reload',
|
||
|
},
|
||
|
{
|
||
|
type: 'separator',
|
||
|
},
|
||
|
{
|
||
|
label: 'Toggle Full Screen',
|
||
|
accelerator: (0, helpers_1.isOSX)() ? 'Ctrl+Cmd+F' : 'F11',
|
||
|
enabled: mainWindow.isFullScreenable() || (0, helpers_1.isOSX)(),
|
||
|
visible: mainWindow.isFullScreenable() || (0, helpers_1.isOSX)(),
|
||
|
click: (item, focusedWindow) => {
|
||
|
log.debug('Toggle Full Screen.click()', {
|
||
|
item,
|
||
|
focusedWindow,
|
||
|
isFullScreen: focusedWindow === null || focusedWindow === void 0 ? void 0 : focusedWindow.isFullScreen(),
|
||
|
isFullScreenable: focusedWindow === null || focusedWindow === void 0 ? void 0 : focusedWindow.isFullScreenable(),
|
||
|
});
|
||
|
if (!focusedWindow) {
|
||
|
focusedWindow = mainWindow;
|
||
|
}
|
||
|
if (focusedWindow.isFullScreenable()) {
|
||
|
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
|
||
|
}
|
||
|
else if ((0, helpers_1.isOSX)()) {
|
||
|
focusedWindow.setSimpleFullScreen(!focusedWindow.isSimpleFullScreen());
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
label: 'Zoom In',
|
||
|
accelerator: 'CmdOrCtrl+=',
|
||
|
click: windowHelpers_1.zoomIn,
|
||
|
},
|
||
|
{
|
||
|
label: 'ZoomInAdditionalShortcut',
|
||
|
visible: false,
|
||
|
acceleratorWorksWhenHidden: true,
|
||
|
accelerator: 'CmdOrCtrl+numadd',
|
||
|
click: windowHelpers_1.zoomIn,
|
||
|
},
|
||
|
{
|
||
|
label: 'Zoom Out',
|
||
|
accelerator: 'CmdOrCtrl+-',
|
||
|
click: windowHelpers_1.zoomOut,
|
||
|
},
|
||
|
{
|
||
|
label: 'ZoomOutAdditionalShortcut',
|
||
|
visible: false,
|
||
|
acceleratorWorksWhenHidden: true,
|
||
|
accelerator: 'CmdOrCtrl+numsub',
|
||
|
click: windowHelpers_1.zoomOut,
|
||
|
},
|
||
|
{
|
||
|
label: zoomResetLabel,
|
||
|
accelerator: 'CmdOrCtrl+0',
|
||
|
click: () => (0, windowHelpers_1.zoomReset)(options),
|
||
|
},
|
||
|
{
|
||
|
label: 'ZoomResetAdditionalShortcut',
|
||
|
visible: false,
|
||
|
acceleratorWorksWhenHidden: true,
|
||
|
accelerator: 'CmdOrCtrl+num0',
|
||
|
click: () => (0, windowHelpers_1.zoomReset)(options),
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
if (!disableDevTools) {
|
||
|
viewMenu.submenu.push({
|
||
|
type: 'separator',
|
||
|
}, {
|
||
|
label: 'Toggle Developer Tools',
|
||
|
accelerator: (0, helpers_1.isOSX)() ? 'Alt+Cmd+I' : 'Ctrl+Shift+I',
|
||
|
click: (item, focusedWindow) => {
|
||
|
log.debug('Toggle Developer Tools.click()', { item, focusedWindow });
|
||
|
if (!focusedWindow) {
|
||
|
focusedWindow = mainWindow;
|
||
|
}
|
||
|
focusedWindow.webContents.toggleDevTools();
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
const windowMenu = {
|
||
|
label: '&Window',
|
||
|
role: 'window',
|
||
|
submenu: [
|
||
|
{
|
||
|
label: 'Minimize',
|
||
|
accelerator: 'CmdOrCtrl+M',
|
||
|
role: 'minimize',
|
||
|
},
|
||
|
{
|
||
|
label: 'Close',
|
||
|
accelerator: 'CmdOrCtrl+W',
|
||
|
role: 'close',
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
const helpMenu = {
|
||
|
label: '&Help',
|
||
|
role: 'help',
|
||
|
submenu: [
|
||
|
{
|
||
|
label: `Built with Nativefier v${nativefierVersion}`,
|
||
|
click: () => {
|
||
|
(0, helpers_1.openExternal)('https://github.com/nativefier/nativefier').catch((err) => log.error('Built with Nativefier v${nativefierVersion}.click ERROR', err));
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
label: 'Report an Issue',
|
||
|
click: () => {
|
||
|
(0, helpers_1.openExternal)('https://github.com/nativefier/nativefier/issues').catch((err) => log.error('Report an Issue.click ERROR', err));
|
||
|
},
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
let menuTemplate;
|
||
|
if ((0, helpers_1.isOSX)()) {
|
||
|
const electronMenu = {
|
||
|
label: 'E&lectron',
|
||
|
submenu: [
|
||
|
{
|
||
|
label: 'Services',
|
||
|
role: 'services',
|
||
|
submenu: [],
|
||
|
},
|
||
|
{
|
||
|
type: 'separator',
|
||
|
},
|
||
|
{
|
||
|
label: 'Hide App',
|
||
|
accelerator: 'Cmd+H',
|
||
|
role: 'hide',
|
||
|
},
|
||
|
{
|
||
|
label: 'Hide Others',
|
||
|
accelerator: 'Cmd+Shift+H',
|
||
|
role: 'hideOthers',
|
||
|
},
|
||
|
{
|
||
|
label: 'Show All',
|
||
|
role: 'unhide',
|
||
|
},
|
||
|
{
|
||
|
type: 'separator',
|
||
|
},
|
||
|
{
|
||
|
label: 'Quit',
|
||
|
accelerator: 'Cmd+Q',
|
||
|
role: 'quit',
|
||
|
},
|
||
|
],
|
||
|
};
|
||
|
windowMenu.submenu.push({
|
||
|
type: 'separator',
|
||
|
}, {
|
||
|
label: 'Bring All to Front',
|
||
|
role: 'front',
|
||
|
});
|
||
|
menuTemplate = [electronMenu, editMenu, viewMenu, windowMenu, helpMenu];
|
||
|
}
|
||
|
else {
|
||
|
menuTemplate = [editMenu, viewMenu, windowMenu, helpMenu];
|
||
|
}
|
||
|
return menuTemplate;
|
||
|
}
|
||
|
exports.generateMenu = generateMenu;
|
||
|
function injectBookmarks(menuTemplate) {
|
||
|
const bookmarkConfigPath = path_1.default.join(__dirname, '..', 'bookmarks.json');
|
||
|
if (!fs.existsSync(bookmarkConfigPath)) {
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
const bookmarksMenuConfig = JSON.parse(fs.readFileSync(bookmarkConfigPath, 'utf-8'));
|
||
|
const submenu = bookmarksMenuConfig.bookmarks.map((bookmark) => {
|
||
|
switch (bookmark.type) {
|
||
|
case 'link':
|
||
|
if (!('title' in bookmark && 'url' in bookmark)) {
|
||
|
throw new Error('All links in the bookmarks menu must have a title and url.');
|
||
|
}
|
||
|
try {
|
||
|
new URL(bookmark.url);
|
||
|
}
|
||
|
catch (_a) {
|
||
|
throw new Error('Bookmark URL "' + bookmark.url + '"is invalid.');
|
||
|
}
|
||
|
return {
|
||
|
label: bookmark.title,
|
||
|
click: () => {
|
||
|
var _a;
|
||
|
(_a = (0, windowHelpers_1.goToURL)(bookmark.url)) === null || _a === void 0 ? void 0 : _a.catch((err) => log.error(`${bookmark.title}.click ERROR`, err));
|
||
|
},
|
||
|
accelerator: 'shortcut' in bookmark ? bookmark.shortcut : undefined,
|
||
|
};
|
||
|
case 'separator':
|
||
|
return {
|
||
|
type: 'separator',
|
||
|
};
|
||
|
default:
|
||
|
throw new Error('A bookmarks menu entry has an invalid type; type must be one of "link", "separator".');
|
||
|
}
|
||
|
});
|
||
|
const bookmarksMenu = {
|
||
|
label: bookmarksMenuConfig.menuLabel,
|
||
|
submenu,
|
||
|
};
|
||
|
// Insert custom bookmarks menu between menus "View" and "Window"
|
||
|
menuTemplate.splice(menuTemplate.length - 2, 0, bookmarksMenu);
|
||
|
}
|
||
|
catch (err) {
|
||
|
log.error('Failed to load & parse bookmarks configuration JSON file.', err);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 69 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.createTrayIcon = void 0;
|
||
|
const electron_1 = __webpack_require__(17);
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
function createTrayIcon(nativefierOptions, mainWindow) {
|
||
|
var _a;
|
||
|
const options = { ...nativefierOptions };
|
||
|
if (options.tray && options.tray !== 'false') {
|
||
|
const iconPath = (0, helpers_1.getAppIcon)();
|
||
|
if (!iconPath) {
|
||
|
throw new Error('Icon path not found found to use with tray option.');
|
||
|
}
|
||
|
const nimage = electron_1.nativeImage.createFromPath(iconPath);
|
||
|
const appIcon = new electron_1.Tray(electron_1.nativeImage.createEmpty());
|
||
|
if ((0, helpers_1.isOSX)()) {
|
||
|
//sets the icon to the height of the tray.
|
||
|
appIcon.setImage(nimage.resize({ height: appIcon.getBounds().height - 2 }));
|
||
|
}
|
||
|
else {
|
||
|
appIcon.setImage(nimage);
|
||
|
}
|
||
|
const onClick = () => {
|
||
|
log.debug('onClick');
|
||
|
if (mainWindow.isVisible()) {
|
||
|
mainWindow.hide();
|
||
|
}
|
||
|
else {
|
||
|
mainWindow.show();
|
||
|
}
|
||
|
};
|
||
|
const contextMenu = electron_1.Menu.buildFromTemplate([
|
||
|
{
|
||
|
label: options.name,
|
||
|
click: onClick,
|
||
|
},
|
||
|
{
|
||
|
label: 'Quit',
|
||
|
click: () => electron_1.app.exit(0),
|
||
|
},
|
||
|
]);
|
||
|
appIcon.on('click', onClick);
|
||
|
if (options.counter) {
|
||
|
mainWindow.on('page-title-updated', (event, title) => {
|
||
|
var _a, _b;
|
||
|
log.debug('mainWindow.page-title-updated', { event, title });
|
||
|
const counterValue = (0, helpers_1.getCounterValue)(title);
|
||
|
if (counterValue) {
|
||
|
appIcon.setToolTip(`(${counterValue}) ${(_a = options.name) !== null && _a !== void 0 ? _a : 'Nativefier'}`);
|
||
|
}
|
||
|
else {
|
||
|
appIcon.setToolTip((_b = options.name) !== null && _b !== void 0 ? _b : '');
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
else {
|
||
|
electron_1.ipcMain.on('notification', () => {
|
||
|
log.debug('ipcMain.notification');
|
||
|
if (mainWindow.isFocused()) {
|
||
|
return;
|
||
|
}
|
||
|
if (options.name) {
|
||
|
appIcon.setToolTip(`• ${options.name}`);
|
||
|
}
|
||
|
});
|
||
|
mainWindow.on('focus', () => {
|
||
|
var _a;
|
||
|
log.debug('mainWindow.focus');
|
||
|
appIcon.setToolTip((_a = options.name) !== null && _a !== void 0 ? _a : '');
|
||
|
});
|
||
|
}
|
||
|
appIcon.setToolTip((_a = options.name) !== null && _a !== void 0 ? _a : '');
|
||
|
appIcon.setContextMenu(contextMenu);
|
||
|
return appIcon;
|
||
|
}
|
||
|
return undefined;
|
||
|
}
|
||
|
exports.createTrayIcon = createTrayIcon;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 70 */
|
||
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||
|
|
||
|
"use strict";
|
||
|
|
||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||
|
}
|
||
|
Object.defineProperty(o, k2, desc);
|
||
|
}) : (function(o, m, k, k2) {
|
||
|
if (k2 === undefined) k2 = k;
|
||
|
o[k2] = m[k];
|
||
|
}));
|
||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||
|
}) : function(o, v) {
|
||
|
o["default"] = v;
|
||
|
});
|
||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||
|
if (mod && mod.__esModule) return mod;
|
||
|
var result = {};
|
||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||
|
__setModuleDefault(result, mod);
|
||
|
return result;
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||
|
exports.inferFlashPath = void 0;
|
||
|
const fs = __importStar(__webpack_require__(15));
|
||
|
const path = __importStar(__webpack_require__(14));
|
||
|
const helpers_1 = __webpack_require__(63);
|
||
|
const log = __importStar(__webpack_require__(33));
|
||
|
/**
|
||
|
* Find a file or directory
|
||
|
*/
|
||
|
function findSync(pattern, basePath, limitSearchToDirectories = false) {
|
||
|
const matches = [];
|
||
|
(function findSyncRecurse(base) {
|
||
|
let children;
|
||
|
try {
|
||
|
children = fs.readdirSync(base);
|
||
|
}
|
||
|
catch (err) {
|
||
|
if (err.code === 'ENOENT') {
|
||
|
return;
|
||
|
}
|
||
|
throw err;
|
||
|
}
|
||
|
for (const child of children) {
|
||
|
const childPath = path.join(base, child);
|
||
|
const childIsDirectory = fs.lstatSync(childPath).isDirectory();
|
||
|
const patternMatches = pattern.test(childPath);
|
||
|
if (!patternMatches) {
|
||
|
if (!childIsDirectory) {
|
||
|
return;
|
||
|
}
|
||
|
findSyncRecurse(childPath);
|
||
|
return;
|
||
|
}
|
||
|
if (!limitSearchToDirectories) {
|
||
|
matches.push(childPath);
|
||
|
return;
|
||
|
}
|
||
|
if (childIsDirectory) {
|
||
|
matches.push(childPath);
|
||
|
}
|
||
|
}
|
||
|
})(basePath);
|
||
|
return matches;
|
||
|
}
|
||
|
function findFlashOnLinux() {
|
||
|
return findSync(/libpepflashplayer\.so/, '/opt/google/chrome')[0];
|
||
|
}
|
||
|
function findFlashOnWindows() {
|
||
|
return findSync(/pepflashplayer\.dll/, 'C:\\Program Files (x86)\\Google\\Chrome')[0];
|
||
|
}
|
||
|
function findFlashOnMac() {
|
||
|
return findSync(/PepperFlashPlayer.plugin/, '/Applications/Google Chrome.app/', true)[0];
|
||
|
}
|
||
|
function inferFlashPath() {
|
||
|
if ((0, helpers_1.isOSX)()) {
|
||
|
return findFlashOnMac();
|
||
|
}
|
||
|
if ((0, helpers_1.isWindows)()) {
|
||
|
return findFlashOnWindows();
|
||
|
}
|
||
|
if ((0, helpers_1.isLinux)()) {
|
||
|
return findFlashOnLinux();
|
||
|
}
|
||
|
log.warn('Unable to determine OS to infer flash player');
|
||
|
return undefined;
|
||
|
}
|
||
|
exports.inferFlashPath = inferFlashPath;
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 71 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
var path = __webpack_require__(14);
|
||
|
var spawn = (__webpack_require__(72).spawn);
|
||
|
var debug = __webpack_require__(73)('electron-squirrel-startup');
|
||
|
var app = (__webpack_require__(17).app);
|
||
|
|
||
|
var run = function(args, done) {
|
||
|
var updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
|
||
|
debug('Spawning `%s` with args `%s`', updateExe, args);
|
||
|
spawn(updateExe, args, {
|
||
|
detached: true
|
||
|
}).on('close', done);
|
||
|
};
|
||
|
|
||
|
var check = function() {
|
||
|
if (process.platform === 'win32') {
|
||
|
var cmd = process.argv[1];
|
||
|
debug('processing squirrel command `%s`', cmd);
|
||
|
var target = path.basename(process.execPath);
|
||
|
|
||
|
if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') {
|
||
|
run(['--createShortcut=' + target + ''], app.quit);
|
||
|
return true;
|
||
|
}
|
||
|
if (cmd === '--squirrel-uninstall') {
|
||
|
run(['--removeShortcut=' + target + ''], app.quit);
|
||
|
return true;
|
||
|
}
|
||
|
if (cmd === '--squirrel-obsolete') {
|
||
|
app.quit();
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
module.exports = check();
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 72 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("child_process");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 73 */
|
||
|
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||
|
|
||
|
/**
|
||
|
* Detect Electron renderer process, which is node, but we should
|
||
|
* treat as a browser.
|
||
|
*/
|
||
|
|
||
|
if (typeof process !== 'undefined' && process.type === 'renderer') {
|
||
|
module.exports = __webpack_require__(74);
|
||
|
} else {
|
||
|
module.exports = __webpack_require__(77);
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 74 */
|
||
|
/***/ ((module, exports, __webpack_require__) => {
|
||
|
|
||
|
/**
|
||
|
* This is the web browser implementation of `debug()`.
|
||
|
*
|
||
|
* Expose `debug()` as the module.
|
||
|
*/
|
||
|
|
||
|
exports = module.exports = __webpack_require__(75);
|
||
|
exports.log = log;
|
||
|
exports.formatArgs = formatArgs;
|
||
|
exports.save = save;
|
||
|
exports.load = load;
|
||
|
exports.useColors = useColors;
|
||
|
exports.storage = 'undefined' != typeof chrome
|
||
|
&& 'undefined' != typeof chrome.storage
|
||
|
? chrome.storage.local
|
||
|
: localstorage();
|
||
|
|
||
|
/**
|
||
|
* Colors.
|
||
|
*/
|
||
|
|
||
|
exports.colors = [
|
||
|
'lightseagreen',
|
||
|
'forestgreen',
|
||
|
'goldenrod',
|
||
|
'dodgerblue',
|
||
|
'darkorchid',
|
||
|
'crimson'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
||
|
* and the Firebug extension (any Firefox version) are known
|
||
|
* to support "%c" CSS customizations.
|
||
|
*
|
||
|
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
||
|
*/
|
||
|
|
||
|
function useColors() {
|
||
|
// NB: In an Electron preload script, document will be defined but not fully
|
||
|
// initialized. Since we know we're in Chrome, we'll just detect this case
|
||
|
// explicitly
|
||
|
if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// is webkit? http://stackoverflow.com/a/16459606/376773
|
||
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
||
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
||
|
// is firebug? http://stackoverflow.com/a/398120/376773
|
||
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
||
|
// is firefox >= v31?
|
||
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
||
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
|
||
|
// double check webkit in userAgent just in case we are in a worker
|
||
|
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
||
|
*/
|
||
|
|
||
|
exports.formatters.j = function(v) {
|
||
|
try {
|
||
|
return JSON.stringify(v);
|
||
|
} catch (err) {
|
||
|
return '[UnexpectedJSONParseError]: ' + err.message;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Colorize log arguments if enabled.
|
||
|
*
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function formatArgs(args) {
|
||
|
var useColors = this.useColors;
|
||
|
|
||
|
args[0] = (useColors ? '%c' : '')
|
||
|
+ this.namespace
|
||
|
+ (useColors ? ' %c' : ' ')
|
||
|
+ args[0]
|
||
|
+ (useColors ? '%c ' : ' ')
|
||
|
+ '+' + exports.humanize(this.diff);
|
||
|
|
||
|
if (!useColors) return;
|
||
|
|
||
|
var c = 'color: ' + this.color;
|
||
|
args.splice(1, 0, c, 'color: inherit')
|
||
|
|
||
|
// the final "%c" is somewhat tricky, because there could be other
|
||
|
// arguments passed either before or after the %c, so we need to
|
||
|
// figure out the correct index to insert the CSS into
|
||
|
var index = 0;
|
||
|
var lastC = 0;
|
||
|
args[0].replace(/%[a-zA-Z%]/g, function(match) {
|
||
|
if ('%%' === match) return;
|
||
|
index++;
|
||
|
if ('%c' === match) {
|
||
|
// we only are interested in the *last* %c
|
||
|
// (the user may have provided their own)
|
||
|
lastC = index;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
args.splice(lastC, 0, c);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invokes `console.log()` when available.
|
||
|
* No-op when `console.log` is not a "function".
|
||
|
*
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function log() {
|
||
|
// this hackery is required for IE8/9, where
|
||
|
// the `console.log` function doesn't have 'apply'
|
||
|
return 'object' === typeof console
|
||
|
&& console.log
|
||
|
&& Function.prototype.apply.call(console.log, console, arguments);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save `namespaces`.
|
||
|
*
|
||
|
* @param {String} namespaces
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function save(namespaces) {
|
||
|
try {
|
||
|
if (null == namespaces) {
|
||
|
exports.storage.removeItem('debug');
|
||
|
} else {
|
||
|
exports.storage.debug = namespaces;
|
||
|
}
|
||
|
} catch(e) {}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load `namespaces`.
|
||
|
*
|
||
|
* @return {String} returns the previously persisted debug modes
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function load() {
|
||
|
var r;
|
||
|
try {
|
||
|
r = exports.storage.debug;
|
||
|
} catch(e) {}
|
||
|
|
||
|
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
||
|
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
||
|
r = process.env.DEBUG;
|
||
|
}
|
||
|
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Enable namespaces listed in `localStorage.debug` initially.
|
||
|
*/
|
||
|
|
||
|
exports.enable(load());
|
||
|
|
||
|
/**
|
||
|
* Localstorage attempts to return the localstorage.
|
||
|
*
|
||
|
* This is necessary because safari throws
|
||
|
* when a user disables cookies/localstorage
|
||
|
* and you attempt to access it.
|
||
|
*
|
||
|
* @return {LocalStorage}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function localstorage() {
|
||
|
try {
|
||
|
return window.localStorage;
|
||
|
} catch (e) {}
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 75 */
|
||
|
/***/ ((module, exports, __webpack_require__) => {
|
||
|
|
||
|
|
||
|
/**
|
||
|
* This is the common logic for both the Node.js and web browser
|
||
|
* implementations of `debug()`.
|
||
|
*
|
||
|
* Expose `debug()` as the module.
|
||
|
*/
|
||
|
|
||
|
exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
|
||
|
exports.coerce = coerce;
|
||
|
exports.disable = disable;
|
||
|
exports.enable = enable;
|
||
|
exports.enabled = enabled;
|
||
|
exports.humanize = __webpack_require__(76);
|
||
|
|
||
|
/**
|
||
|
* The currently active debug mode names, and names to skip.
|
||
|
*/
|
||
|
|
||
|
exports.names = [];
|
||
|
exports.skips = [];
|
||
|
|
||
|
/**
|
||
|
* Map of special "%n" handling functions, for the debug "format" argument.
|
||
|
*
|
||
|
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
||
|
*/
|
||
|
|
||
|
exports.formatters = {};
|
||
|
|
||
|
/**
|
||
|
* Previous log timestamp.
|
||
|
*/
|
||
|
|
||
|
var prevTime;
|
||
|
|
||
|
/**
|
||
|
* Select a color.
|
||
|
* @param {String} namespace
|
||
|
* @return {Number}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function selectColor(namespace) {
|
||
|
var hash = 0, i;
|
||
|
|
||
|
for (i in namespace) {
|
||
|
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
||
|
hash |= 0; // Convert to 32bit integer
|
||
|
}
|
||
|
|
||
|
return exports.colors[Math.abs(hash) % exports.colors.length];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a debugger with the given `namespace`.
|
||
|
*
|
||
|
* @param {String} namespace
|
||
|
* @return {Function}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function createDebug(namespace) {
|
||
|
|
||
|
function debug() {
|
||
|
// disabled?
|
||
|
if (!debug.enabled) return;
|
||
|
|
||
|
var self = debug;
|
||
|
|
||
|
// set `diff` timestamp
|
||
|
var curr = +new Date();
|
||
|
var ms = curr - (prevTime || curr);
|
||
|
self.diff = ms;
|
||
|
self.prev = prevTime;
|
||
|
self.curr = curr;
|
||
|
prevTime = curr;
|
||
|
|
||
|
// turn the `arguments` into a proper Array
|
||
|
var args = new Array(arguments.length);
|
||
|
for (var i = 0; i < args.length; i++) {
|
||
|
args[i] = arguments[i];
|
||
|
}
|
||
|
|
||
|
args[0] = exports.coerce(args[0]);
|
||
|
|
||
|
if ('string' !== typeof args[0]) {
|
||
|
// anything else let's inspect with %O
|
||
|
args.unshift('%O');
|
||
|
}
|
||
|
|
||
|
// apply any `formatters` transformations
|
||
|
var index = 0;
|
||
|
args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
|
||
|
// if we encounter an escaped % then don't increase the array index
|
||
|
if (match === '%%') return match;
|
||
|
index++;
|
||
|
var formatter = exports.formatters[format];
|
||
|
if ('function' === typeof formatter) {
|
||
|
var val = args[index];
|
||
|
match = formatter.call(self, val);
|
||
|
|
||
|
// now we need to remove `args[index]` since it's inlined in the `format`
|
||
|
args.splice(index, 1);
|
||
|
index--;
|
||
|
}
|
||
|
return match;
|
||
|
});
|
||
|
|
||
|
// apply env-specific formatting (colors, etc.)
|
||
|
exports.formatArgs.call(self, args);
|
||
|
|
||
|
var logFn = debug.log || exports.log || console.log.bind(console);
|
||
|
logFn.apply(self, args);
|
||
|
}
|
||
|
|
||
|
debug.namespace = namespace;
|
||
|
debug.enabled = exports.enabled(namespace);
|
||
|
debug.useColors = exports.useColors();
|
||
|
debug.color = selectColor(namespace);
|
||
|
|
||
|
// env-specific initialization logic for debug instances
|
||
|
if ('function' === typeof exports.init) {
|
||
|
exports.init(debug);
|
||
|
}
|
||
|
|
||
|
return debug;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Enables a debug mode by namespaces. This can include modes
|
||
|
* separated by a colon and wildcards.
|
||
|
*
|
||
|
* @param {String} namespaces
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function enable(namespaces) {
|
||
|
exports.save(namespaces);
|
||
|
|
||
|
exports.names = [];
|
||
|
exports.skips = [];
|
||
|
|
||
|
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
|
||
|
var len = split.length;
|
||
|
|
||
|
for (var i = 0; i < len; i++) {
|
||
|
if (!split[i]) continue; // ignore empty strings
|
||
|
namespaces = split[i].replace(/\*/g, '.*?');
|
||
|
if (namespaces[0] === '-') {
|
||
|
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
|
||
|
} else {
|
||
|
exports.names.push(new RegExp('^' + namespaces + '$'));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Disable debug output.
|
||
|
*
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function disable() {
|
||
|
exports.enable('');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns true if the given mode name is enabled, false otherwise.
|
||
|
*
|
||
|
* @param {String} name
|
||
|
* @return {Boolean}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function enabled(name) {
|
||
|
var i, len;
|
||
|
for (i = 0, len = exports.skips.length; i < len; i++) {
|
||
|
if (exports.skips[i].test(name)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
for (i = 0, len = exports.names.length; i < len; i++) {
|
||
|
if (exports.names[i].test(name)) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Coerce `val`.
|
||
|
*
|
||
|
* @param {Mixed} val
|
||
|
* @return {Mixed}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function coerce(val) {
|
||
|
if (val instanceof Error) return val.stack || val.message;
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 76 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
/**
|
||
|
* Helpers.
|
||
|
*/
|
||
|
|
||
|
var s = 1000;
|
||
|
var m = s * 60;
|
||
|
var h = m * 60;
|
||
|
var d = h * 24;
|
||
|
var y = d * 365.25;
|
||
|
|
||
|
/**
|
||
|
* Parse or format the given `val`.
|
||
|
*
|
||
|
* Options:
|
||
|
*
|
||
|
* - `long` verbose formatting [false]
|
||
|
*
|
||
|
* @param {String|Number} val
|
||
|
* @param {Object} [options]
|
||
|
* @throws {Error} throw an error if val is not a non-empty string or a number
|
||
|
* @return {String|Number}
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
module.exports = function(val, options) {
|
||
|
options = options || {};
|
||
|
var type = typeof val;
|
||
|
if (type === 'string' && val.length > 0) {
|
||
|
return parse(val);
|
||
|
} else if (type === 'number' && isNaN(val) === false) {
|
||
|
return options.long ? fmtLong(val) : fmtShort(val);
|
||
|
}
|
||
|
throw new Error(
|
||
|
'val is not a non-empty string or a valid number. val=' +
|
||
|
JSON.stringify(val)
|
||
|
);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Parse the given `str` and return milliseconds.
|
||
|
*
|
||
|
* @param {String} str
|
||
|
* @return {Number}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function parse(str) {
|
||
|
str = String(str);
|
||
|
if (str.length > 100) {
|
||
|
return;
|
||
|
}
|
||
|
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
|
||
|
str
|
||
|
);
|
||
|
if (!match) {
|
||
|
return;
|
||
|
}
|
||
|
var n = parseFloat(match[1]);
|
||
|
var type = (match[2] || 'ms').toLowerCase();
|
||
|
switch (type) {
|
||
|
case 'years':
|
||
|
case 'year':
|
||
|
case 'yrs':
|
||
|
case 'yr':
|
||
|
case 'y':
|
||
|
return n * y;
|
||
|
case 'days':
|
||
|
case 'day':
|
||
|
case 'd':
|
||
|
return n * d;
|
||
|
case 'hours':
|
||
|
case 'hour':
|
||
|
case 'hrs':
|
||
|
case 'hr':
|
||
|
case 'h':
|
||
|
return n * h;
|
||
|
case 'minutes':
|
||
|
case 'minute':
|
||
|
case 'mins':
|
||
|
case 'min':
|
||
|
case 'm':
|
||
|
return n * m;
|
||
|
case 'seconds':
|
||
|
case 'second':
|
||
|
case 'secs':
|
||
|
case 'sec':
|
||
|
case 's':
|
||
|
return n * s;
|
||
|
case 'milliseconds':
|
||
|
case 'millisecond':
|
||
|
case 'msecs':
|
||
|
case 'msec':
|
||
|
case 'ms':
|
||
|
return n;
|
||
|
default:
|
||
|
return undefined;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Short format for `ms`.
|
||
|
*
|
||
|
* @param {Number} ms
|
||
|
* @return {String}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function fmtShort(ms) {
|
||
|
if (ms >= d) {
|
||
|
return Math.round(ms / d) + 'd';
|
||
|
}
|
||
|
if (ms >= h) {
|
||
|
return Math.round(ms / h) + 'h';
|
||
|
}
|
||
|
if (ms >= m) {
|
||
|
return Math.round(ms / m) + 'm';
|
||
|
}
|
||
|
if (ms >= s) {
|
||
|
return Math.round(ms / s) + 's';
|
||
|
}
|
||
|
return ms + 'ms';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Long format for `ms`.
|
||
|
*
|
||
|
* @param {Number} ms
|
||
|
* @return {String}
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function fmtLong(ms) {
|
||
|
return plural(ms, d, 'day') ||
|
||
|
plural(ms, h, 'hour') ||
|
||
|
plural(ms, m, 'minute') ||
|
||
|
plural(ms, s, 'second') ||
|
||
|
ms + ' ms';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Pluralization helper.
|
||
|
*/
|
||
|
|
||
|
function plural(ms, n, name) {
|
||
|
if (ms < n) {
|
||
|
return;
|
||
|
}
|
||
|
if (ms < n * 1.5) {
|
||
|
return Math.floor(ms / n) + ' ' + name;
|
||
|
}
|
||
|
return Math.ceil(ms / n) + ' ' + name + 's';
|
||
|
}
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 77 */
|
||
|
/***/ ((module, exports, __webpack_require__) => {
|
||
|
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
var tty = __webpack_require__(78);
|
||
|
var util = __webpack_require__(21);
|
||
|
|
||
|
/**
|
||
|
* This is the Node.js implementation of `debug()`.
|
||
|
*
|
||
|
* Expose `debug()` as the module.
|
||
|
*/
|
||
|
|
||
|
exports = module.exports = __webpack_require__(75);
|
||
|
exports.init = init;
|
||
|
exports.log = log;
|
||
|
exports.formatArgs = formatArgs;
|
||
|
exports.save = save;
|
||
|
exports.load = load;
|
||
|
exports.useColors = useColors;
|
||
|
|
||
|
/**
|
||
|
* Colors.
|
||
|
*/
|
||
|
|
||
|
exports.colors = [6, 2, 3, 4, 5, 1];
|
||
|
|
||
|
/**
|
||
|
* Build up the default `inspectOpts` object from the environment variables.
|
||
|
*
|
||
|
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
|
||
|
*/
|
||
|
|
||
|
exports.inspectOpts = Object.keys(process.env).filter(function (key) {
|
||
|
return /^debug_/i.test(key);
|
||
|
}).reduce(function (obj, key) {
|
||
|
// camel-case
|
||
|
var prop = key
|
||
|
.substring(6)
|
||
|
.toLowerCase()
|
||
|
.replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() });
|
||
|
|
||
|
// coerce string value into JS value
|
||
|
var val = process.env[key];
|
||
|
if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
|
||
|
else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
|
||
|
else if (val === 'null') val = null;
|
||
|
else val = Number(val);
|
||
|
|
||
|
obj[prop] = val;
|
||
|
return obj;
|
||
|
}, {});
|
||
|
|
||
|
/**
|
||
|
* The file descriptor to write the `debug()` calls to.
|
||
|
* Set the `DEBUG_FD` env variable to override with another value. i.e.:
|
||
|
*
|
||
|
* $ DEBUG_FD=3 node script.js 3>debug.log
|
||
|
*/
|
||
|
|
||
|
var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
|
||
|
|
||
|
if (1 !== fd && 2 !== fd) {
|
||
|
util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')()
|
||
|
}
|
||
|
|
||
|
var stream = 1 === fd ? process.stdout :
|
||
|
2 === fd ? process.stderr :
|
||
|
createWritableStdioStream(fd);
|
||
|
|
||
|
/**
|
||
|
* Is stdout a TTY? Colored output is enabled when `true`.
|
||
|
*/
|
||
|
|
||
|
function useColors() {
|
||
|
return 'colors' in exports.inspectOpts
|
||
|
? Boolean(exports.inspectOpts.colors)
|
||
|
: tty.isatty(fd);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Map %o to `util.inspect()`, all on a single line.
|
||
|
*/
|
||
|
|
||
|
exports.formatters.o = function(v) {
|
||
|
this.inspectOpts.colors = this.useColors;
|
||
|
return util.inspect(v, this.inspectOpts)
|
||
|
.split('\n').map(function(str) {
|
||
|
return str.trim()
|
||
|
}).join(' ');
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Map %o to `util.inspect()`, allowing multiple lines if needed.
|
||
|
*/
|
||
|
|
||
|
exports.formatters.O = function(v) {
|
||
|
this.inspectOpts.colors = this.useColors;
|
||
|
return util.inspect(v, this.inspectOpts);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Adds ANSI color escape codes if enabled.
|
||
|
*
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function formatArgs(args) {
|
||
|
var name = this.namespace;
|
||
|
var useColors = this.useColors;
|
||
|
|
||
|
if (useColors) {
|
||
|
var c = this.color;
|
||
|
var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
|
||
|
|
||
|
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
|
||
|
args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
|
||
|
} else {
|
||
|
args[0] = new Date().toUTCString()
|
||
|
+ ' ' + name + ' ' + args[0];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invokes `util.format()` with the specified arguments and writes to `stream`.
|
||
|
*/
|
||
|
|
||
|
function log() {
|
||
|
return stream.write(util.format.apply(util, arguments) + '\n');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save `namespaces`.
|
||
|
*
|
||
|
* @param {String} namespaces
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function save(namespaces) {
|
||
|
if (null == namespaces) {
|
||
|
// If you set a process.env field to null or undefined, it gets cast to the
|
||
|
// string 'null' or 'undefined'. Just delete instead.
|
||
|
delete process.env.DEBUG;
|
||
|
} else {
|
||
|
process.env.DEBUG = namespaces;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load `namespaces`.
|
||
|
*
|
||
|
* @return {String} returns the previously persisted debug modes
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function load() {
|
||
|
return process.env.DEBUG;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Copied from `node/src/node.js`.
|
||
|
*
|
||
|
* XXX: It's lame that node doesn't expose this API out-of-the-box. It also
|
||
|
* relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
|
||
|
*/
|
||
|
|
||
|
function createWritableStdioStream (fd) {
|
||
|
var stream;
|
||
|
var tty_wrap = process.binding('tty_wrap');
|
||
|
|
||
|
// Note stream._type is used for test-module-load-list.js
|
||
|
|
||
|
switch (tty_wrap.guessHandleType(fd)) {
|
||
|
case 'TTY':
|
||
|
stream = new tty.WriteStream(fd);
|
||
|
stream._type = 'tty';
|
||
|
|
||
|
// Hack to have stream not keep the event loop alive.
|
||
|
// See https://github.com/joyent/node/issues/1726
|
||
|
if (stream._handle && stream._handle.unref) {
|
||
|
stream._handle.unref();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'FILE':
|
||
|
var fs = __webpack_require__(15);
|
||
|
stream = new fs.SyncWriteStream(fd, { autoClose: false });
|
||
|
stream._type = 'fs';
|
||
|
break;
|
||
|
|
||
|
case 'PIPE':
|
||
|
case 'TCP':
|
||
|
var net = __webpack_require__(79);
|
||
|
stream = new net.Socket({
|
||
|
fd: fd,
|
||
|
readable: false,
|
||
|
writable: true
|
||
|
});
|
||
|
|
||
|
// FIXME Should probably have an option in net.Socket to create a
|
||
|
// stream from an existing fd which is writable only. But for now
|
||
|
// we'll just add this hack and set the `readable` member to false.
|
||
|
// Test: ./node test/fixtures/echo.js < /etc/passwd
|
||
|
stream.readable = false;
|
||
|
stream.read = null;
|
||
|
stream._type = 'pipe';
|
||
|
|
||
|
// FIXME Hack to have stream not keep the event loop alive.
|
||
|
// See https://github.com/joyent/node/issues/1726
|
||
|
if (stream._handle && stream._handle.unref) {
|
||
|
stream._handle.unref();
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
// Probably an error on in uv_guess_handle()
|
||
|
throw new Error('Implement me. Unknown stream file type!');
|
||
|
}
|
||
|
|
||
|
// For supporting legacy API we put the FD here.
|
||
|
stream.fd = fd;
|
||
|
|
||
|
stream._isStdio = true;
|
||
|
|
||
|
return stream;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Init logic for `debug` instances.
|
||
|
*
|
||
|
* Create a new `inspectOpts` object in case `useColors` is set
|
||
|
* differently for a particular `debug` instance.
|
||
|
*/
|
||
|
|
||
|
function init (debug) {
|
||
|
debug.inspectOpts = {};
|
||
|
|
||
|
var keys = Object.keys(exports.inspectOpts);
|
||
|
for (var i = 0; i < keys.length; i++) {
|
||
|
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Enable namespaces listed in `process.env.DEBUG` initially.
|
||
|
*/
|
||
|
|
||
|
exports.enable(load());
|
||
|
|
||
|
|
||
|
/***/ }),
|
||
|
/* 78 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("tty");
|
||
|
|
||
|
/***/ }),
|
||
|
/* 79 */
|
||
|
/***/ ((module) => {
|
||
|
|
||
|
"use strict";
|
||
|
module.exports = require("net");
|
||
|
|
||
|
/***/ })
|
||
|
/******/ ]);
|
||
|
/************************************************************************/
|
||
|
/******/ // The module cache
|
||
|
/******/ var __webpack_module_cache__ = {};
|
||
|
/******/
|
||
|
/******/ // The require function
|
||
|
/******/ function __webpack_require__(moduleId) {
|
||
|
/******/ // Check if module is in cache
|
||
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||
|
/******/ if (cachedModule !== undefined) {
|
||
|
/******/ return cachedModule.exports;
|
||
|
/******/ }
|
||
|
/******/ // Create a new module (and put it into the cache)
|
||
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||
|
/******/ id: moduleId,
|
||
|
/******/ loaded: false,
|
||
|
/******/ exports: {}
|
||
|
/******/ };
|
||
|
/******/
|
||
|
/******/ // Execute the module function
|
||
|
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
|
/******/
|
||
|
/******/ // Flag the module as loaded
|
||
|
/******/ module.loaded = true;
|
||
|
/******/
|
||
|
/******/ // Return the exports of the module
|
||
|
/******/ return module.exports;
|
||
|
/******/ }
|
||
|
/******/
|
||
|
/************************************************************************/
|
||
|
/******/ /* webpack/runtime/node module decorator */
|
||
|
/******/ (() => {
|
||
|
/******/ __webpack_require__.nmd = (module) => {
|
||
|
/******/ module.paths = [];
|
||
|
/******/ if (!module.children) module.children = [];
|
||
|
/******/ return module;
|
||
|
/******/ };
|
||
|
/******/ })();
|
||
|
/******/
|
||
|
/************************************************************************/
|
||
|
/******/
|
||
|
/******/ // startup
|
||
|
/******/ // Load entry module and return exports
|
||
|
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||
|
/******/ var __webpack_exports__ = __webpack_require__(0);
|
||
|
/******/
|
||
|
/******/ })()
|
||
|
;
|
||
|
//# sourceMappingURL=main.js.map
|