diff --git a/README.md b/README.md index 4cc01b0b..d94d47ad 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ ![npm bundle size (minified)](https://img.shields.io/bundlephobia/min/wasmboy.svg) ![npm](https://img.shields.io/npm/dt/wasmboy.svg) ![GitHub](https://img.shields.io/github/license/torch2424/wasmboy.svg) -[![Buy Me A Coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/torch2424) @@ -15,15 +14,11 @@ **Project is still < 1.0.0. Most games are playable, but the emulator is still not very accurate. Expect bugs.** -[1.0 Roadmap Tracking Issue](https://github.com/torch2424/wasmBoy/issues/197) - -[Debugger / Demo with support for mobile controls](https://torch2424.github.io/wasmBoy/) +[Core/Lib Documentation](https://github.com/torch2424/wasmBoy/wiki) -[Documentation](https://github.com/torch2424/wasmBoy/wiki) + - - -![Pokemon Crystal Wasmboy Demo](./docs/images/wasmBoyPokemonCrystal.gif) +![Pokemon Crystal Wasmboy Debugger Demo](./docs/images/debuggerDesktopDemo.gif) @@ -32,16 +27,22 @@ - [Features](#features) - [Usage](#usage) - [Supported Platforms](#supported-platforms) -- [Example Gifs & Screenshots](#example-gifs--screenshots) +- [In-Game Screenshots](#in-game-screenshots) + - [Gameboy Support](#gameboy-support) + - [Gameboy Color Support](#gameboy-color-support) +- [Demo Applications](#demo-applications) + - [Debugger](#debugger) + - [Benchmark](#benchmark) - [Tests](#tests) - [Blarrg](#blarrg) - [Mooneye](#mooneye) + - [Timing](#timing) + - [Halt](#halt) - [Contributing](#contributing) - [Installation](#installation) - [CLI Commands / Npm Scripts](#cli-commands--npm-scripts) - [Notable Projects](#notable-projects) - [Special Thanks](#special-thanks) -- [Random Tips for new Gameboy EmuDevs](#random-tips-for-new-gameboy-emudevs) - [Resources](#resources) # Features @@ -73,23 +74,77 @@ Documentation for the project can be found on the [WasmBoy Wiki](https://github. Try to test and aim for support on all major browsers (Chrome, Firefox, and Safari). Also, Node support works with the [`headless` option in the WasmBoy config](https://github.com/torch2424/wasmBoy/wiki/Lib-API#wasmboyoptions), and using the [Worker Threads](https://nodejs.org/api/worker_threads.html) `--experimental-worker` flag. -# Example Gifs & Screenshots +# In-Game Screenshots -**Gameboy Support** +### Gameboy Support ![Is that a demo in your pocket](./docs/images/wasmBoyIsThatADemoInYourPocket.png) ![Megaman 2](./docs/images/wasmBoyMegaman2.png) ![Pokemon Blue](./docs/images/wasmBoyPokemonBlue.png) ![tetris](./docs/images/wasmBoyTetris.png) ![tobu tobu girl](./test/performance/testroms/tobutobugirl/tobutobugirl.gb.noPerformanceOptions.png) -**Gameboy Color Support** +### Gameboy Color Support ![Links Awakening](./docs/images/wasmBoyLinksAwakening.png) ![L s d j](./docs/images/wasmBoyLsdj.png) ![Megaman extreme 2](./docs/images/wasmBoyMegamanXtreme2.png) ![Pokemon Silver](./docs/images/wasmBoyPokemonSilver.png) ![Pokemon Yellow](./docs/images/wasmBoyPokemonYellow.png) ![back to color demo](./test/performance/testroms/back-to-color/back-to-color.gbc.noPerformanceOptions.png) -**Options & Save States** +# Demo Applications + +### Debugger + +[Application Link](https://wasmboy.app/) + +A full debugger meant for analyzing the internals of the gameboy. Great for HomeBrew Gameboy Development, or using as a reference point for building your own GameBoy emulator. **See the gif at the top of the README for an example.** + +**Features** + +- Support of all Gameboy Components: CPU, PPU (Graphics), APU (Audio), Memory, Interrupts, and Timers. 🎮 +- Per cycle state of each Game Boy components data, internal registers, and relevant memory addresses. 🌐 +- Loaded ROM Information and parsing of the [Cartridge Header](http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header). 💾 +- CPU Control options. Stepping per opcode, and breakpoints. 🧠 +- Graphics Background Map, with border for current "camera" location with respect to scroll registers. đŸ–ŧī¸ +- Graphics Tile Data, to display the loaded tiles currently loaded across all VRAM Banks. 🎨 +- WasmBoy Control options. Play, Pause, Save State, and Load State. ⏯ī¸ 📚 +- Ability to log the entire WasmBoy Library Object and Memory to the DevTools Console. đŸ–Ĩī¸ +- Highly productive "Docker" layout, with snapping of widgets onto sections of the screen and tab support. ⚓ +- Saved Layouts between sessions. 💠 +- Help widget with tips on how to be effective in the debugger. 🙋 + +**Anaytics / Privacy** + +[Analytics Wrapper Service](./demo/debugger/analytics.js) + +Analytics is used on this application simply for performance monitoring, and tracking popularity of the applications. The following events are sent, with nothing more than the event name. The analytics provider used is [Google Analytics](https://analytics.google.com/analytics/web/). + +- Whenever a new ROM is loaded, and played for the first time. +- Whether attempting to load a ROM was successful. +- Whenever a state is saved. +- Whenever a state is loaded. +- Whenever custom WasmBoy options are applied. +- Whenever the Google Drive option is selected. +- Whenever the mobile demo is manually reloaded. + +**Mobile Demo** + +For UI/UX reasons, on mobile the debugger is simply a web app for testing the lib. This is useful for testing a ROM on the go. For playing games, I would suggest [VaporBoy](https://vaporboy.net/). Below is an example of the mobile demo: + +![Pokemon Crystal Wasmboy Mobile Demo](./docs/images/debuggerMobileDemo.gif) + +### Benchmark -![Wasm boy options and save states gif](./docs/images/wasmBoySaveStateOptions.gif) +[Application Link](https://wasmboy.app/benchmark/) -**Debugger** +[Medium Article](https://medium.com/@torch2424/webassembly-is-fast-a-real-world-benchmark-of-webassembly-vs-es6-d85a23f8e193) -![was boy pokemon silver debugger demo](./docs/images/wasmBoyPokemonSilverDebugger.gif) +Since WasmBoy is built in AssemblyScript, it can also run it's core through the Typescript compiler if we mock out some of the WebAssembly interface. The benchmarking tool was built as a way to compare WebAssembly performance to Javascript / ES6 performance, after compiling the core to both WebAssembly and Javascript. It includes detailed stats, live running output, and multiple graphs. Also great for comparing the performance of devices that run WasmBoy. + +**Anaytics / Privacy** + +Analytics is used on this application simply for performance monitoring, and tracking popularity of the application. The following events are sent, with nothing more than the event name. The analytics provider used is [Google Analytics](https://analytics.google.com/analytics/web/). + +- Whenever a new ROM is loaded from the particular source. +- Whenever the benchmark is ran. +- Whenever results are rendered for the benchmark. + +**Example** + +![WasmBoy Benchmark Runner Section on Safari](./docs/images/benchmarkSafariBackToColorRunner.png) # Tests @@ -139,7 +194,7 @@ halt_ime0_ei, halt_ime0_nointr_timing, halt_ime1_timing # Contributing -Feel free to fork and submit PRs! Any help is much appreciated, and would be a ton of fun! +Feel free to fork and submit PRs! Opening an issue is reccomended before starting any development, as a discussion would be nice on the idea / feature before writing code. Any help is much appreciated, and would be a ton of fun! ### Installation @@ -149,21 +204,30 @@ Just your standard node app. Install Node with [nvm](https://github.com/creation The project contains three different elements. -- The `debugger` is the container for the wasmboy library, which is simply a [preact](https://github.com/developit/preact) application, generated with [preact-cli](https://github.com/developit/preact-cli). - The `core` or `wasm` which is the web assembly module for wasmboy written in [AssemblyScript](https://github.com/AssemblyScript/assemblyscript). - The `lib` which is the importable library of wasmboy that can be used in other projects, that adds a top level API to the `core`. +- The `demo`, which is a collection of different apps that are used for demoing purposes of the `lib` and `core`. -Each of these uses a different build process. The debugger uses [webpack](https://webpack.js.org/), the wasm uses the [AssemblyScript](https://github.com/AssemblyScript/assemblyscript) compiler CLI tool, and the lib uses [Rollup.js](https://rollupjs.org/guide/en). +Most of the build process in this project is done using [Rollup.js](https://rollupjs.org/guide/en). Each element / component of the project is configured in its own `rollup.*.js` file, and are then all used within the standard `rollup.config.js` file by the rollup CLI. Also, The `core` wasm uses the [AssemblyScript](https://github.com/AssemblyScript/assemblyscript) compiler CLI tool. Commands for each part of the project will be prepended with their element name and a colon, e.g `debugger:[command here]`. +Common command parts are: + +- `dev` / `watch` - How the project should be served and developed with tools like reloading. +- `build` - Make production builds of the component / element of the project. + Commands not prepended with a colon are meant for easily building on all of the different parts as a whole. +Not all commands are documented, only ones relevant to making changes to the library for contributions. `*` represents the category of commands, and is not an actual command. + ```bash # Command to serve the project, and watch the debugger, wasm, and lib for changes # Uses concurrently: https://github.com/kimmobrunfeldt/concurrently -# Concurrently helps cleanup the output and organizes all three watchers/servers -npm start +# Concurrently helps cleanup the output and organizes watchers on commands that require concurrent tools + +# Serve the general project for development (Watches the core, lib, and debugger) +npm run start # Same as npm start npm run dev @@ -171,39 +235,37 @@ npm run dev # Same as npm start npm run watch -# Build the wasm module and the lib to be ready to be pushed to npm or released +# Build everything to be ready to be pushed to npm or released npm run build +# Linting commands used during precommit an tests +npm run prettier:* + +# Commands for building/serving the core, offers commands for building with the Assemblyscript Compiler (WASM) or Typescript (JS) +npm run core:* + +# Commands for building/serving the JS lib +npm run lib:* + # Run tests in `test/accuracy/test.js` npm run test # Run tests in `test/performance/test.js` npm run test:performance -# Watch the debugger (preact) project for changes and livereload -npm run debugger:watch +# All commands for testing, and are test related +npm run test:* -# Build the debugger (preact) project and serve it -npm run debugger:serve +# Commands for the building / serving the debugger +npm run debugger:* -# Build the debugger (preact) project -npm run debugger:build +# Commands for building / serving the benchmark tool +npm run benchmark:* -# Watch the wasm (AssemblyScript) *.ts files and build on changes -npm run core:watch - -# Build the wasm (AssemblyScript) *.ts files, with the correct CLI flags -npm run core:build - -# Watch the Wasmboy ES6 Module for changes, and build -npm run lib:watch - -# Build the WasmBoy Es6 module -npm run lib:build +# Commands for building / serving all available apps in wasmboy +npm run demo:* ``` -The debugger application/container for wasmboy utilizes the [preact-cli](https://github.com/developit/preact-cli/blob/master/README.md). Additional workflow commands and tips can be found there. - Using the [gh-pages](https://www.npmjs.com/package/gh-pages) for debugger/demo deployment onto gh-pages. # Notable Projects diff --git a/core/debug/debug-graphics.ts b/core/debug/debug-graphics.ts index b28936c0..e7c76063 100644 --- a/core/debug/debug-graphics.ts +++ b/core/debug/debug-graphics.ts @@ -19,7 +19,7 @@ export function getLY(): i32 { return Graphics.scanlineRegister; } -export function drawBackgroundMapToWasmMemory(showColor: i32 = 0): void { +export function drawBackgroundMapToWasmMemory(showColor: i32): void { // http://www.codeslinger.co.uk/pages/projects/gameboy/graphics.html // Bit 7 - LCD Display Enable (0=Off, 1=On) // Bit 6 - Window Tile Map Display Select (0=9800-9BFF, 1=9C00-9FFF) @@ -221,7 +221,9 @@ export function drawTileDataToWasmMemory(): void { tileDataMapGridY * 8 + tileLineY, 0x1f * 8, TILE_DATA_LOCATION, - true + true, + 0, + -1 ); } } diff --git a/core/graphics/tiles.ts b/core/graphics/tiles.ts index 219b340b..0ad95151 100644 --- a/core/graphics/tiles.ts +++ b/core/graphics/tiles.ts @@ -33,9 +33,9 @@ export function drawPixelsFromLineOfTile( outputLineY: i32, outputWidth: i32, wasmMemoryStart: i32, - shouldRepresentMonochromeColorByColorId: boolean = false, - paletteLocation: i32 = 0, - bgMapAttributes: i32 = -1 + shouldRepresentMonochromeColorByColorId: boolean, + paletteLocation: i32, + bgMapAttributes: i32 ): i32 { // Get our number of pixels drawn let pixelsDrawn: i32 = 0; diff --git a/demo/benchmark/index.js b/demo/benchmark/index.js index 691cb984..98b67d83 100644 --- a/demo/benchmark/index.js +++ b/demo/benchmark/index.js @@ -1,7 +1,7 @@ import { h, render, Component } from 'preact'; import 'bulma/css/bulma.css'; -import '../debugger/style.css'; +import './style.css'; import './index.css'; import valoo from 'valoo'; diff --git a/demo/benchmark/loadrom.js b/demo/benchmark/loadrom.js index c7982a8f..0a7a2417 100644 --- a/demo/benchmark/loadrom.js +++ b/demo/benchmark/loadrom.js @@ -1,14 +1,15 @@ import { h, Component } from 'preact'; import Portal from 'preact-portal'; -import '../debugger/wasmboyFilePicker/wasmboyFilePicker.css'; +import './wasmboyFilePicker.css'; // Import some functions from our lib import { sendAnalyticsEvent } from './analytics'; import { fetchROMAsByteArray } from '../../lib/wasmboy/fetchrom.js'; -// Import our open source roms from the debugger -import { openSourceROMs, getOpenSourceROMElements } from '../debugger/wasmboyFilePicker/openSourceROMs'; +// Import our open source roms +import { openSourceROMS } from '../openSourceROMs'; +import { getOpenSourceROMElements } from '../openSourceROMsPreact'; export default class LoadROMSelector extends Component { constructor(props) { diff --git a/demo/debugger/style.css b/demo/benchmark/style.css similarity index 100% rename from demo/debugger/style.css rename to demo/benchmark/style.css diff --git a/demo/debugger/wasmboyFilePicker/wasmboyFilePicker.css b/demo/benchmark/wasmboyFilePicker.css similarity index 100% rename from demo/debugger/wasmboyFilePicker/wasmboyFilePicker.css rename to demo/benchmark/wasmboyFilePicker.css diff --git a/demo/debugger/analytics.js b/demo/debugger/analytics.js new file mode 100644 index 00000000..9cab1884 --- /dev/null +++ b/demo/debugger/analytics.js @@ -0,0 +1,85 @@ +import loadScript from 'load-script'; + +class DebuggerAnalyticsLib { + constructor() { + /*ROLLUP_REPLACE_DEBUGGER_DEV + this.readyPromise = Promise.resolve(); + return; + ROLLUP_REPLACE_DEBUGGER_DEV*/ + + this.readyPromise = new Promise((resolve, reject) => { + if (typeof window !== 'undefined') { + loadScript('https://www.googletagmanager.com/gtag/js?id=UA-125276735-1', (err, script) => { + if (err) { + reject(err); + } + + window.dataLayer = window.dataLayer || []; + function gtag() { + window.dataLayer.push(arguments); + } + gtag('js', new Date()); + gtag('config', 'UA-125276735-1'); + + // Attach Analytics to this class + this.gtag = gtag; + resolve(); + }); + } else { + reject(new Error('Not in a browser Environment')); + } + }); + } + + _fireAnalyticsEvent(eventAction) { + const fireEventTask = async () => { + await this.readyPromise; + + if (this.gtag) { + this.gtag('event', eventAction); + } else { + console.log('Analytics Event Action:', eventAction); + } + }; + + fireEventTask().catch(() => { + // Do Nothing + }); + } + + // Define our events + ROMLoadedAndStarted() { + this._fireAnalyticsEvent('rom_loaded_and_started'); + } + + loadROMSuccess() { + this._fireAnalyticsEvent('load_rom_success'); + } + + loadROMFail() { + this._fireAnalyticsEvent('load_rom_fail'); + } + + saveState() { + this._fireAnalyticsEvent('save_state'); + } + + loadState() { + this._fireAnalyticsEvent('load_state'); + } + + appliedOptions() { + this._fireAnalyticsEvent('applied_options'); + } + + googleDriveLoad() { + this._fireAnalyticsEvent('google_drive_load'); + } + + reload() { + this._fireAnalyticsEvent('reload'); + } +} + +const DebuggerAnalytics = new DebuggerAnalyticsLib(); +export default DebuggerAnalytics; diff --git a/demo/debugger/assets/debuggerWalkthrough.mp4 b/demo/debugger/assets/debuggerWalkthrough.mp4 new file mode 100644 index 00000000..93342c5b Binary files /dev/null and b/demo/debugger/assets/debuggerWalkthrough.mp4 differ diff --git a/demo/debugger/assets/helpOpenROM.jpg b/demo/debugger/assets/helpOpenROM.jpg new file mode 100644 index 00000000..b533aa56 Binary files /dev/null and b/demo/debugger/assets/helpOpenROM.jpg differ diff --git a/demo/debugger/assets/helpOpenWidget.jpg b/demo/debugger/assets/helpOpenWidget.jpg new file mode 100644 index 00000000..43e832b6 Binary files /dev/null and b/demo/debugger/assets/helpOpenWidget.jpg differ diff --git a/demo/debugger/commands/command.js b/demo/debugger/commands/command.js new file mode 100644 index 00000000..590e28fa --- /dev/null +++ b/demo/debugger/commands/command.js @@ -0,0 +1,16 @@ +// Base Class for all of out other commands +export default class Command { + constructor(id) { + this.id = id; + + // http://phosphorjs.github.io/phosphor/api/commands/interfaces/commandregistry.icommandoptions.html + this.options = { + label: 'Command', + execute: () => this.execute() + }; + } + + execute() { + console.log('Command Executed!'); + } +} diff --git a/demo/debugger/commands/commands.js b/demo/debugger/commands/commands.js new file mode 100644 index 00000000..5f227b90 --- /dev/null +++ b/demo/debugger/commands/commands.js @@ -0,0 +1,33 @@ +import phosphorCommands from '@phosphor/commands'; + +// Commands +import openCommands from './open'; +import playbackCommands from './widgets/playback'; +import cpuCommands from './widgets/cpu'; +import graphicsCommands from './widgets/graphics'; +import audioCommands from './widgets/audio'; +import interruptCommands from './widgets/interrupt'; +import timerCommands from './widgets/timer'; +import otherCommands from './widgets/other'; + +const importedCommands = [ + openCommands, + playbackCommands, + cpuCommands, + graphicsCommands, + audioCommands, + interruptCommands, + timerCommands, + otherCommands +]; + +// Commands that will be execute by click actions and things +const commands = new phosphorCommands.CommandRegistry(); + +importedCommands.forEach(importedCommand => { + importedCommand.forEach(command => { + commands.addCommand(command.id, command.options); + }); +}); + +export default commands; diff --git a/demo/debugger/commands/open.js b/demo/debugger/commands/open.js new file mode 100644 index 00000000..bb0f0c0d --- /dev/null +++ b/demo/debugger/commands/open.js @@ -0,0 +1,153 @@ +// Top Bar Menu to open files to be played + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import loadScript from 'load-script'; + +import Command from './command'; +import { WasmBoy } from '../wasmboy'; +import DebuggerAnalytics from '../analytics'; +import loadROM from '../loadROM'; +import { PUBX_KEYS } from '../pubx.config'; + +import { getOpenSourceROMElements } from '../../openSourceROMsPreact'; +import GoogleDrivePicker from '../../googleDrivePicker'; + +class OpenLocalFile extends Command { + constructor() { + super('open:local'); + this.options.label = 'Local File'; + + // Create a hidden input on the page for opening files + const hiddenInput = document.createElement('input'); + hiddenInput.classList.add('hidden-rom-input'); + hiddenInput.setAttribute('type', 'file'); + hiddenInput.setAttribute('accept', '.gb, .gbc, .zip'); + hiddenInput.setAttribute('hidden', true); + hiddenInput.addEventListener('change', this.onChange.bind(this)); + document.body.appendChild(hiddenInput); + + this.hiddenInput = hiddenInput; + } + + execute() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + this.hiddenInput.click(); + } + + onChange(event) { + loadROM(event.target.files[0], event.target.files[0].name); + } +} + +// Open Source Roms +class OpenOpenSourceROM extends Command { + constructor() { + super('open:opensource'); + this.options.label = 'Open Source ROMs'; + } + + execute() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + + // Using a stateless functional component + Pubx.get(PUBX_KEYS.MODAL).showModal(() => { + return ( +
+ {getOpenSourceROMElements(ROMObject => { + loadROM(ROMObject.url, ROMObject.title); + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + })} +
+ ); + }); + } +} + +// TODO: This is for testing for now +// https://gbhh.avivace.com/developers +class OpenHomebrewHubROM extends Command { + constructor() { + super('open:homebrewhub'); + this.options.label = 'Homebrew Hub ROMs'; + } + + execute() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + + // Just fetch and run 2048 for testing + const homebrewHubTask = async () => { + // Test making a request for the ROMS + const json = await fetch('https://gbhh.avivace.com/api/homebrews').then(response => response.json()); + console.log('Homebrews response', json); + + // Fetch using Wasmboy + await WasmBoy.loadROM('https://gbhh.avivace.com/database/entries/2048gb/2048.gb'); + await WasmBoy.play(); + }; + homebrewHubTask(); + } +} + +// Public Keys for Google Drive API +const WASMBOY_DEBUGGER_GOOGLE_PICKER_CLIENT_ID = '427833658710-bntpbmf6pimh8trt0n4c36gteomseg61.apps.googleusercontent.com'; + +class OpenGoogleDriveROM extends Command { + constructor() { + super('open:googledrive'); + this.options.label = 'Google Drive'; + + GoogleDrivePicker.initialize(WASMBOY_DEBUGGER_GOOGLE_PICKER_CLIENT_ID); + } + + execute() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + + // Fire off some analytics + DebuggerAnalytics.googleDriveLoad(); + + // Get the ROM from google drive + const loadGDriveROMTask = async () => { + const pickerResponse = await GoogleDrivePicker.getFile(['application/zip', 'application/octet-stream']); + + if (pickerResponse.cancelled) { + return; + } + + const { response, oAuthHeaders } = pickerResponse; + + if (response.title.endsWith('.zip') || response.title.endsWith('.gb') || response.title.endsWith('.gbc')) { + await WasmBoy.pause(); + await WasmBoy.loadROM(response.downloadUrl, { + headers: oAuthHeaders, + fileName: response.title + }); + await WasmBoy.play(); + Pubx.publish(PUBX_KEYS.WASMBOY, { + filename: response.title + }); + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Game Loaded! 🎉'); + } else { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Invalid file type. 😞'); + } + }; + const loadGDriveROMPromise = loadGDriveROMTask().catch(error => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification(error); + }); + Pubx.get(PUBX_KEYS.LOADING).addControlPromise(loadGDriveROMPromise); + } +} + +const exportedCommands = [ + new OpenLocalFile(), + new OpenOpenSourceROM(), + // new OpenHomebrewHubROM(), + new OpenGoogleDriveROM() +]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/audio.js b/demo/debugger/commands/widgets/audio.js new file mode 100644 index 00000000..6174c764 --- /dev/null +++ b/demo/debugger/commands/widgets/audio.js @@ -0,0 +1,28 @@ +// Commands for playback + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import AudioState from '../../components/audio/audioState/audioState'; + +class AudioStateCommand extends Command { + constructor() { + super('audio:state'); + this.options.label = 'State'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Audio State' + }); + } +} + +const exportedCommands = [new AudioStateCommand()]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/cpu.js b/demo/debugger/commands/widgets/cpu.js new file mode 100644 index 00000000..a30c9e96 --- /dev/null +++ b/demo/debugger/commands/widgets/cpu.js @@ -0,0 +1,43 @@ +// Commands for playback + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import CpuState from '../../components/cpu/cpuState/cpuState'; +import CpuControl from '../../components/cpu/cpuControl/cpuControl'; + +class CpuStateCommand extends Command { + constructor() { + super('cpu:state'); + this.options.label = 'State'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'CPU State' + }); + } +} + +class CpuControlCommand extends Command { + constructor() { + super('cpu:control'); + this.options.label = 'Control'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'CPU Control' + }); + } +} + +const exportedCommands = [new CpuStateCommand(), new CpuControlCommand()]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/graphics.js b/demo/debugger/commands/widgets/graphics.js new file mode 100644 index 00000000..37562b9b --- /dev/null +++ b/demo/debugger/commands/widgets/graphics.js @@ -0,0 +1,58 @@ +// Commands for playback + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import GraphicsState from '../../components/graphics/graphicsState/graphicsState'; +import BackgroundMap from '../../components/graphics/backgroundMap/backgroundMap'; +import TileData from '../../components/graphics/tileData/tileData'; + +class GraphicsStateCommand extends Command { + constructor() { + super('graphics:state'); + this.options.label = 'State'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Graphics State' + }); + } +} + +class BackgroundMapCommand extends Command { + constructor() { + super('graphics:backgroundmap'); + this.options.label = 'Background Map'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Background Map' + }); + } +} + +class TileDataCommand extends Command { + constructor() { + super('graphics:tiledata'); + this.options.label = 'Tile Data'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Tile Data' + }); + } +} + +const exportedCommands = [new GraphicsStateCommand(), new BackgroundMapCommand(), new TileDataCommand()]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/interrupt.js b/demo/debugger/commands/widgets/interrupt.js new file mode 100644 index 00000000..51f07987 --- /dev/null +++ b/demo/debugger/commands/widgets/interrupt.js @@ -0,0 +1,28 @@ +// Commands for playback + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import InterruptState from '../../components/interrupt/interruptState/interruptState'; + +class InterruptStateCommand extends Command { + constructor() { + super('interrupt:state'); + this.options.label = 'State'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Interrupt State' + }); + } +} + +const exportedCommands = [new InterruptStateCommand()]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/other.js b/demo/debugger/commands/widgets/other.js new file mode 100644 index 00000000..f5ed9a7c --- /dev/null +++ b/demo/debugger/commands/widgets/other.js @@ -0,0 +1,43 @@ +// Commands for other components + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import AboutComponent from '../../components/other/about/about'; +import HelpComponent from '../../components/other/help/help'; + +class AboutCommand extends Command { + constructor() { + super('other:about'); + this.options.label = 'About'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'About' + }); + } +} + +class HelpCommand extends Command { + constructor() { + super('other:help'); + this.options.label = 'Help'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Help' + }); + } +} + +const exportedCommands = [new AboutCommand(), new HelpCommand()]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/playback.js b/demo/debugger/commands/widgets/playback.js new file mode 100644 index 00000000..0fc321d5 --- /dev/null +++ b/demo/debugger/commands/widgets/playback.js @@ -0,0 +1,58 @@ +// Commands for playback + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import WasmBoyControls from '../../components/playback/wasmboyControls/wasmboyControls'; +import WasmBoyInfo from '../../components/playback/wasmboyInfo/wasmboyInfo'; +import WasmBoyOptions from '../../components/playback/wasmboyOptions/wasmboyOptions'; + +class PlaybackControls extends Command { + constructor() { + super('playback:controls'); + this.options.label = 'Controls'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Playback Controls' + }); + } +} + +class PlaybackInfo extends Command { + constructor() { + super('playback:info'); + this.options.label = 'Info'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Playback Info' + }); + } +} + +class PlaybackOptions extends Command { + constructor() { + super('playback:options'); + this.options.label = 'Options'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Playback Options' + }); + } +} + +const exportedCommands = [new PlaybackControls(), new PlaybackInfo(), new PlaybackOptions()]; +export default exportedCommands; diff --git a/demo/debugger/commands/widgets/timer.js b/demo/debugger/commands/widgets/timer.js new file mode 100644 index 00000000..d548d20a --- /dev/null +++ b/demo/debugger/commands/widgets/timer.js @@ -0,0 +1,28 @@ +// Commands for playback + +import { h } from 'preact'; + +import { Pubx } from 'pubx'; + +import { PUBX_KEYS } from '../../pubx.config'; + +import Command from '../command'; + +import TimerState from '../../components/timer/timerState/timerState'; + +class TimerStateCommand extends Command { + constructor() { + super('timer:state'); + this.options.label = 'State'; + } + + execute() { + Pubx.get(PUBX_KEYS.WIDGET).addWidget({ + component: , + label: 'Timer State' + }); + } +} + +const exportedCommands = [new TimerStateCommand()]; +export default exportedCommands; diff --git a/demo/debugger/components/audio/audioState/audioState.css b/demo/debugger/components/audio/audioState/audioState.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/components/audio/audioState/audioState.js b/demo/debugger/components/audio/audioState/audioState.js new file mode 100644 index 00000000..74d4ef08 --- /dev/null +++ b/demo/debugger/components/audio/audioState/audioState.js @@ -0,0 +1,43 @@ +import { WasmBoy } from '../../../wasmboy'; + +import ValueTable from '../../valueTable.js'; +import './audioState.css'; + +export default class AudioState extends ValueTable { + constructor() { + super(); + + this.state.title = 'Audio'; + } + + intervalUpdate() { + if (!WasmBoy.isReady()) { + return; + } + + const updateTask = async () => { + const valueTable = {}; + + // Get all of the gameboy 0xffXX memory + const debugMemoryStart = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xff00]); + const debugMemoryEnd = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xffff]); + const debugMemory = await WasmBoy._getWasmMemorySection(debugMemoryStart, debugMemoryEnd + 1); + + // Update APU valueTable + // Add the register valueTable for our 4 channels + for (let channelNum = 1; channelNum <= 4; channelNum++) { + for (let registerNum = 0; registerNum < 5; registerNum++) { + let registerAddress = 0xff10 + 5 * (channelNum - 1) + registerNum; + valueTable[`Channel ${channelNum} - NR${channelNum}${registerNum} - 0x${registerAddress.toString(16).toUpperCase()}`] = + debugMemory[registerAddress & 0x00ff]; + } + } + + this.setState({ + ...this.state, + object: valueTable + }); + }; + updateTask(); + } +} diff --git a/demo/debugger/components/cpu/cpuControl/cpuControl.css b/demo/debugger/components/cpu/cpuControl/cpuControl.css new file mode 100644 index 00000000..ac7da44c --- /dev/null +++ b/demo/debugger/components/cpu/cpuControl/cpuControl.css @@ -0,0 +1,14 @@ +.cpu-control { +} + +.cpu-control .donut { + display: none; +} + +.cpu-control--control-loading .donut { + display: block; +} + +.cpu-control--control-loading .cpu-control__control-container { + display: none; +} diff --git a/demo/debugger/components/cpu/cpuControl/cpuControl.js b/demo/debugger/components/cpu/cpuControl/cpuControl.js new file mode 100644 index 00000000..db3ecf88 --- /dev/null +++ b/demo/debugger/components/cpu/cpuControl/cpuControl.js @@ -0,0 +1,134 @@ +import { h, Component } from 'preact'; + +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import { WasmBoy } from '../../../wasmboy'; + +import ValueTable from '../../valueTable.js'; +import './cpuControl.css'; + +import { stepOpcode, runNumberOfOpcodes, runUntilBreakPoint } from '../opcode.js'; + +let unsubLoading = false; + +export default class CpuControl extends Component { + constructor() { + super(); + + this.state.numberOfOpcodes = 2000; + this.state.breakPoint = 40; + } + + componentDidMount() { + unsubLoading = Pubx.subscribe(PUBX_KEYS.LOADING, newState => this.checkControlLoading(newState)); + this.checkControlLoading(Pubx.get(PUBX_KEYS.LOADING)); + } + + componentWillUnmount() { + if (unsubLoading) { + unsubLoading(); + } + } + + checkControlLoading(newState) { + if (newState.controlLoading) { + this.base.classList.add('cpu-control--control-loading'); + } else { + this.base.classList.remove('cpu-control--control-loading'); + } + } + + stepOpcode() { + if (!WasmBoy.isReady()) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please load a ROM. 💾'); + return; + } + + stepOpcode(); + } + + runNumberOfOpcodes() { + if (!WasmBoy.isReady()) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please load a ROM. 💾'); + return; + } + + const numberOfOpcodes = Math.floor(this.state.numberOfOpcodes); + + if (!numberOfOpcodes || numberOfOpcodes < 1) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please enter a valid value. 😄'); + return; + } + + const runOpcodesPromise = runNumberOfOpcodes(numberOfOpcodes); + runOpcodesPromise.then(() => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification(`Ran ${numberOfOpcodes} opcodes! 😄`); + }); + Pubx.get(PUBX_KEYS.LOADING).addControlPromise(runOpcodesPromise); + } + + runUntilBreakPoint() { + if (!WasmBoy.isReady()) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please load a ROM. 💾'); + return; + } + + const breakPoint = Math.floor(this.state.breakPoint); + + if (!breakPoint || breakPoint < 0) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please enter a valid value. 😄'); + return; + } + + const runUntilBreakPointPromise = runUntilBreakPoint(breakPoint); + runUntilBreakPointPromise.then(() => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification(`Ran until the 0x${breakPoint} break point! 😄`); + }); + Pubx.get(PUBX_KEYS.LOADING).addControlPromise(runUntilBreakPointPromise); + } + + render() { + return ( +
+

CPU Control

+
+ ROMs will not autoplay while this widget is open. +
+ +
+ + {/* Single Stepping */} +
+ +
+ + {/* Run a specified number */} +
+ + this.setState({ numberOfOpcodes: event.target.value })} + /> + +
+ + {/* Break Points */} +
+ + this.setState({ breakPoint: event.target.value })} + /> + +
+
+ ); + } +} diff --git a/demo/debugger/components/cpu/cpuState/cpuState.css b/demo/debugger/components/cpu/cpuState/cpuState.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/components/cpu/cpuState/cpuState.js b/demo/debugger/components/cpu/cpuState/cpuState.js new file mode 100644 index 00000000..2889728b --- /dev/null +++ b/demo/debugger/components/cpu/cpuState/cpuState.js @@ -0,0 +1,46 @@ +import { h } from 'preact'; + +import { WasmBoy } from '../../../wasmboy'; + +import ValueTable from '../../valueTable.js'; +import './cpuState.css'; + +export default class CpuState extends ValueTable { + constructor() { + super(); + + this.state.title = 'CPU'; + } + + intervalUpdate() { + if (!WasmBoy.isReady()) { + return; + } + + const updateTask = async () => { + const valueTable = {}; + + // Update CPU valueTable + valueTable['Program Counter (PC)'] = await WasmBoy._runWasmExport('getProgramCounter'); + valueTable['Opcode at PC'] = await WasmBoy._runWasmExport('getOpcodeAtProgramCounter'); + valueTable['Stack Pointer'] = await WasmBoy._runWasmExport('getStackPointer'); + valueTable['Register A'] = await WasmBoy._runWasmExport('getRegisterA'); + valueTable['Register F'] = await WasmBoy._runWasmExport('getRegisterF'); + valueTable['Register B'] = await WasmBoy._runWasmExport('getRegisterB'); + valueTable['Register C'] = await WasmBoy._runWasmExport('getRegisterC'); + valueTable['Register D'] = await WasmBoy._runWasmExport('getRegisterD'); + valueTable['Register E'] = await WasmBoy._runWasmExport('getRegisterE'); + valueTable['Register H'] = await WasmBoy._runWasmExport('getRegisterH'); + valueTable['Register L'] = await WasmBoy._runWasmExport('getRegisterL'); + + const cyclesRan = await WasmBoy._getCyclesAsString(); + + this.setState({ + ...this.state, + object: valueTable, + headerElement:
Cycles Ran: {cyclesRan}
+ }); + }; + updateTask(); + } +} diff --git a/demo/debugger/components/cpu/opcode.js b/demo/debugger/components/cpu/opcode.js new file mode 100644 index 00000000..76940f74 --- /dev/null +++ b/demo/debugger/components/cpu/opcode.js @@ -0,0 +1,80 @@ +// File to do per-opcode operations + +import { WasmBoy } from '../../wasmboy'; + +// Function to run a single opcode +export function stepOpcode() { + const stepOpcodeTask = async () => { + // We should pause wasmboy + if (WasmBoy.isPlaying()) { + await WasmBoy.pause(); + } + + const numberOfCycles = await WasmBoy._runWasmExport('emulationStep'); + + if (numberOfCycles <= 0) { + console.error('Opcode not recognized! Check wasm logs.'); + this.updateDebugInfo(); + throw new Error(); + } + }; + return stepOpcodeTask(); +} + +// Function to run a specifed number of opcodes for faster stepping +export function runNumberOfOpcodes(numberOfOpcodes, breakPoint) { + // Keep stepping until highest opcode increases + let opcodesToRun = numberOfOpcodes; + + const runNumberOfOpcodesTask = async () => { + let opcodesRan = 0; + + const runOpcode = async () => { + await stepOpcode(true); + const programCounter = await WasmBoy._runWasmExport('getProgramCounter'); + if (breakPoint && breakPoint === programCounter) { + return; + } + + if (opcodesRan < opcodesToRun) { + opcodesRan++; + await runOpcode(); + return; + } + }; + await runOpcode(); + }; + return runNumberOfOpcodesTask(); +} + +// Function to keep running opcodes until a breakpoint is reached +export function runUntilBreakPoint(passedBreakPoint) { + // Set our opcode breakpoint + const breakPoint = parseInt(passedBreakPoint, 16); + + stepOpcode(); + + const breakPointTask = async breakPoint => { + const response = await WasmBoy._runWasmExport('executeFrameUntilBreakpoint', [breakPoint]); + + if (response === 0) { + const continueSearchingForBreakPointTask = async () => { + await new Promise(resolve => { + requestAnimationFrame(() => { + resolve(); + }); + }); + + return breakPointTask(breakPoint); + }; + + return continueSearchingForBreakPointTask(); + } else if (response === -1) { + throw new Error('WasmBoy Crashed while trying to reach the breakpoint'); + } + + // We Reached the breakpoint! + return true; + }; + return breakPointTask(breakPoint); +} diff --git a/demo/debugger/components/graphics/backgroundMap/backgroundMap.css b/demo/debugger/components/graphics/backgroundMap/backgroundMap.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/wasmboyDebugger/wasmboyBackgroundMap/wasmboyBackgroundMap.js b/demo/debugger/components/graphics/backgroundMap/backgroundMap.js similarity index 79% rename from demo/debugger/wasmboyDebugger/wasmboyBackgroundMap/wasmboyBackgroundMap.js rename to demo/debugger/components/graphics/backgroundMap/backgroundMap.js index 4b7e0ba8..26662b43 100644 --- a/demo/debugger/wasmboyDebugger/wasmboyBackgroundMap/wasmboyBackgroundMap.js +++ b/demo/debugger/components/graphics/backgroundMap/backgroundMap.js @@ -1,14 +1,22 @@ -import { Component } from 'preact'; -import { WasmBoy } from '../../../../dist/wasmboy.wasm.esm'; -import './wasmboyBackgroundMap.css'; +import { h, Component } from 'preact'; -export class WasmBoyBackgroundMap extends Component { - constructor(props) { - super(props); +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import { WasmBoy } from '../../../wasmboy'; + +import './backgroundMap.css'; + +export default class BackgroundMap extends Component { + constructor() { + super(); + + this.shouldUpdate = true; + this.updateTimeout = false; } componentDidMount() { - const canvasElement = document.getElementById('WasmBoyBackgroundMap'); + const canvasElement = this.base.querySelector('#background-map__canvas'); const canvasContext = canvasElement.getContext('2d'); const canvasImageData = canvasContext.createImageData(256, 256); @@ -25,25 +33,36 @@ export class WasmBoyBackgroundMap extends Component { `; // Fill the canvas with a blank screen - // using client width since we are not requiring a width and height oin the canvas + // using client width since we are not requiring a width and height on the canvas // https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth - // TODO: Mention respopnsive canvas scaling in the docs canvasContext.clearRect(0, 0, canvasElement.width, canvasElement.height); + this.shouldUpdate = true; + const updateBackgroundMap = () => { this.updateBackgroundMap(canvasElement, canvasContext, canvasImageData).then(() => { - setTimeout(() => { - updateBackgroundMap(); - }, 500); + if (this.shouldUpdate) { + this.updateTimeout = setTimeout(() => { + updateBackgroundMap(); + }, 100); + } }); }; updateBackgroundMap(); } + componentWillUnmount() { + this.shouldUpdate = false; + if (this.updateTimeout) { + clearTimeout(this.updateTimeout); + this.updateTimeout = false; + } + } + updateBackgroundMap(canvasElement, canvasContext, canvasImageData) { const updateBackgroundMapTask = async () => { // Dont update for the following - if (!WasmBoy.isReady() || WasmBoy.isPaused() || !this.props.shouldUpdate) { + if (!WasmBoy.isReady() || WasmBoy.isPaused()) { return; } @@ -91,8 +110,8 @@ export class WasmBoyBackgroundMap extends Component { // Draw a semi Transparent camera thing over the imagedata // https://www.html5canvastutorials.com/tutorials/html5-canvas-rectangles/ // Get the scroll X and Y - const scrollMemoryRegistersStart = await this.props.getWasmBoyOffsetFromGameBoyOffset(0xff42); - const scrollMemoryRegistersEnd = (await this.props.getWasmBoyOffsetFromGameBoyOffset(0xff43)) + 1; + const scrollMemoryRegistersStart = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xff42]); + const scrollMemoryRegistersEnd = (await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xff43])) + 1; const scrollMemoryRegisters = await WasmBoy._getWasmMemorySection(scrollMemoryRegistersStart, scrollMemoryRegistersEnd); @@ -139,11 +158,9 @@ export class WasmBoyBackgroundMap extends Component { render() { return ( -
+

Background Map

-
- -
+
); } diff --git a/demo/debugger/components/graphics/graphicsState/graphicsState.css b/demo/debugger/components/graphics/graphicsState/graphicsState.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/components/graphics/graphicsState/graphicsState.js b/demo/debugger/components/graphics/graphicsState/graphicsState.js new file mode 100644 index 00000000..d3e76cc7 --- /dev/null +++ b/demo/debugger/components/graphics/graphicsState/graphicsState.js @@ -0,0 +1,42 @@ +import { WasmBoy } from '../../../wasmboy'; + +import ValueTable from '../../valueTable.js'; +import './graphicsState.css'; + +export default class GraphicsState extends ValueTable { + constructor() { + super(); + + this.state.title = 'Graphics'; + } + + intervalUpdate() { + if (!WasmBoy.isReady()) { + return; + } + + const updateTask = async () => { + const valueTable = {}; + + // Get all of the gameboy 0xffXX memory + const debugMemoryStart = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xff00]); + const debugMemoryEnd = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xffff]); + const debugMemory = await WasmBoy._getWasmMemorySection(debugMemoryStart, debugMemoryEnd + 1); + + // Update CPU valueTable + valueTable['Scanline Register (LY) - 0xFF44'] = await WasmBoy._runWasmExport('getLY'); + valueTable['LCD Status (STAT) - 0xFF41'] = debugMemory[0x0041]; + valueTable['LCD Control (LCDC) - 0xFF40'] = debugMemory[0x0040]; + valueTable['Scroll X - 0xFF43'] = debugMemory[0x0043]; + valueTable['Scroll Y - 0xFF42'] = debugMemory[0x0042]; + valueTable['Window X - 0xFF4B'] = debugMemory[0x004b]; + valueTable['Window Y - 0xFF4A'] = debugMemory[0x004a]; + + this.setState({ + ...this.state, + object: valueTable + }); + }; + updateTask(); + } +} diff --git a/demo/debugger/components/graphics/tileData/tileData.css b/demo/debugger/components/graphics/tileData/tileData.css new file mode 100644 index 00000000..54a81675 --- /dev/null +++ b/demo/debugger/components/graphics/tileData/tileData.css @@ -0,0 +1,2 @@ +.tile-data { +} diff --git a/demo/debugger/wasmboyDebugger/wasmboyTileData/wasmboyTileData.js b/demo/debugger/components/graphics/tileData/tileData.js similarity index 70% rename from demo/debugger/wasmboyDebugger/wasmboyTileData/wasmboyTileData.js rename to demo/debugger/components/graphics/tileData/tileData.js index 496c5730..c799ce57 100644 --- a/demo/debugger/wasmboyDebugger/wasmboyTileData/wasmboyTileData.js +++ b/demo/debugger/components/graphics/tileData/tileData.js @@ -1,18 +1,25 @@ -import { Component } from 'preact'; -import { WasmBoy } from '../../../../dist/wasmboy.wasm.esm'; -import './wasmboyTileData.css'; +import { h, Component } from 'preact'; + +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import { WasmBoy } from '../../../wasmboy'; + +import './tileData.css'; -const canvasId = 'WasmBoyTileData'; const tileDataXPixels = 0x1f * 8; const tileDataYPixels = 0x17 * 8; -export class WasmBoyTileData extends Component { - constructor(props) { - super(props); +export default class TileData extends Component { + constructor() { + super(); + + this.shouldUpdate = true; + this.updateTimeout = false; } componentDidMount() { - const canvasElement = document.getElementById(canvasId); + const canvasElement = this.base.querySelector('#tile-data__canvas'); const canvasContext = canvasElement.getContext('2d'); const canvasImageData = canvasContext.createImageData(tileDataXPixels, tileDataYPixels); @@ -31,28 +38,39 @@ export class WasmBoyTileData extends Component { // Fill the canvas with a blank screen // using client width since we are not requiring a width and height oin the canvas // https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth - // TODO: Mention respopnsive canvas scaling in the docs canvasContext.clearRect(0, 0, canvasElement.width, canvasElement.height); - const updateCanvas = () => { - this.updateCanvas(canvasElement, canvasContext, canvasImageData).then(() => { - setTimeout(() => { - updateCanvas(); - }, 500); + this.shouldUpdate = true; + + const updateCallback = () => { + this.updateCallback(canvasElement, canvasContext, canvasImageData).then(() => { + if (this.shouldUpdate) { + this.updateTimeout = setTimeout(() => { + updateCallback(); + }, 100); + } }); }; - updateCanvas(); + updateCallback(); + } + + componentWillUnmount() { + this.shouldUpdate = false; + if (this.updateTimeout) { + clearTimeout(this.updateTimeout); + this.updateTimeout = false; + } } - updateCanvas(canvasElement, canvasContext, canvasImageData) { + updateCallback(canvasElement, canvasContext, canvasImageData) { const updateCanvasTask = async () => { // Dont update for the following - if (!WasmBoy.isReady() || WasmBoy.isPaused() || !this.props.shouldUpdate) { + if (!WasmBoy.isReady() || WasmBoy.isPaused()) { return; } // Draw our tile Data - WasmBoy._runWasmExport('drawTileDataToWasmMemory'); + await WasmBoy._runWasmExport('drawTileDataToWasmMemory'); const imageDataArray = new Uint8ClampedArray(tileDataYPixels * tileDataXPixels * 4); const rgbColor = new Uint8ClampedArray(3); @@ -100,11 +118,9 @@ export class WasmBoyTileData extends Component { render() { return ( -
+

Tile Data

-
- -
+
); } diff --git a/demo/debugger/components/interrupt/interruptState/interruptState.css b/demo/debugger/components/interrupt/interruptState/interruptState.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/components/interrupt/interruptState/interruptState.js b/demo/debugger/components/interrupt/interruptState/interruptState.js new file mode 100644 index 00000000..7004b83e --- /dev/null +++ b/demo/debugger/components/interrupt/interruptState/interruptState.js @@ -0,0 +1,43 @@ +import { WasmBoy } from '../../../wasmboy'; + +import ValueTable from '../../valueTable.js'; +import './interruptState.css'; + +export default class InterruptState extends ValueTable { + constructor() { + super(); + + this.state.title = 'Interrupt'; + } + + intervalUpdate() { + if (!WasmBoy.isReady()) { + return; + } + + const updateTask = async () => { + const valueTable = {}; + + // Get all of the gameboy 0xffXX memory + const debugMemoryStart = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xff00]); + const debugMemoryEnd = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xffff]); + const debugMemory = await WasmBoy._getWasmMemorySection(debugMemoryStart, debugMemoryEnd + 1); + + // Update interrupts valueTable + // TODO: Interrupot master switch + // if(WasmBoy._getWasmInstance().exports.areInterruptsEnabled()) { + // valueTable.interrupts['Interrupt Master Switch'] = 0x01; + // } else { + // valueTable.interrupts['Interrupt Master Switch'] = 0x00; + // } + valueTable['IE/Interrupt Enabled - 0xFFFF'] = debugMemory[0x00ff]; + valueTable['IF/Interrupt Request - 0xFF0F'] = debugMemory[0x000f]; + + this.setState({ + ...this.state, + object: valueTable + }); + }; + updateTask(); + } +} diff --git a/demo/debugger/components/mobile/mobile.css b/demo/debugger/components/mobile/mobile.css new file mode 100644 index 00000000..990a1b35 --- /dev/null +++ b/demo/debugger/components/mobile/mobile.css @@ -0,0 +1,119 @@ +html.mobile #phosphor-container { + display: none; +} + +html:not(.mobile) #mobile-container { + display: none; +} + +html.mobile #mobile-container { + width: 100%; + height: 100%; + display: block; + overflow: hidden; +} + +html.mobile, +html.mobile body { + height: 100%; + width: 100vw; + margin: 0px; + + /* + // Disable pull to refresh on Chrome and Firefox + // https://stackoverflow.com/questions/36212722/how-to-prevent-pull-down-to-refresh-of-mobile-chrome + // https://developers.google.com/web/updates/2017/11/overscroll-behavior + */ + overscroll-behavior-y: contain; +} + +html.mobile { + overflow: hidden; +} + +html.mobile body { + position: fixed; /* prevent overscroll bounce*/ + overflow-y: scroll; + -webkit-overflow-scrolling: touch; /* iOS velocity scrolling */ +} + +.mobile-container { + width: 100%; + height: 100%; + + background-color: #020202; +} + +.mobile-container__canvas-container { + width: 100%; + height: 100%; +} + +.mobile-container__canvas-container canvas { + object-position: top; +} + +.mobile-container__info-container { + position: absolute; + top: 0; + left: 0; + z-index: 1; + + width: 100%; + height: 100%; + + display: flex; +} + +html.portrait .mobile-container__info-container { + justify-content: center; + align-items: flex-start; +} + +html.landscape .mobile-container__info-container { + justify-content: center; + align-items: center; +} + +.mobile-container__info-container__info { + padding: 10px; + background-color: #fff; +} + +html.portrait .mobile-container__info-container__info { + width: 100%; + height: 45%; + overflow: auto; +} + +html.landscape .mobile-container__info-container__info { + width: 50%; + height: 100%; + overflow: auto; + + padding-top: 50px; + padding-bottom: 100px; +} + +.mobile-container .donut { + position: absolute; + + display: none; + z-index: 2; +} + +.mobile-container.control-loading .donut { + display: flex; +} + +.mobile-container.control-loading .mobile-container__info-container { + display: none; +} + +html.portrait .mobile-container.control-loading .donut { + height: 45%; +} + +html.landscape .mobile-container.control-loading .donut { + height: 100%; +} diff --git a/demo/debugger/components/mobile/mobile.js b/demo/debugger/components/mobile/mobile.js new file mode 100644 index 00000000..b24be448 --- /dev/null +++ b/demo/debugger/components/mobile/mobile.js @@ -0,0 +1,127 @@ +// Base Component to handle showing mobile UIs + +import { h, Component } from 'preact'; +import { WasmBoy } from '../../wasmboy'; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../pubx.config'; + +import Touchpad from './touchpad/touchpad'; + +import './mobile.css'; + +let resizeThrottle = undefined; + +export default class Mobile extends Component { + constructor() { + super(); + + Pubx.subscribe(PUBX_KEYS.WASMBOY, newState => this.setState(newState)); + Pubx.subscribe(PUBX_KEYS.LOADING, newState => { + if (newState.controlLoading) { + this.base.classList.add('control-loading'); + } else { + this.base.classList.remove('control-loading'); + } + }); + + window.addEventListener('resize', () => { + if (resizeThrottle) { + return; + } + + resizeThrottle = setTimeout(() => { + Pubx.get(PUBX_KEYS.MOBILE).update(); + resizeThrottle = undefined; + }, 500); + }); + + window.addEventListener('orientationchange', () => { + if (resizeThrottle) { + return; + } + + resizeThrottle = setTimeout(() => { + Pubx.get(PUBX_KEYS.MOBILE).update(); + resizeThrottle = undefined; + }, 500); + }); + + Pubx.get(PUBX_KEYS.MOBILE).update(); + } + + componentDidMount() {} + + render() { + let wasmboyInfo = ''; + if (!WasmBoy.isLoadedAndStarted()) { + wasmboyInfo = ( +
+

WasmBoy Mobile Demo

+ + {/*VaporBoy Plug*/} +
+ + Try{' '} + + VaporBoy + {' '} + for a full featured, GB / GBC Emulator Progressive Web App. + +
+ + {/* Github Repo */} + + + {/*Lib Version*/} +
WasmBoy Lib Version: {WasmBoy.getVersion()}
+ + {/* Info */} +

Introduction

+
+ Hello! Welcome to the WasmBoy Mobile Demo! WasmBoy is a Game Boy / Game Boy Color Emulation Library, written for Web Assembly + using{' '} + + AssemblyScript + + . 🚀 This application is written in{' '} + + Preact + {' '} + ⚛ī¸. This website also happens to be the Wasmboy Debugger. However, the debugger is only available on desktop, due to UX issues. +
+
+ Since this is a demo, this is only meant for "checking it out", and this is lacking some features that would, normally be + present that the lib does support (such as save states), for a full-featured GB / GBC emulator built with WasmBoy, try{' '} + + VaporBoy + + . Also, since this is meant for mobile, some of the WasmBoy configuration options are set to improve performance, but at the + expense of less accuracy. +
+ + {/* Getting Started */} +

Getting Started

+
+ To try a ROM / Game, click the 💾 button, to open the ROM loader. To Play/Pause emulation, click the ⏯ī¸ button. For more + information on WasmBoy, click the ℹī¸ button. To reload this demo, click the â™ģī¸ button. +
+
+ ); + } + + return ( +
+
+
+ +
+
{wasmboyInfo}
+ +
+ ); + } +} diff --git a/demo/debugger/components/mobile/touchpad/touchpad.css b/demo/debugger/components/mobile/touchpad/touchpad.css new file mode 100644 index 00000000..6288c90a --- /dev/null +++ b/demo/debugger/components/mobile/touchpad/touchpad.css @@ -0,0 +1,205 @@ +.touchpad-container { + position: absolute; + top: 0; + left: 0; + + height: 100%; + width: 100%; +} + +.touchpad-container * { + user-select: none; +} + +.debugger-input { + position: absolute; + left: 0; + z-index: 2; + + width: 100%; + + display: flex; + justify-content: space-evenly; + align-items: center; +} + +html.portrait .debugger-input { + bottom: 0; +} + +html.landscape .debugger-input { + top: 0; +} + +.debugger-input { + background-color: rgba(0, 0, 0, 0.5); +} + +.debugger-input button { + padding: 12px; + font-size: 2em; +} + +.mobile-rom-source { + display: flex; + justify-content: space-evenly; + align-items: center; + flex-direction: column; +} + +.mobile-rom-source button { + background-color: transparent; + font-size: 25px; + margin: 20px; + border: solid 2px black; +} + +.touchpad-container svg { + width: 100%; + height: 100%; + + padding: 3px; + overflow: visible; + cursor: pointer; +} + +.touchpad-container svg path, +.touchpad-container svg rect { + stroke: #000; + stroke-width: 2px; +} + +.touchpad-container svg text, +.touchpad-container svg polygon { + stroke: #000; + stroke-width: 1px; +} + +.touchpad-container svg text { + font-size: 80px; + font-weight: 700; + text-transform: capitalize; +} + +.gameboy-input { + position: relative; + top: 0; + left: 0; + + height: 100%; + width: 100%; +} + +.gameboy-input__select svg text, +.gameboy-input__start svg text { + font-size: 23px; +} + +/* PORTRAIT */ + +html.portrait .gameboy-input__dpad { + width: 37vw; + height: 37vw; + max-width: 170px; + max-height: 170px; + + position: absolute; + z-index: 1; + bottom: 27.5%; + left: 5%; +} + +html.portrait .gameboy-input__b { + width: 20vw; + height: 20vw; + max-width: 95px; + max-height: 95px; + + position: absolute; + z-index: 1; + bottom: 27.5%; + right: 21%; +} + +html.portrait .gameboy-input__a { + width: 20vw; + height: 20vw; + max-width: 95px; + max-height: 95px; + + position: absolute; + z-index: 1; + bottom: 37.5%; + right: 3%; +} + +html.portrait .gameboy-input__select { + width: 19.5vw; + height: 19.5vw; + max-width: 100px; + max-height: 100px; + + position: absolute; + z-index: 1; + left: 25.5%; + bottom: 13%; +} + +html.portrait .gameboy-input__start { + width: 19.5vw; + height: 19.5vw; + max-width: 100px; + max-height: 100px; + + position: absolute; + z-index: 1; + left: 51.5%; + bottom: 13%; +} + +/* LANDSCAPE */ + +html.landscape .gameboy-input__dpad { + width: 20vw; + height: 20vw; + position: absolute; + z-index: 1; + top: calc(50% - 13vw); + left: 5%; +} + +html.landscape .gameboy-input__b { + width: 12vw; + height: 12vw; + position: absolute; + z-index: 1; + top: calc(50% - 5vw); + right: 15%; +} + +html.landscape .gameboy-input__a { + width: 12vw; + height: 12vw; + position: absolute; + z-index: 1; + top: calc(50% - 13vw); + right: 1%; +} + +html.landscape .gameboy-input__select { + width: 22.5vh; + height: 22.5vh; + position: absolute; + z-index: 1; + left: 30.5%; + bottom: 7%; +} + +html.landscape .gameboy-input__start { + width: 22.5vh; + height: 22.5vh; + position: absolute; + z-index: 1; + left: 54.5%; + bottom: 7%; +} diff --git a/demo/debugger/components/mobile/touchpad/touchpad.js b/demo/debugger/components/mobile/touchpad/touchpad.js new file mode 100644 index 00000000..1f080cf8 --- /dev/null +++ b/demo/debugger/components/mobile/touchpad/touchpad.js @@ -0,0 +1,201 @@ +// Base Component to handle showing mobile UIs + +import { h, Component } from 'preact'; +import { WasmBoy } from '../../../wasmboy'; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import loadROM from '../../../loadROM'; +import DebuggerAnalytics from '../../../analytics'; +import { getOpenSourceROMElements } from '../../../../openSourceROMsPreact'; +import GoogleDrivePicker from '../../../../googleDrivePicker'; + +import AboutComponent from '../../other/about/about'; + +import { + vaporboyExpandedDpad, + vaporboyExpandedAButton, + vaporboyExpandedBButton, + vaporboyExpandedStartButton, + vaporboyExpandedSelectButton +} from './vaporboyButtons'; + +import './touchpad.css'; + +export default class Touchpad extends Component { + constructor() { + super(); + } + + componentDidMount() { + // Add our touch inputs + const dpadElement = document.querySelector('.gameboy-input__dpad'); + const startElement = document.querySelector('.gameboy-input__start'); + const selectElement = document.querySelector('.gameboy-input__select'); + const aElement = document.querySelector('.gameboy-input__a'); + const bElement = document.querySelector('.gameboy-input__b'); + + WasmBoy.addTouchInput('UP', dpadElement, 'DPAD', 'UP'); + WasmBoy.addTouchInput('RIGHT', dpadElement, 'DPAD', 'RIGHT'); + WasmBoy.addTouchInput('DOWN', dpadElement, 'DPAD', 'DOWN'); + WasmBoy.addTouchInput('LEFT', dpadElement, 'DPAD', 'LEFT'); + WasmBoy.addTouchInput('A', aElement, 'BUTTON'); + WasmBoy.addTouchInput('B', bElement, 'BUTTON'); + WasmBoy.addTouchInput('START', startElement, 'BUTTON'); + WasmBoy.addTouchInput('SELECT', selectElement, 'BUTTON'); + } + + openROM() { + // Using a stateless functional component + Pubx.get(PUBX_KEYS.MODAL).showModal(() => { + return ( +
+ + + +
+ ); + }); + } + + openLocalFile() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + + // Close the modal + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + + // Use the hidden input from the desktop open command + // Will handle loading the rom for us as well! + document.querySelector('.hidden-rom-input').click(); + } + + openOpenSourceROMViewer() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + + // Close the modal + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + + // Using a stateless functional component + Pubx.get(PUBX_KEYS.MODAL).showModal(() => { + return ( +
+ {getOpenSourceROMElements(ROMObject => { + loadROM(ROMObject.url, ROMObject.title); + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + })} +
+ ); + }); + } + + openGoogleDriveROM() { + // Allow autoplaying audio to work + WasmBoy.resumeAudioContext(); + + // Close the modal + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + + // Fire off some analytics + DebuggerAnalytics.googleDriveLoad(); + + // Get the ROM from google drive + const loadGDriveROMTask = async () => { + const pickerResponse = await GoogleDrivePicker.getFile(['application/zip', 'application/octet-stream']); + + if (pickerResponse.cancelled) { + return; + } + + const { response, oAuthHeaders } = pickerResponse; + + if (response.title.endsWith('.zip') || response.title.endsWith('.gb') || response.title.endsWith('.gbc')) { + await WasmBoy.pause(); + await WasmBoy.loadROM(response.downloadUrl, { + headers: oAuthHeaders, + fileName: response.title + }); + await WasmBoy.play(); + Pubx.publish(PUBX_KEYS.WASMBOY, { + filename: response.title + }); + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Game Loaded! 🎉'); + } else { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Invalid file type. 😞'); + } + }; + const loadGDriveROMPromise = loadGDriveROMTask().catch(error => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification(error); + }); + Pubx.get(PUBX_KEYS.LOADING).addControlPromise(loadGDriveROMPromise); + } + + togglePlayPause() { + if (!WasmBoy.isLoadedAndStarted()) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please load a ROM first. 💾'); + return; + } + + if (WasmBoy.isPlaying()) { + WasmBoy.pause(); + } else { + WasmBoy.play(); + } + } + + showAbout() { + // Using a stateless functional component + Pubx.get(PUBX_KEYS.MODAL).showModal(() => { + return ; + }); + } + + reload() { + // Fire off some analytics + DebuggerAnalytics.reload(); + + // Reload + window.location.reload(true); + } + + render() { + return ( +
+
+
{vaporboyExpandedDpad}
+ +
{vaporboyExpandedBButton}
+
{vaporboyExpandedAButton}
+ +
{vaporboyExpandedSelectButton}
+
{vaporboyExpandedStartButton}
+
+ +
+ + + + +
+
+ ); + } +} diff --git a/demo/debugger/components/mobile/touchpad/vaporboyButtons.js b/demo/debugger/components/mobile/touchpad/vaporboyButtons.js new file mode 100644 index 00000000..de824022 --- /dev/null +++ b/demo/debugger/components/mobile/touchpad/vaporboyButtons.js @@ -0,0 +1,139 @@ +// Buttons taken from mobile exapanded mode from +// Vaporboy +// https://vaporboy.net/ +// https://github.com/torch2424/vaporBoy + +import { h } from 'preact'; + +export const vaporboyExpandedDpad = ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +export const vaporboyExpandedBButton = ( + + + + + + + + + + + + + + + + + + + B + + +); + +export const vaporboyExpandedAButton = ( + + + + + + + + + + + + + + + + + + + A + + +); + +export const vaporboyExpandedStartButton = ( + + + + + + + + + + + + + + + + + + + start + + +); + +export const vaporboyExpandedSelectButton = ( + + + + + + + + + + + + + + + + + + + select + + +); diff --git a/demo/debugger/components/other/about/about.css b/demo/debugger/components/other/about/about.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/components/other/about/about.js b/demo/debugger/components/other/about/about.js new file mode 100644 index 00000000..51fe8175 --- /dev/null +++ b/demo/debugger/components/other/about/about.js @@ -0,0 +1,71 @@ +import { h, Component } from 'preact'; + +import './about.css'; + +export default class AboutComponent extends Component { + render() { + return ( +
+

About

+
+ WasmBoy is a Game Boy / Game Boy Color Emulation Library, written for Web Assembly using{' '} + + AssemblyScript + + . 🚀 This application is a debugger written in{' '} + + Preact + {' '} + ⚛ī¸.{' '} + + PhosphorJS + {' '} + is used for the Desktop UI.{' '} + + Pubx + {' '} + is used for for state management. This debugger is meant for developing / debugging the emulation lib, as well as game boy + homebrew development. WasmBoy is written by{' '} + + Aaron Turner (torch2424) + + , and Licensed under{' '} + + Apache 2.0 + + . +
+
+ For standard game boy emulation playing for fun, speed running, etc... Check out{' '} + + VaporBoy + + , a full featured GB / GBC Emulator Progressive Web App. +
+

WasmBoy Links

+ +
+ ); + } +} diff --git a/demo/debugger/components/other/help/help.css b/demo/debugger/components/other/help/help.css new file mode 100644 index 00000000..55c56f1c --- /dev/null +++ b/demo/debugger/components/other/help/help.css @@ -0,0 +1,19 @@ +.help__media-container { + width: 100%; + text-align: center; + margin-left: auto; + margin-right: auto; + + padding: 2px; + border: 1px solid black; +} + +.help__media-container img { + width: 100%; + max-width: 350px; +} + +.help__media-container video { + width: 100%; + max-width: 350px; +} diff --git a/demo/debugger/components/other/help/help.js b/demo/debugger/components/other/help/help.js new file mode 100644 index 00000000..e1d3129e --- /dev/null +++ b/demo/debugger/components/other/help/help.js @@ -0,0 +1,32 @@ +import { h, Component } from 'preact'; + +import './help.css'; + +export default class HelpComponent extends Component { + render() { + return ( +
+

Help

+

How do I use this Debugger

+
+ Please see the video below on how to open a ROM, open widgets, and move around tabs. Widgets can also be resiezed, by hovering + over their edges, and stretching to the desired size. All open widgets, and layout configurations are saved in localStorage, and + are preserved between sessions. +
+ +
+
+

How to report bugs / suggestions

+
+ Please feel free to file any bugs, suggestions, issues, etc.. At the{' '} + + WasmBoy Github repo + + . +
+
+ ); + } +} diff --git a/demo/debugger/components/overlay/modal/modal.css b/demo/debugger/components/overlay/modal/modal.css new file mode 100644 index 00000000..d2d7402b --- /dev/null +++ b/demo/debugger/components/overlay/modal/modal.css @@ -0,0 +1,81 @@ +.modal { + display: none; + justify-content: center; + align-items: center; + + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; + overflow: hidden; +} + +.modal--visible { + display: flex; + pointer-events: all; +} + +.modal__mask { + background-color: rgba(0, 0, 0, 0.45); + + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; + overflow: hidden; + + z-index: 0; +} + +.modal__container { + display: block; + width: 80%; + height: 80%; + min-width: 300px; + min-height: 300px; + max-width: 800px; + max-height: 800px; + + background-color: #fafafa; + border: 2px solid #020202; + border-radius: 5px; + z-index: 1; +} + +.modal__container__title-bar { + display: flex; + justify-content: center; + align-items: center; + border-bottom: 2px solid #020202; + height: 20px; + width: 100%; +} + +.modal__container__title-bar__close { + margin-left: auto; + margin-right: 10px; + cursor: pointer; +} + +.modal__container__component { + z-index: 1; + overflow: auto; + width: 100%; + + /* Height is 100% - title bar height */ + height: calc(100% - 20px); + min-height: 100px; + padding: 10px; +} + +@media only screen and (max-width: 675px) { + .modal__container__component .open-source-rom__button { + justify-content: space-around; + } +} diff --git a/demo/debugger/components/overlay/modal/modal.js b/demo/debugger/components/overlay/modal/modal.js new file mode 100644 index 00000000..abc96d0b --- /dev/null +++ b/demo/debugger/components/overlay/modal/modal.js @@ -0,0 +1,44 @@ +// Component to overlay components in full page view + +import { h, Component } from 'preact'; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; +import './modal.css'; +import '../../../../openSourceROMs.css'; + +export default class Modal extends Component { + constructor() { + super(); + + this.state.visible = undefined; + + Pubx.subscribe(PUBX_KEYS.MODAL, newState => this.setState(newState)); + } + + close() { + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + } + + render() { + let ModalContent = () =>
; + if (this.state.component) { + ModalContent = this.state.component; + } + + return ( +
+ + ); + } +} diff --git a/demo/debugger/components/overlay/notification/notification.css b/demo/debugger/components/overlay/notification/notification.css new file mode 100644 index 00000000..46261591 --- /dev/null +++ b/demo/debugger/components/overlay/notification/notification.css @@ -0,0 +1,39 @@ +.notification { + display: none; + pointer-events: all; + + position: absolute; + bottom: 0; + right: 0; + + width: 50vw; + min-width: 200px; + max-width: 500px; + + min-height: 50px; + + background-color: rgba(0, 0, 0, 0.85); + color: #fafafa; + + margin: 10px; + padding: 5px; + + border-radius: 5px; + box-shadow: 1px 1px 10px 1px rgba(0, 0, 0, 0.75); +} + +.notification--show { + display: block; +} + +.notification__close { + text-align: right; + margin-right: 5px; +} + +.notification__close > button { + color: #fafafa; + + padding-left: 10px; + padding-right: 10px; +} diff --git a/demo/debugger/components/overlay/notification/notification.js b/demo/debugger/components/overlay/notification/notification.js new file mode 100644 index 00000000..9c0e5e39 --- /dev/null +++ b/demo/debugger/components/overlay/notification/notification.js @@ -0,0 +1,50 @@ +// Component to show text notifications + +import { h, Component } from 'preact'; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; +import './notification.css'; + +export default class Notification extends Component { + constructor() { + super(); + + this.state.visible = undefined; + this.state.hideTimeout = false; + + Pubx.subscribe(PUBX_KEYS.NOTIFICATION, newState => { + this.close(); + + this.setState({ + ...newState, + visible: 'notification--show', + hideTimeout: setTimeout(() => { + this.close(); + }, newState.timeout) + }); + }); + } + + close() { + if (this.state.hideTimeout) { + clearTimeout(this.state.hideTimeout); + } + + this.setState({ + visible: undefined + }); + } + + render() { + return ( +
+
+ +
+
{this.state.text}
+
+ ); + } +} diff --git a/demo/debugger/components/overlay/overlay.css b/demo/debugger/components/overlay/overlay.css new file mode 100644 index 00000000..50a5b916 --- /dev/null +++ b/demo/debugger/components/overlay/overlay.css @@ -0,0 +1,12 @@ +.overlay { + display: flex; + flex-direction: column; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; + overflow: hidden; +} diff --git a/demo/debugger/components/overlay/overlay.js b/demo/debugger/components/overlay/overlay.js new file mode 100644 index 00000000..d5ad44ee --- /dev/null +++ b/demo/debugger/components/overlay/overlay.js @@ -0,0 +1,27 @@ +// Base Component to handle all overlaying elements +// Such as Modals, and Notifications + +import { h, Component } from 'preact'; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../pubx.config'; +import './overlay.css'; + +import Notification from './notification/notification'; +import Modal from './modal/modal'; + +export default class Overlay extends Component { + constructor() { + super(); + + Pubx.subscribe(PUBX_KEYS.OVERLAY, newState => this.setState(newState)); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/demo/debugger/components/playback/wasmboyControls/wasmboyControls.css b/demo/debugger/components/playback/wasmboyControls/wasmboyControls.css new file mode 100644 index 00000000..b019ad63 --- /dev/null +++ b/demo/debugger/components/playback/wasmboyControls/wasmboyControls.css @@ -0,0 +1,58 @@ +.wasmboy-controls { + display: block; + + width: 100%; + height: 100%; +} + +.wasmboy-controls .donut { + display: none; +} + +.wasmboy-controls--control-loading .donut { + display: block; +} + +.wasmboy-controls--control-loading .wasmboy-controls__group { + display: none; +} + +.wasmboy-controls__group { + width: 100%; + + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; +} + +.wasmboy-controls__group * { + margin: 5px; +} + +.load-state-container { + margin-left: auto; + margin-right: auto; + margin-top: 25px; + + display: flex; + justify-content: space-around; + align-items: flex-start; + flex-wrap: wrap; + flex-direction: row; +} + +.load-state-container__save-state { + margin-left: 5px; + margin-right: 5px; + padding: 10px; + + word-wrap: break-word; + + transition: background-color 0.25s; +} + +.load-state-container__save-state:hover { + background-color: rgba(0, 0, 0, 0.25); + cursor: pointer; +} diff --git a/demo/debugger/components/playback/wasmboyControls/wasmboyControls.js b/demo/debugger/components/playback/wasmboyControls/wasmboyControls.js new file mode 100644 index 00000000..795bd892 --- /dev/null +++ b/demo/debugger/components/playback/wasmboyControls/wasmboyControls.js @@ -0,0 +1,172 @@ +// Compoonent that contains the canvas and the actual output +// of WasmBoy + +import { h, Component } from 'preact'; +s; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import DebuggerAnalytics from '../../../analytics'; +import { WasmBoy } from '../../../wasmboy'; + +import './wasmboyControls.css'; + +let unsubLoading = false; + +export default class WasmBoyControls extends Component { + constructor() { + super(); + + // Exerytime WasmBoy gets updated, simply re-render + Pubx.subscribe(PUBX_KEYS.WASMBOY, newState => this.setState(newState)); + } + + componentDidMount() { + Pubx.get(PUBX_KEYS.WASMBOY).update(); + + unsubLoading = Pubx.subscribe(PUBX_KEYS.LOADING, newState => this.checkControlLoading(newState)); + this.checkControlLoading(Pubx.get(PUBX_KEYS.LOADING)); + } + + componentWillUnmount() { + if (unsubLoading) { + unsubLoading(); + } + } + + checkControlLoading(newState) { + if (newState.controlLoading) { + this.base.classList.add('wasmboy-controls--control-loading'); + } else { + this.base.classList.remove('wasmboy-controls--control-loading'); + } + } + + saveState() { + WasmBoy.saveState() + .then(saveState => { + console.log('Resolved Save State from WasmBoy.saveState():', saveState); + WasmBoy.play() + .then(() => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('State Saved! 💾'); + DebuggerAnalytics.saveState(); + }) + .catch(err => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Error Saving State... 😞'); + console.error(err); + }); + }) + .catch(err => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Error Saving State... 😞'); + console.error(err); + }); + } + + showLoadStateModal() { + // Using a stateless functional component + Pubx.get(PUBX_KEYS.MODAL).showModal(() => { + return
; + }); + + // Get our save states + WasmBoy.getSaveStates() + .then(saveStates => { + if (!saveStates || saveStates.length === 0) { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('No Save States For the Current ROM 🤔'); + return; + } + + const saveStateElements = []; + + saveStates.forEach(saveState => { + let saveStateDateString = new Date(saveState.date); + saveStateDateString = saveStateDateString.toLocaleString(); + saveStateElements.unshift( +
{ + this.loadState(saveState); + Pubx.get(PUBX_KEYS.MODAL).closeModal(); + }} + > + +

Date:

+ {saveStateDateString} +

Auto:

+ {saveState.isAuto ? 'true' : 'false'} +
+ ); + }); + + // Using a stateless functional component + Pubx.get(PUBX_KEYS.MODAL).showModal(() => { + return
{saveStateElements}
; + }); + }) + .catch(err => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Error Getting Saving States... 😞'); + console.error(err); + }); + } + + loadState(saveState) { + const loadStateTask = async () => { + await WasmBoy.loadState(saveState); + + // Check if the Playback Control or CPU Control is open , if not, let's autoplay + if (!Pubx.get(PUBX_KEYS.WIDGET).isControlWidgetsOpen()) { + await WasmBoy.play(); + } + + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('State Loaded! 😀'); + DebuggerAnalytics.loadState(); + }; + loadStateTask().catch(() => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Error Loading State... 😞'); + }); + } + + render() { + return ( +
+

Playback Controls

+
+ ROMs will not autoplay while this widget is open. +
+ +
+ + {/* Play/Pause Toggle */} +
+ {this.state.playing ? ( + + ) : ( + + )} +
+ + {/* Save / Load States */} +
+ + +
+
+ ); + } +} diff --git a/demo/debugger/components/playback/wasmboyInfo/wasmboyInfo.css b/demo/debugger/components/playback/wasmboyInfo/wasmboyInfo.css new file mode 100644 index 00000000..df34867c --- /dev/null +++ b/demo/debugger/components/playback/wasmboyInfo/wasmboyInfo.css @@ -0,0 +1,10 @@ +.wasmboy-info { + display: block; + + width: 100%; + height: 100%; +} + +.wasmboy-info__action-buttons button { + margin: 5px; +} diff --git a/demo/debugger/components/playback/wasmboyInfo/wasmboyInfo.js b/demo/debugger/components/playback/wasmboyInfo/wasmboyInfo.js new file mode 100644 index 00000000..a3a0513e --- /dev/null +++ b/demo/debugger/components/playback/wasmboyInfo/wasmboyInfo.js @@ -0,0 +1,122 @@ +// Component that represents the information +// About what is currently playing, and it's performance + +import { h, Component } from 'preact'; + +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import { WasmBoy } from '../../../wasmboy'; + +import './wasmboyInfo.css'; + +export default class WasmBoyInfo extends Component { + constructor() { + super(); + + // Exerytime WasmBoy gets updated, simply re-render + Pubx.subscribe(PUBX_KEYS.WASMBOY, newState => this.setState(newState)); + + this.state = { + cartridge: {} + }; + } + + componentDidMount() { + Pubx.get(PUBX_KEYS.WASMBOY).update(); + + const callback = () => { + const fpsElement = document.getElementById('wasmboy-info__fps'); + if (fpsElement) { + fpsElement.textContent = `WasmBoy Current FPS: ${WasmBoy.getFPS()}`; + } + }; + setInterval(callback, 1000); + } + + notifyWasmBoyMustBeReady() { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Please load a ROM. 💾'); + } + + logWasmBoyObject() { + console.log('WasmBoy', WasmBoy); + } + + logWasmBoyMemory() { + if (!WasmBoy.isReady()) { + this.notifyWasmBoyMustBeReady(); + return; + } + + WasmBoy._getWasmMemorySection().then(wasmByteMemory => { + console.log(`[WasmBoy Debugger] Entire WasmBoy Memory:`, wasmByteMemory); + }); + } + + logGameBoyMemory() { + if (!WasmBoy.isReady()) { + this.notifyWasmBoyMustBeReady(); + return; + } + + const asyncTask = async () => { + const location = await WasmBoy._getWasmConstant('GAMEBOY_INTERNAL_MEMORY_LOCATION'); + const size = await WasmBoy._getWasmConstant('GAMEBOY_INTERNAL_MEMORY_SIZE'); + const memory = await WasmBoy._getWasmMemorySection(location, location + size + 1); + console.log(`[WasmBoy Debugger] Gameboy Memory:`, memory); + }; + asyncTask(); + } + + saveAudioBuffer() { + if (!WasmBoy.isReady()) { + this.notifyWasmBoyMustBeReady(); + return; + } + + WasmBoy._saveCurrentAudioBufferToWav(); + } + + render() { + return ( +
+

WasmBoy

+
WasmBoy Version: {this.state.version}
+
WasmBoy Core Type: {this.state.core}
+
+ +

WasmBoy Debug Actions

+
+ + + + +
+ +

ROM

+
Loaded ROM Filename: {this.state.filename}
+

+ + Cartridge Header + +

+
Title: {this.state.cartridge.titleAsString}
+
Manufacturer Code: {JSON.stringify(this.state.cartridge.manufacturerCode)}
+
CGB Flag: {JSON.stringify(this.state.cartridge.CGBFlag)}
+
New Licensee Code: {JSON.stringify(this.state.cartridge.newLicenseeCode)}
+
Cartridge Type: {JSON.stringify(this.state.cartridge.cartridgeType)}
+
ROM Size: {JSON.stringify(this.state.cartridge.ROMSize)}
+
RAM Size: {JSON.stringify(this.state.cartridge.RAMSize)}
+
Destination Code: {JSON.stringify(this.state.cartridge.destinationCode)}
+
Old Licensee Code: {JSON.stringify(this.state.cartridge.oldLicenseeCode)}
+
Mask ROM Version number: {JSON.stringify(this.state.cartridge.maskROMVersionNumber)}
+
Header Checksum: {JSON.stringify(this.state.cartridge.headerChecksum)}
+
Global Checksum: {JSON.stringify(this.state.cartridge.globalChecksum)}
+ + +
+ ); + } +} diff --git a/demo/debugger/wasmboyOptions/wasmboyOptions.css b/demo/debugger/components/playback/wasmboyOptions/wasmboyOptions.css similarity index 51% rename from demo/debugger/wasmboyOptions/wasmboyOptions.css rename to demo/debugger/components/playback/wasmboyOptions/wasmboyOptions.css index 296cbc67..851f462c 100644 --- a/demo/debugger/wasmboyOptions/wasmboyOptions.css +++ b/demo/debugger/components/playback/wasmboyOptions/wasmboyOptions.css @@ -1,18 +1,17 @@ -.wasmboy__options { +.wasmboy-options { margin-left: auto; margin-right: auto; - padding: 10px; } -.wasmboy__options__info { +.wasmboy-options__info { margin-top: 10px; margin-bottom: 10px; } -.wasmboy__options__inputs div { +.wasmboy-options__inputs div { margin: 5px; } -.wasmboy__options__apply { +.wasmboy-options__apply { margin-top: 10px; } diff --git a/demo/debugger/wasmboyOptions/wasmboyOptions.js b/demo/debugger/components/playback/wasmboyOptions/wasmboyOptions.js similarity index 82% rename from demo/debugger/wasmboyOptions/wasmboyOptions.js rename to demo/debugger/components/playback/wasmboyOptions/wasmboyOptions.js index 751edf1d..af17e4a2 100644 --- a/demo/debugger/wasmboyOptions/wasmboyOptions.js +++ b/demo/debugger/components/playback/wasmboyOptions/wasmboyOptions.js @@ -1,8 +1,16 @@ -import { Component } from 'preact'; -import { WasmBoy } from '../../../dist/wasmboy.wasm.esm'; +// Allow configuring the wasmboy options + +import { h, Component } from 'preact'; + +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import DebuggerAnalytics from '../../../analytics'; +import { WasmBoy, WasmBoyDefaultDesktopOptions } from '../../../wasmboy'; + import './wasmboyOptions.css'; -export class WasmBoyOptions extends Component { +export default class WasmBoyOptions extends Component { constructor(props) { super(props); @@ -13,7 +21,7 @@ export class WasmBoyOptions extends Component { // Add all of our default options from the props to our component state const newState = Object.assign({}, this.state); const wasmboyConfig = WasmBoy.getConfig(); - Object.keys(this.props.availableOptions).forEach(optionKey => { + Object.keys(WasmBoyDefaultDesktopOptions).forEach(optionKey => { newState[optionKey] = wasmboyConfig[optionKey]; }); this.setState(newState); @@ -29,15 +37,13 @@ export class WasmBoyOptions extends Component { applyOptions() { WasmBoy.reset(this.state) .then(() => { - this.props.showNotification('Applied Options! 🛠ī¸'); + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Applied Options! 🛠ī¸'); // Fire off Analytics - if (window !== undefined && window.gtag) { - gtag('event', 'applied_options'); - } + DebuggerAnalytics.appliedOptions(); }) .catch(error => { - this.props.showNotification('Options Error! 😞'); + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Options Error! 😞'); }); } diff --git a/demo/debugger/components/playback/wasmboyPlayer/wasmboyPlayer.css b/demo/debugger/components/playback/wasmboyPlayer/wasmboyPlayer.css new file mode 100644 index 00000000..1a5ad109 --- /dev/null +++ b/demo/debugger/components/playback/wasmboyPlayer/wasmboyPlayer.css @@ -0,0 +1,23 @@ +.wasmboy-player { + display: flex; + justify-content: center; + align-items: center; + + width: 100%; + height: 100%; +} + +.wasmboy-player .donut { + display: none; +} + +.wasmboy-player--control-loading { +} + +.wasmboy-player--control-loading .donut { + display: flex; +} + +.wasmboy-player--control-loading canvas { + display: none; +} diff --git a/demo/debugger/components/playback/wasmboyPlayer/wasmboyPlayer.js b/demo/debugger/components/playback/wasmboyPlayer/wasmboyPlayer.js new file mode 100644 index 00000000..c8dd5f09 --- /dev/null +++ b/demo/debugger/components/playback/wasmboyPlayer/wasmboyPlayer.js @@ -0,0 +1,46 @@ +// Compoonent that contains the canvas and the actual output +// of WasmBoy + +import { h, Component } from 'preact'; + +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from '../../../pubx.config'; + +import { WasmBoy, WasmBoyUpdateCanvas } from '../../../wasmboy'; + +import './wasmboyPlayer.css'; + +const getCanvasElement = () => { + return document.querySelector('.wasmboy-player canvas'); +}; + +export default class WasmBoyPlayer extends Component { + constructor() { + super(); + } + + componentDidMount() { + // Set our canvas + WasmBoyUpdateCanvas(false, Pubx.get(PUBX_KEYS.WASMBOY).update); + + Pubx.subscribe(PUBX_KEYS.LOADING, newState => this.checkControlLoading(newState)); + this.checkControlLoading(Pubx.get(PUBX_KEYS.LOADING)); + } + + checkControlLoading(newState) { + if (newState.controlLoading) { + this.base.classList.add('wasmboy-player--control-loading'); + } else { + this.base.classList.remove('wasmboy-player--control-loading'); + } + } + + render() { + return ( +
+
+ +
+ ); + } +} diff --git a/demo/debugger/components/timer/timerState/timerState.css b/demo/debugger/components/timer/timerState/timerState.css new file mode 100644 index 00000000..e69de29b diff --git a/demo/debugger/components/timer/timerState/timerState.js b/demo/debugger/components/timer/timerState/timerState.js new file mode 100644 index 00000000..a232c201 --- /dev/null +++ b/demo/debugger/components/timer/timerState/timerState.js @@ -0,0 +1,39 @@ +import { WasmBoy } from '../../../wasmboy'; + +import ValueTable from '../../valueTable.js'; +import './timerState.css'; + +export default class TimerState extends ValueTable { + constructor() { + super(); + + this.state.title = 'Timer'; + } + + intervalUpdate() { + if (!WasmBoy.isReady()) { + return; + } + + const updateTask = async () => { + const valueTable = {}; + + // Get all of the gameboy 0xffXX memory + const debugMemoryStart = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xff00]); + const debugMemoryEnd = await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [0xffff]); + const debugMemory = await WasmBoy._getWasmMemorySection(debugMemoryStart, debugMemoryEnd + 1); + + // Update Timers valueTable + valueTable['TIMA - 0xFF05'] = await WasmBoy._runWasmExport('getTIMA'); + valueTable['TMA - 0xFF06'] = await WasmBoy._runWasmExport('getTMA'); + valueTable['TIMC/TAC - 0xFF07'] = await WasmBoy._runWasmExport('getTAC'); + valueTable['DIV/Divider Register - 0xFF04'] = await WasmBoy._runWasmExport('getDIV'); + + this.setState({ + ...this.state, + object: valueTable + }); + }; + updateTask(); + } +} diff --git a/demo/debugger/wasmboyDebugger/numberBaseTable/numberBaseTable.css b/demo/debugger/components/valueTable.css similarity index 50% rename from demo/debugger/wasmboyDebugger/numberBaseTable/numberBaseTable.css rename to demo/debugger/components/valueTable.css index f9392334..e86e027c 100644 --- a/demo/debugger/wasmboyDebugger/numberBaseTable/numberBaseTable.css +++ b/demo/debugger/components/valueTable.css @@ -1,32 +1,30 @@ -.number-base-table-container { +.value-table-container { width: 100%; - min-width: 1024px; - margin-top: 10px; - overflow-x: auto; + margin: 10px; } -.number-base-table { +.value-table { border-collapse: collapse; width: 100%; } -.number-base-table th { +.value-table th { height: 50px; font-weight: bold; background-color: #9bbc0f; } -.number-base-table td { +.value-table td { width: 75px; } -.number-base-table tr:hover { +.value-table tr:hover { background-color: #f5f5f5; } -.number-base-table th, -.number-base-table td, -.number-base-table tr { +.value-table th, +.value-table td, +.value-table tr { text-align: left; border: 1px solid black; padding: 5px; diff --git a/demo/debugger/components/valueTable.js b/demo/debugger/components/valueTable.js new file mode 100644 index 00000000..55707012 --- /dev/null +++ b/demo/debugger/components/valueTable.js @@ -0,0 +1,106 @@ +import { h, Component } from 'preact'; +import './valueTable.css'; + +// Component that takes in a JSON object, where the Keys are the row names, +// And the columns will represent each base value of the number in the value of the key +export default class ValueTable extends Component { + constructor() { + super(); + this.state = { + object: {} + }; + + this.updateInterval = false; + } + + componentDidMount() { + this.updateInterval = setInterval(() => this.intervalUpdate(), 100); + } + + componentWillUnmount() { + clearInterval(this.updateInterval); + } + + intervalUpdate() { + // Should Override this. + } + + // Modifed from: https://ourcodeworld.com/articles/read/380/how-to-convert-a-binary-string-into-a-readable-string-and-vice-versa-with-javascript + numberToBinaryString(number) { + // Simply Convert each place in hex to binary + const hexString = number.toString(16); + + let binaryString = ''; + for (let i = 0; i < hexString.length; i++) { + let valueAtIncrementer = parseInt(hexString.charAt(i), 16).toString(2); + let paddedValueAtIncrementer = valueAtIncrementer; + // Pad to 4 bits + while (paddedValueAtIncrementer.length < 4) { + paddedValueAtIncrementer = '0' + paddedValueAtIncrementer; + } + + binaryString += paddedValueAtIncrementer; + + if (i !== hexString.length - 1) { + binaryString += ' '; + } + } + + // Padd out to 8 bit increments + if (!(binaryString.length & 1)) { + binaryString = '0000 ' + binaryString; + } + + return binaryString; + } + + getValueWithBase(value, valueBase) { + if (valueBase === 16) { + return value.toString(16); + } else if (valueBase === 2) { + return this.numberToBinaryString(value); + } else { + return value.toString(10); + } + } + + render() { + if (!this.state.object || Object.keys(this.state.object).length < 1) { + return ( +
+

{this.state.title}

+
Please open a ROM to view the state values.
+
+ ); + } + + const keyRows = []; + Object.keys(this.state.object).forEach(objectKey => { + keyRows.push( + + {objectKey} + 0x{this.getValueWithBase(this.state.object[objectKey], 16)} + {this.getValueWithBase(this.state.object[objectKey], 2)} + {this.getValueWithBase(this.state.object[objectKey], 10)} + + ); + }); + + return ( +
+

{this.state.title}

+ {this.state.headerElement} + + + + + + + + + {keyRows} +
ValueHexadecimal:Binary:Decimal:
+
+ ); + } +} diff --git a/demo/debugger/index.css b/demo/debugger/index.css new file mode 100644 index 00000000..99c1085e --- /dev/null +++ b/demo/debugger/index.css @@ -0,0 +1,7 @@ +/* Simply imports frameworks and application styles */ + +@import 'normalize.css'; +@import './styles/phosphor.css'; +@import 'chota/dist/chota.css'; +@import './styles/app.css'; +@import './styles/shared.css'; diff --git a/demo/debugger/index.html b/demo/debugger/index.html new file mode 100644 index 00000000..efcc0b2d --- /dev/null +++ b/demo/debugger/index.html @@ -0,0 +1,25 @@ + + + + + WasmBoy Debugger + + + + + + + + + + + + + +
+
+
+ + + + diff --git a/demo/debugger/index.js b/demo/debugger/index.js index fec340b5..a106fea8 100644 --- a/demo/debugger/index.js +++ b/demo/debugger/index.js @@ -1,320 +1,70 @@ -import './style'; -import 'bulma/css/bulma.css'; -import { Component } from 'preact'; -// The following line can be changed to './dist/wasmboy.esm.js', to test the built lib -import { WasmBoy } from '../../dist/wasmboy.wasm.esm'; -import { WasmBoyDebugger } from './wasmboyDebugger/wasmboyDebugger'; -import { WasmBoySystemControls } from './wasmboySystemControls/wasmboySystemControls'; -import { WasmBoyFilePicker } from './wasmboyFilePicker/wasmboyFilePicker'; -import { WasmBoyOptions } from './wasmboyOptions/wasmboyOptions'; -import { WasmBoyGamepad } from './wasmboyGamepad/wasmboyGamepad'; +import { h, render, Component } from 'preact'; -// Log the wasmboy lib -console.log('WasmBoy', WasmBoy); +import { WasmBoy } from './wasmboy'; -// Our current canvas object. -// Up here for the saveStateCallback -const getCanvasElement = () => { - const canvasElement = document.querySelector('.wasmboy__canvas-container__canvas'); - return canvasElement; -}; - -// Our notification timeout -let notificationTimeout = undefined; - -// Variables to tell if our callbacks were ever run -let saveStateCallbackCalled = false; -let graphicsCallbackCalled = false; -let audioCallbackCalled = false; - -// WasmBoy Options -const WasmBoyDefaultOptions = { - isGbcEnabled: true, - isAudioEnabled: true, - frameSkip: 0, - audioBatchProcessing: true, - timersBatchProcessing: false, - audioAccumulateSamples: true, - graphicsBatchProcessing: false, - graphicsDisableScanlineRendering: false, - tileRendering: true, - tileCaching: true, - gameboyFrameRate: 60, - updateGraphicsCallback: imageDataArray => { - if (!graphicsCallbackCalled) { - console.log('Graphics Callback Called! Only Logging this once... imageDataArray:', imageDataArray); - graphicsCallbackCalled = true; - } - }, - updateAudioCallback: (audioContext, audioBufferSourceNode) => { - if (!audioCallbackCalled) { - console.log( - 'Audio Callback Called! Only Logging this once... audioContext, audioBufferSourceNode:', - audioContext, - audioBufferSourceNode - ); - audioCallbackCalled = true; - } - }, - saveStateCallback: saveStateObject => { - if (!saveStateCallbackCalled) { - console.log('Save State Callback Called! Only Logging this once... saveStateObject:', saveStateObject); - saveStateCallbackCalled = true; - } - - // Function called everytime a savestate occurs - // Used by the WasmBoySystemControls to show screenshots on save states - saveStateObject.screenshotCanvasDataURL = getCanvasElement().toDataURL(); - }, - onReady: () => { - console.log('onReady Callback Called!'); - }, - onPlay: () => { - console.log('onPlay Callback Called!'); - }, - onPause: () => { - console.log('onPause Callback Called!'); - }, - onLoadedAndStarted: () => { - console.log('onLoadedAndStarted Callback Called!'); - } -}; - -// Setup Google Analytics -if (typeof window !== 'undefined') { - const loadScript = require('load-script'); - loadScript('https://www.googletagmanager.com/gtag/js?id=UA-125276735-1', function(err, script) { - if (!err) { - window.dataLayer = window.dataLayer || []; - function gtag() { - window.dataLayer.push(arguments); - } - gtag('js', new Date()); - gtag('config', 'UA-125276735-1'); - // Attach Analytics to window - window.gtag = gtag; - } - }); -} - -export default class App extends Component { - constructor() { - super(); +import phosphorWidgets from '@phosphor/widgets'; - this.state = { - showDebugger: false, - showOptions: false, - showGamepad: false, - autoPlayROMOnLoad: false, - notification:
- }; - } +import packageJson from '../../package.json'; - // Using componentDidMount to wait for the canvas element to be inserted in DOM - componentDidMount() { - // Config our WasmBoy instance - WasmBoy.config(WasmBoyDefaultOptions) - .then(() => { - // Wait for input - this.setWasmBoyCanvas(); - }) - .catch(error => { - console.error(error); - }); - } +import './index.css'; - setWasmBoyCanvas() { - const setCanvasTask = async () => { - // Get our canvas element - await WasmBoy.setCanvas(getCanvasElement()); - await WasmBoy.play(); - }; +import WidgetManager from './widgetManager'; - return setCanvasTask(); - } +import menus from './menus'; - // Function to show notifications to the user - showNotification(notificationText) { - if (notificationTimeout) { - clearTimeout(notificationTimeout); - notificationTimeout = undefined; - } +import { Pubx } from 'pubx'; +import { PUBX_KEYS, PUBX_INITIALIZE } from './pubx.config'; - const closeNotification = () => { - const newState = Object.assign({}, this.state); - newState.notification =
; - this.setState(newState); - }; +import Overlay from './components/overlay/overlay'; +import Mobile from './components/mobile/mobile'; - const newState = Object.assign({}, this.state); - newState.notification = ( -
-
- ); - this.setState(newState); +// Setup from: +// https://github.com/phosphorjs/phosphor/blob/master/examples/example-dockpanel/src/index.ts - notificationTimeout = setTimeout(() => { - closeNotification(); - }, 3000); - } +// Create our dockPanel +const dockPanel = new phosphorWidgets.DockPanel(); +dockPanel.id = 'dock'; - render() { - // Optionally render the options - let optionsComponent =
; - if (this.state.showOptions) { - optionsComponent = ( -
- { - this.showNotification(text); - }} - /> -
- ); - } +// Create our top menu bar +let menuBar = new phosphorWidgets.MenuBar(); +menus.forEach(menu => { + menuBar.addMenu(menu); +}); +menuBar.id = 'menuBar'; - // optionally render the debugger - let debuggerComponent =
; - if (this.state.showDebugger) { - debuggerComponent = ( -
- -
- ); - } +phosphorWidgets.BoxPanel.setStretch(dockPanel, 1); - return ( -
-

WasmBoy (Debugger / Demo)

-
- WasmBoy Lib Version: {WasmBoy.getVersion()} -
- {WasmBoy.getCoreType() ? ( -
- WasmBoy Core Type: {WasmBoy.getCoreType()} -
- ) : ( - '' - )} - -
- Try{' '} - - VaporBoy - {' '} - for a full featured, GB / GBC Emulator Progressive Web App. -
+let main = new phosphorWidgets.BoxPanel({ direction: 'left-to-right', spacing: 0 }); +main.id = 'main'; +main.addWidget(dockPanel); -
- -
- - {optionsComponent} - -
- -
- -
- -
- -
- -
+window.onresize = () => { + main.update(); +}; - {debuggerComponent} +// Initialize Pubx for State Management +PUBX_INITIALIZE(); - { - this.showNotification(text); - }} - autoplay={this.state.autoPlayROMOnLoad} - /> +// Set up our Widget Manager +const widgetManager = new WidgetManager(dockPanel); +Pubx.publish(PUBX_KEYS.WIDGET, { + widgetManager +}); -
- { - this.showNotification(text); - }} - /> -
+// Bind phosphor to DOM +const phosphorContainer = document.getElementById('phosphor-container'); +phosphorWidgets.Widget.attach(menuBar, phosphorContainer); +phosphorWidgets.Widget.attach(main, phosphorContainer); -
- -
+// Bind Preact Overlay to DOM +const overlayContainer = document.getElementById('overlay-container'); +render(, overlayContainer); - {this.state.showGamepad ? : ''} +// Bind the Mobile UI to DOM +const mobileContainer = document.getElementById('mobile-container'); +render(, mobileContainer); - {this.state.notification} -
- ); - } -} +// Show a nice welcome message +setTimeout(() => { + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Welcome to the WasmBoy Debugger/Demo!'); +}, 100); diff --git a/demo/debugger/loadROM.js b/demo/debugger/loadROM.js new file mode 100644 index 00000000..12ffd63c --- /dev/null +++ b/demo/debugger/loadROM.js @@ -0,0 +1,37 @@ +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from './pubx.config'; +import { WasmBoy } from './wasmboy'; +import DebuggerAnalytics from './analytics'; + +export default function(file, fileName) { + const loadROMTask = async () => { + await WasmBoy.pause(); + await WasmBoy.loadROM(file); + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Game Loaded! 🎉'); + Pubx.publish(PUBX_KEYS.WASMBOY, { + filename: fileName + }); + + // Check if the Playback Control or CPU Control is open , if not, let's autoplay + if (Pubx.get(PUBX_KEYS.MOBILE).isMobile || !Pubx.get(PUBX_KEYS.WIDGET).isControlWidgetsOpen()) { + await WasmBoy.play(); + } + + Pubx.get(PUBX_KEYS.WASMBOY).update(); + + // Fire off Analytics + DebuggerAnalytics.loadROMSuccess(); + }; + + const loadROMPromise = loadROMTask(); + + loadROMPromise.catch(error => { + console.log('Load Game Error:', error); + Pubx.get(PUBX_KEYS.NOTIFICATION).showNotification('Game Load Error! 😞'); + + // Fire off Analytics + DebuggerAnalytics.loadROMFail(); + }); + + Pubx.get(PUBX_KEYS.LOADING).addControlPromise(loadROMPromise); +} diff --git a/demo/manifest.json b/demo/debugger/manifest.json similarity index 100% rename from demo/manifest.json rename to demo/debugger/manifest.json diff --git a/demo/debugger/menus.js b/demo/debugger/menus.js new file mode 100644 index 00000000..b7b94a6a --- /dev/null +++ b/demo/debugger/menus.js @@ -0,0 +1,78 @@ +// All of our top bar menus + +import phosphorWidgets from '@phosphor/widgets'; + +import commands from './commands/commands'; + +import openCommands from './commands/open'; +import playbackCommands from './commands/widgets/playback'; +import cpuCommands from './commands/widgets/cpu'; +import graphicsCommands from './commands/widgets/graphics'; +import audioCommands from './commands/widgets/audio'; +import interruptCommands from './commands/widgets/interrupt'; +import timerCommands from './commands/widgets/timer'; +import otherCommands from './commands/widgets/other'; + +const menus = []; + +const addCommandsToMenu = (commands, menu) => { + commands.forEach(command => { + menu.addItem({ command: command.id }); + }); +}; + +// Open +let openMenu = new phosphorWidgets.Menu({ commands }); +openMenu.title.label = 'Open'; +addCommandsToMenu(openCommands, openMenu); +menus.push(openMenu); + +// Widgets +let widgetMenu = new phosphorWidgets.Menu({ commands }); +widgetMenu.title.label = 'Widgets'; + +// Playback Sub Menu +let playbackSubMenu = new phosphorWidgets.Menu({ commands }); +playbackSubMenu.title.label = 'Playback'; +addCommandsToMenu(playbackCommands, playbackSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: playbackSubMenu }); + +// CPU +let cpuSubMenu = new phosphorWidgets.Menu({ commands }); +cpuSubMenu.title.label = 'CPU'; +addCommandsToMenu(cpuCommands, cpuSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: cpuSubMenu }); + +// Graphics +let graphicsSubMenu = new phosphorWidgets.Menu({ commands }); +graphicsSubMenu.title.label = 'Graphics'; +addCommandsToMenu(graphicsCommands, graphicsSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: graphicsSubMenu }); + +// Audio +let audioSubMenu = new phosphorWidgets.Menu({ commands }); +audioSubMenu.title.label = 'Audio'; +addCommandsToMenu(audioCommands, audioSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: audioSubMenu }); + +// Interrupt +let interruptSubMenu = new phosphorWidgets.Menu({ commands }); +interruptSubMenu.title.label = 'Interrupt'; +addCommandsToMenu(interruptCommands, interruptSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: interruptSubMenu }); + +// Timer +let timerSubMenu = new phosphorWidgets.Menu({ commands }); +timerSubMenu.title.label = 'Timer'; +addCommandsToMenu(timerCommands, timerSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: timerSubMenu }); + +// Other +let otherSubMenu = new phosphorWidgets.Menu({ commands }); +otherSubMenu.title.label = 'Other'; +addCommandsToMenu(otherCommands, otherSubMenu); +widgetMenu.addItem({ type: 'submenu', submenu: otherSubMenu }); + +menus.push(widgetMenu); + +export default menus; diff --git a/demo/debugger/preactWidget.js b/demo/debugger/preactWidget.js new file mode 100644 index 00000000..9a13b2b4 --- /dev/null +++ b/demo/debugger/preactWidget.js @@ -0,0 +1,89 @@ +import { h, render, Component } from 'preact'; +import { Pubx } from 'pubx'; +import { PUBX_KEYS } from './pubx.config'; +import phosphorWidgets from '@phosphor/widgets'; + +const createPreactNode = component => { + let node = document.createElement('div'); + let content = document.createElement('div'); + + render(component, content); + + node.appendChild(content); + return node; +}; + +// Our default widget config, spead with the value sent to us +const defaultWidgetConfig = { + component: undefined, + classes: ['default-wasmboy-widget'], + label: 'Preact Widget', + closable: true, + caption: 'Description for Preact Widget' +}; + +export default class PreactWidget extends phosphorWidgets.Widget { + constructor(passedWidgetConfig) { + const widgetConfig = { + ...defaultWidgetConfig, + ...passedWidgetConfig + }; + + if (!widgetConfig.component) { + throw new Error('You must supply a component to the Preact Widget'); + } + + super({ + node: createPreactNode(widgetConfig.component) + }); + this.addClass('content'); + + this.widgetConfig = widgetConfig; + + if (this.widgetConfig.classes) { + widgetConfig.classes.forEach(classString => { + this.addClass(classString); + }); + } + + this.title.label = this.widgetConfig.label; + this.title.closable = !!this.widgetConfig.closable; + this.title.caption = this.widgetConfig.caption; + } + + toJSON() { + // Make our widget config serializeable + const widgetConfigAsJson = { + ...this.widgetConfig + }; + widgetConfigAsJson.component = this.widgetConfig.component.nodeName.name; + + // Create a widget json object + const jsonObject = { + type: 'PreactWidget', + widgetConfig: widgetConfigAsJson + }; + + return JSON.stringify(jsonObject); + } + + onActivateRequest(msg) { + if (this.isAttached) { + // Called whenever panel is focused + } + } + + onCloseRequest() { + Pubx.get(PUBX_KEYS.WIDGET).widgetClosed(this); + + if (this.parent) { + this.parent = null; + } else if (this.isAttached) { + phosphorWidgets.Widget.detach(this); + } + } + + onResize() { + Pubx.get(PUBX_KEYS.WIDGET).widgetResized(this); + } +} diff --git a/demo/debugger/pubx.config.js b/demo/debugger/pubx.config.js new file mode 100644 index 00000000..6b263493 --- /dev/null +++ b/demo/debugger/pubx.config.js @@ -0,0 +1,197 @@ +import { Pubx } from 'pubx'; +import { WasmBoy, WasmBoyUpdateCanvas } from './wasmboy'; + +export const PUBX_KEYS = { + LOADING: 'LOADING', + MOBILE: 'MOBILE', + MODAL: 'MODAL', + NOTIFICATION: 'NOTIFICATION', + WASMBOY: 'WASMBOY', + WIDGET: 'WIDGET' +}; + +export function PUBX_INITIALIZE() { + // LOADING + Pubx.publish(PUBX_KEYS.LOADING, { + controlLoading: false, + controlPromises: [], + addControlPromise: promise => { + Pubx.publish(PUBX_KEYS.LOADING, { + controlLoading: true, + controlPromises: [...Pubx.get(PUBX_KEYS.LOADING).controlPromises, promise] + }); + + const finallyCallback = () => { + const controlPromises = Pubx.get(PUBX_KEYS.LOADING).controlPromises; + controlPromises.splice(controlPromises.indexOf(promise), 1); + + Pubx.publish(PUBX_KEYS.LOADING, { + controlLoading: controlPromises.length > 0, + controlPromises + }); + }; + + promise.then(finallyCallback).catch(finallyCallback); + } + }); + + // MOBILE + Pubx.publish(PUBX_KEYS.MOBILE, { + isMobile: false, + isLandscape: false, + isPortrait: false, + update: () => { + const mobile = window.matchMedia('(max-width: 901px)').matches; + const landscape = window.matchMedia('screen and (orientation: landscape)').matches; + const portrait = window.matchMedia('screen and (orientation: portrait)').matches; + + // Get our document class list + const documentClassList = document.documentElement.classList; + + // Add all Media query based on mobile vs desktop + if (mobile) { + documentClassList.add('mobile'); + documentClassList.remove('desktop'); + } else { + documentClassList.remove('mobile'); + documentClassList.add('desktop'); + } + if (landscape) { + documentClassList.add('landscape'); + } else { + documentClassList.remove('landscape'); + } + if (portrait) { + documentClassList.add('portrait'); + } else { + documentClassList.remove('portrait'); + } + + if (Pubx.get(PUBX_KEYS.MOBILE).isMobile !== mobile) { + WasmBoyUpdateCanvas(mobile, Pubx.get(PUBX_KEYS.WASMBOY).update); + } + + Pubx.publish(PUBX_KEYS.MOBILE, { + isMobile: mobile, + isLandscape: landscape && mobile, + isPortrait: portrait && mobile + }); + } + }); + + // MODAL + Pubx.publish(PUBX_KEYS.MODAL, { + visible: false, + component: false, + showModal: component => { + Pubx.publish(PUBX_KEYS.MODAL, { + visible: 'modal--visible', + component + }); + }, + closeModal: () => { + Pubx.publish(PUBX_KEYS.MODAL, { + visible: false + }); + } + }); + + // NOTIFICATION + const defaultTimeout = 5000; + Pubx.publish(PUBX_KEYS.NOTIFICATION, { + text: '', + timeout: defaultTimeout, + showNotification: (text, timeout) => { + if (!timeout) { + timeout = defaultTimeout; + } + + Pubx.publish(PUBX_KEYS.NOTIFICATION, { + text, + timeout + }); + } + }); + + // WASMBOY + Pubx.publish(PUBX_KEYS.WASMBOY, { + filename: '', + version: WasmBoy.getVersion(), + core: 'Please Load a ROM for the Core Type', + cartridge: {}, + update: () => { + const updateTask = async () => { + let cartridgeInfo = {}; + if (WasmBoy.isLoadedAndStarted()) { + cartridgeInfo = await WasmBoy._getCartridgeInfo(); + } + + Pubx.publish(PUBX_KEYS.WASMBOY, { + playing: WasmBoy.isPlaying(), + paused: WasmBoy.isPaused(), + ready: WasmBoy.isReady(), + loadedAndStarted: WasmBoy.isLoadedAndStarted(), + core: WasmBoy.getCoreType(), + cartridge: cartridgeInfo + }); + }; + updateTask(); + } + }); + + // WIDGET + Pubx.publish(PUBX_KEYS.WIDGET, { + widgetManager: undefined, + addWidget: (preactWidgetConfig, splitConfig) => { + const widgetManager = Pubx.get(PUBX_KEYS.WIDGET).widgetManager; + + if (widgetManager) { + widgetManager.addPreactWidget(preactWidgetConfig, splitConfig); + } else { + throw new Error('Widget Manager not Created!'); + } + }, + widgetClosed: widget => { + const widgetManager = Pubx.get(PUBX_KEYS.WIDGET).widgetManager; + + if (widgetManager) { + widgetManager.handlePreactWidgetClosed(widget); + } else { + throw new Error('Widget Manager not Created!'); + } + }, + widgetResized: widget => { + const widgetManager = Pubx.get(PUBX_KEYS.WIDGET).widgetManager; + + if (widgetManager) { + widgetManager.handlePreactWidgetResized(widget); + } else { + throw new Error('Widget Manager not Created!'); + } + }, + isWidgetOpen: widgetComponentName => { + const widgetManager = Pubx.get(PUBX_KEYS.WIDGET).widgetManager; + + if (widgetManager) { + return widgetManager.widgets.some(widget => { + const widgetJson = JSON.parse(widget.toJSON()); + + if (widgetJson.widgetConfig.component === widgetComponentName) { + return true; + } + + return false; + }); + } + + return false; + }, + isControlWidgetsOpen: () => { + // Check if the Playback Control or CPU Control is open , if not, let's autoplay + const pubxWidget = Pubx.get(PUBX_KEYS.WIDGET); + + const controlWidgetComponentNames = ['WasmBoyControls', 'CpuControl']; + return controlWidgetComponentNames.some(componentName => pubxWidget.isWidgetOpen(componentName)); + } + }); +} diff --git a/demo/debugger/styles/app.css b/demo/debugger/styles/app.css new file mode 100644 index 00000000..fd8585fd --- /dev/null +++ b/demo/debugger/styles/app.css @@ -0,0 +1,87 @@ +/* Styles pertaining to the app itself */ + +body { + display: flex; + z-index: 0; + flex-direction: column; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; + overflow: hidden; +} + +#phosphor-container { + display: flex; + z-index: 0; + flex-direction: column; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; + overflow: hidden; +} + +#mobile-container { + display: block; + z-index: 1; +} + +#overlay-container { + display: flex; + z-index: 2; + pointer-events: none; + flex-direction: column; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0; + padding: 0; + overflow: hidden; +} + +#menuBar { + flex: 0 0 auto; +} + +#main { + flex: 1 1 auto; +} + +#palette { + min-width: 300px; + border-right: 1px solid #dddddd; +} + +#dock { + padding: 4px; +} + +/* The widget themselves inner content */ +.content { + min-width: 50px; + min-height: 50px; + display: flex; + flex-direction: column; + padding: 8px; + border: 1px solid #c0c0c0; + border-top: none; + background: white; + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); +} + +.content > div { + flex: 1 1 auto; + border: 1px solid #020202; + overflow: auto; + height: 100%; + padding: 10px; +} diff --git a/demo/debugger/styles/phosphor.css b/demo/debugger/styles/phosphor.css new file mode 100644 index 00000000..2363c643 --- /dev/null +++ b/demo/debugger/styles/phosphor.css @@ -0,0 +1,20 @@ +/* Styles to allow phosphor to work */ + +@import '@phosphor/dragdrop/style/index.css'; +@import '@phosphor/widgets/style/index.css'; +@import '@phosphor/default-theme/style/dockpanel.css'; +@import '@phosphor/default-theme/style/menu.css'; +@import '@phosphor/default-theme/style/menubar.css'; +@import '@phosphor/default-theme/style/scrollbar.css'; +@import '@phosphor/default-theme/style/tabbar.css'; + +/* Phosphor FontAwesome Fix */ +.p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon:before { + content: 'X' !important; + cursor: pointer; + font-weight: bold; +} +.p-Menu-item[data-type='submenu'] > .p-Menu-itemSubmenuIcon::before { + content: '>' !important; + font-weight: bold; +} diff --git a/demo/debugger/styles/shared.css b/demo/debugger/styles/shared.css new file mode 100644 index 00000000..323b1ddf --- /dev/null +++ b/demo/debugger/styles/shared.css @@ -0,0 +1,60 @@ +/* Styles used by individual elements across the app */ + +.hide { + display: none; +} + +.pixel-canvas { + width: 100%; + height: 100%; + object-fit: contain; +} + +.hidden-rom-input { + display: none !important; + opacity: 0; + visibility: hidden; +} + +.remove-default-button { + background-color: transparent; + border: none; + padding: 0; +} + +.tall { + height: 100vh; + width: 100vw; + background-color: purple; + color: white; +} + +/* https://30-seconds.github.io/30-seconds-of-css/#donut-spinner */ +@keyframes donut-spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.donut { + display: flex; + justify-content: center; + align-items: center; + text-align: center; + + width: 100%; +} + +.donut:after { + content: ' '; + display: inline-block; + border: 4px solid rgba(0, 0, 0, 0.1); + border-left-color: #7983ff; + border-radius: 50%; + width: 30px; + height: 30px; + animation: donut-spin 1.2s linear infinite; +} diff --git a/demo/debugger/wasmboy.js b/demo/debugger/wasmboy.js new file mode 100644 index 00000000..88d8bca1 --- /dev/null +++ b/demo/debugger/wasmboy.js @@ -0,0 +1,147 @@ +// Single place to import WasmBoy +// This is so we can swap between Different Lib outputs Easily +import { WasmBoy as WasmBoyImport } from '../../dist/wasmboy.wasm.esm'; +export const WasmBoy = WasmBoyImport; + +import DebuggerAnalytics from './analytics'; + +// Variables to tell if our callbacks were ever run +let saveStateCallbackCalled = false; +let graphicsCallbackCalled = false; +let audioCallbackCalled = false; + +let isMobileCanvas = false; + +const getDesktopCanvasElement = () => { + return document.querySelector('.wasmboy-player canvas'); +}; + +const getMobileCanvasElement = () => { + return document.querySelector('.mobile-container #mobile-container__wasmboy-canvas'); +}; + +// WasmBoy Options +const WasmBoyDefaultOptions = { + isGbcEnabled: true, + isAudioEnabled: true, + frameSkip: 0, + audioBatchProcessing: false, + timersBatchProcessing: false, + audioAccumulateSamples: false, + graphicsBatchProcessing: false, + graphicsDisableScanlineRendering: false, + tileRendering: false, + tileCaching: false, + gameboyFrameRate: 60, + updateGraphicsCallback: imageDataArray => { + if (!graphicsCallbackCalled) { + console.log('Graphics Callback Called! Only Logging this once... imageDataArray:', imageDataArray); + graphicsCallbackCalled = true; + } + }, + updateAudioCallback: (audioContext, audioBufferSourceNode) => { + if (!audioCallbackCalled) { + console.log( + 'Audio Callback Called! Only Logging this once... audioContext, audioBufferSourceNode:', + audioContext, + audioBufferSourceNode + ); + audioCallbackCalled = true; + } + }, + saveStateCallback: saveStateObject => { + if (!saveStateCallbackCalled) { + console.log('Save State Callback Called! Only Logging this once... saveStateObject:', saveStateObject); + saveStateCallbackCalled = true; + } + + // Function called everytime a savestate occurs + // Used by the WasmBoySystemControls to show screenshots on save states + let canvasElement; + if (isMobileCanvas) { + canvasElement = getMobileCanvasElement(); + } else { + canvasElement = getDesktopCanvasElement(); + } + + if (canvasElement) { + saveStateObject.screenshotCanvasDataURL = canvasElement.toDataURL(); + } + }, + onReady: () => { + console.log('onReady Callback Called!'); + }, + onPlay: () => { + console.log('onPlay Callback Called!'); + }, + onPause: () => { + console.log('onPause Callback Called!'); + }, + onLoadedAndStarted: () => { + console.log('onLoadedAndStarted Callback Called!'); + } +}; + +export const WasmBoyDefaultDesktopOptions = { + ...WasmBoyDefaultOptions +}; + +export const WasmBoyDefaultMobileOptions = { + ...WasmBoyDefaultOptions, + frameSkip: 1, + audioBatchProcessing: true, + audioAccumulateSamples: true, + tileRendering: true, + tileCaching: true +}; + +export const WasmBoyUpdateCanvas = (isMobile, stateUpdateCallback) => { + isMobileCanvas = isMobile; + + const updateTask = async () => { + let canvasElement; + let defaultOptions; + + if (isMobile) { + canvasElement = getMobileCanvasElement(); + defaultOptions = WasmBoyDefaultMobileOptions; + } else { + canvasElement = getDesktopCanvasElement(); + defaultOptions = WasmBoyDefaultDesktopOptions; + } + + if (!canvasElement) { + setTimeout(updateTask, 500); + return; + } + const wasmboyOptions = { + ...defaultOptions + }; + + if (stateUpdateCallback) { + const wasmboyStateCallbackKeys = ['onReady', 'onPlay', 'onPause', 'onLoadedAndStarted']; + + wasmboyStateCallbackKeys.forEach(callbackKey => { + const callback = wasmboyOptions[callbackKey]; + wasmboyOptions[callbackKey] = () => { + callback(); + setTimeout(() => { + stateUpdateCallback(); + }, 50); + }; + }); + } + + // Add an analytics event for when a rom is played from onLoadedAndStarted + const currentLoadedAndStarted = wasmboyOptions.onLoadedAndStarted; + wasmboyOptions.onLoadedAndStarted = () => { + currentLoadedAndStarted(); + DebuggerAnalytics.ROMLoadedAndStarted(); + }; + + await WasmBoy.config(wasmboyOptions); + await WasmBoy.setCanvas(canvasElement); + await WasmBoy.play(); + }; + updateTask(); +}; diff --git a/demo/debugger/wasmboyDebugger/numberBaseTable/numberBaseTable.js b/demo/debugger/wasmboyDebugger/numberBaseTable/numberBaseTable.js deleted file mode 100644 index 75eadddc..00000000 --- a/demo/debugger/wasmboyDebugger/numberBaseTable/numberBaseTable.js +++ /dev/null @@ -1,114 +0,0 @@ -import { Component } from 'preact'; -import './numberBaseTable.css'; - -// Component that takes in a JSON object, where the Keys are the column name, -// And the Rows will represent each base value of the number in the value of the key -export class NumberBaseTable extends Component { - constructor() { - super(); - this.state = { - object: {} - }; - } - - componentWillReceiveProps(nextProps) { - this.setState({ - object: nextProps.object - }); - } - - // Modifed from: https://ourcodeworld.com/articles/read/380/how-to-convert-a-binary-string-into-a-readable-string-and-vice-versa-with-javascript - numberToBinaryString(number) { - // Simply Convert each place in hex to binary - const hexString = number.toString(16); - - let binaryString = ''; - for (let i = 0; i < hexString.length; i++) { - let valueAtIncrementer = parseInt(hexString.charAt(i), 16).toString(2); - let paddedValueAtIncrementer = valueAtIncrementer; - // Pad to 4 bits - while (paddedValueAtIncrementer.length < 4) { - paddedValueAtIncrementer = '0' + paddedValueAtIncrementer; - } - - binaryString += paddedValueAtIncrementer; - - if (i !== hexString.length - 1) { - binaryString += ' '; - } - } - - // Padd out to 8 bit increments - if (!(binaryString.length & 1)) { - binaryString = '0000 ' + binaryString; - } - - return binaryString; - } - - getTableCellsForValueWithBase(valueBase) { - const tableCells = []; - Object.keys(this.state.object).forEach(key => { - if (valueBase === 16) { - tableCells.push( - - 0x - {this.state.object[key].toString(16)} - - ); - } else if (valueBase === 2) { - tableCells.push({this.numberToBinaryString(this.state.object[key])}); - } else { - tableCells.push({this.state.object[key]}); - } - }); - - return tableCells; - } - - getTableCellsForObjectKeys() { - if (!this.state.object) { - return
; - } - - const objectKeysAsTableCells = []; - - Object.keys(this.state.object).forEach(key => { - objectKeysAsTableCells.push({key}); - }); - - return objectKeysAsTableCells; - } - - render() { - if (!this.state.object || Object.keys(this.state.object).length < 1) { - return
; - } - - return ( -
- - - - {this.getTableCellsForObjectKeys()} - - - - - {this.getTableCellsForValueWithBase(16)} - - - - - {this.getTableCellsForValueWithBase(10)} - - - - - {this.getTableCellsForValueWithBase(2)} - -
Value Base
Hexadecimal:
Decimal:
Binary:
-
- ); - } -} diff --git a/demo/debugger/wasmboyDebugger/wasmboyBackgroundMap/wasmboyBackgroundMap.css b/demo/debugger/wasmboyDebugger/wasmboyBackgroundMap/wasmboyBackgroundMap.css deleted file mode 100644 index 9aaf3da5..00000000 --- a/demo/debugger/wasmboyDebugger/wasmboyBackgroundMap/wasmboyBackgroundMap.css +++ /dev/null @@ -1,3 +0,0 @@ -.wasmboy__backgroundMap { - border: 2px solid #020202; -} diff --git a/demo/debugger/wasmboyDebugger/wasmboyDebugger.css b/demo/debugger/wasmboyDebugger/wasmboyDebugger.css deleted file mode 100644 index bd06e572..00000000 --- a/demo/debugger/wasmboyDebugger/wasmboyDebugger.css +++ /dev/null @@ -1,19 +0,0 @@ -.wasmboy__debugger { - margin-top: 10px; - margin-bottom: 10px; - margin-left: auto; - margin-right: auto; - max-width: 800px; -} - -.wasmboy__debugger canvas { - max-width: 600px; - width: 100%; - margin-top: 10px; - margin-bottom: 10px; -} - -.debuggerAction { - margin-top: 15px; - margin-bottom: 15px; -} diff --git a/demo/debugger/wasmboyDebugger/wasmboyDebugger.js b/demo/debugger/wasmboyDebugger/wasmboyDebugger.js deleted file mode 100644 index 6d4d42f0..00000000 --- a/demo/debugger/wasmboyDebugger/wasmboyDebugger.js +++ /dev/null @@ -1,495 +0,0 @@ -import { Component } from 'preact'; -import { WasmBoy } from '../../../dist/wasmboy.wasm.esm'; -import { NumberBaseTable } from './numberBaseTable/numberBaseTable'; -import { WasmBoyBackgroundMap } from './wasmboyBackgroundMap/wasmboyBackgroundMap'; -import { WasmBoyTileData } from './wasmboyTileData/wasmboyTileData'; -import './wasmboyDebugger.css'; - -// Function to get a value in gameboy memory, to wasmboy memory -const getWasmBoyOffsetFromGameBoyOffset = async gameboyOffset => { - return await WasmBoy._runWasmExport('getWasmBoyOffsetFromGameBoyOffset', [gameboyOffset]); -}; - -let autoUpdateValueTableId = false; - -export class WasmBoyDebugger extends Component { - constructor() { - super(); - // set our state to if we are initialized or not - this.state = { - showValueTable: false, - autoUpdateValueTable: false, - showBackgroundMap: false, - showTileData: false, - breakPoint: '40', - opcodesToRun: 2000, - opcodesStepped: '0', - cyclesRan: '0', - valueTable: { - cpu: {}, - ppu: {}, - apu: {}, - timers: {}, - interrupts: {} - } - }; - } - - // Function to simply flip a boolean on the state - flipShowStatus(stateKey) { - const newState = Object.assign({}, this.state); - newState[stateKey] = !newState[stateKey]; - this.setState(newState); - - // Fireoff a a raf for updating the value table - if (stateKey === 'autoUpdateValueTable') { - if (this.state.autoUpdateValueTable) { - const autoUpdateValueTable = () => { - this.updateValueTable(); - if (autoUpdateValueTableId) { - autoUpdateValueTableId = requestAnimationFrame(() => { - autoUpdateValueTable(); - }); - } - }; - autoUpdateValueTableId = true; - autoUpdateValueTable(); - } else { - cancelAnimationFrame(autoUpdateValueTable); - autoUpdateValueTableId = false; - } - } - } - - // Function to return the hidden class deoending oin a boolean in state - getStateClass(stateKey) { - return this.state[stateKey] ? '' : 'hide'; - } - - // Function to runa single opcode - stepOpcode(skipDebugOutput) { - const stepOpcodeTask = async () => { - const numberOfCycles = await WasmBoy._runWasmExport('emulationStep'); - - if (numberOfCycles <= 0) { - console.error('Opcode not recognized! Check wasm logs.'); - this.updateDebugInfo(); - throw new Error(); - } - - this.updateExecutionProgress(); - - if (skipDebugOutput) { - return; - } - this.updateValueTable(); - }; - return stepOpcodeTask(); - } - - // Function to run a specifed number of opcodes for faster stepping - runNumberOfOpcodes(numberOfOpcodes, breakPoint, skipDebugOutput) { - // Keep stepping until highest opcode increases - let opcodesToRun = this.state.opcodesToRun; - if (numberOfOpcodes) { - opcodesToRun = numberOfOpcodes; - } - - const runNumberOfOpcodesTask = async () => { - let opcodesRan = 0; - - const runOpcode = async () => { - await this.stepOpcode(true); - - if (!skipDebugOutput) { - this.updateValueTable(); - } - const programCounter = await WasmBoy._runWasmExport('getProgramCounter'); - if (breakPoint && breakPoint === programCounter) { - if (skipDebugOutput) { - this.updateValueTable(); - } - return; - } - - if (opcodesRan < opcodesToRun) { - opcodesRan++; - await runOpcode(); - return; - } - }; - await runOpcode(); - }; - return runNumberOfOpcodesTask(); - } - - // Function to keep running opcodes until a breakpoint is reached - breakPoint(skipInitialStep) { - // Set our opcode breakpoint - const breakPoint = parseInt(this.state.breakPoint, 16); - - const breakPointTask = async () => { - if (!skipInitialStep) { - await this.runNumberOfOpcodes(1, breakPoint); - } - - const response = await WasmBoy._runWasmExport('executeFrameUntilBreakpoint', [breakPoint]); - if (response === 0) { - requestAnimationFrame(() => { - this.updateExecutionProgress(); - this.updateValueTable(); - this.breakPoint(true); - }); - } else if (response === -1) { - throw new Error('WasmBoy Crashed while trying to reach the breakpoint'); - } else { - console.log('Reached Breakpoint, that satisfies test inside runNumberOfOpcodes'); - this.updateExecutionProgress(); - this.updateValueTable(); - } - }; - breakPointTask(); - } - - logWasmBoyMemory() { - WasmBoy._getWasmMemorySection().then(wasmByteMemory => { - console.log(`[WasmBoy Debugger] Entire WasmBoy Memory:`, wasmByteMemory); - }); - } - - logGameBoyMemory() { - const asyncTask = async () => { - const location = await WasmBoy._getWasmConstant('GAMEBOY_INTERNAL_MEMORY_LOCATION'); - const size = await WasmBoy._getWasmConstant('GAMEBOY_INTERNAL_MEMORY_SIZE'); - const memory = await WasmBoy._getWasmMemorySection(location, location + size + 1); - console.log(`[WasmBoy Debugger] Gameboy Memory:`, memory); - }; - asyncTask(); - } - - updateExecutionProgress() { - // Async task to get the - // opcodes stepped, cycles ran, etc... - - const asyncTask = async () => { - const opcodesStepped = await WasmBoy._getStepsAsString(); - const cyclesRan = await WasmBoy._getCyclesAsString(); - this.setState({ - ...this.state, - opcodesStepped, - cyclesRan - }); - }; - asyncTask(); - } - - updateValueTable() { - // Check that we have our instance and byte memory - if (!WasmBoy.isReady()) { - return; - } - - // Create our new valueTable object - const valueTable = { - cpu: {}, - ppu: {}, - apu: {}, - timers: {}, - interrupts: {} - }; - - const getValueTableTask = async () => { - // Update CPU valueTable - valueTable.cpu['Program Counter (PC)'] = await WasmBoy._runWasmExport('getProgramCounter'); - valueTable.cpu['Opcode at PC'] = await WasmBoy._runWasmExport('getOpcodeAtProgramCounter'); - valueTable.cpu['Stack Pointer'] = await WasmBoy._runWasmExport('getStackPointer'); - valueTable.cpu['Register A'] = await WasmBoy._runWasmExport('getRegisterA'); - valueTable.cpu['Register F'] = await WasmBoy._runWasmExport('getRegisterF'); - valueTable.cpu['Register B'] = await WasmBoy._runWasmExport('getRegisterB'); - valueTable.cpu['Register C'] = await WasmBoy._runWasmExport('getRegisterC'); - valueTable.cpu['Register D'] = await WasmBoy._runWasmExport('getRegisterD'); - valueTable.cpu['Register E'] = await WasmBoy._runWasmExport('getRegisterE'); - valueTable.cpu['Register H'] = await WasmBoy._runWasmExport('getRegisterH'); - valueTable.cpu['Register L'] = await WasmBoy._runWasmExport('getRegisterL'); - valueTable.cpu = Object.assign({}, valueTable.cpu); - - // Get all of the gameboy 0xffXX memory - const debugMemoryStart = await getWasmBoyOffsetFromGameBoyOffset(0xff00); - const debugMemoryEnd = await getWasmBoyOffsetFromGameBoyOffset(0xffff); - const debugMemory = await WasmBoy._getWasmMemorySection(debugMemoryStart, debugMemoryEnd + 1); - - // Update PPI - valueTable.ppu['Scanline Register (LY) - 0xFF44'] = await WasmBoy._runWasmExport('getLY'); - valueTable.ppu['LCD Status (STAT) - 0xFF41'] = debugMemory[0x0041]; - valueTable.ppu['LCD Control (LCDC) - 0xFF40'] = debugMemory[0x0040]; - valueTable.ppu['Scroll X - 0xFF43'] = debugMemory[0x0043]; - valueTable.ppu['Scroll Y - 0xFF42'] = debugMemory[0x0042]; - valueTable.ppu['Window X - 0xFF4B'] = debugMemory[0x004b]; - valueTable.ppu['Window Y - 0xFF4A'] = debugMemory[0x004a]; - - // Update Timers valueTable - valueTable.timers['TIMA - 0xFF05'] = await WasmBoy._runWasmExport('getTIMA'); - valueTable.timers['TMA - 0xFF06'] = await WasmBoy._runWasmExport('getTMA'); - valueTable.timers['TIMC/TAC - 0xFF07'] = await WasmBoy._runWasmExport('getTAC'); - valueTable.timers['DIV/Divider Register - 0xFF04'] = await WasmBoy._runWasmExport('getDIV'); - - // Update interrupts valueTable - // TODO: Interrupot master switch - // if(WasmBoy._getWasmInstance().exports.areInterruptsEnabled()) { - // valueTable.interrupts['Interrupt Master Switch'] = 0x01; - // } else { - // valueTable.interrupts['Interrupt Master Switch'] = 0x00; - // } - valueTable.interrupts['IE/Interrupt Enabled - 0xFFFF'] = debugMemory[0x00ff]; - valueTable.interrupts['IF/Interrupt Request - 0xFF0F'] = debugMemory[0x000f]; - - // Update APU valueTable - // Add the register valueTable for our 4 channels - for (let channelNum = 1; channelNum <= 4; channelNum++) { - for (let registerNum = 0; registerNum < 5; registerNum++) { - let registerAddress = 0xff10 + 5 * (channelNum - 1) + registerNum; - valueTable.apu[`Channel ${channelNum} - NR${channelNum}${registerNum} - 0x${registerAddress.toString(16).toUpperCase()}`] = - debugMemory[registerAddress & 0x00ff]; - } - } - - // Clone our valueTable, that it is immutable and will cause change detection - const newState = Object.assign({}, this.state); - newState.valueTable = valueTable; - this.setState(newState); - }; - getValueTableTask(); - } - - render(props) { - return ( -
-

Debugger

- -

Control Flow Actions:

- -
- -
- -
- Run Specified Number of Opcodes: - { - this.state.opcodesToRun = evt.target.value; - }} - /> - -
- -
- Breakpoint Line Number: 0x - { - this.state.breakPoint = evt.target.value; - }} - /> - -
- -

Wasmboy State Actions:

- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -

Debugger Elements:

- -
- -
- -
- -
- -
- -
- -
- -
- -
-

Opcodes Stepped: {this.state.opcodesStepped}

-

Cycles Ran: {this.state.cyclesRan}

-
- -
-

Value Table

- -

Cpu Info:

- - Reference Doc - - - -

PPU Info:

- - Reference Doc - - - -

APU Info:

- - Reference Doc - - - -

Timer Info:

- - Reference Doc - - - -

Interrupt Info:

- - Reference Doc - - -
- -
- -
- -
- -
-
- ); - } -} diff --git a/demo/debugger/wasmboyDebugger/wasmboyTileData/wasmboyTileData.css b/demo/debugger/wasmboyDebugger/wasmboyTileData/wasmboyTileData.css deleted file mode 100644 index a7cfd0df..00000000 --- a/demo/debugger/wasmboyDebugger/wasmboyTileData/wasmboyTileData.css +++ /dev/null @@ -1,3 +0,0 @@ -.wasmboy__tileData { - border: 2px solid #020202; -} diff --git a/demo/debugger/wasmboyFilePicker/googlePicker/googlePicker.js b/demo/debugger/wasmboyFilePicker/googlePicker/googlePicker.js deleted file mode 100644 index 7f71aedf..00000000 --- a/demo/debugger/wasmboyFilePicker/googlePicker/googlePicker.js +++ /dev/null @@ -1,129 +0,0 @@ -// Taken & Preact-ified from: https://github.com/sdoomz/react-google-picker -// And only using OAuth: https://stackoverflow.com/questions/22435410/google-drive-picker-developer-key-is-invalid-error?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa -// Picker API is super out of date :p - -import { Component } from 'preact'; -import loadScript from 'load-script'; - -const GOOGLE_SDK_URL = 'https://apis.google.com/js/api.js'; - -let scriptLoadingStarted = false; - -export default class GooglePicker extends Component { - static defaultProps = { - onChange: () => {}, - onAuthenticate: () => {}, - scope: ['https://www.googleapis.com/auth/drive.readonly'], - viewId: 'DOCS', - authImmediate: false, - multiselect: false, - navHidden: false, - disabled: false - }; - - constructor(props) { - super(props); - - this.onApiLoad = this.onApiLoad.bind(this); - this.onChoose = this.onChoose.bind(this); - } - - componentDidMount() { - if (this.isGoogleReady()) { - // google api is already exists - // init immediately - this.onApiLoad(); - } else if (!scriptLoadingStarted) { - // load google api and the init - scriptLoadingStarted = true; - loadScript(GOOGLE_SDK_URL, this.onApiLoad); - } else { - // is loading - } - } - - isGoogleReady() { - return !!window.gapi; - } - - isGoogleAuthReady() { - return !!window.gapi.auth; - } - - isGooglePickerReady() { - return !!window.google.picker; - } - - onApiLoad() { - window.gapi.load('auth'); - window.gapi.load('picker'); - } - - doAuth(callback) { - window.gapi.auth.authorize( - { - client_id: this.props.clientId, - scope: this.props.scope, - immediate: this.props.authImmediate - }, - callback - ); - } - - onChoose(event) { - if (!this.isGoogleReady() || !this.isGoogleAuthReady() || !this.isGooglePickerReady() || this.props.disabled) { - return null; - } - - const token = window.gapi.auth.getToken(); - const oauthToken = token && token.access_token; - - if (oauthToken) { - this.createPicker(oauthToken); - } else { - this.doAuth(({ access_token }) => this.createPicker(access_token)); - } - } - - createPicker(oauthToken) { - this.props.onAuthenticate(oauthToken); - - if (this.props.createPicker) { - return this.props.createPicker(google, oauthToken); - } - - const googleViewId = google.picker.ViewId[this.props.viewId]; - const view = new window.google.picker.View(googleViewId); - - if (this.props.mimeTypes) { - view.setMimeTypes(this.props.mimeTypes.join(',')); - } - - if (!view) { - throw new Error("Can't find view by viewId"); - } - - const picker = new window.google.picker.PickerBuilder() - .addView(view) - .setOAuthToken(oauthToken) - .setCallback(this.props.onChange); - - if (this.props.origin) { - picker.setOrigin(this.props.origin); - } - - if (this.props.navHidden) { - picker.enableFeature(window.google.picker.Feature.NAV_HIDDEN); - } - - if (this.props.multiselect) { - picker.enableFeature(window.google.picker.Feature.MULTISELECT_ENABLED); - } - - picker.build().setVisible(true); - } - - render() { - return
{this.props.children ? this.props.children : }
; - } -} diff --git a/demo/debugger/wasmboyFilePicker/wasmboyFilePicker.js b/demo/debugger/wasmboyFilePicker/wasmboyFilePicker.js deleted file mode 100644 index 0cf1b9bd..00000000 --- a/demo/debugger/wasmboyFilePicker/wasmboyFilePicker.js +++ /dev/null @@ -1,273 +0,0 @@ -import { Component } from 'preact'; -import Portal from 'preact-portal'; -import GooglePicker from './googlePicker/googlePicker'; -import { WasmBoy } from '../../../dist/wasmboy.wasm.esm'; -import './wasmboyFilePicker.css'; - -import { openSourceROMs, getOpenSourceROMElements } from './openSourceROMs'; - -// Public Keys for Google Drive API -const WASMBOY_DEBUGGER_GOOGLE_PICKER_CLIENT_ID = '427833658710-bntpbmf6pimh8trt0n4c36gteomseg61.apps.googleusercontent.com'; - -// OAuth Key for Google Drive -let googlePickerOAuthToken = ''; - -export class WasmBoyFilePicker extends Component { - constructor(props) { - super(props); - // set our state to if we are initialized or not - this.state = { - currentFileName: 'No Game Selected...', - isFileLoading: false, - showOpenSourceROMs: false - }; - - this.openSourceROMElements = getOpenSourceROMElements(this.loadOpenSourceROM.bind(this)); - } - - loadROM(file, fileName) { - this.setFileLoadingStatus(true); - - // To test the new autoplay in safari - // and in chrome - WasmBoy.resumeAudioContext(); - - const loadROMTask = async () => { - await WasmBoy.loadROM(file); - this.props.showNotification('Game Loaded! 🎉'); - this.setFileLoadingStatus(false); - - // To test the new autoplay in safari - // and in chrome - if (this.props.autoplay) { - WasmBoy.play(); - } - - // Fire off Analytics - if (window !== undefined && window.gtag) { - gtag('event', 'load_rom_success'); - } - }; - - loadROMTask().catch(error => { - console.log('Load Game Error:', error); - this.props.showNotification('Game Load Error! 😞'); - this.setFileLoadingStatus(false); - - // Fire off Analytics - if (window !== undefined && window.gtag) { - gtag('event', 'load_rom_fail'); - } - }); - - // Set our file name - const newState = Object.assign({}, this.state); - newState.currentFileName = fileName; - this.setState(newState); - } - - // Allow passing a file - // https://gist.github.com/AshikNesin/e44b1950f6a24cfcd85330ffc1713513 - loadLocalFile(event) { - // WasmBoy.resumeAudioContext(); - // Handled by the onClick on the input - this.loadROM(event.target.files[0], event.target.files[0].name); - - if (this.props.autoplay) { - WasmBoy.play(); - } - } - - loadGoogleDriveFile(data) { - WasmBoy.resumeAudioContext(); - if (data.action === 'picked') { - // Fetch from the drive api to download the file - // https://developers.google.com/drive/v3/web/picker - // https://developers.google.com/drive/v2/reference/files/get - - const googlePickerFileObject = data.docs[0]; - const oAuthHeaders = new Headers({ - Authorization: 'Bearer ' + googlePickerOAuthToken - }); - - this.setFileLoadingStatus(true); - - // First Fetch the Information about the file - fetch('https://www.googleapis.com/drive/v2/files/' + googlePickerFileObject.id, { - headers: oAuthHeaders - }) - .then(response => { - return response.json(); - }) - .then(responseJson => { - const lowercaseTitle = responseJson.title.toLowerCase(); - if (lowercaseTitle.includes('.zip') || lowercaseTitle.includes('.gb') || lowercaseTitle.includes('.gbc')) { - // Finally load the file using the oAuthHeaders - WasmBoy.loadROM(responseJson.downloadUrl, { - headers: oAuthHeaders, - fileName: responseJson.title - }) - .then(() => { - console.log('Wasmboy Ready!'); - this.props.showNotification('Game Loaded! 🎉'); - this.setFileLoadingStatus(false); - - if (this.props.autoplay) { - WasmBoy.play(); - } - - // Set our file name - const newState = Object.assign({}, this.state); - newState.currentFileName = responseJson.title; - this.setState(newState); - - // Fire off Analytics - if (window !== undefined && window.gtag) { - gtag('event', 'load_rom_success'); - } - }) - .catch(error => { - console.log('Load Game Error:', error); - this.props.showNotification('Game Load Error! 😞'); - this.setFileLoadingStatus(false); - - // Fire off Analytics - if (window !== undefined && window.gtag) { - gtag('event', 'load_rom_fail'); - } - }); - } else { - this.props.showNotification('Invalid file type. 😞'); - this.setFileLoadingStatus(false); - } - }) - .catch(error => { - this.props.showNotification('Error getting file from google drive 💔'); - this.setFileLoadingStatus(false); - }); - } - } - - loadOpenSourceROM(openSourceROM) { - this.loadROM(openSourceROM.url, openSourceROM.title); - this.setState({ ...this.state, showOpenSourceROMs: false }); - } - - setFileLoadingStatus(isLoading) { - const newState = Object.assign({}, this.state); - newState.isFileLoading = isLoading; - this.setState(newState); - } - - render() { - let fileInput = ( -
-
-
- ); - if (!this.state.isFileLoading) { - fileInput = ( -
- {/* Upload ROM from device */} -
- -
- - {/* Google Drive Picker */} - { - this.loadGoogleDriveFile(data); - }} - onAuthenticate={token => { - googlePickerOAuthToken = token; - }} - multiselect={false} - navHidden={true} - authImmediate={false} - viewId={'DOCS'} - > -
- -
-
- - {/* Open Source ROMs Button */} - this.setState({ ...this.state, showOpenSourceROMs: true })}> - - {/* Material open lock svg https://material.io/tools/icons/static/icons/baseline-lock_open-24px.svg */} - - - - - - Open Source ROMs (Play Now) - - - {/*Open Source ROMs Modal*/} - {this.state.showOpenSourceROMs ? ( - - - - ) : null} -
- ); - } - - return ( -
-

Load Game

-

Supported file types: ".gb", ".gbc", ".zip"

-

{this.state.currentFileName}

- {fileInput} -
- ); - } -} diff --git a/demo/debugger/wasmboyGamepad/wasmboyGamepad.css b/demo/debugger/wasmboyGamepad/wasmboyGamepad.css deleted file mode 100644 index 2bac56c1..00000000 --- a/demo/debugger/wasmboyGamepad/wasmboyGamepad.css +++ /dev/null @@ -1,63 +0,0 @@ -.wasmboy__gamepad { - position: fixed; - pointer-events: none; - top: 0; - left: 0; - - width: 100vw; - height: 90vh; - opacity: 0.65; - - /* Shown in media query at bottom */ - display: none; -} - -.wasmboy__gamepad svg { - position: absolute; - pointer-events: auto; - fill: #b967ff; -} - -#gamepadDpad { - left: 0; - bottom: 50px; - - width: 175px; - height: 175px; -} - -#gamepadSelect { - left: calc(50vw - 125px); - bottom: 0; - - width: 125px; - height: 50px; -} - -#gamepadStart { - right: calc(50vw - 125px); - bottom: 0; - - width: 125px; - height: 50px; -} - -#gamepadB { - right: 125px; - bottom: 60px; - - width: 110px; - height: 110px; -} - -#gamepadA { - right: 0px; - bottom: 120px; - - width: 110px; - height: 110px; -} - -.wasmboy__gamepad { - display: block; -} diff --git a/demo/debugger/wasmboyGamepad/wasmboyGamepad.js b/demo/debugger/wasmboyGamepad/wasmboyGamepad.js deleted file mode 100644 index 9ba47121..00000000 --- a/demo/debugger/wasmboyGamepad/wasmboyGamepad.js +++ /dev/null @@ -1,76 +0,0 @@ -import { Component } from 'preact'; -import { WasmBoy } from '../../../dist/wasmboy.wasm.esm'; -import './wasmboyGamepad.css'; - -// Simple mobile contreols for the wasmboy debugger -export class WasmBoyGamepad extends Component { - constructor() { - super(); - } - - componentDidMount() { - // Add our touch inputs - const dpadElement = document.getElementById('gamepadDpad'); - const startElement = document.getElementById('gamepadStart'); - const selectElement = document.getElementById('gamepadSelect'); - const aElement = document.getElementById('gamepadA'); - const bElement = document.getElementById('gamepadB'); - - WasmBoy.addTouchInput('UP', dpadElement, 'DPAD', 'UP'); - WasmBoy.addTouchInput('RIGHT', dpadElement, 'DPAD', 'RIGHT'); - WasmBoy.addTouchInput('DOWN', dpadElement, 'DPAD', 'DOWN'); - WasmBoy.addTouchInput('LEFT', dpadElement, 'DPAD', 'LEFT'); - WasmBoy.addTouchInput('A', aElement, 'BUTTON'); - WasmBoy.addTouchInput('B', bElement, 'BUTTON'); - WasmBoy.addTouchInput('START', startElement, 'BUTTON'); - WasmBoy.addTouchInput('SELECT', selectElement, 'BUTTON'); - } - - render() { - return ( -
- {/* DPAD */} - - - - - - {/* Start */} - - - - - Start - - - - {/* Select */} - - - - - Select - - - - {/* A */} - - - - - A - - - - {/* B */} - - - - - B - - -
- ); - } -} diff --git a/demo/debugger/wasmboySystemControls/wasmboySystemControls.css b/demo/debugger/wasmboySystemControls/wasmboySystemControls.css deleted file mode 100644 index 3fbfb8d8..00000000 --- a/demo/debugger/wasmboySystemControls/wasmboySystemControls.css +++ /dev/null @@ -1,36 +0,0 @@ -.wasmboy__systemControls { - margin-top: 10px; - margin-bottom: 10px; - text-align: center; -} - -.system-controls button { - margin: 10px; -} - -.saveStateContainer { - margin-left: auto; - margin-right: auto; - margin-top: 25px; - - display: flex; - justify-content: space-around; - align-items: flex-start; - flex-wrap: wrap; - flex-direction: row; -} - -.saveState { - margin-left: 5px; - margin-right: 5px; - padding: 10px; - - word-wrap: break-word; - - transition: background-color 0.25s; -} - -.saveState:hover { - background-color: rgba(0, 0, 0, 0.25); - cursor: pointer; -} diff --git a/demo/debugger/wasmboySystemControls/wasmboySystemControls.js b/demo/debugger/wasmboySystemControls/wasmboySystemControls.js deleted file mode 100644 index df8261ab..00000000 --- a/demo/debugger/wasmboySystemControls/wasmboySystemControls.js +++ /dev/null @@ -1,208 +0,0 @@ -import { Component } from 'preact'; -import Portal from 'preact-portal'; -import { WasmBoy } from '../../../dist/wasmboy.wasm.esm'; -import './wasmboySystemControls.css'; - -export class WasmBoySystemControls extends Component { - constructor(props) { - super(props); - // set our state to if we are initialized or not - this.state = { - showSaveStates: false, - currentFileName: 'No Game Selected...', - saveStates: [], - saveStateError: false - }; - - let fpsCounter; - fpsCounter = () => { - this.setState({ - fps: WasmBoy.getFPS() - }); - setTimeout(() => { - fpsCounter(); - }, 1000); - }; - fpsCounter(); - } - - // Toggle showing all save states - openSaveStates() { - if (this.state.showSaveStates) { - return; - } - - const newState = Object.assign({}, this.state); - newState.showSaveStates = true; - this.setState(newState); - - // Get our save states - WasmBoy.getSaveStates() - .then(saveStates => { - if (saveStates) { - newState.saveStates = saveStates; - } - this.setState(newState); - }) - .catch(() => { - newState.saveStateError = true; - this.setState(newState); - }); - } - - closeSaveStates() { - const newState = Object.assign({}, this.state); - newState.showSaveStates = false; - newState.saveStates = []; - newState.saveStateError = false; - this.setState(newState); - } - - startGame() { - if (!WasmBoy.isReady()) { - this.props.showNotification('Please load a game. ⏏ī¸'); - } else { - WasmBoy.resumeAudioContext(); - WasmBoy.play(); - - // Fire off Analytics - if (window !== undefined && window.gtag) { - gtag('event', 'rom_played'); - } - } - } - - saveState() { - WasmBoy.saveState() - .then(saveState => { - console.log('Resolved Save State from WasmBoy.saveState():', saveState); - WasmBoy.play() - .then(() => { - this.props.showNotification('State Saved! 💾'); - }) - .catch(err => { - this.props.showNotification('Error Saving State... 😞'); - console.error(err); - }); - }) - .catch(err => { - this.props.showNotification('Error Saving State... 😞'); - console.error(err); - }); - } - - loadState(saveState) { - this.closeSaveStates(); - WasmBoy.loadState(saveState) - .then(() => { - WasmBoy.play() - .then(() => { - this.props.showNotification('State Loaded! 😀'); - }) - .catch(() => { - this.props.showNotification('Error Loading State... 😞'); - }); - }) - .catch(() => { - this.props.showNotification('Error Loading State... 😞'); - }); - } - - getStartButtonClass() { - if (WasmBoy.isReady()) { - return 'is-success'; - } - - return 'is-danger'; - } - - render(props) { - let saveStateElements =
; - if (this.state.showSaveStates) { - if (this.state.saveStates.length > 0) { - // Loop through save states - saveStateElements = []; - this.state.saveStates.forEach(saveState => { - let saveStateDateString = new Date(saveState.date); - saveStateDateString = saveStateDateString.toLocaleString(); - saveStateElements.unshift( -
{ - this.loadState(saveState); - }} - > - -

Date:

- {saveStateDateString} -

Auto:

- {saveState.isAuto ? 'true' : 'false'} -
- ); - }); - } - - if (this.state.saveStateError || this.state.saveStates.length <= 0) { - saveStateElements =

No Save States Found 😞

; - } - } - - return ( -
- - - - -
Gameboy FPS: {this.state.fps}
- - {this.state.showSaveStates ? ( - - - - ) : null} -
- ); - } -} diff --git a/demo/debugger/widgetManager.js b/demo/debugger/widgetManager.js new file mode 100644 index 00000000..965f142e --- /dev/null +++ b/demo/debugger/widgetManager.js @@ -0,0 +1,199 @@ +// Organize and hnadle which widgets are currently active + +import { h } from 'preact'; +import { Pubx } from 'pubx'; +import traverse from 'traverse'; +import { PUBX_KEYS } from './pubx.config'; + +import PreactWidget from './preactWidget'; + +// Add all available widgets so they can serialized and restored +import WasmBoyPlayer from './components/playback/wasmboyPlayer/wasmboyPlayer'; +import WasmBoyControls from './components/playback/wasmboyControls/wasmboyControls'; +import WasmBoyInfo from './components/playback/wasmboyInfo/wasmboyInfo'; +import WasmBoyOptions from './components/playback/wasmboyOptions/wasmboyOptions'; +import CpuState from './components/cpu/cpuState/cpuState'; +import CpuControl from './components/cpu/cpuControl/cpuControl'; +import GraphicsState from './components/graphics/graphicsState/graphicsState'; +import BackgroundMap from './components/graphics/backgroundMap/backgroundMap'; +import TileData from './components/graphics/tileData/tileData'; +import AudioState from './components/audio/audioState/audioState'; +import InterruptState from './components/interrupt/interruptState/interruptState'; +import TimerState from './components/timer/timerState/timerState'; +import AboutComponent from './components/other/about/about'; +import HelpComponent from './components/other/help/help'; + +const components = { + WasmBoyPlayer: , + WasmBoyControls: , + WasmBoyInfo: , + WasmBoyOptions: , + CpuState: , + CpuControl: , + GraphicsState: , + BackgroundMap: , + TileData: , + AudioState: , + InterruptState: , + TimerState: , + AboutComponent: , + HelpComponent: +}; + +const LOCALSTORAGE_KEY = 'WASMBOY_DEBUGGER_WIDGET_MANAGER'; + +export default class WidgetManager { + constructor(dockPanel) { + this.dockPanel = dockPanel; + this.widgets = []; + + this.state = {}; + + this._restore(); + + if (this.state.layout) { + this._restoreLayout(); + } else { + this._createDefaultLayout(); + } + + // Some event throttlers + this.eventThrottle = false; + } + + addPreactWidget(preactWidgetConfig, splitConfig) { + if (!splitConfig) { + splitConfig = { + mode: 'split-right', + ref: this.widgets[this.widgets.length - 1] + }; + } + + if (splitConfig.refIndex !== undefined) { + splitConfig.ref = this.widgets[splitConfig.refIndex]; + delete splitConfig.refIndex; + } + + const widget = new PreactWidget(preactWidgetConfig); + this.widgets.push(widget); + + this.dockPanel.addWidget(widget, splitConfig); + + this._saveLayout(); + } + + handlePreactWidgetClosed(widget) { + this.widgets.splice(this.widgets.indexOf(widget), 1); + this._saveLayout(); + } + + handlePreactWidgetResized(widget) { + if (this.eventThrottle) { + return; + } + + this.eventThrottle = setTimeout(() => { + this._saveLayout(); + this.eventThrottle = false; + }, 100); + } + + _saveLayout() { + setTimeout(() => { + this.state.layout = this.dockPanel.saveLayout(); + this._save(); + }); + } + + _restoreLayout() { + if (this.state.layout) { + // Try to create all of the appropriate preact widgets + let hadError = false; + const self = this; + const errorHandler = widgetJson => { + console.error('Could not restore widget', widgetJson); + hadError = true; + self.widgets = []; + }; + traverse(this.state.layout).forEach(function(value) { + if (this.parent && this.parent.key === 'widgets') { + const widgetJson = JSON.parse(value); + + if (widgetJson.type === 'PreactWidget') { + const preactWidgetConfig = widgetJson.widgetConfig; + preactWidgetConfig.component = components[preactWidgetConfig.component]; + + if (preactWidgetConfig.component) { + const newWidget = new PreactWidget(preactWidgetConfig); + this.update(newWidget); + self.widgets.push(newWidget); + } else { + errorHandler(widgetJson); + } + } else { + errorHandler(widgetJson); + } + } + }); + + // Finally restore the layout + if (!hadError) { + this.dockPanel.restoreLayout(this.state.layout); + return; + } + } + + // If could not restore, use the default + this._createDefaultLayout(); + } + + _createDefaultLayout() { + this.addPreactWidget({ + component: , + label: 'Player', + closable: false + }); + this.addPreactWidget( + { + component: , + label: 'Help' + }, + { + mode: 'split-right', + refIndex: 0 + } + ); + this.addPreactWidget( + { + component: , + label: 'Playback Controls' + }, + { + mode: 'split-bottom', + refIndex: 0 + } + ); + this.addPreactWidget( + { + component: , + label: 'About' + }, + { + mode: 'split-bottom', + refIndex: 1 + } + ); + } + + _save() { + localStorage.setItem(LOCALSTORAGE_KEY, JSON.stringify(this.state)); + } + + _restore() { + const restoredState = localStorage.getItem(LOCALSTORAGE_KEY); + + if (restoredState) { + this.state = JSON.parse(restoredState); + } + } +} diff --git a/demo/googleDrivePicker.js b/demo/googleDrivePicker.js new file mode 100644 index 00000000..d04f6010 --- /dev/null +++ b/demo/googleDrivePicker.js @@ -0,0 +1,151 @@ +// API For loading GB Roms from Google Drive +// Using the Picker API + +import loadScript from 'load-script'; + +// Google drive +const GOOGLE_SDK_URL = 'https://apis.google.com/js/api.js'; +// OAuth Key for Google Drive +let googlePickerOAuthToken = ''; + +class GoogleDrivePickerLib { + constructor() { + this.initialized = false; + this.clientId = undefined; + } + + initialize(clientId) { + this.clientId = clientId; + + // Load the Picker SDK + loadScript(GOOGLE_SDK_URL, () => { + window.gapi.load('auth'); + window.gapi.load('picker'); + }); + } + + getFile(mimeTypes) { + if (!this._isGoogleReady() || !this._isGoogleAuthReady() || !this._isGooglePickerReady()) { + return Promise.reject('Google Drive not ready'); + } + + const token = window.gapi.auth.getToken(); + const oauthToken = token && token.access_token; + + const getFilePromiseObject = {}; + + const getFilePromise = new Promise((resolve, reject) => { + getFilePromiseObject.resolve = resolve; + getFilePromiseObject.reject = reject; + }); + + if (oauthToken) { + this._createPicker(oauthToken, mimeTypes, getFilePromiseObject); + } else { + this._doAuth(({ access_token }) => this._createPicker(access_token, mimeTypes, getFilePromiseObject)); + } + + return getFilePromise; + } + + _isGoogleReady() { + return !!window.gapi; + } + + _isGoogleAuthReady() { + return !!window.gapi.auth; + } + + _isGooglePickerReady() { + return !!window.google.picker; + } + + _doAuth(callback) { + window.gapi.auth.authorize( + { + client_id: this.clientId, + scope: ['https://www.googleapis.com/auth/drive.readonly'], + immediate: false + }, + callback + ); + } + + _createPicker(oauthToken, mimeTypes, getFilePromiseObject) { + googlePickerOAuthToken = oauthToken; + + const googleViewId = google.picker.ViewId['DOCS']; + const view = new window.google.picker.DocsView(googleViewId); + + if (mimeTypes) { + view.setMimeTypes(mimeTypes.join(',')); + } + + if (!view) { + getFilePromiseObject.reject("Can't find view by viewId"); + } + + view.setMode(window.google.picker.DocsViewMode.LIST); + + const picker = new window.google.picker.PickerBuilder() + .addView(view) + .setOAuthToken(oauthToken) + .setCallback(data => this._pickerCallback(data, getFilePromiseObject)); + + picker.enableFeature(window.google.picker.Feature.NAV_HIDDEN); + + // Calculate our picker size + // https://stackoverflow.com/questions/1248081/get-the-browser-viewport-dimensions-with-javascript + // https://developers.google.com/picker/docs/reference#PickerBuilder + const viewportWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + const viewportHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + picker.setSize(parseInt(viewportWidth, 10), parseInt(viewportHeight, 10)); + + picker.build().setVisible(true); + } + + _pickerCallback(data, getFilePromiseObject) { + const loadGoogleDriveFileTask = async () => { + if (data.action === 'cancel') { + getFilePromiseObject.resolve({ cancelled: true }); + return; + } + + // We only want the picked action + if (data.action !== 'picked') { + return; + } + + // Fetch from the drive api to download the file + // https://developers.google.com/drive/v3/web/picker + // https://developers.google.com/drive/v2/reference/files/get + + const googlePickerFileObject = data.docs[0]; + const oAuthHeaders = new Headers({ + Authorization: 'Bearer ' + googlePickerOAuthToken + }); + + // First Fetch the Information about the file + const responseJson = await fetch('https://www.googleapis.com/drive/v2/files/' + googlePickerFileObject.id, { + headers: oAuthHeaders + }) + .then(response => { + return response.json(); + }) + .catch(error => { + getFilePromiseObject.reject(error); + }); + + // Resolve the final downloadUrl and oAuthHeader + getFilePromiseObject.resolve({ + response: responseJson, + oAuthHeaders + }); + }; + loadGoogleDriveFileTask(); + } +} + +// Export a singleton +const GoogleDrivePicker = new GoogleDrivePickerLib(); +export default GoogleDrivePicker; diff --git a/demo/openSourceROMs.css b/demo/openSourceROMs.css new file mode 100644 index 00000000..fae8ce95 --- /dev/null +++ b/demo/openSourceROMs.css @@ -0,0 +1,94 @@ +.open-source-rom-container { + width: 100%; + height: 100%; + overflow: auto; +} + +.open-source-rom { + position: relative; +} + +.open-source-rom__button { + display: flex; + flex-direction: row; + justify-items: center; + align-items: center; + flex-wrap: wrap; + width: 100%; + padding: 10px; + margin: 10px; + + background-color: transparent; + transition: background-color 0.5s; + border: none; +} + +.open-source-rom:hover { + background-color: rgba(0, 0, 0, 0.15); +} + +.open-source-rom__left, +.open-source-rom__right { + display: flex; + flex-direction: column; + justify-items: center; + align-items: center; +} + +.open-source-rom__left { + width: 200px; + min-width: 200px; + height: 200px; +} + +.open-source-rom__left img { + object-fit: contain; + width: 100%; + height: 100%; +} + +.open-source-rom__right { + flex-grow: 1; + padding-top: 5px; + padding-bottom: 5px; + padding-left: 5px; + padding-right: 10px; + + max-width: 300px; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.open-source-rom h3 { + font-weight: bold; + font-size: 1.25rem; +} + +.open-source-rom__info { + z-index: 100; +} + +.open-source-rom__link { + position: absolute; + right: 5px; + top: 5px; + width: 30px; + height: 30px; + + display: flex; + justify-content: center; + align-items: center; + border-radius: 25px; + + z-index: 100; + transition: background-color 0.5s; + background-color: rgba(0, 0, 0, 0.15); + box-shadow: 0px 1px 5px #020202; +} + +.open-source-rom__link:hover { + background-color: rgba(0, 0, 0, 0.35); +} diff --git a/demo/openSourceROMs.js b/demo/openSourceROMs.js new file mode 100644 index 00000000..869a2491 --- /dev/null +++ b/demo/openSourceROMs.js @@ -0,0 +1,5 @@ +// Import/Export our demo roms +export blarggsCpuROM from '../test/accuracy/testroms/blargg/cpu_instrs/cpu_instrs.gb'; +export blarggsInstrTimingROM from '../test/accuracy/testroms/blargg/instr_timing/instr_timing.gb'; +export tobuTobuGirlROM from '../test/performance/testroms/tobutobugirl/tobutobugirl.gb'; +export backToColorDemoROM from '../test/performance/testroms/back-to-color/back-to-color.gbc'; diff --git a/demo/debugger/wasmboyFilePicker/openSourceROMs.js b/demo/openSourceROMsPreact.js similarity index 82% rename from demo/debugger/wasmboyFilePicker/openSourceROMs.js rename to demo/openSourceROMsPreact.js index 11452106..b0dc9d42 100644 --- a/demo/debugger/wasmboyFilePicker/openSourceROMs.js +++ b/demo/openSourceROMsPreact.js @@ -2,16 +2,19 @@ import { h } from 'preact'; // Import our demo roms -import blarggsCpuROM from '../../../test/accuracy/testroms/blargg/cpu_instrs/cpu_instrs.gb'; -import blarggsInstrTimingROM from '../../../test/accuracy/testroms/blargg/instr_timing/instr_timing.gb'; -import tobuTobuGirlROM from '../../../test/performance/testroms/tobutobugirl/tobutobugirl.gb'; -import backToColorDemoROM from '../../../test/performance/testroms/back-to-color/back-to-color.gbc'; +import { blarggsCpuROM, blarggsInstrTimingROM, tobuTobuGirlROM, backToColorDemoROM } from './openSourceROMs'; + +// Import our ROM imags +import tobuTobuGirlImage from './debugger/assets/tobutobugirl.png'; +import backToColorImage from './debugger/assets/back-to-color.gbc.noPerformanceOptions.png'; +import blarggsCpuImage from './debugger/assets/cpu_instrs.golden.png'; +import blarggsInstrTimingImage from './debugger/assets/instr_timing.golden.png'; export const openSourceROMs = { tobutobugirl: { title: 'tobu tobu girl', url: tobuTobuGirlROM, - image: 'assets/tobutobugirl.png', + image: tobuTobuGirlImage, link: 'http://tangramgames.dk/tobutobugirl/', infoElement: (
@@ -25,7 +28,7 @@ export const openSourceROMs = { backToColor: { title: 'Back to Color', url: backToColorDemoROM, - image: 'assets/back-to-color.gbc.noPerformanceOptions.png', + image: backToColorImage, link: 'https://github.com/AntonioND/back-to-color', infoElement: (
@@ -36,7 +39,7 @@ export const openSourceROMs = { blarggsCpu: { title: "Blargg's CPU Test", url: blarggsCpuROM, - image: 'assets/cpu_instrs.golden.png', + image: blarggsCpuImage, link: 'http://gbdev.gg8.se/wiki/articles/Test_ROMs', infoElement: (
@@ -47,7 +50,7 @@ export const openSourceROMs = { blarggsInstrTiming: { title: "Blargg's instr_timing Test", url: blarggsInstrTimingROM, - image: 'assets/instr_timing.golden.png', + image: blarggsInstrTimingImage, link: 'http://gbdev.gg8.se/wiki/articles/Test_ROMs', infoElement: (
diff --git a/demo/template.html b/demo/template.html deleted file mode 100644 index 4c8d0f9c..00000000 --- a/demo/template.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - <%= htmlWebpackPlugin.options.title %> - - - - - - <% if (htmlWebpackPlugin.options.manifest.theme_color) { %> - - <% } %> <% for (var chunk of webpack.chunks) { %> <% if (chunk.names.length === 1 && chunk.names[0] === 'polyfills') continue; %> <% for - (var file of chunk.files) { %> <% if (htmlWebpackPlugin.options.preload && file.match(/\.(js|css)$/)) { %> - - <% } else if (file.match(/manifest\.json$/)) { %> - - <% } %> <% } %> <% } %> - - - <%= htmlWebpackPlugin.options.ssr({ url: '/' }) %> - - - - diff --git a/dist/core/core.untouched.wasm b/dist/core/core.untouched.wasm index 0ae14292..bc666b8d 100644 Binary files a/dist/core/core.untouched.wasm and b/dist/core/core.untouched.wasm differ diff --git a/dist/core/core.untouched.wast b/dist/core/core.untouched.wast index 63edaeef..1bd888a9 100644 --- a/dist/core/core.untouched.wast +++ b/dist/core/core.untouched.wast @@ -261,7 +261,6 @@ (global $core/graphics/palette/Palette.memoryLocationBackgroundPaletteIndex (mut i32) (i32.const 65384)) (global $core/graphics/palette/Palette.memoryLocationSpritePaletteData (mut i32) (i32.const 65387)) (global $core/graphics/palette/Palette.memoryLocationBackgroundPaletteData (mut i32) (i32.const 65385)) - (global $~argc (mut i32) (i32.const 0)) (global $core/legacy/wasmMemorySize i32 (i32.const 9109504)) (global $core/legacy/wasmBoyInternalStateLocation i32 (i32.const 1024)) (global $core/legacy/wasmBoyInternalStateSize i32 (i32.const 1024)) @@ -276,6 +275,7 @@ (global $core/legacy/soundOutputLocation i32 (i32.const 588800)) (global $core/legacy/gameRamBanksLocation i32 (i32.const 719872)) (global $core/legacy/gameBytesLocation i32 (i32.const 850944)) + (global $~argc (mut i32) (i32.const 0)) (memory $0 0) (export "memory" (memory $0)) (export "config" (func $core/core/config)) @@ -346,7 +346,7 @@ (export "getStackPointer" (func $core/debug/debug-cpu/getStackPointer)) (export "getOpcodeAtProgramCounter" (func $core/debug/debug-cpu/getOpcodeAtProgramCounter)) (export "getLY" (func $core/debug/debug-graphics/getLY)) - (export "drawBackgroundMapToWasmMemory" (func $core/debug/debug-graphics/drawBackgroundMapToWasmMemory|trampoline)) + (export "drawBackgroundMapToWasmMemory" (func $core/debug/debug-graphics/drawBackgroundMapToWasmMemory)) (export "drawTileDataToWasmMemory" (func $core/debug/debug-graphics/drawTileDataToWasmMemory)) (export "getDIV" (func $core/debug/debug-timer/getDIV)) (export "getTIMA" (func $core/debug/debug-timer/getTIMA)) @@ -25151,53 +25151,7 @@ ) ) ) - (func $core/graphics/tiles/drawPixelsFromLineOfTile|trampoline (; 299 ;) (; has Stack IR ;) (type $iiiiiiiiiiiiii) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) (param $6 i32) (param $7 i32) (param $8 i32) (param $9 i32) (param $10 i32) (param $11 i32) (param $12 i32) (result i32) - (block $3of3 - (block $2of3 - (block $1of3 - (block $0of3 - (block $outOfRange - (br_table $0of3 $1of3 $2of3 $3of3 $outOfRange - (i32.sub - (get_global $~argc) - (i32.const 10) - ) - ) - ) - (unreachable) - ) - (set_local $10 - ;;@ core/graphics/tiles.ts:36:53 - (i32.const 0) - ) - ) - (set_local $11 - ;;@ core/graphics/tiles.ts:37:25 - (i32.const 0) - ) - ) - (set_local $12 - ;;@ core/graphics/tiles.ts:38:25 - (i32.const -1) - ) - ) - (call $core/graphics/tiles/drawPixelsFromLineOfTile - (get_local $0) - (get_local $1) - (get_local $2) - (get_local $3) - (get_local $4) - (get_local $5) - (get_local $6) - (get_local $7) - (get_local $8) - (get_local $9) - (get_local $10) - (get_local $11) - (get_local $12) - ) - ) - (func $core/debug/debug-graphics/drawTileDataToWasmMemory (; 300 ;) (; has Stack IR ;) (type $v) + (func $core/debug/debug-graphics/drawTileDataToWasmMemory (; 299 ;) (; has Stack IR ;) (type $v) (local $0 i32) (local $1 i32) (local $2 i32) @@ -25339,11 +25293,9 @@ (i32.const 8) ) ) - (set_global $~argc - (i32.const 11) - ) + ;;@ core/debug/debug-graphics.ts:213:8 (drop - (call $core/graphics/tiles/drawPixelsFromLineOfTile|trampoline + (call $core/graphics/tiles/drawPixelsFromLineOfTile (get_local $1) (get_local $5) (get_local $4) @@ -25371,8 +25323,10 @@ (i32.const 429056) ;;@ core/debug/debug-graphics.ts:224:10 (i32.const 1) + ;;@ core/debug/debug-graphics.ts:225:10 (i32.const 0) - (i32.const 0) + ;;@ core/debug/debug-graphics.ts:226:10 + (i32.const -1) ) ) ;;@ core/debug/debug-graphics.ts:212:50 @@ -25406,19 +25360,19 @@ ) ) ) - (func $core/debug/debug-timer/getDIV (; 301 ;) (; has Stack IR ;) (type $i) (result i32) + (func $core/debug/debug-timer/getDIV (; 300 ;) (; has Stack IR ;) (type $i) (result i32) ;;@ core/debug/debug-timer.ts:5:16 (get_global $core/timers/timers/Timers.dividerRegister) ) - (func $core/debug/debug-timer/getTIMA (; 302 ;) (; has Stack IR ;) (type $i) (result i32) + (func $core/debug/debug-timer/getTIMA (; 301 ;) (; has Stack IR ;) (type $i) (result i32) ;;@ core/debug/debug-timer.ts:9:16 (get_global $core/timers/timers/Timers.timerCounter) ) - (func $core/debug/debug-timer/getTMA (; 303 ;) (; has Stack IR ;) (type $i) (result i32) + (func $core/debug/debug-timer/getTMA (; 302 ;) (; has Stack IR ;) (type $i) (result i32) ;;@ core/debug/debug-timer.ts:13:16 (get_global $core/timers/timers/Timers.timerModulo) ) - (func $core/debug/debug-timer/getTAC (; 304 ;) (; has Stack IR ;) (type $i) (result i32) + (func $core/debug/debug-timer/getTAC (; 303 ;) (; has Stack IR ;) (type $i) (result i32) (local $0 i32) ;;@ core/debug/debug-timer.ts:17:2 (set_local $0 @@ -25441,7 +25395,7 @@ ) (get_local $0) ) - (func $start (; 305 ;) (; has Stack IR ;) (type $v) + (func $start (; 304 ;) (; has Stack IR ;) (type $v) ;;@ core/core.ts:17:0 (if ;;@ core/core.ts:17:4 @@ -25463,7 +25417,7 @@ ) ) ) - (func $core/execute/executeFrameAndCheckAudio|trampoline (; 306 ;) (; has Stack IR ;) (type $ii) (param $0 i32) (result i32) + (func $core/execute/executeFrameAndCheckAudio|trampoline (; 305 ;) (; has Stack IR ;) (type $ii) (param $0 i32) (result i32) (block $1of1 (block $0of1 (block $outOfRange @@ -25482,12 +25436,12 @@ (get_local $0) ) ) - (func $~setargc (; 307 ;) (; has Stack IR ;) (type $iv) (param $0 i32) + (func $~setargc (; 306 ;) (; has Stack IR ;) (type $iv) (param $0 i32) (set_global $~argc (get_local $0) ) ) - (func $core/execute/executeUntilCondition|trampoline (; 308 ;) (; has Stack IR ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (func $core/execute/executeUntilCondition|trampoline (; 307 ;) (; has Stack IR ;) (type $iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) (block $3of3 (block $2of3 (block $1of3 @@ -25520,23 +25474,4 @@ (get_local $2) ) ) - (func $core/debug/debug-graphics/drawBackgroundMapToWasmMemory|trampoline (; 309 ;) (; has Stack IR ;) (type $iv) (param $0 i32) - (block $1of1 - (block $0of1 - (block $outOfRange - (br_table $0of1 $1of1 $outOfRange - (get_global $~argc) - ) - ) - (unreachable) - ) - (set_local $0 - ;;@ core/debug/debug-graphics.ts:22:63 - (i32.const 0) - ) - ) - (call $core/debug/debug-graphics/drawBackgroundMapToWasmMemory - (get_local $0) - ) - ) ) diff --git a/docs/benchmarkResults/2015-MBP-Mojave-10.14.1/Safari12.0.1/Screen Shot 2018-12-04 at 2.56.38 AM.png b/docs/benchmarkResults/2015-MBP-Mojave-10.14.1/Safari12.0.1/safariBackToColorRunner.png similarity index 100% rename from docs/benchmarkResults/2015-MBP-Mojave-10.14.1/Safari12.0.1/Screen Shot 2018-12-04 at 2.56.38 AM.png rename to docs/benchmarkResults/2015-MBP-Mojave-10.14.1/Safari12.0.1/safariBackToColorRunner.png diff --git a/docs/images/benchmarkSafariBackToColorRunner.png b/docs/images/benchmarkSafariBackToColorRunner.png new file mode 100644 index 00000000..e34eb5c0 Binary files /dev/null and b/docs/images/benchmarkSafariBackToColorRunner.png differ diff --git a/docs/images/debuggerDesktopDemo.gif b/docs/images/debuggerDesktopDemo.gif new file mode 100644 index 00000000..0ddc4806 Binary files /dev/null and b/docs/images/debuggerDesktopDemo.gif differ diff --git a/docs/images/debuggerMobileDemo.gif b/docs/images/debuggerMobileDemo.gif new file mode 100644 index 00000000..fcb0aa10 Binary files /dev/null and b/docs/images/debuggerMobileDemo.gif differ diff --git a/lib/wasmboy/wasmboy.js b/lib/wasmboy/wasmboy.js index c28f4ce9..8ed9bf70 100644 --- a/lib/wasmboy/wasmboy.js +++ b/lib/wasmboy/wasmboy.js @@ -103,9 +103,7 @@ class WasmBoyLibService { // Set our new canvas element, and re-run init on graphics to apply styles and things this.canvasElement = canvasElement; - if (this.wasmInstance && this.wasmByteMemory) { - await WasmBoyGraphics.initialize(this.canvasElement, this.wasmInstance, this.wasmByteMemory, this.options.updateGraphicsCallback); - } + await WasmBoyGraphics.initialize(this.canvasElement, this.options.updateGraphicsCallback); }; return setCanvasTask(); diff --git a/lib/worker/smartworker.js b/lib/worker/smartworker.js index f1e141ce..91e6659c 100644 --- a/lib/worker/smartworker.js +++ b/lib/worker/smartworker.js @@ -42,7 +42,7 @@ export class SmartWorker { } this.messageListeners = []; - /*ROLLUP_REPLACE_BROWSER + /*ROLLUP_REPLACE_PROD_BROWSER // Can't load base63 data string directly because safari // https://stackoverflow.com/questions/10343913/how-to-create-a-web-worker-from-a-string @@ -61,9 +61,16 @@ export class SmartWorker { this.worker = new Worker(URL.createObjectURL(blob)); + this.worker.onmessage = this._onMessageHandler.bind(this); + + ROLLUP_REPLACE_PROD_BROWSER*/ + + /*ROLLUP_REPLACE_DEV_BROWSER + + this.worker = new Worker(workerUrl); this.worker.onmessage = this._onMessageHandler.bind(this); - ROLLUP_REPLACE_BROWSER*/ + ROLLUP_REPLACE_DEV_BROWSER*/ /*ROLLUP_REPLACE_NODE diff --git a/package-lock.json b/package-lock.json index b615f37b..2d426e4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -226,6 +226,16 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-proposal-export-default-from": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.2.0.tgz", + "integrity": "sha512-NVfNe7F6nsasG1FnvcFxh2FN0l04ZNe75qTOAVOILWPam0tw9a63RtT/Dab8dPjedZa4fTQaQ83yMMywF9OSug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.2.0" + } + }, "@babel/plugin-proposal-object-rest-spread": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz", @@ -236,6 +246,15 @@ "@babel/plugin-syntax-object-rest-spread": "^7.2.0" } }, + "@babel/plugin-syntax-export-default-from": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz", + "integrity": "sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-syntax-jsx": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", @@ -304,6 +323,135 @@ "to-fast-properties": "^2.0.0" } }, + "@phosphor/algorithm": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/algorithm/-/algorithm-1.1.2.tgz", + "integrity": "sha1-/R3pEEyafzTpKGRYbd8ufy53eeg=", + "dev": true + }, + "@phosphor/collections": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/collections/-/collections-1.1.2.tgz", + "integrity": "sha1-xMC4uREpkF+zap8kPy273kYtq40=", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2" + } + }, + "@phosphor/commands": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@phosphor/commands/-/commands-1.6.1.tgz", + "integrity": "sha512-iRgn7QX64e0VwZ91KFo964a/LVpw9XtiYIYtpymEyKY757NXvx6ZZMt1CqKfntoDcSZJeVte4eV8jJWhZoVlDA==", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2", + "@phosphor/coreutils": "^1.3.0", + "@phosphor/disposable": "^1.1.2", + "@phosphor/domutils": "^1.1.2", + "@phosphor/keyboard": "^1.1.2", + "@phosphor/signaling": "^1.2.2" + } + }, + "@phosphor/coreutils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@phosphor/coreutils/-/coreutils-1.3.0.tgz", + "integrity": "sha1-YyktOBwBLFqw0Blug87YKbfgSkI=", + "dev": true + }, + "@phosphor/default-theme": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@phosphor/default-theme/-/default-theme-0.1.0.tgz", + "integrity": "sha512-XVjYHQUH4e1JxAnMebtoutx/DRlAjgeh6JRb8jRGEWgFDAEHdvTXJEtARdR1SnNIDMCaho4t3nXHFhtcFh4JKg==", + "dev": true, + "requires": { + "@phosphor/dragdrop": "^1.3.0", + "@phosphor/widgets": "^1.6.0" + } + }, + "@phosphor/disposable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/disposable/-/disposable-1.1.2.tgz", + "integrity": "sha1-oZLdai5sadXQnTns8zTauTd4Bg4=", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2" + } + }, + "@phosphor/domutils": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/domutils/-/domutils-1.1.2.tgz", + "integrity": "sha1-4u/rBS85jEK5O4npurJq8VzABRQ=", + "dev": true + }, + "@phosphor/dragdrop": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@phosphor/dragdrop/-/dragdrop-1.3.0.tgz", + "integrity": "sha1-fOatOdbKIW1ipW94EE0Cp3rmcwc=", + "dev": true, + "requires": { + "@phosphor/coreutils": "^1.3.0", + "@phosphor/disposable": "^1.1.2" + } + }, + "@phosphor/keyboard": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/keyboard/-/keyboard-1.1.2.tgz", + "integrity": "sha1-PjIjRFF2QkCpjhSANNWoeXQi3R8=", + "dev": true + }, + "@phosphor/messaging": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@phosphor/messaging/-/messaging-1.2.2.tgz", + "integrity": "sha1-fYlt3TeXuUo0dwje0T2leD23XBQ=", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2", + "@phosphor/collections": "^1.1.2" + } + }, + "@phosphor/properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/properties/-/properties-1.1.2.tgz", + "integrity": "sha1-eMx37/RSg52gIlXeSOgUlGzAmig=", + "dev": true + }, + "@phosphor/signaling": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@phosphor/signaling/-/signaling-1.2.2.tgz", + "integrity": "sha1-P8+Xyojji/s1f+j+a/dRM0elFKk=", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2" + } + }, + "@phosphor/virtualdom": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@phosphor/virtualdom/-/virtualdom-1.1.2.tgz", + "integrity": "sha1-zlXIbu8x5dDiax3JbqMr1oRFj0E=", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2" + } + }, + "@phosphor/widgets": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@phosphor/widgets/-/widgets-1.6.0.tgz", + "integrity": "sha512-HqVckVF8rJ15ss0Zf/q0AJ69ZKNFOO26qtNKAdGZ9SmmkSMf73X6pB0R3Fj5+Y4Sjl8ezIIKG6mXj+DxOofnwA==", + "dev": true, + "requires": { + "@phosphor/algorithm": "^1.1.2", + "@phosphor/commands": "^1.5.0", + "@phosphor/coreutils": "^1.3.0", + "@phosphor/disposable": "^1.1.2", + "@phosphor/domutils": "^1.1.2", + "@phosphor/dragdrop": "^1.3.0", + "@phosphor/keyboard": "^1.1.2", + "@phosphor/messaging": "^1.2.2", + "@phosphor/properties": "^1.1.2", + "@phosphor/signaling": "^1.2.2", + "@phosphor/virtualdom": "^1.1.2" + } + }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", @@ -319,12 +467,6 @@ "any-observable": "^0.3.0" } }, - "@sindresorhus/is": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", - "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", - "dev": true - }, "@szmarczak/http-timer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.1.tgz", @@ -334,71 +476,18 @@ "defer-to-connect": "^1.0.1" } }, - "@types/configstore": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-2.1.1.tgz", - "integrity": "sha1-zR6FU2M60xhcPy8jns/10mQ+krY=", - "dev": true - }, - "@types/debug": { - "version": "0.0.29", - "resolved": "http://registry.npmjs.org/@types/debug/-/debug-0.0.29.tgz", - "integrity": "sha1-oeUUrfvZLwOiJLpU1pMRHb8fN1Q=", - "dev": true - }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, - "@types/events": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true - }, - "@types/get-port": { - "version": "0.0.4", - "resolved": "http://registry.npmjs.org/@types/get-port/-/get-port-0.0.4.tgz", - "integrity": "sha1-62u3Qj2fiItjJmDcfS/T5po1ZD4=", - "dev": true - }, - "@types/glob": { - "version": "5.0.36", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.36.tgz", - "integrity": "sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/mkdirp": { - "version": "0.3.29", - "resolved": "http://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.3.29.tgz", - "integrity": "sha1-fyrX7FX5FEgvybHsS7GuYCjUYGY=", - "dev": true - }, "@types/node": { "version": "7.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.2.tgz", "integrity": "sha512-RO4ig5taKmcrU4Rex8ojG1gpwFkjddzug9iPQSDvbewHN9vDpcFewevkaOK+KT+w1LeZnxbgOyfXwV4pxsQ4GQ==", "dev": true }, - "@types/tmp": { - "version": "0.0.32", - "resolved": "http://registry.npmjs.org/@types/tmp/-/tmp-0.0.32.tgz", - "integrity": "sha1-DTyzECL4Qn6ljACK8yuA2hJspOM=", - "dev": true - }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -415,23 +504,6 @@ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, - "acorn-dynamic-import": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", - "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", - "dev": true, - "requires": { - "acorn": "^4.0.3" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - }, "ajv": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz", @@ -456,17 +528,6 @@ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", "dev": true }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, "alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", @@ -534,29 +595,6 @@ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, - "arch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", - "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", - "dev": true - }, - "archive-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", - "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", - "dev": true, - "requires": { - "file-type": "^4.2.0" - }, - "dependencies": { - "file-type": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", - "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", - "dev": true - } - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -602,16 +640,6 @@ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", "dev": true }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, "array-map": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", @@ -660,17 +688,6 @@ "safer-buffer": "~2.1.0" } }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "assemblyscript": { "version": "github:AssemblyScript/assemblyscript#c769f65bacd5392e5c9efab112b33244fc0a0c8f", "from": "github:AssemblyScript/assemblyscript#c769f65bacd5392e5c9efab112b33244fc0a0c8f", @@ -682,32 +699,6 @@ "long": "^4.0.0" } }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -751,32 +742,6 @@ "version": "git+https://github.com/torch2424/audiobuffer-to-wav.git#8878a20c5cc7e457b113dabfb1781ad4178f9c62", "from": "git+https://github.com/torch2424/audiobuffer-to-wav.git#es-module-rollup" }, - "autoprefixer": { - "version": "7.2.6", - "resolved": "http://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", - "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", - "dev": true, - "requires": { - "browserslist": "^2.11.3", - "caniuse-lite": "^1.0.30000805", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^6.0.17", - "postcss-value-parser": "^3.2.3" - }, - "dependencies": { - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000792", - "electron-to-chromium": "^1.3.30" - } - } - } - }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -808,86 +773,6 @@ } } }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - } - } - }, "babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", @@ -899,17 +784,6 @@ "babel-types": "^6.24.1" } }, - "babel-helper-builder-react-jsx": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", - "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "esutils": "^2.0.2" - } - }, "babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", @@ -1026,27 +900,6 @@ "babel-types": "^6.24.1" } }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-loader": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.5.tgz", - "integrity": "sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw==", - "dev": true, - "requires": { - "find-cache-dir": "^1.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1" - } - }, "babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", @@ -1075,67 +928,22 @@ "lodash": "^4.17.11" } }, - "babel-plugin-jsx-pragmatic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jsx-pragmatic/-/babel-plugin-jsx-pragmatic-1.0.2.tgz", - "integrity": "sha1-QeK+uGQiNfNLKnqxLKOeByAbjlk=", - "dev": true, - "requires": { - "babel-plugin-syntax-jsx": "^6.0.0" - } - }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", "dev": true }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", - "dev": true - }, - "babel-plugin-syntax-decorators": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", - "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", - "dev": true - }, - "babel-plugin-syntax-dynamic-import": { - "version": "6.18.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", - "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", - "dev": true - }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", "dev": true }, - "babel-plugin-syntax-export-extensions": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", - "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", - "dev": true - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", "dev": true }, "babel-plugin-transform-async-to-generator": { @@ -1149,29 +957,6 @@ "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "dev": true, - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-plugin-syntax-class-properties": "^6.8.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-decorators-legacy": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.5.tgz", - "integrity": "sha512-jYHwjzRXRelYQ1uGm353zNzf3QmtdCfvJbuYTZ4gKveK7M9H1fs3a5AKdY1JUDl0z97E30ukORW1dzhWvsabtA==", - "dev": true, - "requires": { - "babel-plugin-syntax-decorators": "^6.1.18", - "babel-runtime": "^6.2.0", - "babel-template": "^6.3.0" - } - }, "babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", @@ -1417,61 +1202,6 @@ "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-export-extensions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", - "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", - "dev": true, - "requires": { - "babel-plugin-syntax-export-extensions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-assign": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz", - "integrity": "sha1-+Z0vZvGgsNSY40bFNZaEdAyqILo=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", - "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "dev": true, - "requires": { - "babel-plugin-syntax-object-rest-spread": "^6.8.0", - "babel-runtime": "^6.26.0" - } - }, - "babel-plugin-transform-react-constant-elements": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-constant-elements/-/babel-plugin-transform-react-constant-elements-6.23.0.tgz", - "integrity": "sha1-LxGb9NLN1F65uqrldAU8YE9hR90=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", - "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", - "dev": true, - "requires": { - "babel-helper-builder-react-jsx": "^6.24.1", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.21.tgz", - "integrity": "sha512-+gQBtcnEhYFbMPFGr8YL7SHD4BpHifFDGEc+ES0+1iDwC9psist2+eumcLoHjBMumL7N/HI/G64XR5aQC8Nr5Q==", - "dev": true - }, "babel-plugin-transform-regenerator": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", @@ -1529,21 +1259,6 @@ "semver": "^5.3.0" } }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "dev": true, - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -1700,12 +1415,6 @@ } } }, - "base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", - "dev": true - }, "batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", @@ -1733,99 +1442,6 @@ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "dev": true }, - "bin-check": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", - "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "executable": "^4.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, - "bin-version": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.0.0.tgz", - "integrity": "sha512-Ekhwm6AUiMbZ1LgVCNMkgjovpMR30FyQN74laAW9gs0NPjZR5gdY0ARNB0YsQG8GOme3CsHbxmeyq/7Ofq6QYQ==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "find-versions": "^3.0.0" - } - }, - "bin-version-check": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz", - "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==", - "dev": true, - "requires": { - "bin-version": "^3.0.0", - "semver": "^5.6.0", - "semver-truncate": "^1.1.2" - } - }, - "bin-wrapper": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", - "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==", - "dev": true, - "requires": { - "bin-check": "^4.1.0", - "bin-version-check": "^4.0.0", - "download": "^7.1.0", - "import-lazy": "^3.1.0", - "os-filter-obj": "^2.0.0", - "pify": "^4.0.1" - }, - "dependencies": { - "import-lazy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", - "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - } - } - }, "binary-extensions": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", @@ -1838,28 +1454,12 @@ "integrity": "sha512-uZ7bizGTMbEOzIwZmGbXIcGFy8IkZjDoNOy+nPnIv7Dy1MiURItE0PRMnpXO2GPOOq6ZALW8pb5xb9MShD0zQQ==", "dev": true }, - "bl": { - "version": "1.2.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, "bluebird": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", "dev": true }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, "body-parser": { "version": "1.18.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", @@ -1918,12 +1518,6 @@ "multicast-dns-service-types": "^1.1.0" } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", @@ -2009,12 +1603,6 @@ } } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, "browser-detect": { "version": "0.2.28", "resolved": "https://registry.npmjs.org/browser-detect/-/browser-detect-0.2.28.tgz", @@ -2030,85 +1618,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - }, - "dependencies": { - "pako": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz", - "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==", - "dev": true - } - } - }, "browserslist": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", @@ -2119,45 +1628,6 @@ "electron-to-chromium": "^1.3.47" } }, - "buffer": { - "version": "3.6.0", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", - "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", - "dev": true, - "requires": { - "base64-js": "0.0.8", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -2170,24 +1640,12 @@ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, "builtins": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", @@ -2244,72 +1702,6 @@ "unset-value": "^1.0.0" } }, - "cacheable-request": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", - "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", - "dev": true, - "requires": { - "clone-response": "1.0.2", - "get-stream": "3.0.0", - "http-cache-semantics": "3.8.1", - "keyv": "3.0.0", - "lowercase-keys": "1.0.0", - "normalize-url": "2.0.1", - "responselike": "1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "normalize-url": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", - "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", - "dev": true, - "requires": { - "prepend-http": "^2.0.0", - "query-string": "^5.0.1", - "sort-keys": "^2.0.0" - } - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "query-string": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - } - } - }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", @@ -2334,16 +1726,6 @@ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -2409,32 +1791,10 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "caw": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", - "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", - "dev": true, - "requires": { - "get-proxy": "^2.0.0", - "isurl": "^1.0.0-alpha5", - "tunnel-agent": "^0.6.0", - "url-to-options": "^1.0.1" - } - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "chalk": { + "version": "1.1.3", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -2517,6 +1877,12 @@ "upath": "^1.0.5" } }, + "chota": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/chota/-/chota-0.5.2.tgz", + "integrity": "sha512-bW5CB0HBti7QWowNSaVRe7bZzpIslIHCAPc74kerRNJjj/7b19zZmrrOdAxyswepvNMSVLhWjmlLUf5HIICD/w==", + "dev": true + }, "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", @@ -2529,16 +1895,6 @@ "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", "dev": true }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "clap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", @@ -2571,23 +1927,6 @@ } } }, - "clean-css": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, "cli-boxes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", @@ -2603,12 +1942,6 @@ "restore-cursor": "^2.0.0" } }, - "cli-spinners": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", - "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", - "dev": true - }, "cli-truncate": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", @@ -2647,17 +1980,6 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - } - }, "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", @@ -2696,12 +2018,6 @@ "readable-stream": "^2.3.5" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, "coa": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", @@ -2796,12 +2112,6 @@ "delayed-stream": "~1.0.0" } }, - "command-exists": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", - "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==", - "dev": true - }, "commander": { "version": "2.6.0", "resolved": "http://registry.npmjs.org/commander/-/commander-2.6.0.tgz", @@ -2963,16 +2273,6 @@ } } }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", @@ -2993,33 +2293,6 @@ "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", "dev": true }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "console-clear": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", - "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==", - "dev": true - }, - "console-stream": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", - "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -3073,59 +2346,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "copy-webpack-plugin": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz", - "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==", - "dev": true, - "requires": { - "cacache": "^10.0.4", - "find-cache-dir": "^1.0.0", - "globby": "^7.1.1", - "is-glob": "^4.0.0", - "loader-utils": "^1.1.0", - "minimatch": "^3.0.4", - "p-limit": "^1.0.0", - "serialize-javascript": "^1.4.0" - }, - "dependencies": { - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "dir-glob": "^2.0.0", - "glob": "^7.1.2", - "ignore": "^3.3.5", - "pify": "^3.0.0", - "slash": "^1.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - } - } - }, "core-js": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.0.tgz", @@ -3150,16 +2370,6 @@ "parse-json": "^4.0.0" } }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -3169,33 +2379,6 @@ "capture-stack-trace": "^1.0.0" } }, - "create-hash": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3209,47 +2392,6 @@ "which": "^1.2.9" } }, - "cross-spawn-promise": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/cross-spawn-promise/-/cross-spawn-promise-0.10.1.tgz", - "integrity": "sha1-25y0xQxgtyoVvgSbeBIs44LYexA=", - "dev": true, - "requires": { - "cross-spawn": "^5.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, "crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", @@ -3262,57 +2404,6 @@ "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", "dev": true }, - "css-loader": { - "version": "0.28.11", - "resolved": "http://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", - "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==", - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "css-selector-tokenizer": "^0.7.0", - "cssnano": "^3.10.0", - "icss-utils": "^2.1.0", - "loader-utils": "^1.0.2", - "lodash.camelcase": "^4.3.0", - "object-assign": "^4.1.1", - "postcss": "^5.0.6", - "postcss-modules-extract-imports": "^1.2.0", - "postcss-modules-local-by-default": "^1.2.0", - "postcss-modules-scope": "^1.1.0", - "postcss-modules-values": "^1.3.0", - "postcss-value-parser": "^3.3.0", - "source-list-map": "^2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, "css-modules-loader-core": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", @@ -3364,55 +2455,6 @@ } } }, - "css-modules-require-hook": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/css-modules-require-hook/-/css-modules-require-hook-4.2.3.tgz", - "integrity": "sha1-Z5LKQSsV4j5vm+agfc739Xf/kE0=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "generic-names": "^1.0.1", - "glob-to-regexp": "^0.3.0", - "icss-replace-symbols": "^1.0.2", - "lodash": "^4.3.0", - "postcss": "^6.0.1", - "postcss-modules-extract-imports": "^1.0.0", - "postcss-modules-local-by-default": "^1.0.1", - "postcss-modules-resolve-imports": "^1.3.0", - "postcss-modules-scope": "^1.0.0", - "postcss-modules-values": "^1.1.1", - "seekout": "^1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "css-select": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", - "dev": true, - "requires": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" - } - }, "css-selector-tokenizer": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", @@ -3437,12 +2479,6 @@ } } }, - "css-what": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz", - "integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==", - "dev": true - }, "cssesc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", @@ -3567,15 +2603,6 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, - "d": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "^0.10.9" - } - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -3591,12 +2618,6 @@ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", "dev": true }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, "debug": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", @@ -3636,30 +2657,6 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", - "dev": true, - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", @@ -3669,121 +2666,26 @@ "mimic-response": "^1.0.0" } }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - }, - "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - } - } + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "default-gateway": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.7.2.tgz", + "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==", "dev": true, "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - }, - "dependencies": { - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - } - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "dev": true, - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "default-gateway": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.7.2.tgz", - "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==", - "dev": true, - "requires": { - "execa": "^0.10.0", - "ip-regex": "^2.1.0" + "execa": "^0.10.0", + "ip-regex": "^2.1.0" }, "dependencies": { "execa": { @@ -3903,114 +2805,24 @@ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, "detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, - "devcert-san": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/devcert-san/-/devcert-san-0.3.3.tgz", - "integrity": "sha1-qnckR0Gy2DF3HAEfIu4l45atS6k=", - "dev": true, - "requires": { - "@types/configstore": "^2.1.1", - "@types/debug": "^0.0.29", - "@types/get-port": "^0.0.4", - "@types/glob": "^5.0.30", - "@types/mkdirp": "^0.3.29", - "@types/node": "^7.0.11", - "@types/tmp": "^0.0.32", - "command-exists": "^1.2.2", - "configstore": "^3.0.0", - "debug": "^2.6.3", - "eol": "^0.8.1", - "get-port": "^3.0.0", - "glob": "^7.1.1", - "mkdirp": "^0.5.1", - "tmp": "^0.0.31", - "tslib": "^1.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - } - } - }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "path-type": "^3.0.0" - } - }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -4036,73 +2848,6 @@ "buffer-indexof": "^1.0.0" } }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, - "requires": { - "domelementtype": "~1.1.1", - "entities": "~1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true - } - } - }, - "dom-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/dom-urls/-/dom-urls-1.1.0.tgz", - "integrity": "sha1-AB3fgWKM0ecGElxxdvU8zsVdkY4=", - "dev": true, - "requires": { - "urijs": "^1.16.1" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", - "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", @@ -4112,91 +2857,6 @@ "is-obj": "^1.0.0" } }, - "download": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", - "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", - "dev": true, - "requires": { - "archive-type": "^4.0.0", - "caw": "^2.0.1", - "content-disposition": "^0.5.2", - "decompress": "^4.2.0", - "ext-name": "^5.0.0", - "file-type": "^8.1.0", - "filenamify": "^2.0.0", - "get-stream": "^3.0.0", - "got": "^8.3.1", - "make-dir": "^1.2.0", - "p-event": "^2.1.0", - "pify": "^3.0.0" - }, - "dependencies": { - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true - }, - "filenamify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", - "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", - "dev": true, - "requires": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.0", - "trim-repeated": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "got": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", - "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.7.0", - "cacheable-request": "^2.1.1", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "into-stream": "^3.1.0", - "is-retry-allowed": "^1.1.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "mimic-response": "^1.0.0", - "p-cancelable": "^0.4.0", - "p-timeout": "^2.0.1", - "pify": "^3.0.0", - "safe-buffer": "^5.1.1", - "timed-out": "^4.0.1", - "url-parse-lax": "^3.0.0", - "url-to-options": "^1.0.1" - } - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - } - } - } - }, "duplexer": { "version": "0.1.1", "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -4237,42 +2897,6 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, - "ejs-loader": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ejs-loader/-/ejs-loader-0.3.1.tgz", - "integrity": "sha512-bdJHTxBY3uqZ6L5V1WRohf1gr7ousgESpArPVseEQCWCATs+M8BRqxyJWqnFo+h815gTA++g5LyAyqS5OTIfdQ==", - "dev": true, - "requires": { - "loader-utils": "^0.2.7", - "lodash": "^3.6.0" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, "electron-to-chromium": { "version": "1.3.90", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.90.tgz", @@ -4285,21 +2909,6 @@ "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", "dev": true }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -4321,30 +2930,6 @@ "once": "^1.4.0" } }, - "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "object-assign": "^4.0.1", - "tapable": "^0.2.7" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "eol": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/eol/-/eol-0.8.1.tgz", - "integrity": "sha1-3vwyJJkMfspzuzRGGlbPncJHYdA=", - "dev": true - }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", @@ -4387,126 +2972,22 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.46", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz", - "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "1" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-set": "~0.1.5", - "es6-symbol": "~3.1.1", - "event-emitter": "~0.3.5" - } + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, - "es6-promise": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", - "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", - "dev": true - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14", - "es6-iterator": "~2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "~0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.14", - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "^0.1.3", - "es6-weak-map": "^2.0.1", - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "estree-walker": { @@ -4527,47 +3008,12 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", "dev": true }, - "events": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "eventsource": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", - "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", - "dev": true, - "requires": { - "original": ">=0.0.5" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "exec-sh": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", @@ -4592,23 +3038,6 @@ "strip-eof": "^1.0.0" } }, - "executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "requires": { - "pify": "^2.2.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -4768,25 +3197,6 @@ } } }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "requires": { - "mime-db": "^1.28.0" - } - }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "requires": { - "ext-list": "^2.0.0", - "sort-keys-length": "^1.0.0" - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4896,18 +3306,6 @@ } } }, - "extract-text-webpack-plugin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", - "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", - "dev": true, - "requires": { - "async": "^2.4.1", - "loader-utils": "^1.1.0", - "schema-utils": "^0.3.0", - "webpack-sources": "^1.0.1" - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -4941,15 +3339,6 @@ "websocket-driver": ">=0.5.1" } }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -4959,21 +3348,6 @@ "escape-string-regexp": "^1.0.5" } }, - "file-loader": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.11.2.tgz", - "integrity": "sha512-N+uhF3mswIFeziHQjGScJ/yHXYt3DiLBeC+9vWW+WjUBiClMSOlV1YrXQi+7KM2aA3Rn4Bybgv+uXFQbfkzpvg==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2" - } - }, - "file-type": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", - "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==", - "dev": true - }, "filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -5136,24 +3510,6 @@ "locate-path": "^3.0.0" } }, - "find-versions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.0.0.tgz", - "integrity": "sha512-IUvtItVFNmTtKoB0PRfbkR0zR9XMG5rWNO3qI1S8L0zdv+v2gqzM0pAunloxqbqAfT8w7bg8n/5gHzTXte8H5A==", - "dev": true, - "requires": { - "array-uniq": "^2.0.0", - "semver-regex": "^2.0.0" - }, - "dependencies": { - "array-uniq": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.0.0.tgz", - "integrity": "sha512-O3QZEr+3wDj7otzF7PjNGs6CA3qmYMLvt5xGkjY/V0VxS+ovvqVo/5wKM/OVOAyuX4DTh9H31zE/yKtO66hTkg==", - "dev": true - } - } - }, "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", @@ -5259,12 +3615,6 @@ "readable-stream": "^2.0.0" } }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "fs-extra": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", @@ -5276,15 +3626,6 @@ "universalify": "^0.1.0" } }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "requires": { - "minipass": "^2.2.1" - } - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -5297,12 +3638,6 @@ "readable-stream": "1 || 2" } }, - "fs.promised": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fs.promised/-/fs.promised-3.0.0.tgz", - "integrity": "sha1-q3c3n3wa0JOeEmKows7ZP6bDnTs=", - "dev": true - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5879,21 +4214,6 @@ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", "dev": true }, - "get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", - "dev": true - }, - "get-proxy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", - "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", - "dev": true, - "requires": { - "npm-conf": "^1.1.0" - } - }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -5959,16 +4279,6 @@ "integrity": "sha1-+YX+3MCpqledyI16/waNVcxiUaA=", "dev": true }, - "gittar": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/gittar/-/gittar-0.1.1.tgz", - "integrity": "sha1-1pk+phYKhsi3895yKmH3O8meFLQ=", - "dev": true, - "requires": { - "mkdirp": "^0.5.1", - "tar": "^4.4.1" - } - }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -6040,12 +4350,6 @@ } } }, - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, "global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -6143,12 +4447,6 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", @@ -6210,27 +4508,12 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true - }, "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -6269,24 +4552,14 @@ "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=", "dev": true }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "is-stream": "^1.0.1", + "pinkie-promise": "^2.0.0" } }, "he": { @@ -6295,27 +4568,6 @@ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -6346,128 +4598,6 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - } - } - }, - "html-webpack-exclude-assets-plugin": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/html-webpack-exclude-assets-plugin/-/html-webpack-exclude-assets-plugin-0.0.5.tgz", - "integrity": "sha1-Qa9lAD837zM/BE9J5q2opNP4KVk=", - "dev": true - }, - "html-webpack-plugin": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz", - "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", - "dev": true, - "requires": { - "bluebird": "^3.4.7", - "html-minifier": "^3.2.3", - "loader-utils": "^0.2.16", - "lodash": "^4.17.3", - "pretty-error": "^2.0.2", - "toposort": "^1.0.0" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "^3.1.3", - "emojis-list": "^2.0.0", - "json5": "^0.5.0", - "object-assign": "^4.0.1" - } - } - } - }, - "htmlparser2": { - "version": "3.3.0", - "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", - "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", - "dev": true, - "requires": { - "domelementtype": "1", - "domhandler": "2.1", - "domutils": "1.1", - "readable-stream": "1.0" - }, - "dependencies": { - "domutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", - "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", - "dev": true - }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -6503,123 +4633,10 @@ "requires-port": "^1.0.0" } }, - "http-proxy-middleware": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", - "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", - "dev": true, - "requires": { - "http-proxy": "^1.16.2", - "is-glob": "^3.1.0", - "lodash": "^4.17.2", - "micromatch": "^2.3.11" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - } - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - } - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -6627,12 +4644,6 @@ "sshpk": "^1.7.0" } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, "humanize-url": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", @@ -6689,26 +4700,11 @@ "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", "dev": true }, - "icss-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", - "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", - "dev": true, - "requires": { - "postcss": "^6.0.1" - } - }, "idb": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/idb/-/idb-2.1.3.tgz", "integrity": "sha512-1He6QAuavrD38HCiJasi4lEEK87Y22ldFuM+ZHkp433n4Fd5jXjWKutClYFp8w4mgx3zgrjnWxL8dpjMzcQ+WQ==" }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", - "dev": true - }, "iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", @@ -6764,70 +4760,6 @@ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", "dev": true }, - "import-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", - "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", - "dev": true, - "requires": { - "pkg-dir": "^2.0.0", - "resolve-cwd": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6846,12 +4778,6 @@ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -6950,216 +4876,15 @@ } } }, - "internal-ip": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", - "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "meow": "^3.3.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - } + "loose-envify": "^1.0.0" } }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, - "into-stream": { - "version": "3.1.0", - "resolved": "http://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", - "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", - "dev": true, - "requires": { - "from2": "^2.1.1", - "p-is-promise": "^1.1.0" - } - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -7305,15 +5030,6 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -7345,12 +5061,6 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "dev": true - }, "is-npm": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", @@ -7372,12 +5082,6 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true - }, "is-observable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", @@ -7512,12 +5216,6 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -7554,16 +5252,6 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, - "isomorphic-unfetch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-2.1.1.tgz", - "integrity": "sha512-nd8AULy4i2rA8dv0nOBT9xieIegd3xi7NDxTQ9+iNXDTyaG6VbUYW3F+TdMRqxqXhDFWM2k7fttKx9W2Wd8JpQ==", - "dev": true, - "requires": { - "node-fetch": "^2.1.2", - "unfetch": "^3.1.0" - } - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -7576,16 +5264,6 @@ "integrity": "sha512-flaQ/45dMqCYSMzBQI/h3bcto6T70uN7kjNnI8n3gQU6no5p+QcnMWBNXkraED0YvbUymxKaqdvgPa09RZQM5A==", "dev": true }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, "js-base64": { "version": "2.4.9", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz", @@ -7626,12 +5304,6 @@ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", "dev": true }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", - "dev": true - }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -7731,21 +5403,6 @@ "package-json": "^4.0.0" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, "listr": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", @@ -7963,12 +5620,6 @@ "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=", "dev": true }, - "loader-runner": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz", - "integrity": "sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==", - "dev": true - }, "loader-utils": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", @@ -8004,12 +5655,6 @@ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", @@ -8022,37 +5667,12 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, - "lodash.template": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", - "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", - "dev": true, - "requires": { - "lodash._reinterpolate": "~3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", - "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", - "dev": true, - "requires": { - "lodash._reinterpolate": "~3.0.0" - } - }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -8116,28 +5736,6 @@ "wrap-ansi": "^3.0.1" } }, - "logalot": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", - "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=", - "dev": true, - "requires": { - "figures": "^1.3.5", - "squeak": "^1.0.0" - }, - "dependencies": { - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - } - } - }, "loglevel": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", @@ -8150,12 +5748,6 @@ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", "dev": true }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -8175,200 +5767,12 @@ "signal-exit": "^3.0.0" } }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, - "lpad-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", - "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "indent-string": "^2.1.0", - "longest": "^1.0.0", - "meow": "^3.3.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - } - } - }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -8478,32 +5882,12 @@ } } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "media-typer": { "version": "0.3.0", "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -8590,20 +5974,10 @@ "integrity": "sha1-R9x7z2IXG4Aw4hUv2C8SpolKcRk=", "dev": true }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, "mime": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz", - "integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA=", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "mime-db": { @@ -8639,12 +6013,6 @@ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -8670,33 +6038,6 @@ "is-plain-obj": "^1.1.0" } }, - "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true - } - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "dev": true, - "requires": { - "minipass": "^2.2.1" - } - }, "mississippi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", @@ -8765,6 +6106,12 @@ } } }, + "mkpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-1.0.0.tgz", + "integrity": "sha1-67Opd+evHGg65v2hK1Raa6bFhT0=", + "dev": true + }, "mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", @@ -8924,101 +6271,18 @@ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, - "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-fetch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", - "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==", - "dev": true - }, "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", "dev": true }, - "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^1.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.10.3", - "vm-browserify": "0.0.4" - }, - "dependencies": { - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true - }, - "buffer": { - "version": "4.9.1", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -9058,6 +6322,12 @@ "sort-keys": "^1.0.0" } }, + "normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "dev": true + }, "np": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/np/-/np-3.1.0.tgz", @@ -9140,16 +6410,6 @@ } } }, - "npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "dev": true, - "requires": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - } - }, "npm-name": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npm-name/-/npm-name-5.0.1.tgz", @@ -9304,15 +6564,6 @@ "path-key": "^2.0.0" } }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -9374,18 +6625,6 @@ "isobject": "^3.0.0" } }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -9459,49 +6698,6 @@ "is-wsl": "^1.1.0" } }, - "ora": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz", - "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "cli-cursor": "^2.1.0", - "cli-spinners": "^1.0.1", - "log-symbols": "^2.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -9511,99 +6707,24 @@ "url-parse": "^1.4.3" } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-filter-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", - "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", - "dev": true, - "requires": { - "arch": "^2.1.0" - } - }, "os-homedir": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, "os-tmpdir": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "p-cancelable": { - "version": "0.4.1", - "resolved": "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", - "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", - "dev": true - }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, - "p-event": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.1.0.tgz", - "integrity": "sha512-sDEpDVnzLGlJj3k590uUdpfEUySP5yAYlvfTCu5hTDvSTXQVecYWKcEwdO49PrZlnJ5wkfAvtawnno/jyXeqvA==", - "dev": true, - "requires": { - "p-timeout": "^2.0.1" - } - }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -9690,28 +6811,6 @@ "readable-stream": "^2.1.5" } }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parse-asn1": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" - } - }, "parse-glob": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", @@ -9763,12 +6862,6 @@ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true }, - "path-browserify": { - "version": "0.0.0", - "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", - "dev": true - }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", @@ -9805,23 +6898,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", @@ -9831,36 +6907,11 @@ "pify": "^3.0.0" } }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "persist-path": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/persist-path/-/persist-path-1.0.2.tgz", - "integrity": "sha1-t7lHU2W1zPA4qvpVrxKw3YxBjXo=", - "dev": true - }, "pidtree": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", @@ -10362,26 +7413,62 @@ } } }, - "postcss-load-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz", - "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==", + "postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", "dev": true, "requires": { - "cosmiconfig": "^4.0.0", - "import-cwd": "^2.0.0" + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" }, "dependencies": { - "cosmiconfig": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", - "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "is-directory": "^0.3.1", - "js-yaml": "^3.9.0", - "parse-json": "^4.0.0", - "require-from-string": "^2.0.1" + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "postcss": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz", + "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.5.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } } @@ -10470,30 +7557,6 @@ } } }, - "postcss-loader": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz", - "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^6.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^0.4.0" - }, - "dependencies": { - "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, "postcss-merge-idents": { "version": "2.1.7", "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", @@ -10852,15 +7915,6 @@ } } }, - "postcss-modules-extract-imports": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", - "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", - "dev": true, - "requires": { - "postcss": "^6.0.1" - } - }, "postcss-modules-local-by-default": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", @@ -10871,28 +7925,6 @@ "postcss": "^6.0.1" } }, - "postcss-modules-resolve-imports": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/postcss-modules-resolve-imports/-/postcss-modules-resolve-imports-1.3.0.tgz", - "integrity": "sha1-OY0wALla6WlCDN9M2D+oBn8cXq4=", - "dev": true, - "requires": { - "css-selector-tokenizer": "^0.7.0", - "icss-utils": "^3.0.1", - "minimist": "^1.2.0" - }, - "dependencies": { - "icss-utils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-3.0.1.tgz", - "integrity": "sha1-7nDTroysOMa+XtkehRsn7tNDrQ8=", - "dev": true, - "requires": { - "postcss": "^6.0.2" - } - } - } - }, "postcss-modules-scope": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", @@ -11252,515 +8284,44 @@ "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", "dev": true, "requires": { - "has": "^1.0.1", - "postcss": "^5.0.4", - "uniqs": "^2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "postcss": { - "version": "5.2.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "js-base64": "^2.1.9", - "source-map": "^0.5.6", - "supports-color": "^3.2.3" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "preact": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-8.4.2.tgz", - "integrity": "sha512-TsINETWiisfB6RTk0wh3/mvxbGRvx+ljeBccZ4Z6MPFKgu/KFGyf2Bmw3Z/jlXhL5JlNKY6QAbA9PVyzIy9//A==", - "dev": true - }, - "preact-cli": { - "version": "2.2.1", - "resolved": "http://registry.npmjs.org/preact-cli/-/preact-cli-2.2.1.tgz", - "integrity": "sha1-BaMxHom9sSClJzUyx3uHvdcQ4Es=", - "dev": true, - "requires": { - "autoprefixer": "^7.1.0", - "babel-loader": "^7.0.0", - "babel-plugin-jsx-pragmatic": "^1.0.2", - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-decorators-legacy": "^1.3.4", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-plugin-transform-object-assign": "^6.22.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-plugin-transform-react-constant-elements": "^6.23.0", - "babel-plugin-transform-react-jsx": "^6.24.1", - "babel-plugin-transform-react-remove-prop-types": "^0.4.5", - "babel-preset-env": "^1.3.3", - "babel-register": "^6.24.1", - "bluebird": "^3.5.0", - "chalk": "^2.1.0", - "console-clear": "^1.0.0", - "copy-webpack-plugin": "^4.1.0", - "cross-spawn-promise": "^0.10.1", - "css-loader": "^0.28.7", - "css-modules-require-hook": "^4.0.6", - "devcert-san": "^0.3.3", - "ejs-loader": "^0.3.0", - "extract-text-webpack-plugin": "^3.0.0", - "file-loader": "^0.11.1", - "fs.promised": "^3.0.0", - "get-port": "^3.1.0", - "gittar": "^0.1.0", - "glob": "^7.1.2", - "html-webpack-exclude-assets-plugin": "0.0.5", - "html-webpack-plugin": "^2.28.0", - "inquirer": "^3.3.0", - "ip": "^1.1.5", - "isomorphic-unfetch": "^2.0.0", - "json-loader": "^0.5.4", - "loader-utils": "^1.1.0", - "log-symbols": "^2.1.0", - "minimatch": "^3.0.3", - "ora": "^1.2.0", - "persist-path": "^1.0.1", - "postcss-loader": "^2.0.6", - "preact": "^8.1.0", - "preact-compat": "^3.14.3", - "preact-render-to-string": "^3.6.0", - "preact-router": "^2.5.2", - "progress-bar-webpack-plugin": "^1.9.3", - "promise-polyfill": "^6.0.2", - "raw-loader": "^0.5.1", - "require-relative": "^0.8.7", - "rimraf": "^2.6.1", - "script-ext-html-webpack-plugin": "^1.8.0", - "simplehttp2server": "^2.0.0", - "source-map": "^0.5.6", - "stack-trace": "0.0.10", - "style-loader": "^0.18.2", - "sw-precache-webpack-plugin": "^0.11.2", - "tmp": "0.0.31", - "unfetch": "^3.0.0", - "update-notifier": "^2.3.0", - "url-loader": "^0.5.8", - "validate-npm-package-name": "^3.0.0", - "webpack": "^3.7.0", - "webpack-dev-server": "^2.9.0", - "webpack-merge": "^4.1.0", - "webpack-plugin-replace": "^1.1.1", - "which": "^1.2.14", - "yargs": "^8.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "url-loader": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.9.tgz", - "integrity": "sha512-B7QYFyvv+fOBqBVeefsxv6koWWtjmHaMFT6KZWti4KRw8YUD/hOU+3AECvXuzyVawIBx3z7zQRejXCDSO5kk1Q==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "mime": "1.3.x" - } - }, - "webpack-dev-server": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.3.tgz", - "integrity": "sha512-Qz22YEFhWx+M2vvJ+rQppRv39JA0h5NNbOOdODApdX6iZ52Diz7vTPXjF7kJlfn+Uc24Qr48I3SZ9yncQwRycg==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "array-includes": "^3.0.3", - "bonjour": "^3.5.0", - "chokidar": "^2.0.0", - "compression": "^1.5.2", - "connect-history-api-fallback": "^1.3.0", - "debug": "^3.1.0", - "del": "^3.0.0", - "express": "^4.16.2", - "html-entities": "^1.2.0", - "http-proxy-middleware": "~0.17.4", - "import-local": "^1.0.0", - "internal-ip": "1.2.0", - "ip": "^1.1.5", - "killable": "^1.0.0", - "loglevel": "^1.4.1", - "opn": "^5.1.0", - "portfinder": "^1.0.9", - "selfsigned": "^1.9.1", - "serve-index": "^1.7.2", - "sockjs": "0.3.19", - "sockjs-client": "1.1.5", - "spdy": "^3.4.1", - "strip-ansi": "^3.0.0", - "supports-color": "^5.1.0", - "webpack-dev-middleware": "1.12.2", - "yargs": "6.6.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "yargs": { - "version": "6.6.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.2.0" - } - } - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "has": "^1.0.1", + "postcss": "^5.0.4", + "uniqs": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "postcss": { + "version": "5.2.18", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "js-base64": "^2.1.9", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "dev": true, "requires": { - "camelcase": "^3.0.0" + "has-flag": "^1.0.0" } } } }, - "preact-cli-sw-precache": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/preact-cli-sw-precache/-/preact-cli-sw-precache-1.0.3.tgz", - "integrity": "sha512-IDgp/rmrhXXZzL8qIlu+kwM0abMwlHOYpvLyPFIfI+pXo2qZ26l1fWfnmH3tHsgIx9G4eHGAkHJVIjxXVMbu1g==", + "preact": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-8.4.2.tgz", + "integrity": "sha512-TsINETWiisfB6RTk0wh3/mvxbGRvx+ljeBccZ4Z6MPFKgu/KFGyf2Bmw3Z/jlXhL5JlNKY6QAbA9PVyzIy9//A==", "dev": true }, "preact-compat": { @@ -11791,12 +8352,6 @@ "pretty-format": "^3.5.1" } }, - "preact-router": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/preact-router/-/preact-router-2.6.1.tgz", - "integrity": "sha512-Ql3fptQ8hiioIw5zUcWUq5NShl7yFR4e6KBUzLbGI7+HKMIgBnH+aOITN5IrY1rbr2vhKXBdHdd9nLbbjcJTOQ==", - "dev": true - }, "preact-transition-group": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/preact-transition-group/-/preact-transition-group-1.1.1.tgz", @@ -11821,22 +8376,6 @@ "integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==", "dev": true }, - "pretty-bytes": { - "version": "4.0.2", - "resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", - "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", - "dev": true - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", - "dev": true, - "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" - } - }, "pretty-format": { "version": "3.8.0", "resolved": "http://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", @@ -11968,47 +8507,18 @@ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, - "progress": { - "version": "1.1.8", - "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "progress-bar-webpack-plugin": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/progress-bar-webpack-plugin/-/progress-bar-webpack-plugin-1.11.0.tgz", - "integrity": "sha512-XT6r8strD6toU0ZVip25baJINo7uE4BD4H8d4vhOV4GIK5PvNNky8GYJ2wMmVoYP8eo/sSmtNWn0Vw7zWDDE3A==", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "object.assign": "^4.0.1", - "progress": "^1.1.8" - } - }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, - "promise-polyfill": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz", - "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=", - "dev": true - }, "promise.series": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/promise.series/-/promise.series-0.2.0.tgz", @@ -12025,12 +8535,6 @@ "object-assign": "^4.1.1" } }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true - }, "proxy-addr": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", @@ -12059,19 +8563,11 @@ "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", "dev": true }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } + "pubx": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/pubx/-/pubx-0.0.3.tgz", + "integrity": "sha512-NJkVmslxVsjYTBKBA1ufANGBtaTFhmfLhGMiNEAKdtsDR+izbfFEzu2+aXno7MuwdLeVDp8YXjPUUztpgZlhaA==", + "dev": true }, "pump": { "version": "3.0.0", @@ -12134,18 +8630,6 @@ "strict-uri-encode": "^1.0.0" } }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, "querystringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", @@ -12191,25 +8675,6 @@ } } }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -12239,12 +8704,6 @@ } } }, - "raw-loader": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", - "dev": true - }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -12257,6 +8716,23 @@ "strip-json-comments": "~2.0.1" } }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -12496,31 +8972,12 @@ } } }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", "dev": true }, - "renderkid": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.2.tgz", - "integrity": "sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==", - "dev": true, - "requires": { - "css-select": "^1.1.0", - "dom-converter": "~0.2", - "htmlparser2": "~3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" - } - }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -12533,15 +8990,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, "replace-ext": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", @@ -12582,24 +9030,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, - "require-relative": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", - "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -12672,15 +9108,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "^0.1.1" - } - }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -12690,16 +9117,6 @@ "glob": "^7.0.5" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "rollup": { "version": "0.66.6", "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.66.6.tgz", @@ -12776,6 +9193,24 @@ } } }, + "rollup-plugin-delete": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-delete/-/rollup-plugin-delete-0.1.2.tgz", + "integrity": "sha512-WTr9fh2xDIhUkdRQq1XD0uM+/7VzuEdr5Kstj7uPrC1OzmvOt7VHlRNIeZv76fUzrkMAxp/IudiY+WgYqK0xMg==", + "dev": true, + "requires": { + "del": "^3.0.0" + } + }, + "rollup-plugin-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-hash/-/rollup-plugin-hash-1.3.0.tgz", + "integrity": "sha512-a/DUrOlXOqCpwCF+dPXEPDlqbOMkfXDWEWOeVU2bhrW18Dbh0nu2JLLrS3FIiasVrDZhoxhwhSkV/dg15gwPyw==", + "dev": true, + "requires": { + "hasha": "^2.2.0" + } + }, "rollup-plugin-json": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-3.1.0.tgz", @@ -12932,13 +9367,14 @@ } }, "rollup-plugin-url": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-url/-/rollup-plugin-url-1.4.0.tgz", - "integrity": "sha512-e5gXCLwUd7UQ/aVRJb/K8GNgOYHjqIOVGukhhdZVMuTHPslMJIFkiTVjvPbwwS/5SLbMGjfS0219ur5tmhMD0w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-url/-/rollup-plugin-url-2.1.0.tgz", + "integrity": "sha512-qANv7Yf9JiUcOmlUS5j0Woo1tiyyCiBVX7UFZAFImu+1eHrVlkc1LSk+zetOvZ4e8cwhGUIrtGe7wP/dNOCASw==", "dev": true, "requires": { "mime": "^2.3.1", - "rollup-pluginutils": "^2.0.1" + "mkpath": "^1.0.0", + "rollup-pluginutils": "^2.3.3" }, "dependencies": { "mime": { @@ -13122,93 +9558,12 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "^5.0.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - } - } - }, "scoped-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/scoped-regex/-/scoped-regex-1.0.0.tgz", "integrity": "sha1-o0a7Gs1CB65wvXwMfKnlZra63bg=", "dev": true }, - "script-ext-html-webpack-plugin": { - "version": "1.8.8", - "resolved": "https://registry.npmjs.org/script-ext-html-webpack-plugin/-/script-ext-html-webpack-plugin-1.8.8.tgz", - "integrity": "sha512-9mxSrvfX8on97tu4pUfLXQ9StKGxfHKSy3NXsYBi+4EpyhI4oUUhE3KEWUViDiTQHmY7u2ztLT5OfOjQRzmJaQ==", - "dev": true, - "requires": { - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "dev": true, - "requires": { - "commander": "~2.8.1" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - } - } - }, - "seekout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/seekout/-/seekout-1.0.2.tgz", - "integrity": "sha1-CbqfG9W0b7sTRxjrGaaDgsuxuck=", - "dev": true - }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -13245,21 +9600,6 @@ "semver": "^5.0.3" } }, - "semver-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", - "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", - "dev": true - }, - "semver-truncate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", - "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", - "dev": true, - "requires": { - "semver": "^5.3.0" - } - }, "send": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", @@ -13354,12 +9694,6 @@ "send": "0.16.2" } }, - "serviceworker-cache-polyfill": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serviceworker-cache-polyfill/-/serviceworker-cache-polyfill-4.0.0.tgz", - "integrity": "sha1-3hnuc77yGrPAdAo3sz22JGS6ves=", - "dev": true - }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -13389,28 +9723,12 @@ } } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, - "sha.js": { - "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -13444,16 +9762,6 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "simplehttp2server": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/simplehttp2server/-/simplehttp2server-2.0.1.tgz", - "integrity": "sha512-YLmk3emFS4P0upqDOdXlEjeNO2FHQs17UrXnur/NPZguNmQeKTon79/wCFFpJo8auSlrrV5GBX/UgCirBoYzeA==", - "dev": true, - "requires": { - "bin-wrapper": "^4.1.0", - "logalot": "^2.1.0" - } - }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -13573,64 +9881,24 @@ "dev": true } } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } - }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz", - "integrity": "sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM=", - "dev": true, - "requires": { - "debug": "^2.6.6", - "eventsource": "0.1.6", - "faye-websocket": "~0.11.0", - "inherits": "^2.0.1", - "json3": "^3.3.2", - "url-parse": "^1.1.8" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" } }, "sort-keys": { @@ -13642,15 +9910,6 @@ "is-plain-obj": "^1.0.0" } }, - "sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", - "dev": true, - "requires": { - "sort-keys": "^1.0.0" - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -13686,15 +9945,6 @@ "urix": "^0.1.0" } }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", @@ -13832,17 +10082,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "squeak": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", - "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "console-stream": "^0.1.1", - "lpad-align": "^1.0.1" - } - }, "sshpk": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", @@ -13869,12 +10108,6 @@ "safe-buffer": "^5.1.1" } }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, "standalone-react-addons-pure-render-mixin": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/standalone-react-addons-pure-render-mixin/-/standalone-react-addons-pure-render-mixin-0.1.1.tgz", @@ -13917,16 +10150,6 @@ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", "dev": true }, - "stream-browserify": { - "version": "2.0.1", - "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, "stream-buffers": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-1.0.1.tgz", @@ -13943,19 +10166,6 @@ "stream-shift": "^1.0.0" } }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", @@ -14036,15 +10246,6 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "dev": true, - "requires": { - "is-natural-number": "^4.0.1" - } - }, "strip-eof": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -14084,16 +10285,6 @@ "integrity": "sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==", "dev": true }, - "style-loader": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.18.2.tgz", - "integrity": "sha512-WPpJPZGUxWYHWIUMNNOYqql7zh85zGmr84FdTVWq52WTIkqlW9xSxD3QYWi/T31cqn9UNSsietVEgGn2aaSCzw==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "schema-utils": "^0.3.0" - } - }, "supports-color": { "version": "2.0.0", "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -14168,289 +10359,12 @@ } } }, - "sw-precache": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/sw-precache/-/sw-precache-5.2.1.tgz", - "integrity": "sha512-8FAy+BP/FXE+ILfiVTt+GQJ6UEf4CVHD9OfhzH0JX+3zoy2uFk7Vn9EfXASOtVmmIVbL3jE/W8Z66VgPSZcMhw==", - "dev": true, - "requires": { - "dom-urls": "^1.1.0", - "es6-promise": "^4.0.5", - "glob": "^7.1.1", - "lodash.defaults": "^4.2.0", - "lodash.template": "^4.4.0", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "pretty-bytes": "^4.0.2", - "sw-toolbox": "^3.4.0", - "update-notifier": "^2.3.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - } - } - }, - "sw-precache-webpack-plugin": { - "version": "0.11.5", - "resolved": "http://registry.npmjs.org/sw-precache-webpack-plugin/-/sw-precache-webpack-plugin-0.11.5.tgz", - "integrity": "sha512-K6E52DbYyzGNXGyv2LhI2Duomr3t/2FFMmnGdHZ1Ruk3ulFHDMASJtg3WpA3CXlWODZx189tTaOIO5mWkSKyVg==", - "dev": true, - "requires": { - "del": "^3.0.0", - "sw-precache": "^5.2.1", - "uglify-es": "^3.3.9" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "~2.13.0", - "source-map": "~0.6.1" - } - } - } - }, - "sw-toolbox": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/sw-toolbox/-/sw-toolbox-3.6.0.tgz", - "integrity": "sha1-Jt8dHHA0hljk3qKIQxkUm3sxg7U=", - "dev": true, - "requires": { - "path-to-regexp": "^1.0.1", - "serviceworker-cache-polyfill": "^4.0.0" - } - }, "symbol-observable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", "dev": true }, - "tapable": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz", - "integrity": "sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A==", - "dev": true - }, - "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - }, - "dependencies": { - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true - } - } - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - } - }, "temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", @@ -14546,27 +10460,12 @@ "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", "dev": true }, - "time-stamp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.2.0.tgz", - "integrity": "sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA==", - "dev": true - }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, - "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -14576,18 +10475,6 @@ "os-tmpdir": "~1.0.2" } }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -14631,12 +10518,6 @@ "repeat-string": "^1.6.1" } }, - "toposort": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", - "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", - "dev": true - }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -14655,6 +10536,12 @@ } } }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, "tree-kill": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz", @@ -14688,12 +10575,6 @@ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -14731,37 +10612,6 @@ "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", "dev": true }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "dev": true, - "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, "uglifyjs-webpack-plugin": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz", @@ -14812,28 +10662,12 @@ } } }, - "unbzip2-stream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz", - "integrity": "sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==", - "dev": true, - "requires": { - "buffer": "^3.0.1", - "through": "^2.3.6" - } - }, "underscore": { "version": "1.7.0", "resolved": "http://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", "dev": true }, - "unfetch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-3.1.2.tgz", - "integrity": "sha512-L0qrK7ZeAudGiKYw6nzFjnJ2D5WHblUBwmHIqtPS6oKUd+Hcpk7/hKsSmcHsTlpd1TbTNsiRBUKRq3bHLNIqIw==", - "dev": true - }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", @@ -15021,12 +10855,6 @@ } } }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -15036,36 +10864,12 @@ "punycode": "^2.1.0" } }, - "urijs": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz", - "integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==", - "dev": true - }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, "url-loader": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", @@ -15115,39 +10919,18 @@ "prepend-http": "^1.0.1" } }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -15231,15 +11014,6 @@ "source-map": "^0.5.1" } }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } - }, "watch": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz", @@ -15250,17 +11024,6 @@ "minimist": "^1.2.0" } }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, "wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", @@ -15270,122 +11033,6 @@ "minimalistic-assert": "^1.0.0" } }, - "webpack": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", - "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==", - "dev": true, - "requires": { - "acorn": "^5.0.0", - "acorn-dynamic-import": "^2.0.0", - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0", - "async": "^2.1.2", - "enhanced-resolve": "^3.4.0", - "escope": "^3.6.0", - "interpret": "^1.0.0", - "json-loader": "^0.5.4", - "json5": "^0.5.1", - "loader-runner": "^2.3.0", - "loader-utils": "^1.1.0", - "memory-fs": "~0.4.1", - "mkdirp": "~0.5.0", - "node-libs-browser": "^2.0.0", - "source-map": "^0.5.3", - "supports-color": "^4.2.1", - "tapable": "^0.2.7", - "uglifyjs-webpack-plugin": "^0.4.6", - "watchpack": "^1.4.0", - "webpack-sources": "^1.0.1", - "yargs": "^8.0.2" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } - } - }, - "uglifyjs-webpack-plugin": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", - "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", - "dev": true, - "requires": { - "source-map": "^0.5.6", - "uglify-js": "^2.8.29", - "webpack-sources": "^1.0.1" - } - } - } - }, - "webpack-dev-middleware": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", - "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", - "dev": true, - "requires": { - "memory-fs": "~0.4.1", - "mime": "^1.5.0", - "path-is-absolute": "^1.0.0", - "range-parser": "^1.0.3", - "time-stamp": "^2.0.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - } - } - }, "webpack-dev-server": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.10.tgz", @@ -15649,7 +11296,7 @@ "dependencies": { "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { @@ -15692,21 +11339,6 @@ "uuid": "^3.3.2" } }, - "webpack-merge": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.5.tgz", - "integrity": "sha512-sVcM+MMJv6DO0C0GLLltx8mUlGMKXE0zBsuMqZ9jz2X9gsekALw6Rs0cAfTWc97VuWS6NpVUa78959zANnMMLQ==", - "dev": true, - "requires": { - "lodash": "^4.17.5" - } - }, - "webpack-plugin-replace": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/webpack-plugin-replace/-/webpack-plugin-replace-1.1.1.tgz", - "integrity": "sha1-mBZkf+/Jin0XAPk/K0tvSBzyAWE=", - "dev": true - }, "webpack-sources": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", @@ -15771,18 +11403,6 @@ "string-width": "^2.1.1" } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, "worker-farm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", @@ -15866,200 +11486,6 @@ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - }, - "dependencies": { - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, "yargs-parser": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", @@ -16068,16 +11494,6 @@ "requires": { "camelcase": "^4.1.0" } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } } } } diff --git a/package.json b/package.json index 8c0bba93..aa135e05 100644 --- a/package.json +++ b/package.json @@ -66,10 +66,8 @@ "test:performance": "npx run-s build test:performance:nobuild", "test:performance:nobuild": "node --experimental-worker node_modules/mocha/bin/_mocha test/performance/performance-test.js --exit", "debugger:dev": "npm run debugger:watch", - "debugger:watch": "npx preact watch --src demo/debugger", - "debugger:serve": "npx run-s debugger:build debugger:serve:nobuild", - "debugger:serve:nobuild": "npx preact serve", - "debugger:build": "npx preact build -p --src demo/debugger --template demo/template.html --no-prerender", + "debugger:watch": "npx rollup -c -w --environment DEBUGGER,SERVE", + "debugger:build": "npx rollup -c --environment DEBUGGER", "benchmark:build": "npx rollup -c --environment PROD,TS,BENCHMARK", "benchmark:build:skiplib": "npx rollup -c --environment PROD,TS,BENCHMARK,SKIP_LIB", "benchmark:dev": "npm run benchmark:watch", @@ -79,8 +77,7 @@ "amp:dev": "npm run amp:watch", "amp:watch": "npx rollup -c -w --environment TS,AMP,SERVE", "demo:build": "npx run-s core:build lib:build demo:build:apps", - "demo:build:apps": "npx run-s debugger:build benchmark:build:skiplib amp:build:skiplib demo:build:manifest", - "demo:build:manifest": "cp demo/manifest.json build/", + "demo:build:apps": "npx run-s debugger:build benchmark:build:skiplib amp:build:skiplib", "demo:cname": "echo 'wasmboy.app' > build/CNAME", "demo:dist": "cp -r dist/ build/dist", "demo:gh-pages": "npx gh-pages -d build", @@ -101,8 +98,13 @@ "@ampproject/rollup-plugin-closure-compiler": "^0.7.2", "@babel/core": "^7.1.2", "@babel/plugin-proposal-class-properties": "^7.1.0", + "@babel/plugin-proposal-export-default-from": "^7.2.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", "@babel/plugin-transform-react-jsx": "^7.0.0", + "@phosphor/commands": "^1.6.1", + "@phosphor/default-theme": "^0.1.0", + "@phosphor/messaging": "^1.2.2", + "@phosphor/widgets": "^1.6.0", "assemblyscript": "github:AssemblyScript/assemblyscript#c769f65bacd5392e5c9efab112b33244fc0a0c8f", "babel-plugin-filter-imports": "^2.0.3", "babel-preset-env": "^1.6.1", @@ -111,6 +113,7 @@ "bulma": "^0.7.1", "chart.js": "^2.7.3", "chartjs-plugin-downsample": "^1.0.2", + "chota": "^0.5.2", "concurrently": "^3.5.1", "gh-pages": "^1.1.0", "husky": "^1.0.0-rc.8", @@ -118,32 +121,36 @@ "markdown-table": "^1.1.1", "microseconds": "^0.1.0", "mocha": "^5.0.1", + "normalize.css": "^8.0.1", "np": "^3.1.0", "npm-run-all": "^4.1.5", "performance-now": "^2.1.0", "pngjs-image": "^0.11.7", + "postcss-import": "^12.0.1", "preact": "^8.2.1", - "preact-cli": "^2.2.1", - "preact-cli-sw-precache": "^1.0.3", "preact-compat": "^3.17.0", "preact-portal": "^1.1.3", "prettier": "^1.12.1", "pretty-quick": "^1.6.0", + "pubx": "0.0.3", "recursive-readdir-sync": "^1.0.6", "rollup": "^0.66.1", "rollup-plugin-babel": "^4.0.3", "rollup-plugin-bundle-size": "^1.0.2", "rollup-plugin-commonjs": "^9.2.0", "rollup-plugin-copy-glob": "^0.2.2", + "rollup-plugin-delete": "^0.1.2", + "rollup-plugin-hash": "^1.3.0", "rollup-plugin-json": "^3.1.0", "rollup-plugin-node-resolve": "^3.4.0", "rollup-plugin-postcss": "^1.6.2", "rollup-plugin-replace": "^2.1.0", "rollup-plugin-serve": "^0.6.0", "rollup-plugin-typescript": "^1.0.0", - "rollup-plugin-url": "^1.4.0", + "rollup-plugin-url": "^2.1.0", "source-map-loader": "^0.2.4", "stats-lite": "^2.2.0", + "traverse": "^0.6.6", "tslib": "^1.9.3", "typescript": "^3.1.3", "uglifyjs-webpack-plugin": "^1.2.3", diff --git a/preact.config.js b/preact.config.js deleted file mode 100644 index 8ede8ee5..00000000 --- a/preact.config.js +++ /dev/null @@ -1,85 +0,0 @@ -const preactCliSwPrecachePlugin = require('preact-cli-sw-precache'); - -/** - * Function that mutates original webpack config. - * Supports asynchronous changes when promise is returned. - * - * @param {object} config - original webpack config. - * @param {object} env - options passed to CLI. - * @param {WebpackConfigHelpers} helpers - object with useful helpers when working with config. - **/ -export default function(config, env, helpers) { - if (env.production) { - // https://stackoverflow.com/questions/45870467/error-in-bundle-js-from-uglifyjs-name-expected - const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); - - // Remove the other uglify JS plugin - let uglifyIndex = -1; - config.plugins.some((plugin, index) => { - if (plugin.options && plugin.options.mangle) { - uglifyIndex = index; - return true; - } - return false; - }); - - if (uglifyIndex >= 0) { - config.plugins.splice(uglifyIndex, 1); - config.plugins.push(new UglifyJSPlugin()); - } - - // Also, change our outpout directory - // serving on github pages, so: wasmBoy/ - // https://github.com/developit/preact-cli/issues/218 - // https://github.com/developit/preact-cli/pull/323 - config.output.publicPath = '/'; - } else { - // Add a loader for sourcemaps - config.module.loaders.push({ - loader: 'source-map-loader', - test: /\.js$/, - enforce: 'pre' - }); - } - - // Add a loader for gb files - // using url-loader - config.module.loaders.push({ - loader: 'url-loader', - test: /\.gb$/, - options: { - limit: 100 * 1024, - mimetype: 'application/octet-stream' - } - }); - config.resolve.extensions.push('.gb'); - config.module.loaders.push({ - loader: 'url-loader', - test: /\.gbc$/, - options: { - limit: 100 * 1024, - mimetype: 'application/octet-stream' - } - }); - config.resolve.extensions.push('.gbc'); - config.module.loaders.push({ - loader: 'url-loader', - test: /\.png$/, - options: { - limit: 100 * 1024, - mimetype: 'image/png' - } - }); - config.resolve.extensions.push('.png'); - - // Fix our manifest.json - let { plugin } = helpers.getPluginsByName(config, 'HtmlWebpackPlugin')[0] || {}; - if (plugin) { - plugin.options.title = 'WasmBoy'; - plugin.options.manifest = require('./demo/manifest.json'); - } - - return preactCliSwPrecachePlugin(config, { - navigateFallback: '' - }); -} diff --git a/rollup.benchmark.js b/rollup.benchmark.js index 1ed38356..caaa8733 100644 --- a/rollup.benchmark.js +++ b/rollup.benchmark.js @@ -3,6 +3,7 @@ import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; import babel from 'rollup-plugin-babel'; +import compiler from '@ampproject/rollup-plugin-closure-compiler'; import url from 'rollup-plugin-url'; import json from 'rollup-plugin-json'; import serve from 'rollup-plugin-serve'; @@ -16,7 +17,8 @@ const babelPluginConfig = { plugins: [ ['@babel/plugin-proposal-class-properties'], ['@babel/plugin-proposal-object-rest-spread'], - ['@babel/plugin-transform-react-jsx', { pragma: 'h' }] + ['@babel/plugin-transform-react-jsx', { pragma: 'h' }], + ['@babel/plugin-proposal-export-default-from'] ] }; @@ -62,7 +64,8 @@ if (process.env.BENCHMARK && process.env.SERVE) { files: 'demo/benchmark/index.html', dest: 'build/benchmark/' } - ]) + ]), + compiler() ]; } diff --git a/rollup.config.js b/rollup.config.js index 76d5b4dd..c1dbc168 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -3,6 +3,7 @@ import libBundles from './rollup.lib'; import workerBundles from './rollup.worker'; import coreTsBundles from './rollup.core'; import getCoreBundles from './rollup.getcore'; +import debuggerBundles from './rollup.debugger'; import benchmarkBundles from './rollup.benchmark'; import ampBundles from './rollup.amp'; @@ -17,6 +18,10 @@ if (!process.env.SKIP_LIB) { } } +if (process.env.DEBUGGER) { + exports = [...exports, ...debuggerBundles]; +} + if (process.env.BENCHMARK) { exports = [...exports, ...benchmarkBundles]; } diff --git a/rollup.debugger.js b/rollup.debugger.js new file mode 100644 index 00000000..64741e73 --- /dev/null +++ b/rollup.debugger.js @@ -0,0 +1,126 @@ +// Bundle for the debugger app + +import resolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; +import babel from 'rollup-plugin-babel'; +import compiler from '@ampproject/rollup-plugin-closure-compiler'; +import url from 'rollup-plugin-url'; +import json from 'rollup-plugin-json'; +import serve from 'rollup-plugin-serve'; +import replace from 'rollup-plugin-replace'; +import bundleSize from 'rollup-plugin-bundle-size'; +import postcss from 'rollup-plugin-postcss'; +import postcssImport from 'postcss-import'; +import copy from 'rollup-plugin-copy-glob'; +import del from 'rollup-plugin-delete'; +import hash from 'rollup-plugin-hash'; +import pkg from './package.json'; + +const fs = require('fs'); + +const writeIndexHtmlToBuild = bundleName => { + let indexHtml = fs.readFileSync('demo/debugger/index.html', 'utf8'); + indexHtml = indexHtml.replace('<%BUNDLE%>', bundleName.replace('build/', '')); + fs.writeFileSync('build/index.html', indexHtml, 'utf8'); +}; + +const babelPluginConfig = { + exclude: ['node_modules/**'], + plugins: [ + ['@babel/plugin-proposal-class-properties'], + ['@babel/plugin-proposal-object-rest-spread'], + ['@babel/plugin-transform-react-jsx', { pragma: 'h' }], + ['@babel/plugin-proposal-export-default-from'] + ] +}; + +let plugins = [ + postcss({ + extensions: ['.css'], + plugins: [postcssImport()] + }), + resolve({ + preferBuiltins: false + }), + babel(babelPluginConfig), + commonjs(), + json(), + url({ + limit: 0, // Always emit file + include: ['**/*.gb', '**/*.gbc', '**/*.png', '**/*.jpg'], + emitFiles: true + }) +]; + +let sourcemap = false; +if (process.env.DEBUGGER && process.env.SERVE) { + plugins = [ + ...plugins, + replace({ + delimiters: ['', ''], + values: { + '/*ROLLUP_REPLACE_DEBUGGER_DEV': '', + 'ROLLUP_REPLACE_DEBUGGER_DEV*/': '' + } + }), + serve({ + contentBase: ['dist/', 'build/', 'demo/debugger/'], + port: 8080 + }) + ]; + writeIndexHtmlToBuild('index.iife.js'); + sourcemap = 'inline'; +} else { + // Using whitespace only closure as, + // It will mangle preact nodeNames, which is used + // For restoring debugger layout + plugins = [ + ...plugins, + compiler({ + compilation_level: 'WHITESPACE_ONLY' + }), + copy([ + { + files: 'demo/debugger/assets/**/*', + dest: 'build/assets' + }, + { + files: 'demo/debugger/manifest.json', + dest: 'build/' + } + ]), + del({ + targets: ['build/bundle.*.js'] + }), + hash({ + dest: 'build/bundle.[hash].js', + callback: bundleName => { + writeIndexHtmlToBuild(bundleName); + } + }) + ]; +} + +plugins = [...plugins, bundleSize()]; + +// Had to hack around crypto for phosphor +// https://github.com/phosphorjs/phosphor/issues/353 +const debuggerBundles = [ + { + input: 'demo/debugger/index.js', + output: { + name: 'WasmBoyBenchmark', + file: 'build/index.iife.js', + format: 'iife', + globals: { + crypto: 'crypto' + }, + sourcemap: sourcemap + }, + external: ['crypto'], + context: 'window', + plugins: plugins + } +]; + +export default debuggerBundles; diff --git a/rollup.lib.js b/rollup.lib.js index c8b9d78d..6ef0fb68 100644 --- a/rollup.lib.js +++ b/rollup.lib.js @@ -11,6 +11,9 @@ import compiler from '@ampproject/rollup-plugin-closure-compiler'; import bundleSize from 'rollup-plugin-bundle-size'; import pkg from './package.json'; +// For Worker URL Loading +const path = require('path'); + // Our final bundles we are generating for the lib const libBundles = []; @@ -78,6 +81,22 @@ const replaceBrowserOptions = { } }; +const replaceProdBrowserOptions = { + delimiters: ['', ''], + values: { + '/*ROLLUP_REPLACE_PROD_BROWSER': '', + 'ROLLUP_REPLACE_PROD_BROWSER*/': '' + } +}; + +const replaceDevBrowserOptions = { + delimiters: ['', ''], + values: { + '/*ROLLUP_REPLACE_DEV_BROWSER': '', + 'ROLLUP_REPLACE_DEV_BROWSER*/': '' + } +}; + const babelPluginConfig = { // so Rollup can convert unsupported es6 code to es5 exclude: ['node_modules/**'], @@ -100,6 +119,12 @@ baseLibBundles.forEach(baseLibBundle => { // Determine our replacements if (baseLibBundle.output.format !== 'cjs') { plugins.push(replace(replaceBrowserOptions)); + + if (process.env.PROD) { + plugins.push(replace(replaceProdBrowserOptions)); + } else { + plugins.push(replace(replaceDevBrowserOptions)); + } } else { plugins.push(replace(replaceNodeOptions)); } @@ -109,12 +134,22 @@ baseLibBundles.forEach(baseLibBundle => { ...plugins, resolve(), // so Rollup can find node modules commonjs(), - json(), + json() + ]; + + // For Sourcemapping, only url encode workers if we are building for PROD + // Using fileName key, to simply point to our workers in dist + let workerUrlLimit = 0; // Always URL + if (process.env.PROD) { + workerUrlLimit = 1000000 * 1024; // Always inline + } + plugins = [ + ...plugins, url({ - limit: 1000000 * 1024, // Always inline + limit: workerUrlLimit, include: ['**/*.worker.js'], - // Don't emit files, this will replace the worker build output - emitFiles: false + emitFiles: false, + fileName: 'worker/[name][extname]' }) ];