├── .gitignore ├── LICENSE ├── README.md ├── assets ├── icons │ ├── icon-1024x1024.png │ ├── icon-1024x1024.psd │ ├── icon-1024x1024.svg │ ├── icon-1024x1024.xd │ ├── metronome.icns │ ├── metronome.ico │ ├── metronome.iconset │ │ ├── icon_1024x1024.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_32x32.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ ├── icon_512x512@2x.png │ │ └── icon_64x64.png │ └── metronome.svg ├── img │ ├── chrome-screenshot.jpg │ ├── inno-setup.jpg │ ├── installer-windows.jpg │ ├── linux-terminal.jpg │ ├── mac-disk-utility.jpg │ ├── mac-installer.jpg │ ├── mac-screenshot.jpg │ ├── metronome-screen.gif │ ├── nwjs-download.jpg │ ├── nwjs-home.gif │ ├── nwjs-logo.jpg │ ├── resource-hacker.jpg │ ├── ubuntu-screenshot.jpg │ └── windows-screenshot.jpg ├── linux │ ├── control │ └── metronome.desktop └── mac │ └── mac-installer-background.jpg ├── index.js ├── package.json ├── src ├── css │ └── style.css ├── favicon.ico ├── fonts │ └── icons │ │ ├── LICENSE.txt │ │ ├── README.txt │ │ ├── config.json │ │ ├── css │ │ ├── animation.css │ │ ├── settings-codes.css │ │ ├── settings-embedded.css │ │ ├── settings-ie7-codes.css │ │ ├── settings-ie7.css │ │ └── settings.css │ │ ├── demo.html │ │ └── font │ │ ├── settings.eot │ │ ├── settings.svg │ │ ├── settings.ttf │ │ ├── settings.woff │ │ └── settings.woff2 ├── img │ └── icon.png ├── index.html ├── js │ ├── app.js │ └── timebase.js └── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Wouter Hisschemöller 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaScript desktop programs with NW.js 2 | 3 | This is an overview and tutorial of how to create desktop programs for Linux, Mac and Windows using NW.js. 4 | 5 | ![NW.js logo](assets/img/nwjs-logo.jpg 'NW.js logo') 6 | 7 | (Update december 2020: This guide still works with NW.js v50.1 on Mac OS v10.15 (Catalina), Ubuntu v20.04.1 LTS and Windows 10 Pro v1709) 8 | 9 | [NW.js](https://nwjs.io/) is a framework for building desktop applications with HTML, CSS, and JavaScript. It works by combining a JavaScript app with [Node.js](https://nodejs.org) and Google's [Chromium](https://www.chromium.org) browser engine into a single desktop program. 10 | 11 | I'm a frontend developer with little experience in creating desktop applications and installers, so it took me some time find all the details of how to set everything up. This tutorial is an overview of my findings. I hope it can help you to get started using NW.js and to create desktop programs and installers. I've written this tutorial using MacOS 10.14 (Mojave), Ubuntu 18.04 and Windows 10. 12 | 13 | ### NW.js instead or Electron 14 | 15 | [Electron](https://electronjs.org) is the better known of the frameworks for creating native applications. I also found it easier to use. My app however relies on `requestAnimationFrame` for timing, and I couldn't use Electron because of an [issue in Chromium](https://github.com/electron/electron/issues/9567) (the timer stops when the app window is hidden). In the end however NW.js is not that hard to use. 16 | 17 | ### The 'Metronome' project 18 | 19 | ![Metronome icon](assets/icons/metronome.iconset/icon_256x256.png 'Metronome icon') 20 | 21 | The app for this tutorial is a simple metronome. Useful for for musical timekeeping. It uses `requestAnimationFrame` and it generates sound, so it will be easy to demonstrate that with NW.js the `requestAnimationFrame` timer will keep going even if the app's window is hidden behind others. See a demo of the app here: https://hisschemoller.github.io/nwjs-tutorial/src/. 22 | 23 | ### Tutorial overview 24 | 25 | There's quite a lot to go through, so here's an overview of what's included in this tutorial: 26 | 27 | - [Project setup to run it in the browser](#setup-app) 28 | - [Run NW.js directly from the command line](#setup-nw) 29 | - [Create a Mac desktop program (.app file)](#mac-program) 30 | - [Create a Linux desktop program](#linux-program) 31 | - [Create a Windows desktop program (.exe file)](#windows-program) 32 | - [Create a Mac installer (.dmg file)](#mac-installer) 33 | - [Create a Linux installer (.deb file)](#linux-installer) 34 | - [Create a Windows installer (.exe file)](#windows-installer) 35 | 36 | 37 | ## Project setup to run the app in the browser 38 | 39 | Clone the Git repository for the tutorial at https://github.com/hisschemoller/nwjs-tutorial. 40 | 41 | Install the dependencies as usual and start as defined in `package.json`. 42 | 43 | ```bash 44 | yarn install 45 | yarn start 46 | ``` 47 | 48 | The app will now be available at http://localhost:3000 49 | 50 | ![Metronome app](assets/img/chrome-screenshot.jpg 'Metronome app') 51 | 52 | Open the URL in a browser and you'll see a small counter display. Click the Play button. The counter increases and a short blip sounds at each counter increase. 53 | 54 | Note that the metronome stops if you switch to another browser tab, or if the browser is completely hidden by other windows. 55 | 56 | ## Run NW.js directly from the command line 57 | 58 | During development an app can easily be tested within the NW framework from the command line. To set this up requires just a few steps: 59 | 60 | - Add the NW package as a dependency using NPM 61 | - Create a manifest file 62 | - Run the app in the NW framework 63 | 64 | ### Add the NW package as a dependency using NPM 65 | 66 | Two flavors of NW exist: For development purposes there's an SDK version which contains the Chrome developer tools. The regular version lacks the developer tools and because of that results in a smaller file size. To use the SDK version add `-sdk` to the version string. 67 | 68 | Add NW as a devDependency in `package.json`. 69 | 70 | ```json 71 | "devDependencies": { 72 | 73 | "nw": "0.38.0-sdk" 74 | } 75 | ``` 76 | 77 | ### Create a manifest file 78 | 79 | NW needs a manifest file to run. The manifest file is a JSON file called `package.json`. So confusingly it's named exactly the same as NPM's `package.json`. The difference however is that the manifest file is located in the same directory as the app's source files, while NPM's `package.json` is at the root of the project. 80 | 81 | ``` 82 | +-- nwjs-tutorial 83 | | +-- package.json (NPM) 84 | | +-- src 85 | | | +-- index.html 86 | | | +-- package.json (NW manifest file) 87 | ``` 88 | 89 | As a bare minimum the manifest just needs the fields `name` and `main` for NW to run. The `main` field points NW to the app's entry point, which in this case is `index.html`. 90 | 91 | A lot more settings are possible however. a reference of all available options can be found at http://docs.nwjs.io/en/latest/References/Manifest%20Format/ 92 | 93 | This is the manifest for the Metronome app: 94 | 95 | ```json 96 | { 97 | "name": "Metronome_manifest_name", 98 | "description": "A metronome app to keep time.", 99 | "main": "index.html", 100 | "chromium-args": "--disable-raf-throttling", 101 | "window": { 102 | "icon": "img/icon.png", 103 | "height": 240, 104 | "resizable": false, 105 | "width": 400, 106 | "title": "Metronome_manifest_window_title" 107 | } 108 | } 109 | ``` 110 | 111 | ### Run the app in the NW framework 112 | 113 | I've added a script in `package.json` to run NW, but it could as easily be started by just typing `yarn nw` in the command line. 114 | 115 | ```json 116 | "scripts": { 117 | 118 | "start-nw": "nw --disable-raf-throttling" 119 | }, 120 | ``` 121 | 122 | Once started, NW looks for the `"main"` field in `package.json` to find the app's entry point, and looks for the manifest file in the same directory as the entry point. It then has all the data it needs to run the app. 123 | 124 | Try running NW with and without the `--disable-raf-throttling` command line option and notice that with the option the metronome keeps running when the app is hidden. 125 | 126 | ## Creating a desktop program with NW.js 127 | 128 | To create a desktop program a build of NW can be downloaded from the nwjs.io download page at https://nwjs.io/downloads/. Builds are available in different flavors, for Mac, Linux and Windows, 32 or 64 bit, with or without the SDK option. 129 | 130 | ![NW.js download page](assets/img/nwjs-download.jpg 'NW.js download page') 131 | 132 | In general to create a desktop program you will add the project's source files to the downloaded NW build, and the resulting package is the program to distribute. There are differences however between Mac, Linux and Windows. NW.js has it's own documentation [here](http://docs.nwjs.io/en/latest/For%20Users/Package%20and%20Distribute/). 133 | 134 | ## Create a Mac desktop program (.app file) 135 | 136 | 1. Download a Mac release from https://nwjs.io/downloads/ and unzip the download. The unzipped folder contains the file `nwjs.app` (among others). 137 | 2. Package all the files from the project's `/src` directory into a zip file and rename the zip to `app.nw`. So, to be clear, the file extension will be `.nw` instead of `.zip`, and it will contain `index.html`, the `css`, `js` and `fonts` directories and the `package.json` manifest file. 138 | 3. Put `app.nw` inside the downloaded Mac release, in the `nwjs.app/Contents/Resources/` directory. (right click on nwjs.app and choose 'Show Package Contents' to open it) 139 | 4. To add the app icons, rename `/assets/icons/metronome.icns` to `app.icns` and paste it into `nwjs.app/Contents/Resources/`. The file must replace the existing default icons. See below to create an `.icns` file. 140 | 5. Also overwrite `nwjs.app/Contents/Resources/documents.icns` with the `.icns` file. 141 | 6. Open `nwjs.app/Contents/Info.plist` in an text editor. Overwrite the values for `CFBundleDisplayName` and `CFBundleName` as in the example below. 142 | 143 | ```xml 144 | CFBundleDisplayName 145 | Metronome 146 | 147 | CFBundleName 148 | Metronome 149 | ``` 150 | 151 | 152 | ![Mac screenshot](assets/img/mac-screenshot.jpg 'Mac screenshot') 153 | 154 | The file `nwjs.app` is now an executable that runs the app. It's the only file you need, you can delete all the other files in the download. Rename the file to Metronome.app. Double click to run it. 155 | 156 | ### Mac .icns file 157 | 158 | On a Mac you can create an `.icns` file with the `iconutil` command line utility. Here are two tutorials: 159 | 160 | 1. https://retifrav.github.io/blog/2018/10/09/macos-convert-png-to-icns/ 161 | 2. https://elliotekj.com/2014/05/27/how-to-create-high-resolution-icns-files/ 162 | 163 | On MacOS Mojave I created the icon files as described in the first tutorial and ran `iconutil` as described in the second one. That worked. A general overview of the steps: 164 | 165 | 1. Create all the required `png` images. (For this tutorial they're in `/assets/icons/metronome.iconset`). 166 | 2. Put all files in a folder and rename the folder so the name ends with `.iconset`. In this case `metronome.iconset`. 167 | 3. Start Terminal and `cd` to the directory where the `.iconset` is. 168 | 4. Run `iconutil` to generate the `.icns` file, like this: 169 | 170 | ```bash 171 | iconutil -c icns metronome.iconset 172 | ``` 173 | 174 | 175 | 176 | ## Create a Linux desktop program 177 | 178 | I have tested this on Ubuntu 18.04, but I don't know in how far the process is different in other Linux distributions. 179 | 180 | 1. Download a Linux 32 or 64 bit release from https://nwjs.io/downloads/ and unzip the download. 181 | 2. Copy all files in the `/src` directory of the project into the root directory on the downloaded package. In my case it's called `nwjs-sdk-v0.38.0-linux-x64`. So your source files and `package.json` manifest file will share the same directory with the `nw` file in the download. 182 | 3. Copy the `/metronome.desktop` file to the same root directory as the source files and manifest. See below for creating a `.desktop` file. 183 | 184 | ### Linux .desktop file 185 | 186 | In GNOME and other freedesktop.org-compliant desktops, an application gets registered into the desktop's menus through a desktop entry, which is a text file with .desktop extension. This desktop file contains a listing of the configurations for your program. 187 | 188 | - The file should have a unique descriptive filename without spaces. For this project I use `metronone.desktop`. 189 | - The location should be: 190 | - `/usr/share/applications directory` to be accessible by everyone or 191 | - `/.local/share/applications` to be accessible to a single user. 192 | 193 | Desktop file resources: 194 | 195 | - https://wiki.archlinux.org/index.php/Desktop_entries 196 | - https://developer.gnome.org/integration-guide/stable/desktop-files.html.en 197 | - https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html 198 | 199 | ### Manually install on Linux 200 | 201 | Download a Linux package and copy the source files, manifest and icon file as in the steps of 'Create a Linux desktop program' above. 202 | 203 | 1. Rename the package to metronome. 204 | 2. Copy the package to the `/opt` directory. 205 | 3. Copy the `metronome.desktop` file to `/usr/share/applications`. 206 | 207 | To copy to the source files directory and the desktop file use the `cp` command with administrator rights in a terminal: 208 | 209 | ```bash 210 | $ sudo cp -r /path/to/metronome /opt 211 | $ sudo cp /path/to/metronome.desktop /usr/share/applications 212 | ``` 213 | 214 | ![Ubuntu screenshot](assets/img/ubuntu-screenshot.jpg 'Ubuntu screenshot') 215 | 216 | You will now be able to find and run the app just like any program you've installed. No restart or anything needed. 217 | 218 | ## Create a Windows desktop program (.exe file) 219 | 220 | 1. Download a Windows 32 or 64 bit release from https://nwjs.io/downloads/ and unzip the download. 221 | 2. Copy all files in the `/src` directory of the project into the root directory on the downloaded package. Your source files and `package.json` manifest file should be in the same directory as the `nw.exe` file. 222 | 3. The icon for nw.exe can be replaced with tools like Resource Hacker, nw-builder and node-winresourcer. (See below for Resource Hacker instructions.) 223 | 224 | ![Windows screenshot](assets/img/windows-screenshot.jpg 'Windows screenshot') 225 | 226 | Double click nw.exe to run the app. 227 | 228 | ### Change the program's icon with Resource Hacker 229 | 230 | Windows uses icons of the `.ico` file type. Online converters exist that can generate an `.ico` file from another image type. For example ICOConvert at https://icoconvert.com/. 231 | 232 | 1. Download Resource Hacker from http://angusj.com/resourcehacker/ and install. 233 | 2. Start the Resource Hacker program. 234 | 3. Select File > Open... and select the nw.exe 235 | 4. In the left pane right-click the Icon folder and select Replace Icon... 236 | 5. Click 'Open file with new icon...' and select the assets/icons/metronome.ico file. 237 | 6. In the right pane select the icon to be replaced, usually the top one in the list. 238 | 7. Click the Replace button. 239 | 8. Click File > Save to save the executable with the new icon. (Save as.. results in an executable that can't be opened, is my experience) 240 | 9. Rename nw.exe to 'metronome.exe'. 241 | 242 | ![Resource Hacker](assets/img/resource-hacker.jpg 'Resource Hacker') 243 | 244 | More about Resource Hacker: 245 | 246 | - http://angusj.com/resourcehacker/ 247 | - https://www.howtogeek.com/75983/stupid-geek-tricks-how-to-modify-the-icon-of-an-.exe-file/ 248 | 249 | ## Installers 250 | 251 | ## Create a Mac installer (.dmg file) 252 | 253 | I've divided this section into two parts. The first is to create a reusable nice looking template for the installer that shows the app and a shortcut to `Applications` so users can easily add the app to the `Applications` directory. 254 | 255 | The second part is the creation of the actual installer. 256 | 257 | ### Create a template 258 | 259 | ![Mac Disk Utility](assets/img/mac-disk-utility.jpg 'Mac Disk Utility') 260 | 261 | 1. Start Disk Utility. 262 | 2. Go to File > New Image > Blank Image... 263 | 3. Set the file name of the the image to `installerTemplate.dmg`. 264 | 4. Name the image 'metronome-installer'. 265 | 5. Select a size that's enough for the size of the app, 320MB. 266 | 6. Leave the other fields as they are. 267 | 7. Choose a destination folder where to save the installer. 268 | 8. Click 'Save' to create the dmg file. 269 | 270 | That’s it for creating the template file. Now open the template and make it look nice: 271 | 272 | 1. Double click `installerTemplate.dmg` to open it. It will show up in finder as a device. 273 | 2. In the Finder menu choose View > Show View Options. 274 | 3. Customize the look of the folder. Set it to Icon View, larger icons etc. 275 | 4. Copy `metronome.app` file into the folder. 276 | 5. Copy a shortcut to `Applications` into the folder. 277 | 6. Organize the icons within the folder. 278 | 7. Optionally make a background image for the folder that tells users to drag metronome.app into Applications. (Find it in `/assets/mac/mac-installer-background.jpg`.) 279 | 8. Eject the disk image. 280 | 281 | ### Build the final DMG 282 | 283 | ![Mac installer](assets/img/mac-installer.jpg 'Mac installer') 284 | 285 | 1. Start Disk Utility again. 286 | 3. Choose Images > Convert... from the menu. 287 | 2. Select `installerTemplate.dmg` just created. 288 | 4. Enter the name of the final image, `metronome-installer_1.0.dmg`. 289 | 5. Select Compressed as the Image Format. 290 | 6. Click 'Convert' to create the dmg file. 291 | 292 | DMG creation resources: 293 | 294 | - https://kb.parallels.com/en/123895 295 | - https://www.renedohmen.nl/blog/2012/04/building-fancy-dmg-images-on-mac-os-x/ 296 | 297 | ## Create a Linux installer (.deb file) 298 | 299 | I've used an easy to follow tutorial here: https://ubuntuforums.org/showthread.php?t=910717. 300 | 301 | 1. Create a file named `control` with information for package management tools like `dpkg` to manage the package. I've already added the file for this project in `/assets/linux/`. 302 | 2. Create a directory for the files to install that uses the naming convention `_.-`. So here that's `metronome-installer_1.0`. 303 | 3. Inside the folder create a file structure that represents the locations of the files to install. Just as in the manual install described above. See the example below. 304 | 4. Add the icon `png` file at the location you specified in `metronome.desktop`. 305 | 5. Create the `deb` installer with `dpkg-deb --build metronome-installer_1.0`. 306 | 307 | So this is the directory and file structure: 308 | 309 | ``` 310 | +-- metronome-installer_1.0 311 | | +-- DEBIAN 312 | | | +-- control 313 | | +-- usr 314 | | | +-- share 315 | | | | +-- applications 316 | | | | | +-- metronome.desktop 317 | | +-- opt 318 | | | +-- metronome 319 | | | | +-- nw 320 | | | | +-- index.html 321 | | | | +-- package.json 322 | | | | +-- ... (and all the other files of the application) 323 | ``` 324 | 325 | ![Linux Terminal](assets/img/linux-terminal.jpg 'Linux Terminal') 326 | 327 | As mentioned, create the `.deb` file with: 328 | 329 | ```bash 330 | dpkg-deb --build metronome-installer_1.0 331 | ``` 332 | 333 | The result is a file named `metronome-installer_1.0.deb`. The Metronome app can then be installed with: 334 | 335 | ```bash 336 | sudo dpkg -i metronome-installer_1.0.deb 337 | ``` 338 | 339 | If you wish to completely uninstall the package and config files perform the following actions to check if the package is correctly installed and then to remove it: 340 | 341 | ```bash 342 | dpkg -l | grep metronome 343 | sudo dpkg -P metronome 344 | ``` 345 | 346 | Another `deb` installer tutorial: 347 | 348 | - https://ubuntuforums.org/showthread.php?t=910717 349 | 350 | ## Create a Windows installer (.exe file) 351 | 352 | INNO Setup is voted best [here at Slant](https://www.slant.co/topics/4794/versus/~inno-setup_vs_setup-factory_vs_advanced-installer). So that's what I decided to use. 353 | 354 | - Download Inno Setup from http://www.jrsoftware.org/isdl.php (The current version is innosetup-5.6.1.exe) 355 | - Install Inno Setup as usual for Windows applications. 356 | - Launch Inno Setup. 357 | - In the Welcome window select to 'Create a new script file using the Script Wizard'. 358 | - The wizard opens with the Application Information screen: 359 | - The name of the application (Application name), 360 | - its version (Application version), 361 | - the company (or person) owner (Application publisher) 362 | - the website of the application (Application website). 363 | - Then click on next. 364 | - Next is the Application Folder screen; 365 | - keep the destination base folder at 'Program Files folder'. 366 | - application folder name 'Metronome' 367 | - Application Files 368 | - For 'Application main executable file' browse to `metronome.exe`. 369 | - For 'Other application files' choose 'Add Folder...' and select the whole downloaded package with the source files and manifest file. 370 | - Application Shortcuts 371 | - Select the shortcuts you want to have created. 372 | - Application Icons 373 | - 'Start Menu folder name application': 'Metronome' 374 | - Application Documentation 375 | - For 'License file' choose the project's `/LICENSE` file. 376 | - Leave the other fields blank for this project. 377 | - Setup Languages 378 | - Leave it at English, or select the languages you want. 379 | - Compiler Settings 380 | - For 'Custom compiler output folder' choose some directory where to save the installer that will be created. 381 | - For 'Compiler output base file name' use 'metronome-installer'. 382 | - For 'Custom Setup icon file' select the `metronome.ico` file. This must be an `.ico` again. 383 | - Leave the 'Setup password' blank. 384 | - Inno Setup preprocessor 385 | - Leave the Checkbox marked. 386 | - Click 'Finish'. 387 | - Inno Setup Compiler 388 | - Click 'Yes' to compile the new script. 389 | - Agree to save the Setup script so you can compile the installer in the future without having to go through this wizard again. 390 | 391 | ![Inno Setup](assets/img/inno-setup.jpg 'Inno Setup') 392 | 393 | The compiler will take a bit of time to create the installer, but you'll be able to follow the process in the 'Compiler Output' pane of Inno Setup. 394 | 395 | ![Installer on Windows](assets/img/installer-windows.jpg 'Installer on Windows') 396 | 397 | The resulting installer is an `.exe` file that presents users with the installation procedure they're familiar with. 398 | 399 | INNO Setup resources: 400 | 401 | - http://www.jrsoftware.org/isinfo.php 402 | - https://www.supinfo.com/articles/single/7176-create-installer-with-inno-setup 403 | 404 | And finally, some other articles that I've read to get familiar with NW.js: 405 | 406 | - https://dzone.com/articles/what-is-nwjs 407 | - http://docs.nwjs.io/en/latest/For%20Users/Package%20and%20Distribute/ 408 | - https://www.sitepoint.com/cross-platform-desktop-app-nw-js/ 409 | - https://strongloop.com/strongblog/creating-desktop-applications-with-node-webkit/ 410 | - https://github.com/nwjs/nw.js/wiki/how-to-package-and-distribute-your-apps 411 | -------------------------------------------------------------------------------- /assets/icons/icon-1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/icon-1024x1024.png -------------------------------------------------------------------------------- /assets/icons/icon-1024x1024.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/icon-1024x1024.psd -------------------------------------------------------------------------------- /assets/icons/icon-1024x1024.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /assets/icons/icon-1024x1024.xd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/icon-1024x1024.xd -------------------------------------------------------------------------------- /assets/icons/metronome.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.icns -------------------------------------------------------------------------------- /assets/icons/metronome.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.ico -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_1024x1024.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_256x256.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_32x32.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_512x512.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /assets/icons/metronome.iconset/icon_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/icons/metronome.iconset/icon_64x64.png -------------------------------------------------------------------------------- /assets/icons/metronome.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /assets/img/chrome-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/chrome-screenshot.jpg -------------------------------------------------------------------------------- /assets/img/inno-setup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/inno-setup.jpg -------------------------------------------------------------------------------- /assets/img/installer-windows.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/installer-windows.jpg -------------------------------------------------------------------------------- /assets/img/linux-terminal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/linux-terminal.jpg -------------------------------------------------------------------------------- /assets/img/mac-disk-utility.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/mac-disk-utility.jpg -------------------------------------------------------------------------------- /assets/img/mac-installer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/mac-installer.jpg -------------------------------------------------------------------------------- /assets/img/mac-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/mac-screenshot.jpg -------------------------------------------------------------------------------- /assets/img/metronome-screen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/metronome-screen.gif -------------------------------------------------------------------------------- /assets/img/nwjs-download.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/nwjs-download.jpg -------------------------------------------------------------------------------- /assets/img/nwjs-home.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/nwjs-home.gif -------------------------------------------------------------------------------- /assets/img/nwjs-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/nwjs-logo.jpg -------------------------------------------------------------------------------- /assets/img/resource-hacker.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/resource-hacker.jpg -------------------------------------------------------------------------------- /assets/img/ubuntu-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/ubuntu-screenshot.jpg -------------------------------------------------------------------------------- /assets/img/windows-screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/img/windows-screenshot.jpg -------------------------------------------------------------------------------- /assets/linux/control: -------------------------------------------------------------------------------- 1 | Package: metronome 2 | Version: 1.0 3 | Architecture: all 4 | Maintainer: Wouter Hisschemöller 5 | Description: A metronome app to keep musical time. 6 | -------------------------------------------------------------------------------- /assets/linux/metronome.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | 3 | # The name of the application 4 | Name=Metronome 5 | 6 | # The executable of the application, possibly with arguments. 7 | Exec=/opt/metronome/nw 8 | 9 | # The version of the desktop entry specification to which this file complies 10 | Version=1.0 11 | 12 | # The name of the icon that will be used to display this entry 13 | Icon=/opt/metronome/img/icon.png 14 | 15 | # The type of the what this desktop item points to 16 | Type=Application 17 | 18 | # Describes the categories in which this entry should be shown 19 | Categories=GTK;GNOME;Utility;MIDI;Audio;Music; 20 | 21 | # Describes the encoding of the entries in this desktop file. 22 | Encoding=UTF-8 23 | 24 | # Describes whether this application needs to be run in a terminal or not 25 | Terminal=false 26 | 27 | # A comment which can/will be used as a tooltip 28 | Comment=A metronome app to keep musical time. 29 | -------------------------------------------------------------------------------- /assets/mac/mac-installer-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/assets/mac/mac-installer-background.jpg -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | 4 | const app = express(); 5 | const port = process.env.PORT || 3000; 6 | 7 | // Set public folder as root 8 | app.use(express.static(path.join(__dirname, 'src'))); 9 | 10 | // Listen for HTTP requests on the specified port 11 | app.listen(port, () => { 12 | console.log('listening on %d', port); 13 | }); 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nwjs-tutorial", 3 | "version": "0.0.1", 4 | "description": "Tutorial to use NW.js to create a desktop program from a JavaScript app.", 5 | "author": "Wouter Hisschemöller", 6 | "homepage": "https://github.com/hisschemoller/nwjs-tutorial#readme", 7 | "license": "mit", 8 | "private": true, 9 | "main": "src/index.html", 10 | "repository": { 11 | "type" : "git", 12 | "url" : "https://github.com/hisschemoller/nwjs-tutorial.git" 13 | }, 14 | "scripts": { 15 | "start": "node index.js", 16 | "start-nw": "nw --disable-raf-throttling" 17 | }, 18 | "devDependencies": { 19 | "express": "^4.16.4", 20 | "nw": "0.38.0-sdk" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | padding: 0; 4 | margin: 0; 5 | } 6 | 7 | html, body, div, span, applet, object, iframe, 8 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 9 | a, abbr, acronym, address, big, cite, code, 10 | del, dfn, em, img, ins, kbd, q, s, samp, 11 | small, strike, strong, sub, sup, tt, var, 12 | b, u, i, center, 13 | dl, dt, dd, ol, ul, li, 14 | fieldset, form, label, legend, 15 | table, caption, tbody, tfoot, thead, tr, th, td, 16 | article, aside, canvas, details, embed, 17 | figure, figcaption, footer, header, hgroup, 18 | menu, nav, output, ruby, section, summary, 19 | time, mark, audio, video { 20 | margin: 0; 21 | padding: 0; 22 | border: 0; 23 | font-size: 100%; 24 | font-family: sans-serif; 25 | text-align: center; 26 | vertical-align: baseline; 27 | } 28 | body { 29 | overflow: hidden; 30 | } 31 | input[type=range] { 32 | -webkit-appearance: none; 33 | /* width: 100%; */ 34 | background: transparent; 35 | } 36 | input[type=range]::-webkit-slider-thumb { 37 | -webkit-appearance: none; 38 | } 39 | input[type=range]:focus { 40 | outline: none; 41 | } 42 | input[type=range]::-ms-track { 43 | width: 100%; 44 | cursor: pointer; 45 | background: transparent; 46 | border-color: transparent; 47 | color: transparent; 48 | } 49 | 50 | /* thumb */ 51 | input[type=range]::-webkit-slider-thumb { 52 | -webkit-appearance: none; 53 | border: none; 54 | height: 24px; 55 | width: 24px; 56 | border-radius: 18px; 57 | background: #9bc; 58 | cursor: pointer; 59 | margin-top: -11px; 60 | box-shadow: none; 61 | } 62 | input[type=range]::-moz-range-thumb { 63 | box-shadow: none; 64 | border: none; 65 | height: 24px; 66 | width: 24px; 67 | border-radius: 18px; 68 | background: #9bc; 69 | cursor: pointer; 70 | } 71 | input[type=range]::-ms-thumb { 72 | box-shadow: none; 73 | border: none; 74 | height: 24px; 75 | width: 24px; 76 | border-radius: 18px; 77 | background: #9bc; 78 | cursor: pointer; 79 | } 80 | 81 | /* track */ 82 | input[type=range]::-webkit-slider-runnable-track { 83 | width: 100%; 84 | height: 2px; 85 | cursor: pointer; 86 | box-shadow: none; 87 | background: #fff; 88 | border-radius: 0; 89 | border: none; 90 | } 91 | 92 | input[type=range]:focus::-webkit-slider-runnable-track { 93 | background: #fff; 94 | } 95 | input[type=range]::-moz-range-track { 96 | width: 100%; 97 | height: 48px; 98 | cursor: pointer; 99 | box-shadow: none; 100 | background: #fff; 101 | border-radius: 0; 102 | border: none; 103 | } 104 | input[type=range]::-ms-track { 105 | width: 100%; 106 | height: 5px; 107 | cursor: pointer; 108 | background: transparent; 109 | border-color: transparent; 110 | border-width: 16px 0; 111 | color: transparent; 112 | } 113 | input[type=range]::-ms-fill-lower { 114 | background: #fff; 115 | border: none; 116 | border-radius: 0; 117 | box-shadow: none; 118 | } 119 | input[type=range]:focus::-ms-fill-lower { 120 | background: #fff; 121 | } 122 | input[type=range]::-ms-fill-upper { 123 | background: #fff; 124 | border: none; 125 | border-radius: 0; 126 | box-shadow: none; 127 | } 128 | input[type=range]:focus::-ms-fill-upper { 129 | background: #fff; 130 | } 131 | 132 | 133 | #counter { 134 | background-color: #fff; 135 | border-radius: 8px; 136 | color: #0081b1; 137 | flex-grow: 1; 138 | font-size: 48px; 139 | font-weight: bold; 140 | } 141 | 142 | .app { 143 | background-color: #cef; 144 | margin: 0; 145 | max-width: 400px; 146 | padding: 20px 30px 15px 30px; 147 | } 148 | 149 | .row { 150 | display: flex; 151 | padding: 8px 0; 152 | } 153 | .bpm-label { 154 | align-self: flex-end; 155 | color: #9bc; 156 | flex-grow: 1; 157 | font-weight: bold; 158 | padding-left: 8px; 159 | text-align: left; 160 | } 161 | .small-btn { 162 | background: #9bc; 163 | border: none; 164 | border-radius: 24px; 165 | color: #fff; 166 | cursor: pointer; 167 | font-size: 24px; 168 | height: 48px; 169 | outline: none; 170 | width: 48px; 171 | } 172 | .small-btn:hover { 173 | background: #8ab; 174 | } 175 | #slider { 176 | flex-grow: 1; 177 | margin-left: 8px; 178 | margin-right: 8px; 179 | } 180 | #bpm { 181 | border: none; 182 | border-radius: 8px; 183 | color: #9bc; 184 | font-size: 48px; 185 | font-weight: bold; 186 | max-width: 150px; 187 | text-align: center; 188 | } 189 | #run-toggle { 190 | left: -10000px; 191 | position: absolute; 192 | visibility: hidden; 193 | } 194 | #run-toggle + label { 195 | background: #9bc; 196 | border-radius: 24px; 197 | color: #fff; 198 | cursor: pointer; 199 | font-size: 20px; 200 | height: 48px; 201 | line-height: 48px; 202 | outline: none; 203 | width: 48px; 204 | } 205 | #run-toggle + label > i:before { 206 | content: '\e802'; 207 | } 208 | #run-toggle:checked + label > i:before { 209 | content: '\e803'; 210 | } -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/src/favicon.ico -------------------------------------------------------------------------------- /src/fonts/icons/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Font license info 2 | 3 | 4 | ## Font Awesome 5 | 6 | Copyright (C) 2016 by Dave Gandy 7 | 8 | Author: Dave Gandy 9 | License: SIL () 10 | Homepage: http://fortawesome.github.com/Font-Awesome/ 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/fonts/icons/README.txt: -------------------------------------------------------------------------------- 1 | This webfont is generated by http://fontello.com open source project. 2 | 3 | 4 | ================================================================================ 5 | Please, note, that you should obey original font licenses, used to make this 6 | webfont pack. Details available in LICENSE.txt file. 7 | 8 | - Usually, it's enough to publish content of LICENSE.txt file somewhere on your 9 | site in "About" section. 10 | 11 | - If your project is open-source, usually, it will be ok to make LICENSE.txt 12 | file publicly available in your repository. 13 | 14 | - Fonts, used in Fontello, don't require a clickable link on your site. 15 | But any kind of additional authors crediting is welcome. 16 | ================================================================================ 17 | 18 | 19 | Comments on archive content 20 | --------------------------- 21 | 22 | - /font/* - fonts in different formats 23 | 24 | - /css/* - different kinds of css, for all situations. Should be ok with 25 | twitter bootstrap. Also, you can skip style and assign icon classes 26 | directly to text elements, if you don't mind about IE7. 27 | 28 | - demo.html - demo file, to show your webfont content 29 | 30 | - LICENSE.txt - license info about source fonts, used to build your one. 31 | 32 | - config.json - keeps your settings. You can import it back into fontello 33 | anytime, to continue your work 34 | 35 | 36 | Why so many CSS files ? 37 | ----------------------- 38 | 39 | Because we like to fit all your needs :) 40 | 41 | - basic file, .css - is usually enough, it contains @font-face 42 | and character code definitions 43 | 44 | - *-ie7.css - if you need IE7 support, but still don't wish to put char codes 45 | directly into html 46 | 47 | - *-codes.css and *-ie7-codes.css - if you like to use your own @font-face 48 | rules, but still wish to benefit from css generation. That can be very 49 | convenient for automated asset build systems. When you need to update font - 50 | no need to manually edit files, just override old version with archive 51 | content. See fontello source code for examples. 52 | 53 | - *-embedded.css - basic css file, but with embedded WOFF font, to avoid 54 | CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain. 55 | We strongly recommend to resolve this issue by `Access-Control-Allow-Origin` 56 | server headers. But if you ok with dirty hack - this file is for you. Note, 57 | that data url moved to separate @font-face to avoid problems with 2 | 3 | 4 | 278 | 279 | 291 | 292 | 293 |
294 |

settings font demo

295 | 298 |
299 |
300 |
301 |
icon-plus0xe800
302 |
icon-minus0xe801
303 |
icon-play0xe802
304 |
icon-pause0xe803
305 |
306 |
307 | 308 | 309 | -------------------------------------------------------------------------------- /src/fonts/icons/font/settings.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/src/fonts/icons/font/settings.eot -------------------------------------------------------------------------------- /src/fonts/icons/font/settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2019 by original authors @ fontello.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/fonts/icons/font/settings.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/src/fonts/icons/font/settings.ttf -------------------------------------------------------------------------------- /src/fonts/icons/font/settings.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/src/fonts/icons/font/settings.woff -------------------------------------------------------------------------------- /src/fonts/icons/font/settings.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/src/fonts/icons/font/settings.woff2 -------------------------------------------------------------------------------- /src/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hisschemoller/nwjs-tutorial/7ed5a1974fa807af5dcdbce706b17cfd6ca6c2c3/src/img/icon.png -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Metronome (HTML title tag) 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
0
14 |
15 |
16 | 17 | BPM 18 | 19 | 20 |
21 |
22 | 23 | 24 | 25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/js/app.js: -------------------------------------------------------------------------------- 1 | import { pause as pauseTimer, setup as setupTimer, start as startTimer } from './timebase.js'; 2 | 3 | const counterEl = document.getElementById('counter'); 4 | const sliderEl = document.getElementById('slider'); 5 | const bpmEl = document.getElementById('bpm'); 6 | const min = 40; 7 | const max = 208; 8 | 9 | let ctx = null; 10 | let gain = null; 11 | let isRunning = false; 12 | let isSetup = false; 13 | let bpm = 120; 14 | let secondsPerBeat = 60 / bpm; 15 | 16 | sliderEl.addEventListener('input', e => { 17 | setBPM(e.target.value); 18 | }); 19 | 20 | bpmEl.addEventListener('change', e => { 21 | setBPM(e.target.value); 22 | }); 23 | 24 | document.getElementById('decrease').addEventListener('click', e => { 25 | setBPM(bpm - 1); 26 | }); 27 | 28 | document.getElementById('increase').addEventListener('click', e => { 29 | setBPM(bpm + 1); 30 | }); 31 | 32 | document.getElementById('run-toggle').addEventListener('change', e => { 33 | isRunning = e.target.checked; 34 | if (!isSetup) { 35 | isSetup = true; 36 | setupTimer(scheduleEvents); 37 | ctx = new (window.AudioContext || window.webkitAudioContext)(); 38 | gain = ctx.createGain(); 39 | gain.connect(ctx.destination); 40 | } 41 | if (isRunning) { 42 | startTimer(); 43 | } else { 44 | pauseTimer(); 45 | } 46 | }); 47 | 48 | function setBPM(newValue) { 49 | bpm = Math.max(min, Math.min(newValue, max)); 50 | secondsPerBeat = 60 / bpm; 51 | bpmEl.value = bpm; 52 | sliderEl.value = bpm; 53 | } 54 | 55 | function scheduleEvents(now, scanStart, scanEnd) { 56 | const firstBeat = Math.ceil(scanStart / secondsPerBeat); 57 | const lastBeat = Math.floor(scanEnd / secondsPerBeat); 58 | 59 | if (firstBeat <= lastBeat) { 60 | for (let i = firstBeat; i <= lastBeat; i++) { 61 | performEvent(i, now); 62 | } 63 | } 64 | } 65 | 66 | function performEvent(index, now) { 67 | const delay = Math.max(0, (index * secondsPerBeat) - now); 68 | const when = ctx.currentTime + delay; 69 | 70 | gain.gain.setValueAtTime(0.5, when); 71 | gain.gain.exponentialRampToValueAtTime(0.00001, when + 0.15); 72 | 73 | const osc = ctx.createOscillator(); 74 | osc.frequency.setValueAtTime(index % 4 === 0 ? 880 : 440, when); 75 | osc.connect(gain); 76 | osc.start(when); 77 | osc.stop(when + 0.05); 78 | 79 | setTimeout( 80 | () => { 81 | counterEl.textContent = index; 82 | }, delay * 1000); 83 | } 84 | 85 | setBPM(120); 86 | -------------------------------------------------------------------------------- /src/js/timebase.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Run is called at requestAnimationFrame rate, 60 times per second. 3 | * Each time it checks if a next 4 | * 5 | * @see https://github.com/hoch/waax file src/waax.timebase.js 6 | */ 7 | 8 | const scanRange = 4 / 60; 9 | const updateFrequency = 1 / 60; 10 | const callbacks = []; 11 | 12 | let isRunning = false; 13 | let needsScan = false; 14 | let scanStart = 0; 15 | let scanEnd = 0; 16 | let absNow = 0; 17 | let absLastNow = 0; 18 | let now = 0; 19 | 20 | export function setup(callback) { 21 | callbacks.push(callback) 22 | run(); 23 | } 24 | 25 | export function start() { 26 | absNow = performance.now() / 1000; 27 | absLastNow = absNow; 28 | isRunning = true; 29 | } 30 | 31 | export function pause() { 32 | isRunning = false; 33 | } 34 | 35 | export function rewind() { 36 | now = 0; 37 | } 38 | 39 | function run() { 40 | if (isRunning) { 41 | absNow = performance.now() / 1000; 42 | now += (absNow - absLastNow); 43 | absLastNow = absNow; 44 | advanceScanRange(); 45 | scheduleNotesInScanRange(); 46 | } 47 | 48 | requestAnimationFrame(run); 49 | } 50 | 51 | function scheduleNotesInScanRange() { 52 | if (needsScan) { 53 | callbacks.forEach(callback => callback(now, scanStart, scanEnd)); 54 | needsScan = false; 55 | } 56 | } 57 | 58 | function advanceScanRange() { 59 | while (now + updateFrequency > scanEnd) { 60 | scanStart = scanEnd; 61 | scanEnd = scanEnd + scanRange; 62 | if (now + updateFrequency <= scanEnd) { 63 | needsScan = true; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Metronome_manifest_name", 3 | "description": "A metronome app to keep time.", 4 | "main": "index.html", 5 | "chromium-args": "--disable-raf-throttling", 6 | "window": { 7 | "icon": "img/icon.png", 8 | "height": 240, 9 | "resizable": false, 10 | "width": 400, 11 | "title": "Metronome_manifest_window_title" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | accepts@~1.3.5: 6 | version "1.3.5" 7 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" 8 | integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= 9 | dependencies: 10 | mime-types "~2.1.18" 11 | negotiator "0.6.1" 12 | 13 | ansi-regex@^2.0.0: 14 | version "2.1.1" 15 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 16 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 17 | 18 | ansi-styles@^2.2.1: 19 | version "2.2.1" 20 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 21 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= 22 | 23 | array-flatten@1.1.1: 24 | version "1.1.1" 25 | resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" 26 | integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= 27 | 28 | balanced-match@^1.0.0: 29 | version "1.0.0" 30 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 31 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 32 | 33 | base64-js@^1.0.2: 34 | version "1.3.1" 35 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" 36 | integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== 37 | 38 | bl@^1.0.0: 39 | version "1.2.3" 40 | resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" 41 | integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== 42 | dependencies: 43 | readable-stream "^2.3.5" 44 | safe-buffer "^5.1.1" 45 | 46 | body-parser@1.18.3: 47 | version "1.18.3" 48 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" 49 | integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= 50 | dependencies: 51 | bytes "3.0.0" 52 | content-type "~1.0.4" 53 | debug "2.6.9" 54 | depd "~1.1.2" 55 | http-errors "~1.6.3" 56 | iconv-lite "0.4.23" 57 | on-finished "~2.3.0" 58 | qs "6.5.2" 59 | raw-body "2.3.3" 60 | type-is "~1.6.16" 61 | 62 | brace-expansion@^1.1.7: 63 | version "1.1.11" 64 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 65 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 66 | dependencies: 67 | balanced-match "^1.0.0" 68 | concat-map "0.0.1" 69 | 70 | buffer-alloc-unsafe@^1.1.0: 71 | version "1.1.0" 72 | resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" 73 | integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== 74 | 75 | buffer-alloc@^1.2.0: 76 | version "1.2.0" 77 | resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" 78 | integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== 79 | dependencies: 80 | buffer-alloc-unsafe "^1.1.0" 81 | buffer-fill "^1.0.0" 82 | 83 | buffer-crc32@~0.2.3: 84 | version "0.2.13" 85 | resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" 86 | integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= 87 | 88 | buffer-fill@^1.0.0: 89 | version "1.0.0" 90 | resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" 91 | integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= 92 | 93 | buffer@^5.2.1: 94 | version "5.6.0" 95 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" 96 | integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== 97 | dependencies: 98 | base64-js "^1.0.2" 99 | ieee754 "^1.1.4" 100 | 101 | bytes@3.0.0: 102 | version "3.0.0" 103 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 104 | integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= 105 | 106 | camelcase@^2.0.1: 107 | version "2.1.1" 108 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" 109 | integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= 110 | 111 | capture-stack-trace@^1.0.0: 112 | version "1.0.1" 113 | resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" 114 | integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== 115 | 116 | caw@^2.0.0: 117 | version "2.0.1" 118 | resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" 119 | integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== 120 | dependencies: 121 | get-proxy "^2.0.0" 122 | isurl "^1.0.0-alpha5" 123 | tunnel-agent "^0.6.0" 124 | url-to-options "^1.0.1" 125 | 126 | chalk@~1.1.3: 127 | version "1.1.3" 128 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 129 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= 130 | dependencies: 131 | ansi-styles "^2.2.1" 132 | escape-string-regexp "^1.0.2" 133 | has-ansi "^2.0.0" 134 | strip-ansi "^3.0.0" 135 | supports-color "^2.0.0" 136 | 137 | charm@~0.1.1: 138 | version "0.1.2" 139 | resolved "https://registry.yarnpkg.com/charm/-/charm-0.1.2.tgz#06c21eed1a1b06aeb67553cdc53e23274bac2296" 140 | integrity sha1-BsIe7RobBq62dVPNxT4jJ0usIpY= 141 | 142 | cliui@^3.0.3: 143 | version "3.2.0" 144 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" 145 | integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= 146 | dependencies: 147 | string-width "^1.0.1" 148 | strip-ansi "^3.0.1" 149 | wrap-ansi "^2.0.0" 150 | 151 | code-point-at@^1.0.0: 152 | version "1.1.0" 153 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 154 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 155 | 156 | commander@^2.8.1: 157 | version "2.20.3" 158 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 159 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 160 | 161 | concat-map@0.0.1: 162 | version "0.0.1" 163 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 164 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 165 | 166 | config-chain@^1.1.11: 167 | version "1.1.12" 168 | resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" 169 | integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== 170 | dependencies: 171 | ini "^1.3.4" 172 | proto-list "~1.2.1" 173 | 174 | content-disposition@0.5.2: 175 | version "0.5.2" 176 | resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" 177 | integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= 178 | 179 | content-type@~1.0.4: 180 | version "1.0.4" 181 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 182 | integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 183 | 184 | cookie-signature@1.0.6: 185 | version "1.0.6" 186 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" 187 | integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= 188 | 189 | cookie@0.3.1: 190 | version "0.3.1" 191 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" 192 | integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= 193 | 194 | core-util-is@~1.0.0: 195 | version "1.0.2" 196 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 197 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 198 | 199 | create-error-class@^3.0.0: 200 | version "3.0.2" 201 | resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" 202 | integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= 203 | dependencies: 204 | capture-stack-trace "^1.0.0" 205 | 206 | debug@2.6.9: 207 | version "2.6.9" 208 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 209 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 210 | dependencies: 211 | ms "2.0.0" 212 | 213 | decamelize@^1.1.1: 214 | version "1.2.0" 215 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 216 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 217 | 218 | decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: 219 | version "4.1.1" 220 | resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" 221 | integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== 222 | dependencies: 223 | file-type "^5.2.0" 224 | is-stream "^1.1.0" 225 | tar-stream "^1.5.2" 226 | 227 | decompress-tarbz2@^4.0.0: 228 | version "4.1.1" 229 | resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" 230 | integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== 231 | dependencies: 232 | decompress-tar "^4.1.0" 233 | file-type "^6.1.0" 234 | is-stream "^1.1.0" 235 | seek-bzip "^1.0.5" 236 | unbzip2-stream "^1.0.9" 237 | 238 | decompress-targz@^4.0.0: 239 | version "4.1.1" 240 | resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" 241 | integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== 242 | dependencies: 243 | decompress-tar "^4.1.1" 244 | file-type "^5.2.0" 245 | is-stream "^1.1.0" 246 | 247 | decompress-unzip@^4.0.1: 248 | version "4.0.1" 249 | resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" 250 | integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= 251 | dependencies: 252 | file-type "^3.8.0" 253 | get-stream "^2.2.0" 254 | pify "^2.3.0" 255 | yauzl "^2.4.2" 256 | 257 | decompress@^4.0.0, decompress@^4.2.0: 258 | version "4.2.1" 259 | resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" 260 | integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== 261 | dependencies: 262 | decompress-tar "^4.0.0" 263 | decompress-tarbz2 "^4.0.0" 264 | decompress-targz "^4.0.0" 265 | decompress-unzip "^4.0.1" 266 | graceful-fs "^4.1.10" 267 | make-dir "^1.0.0" 268 | pify "^2.3.0" 269 | strip-dirs "^2.0.0" 270 | 271 | depd@~1.1.2: 272 | version "1.1.2" 273 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 274 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 275 | 276 | destroy@~1.0.4: 277 | version "1.0.4" 278 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 279 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 280 | 281 | download@^5.0.3: 282 | version "5.0.3" 283 | resolved "https://registry.yarnpkg.com/download/-/download-5.0.3.tgz#63537f977f99266a30eb8a2a2fbd1f20b8000f7a" 284 | integrity sha1-Y1N/l3+ZJmow64oqL70fILgAD3o= 285 | dependencies: 286 | caw "^2.0.0" 287 | decompress "^4.0.0" 288 | filenamify "^2.0.0" 289 | get-stream "^3.0.0" 290 | got "^6.3.0" 291 | mkdirp "^0.5.1" 292 | pify "^2.3.0" 293 | 294 | duplexer3@^0.1.4: 295 | version "0.1.4" 296 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" 297 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= 298 | 299 | ee-first@1.1.1: 300 | version "1.1.1" 301 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 302 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 303 | 304 | encodeurl@~1.0.2: 305 | version "1.0.2" 306 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 307 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 308 | 309 | end-of-stream@^1.0.0: 310 | version "1.4.4" 311 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 312 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 313 | dependencies: 314 | once "^1.4.0" 315 | 316 | escape-html@~1.0.3: 317 | version "1.0.3" 318 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 319 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 320 | 321 | escape-string-regexp@^1.0.2: 322 | version "1.0.5" 323 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 324 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 325 | 326 | etag@~1.8.1: 327 | version "1.8.1" 328 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 329 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 330 | 331 | express@^4.16.4: 332 | version "4.16.4" 333 | resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" 334 | integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== 335 | dependencies: 336 | accepts "~1.3.5" 337 | array-flatten "1.1.1" 338 | body-parser "1.18.3" 339 | content-disposition "0.5.2" 340 | content-type "~1.0.4" 341 | cookie "0.3.1" 342 | cookie-signature "1.0.6" 343 | debug "2.6.9" 344 | depd "~1.1.2" 345 | encodeurl "~1.0.2" 346 | escape-html "~1.0.3" 347 | etag "~1.8.1" 348 | finalhandler "1.1.1" 349 | fresh "0.5.2" 350 | merge-descriptors "1.0.1" 351 | methods "~1.1.2" 352 | on-finished "~2.3.0" 353 | parseurl "~1.3.2" 354 | path-to-regexp "0.1.7" 355 | proxy-addr "~2.0.4" 356 | qs "6.5.2" 357 | range-parser "~1.2.0" 358 | safe-buffer "5.1.2" 359 | send "0.16.2" 360 | serve-static "1.13.2" 361 | setprototypeof "1.1.0" 362 | statuses "~1.4.0" 363 | type-is "~1.6.16" 364 | utils-merge "1.0.1" 365 | vary "~1.1.2" 366 | 367 | fd-slicer@~1.1.0: 368 | version "1.1.0" 369 | resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" 370 | integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= 371 | dependencies: 372 | pend "~1.2.0" 373 | 374 | file-exists@^2.0.0: 375 | version "2.0.0" 376 | resolved "https://registry.yarnpkg.com/file-exists/-/file-exists-2.0.0.tgz#a24150665150e62d55bc5449281d88d2b0810dca" 377 | integrity sha1-okFQZlFQ5i1VvFRJKB2I0rCBDco= 378 | 379 | file-type@^3.8.0: 380 | version "3.9.0" 381 | resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" 382 | integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= 383 | 384 | file-type@^5.2.0: 385 | version "5.2.0" 386 | resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" 387 | integrity sha1-LdvqfHP/42No365J3DOMBYwritY= 388 | 389 | file-type@^6.1.0: 390 | version "6.2.0" 391 | resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" 392 | integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== 393 | 394 | filename-reserved-regex@^2.0.0: 395 | version "2.0.0" 396 | resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" 397 | integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= 398 | 399 | filenamify@^2.0.0: 400 | version "2.1.0" 401 | resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.1.0.tgz#88faf495fb1b47abfd612300002a16228c677ee9" 402 | integrity sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA== 403 | dependencies: 404 | filename-reserved-regex "^2.0.0" 405 | strip-outer "^1.0.0" 406 | trim-repeated "^1.0.0" 407 | 408 | finalhandler@1.1.1: 409 | version "1.1.1" 410 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" 411 | integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== 412 | dependencies: 413 | debug "2.6.9" 414 | encodeurl "~1.0.2" 415 | escape-html "~1.0.3" 416 | on-finished "~2.3.0" 417 | parseurl "~1.3.2" 418 | statuses "~1.4.0" 419 | unpipe "~1.0.0" 420 | 421 | forwarded@~0.1.2: 422 | version "0.1.2" 423 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" 424 | integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= 425 | 426 | fresh@0.5.2: 427 | version "0.5.2" 428 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 429 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 430 | 431 | fs-constants@^1.0.0: 432 | version "1.0.0" 433 | resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" 434 | integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== 435 | 436 | fs.realpath@^1.0.0: 437 | version "1.0.0" 438 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 439 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 440 | 441 | get-proxy@^2.0.0: 442 | version "2.1.0" 443 | resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" 444 | integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== 445 | dependencies: 446 | npm-conf "^1.1.0" 447 | 448 | get-stream@^2.2.0: 449 | version "2.3.1" 450 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" 451 | integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= 452 | dependencies: 453 | object-assign "^4.0.1" 454 | pinkie-promise "^2.0.0" 455 | 456 | get-stream@^3.0.0: 457 | version "3.0.0" 458 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 459 | integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= 460 | 461 | glob@^7.1.3: 462 | version "7.1.3" 463 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 464 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 465 | dependencies: 466 | fs.realpath "^1.0.0" 467 | inflight "^1.0.4" 468 | inherits "2" 469 | minimatch "^3.0.4" 470 | once "^1.3.0" 471 | path-is-absolute "^1.0.0" 472 | 473 | got@^6.3.0: 474 | version "6.7.1" 475 | resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" 476 | integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= 477 | dependencies: 478 | create-error-class "^3.0.0" 479 | duplexer3 "^0.1.4" 480 | get-stream "^3.0.0" 481 | is-redirect "^1.0.0" 482 | is-retry-allowed "^1.0.0" 483 | is-stream "^1.0.0" 484 | lowercase-keys "^1.0.0" 485 | safe-buffer "^5.0.1" 486 | timed-out "^4.0.0" 487 | unzip-response "^2.0.1" 488 | url-parse-lax "^1.0.0" 489 | 490 | graceful-fs@^4.1.10: 491 | version "4.2.4" 492 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" 493 | integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== 494 | 495 | has-ansi@^2.0.0: 496 | version "2.0.0" 497 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 498 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= 499 | dependencies: 500 | ansi-regex "^2.0.0" 501 | 502 | has-symbol-support-x@^1.4.1: 503 | version "1.4.2" 504 | resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" 505 | integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== 506 | 507 | has-to-string-tag-x@^1.2.0: 508 | version "1.4.1" 509 | resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" 510 | integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== 511 | dependencies: 512 | has-symbol-support-x "^1.4.1" 513 | 514 | http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: 515 | version "1.6.3" 516 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 517 | integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 518 | dependencies: 519 | depd "~1.1.2" 520 | inherits "2.0.3" 521 | setprototypeof "1.1.0" 522 | statuses ">= 1.4.0 < 2" 523 | 524 | iconv-lite@0.4.23: 525 | version "0.4.23" 526 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" 527 | integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== 528 | dependencies: 529 | safer-buffer ">= 2.1.2 < 3" 530 | 531 | ieee754@^1.1.4: 532 | version "1.1.13" 533 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" 534 | integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== 535 | 536 | inflight@^1.0.4: 537 | version "1.0.6" 538 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 539 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 540 | dependencies: 541 | once "^1.3.0" 542 | wrappy "1" 543 | 544 | inherits@2, inherits@2.0.3: 545 | version "2.0.3" 546 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 547 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 548 | 549 | inherits@~2.0.3: 550 | version "2.0.4" 551 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 552 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 553 | 554 | ini@^1.3.4: 555 | version "1.3.7" 556 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" 557 | integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== 558 | 559 | invert-kv@^1.0.0: 560 | version "1.0.0" 561 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" 562 | integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= 563 | 564 | ipaddr.js@1.8.0: 565 | version "1.8.0" 566 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" 567 | integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= 568 | 569 | is-fullwidth-code-point@^1.0.0: 570 | version "1.0.0" 571 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 572 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 573 | dependencies: 574 | number-is-nan "^1.0.0" 575 | 576 | is-natural-number@^4.0.1: 577 | version "4.0.1" 578 | resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" 579 | integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= 580 | 581 | is-object@^1.0.1: 582 | version "1.0.1" 583 | resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" 584 | integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= 585 | 586 | is-redirect@^1.0.0: 587 | version "1.0.0" 588 | resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" 589 | integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= 590 | 591 | is-retry-allowed@^1.0.0: 592 | version "1.1.0" 593 | resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" 594 | integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= 595 | 596 | is-stream@^1.0.0, is-stream@^1.1.0: 597 | version "1.1.0" 598 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 599 | integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= 600 | 601 | isarray@~1.0.0: 602 | version "1.0.0" 603 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 604 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 605 | 606 | isurl@^1.0.0-alpha5: 607 | version "1.0.0" 608 | resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" 609 | integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== 610 | dependencies: 611 | has-to-string-tag-x "^1.2.0" 612 | is-object "^1.0.1" 613 | 614 | lcid@^1.0.0: 615 | version "1.0.0" 616 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" 617 | integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= 618 | dependencies: 619 | invert-kv "^1.0.0" 620 | 621 | lowercase-keys@^1.0.0: 622 | version "1.0.1" 623 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" 624 | integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== 625 | 626 | make-dir@^1.0.0: 627 | version "1.3.0" 628 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" 629 | integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== 630 | dependencies: 631 | pify "^3.0.0" 632 | 633 | media-typer@0.3.0: 634 | version "0.3.0" 635 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" 636 | integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= 637 | 638 | merge-descriptors@1.0.1: 639 | version "1.0.1" 640 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 641 | integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= 642 | 643 | merge@^1.2.0: 644 | version "1.2.1" 645 | resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" 646 | integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== 647 | 648 | methods@~1.1.2: 649 | version "1.1.2" 650 | resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 651 | integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= 652 | 653 | mime-db@~1.38.0: 654 | version "1.38.0" 655 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" 656 | integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== 657 | 658 | mime-types@~2.1.18: 659 | version "2.1.22" 660 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" 661 | integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== 662 | dependencies: 663 | mime-db "~1.38.0" 664 | 665 | mime@1.4.1: 666 | version "1.4.1" 667 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 668 | integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== 669 | 670 | minimatch@^3.0.4: 671 | version "3.0.4" 672 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 673 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 674 | dependencies: 675 | brace-expansion "^1.1.7" 676 | 677 | minimist@0.0.8: 678 | version "0.0.8" 679 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 680 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 681 | 682 | mkdirp@^0.5.1: 683 | version "0.5.1" 684 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 685 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 686 | dependencies: 687 | minimist "0.0.8" 688 | 689 | ms@2.0.0: 690 | version "2.0.0" 691 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 692 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 693 | 694 | multimeter@^0.1.1: 695 | version "0.1.1" 696 | resolved "https://registry.yarnpkg.com/multimeter/-/multimeter-0.1.1.tgz#f856c80fc3cf0f1d4ad8eb36ad68735e3ed5b3ea" 697 | integrity sha1-+FbID8PPDx1K2Os2rWhzXj7Vs+o= 698 | dependencies: 699 | charm "~0.1.1" 700 | 701 | negotiator@0.6.1: 702 | version "0.6.1" 703 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 704 | integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= 705 | 706 | npm-conf@^1.1.0: 707 | version "1.1.3" 708 | resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" 709 | integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== 710 | dependencies: 711 | config-chain "^1.1.11" 712 | pify "^3.0.0" 713 | 714 | number-is-nan@^1.0.0: 715 | version "1.0.1" 716 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 717 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 718 | 719 | nw@0.38.0-sdk: 720 | version "0.38.0-sdk" 721 | resolved "https://registry.yarnpkg.com/nw/-/nw-0.38.0-sdk.tgz#929e314523dd0bdc0007a169de3e3d0392f84028" 722 | integrity sha512-HQC0fwFHW307ueW2DZ5pD4b9PmZzYsKLuK7v/OGxDRYLDMs7LiP6+q/Y7TSxniAGhOFL8FreMltSNFuLbrqevw== 723 | dependencies: 724 | chalk "~1.1.3" 725 | decompress "^4.2.0" 726 | download "^5.0.3" 727 | file-exists "^2.0.0" 728 | merge "^1.2.0" 729 | multimeter "^0.1.1" 730 | rimraf "^2.2.8" 731 | semver "^5.1.0" 732 | yargs "^3.2.1" 733 | 734 | object-assign@^4.0.1: 735 | version "4.1.1" 736 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 737 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 738 | 739 | on-finished@~2.3.0: 740 | version "2.3.0" 741 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 742 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 743 | dependencies: 744 | ee-first "1.1.1" 745 | 746 | once@^1.3.0, once@^1.4.0: 747 | version "1.4.0" 748 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 749 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 750 | dependencies: 751 | wrappy "1" 752 | 753 | os-locale@^1.4.0: 754 | version "1.4.0" 755 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" 756 | integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= 757 | dependencies: 758 | lcid "^1.0.0" 759 | 760 | parseurl@~1.3.2: 761 | version "1.3.2" 762 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 763 | integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= 764 | 765 | path-is-absolute@^1.0.0: 766 | version "1.0.1" 767 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 768 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 769 | 770 | path-to-regexp@0.1.7: 771 | version "0.1.7" 772 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" 773 | integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= 774 | 775 | pend@~1.2.0: 776 | version "1.2.0" 777 | resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" 778 | integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= 779 | 780 | pify@^2.3.0: 781 | version "2.3.0" 782 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 783 | integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= 784 | 785 | pify@^3.0.0: 786 | version "3.0.0" 787 | resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" 788 | integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= 789 | 790 | pinkie-promise@^2.0.0: 791 | version "2.0.1" 792 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 793 | integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= 794 | dependencies: 795 | pinkie "^2.0.0" 796 | 797 | pinkie@^2.0.0: 798 | version "2.0.4" 799 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 800 | integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= 801 | 802 | prepend-http@^1.0.1: 803 | version "1.0.4" 804 | resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" 805 | integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= 806 | 807 | process-nextick-args@~2.0.0: 808 | version "2.0.1" 809 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 810 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 811 | 812 | proto-list@~1.2.1: 813 | version "1.2.4" 814 | resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" 815 | integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= 816 | 817 | proxy-addr@~2.0.4: 818 | version "2.0.4" 819 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" 820 | integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== 821 | dependencies: 822 | forwarded "~0.1.2" 823 | ipaddr.js "1.8.0" 824 | 825 | qs@6.5.2: 826 | version "6.5.2" 827 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" 828 | integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== 829 | 830 | range-parser@~1.2.0: 831 | version "1.2.0" 832 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 833 | integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= 834 | 835 | raw-body@2.3.3: 836 | version "2.3.3" 837 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" 838 | integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== 839 | dependencies: 840 | bytes "3.0.0" 841 | http-errors "1.6.3" 842 | iconv-lite "0.4.23" 843 | unpipe "1.0.0" 844 | 845 | readable-stream@^2.3.0, readable-stream@^2.3.5: 846 | version "2.3.7" 847 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 848 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 849 | dependencies: 850 | core-util-is "~1.0.0" 851 | inherits "~2.0.3" 852 | isarray "~1.0.0" 853 | process-nextick-args "~2.0.0" 854 | safe-buffer "~5.1.1" 855 | string_decoder "~1.1.1" 856 | util-deprecate "~1.0.1" 857 | 858 | rimraf@^2.2.8: 859 | version "2.6.3" 860 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 861 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 862 | dependencies: 863 | glob "^7.1.3" 864 | 865 | safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 866 | version "5.1.2" 867 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 868 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 869 | 870 | safe-buffer@^5.1.1: 871 | version "5.2.1" 872 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 873 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 874 | 875 | "safer-buffer@>= 2.1.2 < 3": 876 | version "2.1.2" 877 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 878 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 879 | 880 | seek-bzip@^1.0.5: 881 | version "1.0.6" 882 | resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4" 883 | integrity sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ== 884 | dependencies: 885 | commander "^2.8.1" 886 | 887 | semver@^5.1.0: 888 | version "5.7.0" 889 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" 890 | integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== 891 | 892 | send@0.16.2: 893 | version "0.16.2" 894 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" 895 | integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== 896 | dependencies: 897 | debug "2.6.9" 898 | depd "~1.1.2" 899 | destroy "~1.0.4" 900 | encodeurl "~1.0.2" 901 | escape-html "~1.0.3" 902 | etag "~1.8.1" 903 | fresh "0.5.2" 904 | http-errors "~1.6.2" 905 | mime "1.4.1" 906 | ms "2.0.0" 907 | on-finished "~2.3.0" 908 | range-parser "~1.2.0" 909 | statuses "~1.4.0" 910 | 911 | serve-static@1.13.2: 912 | version "1.13.2" 913 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" 914 | integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== 915 | dependencies: 916 | encodeurl "~1.0.2" 917 | escape-html "~1.0.3" 918 | parseurl "~1.3.2" 919 | send "0.16.2" 920 | 921 | setprototypeof@1.1.0: 922 | version "1.1.0" 923 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 924 | integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== 925 | 926 | "statuses@>= 1.4.0 < 2": 927 | version "1.5.0" 928 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 929 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 930 | 931 | statuses@~1.4.0: 932 | version "1.4.0" 933 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 934 | integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== 935 | 936 | string-width@^1.0.1: 937 | version "1.0.2" 938 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 939 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 940 | dependencies: 941 | code-point-at "^1.0.0" 942 | is-fullwidth-code-point "^1.0.0" 943 | strip-ansi "^3.0.0" 944 | 945 | string_decoder@~1.1.1: 946 | version "1.1.1" 947 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 948 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 949 | dependencies: 950 | safe-buffer "~5.1.0" 951 | 952 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 953 | version "3.0.1" 954 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 955 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 956 | dependencies: 957 | ansi-regex "^2.0.0" 958 | 959 | strip-dirs@^2.0.0: 960 | version "2.1.0" 961 | resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" 962 | integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== 963 | dependencies: 964 | is-natural-number "^4.0.1" 965 | 966 | strip-outer@^1.0.0: 967 | version "1.0.1" 968 | resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" 969 | integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== 970 | dependencies: 971 | escape-string-regexp "^1.0.2" 972 | 973 | supports-color@^2.0.0: 974 | version "2.0.0" 975 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 976 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= 977 | 978 | tar-stream@^1.5.2: 979 | version "1.6.2" 980 | resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" 981 | integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== 982 | dependencies: 983 | bl "^1.0.0" 984 | buffer-alloc "^1.2.0" 985 | end-of-stream "^1.0.0" 986 | fs-constants "^1.0.0" 987 | readable-stream "^2.3.0" 988 | to-buffer "^1.1.1" 989 | xtend "^4.0.0" 990 | 991 | through@^2.3.8: 992 | version "2.3.8" 993 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 994 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 995 | 996 | timed-out@^4.0.0: 997 | version "4.0.1" 998 | resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" 999 | integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= 1000 | 1001 | to-buffer@^1.1.1: 1002 | version "1.1.1" 1003 | resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" 1004 | integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== 1005 | 1006 | trim-repeated@^1.0.0: 1007 | version "1.0.0" 1008 | resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" 1009 | integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= 1010 | dependencies: 1011 | escape-string-regexp "^1.0.2" 1012 | 1013 | tunnel-agent@^0.6.0: 1014 | version "0.6.0" 1015 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 1016 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 1017 | dependencies: 1018 | safe-buffer "^5.0.1" 1019 | 1020 | type-is@~1.6.16: 1021 | version "1.6.16" 1022 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" 1023 | integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== 1024 | dependencies: 1025 | media-typer "0.3.0" 1026 | mime-types "~2.1.18" 1027 | 1028 | unbzip2-stream@^1.0.9: 1029 | version "1.4.3" 1030 | resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" 1031 | integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== 1032 | dependencies: 1033 | buffer "^5.2.1" 1034 | through "^2.3.8" 1035 | 1036 | unpipe@1.0.0, unpipe@~1.0.0: 1037 | version "1.0.0" 1038 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 1039 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 1040 | 1041 | unzip-response@^2.0.1: 1042 | version "2.0.1" 1043 | resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" 1044 | integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= 1045 | 1046 | url-parse-lax@^1.0.0: 1047 | version "1.0.0" 1048 | resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" 1049 | integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= 1050 | dependencies: 1051 | prepend-http "^1.0.1" 1052 | 1053 | url-to-options@^1.0.1: 1054 | version "1.0.1" 1055 | resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" 1056 | integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= 1057 | 1058 | util-deprecate@~1.0.1: 1059 | version "1.0.2" 1060 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1061 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 1062 | 1063 | utils-merge@1.0.1: 1064 | version "1.0.1" 1065 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 1066 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 1067 | 1068 | vary@~1.1.2: 1069 | version "1.1.2" 1070 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 1071 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 1072 | 1073 | window-size@^0.1.4: 1074 | version "0.1.4" 1075 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" 1076 | integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= 1077 | 1078 | wrap-ansi@^2.0.0: 1079 | version "2.1.0" 1080 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 1081 | integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= 1082 | dependencies: 1083 | string-width "^1.0.1" 1084 | strip-ansi "^3.0.1" 1085 | 1086 | wrappy@1: 1087 | version "1.0.2" 1088 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1089 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1090 | 1091 | xtend@^4.0.0: 1092 | version "4.0.2" 1093 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" 1094 | integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== 1095 | 1096 | y18n@^3.2.0: 1097 | version "3.2.1" 1098 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" 1099 | integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= 1100 | 1101 | yargs@^3.2.1: 1102 | version "3.32.0" 1103 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" 1104 | integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= 1105 | dependencies: 1106 | camelcase "^2.0.1" 1107 | cliui "^3.0.3" 1108 | decamelize "^1.1.1" 1109 | os-locale "^1.4.0" 1110 | string-width "^1.0.1" 1111 | window-size "^0.1.4" 1112 | y18n "^3.2.0" 1113 | 1114 | yauzl@^2.4.2: 1115 | version "2.10.0" 1116 | resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" 1117 | integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= 1118 | dependencies: 1119 | buffer-crc32 "~0.2.3" 1120 | fd-slicer "~1.1.0" 1121 | --------------------------------------------------------------------------------