fix: A whole bunch of cleaning up

This commit is contained in:
Felix Rieseberg 2020-07-27 10:33:55 -07:00
parent 118703356d
commit bf1f043bc4
26 changed files with 401 additions and 112 deletions

15
CREDITS.md Normal file
View File

@ -0,0 +1,15 @@
# macintosh.js Credits
This app by <a href="https://www.felixrieseberg.com">Felix Rieseberg</a>. The real work was done by the people below:
**Emulator**: Basilisk II, a 68k Macintosh emulator, by [Christian Bauer et al](http://basilisk.cebix.net), modified and compiled [with Emscripten](https://jamesfriend.com.au/basilisk-ii-classic-mac-emulator-in-the-browser) by [James Friend](https://jamesfriend.com.au).
**Installed software** from vintage computing archives: [WinWorldPC](https://winworldpc.com), [Macintosh Garden](https://macintoshgarden.org), and [Macintosh Repository](https://www.macintoshrepository.org/).
This software is not affiliated with nor authorized by Apple. It is provided for educational purposes only. This is an unstable toy and should not be expected to work properly.
# Licenses
The [source code for this app can be found on GitHub](https://github.com/felixrieseberg/macintosh).
Basilisk II and its components are released under the GNU GPL. See [LICENSE](src/basilisk/LICENSE.txt) for details.

35
README.md Normal file
View File

@ -0,0 +1,35 @@
# macintosh.js
This is Mac OS 8, running in an [Electron](https://electronjs.org/) app. Yes, it's the full thing. I'm sorry.
## Downloads
| | Windows | macOS | Linux |
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Standalone Download | 📦[Standalone, 32-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-win32-standalone-ia32.zip) <br /> 📦[Standalone, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-win32-standalone-x64.zip) | 📦[Standalone](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-macos-2.2.1.zip) | |
| Installer | 💽[Setup, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-setup-win32-x64.exe) <br /> 💽[Setup, 32-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-setup-win32-ia32.exe) | | 💽[deb, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-linux-2.2.1_amd64.deb) <br /> 💽[rpm, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-linux-2.2.1.x86_64.rpm) |
![Screenshot]()
## Does it work?
Yes! Quite well, actually - on macOS, Windows, and Linux. Bear in mind that this is written entirely in JavaScript, so please adjust your expectations. The virtual machine is emulating a Motorola CPU, which Apple used before switching to IBM's PowerPC architecture in the late 1990s.
## Should this have been a native app?
Absolutely.
## Does it run my favorite game or app?
You'll likely be better off with an actual virtualization app, but the short answer is yes. In fact, you'll find various games and demos preinstalled, thanks to an old MacWorld Demo CD from 1997. Namely, Oregon Trail, Duke Nukem 3D, Civilization II, Alley 19 Bowling, Damage Incorporated, and Dungeons & Dragons.
There are also various apps and trials preinstalled, including Photoshop 3, Premiere 4, Illustrator 5.5, StuffIt Expander, the Apple Web Page Construction Kit, and more.
## Can I transfer files from and to the machine?
Yes, you can. Click on the "Help" button at the bottom of the running app to see instructions.
## Can I connect to the Internet?
No. For what it's worth, the web was quite different 30 years ago - and you wouldn't be able to open even Google. However, Internet Explorer and Netscape are installed, as is the "Web Sharing Server", if you want to play around a bit.
## License
This project is provided for educational purposes only. It is not affiliated with and has
not been approved by Apple.

BIN
assets/icon.icns Normal file

Binary file not shown.

BIN
assets/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

80
forge.config.js Normal file
View File

@ -0,0 +1,80 @@
const path = require('path');
const package = require('./package.json');
module.exports = {
hooks: {
postPackage: require('./tools/notarize')
},
packagerConfig: {
asar: false,
icon: path.resolve(__dirname, 'assets', 'icon'),
appBundleId: 'com.felixrieseberg.macintoshjs',
appCategoryType: 'public.app-category.developer-tools',
win32metadata: {
CompanyName: 'Felix Rieseberg',
OriginalFilename: 'macintosh.js'
},
osxSign: {
identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
'hardened-runtime': true,
'gatekeeper-assess': false,
'entitlements': 'static/entitlements.plist',
'entitlements-inherit': 'static/entitlements.plist',
'signature-flags': 'library'
},
ignore: [
/\/assets(\/?)/,
/\/docs(\/?)/,
/\/tools(\/?)/,
/package-lock\.json/,
/README\.md/,
/CREDITS\.md/,
/issue_template\.md/,
/HELP\.md/,
]
},
makers: [
{
name: '@electron-forge/maker-squirrel',
platforms: ['win32'],
config: (arch) => {
return {
name: 'macintosh.js',
authors: 'Felix Rieseberg',
exe: 'macintoshjs.exe',
noMsi: true,
remoteReleases: '',
setupExe: `macintoshjs-${package.version}-setup-${arch}.exe`,
setupIcon: path.resolve(__dirname, 'assets', 'icon.ico'),
certificateFile: process.env.WINDOWS_CERTIFICATE_FILE,
certificatePassword: process.env.WINDOWS_CERTIFICATE_PASSWORD
}
}
},
{
name: '@electron-forge/maker-zip',
platforms: ['darwin', 'win32']
},
{
name: '@electron-forge/maker-deb',
platforms: ['linux']
},
{
name: '@electron-forge/maker-rpm',
platforms: ['linux']
}
],
publishers: [
{
name: '@electron-forge/publisher-github',
config: {
repository: {
owner: 'felixrieseberg',
name: 'macintosh.js'
},
draft: true,
prerelease: true
}
}
]
};

View File

@ -19,34 +19,11 @@
},
"license": "MIT",
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "macintosh"
}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {}
},
{
"name": "@electron-forge/maker-rpm",
"config": {}
}
]
}
"forge": "./forge.config.js"
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0"
"electron-squirrel-startup": "^1.0.0",
"update-electron-app": "^1.5.0"
},
"devDependencies": {
"@electron-forge/cli": "6.0.0-beta.52",

View File

@ -62,10 +62,22 @@ function addAutoloader(module) {
true
);
} catch (error) {
postMessage("showMessageBoxSync", {
type: 'error',
title: 'Could not transfer file',
message: `We tried to transfer ${fileName} to the virtual machine, but failed. The error was: ${error}`
});
console.error(`loadDatafiles: Failed to preload ${fileName}`, error);
}
});
} catch (error) {
postMessage("showMessageBoxSync", {
type: 'error',
title: 'Could not transfer files',
message: `We tried to transfer files to the virtual machine, but failed. The error was: ${error}`
});
console.error(`loadDatafiles: Failed to copyFilesAtPath`, error);
}
}
@ -115,6 +127,12 @@ function writeSafely(filePath, fileData) {
return new Promise((resolve) => {
fs.writeFile(filePath, fileData, (error) => {
if (error) {
postMessage("showMessageBoxSync", {
type: 'error',
title: 'Could not save files',
message: `We tried to save files from the virtual machine, but failed. The error was: ${error}`
});
console.error(`Disk save: Encountered error for ${filePath}`, error);
} else {
console.log(`Disk save: Finished writing ${filePath}`);
@ -158,6 +176,12 @@ async function saveFilesInPath(folderPath) {
);
}
} catch (error) {
postMessage("showMessageBoxSync", {
type: 'error',
title: 'Could not safe file',
message: `We tried to save the file "${file}" from the virtual machine, but failed. The error was: ${error}`
});
console.error(`Disk save: Could not write ${file}`, error);
}
}

View File

@ -1,23 +1,26 @@
const fs = require('fs');
const path = require('path');
const { app } = require('electron');
const fs = require("fs");
const path = require("path");
const { app } = require("electron");
const appDataPath = app.getPath('userData');
const devFilePath = path.join(appDataPath, 'developer');
const appDataPath = app.getPath("userData");
const devFilePath = path.join(appDataPath, "developer");
let isDevMode = true;
let isDevMode;
function getIsDevMode() {
if (isDevMode !== undefined) {
return isDevMode;
}
return isDevMode = fs.existsSync(devFilePath);
return (isDevMode = !app.isPackaged || fs.existsSync(devFilePath));
}
function setIsDevMode(set) {
if (set && !getIsDevMode()) {
fs.writeFileSync(devFilePath, `So you're a developer, huh? Neat! Welcome aboard!`);
fs.writeFileSync(
devFilePath,
`So you're a developer, huh? Neat! Welcome aboard!`
);
} else if (!set && getIsDevMode()) {
fs.unlinkSync(devFilePath);
}
@ -27,5 +30,5 @@ function setIsDevMode(set) {
module.exports = {
getIsDevMode,
setIsDevMode
setIsDevMode,
};

View File

@ -1,39 +1,54 @@
const { app, BrowserWindow } = require("electron");
const path = require("path");
const { registerIpcHandlers } = require("./ipc");
const { createWindow } = require("./windows");
const { getIsDevMode } = require("./devmode");
const { shouldQuit } = require("./squirrel");
const { setupUpdates } = require("./update");
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require("electron-squirrel-startup")) {
// eslint-disable-line global-require
app.quit();
}
async function onReady() {
if (!getIsDevMode()) process.env.NODE_ENV = "production";
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on("ready", () => {
registerIpcHandlers();
createWindow();
});
setupUpdates();
}
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", () => {
/**
* All windows have been closed, quit on anything but
* macOS.
*/
function onWindowsAllClosed() {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== "darwin") {
app.quit();
}
});
}
app.on("activate", () => {
function onActivate() {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
}
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.
function main() {
// Handle creating/removing shortcuts on Windows when
// installing/uninstalling.
if (shouldQuit()) {
app.quit();
return;
}
// Set the app's name
app.setName("macintosh.js");
// Launch
app.on("ready", onReady);
app.on("activate", onActivate);
app.on("window-all-closed", onWindowsAllClosed);
}
main();

View File

@ -1,5 +1,6 @@
const { ipcMain, app, BrowserWindow } = require("electron");
const { ipcMain, app, BrowserWindow, dialog } = require("electron");
const { setIsDevMode, getIsDevMode } = require("./devmode");
const { getMainWindow } = require("./windows");
function registerIpcHandlers() {
ipcMain.handle("quit", () => app.quit());
@ -12,9 +13,23 @@ function registerIpcHandlers() {
ipcMain.handle("getIsDevMode", () => getIsDevMode());
ipcMain.handle("setIsDevMode", (event, set) => {
ipcMain.handle("setIsDevMode", (_event, set) => {
setIsDevMode(set);
});
ipcMain.handle("showMessageBox", (_event, options) => {
const mainWindow = getMainWindow();
return dialog.showMessageBox(mainWindow, options);
});
ipcMain.handle("showMessageBoxSync", (_event, options) => {
const mainWindow = getMainWindow();
return dialog.showMessageBoxSync(mainWindow, options);
});
ipcMain.handle("getAppVersion", () => {
return app.getVersion();
});
}
module.exports = {

7
src/main/squirrel.js Normal file
View File

@ -0,0 +1,7 @@
function shouldQuit() {
return require("electron-squirrel-startup");
}
module.exports = {
shouldQuit,
};

14
src/main/update.js Normal file
View File

@ -0,0 +1,14 @@
const { app } = require("electron");
function setupUpdates() {
if (app.isPackaged) {
require("update-electron-app")({
repo: "felixrieseberg/macintosh.js",
updateInterval: "1 hour",
});
}
}
module.exports = {
setupUpdates,
};

View File

@ -6,6 +6,10 @@ const { getIsDevMode } = require("./devmode");
const windowList = {};
let mainWindow;
function getMainWindow() {
return mainWindow;
}
function handleNewWindow(event, url, frameName, disposition, options) {
// open window as modal
event.preventDefault();
@ -85,4 +89,5 @@ function createWindow() {
module.exports = {
createWindow,
getMainWindow,
};

View File

@ -4,9 +4,7 @@ var audio = {
channels: 1,
bytesPerSample: 2,
samples: 4096,
// freq: 11025,
freq: 22050,
// freq: 44100,
format: 0x8010,
paused: false,
timer: null,
@ -41,12 +39,6 @@ var audioDataBuffer = new SharedArrayBuffer(AUDIO_DATA_BUFFER_SIZE);
var audioDataBufferView = new Uint8Array(audioDataBuffer);
var audioContext = new AudioContext();
// document.querySelector('#enableAudio').addEventListener('click', function() {
// audioContext.resume().then(() => {
// document.querySelector('#enableAudio').remove();
// });
// });
var gainNode = audioContext.createGain();
gainNode.gain.value = 1;
@ -120,11 +112,6 @@ function openAudio() {
audio.gotFirstBlock &&
Date.now() - getBlockBufferLastWarningTime > 5000
) {
// console.warn(
// `UI thread tried to read audio data from worker-locked chunk ${getBlockBufferWarningCount} times`
// );
//console.log("curChunkIndex", curChunkIndex);
// debugger
getBlockBufferLastWarningTime = Date.now();
getBlockBufferWarningCount = 0;
}
@ -139,10 +126,7 @@ function openAudio() {
curChunkAddr + 2 + audio.bufferSize
);
audio.nextChunkIndex = audioDataBufferView[curChunkAddr + 1];
// console.assert(audio.nextChunkIndex != curChunkIndex, `curChunkIndex=${curChunkIndex} == nextChunkIndex=${audio.nextChunkIndex}`)
audioDataBufferView[curChunkAddr] = LockStates.EMUL_THREAD_LOCK;
// debugger
// console.log(`got buffer=${curChunkIndex}, next=${audio.nextChunkIndex}`)
return blockBuffer;
};
@ -196,7 +180,6 @@ function openAudio() {
// And queue it to be played after the currently playing audio stream.
audio.pushAudio(blockBuffer, audio.bufferSize);
}
// console.log(`queued ${i} buffers of audio`);
};
// Create a callback function that will be routinely called to ask more audio data from the user application.

View File

@ -1,8 +1,9 @@
const { quit, devtools } = require("./ipc");
const { getIsWorkerRunning, getIsWorkerSaving } = require("./worker");
const { showCloseWarning } = require("./dialogs");
const { getIsDevMode } = require("./ipc");
function registerControls() {
async function registerControls() {
document.querySelector("#close").addEventListener("click", () => {
if (!getIsWorkerRunning()) {
quit();
@ -16,6 +17,10 @@ function registerControls() {
document.querySelector("#devtools").addEventListener("click", () => {
devtools();
});
if (await getIsDevMode()) {
document.querySelector("#devtools").classList.remove("hidden");
}
}
registerControls();

View File

@ -8,6 +8,9 @@
</head>
<body>
<h1>Credits</h1>
<small id="versions"></small>
<p>
This app by <a href="https://www.felixrieseberg.com">Felix Rieseberg</a>. The real work was done by the people below:
</p>
@ -29,14 +32,6 @@
<p>Basilisk II and its components are released under the GNU GPL. See <a href="#" id="license">LICENSE</a> for details.</p>
<script>
license.onclick = () => {
const { shell } = require('electron');
const path = require('path');
const licensePath = path.join(__dirname, '../basilisk/LICENSE.txt');
shell.openPath(licensePath);
}
</script>
<script src="./credits.js"></script>
</body>
</html>

19
src/renderer/credits.js Normal file
View File

@ -0,0 +1,19 @@
const { shell, ipcRenderer } = require("electron");
const path = require("path");
const { versions } = require("process");
const { getAppVersion } = require("./ipc.js");
async function credits() {
license.onclick = () => {
const licensePath = path.join(__dirname, "../basilisk/LICENSE.txt");
shell.openPath(licensePath);
};
const version = await getAppVersion();
document.querySelector(
"#versions"
).innerHTML = `macintosh.js v${version} with Electron v${process.versions.electron}`;
}
credits();

View File

@ -9,21 +9,24 @@
<body>
<h1>Help</h1>
<h2>Passing files into the machine</h2>
<h2>How can I get files into the machine?</h2>
<p>
<ul>
<li>Open the folder "macintosh.js" in your <a href="#_" id="user_dir">user directory</a>.</li>
<li>Put any files you want to use in your VM (virtual machine) into that folder.</li>
<li>Restart the app.</li>
<li>On the VM's (virtual machine) desktop, find the "Unix" volume and double-click to open it.</li>
<li>On the VM's desktop, find the "Unix" volume and double-click to open it.</li>
<li>Find the "macintosh.js" folder, which now contains all your files.</li>
</ul>
Files will be copied over when you start your VM (virtual machine). They are not synchronized while the VM is running. However, any changes made to the "macintosh.js" folder in your VM will be saved to the corresponding folder in your home directory once you shut the VM down.
Files will be copied over when you start your VM. They are not synchronized while the VM is running. However, any changes made to the "macintosh.js" folder in your VM will be saved to the corresponding folder in your home directory once you shut the VM down.
Be chill about it: The more files you put into that folder,
the more memory macintosh.js will consume.
</p>
<h2>Getting files out of machine</h2>
<h2>How can I get files out of the machine?</h2>
<p>
<ul>
@ -43,8 +46,6 @@
<button id="devtools">Enable developer tools</button>
</p>
<script>
require('./help.js')
</script>
<script src="./help.js"></script>
</body>
</html>

View File

@ -1,35 +1,47 @@
const { shell, ipcRenderer } = require('electron');
const path = require('path');
const fs = require('fs');
const homedir = require('os').homedir();
const macDir = path.join(homedir, 'macintosh.js');
const { shell, ipcRenderer } = require("electron");
const path = require("path");
const fs = require("fs");
const homedir = require("os").homedir();
const macDir = path.join(homedir, "macintosh.js");
let isDevTools;
// Setup dev mode
function fetchIsDevTools() {
ipcRenderer.invoke('getIsDevMode').then((result) => {
ipcRenderer.invoke("getIsDevMode").then((result) => {
isDevTools = result;
if (result) {
devtools.innerHTML = 'Disable developer tools';
devtools.innerHTML = "Disable developer tools";
} else {
devtools.innerHTML = 'Enable developer tools';
devtools.innerHTML = "Enable developer tools";
}
});
}
user_dir.onclick = user_dir2.onclick = () => {
if (!fs.existsSync(macDir)) {
fs.mkdirSync(macDir);
}
async function help() {
user_dir.onclick = user_dir2.onclick = () => {
try {
if (!fs.existsSync(macDir)) {
fs.mkdirSync(macDir);
}
shell.showItemInFolder(macDir);
}
shell.showItemInFolder(macDir);
} catch (error) {
ipcRenderer.invoke("showMessageBox", {
type: "error",
title: "Could not open folder",
message: `We tried to open the macintosh.js directory, but failed. The error was: ${error}`,
});
}
};
devtools.onclick = async () => {
await ipcRenderer.invoke("setIsDevMode", !isDevTools);
fetchIsDevTools();
};
devtools.onclick = async () => {
await ipcRenderer.invoke('setIsDevMode', !isDevTools);
fetchIsDevTools();
}
fetchIsDevTools();
help();

View File

@ -21,7 +21,7 @@
<a id="close" href="#">Quit</a>
<a id="credits" href="#" onclick="window.open('credits.html')">Credits</a>
<a id="help" href="#" onclick="window.open('help.html')">Help</a>
<a id="devtools" href="#">Dev</a>
<a id="devtools" href="#" class="hidden">Toggle DevTools</a>
</div>
</div>
<div id="warning" class="dialog hidden absolute_center">

View File

@ -8,4 +8,16 @@ module.exports = {
devtools() {
ipcRenderer.invoke("devtools");
},
getIsDevMode() {
return ipcRenderer.invoke("getIsDevMode");
},
setIsDevMode() {
return ipcRenderer.invoke("setIsDevMode");
},
getAppVersion() {
return ipcRenderer.invoke("getAppVersion");
},
};

View File

@ -49,6 +49,21 @@
text-decoration: underline;
}
.controls > .clear > a:before {
content: "• ";
display: inline-block;
text-decoration: none;
margin-right: 4px;
}
.controls > .clear > a:before:hover {
text-decoration: none;
}
.controls > .clear > a:nth-of-type(1):before {
content: "";
}
#progress {
display: none;
}

View File

@ -80,7 +80,7 @@ function registerWorker() {
worker.onmessage = function (e) {
if (e.data.type === "emulator_loading") {
const progressElement = document.querySelector("#progressbar");
const progressDialog = document.querySelector("#progress p")
const progressDialog = document.querySelector("#progress p");
if (progressElement && e.data.type === "emulator_loading") {
const val = Math.max(10, e.data.completion * 100);
@ -102,7 +102,7 @@ function registerWorker() {
// If we're ready, Basilisk II will send
// video_open()
if (e.data.data === "video_open()") {
document.body.classList.remove('emulator_loading');
document.body.classList.remove("emulator_loading");
document.body.classList.add("emulator_running");
}
} else if (e.data.type === "disk_saved") {

30
tools/notarize.js Normal file
View File

@ -0,0 +1,30 @@
const { notarize } = require('electron-notarize');
const path = require('path');
const buildOutput = path.resolve(
__dirname,
'..',
'out',
'macintosh.js-darwin-x64',
'macintosh.js.app'
);
module.exports = function () {
if (process.platform !== 'darwin') {
console.log('Not a Mac; skipping notarization');
return;
}
console.log('Notarizing...');
return notarize({
appBundleId: 'com.felixrieseberg.macintoshjs',
appPath: buildOutput,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
ascProvider: 'LT94ZKYDCJ'
}).catch((e) => {
console.error(e);
throw e;
});
}

View File

@ -933,6 +933,11 @@ electron-installer-redhat@^3.0.0:
word-wrap "^1.2.3"
yargs "^15.1.0"
electron-is-dev@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.3.0.tgz#14e6fda5c68e9e4ecbeff9ccf037cbd7c05c5afe"
integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=
electron-notarize@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-1.0.0.tgz#bc925b1ccc3f79e58e029e8c4706572b01a9fd8f"
@ -1009,7 +1014,7 @@ electron-winstaller@^4.0.0:
lodash.template "^4.2.2"
temp "^0.9.0"
electron@10.0.0-beta.13:
electron@10.0.0-beta.12:
version "10.0.0-beta.12"
resolved "https://registry.yarnpkg.com/electron/-/electron-10.0.0-beta.12.tgz#93db286f96de03104a39fc693c25d0d4c0784813"
integrity sha512-cUYFrtGDD96aes4W+jCD1CwyC17HE4/wbok3yphL66z08ZQ+MIqgEe/pChujcSiMoK9SjvxTPPYGtszyXOrZKg==
@ -1355,6 +1360,13 @@ getpass@^0.1.1:
dependencies:
assert-plus "^1.0.0"
github-url-to-object@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/github-url-to-object/-/github-url-to-object-4.0.4.tgz#a9797b7026e18d53b50b07f45b7e169b55fd90ee"
integrity sha512-1Ri1pR8XTfzLpbtPz5MlW/amGNdNReuExPsbF9rxLsBfO1GH9RtDBamhJikd0knMWq3RTTQDbTtw0GGvvEAJEA==
dependencies:
is-url "^1.1.0"
glob@^7.1.3, glob@^7.1.4, glob@^7.1.5, glob@^7.1.6:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
@ -1591,6 +1603,11 @@ is-typedarray@~1.0.0:
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
is-url@^1.1.0, is-url@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
@ -3036,6 +3053,16 @@ universalify@^1.0.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
update-electron-app@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/update-electron-app/-/update-electron-app-1.5.0.tgz#492cb904db07a0b28dbd83fb52e0fe500bbe3463"
integrity sha512-g7noW9JfQ8Hwq6zw9lmZei+R/ikOIBcaZ04TbmIcU5zNfv23HkN80QLLAyiR/47KvfS4sjnh2/wuDq5nh8+0mQ==
dependencies:
electron-is-dev "^0.3.0"
github-url-to-object "^4.0.4"
is-url "^1.2.4"
ms "^2.1.1"
uri-js@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"