├── .gitignore ├── Readme.md ├── common ├── .gitignore ├── js │ ├── io.js │ ├── rooms.js │ ├── touch.js │ └── utils.js ├── package.json ├── styles │ ├── base.scss │ ├── container.scss │ ├── main.scss │ ├── twitter.scss │ └── variables.scss └── yarn.lock ├── drums ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── license.md ├── package.json ├── postcss.config.js ├── server.js ├── src │ ├── app.js │ ├── app.scss │ ├── favicon.ico │ ├── images │ │ ├── piano.png │ │ ├── space.png │ │ └── space.svg │ ├── index.html │ ├── js │ │ ├── animations.js │ │ ├── drums.js │ │ ├── notes.js │ │ └── tweens.js │ ├── medias │ │ ├── big-tom.mp3 │ │ ├── crash.mp3 │ │ ├── floor-tom.mp3 │ │ ├── hi-hat.mp3 │ │ ├── kick.mp3 │ │ ├── small-tom.mp3 │ │ └── snare.mp3 │ └── styles │ │ └── drums.scss ├── webpack.config.js └── yarn.lock ├── package.json ├── piano ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── license.md ├── package.json ├── postcss.config.js ├── server.js ├── src │ ├── app.js │ ├── app.scss │ ├── favicon.ico │ ├── images │ │ └── piano.png │ ├── index.html │ ├── js │ │ ├── notes.js │ │ └── piano.js │ ├── medias │ │ ├── 1046-C.mp3 │ │ ├── 220-A.mp3 │ │ ├── 246-B.mp3 │ │ ├── 261-C.mp3 │ │ ├── 277-C-sharp.mp3 │ │ ├── 293-D.mp3 │ │ ├── 311-D-sharp.mp3 │ │ ├── 329-E.mp3 │ │ ├── 349-F.mp3 │ │ ├── 369F-sharp.mp3 │ │ ├── 391-G.mp3 │ │ ├── 415-G-sharp.mp3 │ │ ├── 440-A.mp3 │ │ ├── 466-A-sharp.mp3 │ │ ├── 495-B.mp3 │ │ ├── 523-C.mp3 │ │ ├── 545-C-sharp.mp3 │ │ ├── 587-D.mp3 │ │ ├── 622-D-sharp.mp3 │ │ ├── 659-E.mp3 │ │ ├── 698-F-sharp.mp3 │ │ ├── 698-F.mp3 │ │ ├── 783-G.mp3 │ │ ├── 830-G-sharp.mp3 │ │ ├── 880-A.mp3 │ │ ├── 932-A-sharp.mp3 │ │ └── 987-B.mp3 │ └── styles │ │ └── piano.scss ├── webpack.config.js └── yarn.lock └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | Thumbs.db 4 | .idea/ 5 | .vscode/ 6 | *.sublime-project 7 | *.sublime-workspace 8 | *.log -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Magic Instruments 2 | 3 | Home of 4 | 5 | - https://magicpiano.now.sh 6 | - https://magicdrums.now.sh 7 | -------------------------------------------------------------------------------- /common/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | Thumbs.db 4 | .idea/ 5 | .vscode/ 6 | *.sublime-project 7 | *.sublime-workspace 8 | *.log 9 | -------------------------------------------------------------------------------- /common/js/io.js: -------------------------------------------------------------------------------- 1 | module.exports = io => { 2 | const users = { total: 0 } 3 | io.on('connection', socket => { 4 | // Handle user counts 5 | users.total++ 6 | socket.on('disconnect', () => { 7 | users.total-- 8 | io.emit('users', users.total) 9 | }) 10 | io.emit('users', users.total) 11 | 12 | // Handle incoming messages 13 | // Someone played a note 14 | socket.on('played note', key => { 15 | // send it just to their room 16 | if (socket.room) { 17 | socket.broadcast.to(socket.room).emit('played', key) 18 | } else { 19 | // fallback, shouldn't ever get here 20 | socket.broadcast.emit('played', key) 21 | } 22 | }) 23 | 24 | // User wants to change rooms 25 | socket.on('room', room => { 26 | if (socket.room) { 27 | socket.leave(socket.room) 28 | if (!users[socket.room]) { 29 | users[socket.room] = 0 30 | } 31 | users[socket.room]-- 32 | io.to(socket.room).emit('roomusers', users[socket.room]) 33 | } 34 | socket.room = room 35 | socket.join(room) 36 | 37 | if (!users[socket.room]) { 38 | users[socket.room] = 0 39 | } 40 | if (users[socket.room] < users.total) { 41 | users[socket.room]++ 42 | } 43 | io.to(socket.room).emit('roomusers', users[socket.room]) 44 | }) 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /common/js/rooms.js: -------------------------------------------------------------------------------- 1 | export var currentRoom = 'main' 2 | 3 | const changeRoom = (socket, newRoom) => { 4 | var $btn = document.querySelector(`[data-room='${currentRoom}']`) || '' 5 | if ($btn) { 6 | $btn.classList.remove('active') 7 | } 8 | currentRoom = newRoom 9 | socket.emit('room', newRoom) 10 | $btn = document.querySelector(`[data-room='${newRoom}']`) || '' 11 | if ($btn) { 12 | $btn.classList.add('active') 13 | } 14 | } 15 | 16 | export default socket => { 17 | document.querySelectorAll('[data-room]').forEach(roomButton => { 18 | const room = roomButton.getAttribute('data-room') 19 | roomButton.addEventListener('click', () => changeRoom(socket, room)) 20 | }) 21 | let customRoom = document.getElementById('customRoom') 22 | customRoom.addEventListener('change', () => 23 | changeRoom(socket, customRoom.value) 24 | ) 25 | customRoom.addEventListener('blur', () => 26 | changeRoom(socket, customRoom.value) 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /common/js/touch.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /** 3 | * Source: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js 4 | */ 5 | const isTouchDevice = () => { 6 | var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ') 7 | var mq = query => { 8 | return window.matchMedia(query).matches 9 | } 10 | if ( 11 | 'ontouchstart' in window || 12 | (window.DocumentTouch && document instanceof DocumentTouch) 13 | ) { 14 | return true 15 | } 16 | 17 | // include the 'heartz' as a way to have a non matching MQ to help terminate the join 18 | // https://git.io/vznFH 19 | var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('') 20 | return mq(query) 21 | } 22 | /* eslint-enable no-undef */ 23 | 24 | export default isTouchDevice 25 | -------------------------------------------------------------------------------- /common/js/utils.js: -------------------------------------------------------------------------------- 1 | export const pre = c => (c === 1 ? 'is' : 'are') 2 | export const title = c => (c === 1 ? 'person' : 'people') 3 | -------------------------------------------------------------------------------- /common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "common", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "webpack.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "babel-preset-env": "^1.7.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /common/styles/base.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | 6 | &:before, 7 | &:after { 8 | box-sizing: border-box; 9 | } 10 | } 11 | 12 | html { 13 | font-size: responsive 8px 10px; 14 | } 15 | 16 | body { 17 | -moz-osx-font-smoothing: auto; 18 | -webkit-font-smoothing: antialiased; 19 | -webkit-overflow-scrolling: touch; 20 | color: $gray-dark; 21 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 22 | Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; 23 | overflow-x: hidden; 24 | visibility: visible; 25 | background: #141e30; /* fallback for old browsers */ 26 | background: -webkit-linear-gradient( 27 | to right, 28 | #243b55, 29 | #141e30 30 | ); /* Chrome 10-25, Safari 5.1-6 */ 31 | background: linear-gradient( 32 | to right, 33 | #243b55, 34 | #141e30 35 | ); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ 36 | } 37 | 38 | .title, 39 | .channel, 40 | .users { 41 | font-family: 'Comfortaa', cursive; 42 | color: white; 43 | margin: 20px 0; 44 | margin-bottom: 10px; 45 | text-align: center; 46 | font-size: 40px; 47 | } 48 | 49 | .channel, 50 | .users { 51 | font-size: 30px; 52 | margin-bottom: 20px; 53 | margin-top: 40px; 54 | } 55 | 56 | .channel .input { 57 | max-width: 130pt; 58 | 59 | } 60 | 61 | .channel .small { 62 | font-size: 12pt; 63 | font-style: italic; 64 | } 65 | 66 | .channel { 67 | margin-top: 10px; 68 | margin-bottom: 10px; 69 | } 70 | 71 | .channel .row { 72 | 73 | } 74 | 75 | .button 76 | { 77 | background-color: black; 78 | padding: 10px; 79 | border: 1px solid #243b55; 80 | border-radius: 5px; 81 | cursor: pointer; 82 | } 83 | 84 | .button.active { 85 | background-color: #192235; 86 | } 87 | 88 | a { 89 | color: $blue; 90 | text-decoration: none; 91 | 92 | &:focus, 93 | &:hover { 94 | text-decoration: underline; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /common/styles/container.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | margin-left: auto; 3 | margin-right: auto; 4 | max-width: $screen-sm; 5 | padding-left: $space; 6 | padding-right: $space; 7 | width: 100%; 8 | } 9 | -------------------------------------------------------------------------------- /common/styles/main.scss: -------------------------------------------------------------------------------- 1 | .main { 2 | background: $white; 3 | min-height: 100vh; 4 | padding-bottom: $space-md; 5 | padding-top: $space-md; 6 | position: relative; 7 | z-index: $zindex-site; 8 | } 9 | -------------------------------------------------------------------------------- /common/styles/twitter.scss: -------------------------------------------------------------------------------- 1 | .resp-sharing-button__link, 2 | .resp-sharing-button__icon { 3 | display: inline-block; 4 | } 5 | 6 | .resp-sharing-button__link { 7 | text-decoration: none; 8 | color: #fff; 9 | margin: 0.5em; 10 | margin: auto; 11 | display: block; 12 | width: 110px; 13 | } 14 | 15 | .resp-sharing-button { 16 | border-radius: 5px; 17 | transition: 25ms ease-out; 18 | padding: 0.5em 0.75em; 19 | font-family: Helvetica Neue, Helvetica, Arial, sans-serif; 20 | } 21 | 22 | .resp-sharing-button__icon svg { 23 | width: 1em; 24 | height: 1em; 25 | margin-right: 0.4em; 26 | vertical-align: top; 27 | } 28 | 29 | .resp-sharing-button--small svg { 30 | margin: 0; 31 | vertical-align: middle; 32 | } 33 | 34 | /* Non solid icons get a stroke */ 35 | .resp-sharing-button__icon { 36 | stroke: #fff; 37 | fill: none; 38 | } 39 | 40 | /* Solid icons get a fill */ 41 | .resp-sharing-button__icon--solid, 42 | .resp-sharing-button__icon--solidcircle { 43 | fill: #fff; 44 | stroke: none; 45 | } 46 | 47 | .resp-sharing-button--twitter { 48 | background-color: #55acee; 49 | } 50 | 51 | .resp-sharing-button--twitter:hover { 52 | background-color: #2795e9; 53 | } 54 | 55 | .resp-sharing-button--pinterest { 56 | background-color: #bd081c; 57 | } 58 | 59 | .resp-sharing-button--pinterest:hover { 60 | background-color: #8c0615; 61 | } 62 | 63 | .resp-sharing-button--facebook { 64 | background-color: #3b5998; 65 | } 66 | 67 | .resp-sharing-button--facebook:hover { 68 | background-color: #2d4373; 69 | } 70 | 71 | .resp-sharing-button--tumblr { 72 | background-color: #35465c; 73 | } 74 | 75 | .resp-sharing-button--tumblr:hover { 76 | background-color: #222d3c; 77 | } 78 | 79 | .resp-sharing-button--reddit { 80 | background-color: #5f99cf; 81 | } 82 | 83 | .resp-sharing-button--reddit:hover { 84 | background-color: #3a80c1; 85 | } 86 | 87 | .resp-sharing-button--google { 88 | background-color: #dd4b39; 89 | } 90 | 91 | .resp-sharing-button--google:hover { 92 | background-color: #c23321; 93 | } 94 | 95 | .resp-sharing-button--linkedin { 96 | background-color: #0077b5; 97 | } 98 | 99 | .resp-sharing-button--linkedin:hover { 100 | background-color: #046293; 101 | } 102 | 103 | .resp-sharing-button--email { 104 | background-color: #777; 105 | } 106 | 107 | .resp-sharing-button--email:hover { 108 | background-color: #5e5e5e; 109 | } 110 | 111 | .resp-sharing-button--xing { 112 | background-color: #1a7576; 113 | } 114 | 115 | .resp-sharing-button--xing:hover { 116 | background-color: #114c4c; 117 | } 118 | 119 | .resp-sharing-button--whatsapp { 120 | background-color: #25d366; 121 | } 122 | 123 | .resp-sharing-button--whatsapp:hover { 124 | background-color: #1da851; 125 | } 126 | 127 | .resp-sharing-button--hackernews { 128 | background-color: #ff6600; 129 | } 130 | .resp-sharing-button--hackernews:hover, 131 | .resp-sharing-button--hackernews:focus { 132 | background-color: #fb6200; 133 | } 134 | 135 | .resp-sharing-button--vk { 136 | background-color: #507299; 137 | } 138 | 139 | .resp-sharing-button--vk:hover { 140 | background-color: #43648c; 141 | } 142 | 143 | .resp-sharing-button--twitter { 144 | background-color: #55acee; 145 | border-color: #55acee; 146 | } 147 | 148 | .resp-sharing-button--twitter:hover, 149 | .resp-sharing-button--twitter:active { 150 | background-color: #2795e9; 151 | border-color: #2795e9; 152 | } 153 | -------------------------------------------------------------------------------- /common/styles/variables.scss: -------------------------------------------------------------------------------- 1 | $gray-darker: #282828; 2 | $gray-dark: #333; 3 | $gray: #666; 4 | $gray-medium: #aaa; 5 | $gray-light: #c8c8c8; 6 | $gray-lighter: #dedede; 7 | $gray-white: #fafafa; 8 | $white: #fff; 9 | 10 | $yellow: #eade00; 11 | $blue: #0291a7; 12 | $blue-light: #aceff9; 13 | $red: #cc0000; 14 | $green: #afcc49; 15 | 16 | $space-xxs: 0.4rem; 17 | $space-xs: 0.8rem; 18 | $space-sm: 1.6rem; 19 | $space: 2.4rem; 20 | $space-md: 3.2rem; 21 | $space-lg: 4.8rem; 22 | $space-xlg: 6.4rem; 23 | $space-xxlg: 8.8rem; 24 | 25 | $drums-height: 80vh; 26 | 27 | $screen-xxs: 380px; 28 | $screen-xs: 440px; 29 | $screen-sm: 768px; 30 | $screen-md: 992px; 31 | $screen-lg: 1200px; 32 | $screen-xlg: 1400px; 33 | $screen-xxlg: 1600px; 34 | 35 | $zindex-drums: 1; 36 | $zindex-site: 10; 37 | -------------------------------------------------------------------------------- /common/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-regex@^2.0.0: 6 | version "2.1.1" 7 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 8 | 9 | ansi-styles@^2.2.1: 10 | version "2.2.1" 11 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 12 | 13 | babel-code-frame@^6.26.0: 14 | version "6.26.0" 15 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 16 | dependencies: 17 | chalk "^1.1.3" 18 | esutils "^2.0.2" 19 | js-tokens "^3.0.2" 20 | 21 | babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: 22 | version "6.24.1" 23 | resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" 24 | dependencies: 25 | babel-helper-explode-assignable-expression "^6.24.1" 26 | babel-runtime "^6.22.0" 27 | babel-types "^6.24.1" 28 | 29 | babel-helper-call-delegate@^6.24.1: 30 | version "6.24.1" 31 | resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" 32 | dependencies: 33 | babel-helper-hoist-variables "^6.24.1" 34 | babel-runtime "^6.22.0" 35 | babel-traverse "^6.24.1" 36 | babel-types "^6.24.1" 37 | 38 | babel-helper-define-map@^6.24.1: 39 | version "6.26.0" 40 | resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" 41 | dependencies: 42 | babel-helper-function-name "^6.24.1" 43 | babel-runtime "^6.26.0" 44 | babel-types "^6.26.0" 45 | lodash "^4.17.4" 46 | 47 | babel-helper-explode-assignable-expression@^6.24.1: 48 | version "6.24.1" 49 | resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" 50 | dependencies: 51 | babel-runtime "^6.22.0" 52 | babel-traverse "^6.24.1" 53 | babel-types "^6.24.1" 54 | 55 | babel-helper-function-name@^6.24.1: 56 | version "6.24.1" 57 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" 58 | dependencies: 59 | babel-helper-get-function-arity "^6.24.1" 60 | babel-runtime "^6.22.0" 61 | babel-template "^6.24.1" 62 | babel-traverse "^6.24.1" 63 | babel-types "^6.24.1" 64 | 65 | babel-helper-get-function-arity@^6.24.1: 66 | version "6.24.1" 67 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" 68 | dependencies: 69 | babel-runtime "^6.22.0" 70 | babel-types "^6.24.1" 71 | 72 | babel-helper-hoist-variables@^6.24.1: 73 | version "6.24.1" 74 | resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" 75 | dependencies: 76 | babel-runtime "^6.22.0" 77 | babel-types "^6.24.1" 78 | 79 | babel-helper-optimise-call-expression@^6.24.1: 80 | version "6.24.1" 81 | resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" 82 | dependencies: 83 | babel-runtime "^6.22.0" 84 | babel-types "^6.24.1" 85 | 86 | babel-helper-regex@^6.24.1: 87 | version "6.26.0" 88 | resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" 89 | dependencies: 90 | babel-runtime "^6.26.0" 91 | babel-types "^6.26.0" 92 | lodash "^4.17.4" 93 | 94 | babel-helper-remap-async-to-generator@^6.24.1: 95 | version "6.24.1" 96 | resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" 97 | dependencies: 98 | babel-helper-function-name "^6.24.1" 99 | babel-runtime "^6.22.0" 100 | babel-template "^6.24.1" 101 | babel-traverse "^6.24.1" 102 | babel-types "^6.24.1" 103 | 104 | babel-helper-replace-supers@^6.24.1: 105 | version "6.24.1" 106 | resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" 107 | dependencies: 108 | babel-helper-optimise-call-expression "^6.24.1" 109 | babel-messages "^6.23.0" 110 | babel-runtime "^6.22.0" 111 | babel-template "^6.24.1" 112 | babel-traverse "^6.24.1" 113 | babel-types "^6.24.1" 114 | 115 | babel-messages@^6.23.0: 116 | version "6.23.0" 117 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 118 | dependencies: 119 | babel-runtime "^6.22.0" 120 | 121 | babel-plugin-check-es2015-constants@^6.22.0: 122 | version "6.22.0" 123 | resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" 124 | dependencies: 125 | babel-runtime "^6.22.0" 126 | 127 | babel-plugin-syntax-async-functions@^6.8.0: 128 | version "6.13.0" 129 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" 130 | 131 | babel-plugin-syntax-exponentiation-operator@^6.8.0: 132 | version "6.13.0" 133 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" 134 | 135 | babel-plugin-syntax-trailing-function-commas@^6.22.0: 136 | version "6.22.0" 137 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" 138 | 139 | babel-plugin-transform-async-to-generator@^6.22.0: 140 | version "6.24.1" 141 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" 142 | dependencies: 143 | babel-helper-remap-async-to-generator "^6.24.1" 144 | babel-plugin-syntax-async-functions "^6.8.0" 145 | babel-runtime "^6.22.0" 146 | 147 | babel-plugin-transform-es2015-arrow-functions@^6.22.0: 148 | version "6.22.0" 149 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" 150 | dependencies: 151 | babel-runtime "^6.22.0" 152 | 153 | babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: 154 | version "6.22.0" 155 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" 156 | dependencies: 157 | babel-runtime "^6.22.0" 158 | 159 | babel-plugin-transform-es2015-block-scoping@^6.23.0: 160 | version "6.26.0" 161 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" 162 | dependencies: 163 | babel-runtime "^6.26.0" 164 | babel-template "^6.26.0" 165 | babel-traverse "^6.26.0" 166 | babel-types "^6.26.0" 167 | lodash "^4.17.4" 168 | 169 | babel-plugin-transform-es2015-classes@^6.23.0: 170 | version "6.24.1" 171 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" 172 | dependencies: 173 | babel-helper-define-map "^6.24.1" 174 | babel-helper-function-name "^6.24.1" 175 | babel-helper-optimise-call-expression "^6.24.1" 176 | babel-helper-replace-supers "^6.24.1" 177 | babel-messages "^6.23.0" 178 | babel-runtime "^6.22.0" 179 | babel-template "^6.24.1" 180 | babel-traverse "^6.24.1" 181 | babel-types "^6.24.1" 182 | 183 | babel-plugin-transform-es2015-computed-properties@^6.22.0: 184 | version "6.24.1" 185 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" 186 | dependencies: 187 | babel-runtime "^6.22.0" 188 | babel-template "^6.24.1" 189 | 190 | babel-plugin-transform-es2015-destructuring@^6.23.0: 191 | version "6.23.0" 192 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" 193 | dependencies: 194 | babel-runtime "^6.22.0" 195 | 196 | babel-plugin-transform-es2015-duplicate-keys@^6.22.0: 197 | version "6.24.1" 198 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" 199 | dependencies: 200 | babel-runtime "^6.22.0" 201 | babel-types "^6.24.1" 202 | 203 | babel-plugin-transform-es2015-for-of@^6.23.0: 204 | version "6.23.0" 205 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" 206 | dependencies: 207 | babel-runtime "^6.22.0" 208 | 209 | babel-plugin-transform-es2015-function-name@^6.22.0: 210 | version "6.24.1" 211 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" 212 | dependencies: 213 | babel-helper-function-name "^6.24.1" 214 | babel-runtime "^6.22.0" 215 | babel-types "^6.24.1" 216 | 217 | babel-plugin-transform-es2015-literals@^6.22.0: 218 | version "6.22.0" 219 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" 220 | dependencies: 221 | babel-runtime "^6.22.0" 222 | 223 | babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: 224 | version "6.24.1" 225 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" 226 | dependencies: 227 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 228 | babel-runtime "^6.22.0" 229 | babel-template "^6.24.1" 230 | 231 | babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: 232 | version "6.26.2" 233 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" 234 | dependencies: 235 | babel-plugin-transform-strict-mode "^6.24.1" 236 | babel-runtime "^6.26.0" 237 | babel-template "^6.26.0" 238 | babel-types "^6.26.0" 239 | 240 | babel-plugin-transform-es2015-modules-systemjs@^6.23.0: 241 | version "6.24.1" 242 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" 243 | dependencies: 244 | babel-helper-hoist-variables "^6.24.1" 245 | babel-runtime "^6.22.0" 246 | babel-template "^6.24.1" 247 | 248 | babel-plugin-transform-es2015-modules-umd@^6.23.0: 249 | version "6.24.1" 250 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" 251 | dependencies: 252 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 253 | babel-runtime "^6.22.0" 254 | babel-template "^6.24.1" 255 | 256 | babel-plugin-transform-es2015-object-super@^6.22.0: 257 | version "6.24.1" 258 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" 259 | dependencies: 260 | babel-helper-replace-supers "^6.24.1" 261 | babel-runtime "^6.22.0" 262 | 263 | babel-plugin-transform-es2015-parameters@^6.23.0: 264 | version "6.24.1" 265 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" 266 | dependencies: 267 | babel-helper-call-delegate "^6.24.1" 268 | babel-helper-get-function-arity "^6.24.1" 269 | babel-runtime "^6.22.0" 270 | babel-template "^6.24.1" 271 | babel-traverse "^6.24.1" 272 | babel-types "^6.24.1" 273 | 274 | babel-plugin-transform-es2015-shorthand-properties@^6.22.0: 275 | version "6.24.1" 276 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" 277 | dependencies: 278 | babel-runtime "^6.22.0" 279 | babel-types "^6.24.1" 280 | 281 | babel-plugin-transform-es2015-spread@^6.22.0: 282 | version "6.22.0" 283 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" 284 | dependencies: 285 | babel-runtime "^6.22.0" 286 | 287 | babel-plugin-transform-es2015-sticky-regex@^6.22.0: 288 | version "6.24.1" 289 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" 290 | dependencies: 291 | babel-helper-regex "^6.24.1" 292 | babel-runtime "^6.22.0" 293 | babel-types "^6.24.1" 294 | 295 | babel-plugin-transform-es2015-template-literals@^6.22.0: 296 | version "6.22.0" 297 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" 298 | dependencies: 299 | babel-runtime "^6.22.0" 300 | 301 | babel-plugin-transform-es2015-typeof-symbol@^6.23.0: 302 | version "6.23.0" 303 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" 304 | dependencies: 305 | babel-runtime "^6.22.0" 306 | 307 | babel-plugin-transform-es2015-unicode-regex@^6.22.0: 308 | version "6.24.1" 309 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" 310 | dependencies: 311 | babel-helper-regex "^6.24.1" 312 | babel-runtime "^6.22.0" 313 | regexpu-core "^2.0.0" 314 | 315 | babel-plugin-transform-exponentiation-operator@^6.22.0: 316 | version "6.24.1" 317 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" 318 | dependencies: 319 | babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" 320 | babel-plugin-syntax-exponentiation-operator "^6.8.0" 321 | babel-runtime "^6.22.0" 322 | 323 | babel-plugin-transform-regenerator@^6.22.0: 324 | version "6.26.0" 325 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" 326 | dependencies: 327 | regenerator-transform "^0.10.0" 328 | 329 | babel-plugin-transform-strict-mode@^6.24.1: 330 | version "6.24.1" 331 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" 332 | dependencies: 333 | babel-runtime "^6.22.0" 334 | babel-types "^6.24.1" 335 | 336 | babel-preset-env@^1.7.0: 337 | version "1.7.0" 338 | resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" 339 | dependencies: 340 | babel-plugin-check-es2015-constants "^6.22.0" 341 | babel-plugin-syntax-trailing-function-commas "^6.22.0" 342 | babel-plugin-transform-async-to-generator "^6.22.0" 343 | babel-plugin-transform-es2015-arrow-functions "^6.22.0" 344 | babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" 345 | babel-plugin-transform-es2015-block-scoping "^6.23.0" 346 | babel-plugin-transform-es2015-classes "^6.23.0" 347 | babel-plugin-transform-es2015-computed-properties "^6.22.0" 348 | babel-plugin-transform-es2015-destructuring "^6.23.0" 349 | babel-plugin-transform-es2015-duplicate-keys "^6.22.0" 350 | babel-plugin-transform-es2015-for-of "^6.23.0" 351 | babel-plugin-transform-es2015-function-name "^6.22.0" 352 | babel-plugin-transform-es2015-literals "^6.22.0" 353 | babel-plugin-transform-es2015-modules-amd "^6.22.0" 354 | babel-plugin-transform-es2015-modules-commonjs "^6.23.0" 355 | babel-plugin-transform-es2015-modules-systemjs "^6.23.0" 356 | babel-plugin-transform-es2015-modules-umd "^6.23.0" 357 | babel-plugin-transform-es2015-object-super "^6.22.0" 358 | babel-plugin-transform-es2015-parameters "^6.23.0" 359 | babel-plugin-transform-es2015-shorthand-properties "^6.22.0" 360 | babel-plugin-transform-es2015-spread "^6.22.0" 361 | babel-plugin-transform-es2015-sticky-regex "^6.22.0" 362 | babel-plugin-transform-es2015-template-literals "^6.22.0" 363 | babel-plugin-transform-es2015-typeof-symbol "^6.23.0" 364 | babel-plugin-transform-es2015-unicode-regex "^6.22.0" 365 | babel-plugin-transform-exponentiation-operator "^6.22.0" 366 | babel-plugin-transform-regenerator "^6.22.0" 367 | browserslist "^3.2.6" 368 | invariant "^2.2.2" 369 | semver "^5.3.0" 370 | 371 | babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: 372 | version "6.26.0" 373 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 374 | dependencies: 375 | core-js "^2.4.0" 376 | regenerator-runtime "^0.11.0" 377 | 378 | babel-template@^6.24.1, babel-template@^6.26.0: 379 | version "6.26.0" 380 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 381 | dependencies: 382 | babel-runtime "^6.26.0" 383 | babel-traverse "^6.26.0" 384 | babel-types "^6.26.0" 385 | babylon "^6.18.0" 386 | lodash "^4.17.4" 387 | 388 | babel-traverse@^6.24.1, babel-traverse@^6.26.0: 389 | version "6.26.0" 390 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 391 | dependencies: 392 | babel-code-frame "^6.26.0" 393 | babel-messages "^6.23.0" 394 | babel-runtime "^6.26.0" 395 | babel-types "^6.26.0" 396 | babylon "^6.18.0" 397 | debug "^2.6.8" 398 | globals "^9.18.0" 399 | invariant "^2.2.2" 400 | lodash "^4.17.4" 401 | 402 | babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: 403 | version "6.26.0" 404 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 405 | dependencies: 406 | babel-runtime "^6.26.0" 407 | esutils "^2.0.2" 408 | lodash "^4.17.4" 409 | to-fast-properties "^1.0.3" 410 | 411 | babylon@^6.18.0: 412 | version "6.18.0" 413 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 414 | 415 | browserslist@^3.2.6: 416 | version "3.2.8" 417 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" 418 | dependencies: 419 | caniuse-lite "^1.0.30000844" 420 | electron-to-chromium "^1.3.47" 421 | 422 | caniuse-lite@^1.0.30000844: 423 | version "1.0.30000880" 424 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000880.tgz#b7b6ceaf739e17d0dda0d89426cba4be16d07bb0" 425 | 426 | chalk@^1.1.3: 427 | version "1.1.3" 428 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 429 | dependencies: 430 | ansi-styles "^2.2.1" 431 | escape-string-regexp "^1.0.2" 432 | has-ansi "^2.0.0" 433 | strip-ansi "^3.0.0" 434 | supports-color "^2.0.0" 435 | 436 | core-js@^2.4.0: 437 | version "2.5.7" 438 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" 439 | 440 | debug@^2.6.8: 441 | version "2.6.9" 442 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 443 | dependencies: 444 | ms "2.0.0" 445 | 446 | electron-to-chromium@^1.3.47: 447 | version "1.3.61" 448 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.61.tgz#a8ac295b28d0f03d85e37326fd16b6b6b17a1795" 449 | 450 | escape-string-regexp@^1.0.2: 451 | version "1.0.5" 452 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 453 | 454 | esutils@^2.0.2: 455 | version "2.0.2" 456 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 457 | 458 | globals@^9.18.0: 459 | version "9.18.0" 460 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 461 | 462 | has-ansi@^2.0.0: 463 | version "2.0.0" 464 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 465 | dependencies: 466 | ansi-regex "^2.0.0" 467 | 468 | invariant@^2.2.2: 469 | version "2.2.4" 470 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 471 | dependencies: 472 | loose-envify "^1.0.0" 473 | 474 | "js-tokens@^3.0.0 || ^4.0.0": 475 | version "4.0.0" 476 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 477 | 478 | js-tokens@^3.0.2: 479 | version "3.0.2" 480 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 481 | 482 | jsesc@~0.5.0: 483 | version "0.5.0" 484 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 485 | 486 | lodash@^4.17.4: 487 | version "4.17.10" 488 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" 489 | 490 | loose-envify@^1.0.0: 491 | version "1.4.0" 492 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 493 | dependencies: 494 | js-tokens "^3.0.0 || ^4.0.0" 495 | 496 | ms@2.0.0: 497 | version "2.0.0" 498 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 499 | 500 | private@^0.1.6: 501 | version "0.1.8" 502 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" 503 | 504 | regenerate@^1.2.1: 505 | version "1.4.0" 506 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" 507 | 508 | regenerator-runtime@^0.11.0: 509 | version "0.11.1" 510 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" 511 | 512 | regenerator-transform@^0.10.0: 513 | version "0.10.1" 514 | resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" 515 | dependencies: 516 | babel-runtime "^6.18.0" 517 | babel-types "^6.19.0" 518 | private "^0.1.6" 519 | 520 | regexpu-core@^2.0.0: 521 | version "2.0.0" 522 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" 523 | dependencies: 524 | regenerate "^1.2.1" 525 | regjsgen "^0.2.0" 526 | regjsparser "^0.1.4" 527 | 528 | regjsgen@^0.2.0: 529 | version "0.2.0" 530 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" 531 | 532 | regjsparser@^0.1.4: 533 | version "0.1.5" 534 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" 535 | dependencies: 536 | jsesc "~0.5.0" 537 | 538 | semver@^5.3.0: 539 | version "5.5.1" 540 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" 541 | 542 | strip-ansi@^3.0.0: 543 | version "3.0.1" 544 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 545 | dependencies: 546 | ansi-regex "^2.0.0" 547 | 548 | supports-color@^2.0.0: 549 | version "2.0.0" 550 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 551 | 552 | to-fast-properties@^1.0.3: 553 | version "1.0.3" 554 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 555 | -------------------------------------------------------------------------------- /drums/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'standard' 3 | } 4 | -------------------------------------------------------------------------------- /drums/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | package-lock.json 4 | .DS_Store 5 | .vscode/settings.json 6 | -------------------------------------------------------------------------------- /drums/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "semi": false, 4 | "singleQuote": true, 5 | "overrides": [ 6 | { 7 | "files": "*.md", 8 | "options": { 9 | "printWidth": 70, 10 | "useTabs": false, 11 | "trailingComma": "none", 12 | "proseWrap": "never" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /drums/README.md: -------------------------------------------------------------------------------- 1 | # Magic Drums - Play drums with the world 2 | 3 | https://magicdrums.now.sh 4 | 5 | Drums that you can play anywhere and connects through websockets so that you can play drums with anyone. 6 | 7 | ## How to play 8 | 9 | Either click the keys or use the keys mentioned. 10 | 11 | ## Run 12 | 13 | ```bash 14 | git clone git@github.com:SaraVieira/magic-drums.git 15 | yarn 16 | yarn start 17 | ``` 18 | 19 | ## Atributtion 20 | 21 | SVG and Sound from https://tympanus.net/Tutorials/SVGDrums/ 22 | 23 | ## License 24 | 25 | WTFPL – Do What the Fuck You Want to Public License 26 | -------------------------------------------------------------------------------- /drums/license.md: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 2 | 3 | Copyright (C) 2004 Sam Hocevar 4 | 5 | Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. 6 | 7 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 8 | 9 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 10 | 11 | 0. You just DO WHAT THE FUCK YOU WANT TO. 12 | -------------------------------------------------------------------------------- /drums/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magic-drums", 3 | "version": "1.0.0", 4 | "description": "To play drums using CSS and JavaScript", 5 | "homepage": "https://github.com/SaraVieira/magic-drums", 6 | "browserslist": [ 7 | "> 1%", 8 | "last 2 versions" 9 | ], 10 | "author": { 11 | "name": "Sara Vieira", 12 | "email": "hey@iamsaravieira.com" 13 | }, 14 | "now": { 15 | "alias": "magicdrums", 16 | "files": [ 17 | "server.js", 18 | "dist" 19 | ] 20 | }, 21 | "scripts": { 22 | "start": "run-p serve watch", 23 | "now-start": "node server.js", 24 | "now-build": "echo $0", 25 | "build": "NODE_ENV=production webpack -p", 26 | "watch": "NODE_ENV=development webpack -w", 27 | "serve": "nodemon server.js", 28 | "lint": "eslint ./src/", 29 | "format": "prettier --write '**/*.{js,css,md}'" 30 | }, 31 | "dependencies": { 32 | "express": "4.16.3", 33 | "gsap": "^2.0.2", 34 | "howler": "2.0.15", 35 | "socket.io": "2.1.1", 36 | "webpack": "3.5.5" 37 | }, 38 | "devDependencies": { 39 | "autoprefixer": "9.1.3", 40 | "babel-core": "6.26.0", 41 | "babel-loader": "7.1.4", 42 | "babel-preset-env": "1.6.0", 43 | "clean-webpack-plugin": "0.1.19", 44 | "copy-webpack-plugin": "4.5.1", 45 | "css-loader": "0.28.5", 46 | "cssnano": "3.10.0", 47 | "eslint": "4.19.1", 48 | "eslint-config-standard": "11.0.0", 49 | "eslint-plugin-import": "2.14.0", 50 | "eslint-plugin-node": "7.0.1", 51 | "eslint-plugin-promise": "4.0.0", 52 | "eslint-plugin-standard": "3.1.0", 53 | "html-webpack-plugin": "3.2.0", 54 | "node-sass": "4.9.3", 55 | "nodemon": "1.18.3", 56 | "npm-run-all": "4.1.3", 57 | "postcss-loader": "2.1.3", 58 | "prettier": "1.14.2", 59 | "rucksack-css": "1.0.2", 60 | "sass-loader": "7.1.0", 61 | "style-loader": "0.18.2", 62 | "webpack-bundle-analyzer": "2.11.1", 63 | "webpack-dev-server": "2.7.1" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /drums/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | 'rucksack-css': {}, 5 | cssnano: {} 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /drums/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const path = require('path') 3 | const app = express() 4 | const http = require('http').Server(app) 5 | const io = require('socket.io')(http) 6 | 7 | const DIST_DIR = path.join(__dirname, 'dist') 8 | 9 | const users = { total: 0 } 10 | io.on('connection', socket => { 11 | // Handle user counts 12 | users.total++ 13 | socket.on('disconnect', () => { 14 | users.total-- 15 | io.emit('users', users.total) 16 | }) 17 | io.emit('users', users.total) 18 | 19 | // Handle incoming messages 20 | // Someone played a note 21 | socket.on('played note', key => { 22 | // send it just to their room 23 | if (socket.room) { 24 | socket.broadcast.to(socket.room).emit('played', key) 25 | } else { 26 | // fallback, shouldn't ever get here 27 | socket.broadcast.emit('played', key) 28 | } 29 | }) 30 | 31 | // User wants to change rooms 32 | socket.on('room', room => { 33 | if (socket.room) { 34 | socket.leave(socket.room) 35 | if (!users[socket.room]) { 36 | users[socket.room] = 0 37 | } 38 | users[socket.room]-- 39 | io.to(socket.room).emit('roomusers', users[socket.room]) 40 | } 41 | socket.room = room 42 | socket.join(room) 43 | 44 | if (!users[socket.room]) { 45 | users[socket.room] = 0 46 | } 47 | if (users[socket.room] < users.total) { 48 | users[socket.room]++ 49 | } 50 | io.to(socket.room).emit('roomusers', users[socket.room]) 51 | }) 52 | }) 53 | 54 | app.use(express.static(DIST_DIR)) 55 | 56 | app.get('/', (req, res) => { 57 | res.sendFile(path.join(DIST_DIR, 'index.html')) 58 | }) 59 | 60 | http.listen(3000, () => { 61 | console.log('listening on http://localhost:3000') 62 | }) 63 | -------------------------------------------------------------------------------- /drums/src/app.js: -------------------------------------------------------------------------------- 1 | import drums from './js/drums' 2 | import animations from './js/animations' 3 | import './app.scss' 4 | 5 | drums() 6 | animations() 7 | -------------------------------------------------------------------------------- /drums/src/app.scss: -------------------------------------------------------------------------------- 1 | @import '../common/styles/variables'; 2 | @import '../common/styles/base'; 3 | @import '../common/styles/container'; 4 | @import '../common/styles/main'; 5 | @import '../common/styles/twitter'; 6 | 7 | @import 'styles/drums'; 8 | -------------------------------------------------------------------------------- /drums/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/favicon.ico -------------------------------------------------------------------------------- /drums/src/images/piano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/images/piano.png -------------------------------------------------------------------------------- /drums/src/images/space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/images/space.png -------------------------------------------------------------------------------- /drums/src/images/space.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | space 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /drums/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Magic Drums - Play drums with the world 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | 30 |
31 |

Play the drums with the world 🌎

32 |
33 |

34 | Pick a room:
35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | For a private jam session, type a unique name in the "Custom" box and hit "Enter" for it to take affect.
Your friends will need to use this same room name.
43 |

44 |
45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | J 356 | 357 | 358 | 359 | H 360 | 361 | 362 | 363 | G 364 | 365 | 366 | 367 | F 368 | 369 | 370 | 371 | Y 372 | 373 | 374 | 375 | T 376 | 377 | 378 | 379 |
380 |
381 |
There playing the drums right now, and in this room.
382 | 383 | 389 | 390 | 391 | 392 | 393 | -------------------------------------------------------------------------------- /drums/src/js/animations.js: -------------------------------------------------------------------------------- 1 | import tweens from './tweens' 2 | 3 | export default () => { 4 | document.querySelectorAll('[data-key]').forEach(el => { 5 | const note = el.getAttribute('data-note') 6 | 7 | const handler = () => { 8 | tweens[note].restart() 9 | tweens[note].play() 10 | } 11 | 12 | el.addEventListener('touchstart', handler) 13 | el.addEventListener('click', handler) 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /drums/src/js/drums.js: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client' 2 | import notes from './notes' 3 | import isTouchDevice from '../../../common/js/touch' 4 | import setRoomButtons, { currentRoom } from '../../../common/js/rooms' 5 | import { pre, title } from '../../../common/js/utils' 6 | import tweens from './tweens' 7 | 8 | const socket = io() 9 | 10 | socket.on('connect', () => { 11 | socket.emit('room', currentRoom) 12 | }) 13 | 14 | socket.on('played', key => { 15 | notes[key].play() 16 | tweens[key].restart() 17 | tweens[key].play() 18 | }) 19 | 20 | socket.on('users', count => { 21 | const element = document.getElementById('users') 22 | element.innerHTML = `${pre(count)} ${count} ${title(count)}` 23 | }) 24 | 25 | socket.on('roomusers', count => { 26 | const element = document.getElementById('roomusers') 27 | element.innerHTML = `${pre(count)} ${count} ${title(count)}` 28 | }) 29 | 30 | const addKeyboardEvents = notes => { 31 | window.addEventListener('keydown', e => { 32 | const keyNo = e.which 33 | const $key = document.querySelector(`[data-key='${keyNo}']`) || '' 34 | 35 | if ($key) { 36 | const note = $key.getAttribute('data-note') 37 | socket.emit('played note', note) 38 | tweens[note].restart() 39 | tweens[note].play() 40 | notes[note].play() 41 | } 42 | }) 43 | } 44 | 45 | const addTapEvents = notes => { 46 | let mouseIsDown = false 47 | let lastKeyPlayed = null 48 | 49 | window.addEventListener('mousedown', e => { 50 | mouseIsDown = true 51 | }) 52 | window.addEventListener('mouseup', e => { 53 | mouseIsDown = false 54 | }) 55 | 56 | document.querySelectorAll('[data-key]').forEach(key => { 57 | const note = key.getAttribute('data-note') 58 | 59 | let handler = e => { 60 | socket.emit('played note', note) 61 | notes[note].play() 62 | lastKeyPlayed = note 63 | } 64 | 65 | let handlerMouseMove = e => { 66 | if (!mouseIsDown || lastKeyPlayed === note) { 67 | return false 68 | } 69 | 70 | handler(e) 71 | } 72 | 73 | if (isTouchDevice()) { 74 | key.addEventListener('touchstart', handler) 75 | } else { 76 | key.addEventListener('mousedown', handler) 77 | key.addEventListener('mousemove', handlerMouseMove) 78 | } 79 | }) 80 | } 81 | 82 | export default drums => { 83 | addKeyboardEvents(notes) 84 | addTapEvents(notes) 85 | setRoomButtons(socket) 86 | } 87 | -------------------------------------------------------------------------------- /drums/src/js/notes.js: -------------------------------------------------------------------------------- 1 | import { Howl } from 'howler' 2 | 3 | export default { 4 | 'big-tom': new Howl({ src: ['medias/big-tom.mp3'] }), 5 | rightTom: new Howl({ src: ['medias/small-tom.mp3'] }), 6 | leftTom: new Howl({ src: ['medias/small-tom.mp3'] }), 7 | crash: new Howl({ src: ['medias/crash.mp3'] }), 8 | floorTom: new Howl({ src: ['medias/floor-tom.mp3'] }), 9 | kick: new Howl({ src: ['medias/kick.mp3'] }), 10 | hiHat: new Howl({ src: ['medias/hi-hat.mp3'] }), 11 | snare: new Howl({ src: ['medias/snare.mp3'] }) 12 | } 13 | -------------------------------------------------------------------------------- /drums/src/js/tweens.js: -------------------------------------------------------------------------------- 1 | import { Elastic, Expo } from 'gsap/all' 2 | import TimelineMax from 'gsap/TimelineMax' 3 | 4 | const $ = id => document.getElementById(id) 5 | const crashCymbol = $('Crash-Cymbol') 6 | const leftTomDrumAll = $('Tom-Left-All') 7 | const leftTomDrum = $('Tom-Left-Drum') 8 | const rightTomDrumAll = $('Tom-Right-All') 9 | const rightTomDrum = $('Tom-Right-Drum') 10 | const floorTomDrumAll = $('Floor-Tom') 11 | const snareDrum = $('Snare-Drum') 12 | const kickDrumAll = $('Kick') 13 | const hiHatTop = $('Hi-Hat-Top') 14 | const hiHatBottom = $('Hi-Hat-Bottom') 15 | 16 | var crash = new TimelineMax({ 17 | paused: true 18 | }) 19 | 20 | crash 21 | .to(crashCymbol, 0.1, { rotation: 8, transformOrigin: '50% 50%' }) 22 | .to(crashCymbol, 1.5, { 23 | rotation: 0, 24 | transformOrigin: '50% 50%', 25 | ease: Elastic.easeOut.config(2.5, 0.3) 26 | }) 27 | 28 | var rightTom = new TimelineMax({ 29 | paused: true 30 | }) 31 | 32 | var leftTom = new TimelineMax({ 33 | paused: true 34 | }) 35 | leftTom 36 | .to(leftTomDrum, 0.1, { 37 | scaleX: 1.04, 38 | transformOrigin: '50% 50%', 39 | ease: Expo.easeOut 40 | }) 41 | .to( 42 | leftTomDrum, 43 | 0.1, 44 | { scaleY: 0.95, transformOrigin: '50% 50%', ease: Expo.easeOut }, 45 | '0' 46 | ) 47 | .to( 48 | leftTomDrumAll, 49 | 0.1, 50 | { rotation: -2.5, transformOrigin: '100% 50%', ease: Elastic.easeOut }, 51 | '0' 52 | ) 53 | .to(leftTomDrum, 0.4, { 54 | scale: 1, 55 | transformOrigin: '50% 50%', 56 | ease: Elastic.easeOut 57 | }) 58 | .to( 59 | leftTomDrumAll, 60 | 0.6, 61 | { rotation: 0, transformOrigin: '100% 50%', ease: Elastic.easeOut }, 62 | '-=0.4' 63 | ) 64 | 65 | rightTom 66 | .to(rightTomDrum, 0.1, { 67 | scaleX: 1.04, 68 | transformOrigin: '50% 50%', 69 | ease: Expo.easeOut 70 | }) 71 | .to( 72 | rightTomDrum, 73 | 0.1, 74 | { scaleY: 0.95, transformOrigin: '50% 50%', ease: Expo.easeOut }, 75 | '0' 76 | ) 77 | .to( 78 | rightTomDrumAll, 79 | 0.1, 80 | { rotation: 2.5, transformOrigin: '0 50%', ease: Elastic.easeOut }, 81 | '0' 82 | ) 83 | .to(rightTomDrum, 0.4, { 84 | scale: 1, 85 | transformOrigin: '50% 50%', 86 | ease: Elastic.easeOut 87 | }) 88 | .to( 89 | rightTomDrumAll, 90 | 0.6, 91 | { rotation: 0, transformOrigin: '0 50%', ease: Elastic.easeOut }, 92 | '-=0.4' 93 | ) 94 | 95 | var floorTom = new TimelineMax({ 96 | paused: true 97 | }) 98 | floorTom 99 | .to(floorTomDrumAll, 0.1, { 100 | scaleX: 1.02, 101 | transformOrigin: '50% 50%', 102 | ease: Expo.easeOut 103 | }) 104 | .to( 105 | floorTomDrumAll, 106 | 0.1, 107 | { scaleY: 0.95, transformOrigin: '50% 100%', ease: Expo.easeOut }, 108 | '0' 109 | ) 110 | .to(floorTomDrumAll, 0.4, { 111 | scale: 1, 112 | transformOrigin: '50% 100%', 113 | ease: Elastic.easeOut 114 | }) 115 | 116 | var snare = new TimelineMax({ 117 | paused: true 118 | }) 119 | snare 120 | .to(snareDrum, 0.1, { 121 | scaleX: 1.04, 122 | transformOrigin: '50% 50%', 123 | ease: Expo.easeOut 124 | }) 125 | .to( 126 | snareDrum, 127 | 0.1, 128 | { scaleY: 0.9, transformOrigin: '50% 100%', ease: Expo.easeOut }, 129 | '0' 130 | ) 131 | .to(snareDrum, 0.4, { 132 | scale: 1, 133 | transformOrigin: '50% 100%', 134 | ease: Elastic.easeOut 135 | }) 136 | 137 | var kick = new TimelineMax({ 138 | paused: true 139 | }) 140 | kick 141 | .to(kickDrumAll, 0.1, { 142 | scale: 1.02, 143 | transformOrigin: '50% 100%', 144 | ease: Expo.easeOut 145 | }) 146 | .to(kickDrumAll, 0.4, { 147 | scale: 1, 148 | transformOrigin: '50% 100%', 149 | ease: Elastic.easeOut 150 | }) 151 | 152 | var hiHat = new TimelineMax({ 153 | paused: true 154 | }) 155 | hiHat 156 | .to([hiHatTop, hiHatBottom], 0.1, { 157 | rotation: -4, 158 | transformOrigin: '50% 50%' 159 | }) 160 | .to([hiHatTop, hiHatBottom], 0.6, { 161 | rotation: 0, 162 | transformOrigin: '50% 50%', 163 | ease: Elastic.easeOut.config(1.5, 0.2) 164 | }) 165 | 166 | export default { 167 | hiHat, 168 | snare, 169 | kick, 170 | crash, 171 | leftTom, 172 | rightTom, 173 | floorTom 174 | } 175 | -------------------------------------------------------------------------------- /drums/src/medias/big-tom.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/big-tom.mp3 -------------------------------------------------------------------------------- /drums/src/medias/crash.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/crash.mp3 -------------------------------------------------------------------------------- /drums/src/medias/floor-tom.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/floor-tom.mp3 -------------------------------------------------------------------------------- /drums/src/medias/hi-hat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/hi-hat.mp3 -------------------------------------------------------------------------------- /drums/src/medias/kick.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/kick.mp3 -------------------------------------------------------------------------------- /drums/src/medias/small-tom.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/small-tom.mp3 -------------------------------------------------------------------------------- /drums/src/medias/snare.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/drums/src/medias/snare.mp3 -------------------------------------------------------------------------------- /drums/src/styles/drums.scss: -------------------------------------------------------------------------------- 1 | .container-drums { 2 | display: flex; 3 | align-items: center; 4 | height: 100%; 5 | padding: 2em 0 0 0; 6 | margin: 80px 0; 7 | } 8 | 9 | .screen-sm-hidden { 10 | transform: translateX(0); 11 | } 12 | 13 | .container-drums svg { 14 | width: 100%; 15 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 16 | } 17 | 18 | .container-drums svg g { 19 | cursor: pointer; 20 | } 21 | 22 | .demo-footer { 23 | position: absolute; 24 | z-index: 1000; 25 | top: 0; 26 | right: 0; 27 | display: flex; 28 | padding: 2em; 29 | } 30 | 31 | /* 32 | * --- Buttons --- 33 | */ 34 | 35 | .btn { 36 | font-size: 1.65em; 37 | font-weight: bold; 38 | line-height: 1; 39 | width: auto; 40 | margin: 0 0.125em; 41 | padding: 0.5rem; 42 | vertical-align: middle; 43 | text-decoration: none; 44 | color: #89939b; 45 | border: 0; 46 | border-radius: 2px; 47 | background: #b0b9c0; 48 | } 49 | 50 | .btn:focus, 51 | .btn:hover { 52 | color: #2d2e36; 53 | border-color: #2d2e36; 54 | outline: none; 55 | } 56 | 57 | .btn:focus { 58 | color: #89939b; 59 | } 60 | 61 | .btn .fa { 62 | vertical-align: middle; 63 | } 64 | 65 | /* 66 | * --- Keys --- 67 | */ 68 | 69 | // #All-Keys { 70 | // display: none; 71 | // } 72 | 73 | .space-img { 74 | transform: translateX(47.5%) translateY(90%); 75 | } 76 | 77 | .key-wrap { 78 | fill: #f3f8fc; 79 | user-select: none; 80 | position: relative; 81 | } 82 | 83 | .key-text { 84 | font-size: 62px; 85 | font-weight: bold; 86 | fill: #b0b9c0; 87 | user-select: none; 88 | } 89 | 90 | @media (min-width: 700px) { 91 | .content { 92 | display: flex; 93 | justify-content: center; 94 | } 95 | .container-sequencer { 96 | transition: transform 0.6s; 97 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 98 | } 99 | .container-sequencer.collapse { 100 | transform: translateX(-100%); 101 | } 102 | .container-drums { 103 | width: 50%; 104 | transform: translateX(50%); 105 | } 106 | .container-drums svg { 107 | max-height: 65%; 108 | transform: scale(1.25); 109 | transition: transform 0.6s; 110 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 111 | } 112 | .screen-sm-hidden { 113 | transform: translateX(0); 114 | } 115 | .screen-sm-hidden svg { 116 | transform: scale(0.85); 117 | } 118 | .btn-tooltip { 119 | position: relative; 120 | } 121 | .btn-tooltip::before, 122 | .btn-tooltip::after { 123 | position: absolute; 124 | left: 50%; 125 | pointer-events: none; 126 | opacity: 0; 127 | } 128 | .btn-tooltip:hover::before, 129 | .btn-tooltip:hover::after { 130 | opacity: 1; 131 | transition: opacity 0.3s ease, transform 0.3s ease; 132 | transition-delay: 0.1s; 133 | } 134 | .btn-tooltip::before { 135 | content: ''; 136 | z-index: 1001; 137 | top: 100%; 138 | width: 0; 139 | height: 0; 140 | margin: 0 0 0 -6px; 141 | pointer-events: none; 142 | border: solid transparent; 143 | border-width: 6px; 144 | border-color: transparent; 145 | border-bottom-color: #2d2e36; 146 | transform: translate3d(0, -5px, 0); 147 | } 148 | .btn-tooltip:hover::before { 149 | transform: translate3d(0, 0, 0); 150 | } 151 | .btn-tooltip::after { 152 | content: attr(aria-label); 153 | font-size: 0.41em; 154 | font-weight: bold; 155 | line-height: 1.2; 156 | z-index: 1000; 157 | top: 100%; 158 | margin: 12px 0 0 0; 159 | padding: 8px 10px; 160 | letter-spacing: 1px; 161 | text-transform: uppercase; 162 | color: #fff; 163 | border-radius: 3px; 164 | background: #2d2e36; 165 | transform: translate3d(-50%, -5px, 0); 166 | } 167 | .btn-tooltip:hover::after { 168 | transform: translate3d(-50%, 0, 0); 169 | } 170 | } 171 | 172 | @media (max-width: 500px) { 173 | .container-drums { 174 | align-items: flex-start; 175 | padding-top: 6em; 176 | } 177 | .btn-keys { 178 | display: none; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /drums/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const HtmlWebpackPlugin = require('html-webpack-plugin') 3 | const webpack = require('webpack') 4 | const CopyWebpackPlugin = require('copy-webpack-plugin') 5 | const CleanWebpackPlugin = require('clean-webpack-plugin') 6 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') 7 | .BundleAnalyzerPlugin 8 | const PROD = process.env.NODE_ENV === 'production' 9 | const DEV = process.env.NODE_ENV === 'development' 10 | 11 | const copyFiles = [ 12 | { from: './src/medias/', to: './medias' }, 13 | { from: './src/images/', to: './images' }, 14 | { from: './src/favicon.ico', to: './' } 15 | ] 16 | 17 | const baseWebpack = { 18 | entry: { 19 | app: './src/app.js' 20 | }, 21 | output: { 22 | path: path.resolve(__dirname, 'dist'), 23 | filename: '[name].bundle.js' 24 | }, 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.scss/, 29 | use: [ 30 | 'style-loader', 31 | { 32 | loader: 'css-loader', 33 | options: { importLoaders: 1 } 34 | }, 35 | 'postcss-loader', 36 | { 37 | loader: 'sass-loader' 38 | } 39 | ] 40 | }, 41 | { 42 | test: /\.js$/, 43 | exclude: /node_modules/, 44 | use: { 45 | loader: 'babel-loader', 46 | options: { 47 | presets: ['env'] 48 | } 49 | } 50 | } 51 | ] 52 | }, 53 | plugins: [ 54 | new webpack.DefinePlugin({ 55 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 56 | }), 57 | new CleanWebpackPlugin(['dist']), 58 | new HtmlWebpackPlugin({ 59 | hash: true, 60 | template: './src/index.html' 61 | }), 62 | new CopyWebpackPlugin(copyFiles) 63 | ] 64 | } 65 | 66 | if (PROD) { 67 | baseWebpack.plugins.push(new webpack.optimize.UglifyJsPlugin({})) 68 | baseWebpack.plugins.push( 69 | new BundleAnalyzerPlugin({ analyzerMode: 'disabled' }) 70 | ) 71 | } 72 | 73 | if (DEV) { 74 | baseWebpack.devServer = { 75 | contentBase: path.join(__dirname, 'dist'), 76 | compress: true, 77 | open: true, 78 | host: '0.0.0.0', 79 | disableHostCheck: true 80 | } 81 | } 82 | 83 | module.exports = env => { 84 | return baseWebpack 85 | } 86 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magic-instruments", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": { 6 | "name": "SaraVieira", 7 | "url": "https://iamsaravieira.com" 8 | }, 9 | "homepage": "https://github.com/SaraVieira/magic-instruments", 10 | "repository": "SaraVieira/magic-instruments", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "npm-run-all": "^4.1.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /piano/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'standard' 3 | } 4 | -------------------------------------------------------------------------------- /piano/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | package-lock.json 4 | .DS_Store 5 | .vscode/settings.json 6 | -------------------------------------------------------------------------------- /piano/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "semi": false, 4 | "singleQuote": true, 5 | "overrides": [ 6 | { 7 | "files": "*.md", 8 | "options": { 9 | "printWidth": 70, 10 | "useTabs": false, 11 | "trailingComma": "none", 12 | "proseWrap": "never" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /piano/README.md: -------------------------------------------------------------------------------- 1 | # Magic Piano - Play piano with the world 2 | 3 | https://magicpiano.now.sh 4 | 5 | Piano that you can play anywhere and connects through websockets so that you can play piano with anyone. 6 | 7 | Suggested here: https://twitter.com/CompuIves/status/1033464011721867264 8 | 9 | ## How to play 10 | 11 | Either click the keys or use the keyboard top two letter rows. 12 | 13 | ## Run 14 | 15 | ```bash 16 | git clone git@github.com:SaraVieira/magic-piano.git 17 | yarn 18 | yarn start 19 | ``` 20 | 21 | ## Atributtion 22 | 23 | Forked from https://github.com/LFeh/piano 24 | 25 | ## License 26 | 27 | WTFPL – Do What the Fuck You Want to Public License 28 | -------------------------------------------------------------------------------- /piano/license.md: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 2 | 3 | Copyright (C) 2004 Sam Hocevar 4 | 5 | Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. 6 | 7 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 8 | 9 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 10 | 11 | 0. You just DO WHAT THE FUCK YOU WANT TO. 12 | -------------------------------------------------------------------------------- /piano/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "magic-piano", 3 | "version": "1.0.0", 4 | "description": "To play piano using CSS and JavaScript", 5 | "homepage": "https://github.com/SaraVieira/magic-piano", 6 | "browserslist": [ 7 | "> 1%", 8 | "last 2 versions" 9 | ], 10 | "now": { 11 | "alias": "magicpiano", 12 | "files": [ 13 | "server.js", 14 | "dist" 15 | ] 16 | }, 17 | "author": { 18 | "name": "Sara Vieira", 19 | "email": "hey@iamsaravieira.com" 20 | }, 21 | "scripts": { 22 | "start": "run-p serve watch", 23 | "now-start": "node server.js", 24 | "build": "NODE_ENV=production webpack -p", 25 | "watch": "NODE_ENV=development webpack -w", 26 | "serve": "nodemon server.js", 27 | "lint": "eslint ./src/", 28 | "format": "prettier --write '**/*.{js,css,md}'" 29 | }, 30 | "dependencies": { 31 | "express": "4.16.3", 32 | "howler": "2.0.15", 33 | "socket.io": "2.1.1" 34 | }, 35 | "devDependencies": { 36 | "autoprefixer": "9.1.3", 37 | "babel-core": "6.26.0", 38 | "babel-loader": "7.1.4", 39 | "babel-preset-env": "1.6.0", 40 | "cssnano": "3.10.0", 41 | "eslint": "4.19.1", 42 | "eslint-config-standard": "11.0.0", 43 | "eslint-plugin-import": "2.14.0", 44 | "eslint-plugin-node": "7.0.1", 45 | "eslint-plugin-promise": "4.0.0", 46 | "eslint-plugin-standard": "3.1.0", 47 | "nodemon": "1.18.3", 48 | "npm-run-all": "4.1.3", 49 | "prettier": "1.14.2", 50 | "rucksack-css": "1.0.2", 51 | "clean-webpack-plugin": "0.1.19", 52 | "copy-webpack-plugin": "4.5.1", 53 | "css-loader": "^1.0.0", 54 | "html-webpack-plugin": "3.2.0", 55 | "node-sass": "4.9.3", 56 | "postcss-loader": "2.1.3", 57 | "sass-loader": "7.1.0", 58 | "style-loader": "0.18.2", 59 | "webpack": "3.5.5", 60 | "webpack-bundle-analyzer": "2.11.1" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /piano/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | 'rucksack-css': {}, 5 | cssnano: {} 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /piano/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const path = require('path') 3 | const app = express() 4 | const http = require('http').Server(app) 5 | const io = require('socket.io')(http) 6 | 7 | const DIST_DIR = path.join(__dirname, 'dist') 8 | 9 | const users = { total: 0 } 10 | io.on('connection', socket => { 11 | // Handle user counts 12 | users.total++ 13 | socket.on('disconnect', () => { 14 | users.total-- 15 | io.emit('users', users.total) 16 | }) 17 | io.emit('users', users.total) 18 | 19 | // Handle incoming messages 20 | // Someone played a note 21 | socket.on('played note', key => { 22 | // send it just to their room 23 | if (socket.room) { 24 | socket.broadcast.to(socket.room).emit('played', key) 25 | } else { 26 | // fallback, shouldn't ever get here 27 | socket.broadcast.emit('played', key) 28 | } 29 | }) 30 | 31 | // User wants to change rooms 32 | socket.on('room', room => { 33 | if (socket.room) { 34 | socket.leave(socket.room) 35 | if (!users[socket.room]) { 36 | users[socket.room] = 0 37 | } 38 | users[socket.room]-- 39 | io.to(socket.room).emit('roomusers', users[socket.room]) 40 | } 41 | socket.room = room 42 | socket.join(room) 43 | 44 | if (!users[socket.room]) { 45 | users[socket.room] = 0 46 | } 47 | if (users[socket.room] < users.total) { 48 | users[socket.room]++ 49 | } 50 | io.to(socket.room).emit('roomusers', users[socket.room]) 51 | }) 52 | }) 53 | 54 | app.use(express.static(DIST_DIR)) 55 | 56 | app.get('/', (req, res) => { 57 | res.sendFile(path.join(DIST_DIR, 'index.html')) 58 | }) 59 | 60 | http.listen(3000, () => { 61 | console.log('listening on http://localhost:3000') 62 | }) 63 | -------------------------------------------------------------------------------- /piano/src/app.js: -------------------------------------------------------------------------------- 1 | import piano from './js/piano' 2 | import './app.scss' 3 | 4 | piano() 5 | -------------------------------------------------------------------------------- /piano/src/app.scss: -------------------------------------------------------------------------------- 1 | @import '../common/styles/variables'; 2 | @import '../common/styles/base'; 3 | @import '../common/styles/container'; 4 | @import '../common/styles/main'; 5 | @import '../common/styles/twitter'; 6 | 7 | @import 'styles/piano'; 8 | -------------------------------------------------------------------------------- /piano/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/favicon.ico -------------------------------------------------------------------------------- /piano/src/images/piano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/images/piano.png -------------------------------------------------------------------------------- /piano/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Magic Piano - Play piano with the world 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | 30 |
31 |

Play the piano with the world 🌎

32 |
33 |

34 | Pick a room:
35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | For a private jam session, type a unique name in the "Custom" box and hit "Enter" for it to take affect.
Your friends will need to use this same room name.
43 |

44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
There playing the piano right now, and in this room.
101 | 102 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /piano/src/js/notes.js: -------------------------------------------------------------------------------- 1 | import { Howl } from 'howler' 2 | 3 | export default { 4 | '1C': new Howl({ src: ['medias/261-C.mp3'] }), 5 | '1Cs': new Howl({ src: ['medias/277-C-sharp.mp3'] }), 6 | '1D': new Howl({ src: ['medias/293-D.mp3'] }), 7 | '1Ds': new Howl({ src: ['medias/311-D-sharp.mp3'] }), 8 | '1E': new Howl({ src: ['medias/329-E.mp3'] }), 9 | '1F': new Howl({ src: ['medias/349-F.mp3'] }), 10 | '1Fs': new Howl({ src: ['medias/369F-sharp.mp3'] }), 11 | '1G': new Howl({ src: ['medias/391-G.mp3'] }), 12 | '1Gs': new Howl({ src: ['medias/415-G-sharp.mp3'] }), 13 | '2A': new Howl({ src: ['medias/440-A.mp3'] }), 14 | '2As': new Howl({ src: ['medias/466-A-sharp.mp3'] }), 15 | '2B': new Howl({ src: ['medias/495-B.mp3'] }), 16 | '2C': new Howl({ src: ['medias/523-C.mp3'] }), 17 | '2Cs': new Howl({ src: ['medias/545-C-sharp.mp3'] }), 18 | '2D': new Howl({ src: ['medias/587-D.mp3'] }), 19 | '2Ds': new Howl({ src: ['medias/622-D-sharp.mp3'] }), 20 | '2E': new Howl({ src: ['medias/659-E.mp3'] }), 21 | '2F': new Howl({ src: ['medias/698-F.mp3'] }), 22 | '2Fs': new Howl({ src: ['medias/698-F-sharp.mp3'] }), 23 | '2G': new Howl({ src: ['medias/783-G.mp3'] }), 24 | '2Gs': new Howl({ src: ['medias/830-G-sharp.mp3'] }), 25 | '3A': new Howl({ src: ['medias/880-A.mp3'] }), 26 | '3As': new Howl({ src: ['medias/932-A-sharp.mp3'] }), 27 | '3B': new Howl({ src: ['medias/987-B.mp3'] }) 28 | } 29 | -------------------------------------------------------------------------------- /piano/src/js/piano.js: -------------------------------------------------------------------------------- 1 | import io from 'socket.io-client' 2 | import notes from './notes' 3 | import isTouchDevice from '../../../common/js/touch' 4 | import setRoomButtons, { currentRoom } from '../../../common/js/rooms' 5 | import { pre, title } from '../../../common/js/utils' 6 | 7 | const socket = io() 8 | 9 | socket.on('connect', () => { 10 | socket.emit('room', currentRoom) 11 | }) 12 | 13 | socket.on('played', key => { 14 | const $key = document.querySelector(`[data-note='${key}']`) || '' 15 | notes[key].play() 16 | $key.classList.add('active') 17 | setTimeout(() => $key.classList.remove('active'), 100) 18 | }) 19 | 20 | socket.on('users', count => { 21 | const element = document.getElementById('users') 22 | element.innerHTML = `${pre(count)} ${count} ${title(count)}` 23 | }) 24 | 25 | socket.on('roomusers', count => { 26 | const element = document.getElementById('roomusers') 27 | element.innerHTML = `${pre(count)} ${count} ${title(count)}` 28 | }) 29 | 30 | const addKeyboardEvents = notes => { 31 | window.addEventListener('keydown', e => { 32 | const keyNo = e.which 33 | const $key = document.querySelector(`[data-key='${keyNo}']`) || '' 34 | 35 | if ($key) { 36 | const note = $key.getAttribute('data-note') 37 | socket.emit('played note', note) 38 | notes[note].play() 39 | $key.classList.add('active') 40 | setTimeout(() => $key.classList.remove('active'), 100) 41 | } 42 | }) 43 | } 44 | 45 | const addTapEvents = notes => { 46 | let mouseIsDown = false 47 | let lastKeyPlayed = null 48 | 49 | window.addEventListener('mousedown', e => { 50 | mouseIsDown = true 51 | }) 52 | window.addEventListener('mouseup', e => { 53 | mouseIsDown = false 54 | }) 55 | 56 | document.querySelectorAll('[data-key]').forEach(key => { 57 | const note = key.getAttribute('data-note') 58 | 59 | let handler = e => { 60 | socket.emit('played note', note) 61 | notes[note].play() 62 | lastKeyPlayed = note 63 | key.classList.add('active') 64 | setTimeout(() => key.classList.remove('active'), 100) 65 | } 66 | 67 | let handlerMouseMove = e => { 68 | if (!mouseIsDown || lastKeyPlayed === note) { 69 | return false 70 | } 71 | 72 | handler(e) 73 | } 74 | 75 | if (isTouchDevice()) { 76 | key.addEventListener('touchstart', handler) 77 | } else { 78 | key.addEventListener('mousedown', handler) 79 | key.addEventListener('mousemove', handlerMouseMove) 80 | } 81 | }) 82 | } 83 | 84 | export default piano => { 85 | addKeyboardEvents(notes) 86 | addTapEvents(notes) 87 | setRoomButtons() 88 | } 89 | -------------------------------------------------------------------------------- /piano/src/medias/1046-C.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/1046-C.mp3 -------------------------------------------------------------------------------- /piano/src/medias/220-A.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/220-A.mp3 -------------------------------------------------------------------------------- /piano/src/medias/246-B.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/246-B.mp3 -------------------------------------------------------------------------------- /piano/src/medias/261-C.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/261-C.mp3 -------------------------------------------------------------------------------- /piano/src/medias/277-C-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/277-C-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/293-D.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/293-D.mp3 -------------------------------------------------------------------------------- /piano/src/medias/311-D-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/311-D-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/329-E.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/329-E.mp3 -------------------------------------------------------------------------------- /piano/src/medias/349-F.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/349-F.mp3 -------------------------------------------------------------------------------- /piano/src/medias/369F-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/369F-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/391-G.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/391-G.mp3 -------------------------------------------------------------------------------- /piano/src/medias/415-G-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/415-G-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/440-A.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/440-A.mp3 -------------------------------------------------------------------------------- /piano/src/medias/466-A-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/466-A-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/495-B.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/495-B.mp3 -------------------------------------------------------------------------------- /piano/src/medias/523-C.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/523-C.mp3 -------------------------------------------------------------------------------- /piano/src/medias/545-C-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/545-C-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/587-D.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/587-D.mp3 -------------------------------------------------------------------------------- /piano/src/medias/622-D-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/622-D-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/659-E.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/659-E.mp3 -------------------------------------------------------------------------------- /piano/src/medias/698-F-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/698-F-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/698-F.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/698-F.mp3 -------------------------------------------------------------------------------- /piano/src/medias/783-G.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/783-G.mp3 -------------------------------------------------------------------------------- /piano/src/medias/830-G-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/830-G-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/880-A.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/880-A.mp3 -------------------------------------------------------------------------------- /piano/src/medias/932-A-sharp.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/932-A-sharp.mp3 -------------------------------------------------------------------------------- /piano/src/medias/987-B.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaraVieira/magic-instruments/7c436b5dea8aca35841ae8a548f5be07162d1824/piano/src/medias/987-B.mp3 -------------------------------------------------------------------------------- /piano/src/styles/piano.scss: -------------------------------------------------------------------------------- 1 | .piano { 2 | display: flex; 3 | height: 80vh; 4 | justify-content: center; 5 | overflow: hidden; 6 | user-select: none; 7 | -webkit-user-drag: none; 8 | user-drag: none; 9 | cursor: pointer; 10 | 11 | @media screen and (min-height: $screen-xs) { 12 | height: $piano-height; 13 | max-height: 420px; 14 | } 15 | 16 | @media screen and (max-width: $screen-xs) { 17 | height: 300px; 18 | max-height: 100%; 19 | } 20 | 21 | &-key { 22 | flex: 1; 23 | margin: 0, $space-xxs / 4; 24 | max-width: $space-xxlg; 25 | position: relative; 26 | 27 | @media screen and (max-width: $screen-xs) { 28 | &:nth-child(1), 29 | &:nth-child(2), 30 | &:nth-child(3), 31 | &:nth-child(11), 32 | &:nth-child(12), 33 | &:nth-child(13), 34 | &:nth-child(14) { 35 | display: none; 36 | } 37 | } 38 | 39 | &__white { 40 | background: linear-gradient(-30deg, #f8f8f8, #fff); 41 | box-shadow: inset 0 1px 0px rgba(255, 255, 255, 1), 42 | inset 0 -1px 0px rgba(255, 255, 255, 1), 43 | inset 1px 0px 0px rgba(255, 255, 255, 1), 44 | inset -1px 0px 0px rgba(255, 255, 255, 1), 0 4px 3px rgba(0, 0, 0, 0.3), 45 | inset 0 -1px 0px rgba(255, 255, 255, 1), 46 | inset 1px 0px 0px rgba(255, 255, 255, 1), 47 | inset -1px -1px 15px rgba(0, 0, 0, 0.3), -3px 4px 6px rgba(0, 0, 0, 0.3); 48 | height: 100%; 49 | position: relative; 50 | 51 | &.active { 52 | box-shadow: inset 0 1px 0px rgba(255, 255, 255, 1), 53 | inset 0 -1px 0px rgba(255, 255, 255, 1), 54 | inset 1px 0px 0px rgba(255, 255, 255, 1), 55 | inset -1px 0px 0px rgba(255, 255, 255, 1), 56 | 0 4px 3px rgba(0, 0, 0, 0.7), inset 0 -1px 0px rgba(255, 255, 255, 1), 57 | inset 1px 0px 0px rgba(255, 255, 255, 1), 58 | inset -1px -1px 15px rgba(0, 0, 0, 0.5), 59 | -3px 4px 6px rgba(0, 0, 0, 0.3); 60 | height: calc(100% - #{$space-xxs}); 61 | position: relative; 62 | top: -($space-xxs); 63 | } 64 | } 65 | 66 | &__black { 67 | background: linear-gradient(-20deg, #222, #000, #222); 68 | box-shadow: inset 0px -1px 2px rgba(255, 255, 255, 0.4), 69 | 0 2px 3px rgba(0, 0, 0, 0.4); 70 | border-width: $space-xxs / 2 $space-xxs, $space-xs + $space-xxs; 71 | border-style: solid; 72 | border-color: #666 #222 #111 #555; 73 | height: 60%; 74 | left: 100%; 75 | position: absolute; 76 | transform: translateX(-50%); 77 | top: 0; 78 | width: 70%; 79 | z-index: $zindex-piano; 80 | 81 | &:active, 82 | &.active { 83 | border-bottom-width: $space-xxs; 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /piano/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const HtmlWebpackPlugin = require('html-webpack-plugin') 3 | const webpack = require('webpack') 4 | const CopyWebpackPlugin = require('copy-webpack-plugin') 5 | const CleanWebpackPlugin = require('clean-webpack-plugin') 6 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') 7 | .BundleAnalyzerPlugin 8 | const PROD = process.env.NODE_ENV === 'production' 9 | const DEV = process.env.NODE_ENV === 'development' 10 | 11 | const copyFiles = [ 12 | { from: './src/medias/', to: './medias' }, 13 | { from: './src/images/', to: './images' }, 14 | { from: './src/favicon.ico', to: './' } 15 | ] 16 | 17 | const baseWebpack = { 18 | entry: { 19 | app: './src/app.js' 20 | }, 21 | output: { 22 | path: path.resolve(__dirname, 'dist'), 23 | filename: '[name].bundle.js' 24 | }, 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.scss/, 29 | use: [ 30 | 'style-loader', 31 | { 32 | loader: 'css-loader', 33 | options: { importLoaders: 1 } 34 | }, 35 | 'postcss-loader', 36 | { 37 | loader: 'sass-loader' 38 | } 39 | ] 40 | }, 41 | { 42 | test: /\.js$/, 43 | exclude: /node_modules/, 44 | use: { 45 | loader: 'babel-loader', 46 | options: { 47 | presets: ['env'] 48 | } 49 | } 50 | } 51 | ] 52 | }, 53 | plugins: [ 54 | new webpack.DefinePlugin({ 55 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) 56 | }), 57 | new CleanWebpackPlugin(['dist']), 58 | new HtmlWebpackPlugin({ 59 | hash: true, 60 | template: './src/index.html' 61 | }), 62 | new CopyWebpackPlugin(copyFiles) 63 | ] 64 | } 65 | 66 | if (PROD) { 67 | baseWebpack.plugins.push(new webpack.optimize.UglifyJsPlugin({})) 68 | baseWebpack.plugins.push( 69 | new BundleAnalyzerPlugin({ analyzerMode: 'disabled' }) 70 | ) 71 | } 72 | 73 | if (DEV) { 74 | baseWebpack.devServer = { 75 | contentBase: path.join(__dirname, 'dist'), 76 | compress: true, 77 | open: true, 78 | host: '0.0.0.0', 79 | disableHostCheck: true 80 | } 81 | } 82 | 83 | module.exports = env => { 84 | return baseWebpack 85 | } 86 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 6 | version "3.2.1" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 8 | dependencies: 9 | color-convert "^1.9.0" 10 | 11 | array-filter@~0.0.0: 12 | version "0.0.1" 13 | resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" 14 | 15 | array-map@~0.0.0: 16 | version "0.0.0" 17 | resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" 18 | 19 | array-reduce@~0.0.0: 20 | version "0.0.0" 21 | resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" 22 | 23 | balanced-match@^1.0.0: 24 | version "1.0.0" 25 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 26 | 27 | brace-expansion@^1.1.7: 28 | version "1.1.11" 29 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 30 | dependencies: 31 | balanced-match "^1.0.0" 32 | concat-map "0.0.1" 33 | 34 | builtin-modules@^1.0.0: 35 | version "1.1.1" 36 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 37 | 38 | chalk@^2.1.0: 39 | version "2.4.1" 40 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" 41 | dependencies: 42 | ansi-styles "^3.2.1" 43 | escape-string-regexp "^1.0.5" 44 | supports-color "^5.3.0" 45 | 46 | color-convert@^1.9.0: 47 | version "1.9.3" 48 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 49 | dependencies: 50 | color-name "1.1.3" 51 | 52 | color-name@1.1.3: 53 | version "1.1.3" 54 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 55 | 56 | concat-map@0.0.1: 57 | version "0.0.1" 58 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 59 | 60 | cross-spawn@^6.0.4: 61 | version "6.0.5" 62 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" 63 | dependencies: 64 | nice-try "^1.0.4" 65 | path-key "^2.0.1" 66 | semver "^5.5.0" 67 | shebang-command "^1.2.0" 68 | which "^1.2.9" 69 | 70 | define-properties@^1.1.2: 71 | version "1.1.3" 72 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" 73 | dependencies: 74 | object-keys "^1.0.12" 75 | 76 | duplexer@~0.1.1: 77 | version "0.1.1" 78 | resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" 79 | 80 | error-ex@^1.3.1: 81 | version "1.3.2" 82 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" 83 | dependencies: 84 | is-arrayish "^0.2.1" 85 | 86 | es-abstract@^1.4.3: 87 | version "1.12.0" 88 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" 89 | dependencies: 90 | es-to-primitive "^1.1.1" 91 | function-bind "^1.1.1" 92 | has "^1.0.1" 93 | is-callable "^1.1.3" 94 | is-regex "^1.0.4" 95 | 96 | es-to-primitive@^1.1.1: 97 | version "1.1.1" 98 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" 99 | dependencies: 100 | is-callable "^1.1.1" 101 | is-date-object "^1.0.1" 102 | is-symbol "^1.0.1" 103 | 104 | escape-string-regexp@^1.0.5: 105 | version "1.0.5" 106 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 107 | 108 | event-stream@~3.3.0: 109 | version "3.3.4" 110 | resolved "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" 111 | dependencies: 112 | duplexer "~0.1.1" 113 | from "~0" 114 | map-stream "~0.1.0" 115 | pause-stream "0.0.11" 116 | split "0.3" 117 | stream-combiner "~0.0.4" 118 | through "~2.3.1" 119 | 120 | from@~0: 121 | version "0.1.7" 122 | resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" 123 | 124 | function-bind@^1.0.2, function-bind@^1.1.1: 125 | version "1.1.1" 126 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 127 | 128 | graceful-fs@^4.1.2: 129 | version "4.1.11" 130 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 131 | 132 | has-flag@^3.0.0: 133 | version "3.0.0" 134 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 135 | 136 | has@^1.0.1: 137 | version "1.0.3" 138 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 139 | dependencies: 140 | function-bind "^1.1.1" 141 | 142 | hosted-git-info@^2.1.4: 143 | version "2.7.1" 144 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" 145 | 146 | is-arrayish@^0.2.1: 147 | version "0.2.1" 148 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 149 | 150 | is-builtin-module@^1.0.0: 151 | version "1.0.0" 152 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" 153 | dependencies: 154 | builtin-modules "^1.0.0" 155 | 156 | is-callable@^1.1.1, is-callable@^1.1.3: 157 | version "1.1.4" 158 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" 159 | 160 | is-date-object@^1.0.1: 161 | version "1.0.1" 162 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 163 | 164 | is-regex@^1.0.4: 165 | version "1.0.4" 166 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 167 | dependencies: 168 | has "^1.0.1" 169 | 170 | is-symbol@^1.0.1: 171 | version "1.0.1" 172 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" 173 | 174 | isexe@^2.0.0: 175 | version "2.0.0" 176 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 177 | 178 | json-parse-better-errors@^1.0.1: 179 | version "1.0.2" 180 | resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" 181 | 182 | jsonify@~0.0.0: 183 | version "0.0.0" 184 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 185 | 186 | load-json-file@^4.0.0: 187 | version "4.0.0" 188 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" 189 | dependencies: 190 | graceful-fs "^4.1.2" 191 | parse-json "^4.0.0" 192 | pify "^3.0.0" 193 | strip-bom "^3.0.0" 194 | 195 | map-stream@~0.1.0: 196 | version "0.1.0" 197 | resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" 198 | 199 | memorystream@^0.3.1: 200 | version "0.3.1" 201 | resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" 202 | 203 | minimatch@^3.0.4: 204 | version "3.0.4" 205 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 206 | dependencies: 207 | brace-expansion "^1.1.7" 208 | 209 | nice-try@^1.0.4: 210 | version "1.0.5" 211 | resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" 212 | 213 | normalize-package-data@^2.3.2: 214 | version "2.4.0" 215 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 216 | dependencies: 217 | hosted-git-info "^2.1.4" 218 | is-builtin-module "^1.0.0" 219 | semver "2 || 3 || 4 || 5" 220 | validate-npm-package-license "^3.0.1" 221 | 222 | npm-run-all@^4.1.3: 223 | version "4.1.3" 224 | resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.3.tgz#49f15b55a66bb4101664ce270cb18e7103f8f185" 225 | dependencies: 226 | ansi-styles "^3.2.0" 227 | chalk "^2.1.0" 228 | cross-spawn "^6.0.4" 229 | memorystream "^0.3.1" 230 | minimatch "^3.0.4" 231 | ps-tree "^1.1.0" 232 | read-pkg "^3.0.0" 233 | shell-quote "^1.6.1" 234 | string.prototype.padend "^3.0.0" 235 | 236 | object-keys@^1.0.12: 237 | version "1.0.12" 238 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" 239 | 240 | parse-json@^4.0.0: 241 | version "4.0.0" 242 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" 243 | dependencies: 244 | error-ex "^1.3.1" 245 | json-parse-better-errors "^1.0.1" 246 | 247 | path-key@^2.0.1: 248 | version "2.0.1" 249 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 250 | 251 | path-type@^3.0.0: 252 | version "3.0.0" 253 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" 254 | dependencies: 255 | pify "^3.0.0" 256 | 257 | pause-stream@0.0.11: 258 | version "0.0.11" 259 | resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" 260 | dependencies: 261 | through "~2.3" 262 | 263 | pify@^3.0.0: 264 | version "3.0.0" 265 | resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" 266 | 267 | ps-tree@^1.1.0: 268 | version "1.1.0" 269 | resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" 270 | dependencies: 271 | event-stream "~3.3.0" 272 | 273 | read-pkg@^3.0.0: 274 | version "3.0.0" 275 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" 276 | dependencies: 277 | load-json-file "^4.0.0" 278 | normalize-package-data "^2.3.2" 279 | path-type "^3.0.0" 280 | 281 | "semver@2 || 3 || 4 || 5", semver@^5.5.0: 282 | version "5.5.1" 283 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" 284 | 285 | shebang-command@^1.2.0: 286 | version "1.2.0" 287 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 288 | dependencies: 289 | shebang-regex "^1.0.0" 290 | 291 | shebang-regex@^1.0.0: 292 | version "1.0.0" 293 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 294 | 295 | shell-quote@^1.6.1: 296 | version "1.6.1" 297 | resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" 298 | dependencies: 299 | array-filter "~0.0.0" 300 | array-map "~0.0.0" 301 | array-reduce "~0.0.0" 302 | jsonify "~0.0.0" 303 | 304 | spdx-correct@^3.0.0: 305 | version "3.0.0" 306 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" 307 | dependencies: 308 | spdx-expression-parse "^3.0.0" 309 | spdx-license-ids "^3.0.0" 310 | 311 | spdx-exceptions@^2.1.0: 312 | version "2.1.0" 313 | resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" 314 | 315 | spdx-expression-parse@^3.0.0: 316 | version "3.0.0" 317 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" 318 | dependencies: 319 | spdx-exceptions "^2.1.0" 320 | spdx-license-ids "^3.0.0" 321 | 322 | spdx-license-ids@^3.0.0: 323 | version "3.0.0" 324 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" 325 | 326 | split@0.3: 327 | version "0.3.3" 328 | resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" 329 | dependencies: 330 | through "2" 331 | 332 | stream-combiner@~0.0.4: 333 | version "0.0.4" 334 | resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" 335 | dependencies: 336 | duplexer "~0.1.1" 337 | 338 | string.prototype.padend@^3.0.0: 339 | version "3.0.0" 340 | resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" 341 | dependencies: 342 | define-properties "^1.1.2" 343 | es-abstract "^1.4.3" 344 | function-bind "^1.0.2" 345 | 346 | strip-bom@^3.0.0: 347 | version "3.0.0" 348 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 349 | 350 | supports-color@^5.3.0: 351 | version "5.5.0" 352 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 353 | dependencies: 354 | has-flag "^3.0.0" 355 | 356 | through@2, through@~2.3, through@~2.3.1: 357 | version "2.3.8" 358 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 359 | 360 | validate-npm-package-license@^3.0.1: 361 | version "3.0.4" 362 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" 363 | dependencies: 364 | spdx-correct "^3.0.0" 365 | spdx-expression-parse "^3.0.0" 366 | 367 | which@^1.2.9: 368 | version "1.3.1" 369 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 370 | dependencies: 371 | isexe "^2.0.0" 372 | --------------------------------------------------------------------------------