🔛 Initial commit

This commit is contained in:
matteo78 2014-11-08 18:52:36 +01:00
parent 8c0e175ce0
commit 58e41f8fc9
90 changed files with 57784 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build/*
node_modules/*
music/*

207
App.js Normal file
View File

@ -0,0 +1,207 @@
/*jshint node:true, nomen:true */
'use strict';
var app = require('app');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');
var net = require('net');
var util = require('util');
var events = require('events');
/**
* App
*
* Controls the app flow
*/
function App() {
this.windows = [];
this.ready = false;
this.visible = true;
app.on('ready', function () {
this.ready = true;
}.bind(this));
app.on('window-all-closed', function () {
app.quit();
});
events.EventEmitter.call(this);
}
util.inherits(App, events.EventEmitter);
module.exports = App;
App.socket = '\\\\.\\pipe\\piano-sock';
/**
* Add a new window
*
* Open a window and add it to the
* window stack. Returns window instance.
*
* @param {options: Object} Window options (see atom-shell docs)
*/
App.prototype.addWindow = function (options) {
var window = new BrowserWindow(options),
index = this.windows.length;
window.on('closed', function () {
this.windows.splice(index, 1);
}.bind(this));
this.windows.push(window);
return window;
};
/**
* Fetch options
*
* Gather options in a litteral from
* argv parameters.
*/
App.prototype.fetchOptions = function () {
var argv, i, arg, options = {};
argv = process.argv.slice(1);
for (i in argv) {
if (argv.hasOwnProperty(i)) {
arg = argv[i];
if (arg[0] !== '-') {
options.file = arg;
}
}
}
this.emit('options', options);
return options;
};
/**
* Chain options
*
* Pass current options to the instance that
* is already opened, if there is one.
* Otherwise, code in callback is executed,
* and server is launched.
*
* @param {callback: function} Function to call if this is the first instance
*/
App.prototype.chainOptions = function (callback) {
var client;
client = net.connect({
path: App.socket
}, function () {
// if the connection is established,
// an instance is already running.
// Pass on parameters and close app.
client.write(
JSON.stringify(this.fetchOptions()),
function () {
client.end();
app.terminate();
}
);
}.bind(this));
client.on('error', function (err) {
// if an error occurred, that means no
// server was created yet: this is the
// first instance
this.startServer();
if (this.ready) {
callback();
} else {
app.on('ready', callback);
}
}.bind(this));
};
/**
* Start app server
*
* Start a server on App.socket path, waiting
* for new instances to pass their options.
*/
App.prototype.startServer = function () {
var server;
server = net.createServer(function (connection) {
connection.on('data', function (data) {
this.windows[0].focus();
this.emit('options', JSON.parse(data));
}.bind(this));
}.bind(this));
server.listen(App.socket);
};
/**
* Add a switch
*
* @param {switch: string} Switch name
* @param {value: mixed} Switch value
*/
App.prototype.addSwitch = function (name, value) {
app.commandLine.appendSwitch(name, value);
};
/**
* Start the app
*
* Check if another instance is already opened,
* if so, transmit options and close instantly.
* Otherwise, open main window.
*/
App.prototype.start = function () {
this.chainOptions(function () {
// enable MIDI support
this.addSwitch('enable-web-midi');
// create main window
var window = this.addWindow({
title: 'Piano',
icon: __dirname + '/images/logos/logo32.png',
'min-width': 750,
'min-height': 400,
width: 937,
height: 500,
show: false
});
window.loadUrl('file://' + __dirname + '/index.html');
// FIXME: atom-shell currently doesn't have a
// minimize/restore event, so we poll
//
// https://github.com/atom/atom-shell/issues/73
setInterval(function () {
if (this.visible && window.isMinimized()) {
this.visible = false;
window.webContents.send('visible', false);
}
if (!this.visible && !window.isMinimized()) {
this.visible = true;
window.webContents.send('visible', true);
}
}.bind(this), 500);
// start sending options
this.on('options', function (options) {
window.webContents.send('options', options);
});
ipc.on('ready', function () {
window.show();
window.focus();
window.webContents.send('visible', true);
this.fetchOptions();
}.bind(this));
}.bind(this));
};

96
Gruntfile.js Normal file
View File

@ -0,0 +1,96 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
repo: 'atom/atom-shell',
releases: 'https://api.github.com/repos/<%= repo %>/releases',
pkg: grunt.file.readJSON('package.json'),
meta: {
CompanyName: '<%= pkg.author.name %>',
FileDescription: '<%= pkg.name %>',
FileVersion: '<%= pkg.version %>',
InternalName: '<%= pkg.name.toLowerCase() %>.exe',
LegalCopyright: 'Copyright (C) <%= grunt.template.' +
'today("yyyy") %> <%= pkg.author.name %>',
OriginalFilename: '<%= pkg.name.toLowerCase() %>.exe',
ProductName: '<%= pkg.name %>',
ProductVersion: '<%= pkg.version %>'
},
files: [
'css/**',
'js/**',
'images/**',
'App.js',
'index.html',
'LICENSE',
'main.js',
'package.json'
],
paths: {
resources: {
win: 'win/resources',
mac: 'mac/Atom.app/Contents/Resources',
linux: 'linux/resources'
},
originalExe: {
win: 'win/atom.exe',
mac: 'mac/Atom.app',
linux: 'linux/atom'
},
exe: {
win: 'win/<%= pkg.name.toLowerCase() %>.exe',
mac: 'mac/<%= pkg.name %>.app',
linux: 'linux/<%= pkg.name.toLowerCase() %>'
}
},
platforms: {
win: 'win32-ia32',
mac: 'darwin-x64',
linux: 'linux-x64'
}
});
// load tasks defined in grunt/
grunt.loadTasks('grunt');
// create aliases
grunt.registerTask(
'build',
'Fetch last shell release and build application',
function (platform) {
var tasks = [
'clean:clean-build',
'mkdir:create-build',
'http:find-asset',
'curl:fetch-asset',
'unzip:extract-asset',
'clean:clean-default',
'rename:rename-exe',
'rebrand:rebrand-exe',
'copy:copy-files'
], length = tasks.length, i;
for (i = 0; i < length; i += 1) {
tasks[i] = tasks[i] + ':' + platform;
}
grunt.task.run(tasks);
}
);
grunt.registerTask(
'auto-update',
'Automatically rebuild application whenever a file changes',
function (platform) {
grunt.task.run('watch:watch-changes:' + platform);
}
);
};

19
LICENSE Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2014 Mattéo DELABRE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# Building
Using Grunt:
```sh
$ npm install
$ grunt build:win # use build:linux or build:mac for other systems
```
Then run the app in `build/win` folder.
# Credits
Icons made by:
- Freepik (http://freepik.com) from http://flaticon.com (CC BY 3.0);
- Icons8 (http://icons8.com) from http://flaticon.com (CC BY 3.0).

147
css/dialog-theme.css Normal file
View File

@ -0,0 +1,147 @@
/**
* Dialog Theme
* Based on top theme
*/
/**
* Animations
*/
/* drop in */
@-webkit-keyframes vex-dropin {
0% {
transform: translateY(0);
opacity: 0;
}
1% {
transform: translateY(-800px);
opacity: 0;
}
2% {
transform: translateY(-800px);
opacity: 1;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
/* drop out */
@-webkit-keyframes vex-dropout {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-800px);
}
}
/**
* Content
*/
.vex.dialog-theme.vex-closing .vex-content {
-webkit-animation: vex-dropout 0.5s;
backface-visibility: hidden;
}
.vex.dialog-theme .vex-content {
-webkit-animation: vex-dropin 0.5s;
backface-visibility: hidden;
}
.vex.dialog-theme .vex-content {
position: relative;
padding: 1em 1em 0 1em;
background: white;
margin: 0 auto;
max-width: 100%;
width: 450px;
max-height: 80%;
overflow: auto;
font-family: "Helvetica Neue", sans-serif;
color: #282828;
font-size: 1.1em;
line-height: 1.5em;
}
.vex.dialog-theme .vex-content .main-title {
border-bottom: 1px solid currentColor;
margin-top: 0;
margin-bottom: 0.5em;
}
/* closing button */
.vex.dialog-theme .vex-close {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
.vex.dialog-theme .vex-close:before {
content: "\00D7";
position: absolute;
top: 3px;
right: 3px;
background: transparent;
text-align: center;
height: 30px;
width: 30px;
color: #bbbbbb;
font-size: 26px;
font-weight: normal;
line-height: 31px;
}
.vex.dialog-theme .vex-close:hover:before, .vex.dialog-theme .vex-close:active:before {
color: #282828;
background: #e0e0e0;
}
/* inputs, forms, buttons */
.vex.dialog-theme .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
.vex.dialog-theme .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
.vex.dialog-theme .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
.vex.dialog-theme .bt {
float: right;
margin: 0 0 0 0.5em;
}
.vex.dialog-theme .bt:last-child {
margin-left: 0;
}
.vex-loading-spinner.dialog-theme {
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
border-radius: 100%;
background: #f0f0f0;
border: 0.2em solid transparent;
border-top-color: #bbbbbb;
top: -1.1em;
bottom: auto;
}

99
css/forms.css Normal file
View File

@ -0,0 +1,99 @@
/**
* Forms
*/
/** inputs **/
textarea, input[type="date"], input[type="datetime"],
input[type="datetime-local"], input[type="email"], input[type="month"],
input[type="number"], input[type="password"], input[type="search"],
input[type="tel"], input[type="text"], input[type="time"],
input[type="url"], input[type="week"] {
background: white;
width: 100%;
margin: 0 0 0.25em;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
}
textarea:focus, input[type="date"]:focus, input[type="datetime"]:focus,
input[type="datetime-local"]:focus, input[type="email"]:focus,
input[type="month"]:focus, input[type="number"]:focus,
input[type="password"]:focus, input[type="search"]:focus,
input[type="tel"]:focus, input[type="text"]:focus, input[type="time"]:focus,
input[type="url"]:focus, input[type="week"]:focus {
box-shadow: inset 0 0 0 2px #8dbdf1;
outline: none;
}
/** buttons **/
.bt {
margin: 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* primary button */
.bt.primary {
border: 1px solid #e0e0e0;
background: transparent;
color: #e0e0e0;
}
.bt.primary.inverse {
border-color: #262626;
color: #262626;
}
.bt.primary:hover {
background: rgba(255, 255, 255, 0.1);
}
.bt.primary.inverse:hover {
background: rgba(0, 0, 0, 0.1);
}
.bt.primary:active, .bt.secondary:active {
background: #e0e0e0;
color: #262626;
}
.bt.primary.inverse:active, .bt.secondary.inverse:active {
background: #262626;
color: #e0e0e0;
}
/* secondary button */
.bt.secondary {
border: 1px solid transparent;
background: transparent;
color: #e0e0e0;
}
.bt.secondary.inverse {
color: #262626;
}
.bt.secondary:hover, .bt.secondary:active {
border: 1px solid #e0e0e0;
}
.bt.secondary.inverse:hover, .bt.secondary.inverse:active {
border-color: #262626;
}
.bt.secondary:active {
background: #e0e0e0;
color: #262626;
}

View File

@ -0,0 +1,631 @@
@keyframes vex-slideup {
/* line 83, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 86, ../sass/_keyframes.sass */
1% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 0;
}
/* line 91, ../sass/_keyframes.sass */
2% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 1;
}
/* line 94, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-webkit-keyframes vex-slideup {
/* line 83, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 86, ../sass/_keyframes.sass */
1% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 0;
}
/* line 91, ../sass/_keyframes.sass */
2% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 1;
}
/* line 94, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-moz-keyframes vex-slideup {
/* line 83, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 86, ../sass/_keyframes.sass */
1% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 0;
}
/* line 91, ../sass/_keyframes.sass */
2% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 1;
}
/* line 94, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-ms-keyframes vex-slideup {
/* line 83, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 86, ../sass/_keyframes.sass */
1% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 0;
}
/* line 91, ../sass/_keyframes.sass */
2% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 1;
}
/* line 94, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-o-keyframes vex-slideup {
/* line 83, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 86, ../sass/_keyframes.sass */
1% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 0;
}
/* line 91, ../sass/_keyframes.sass */
2% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
opacity: 1;
}
/* line 94, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@keyframes vex-slidedown {
/* line 100, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 102, ../sass/_keyframes.sass */
100% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
}
}
@-webkit-keyframes vex-slidedown {
/* line 100, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 102, ../sass/_keyframes.sass */
100% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
}
}
@-moz-keyframes vex-slidedown {
/* line 100, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 102, ../sass/_keyframes.sass */
100% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
}
}
@-ms-keyframes vex-slidedown {
/* line 100, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 102, ../sass/_keyframes.sass */
100% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
}
}
@-o-keyframes vex-slidedown {
/* line 100, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 102, ../sass/_keyframes.sass */
100% {
transform: translateY(800px);
-webkit-transform: translateY(800px);
-moz-transform: translateY(800px);
-ms-transform: translateY(800px);
-o-transform: translateY(800px);
}
}
@keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-webkit-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-moz-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-ms-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-o-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
/* line 13, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner {
top: auto;
bottom: 0;
right: 0;
overflow: visible;
}
/* line 19, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-overlay {
display: none;
}
/* line 22, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner.vex-closing .vex-content {
animation: vex-slidedown 0.5s;
-webkit-animation: vex-slidedown 0.5s;
-moz-animation: vex-slidedown 0.5s;
-ms-animation: vex-slidedown 0.5s;
-o-animation: vex-slidedown 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 25, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-content {
animation: vex-slideup 0.5s;
-webkit-animation: vex-slideup 0.5s;
-moz-animation: vex-slideup 0.5s;
-ms-animation: vex-slideup 0.5s;
-o-animation: vex-slideup 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 28, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-content {
-webkit-border-radius: 5px 0 0 0;
-moz-border-radius: 5px 0 0 0;
-ms-border-radius: 5px 0 0 0;
-o-border-radius: 5px 0 0 0;
border-radius: 5px 0 0 0;
font-family: "Helvetica Neue", sans-serif;
background: #f0f0f0;
color: #444444;
padding: 1em;
max-width: 100%;
width: 450px;
font-size: 1.1em;
line-height: 1.5em;
position: fixed;
bottom: 0;
right: 0;
left: auto;
}
/* line 43, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-content h1, .vex.vex-theme-bottom-right-corner .vex-content h2, .vex.vex-theme-bottom-right-corner .vex-content h3, .vex.vex-theme-bottom-right-corner .vex-content h4, .vex.vex-theme-bottom-right-corner .vex-content h5, .vex.vex-theme-bottom-right-corner .vex-content h6, .vex.vex-theme-bottom-right-corner .vex-content p, .vex.vex-theme-bottom-right-corner .vex-content ul, .vex.vex-theme-bottom-right-corner .vex-content li {
color: inherit;
}
/* line 46, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-close {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 53, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-close:before {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
position: absolute;
content: "\00D7";
font-size: 26px;
font-weight: normal;
line-height: 31px;
height: 30px;
width: 30px;
text-align: center;
top: 3px;
right: 3px;
color: #bbbbbb;
background: transparent;
}
/* line 68, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-close:hover:before, .vex.vex-theme-bottom-right-corner .vex-close:active:before {
color: #777777;
background: #e0e0e0;
}
/* line 74, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 77, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
/* line 80, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="week"] {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: white;
width: 100%;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
}
/* line 92, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #8dbdf1;
-moz-box-shadow: inset 0 0 0 2px #8dbdf1;
box-shadow: inset 0 0 0 2px #8dbdf1;
outline: none;
}
/* line 96, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-bottom-right-corner .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 99, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-button {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
border: 0;
float: right;
margin: 0 0 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* line 111, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 114, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-button:focus {
animation: vex-pulse 1.1s infinite;
-webkit-animation: vex-pulse 1.1s infinite;
-moz-animation: vex-pulse 1.1s infinite;
-ms-animation: vex-pulse 1.1s infinite;
-o-animation: vex-pulse 1.1s infinite;
-webkit-backface-visibility: hidden;
outline: none;
}
@media (max-width: 568px) {
/* line 114, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-button:focus {
animation: none;
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
-o-animation: none;
-webkit-backface-visibility: hidden;
}
}
/* line 123, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-button.vex-dialog-button-primary {
background: #3288e6;
color: white;
}
/* line 127, ../sass/vex-theme-bottom-right-corner.sass */
.vex.vex-theme-bottom-right-corner .vex-dialog-button.vex-dialog-button-secondary {
background: #e0e0e0;
color: #777777;
}
/* line 131, ../sass/vex-theme-bottom-right-corner.sass */
.vex-loading-spinner.vex-theme-bottom-right-corner {
-webkit-box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
-ms-border-radius: 100%;
-o-border-radius: 100%;
border-radius: 100%;
background: #f0f0f0;
border: 0.2em solid transparent;
border-top-color: #bbbbbb;
top: -1.1em;
bottom: auto;
}
/* line 140, ../sass/vex-theme-bottom-right-corner.sass */
body.vex-open {
overflow: initial;
}

View File

@ -0,0 +1,528 @@
@keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-webkit-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-moz-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-ms-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-o-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-webkit-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-moz-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-ms-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-o-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-webkit-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-moz-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-ms-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-o-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
/* line 13, ../sass/vex-theme-default.sass */
.vex.vex-theme-default {
padding-top: 160px;
padding-bottom: 160px;
}
/* line 17, ../sass/vex-theme-default.sass */
.vex.vex-theme-default.vex-closing .vex-content {
animation: vex-flyout 0.5s;
-webkit-animation: vex-flyout 0.5s;
-moz-animation: vex-flyout 0.5s;
-ms-animation: vex-flyout 0.5s;
-o-animation: vex-flyout 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 20, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-content {
animation: vex-flyin 0.5s;
-webkit-animation: vex-flyin 0.5s;
-moz-animation: vex-flyin 0.5s;
-ms-animation: vex-flyin 0.5s;
-o-animation: vex-flyin 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 23, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-content {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
font-family: "Helvetica Neue", sans-serif;
background: #f0f0f0;
color: #444444;
padding: 1em;
position: relative;
margin: 0 auto;
max-width: 100%;
width: 450px;
font-size: 1.1em;
line-height: 1.5em;
}
/* line 36, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-content h1, .vex.vex-theme-default .vex-content h2, .vex.vex-theme-default .vex-content h3, .vex.vex-theme-default .vex-content h4, .vex.vex-theme-default .vex-content h5, .vex.vex-theme-default .vex-content h6, .vex.vex-theme-default .vex-content p, .vex.vex-theme-default .vex-content ul, .vex.vex-theme-default .vex-content li {
color: inherit;
}
/* line 39, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-close {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 46, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-close:before {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
position: absolute;
content: "\00D7";
font-size: 26px;
font-weight: normal;
line-height: 31px;
height: 30px;
width: 30px;
text-align: center;
top: 3px;
right: 3px;
color: #bbbbbb;
background: transparent;
}
/* line 61, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-close:hover:before, .vex.vex-theme-default .vex-close:active:before {
color: #777777;
background: #e0e0e0;
}
/* line 67, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 70, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
/* line 73, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"] {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: white;
width: 100%;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
}
/* line 85, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #8dbdf1;
-moz-box-shadow: inset 0 0 0 2px #8dbdf1;
box-shadow: inset 0 0 0 2px #8dbdf1;
outline: none;
}
/* line 89, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-default .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 92, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-button {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
border: 0;
float: right;
margin: 0 0 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* line 104, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 107, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-button:focus {
animation: vex-pulse 1.1s infinite;
-webkit-animation: vex-pulse 1.1s infinite;
-moz-animation: vex-pulse 1.1s infinite;
-ms-animation: vex-pulse 1.1s infinite;
-o-animation: vex-pulse 1.1s infinite;
-webkit-backface-visibility: hidden;
outline: none;
}
@media (max-width: 568px) {
/* line 107, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-button:focus {
animation: none;
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
-o-animation: none;
-webkit-backface-visibility: hidden;
}
}
/* line 116, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-button.vex-dialog-button-primary {
background: #3288e6;
color: white;
}
/* line 120, ../sass/vex-theme-default.sass */
.vex.vex-theme-default .vex-dialog-button.vex-dialog-button-secondary {
background: #e0e0e0;
color: #777777;
}
/* line 124, ../sass/vex-theme-default.sass */
.vex-loading-spinner.vex-theme-default {
-webkit-box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
-ms-border-radius: 100%;
-o-border-radius: 100%;
border-radius: 100%;
background: #f0f0f0;
border: 0.2em solid transparent;
border-top-color: #bbbbbb;
top: -1.1em;
bottom: auto;
}

View File

@ -0,0 +1,461 @@
@keyframes vex-flipin-horizontal {
/* line 107, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: rotateY(-90deg);
-webkit-transform: rotateY(-90deg);
-moz-transform: rotateY(-90deg);
-ms-transform: rotateY(-90deg);
-o-transform: rotateY(-90deg);
}
/* line 110, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
}
@-webkit-keyframes vex-flipin-horizontal {
/* line 107, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: rotateY(-90deg);
-webkit-transform: rotateY(-90deg);
-moz-transform: rotateY(-90deg);
-ms-transform: rotateY(-90deg);
-o-transform: rotateY(-90deg);
}
/* line 110, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
}
@-moz-keyframes vex-flipin-horizontal {
/* line 107, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: rotateY(-90deg);
-webkit-transform: rotateY(-90deg);
-moz-transform: rotateY(-90deg);
-ms-transform: rotateY(-90deg);
-o-transform: rotateY(-90deg);
}
/* line 110, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
}
@-ms-keyframes vex-flipin-horizontal {
/* line 107, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: rotateY(-90deg);
-webkit-transform: rotateY(-90deg);
-moz-transform: rotateY(-90deg);
-ms-transform: rotateY(-90deg);
-o-transform: rotateY(-90deg);
}
/* line 110, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
}
@-o-keyframes vex-flipin-horizontal {
/* line 107, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: rotateY(-90deg);
-webkit-transform: rotateY(-90deg);
-moz-transform: rotateY(-90deg);
-ms-transform: rotateY(-90deg);
-o-transform: rotateY(-90deg);
}
/* line 110, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
}
@keyframes vex-flipout-horizontal {
/* line 116, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
/* line 119, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: rotateY(90deg);
-webkit-transform: rotateY(90deg);
-moz-transform: rotateY(90deg);
-ms-transform: rotateY(90deg);
-o-transform: rotateY(90deg);
}
}
@-webkit-keyframes vex-flipout-horizontal {
/* line 116, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
/* line 119, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: rotateY(90deg);
-webkit-transform: rotateY(90deg);
-moz-transform: rotateY(90deg);
-ms-transform: rotateY(90deg);
-o-transform: rotateY(90deg);
}
}
@-moz-keyframes vex-flipout-horizontal {
/* line 116, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
/* line 119, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: rotateY(90deg);
-webkit-transform: rotateY(90deg);
-moz-transform: rotateY(90deg);
-ms-transform: rotateY(90deg);
-o-transform: rotateY(90deg);
}
}
@-ms-keyframes vex-flipout-horizontal {
/* line 116, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
/* line 119, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: rotateY(90deg);
-webkit-transform: rotateY(90deg);
-moz-transform: rotateY(90deg);
-ms-transform: rotateY(90deg);
-o-transform: rotateY(90deg);
}
}
@-o-keyframes vex-flipout-horizontal {
/* line 116, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: rotateY(0deg);
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
}
/* line 119, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: rotateY(90deg);
-webkit-transform: rotateY(90deg);
-moz-transform: rotateY(90deg);
-ms-transform: rotateY(90deg);
-o-transform: rotateY(90deg);
}
}
/* line 31, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack {
-webkit-perspective: 1300px;
-moz-perspective: 1300px;
-ms-perspective: 1300px;
-o-perspective: 1300px;
perspective: 1300px;
-webkit-perspective-origin: 50% 150px;
-moz-perspective-origin: 50% 150px;
-ms-perspective-origin: 50% 150px;
-o-perspective-origin: 50% 150px;
perspective-origin: 50% 150px;
padding-top: 100px;
padding-bottom: 100px;
font-size: 1.5em;
}
/* line 38, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-closing .vex-content {
animation: vex-flipout-horizontal 0.5s;
-webkit-animation: vex-flipout-horizontal 0.5s;
-moz-animation: vex-flipout-horizontal 0.5s;
-ms-animation: vex-flipout-horizontal 0.5s;
-o-animation: vex-flipout-horizontal 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 41, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-content {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
animation: vex-flipin-horizontal 0.5s;
-webkit-animation: vex-flipin-horizontal 0.5s;
-moz-animation: vex-flipin-horizontal 0.5s;
-ms-animation: vex-flipin-horizontal 0.5s;
-o-animation: vex-flipin-horizontal 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 45, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-content {
font-family: "Helvetica Neue", sans-serif;
font-weight: 200;
background: white;
color: #444444;
padding: 2em 2em 3em 2em;
line-height: 1.5em;
position: relative;
margin: 0 auto;
max-width: 100%;
width: 600px;
}
/* line 57, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-content h1, .vex.vex-theme-flat-attack .vex-content h2, .vex.vex-theme-flat-attack .vex-content h3, .vex.vex-theme-flat-attack .vex-content h4, .vex.vex-theme-flat-attack .vex-content h5, .vex.vex-theme-flat-attack .vex-content h6, .vex.vex-theme-flat-attack .vex-content p, .vex.vex-theme-flat-attack .vex-content ul, .vex.vex-theme-flat-attack .vex-content li {
color: inherit;
}
/* line 60, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-close {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 66, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-close:before {
font-family: "Helvetica Neue", sans-serif;
font-weight: 100;
line-height: 1px;
padding-top: 0.5em;
display: block;
font-size: 2em;
text-indent: 1px;
overflow: hidden;
height: 1.25em;
width: 1.25em;
text-align: center;
top: 0;
right: 0;
color: white;
background: #666666;
}
/* line 85, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 88, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input {
margin-bottom: 0.5em;
}
/* line 91, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="week"] {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: #f0f0f0;
width: 100%;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
}
/* line 103, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #666666;
-moz-box-shadow: inset 0 0 0 2px #666666;
box-shadow: inset 0 0 0 2px #666666;
outline: none;
}
/* line 107, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
padding-top: 1em;
margin-bottom: -3em;
margin-left: -2em;
margin-right: -2em;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-flat-attack .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 114, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button {
-webkit-border-radius: 0;
-moz-border-radius: 0;
-ms-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border: 0;
margin: 0;
float: right;
padding: 0.5em 1em;
font-size: 1.13em;
text-transform: uppercase;
font-weight: 200;
letter-spacing: 0.1em;
line-height: 1em;
font-family: inherit;
}
/* line 127, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 130, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button:focus {
outline: none;
}
/* line 133, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-primary {
background: #666666;
color: white;
}
/* line 137, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-primary:focus {
-webkit-box-shadow: inset 0 3px rgba(0, 0, 0, 0.2);
-moz-box-shadow: inset 0 3px rgba(0, 0, 0, 0.2);
box-shadow: inset 0 3px rgba(0, 0, 0, 0.2);
}
/* line 140, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary {
background: white;
color: #cccccc;
}
/* line 144, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary:focus {
-webkit-box-shadow: inset 0 3px #aaaaaa;
-moz-box-shadow: inset 0 3px #aaaaaa;
box-shadow: inset 0 3px #aaaaaa;
background: #eeeeee;
color: #777777;
}
/* line 149, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary:hover, .vex.vex-theme-flat-attack .vex-dialog-button.vex-dialog-button-secondary:active {
color: #777777;
}
/* line 16, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-close:before {
background: #ff7ea7;
}
/* line 25, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #ff7ea7;
-moz-box-shadow: inset 0 0 0 2px #ff7ea7;
box-shadow: inset 0 0 0 2px #ff7ea7;
}
/* line 28, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-pink .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
background: #ff7ea7;
}
/* line 16, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-close:before {
background: #ce4a55;
}
/* line 25, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #ce4a55;
-moz-box-shadow: inset 0 0 0 2px #ce4a55;
box-shadow: inset 0 0 0 2px #ce4a55;
}
/* line 28, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-red .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
background: #ce4a55;
}
/* line 16, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-close:before {
background: #34b989;
}
/* line 25, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #34b989;
-moz-box-shadow: inset 0 0 0 2px #34b989;
box-shadow: inset 0 0 0 2px #34b989;
}
/* line 28, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-green .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
background: #34b989;
}
/* line 16, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-close:before {
background: #477fa5;
}
/* line 25, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #477fa5;
-moz-box-shadow: inset 0 0 0 2px #477fa5;
box-shadow: inset 0 0 0 2px #477fa5;
}
/* line 28, ../sass/vex-theme-flat-attack.sass */
.vex.vex-theme-flat-attack.vex-theme-flat-attack-blue .vex-dialog-form .vex-dialog-buttons .vex-dialog-button.vex-dialog-button-primary {
background: #477fa5;
}
/* line 166, ../sass/vex-theme-flat-attack.sass */
.vex-loading-spinner.vex-theme-flat-attack {
height: 4em;
width: 4em;
}

View File

@ -0,0 +1,533 @@
@keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-webkit-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-moz-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-ms-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@-o-keyframes vex-flyin {
/* line 25, ../sass/_keyframes.sass */
0% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
/* line 28, ../sass/_keyframes.sass */
100% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
}
@keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-webkit-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-moz-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-ms-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@-o-keyframes vex-flyout {
/* line 34, ../sass/_keyframes.sass */
0% {
opacity: 1;
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 37, ../sass/_keyframes.sass */
100% {
opacity: 0;
transform: translateY(-40px);
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
}
}
@keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-webkit-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-moz-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-ms-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-o-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
/* line 13, ../sass/vex-theme-os.sass */
.vex.vex-theme-os {
padding-top: 160px;
padding-bottom: 160px;
}
/* line 17, ../sass/vex-theme-os.sass */
.vex.vex-theme-os.vex-closing .vex-content {
animation: vex-flyout 0.5s;
-webkit-animation: vex-flyout 0.5s;
-moz-animation: vex-flyout 0.5s;
-ms-animation: vex-flyout 0.5s;
-o-animation: vex-flyout 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 20, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-content {
animation: vex-flyin 0.5s;
-webkit-animation: vex-flyin 0.5s;
-moz-animation: vex-flyin 0.5s;
-ms-animation: vex-flyin 0.5s;
-o-animation: vex-flyin 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 23, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-content {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
-webkit-box-shadow: inset 0 1px #a6a6a6, 0 0 0 1px rgba(0, 0, 0, 0.08);
-moz-box-shadow: inset 0 1px #a6a6a6, 0 0 0 1px rgba(0, 0, 0, 0.08);
box-shadow: inset 0 1px #a6a6a6, 0 0 0 1px rgba(0, 0, 0, 0.08);
font-family: "Helvetica Neue", sans-serif;
border-top: 20px solid #bbbbbb;
background: #f0f0f0;
color: #444444;
padding: 1em;
position: relative;
margin: 0 auto;
max-width: 100%;
width: 450px;
font-size: 1.1em;
line-height: 1.5em;
}
/* line 38, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-content h1, .vex.vex-theme-os .vex-content h2, .vex.vex-theme-os .vex-content h3, .vex.vex-theme-os .vex-content h4, .vex.vex-theme-os .vex-content h5, .vex.vex-theme-os .vex-content h6, .vex.vex-theme-os .vex-content p, .vex.vex-theme-os .vex-content ul, .vex.vex-theme-os .vex-content li {
color: inherit;
}
/* line 41, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-close {
-webkit-border-radius: 0 5px 0 0;
-moz-border-radius: 0 5px 0 0;
-ms-border-radius: 0 5px 0 0;
-o-border-radius: 0 5px 0 0;
border-radius: 0 5px 0 0;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 48, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-close:before {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
position: absolute;
content: "\00D7";
font-size: 26px;
font-weight: normal;
line-height: 31px;
height: 30px;
width: 30px;
text-align: center;
top: 3px;
right: 3px;
color: #bbbbbb;
background: transparent;
}
/* line 63, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-close:hover:before, .vex.vex-theme-os .vex-close:active:before {
color: #777777;
background: #e0e0e0;
}
/* line 69, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 72, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
/* line 75, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"] {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: white;
width: 100%;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
}
/* line 87, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-os .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 1px #3288e6;
-moz-box-shadow: inset 0 0 0 1px #3288e6;
box-shadow: inset 0 0 0 1px #3288e6;
outline: none;
}
/* line 91, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-os .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 94, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-button {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
border: 0;
float: right;
margin: 0 0 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* line 106, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 109, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-button:focus {
animation: vex-pulse 1.1s infinite;
-webkit-animation: vex-pulse 1.1s infinite;
-moz-animation: vex-pulse 1.1s infinite;
-ms-animation: vex-pulse 1.1s infinite;
-o-animation: vex-pulse 1.1s infinite;
-webkit-backface-visibility: hidden;
outline: none;
}
@media (max-width: 568px) {
/* line 109, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-button:focus {
animation: none;
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
-o-animation: none;
-webkit-backface-visibility: hidden;
}
}
/* line 118, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-button.vex-dialog-button-primary {
background: #3288e6;
color: white;
}
/* line 122, ../sass/vex-theme-os.sass */
.vex.vex-theme-os .vex-dialog-button.vex-dialog-button-secondary {
background: #e0e0e0;
color: #777777;
}
/* line 126, ../sass/vex-theme-os.sass */
.vex-loading-spinner.vex-theme-os {
-webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0.5em rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0.5em rgba(0, 0, 0, 0.2);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2), 0 0 0.5em rgba(0, 0, 0, 0.2);
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
-ms-border-radius: 100%;
-o-border-radius: 100%;
border-radius: 100%;
background: rgba(255, 255, 255, 0.2);
width: 0;
height: 0;
border: 1.2em solid #bbbbbb;
border-top-color: #f0f0f0;
border-bottom-color: #f0f0f0;
}

View File

@ -0,0 +1,259 @@
@keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-webkit-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-moz-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-ms-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-o-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
/* line 11, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain {
padding-top: 160px;
padding-bottom: 160px;
}
/* line 15, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-content {
font-family: "Helvetica Neue", sans-serif;
background: white;
color: #444444;
padding: 1em;
position: relative;
margin: 0 auto;
max-width: 100%;
width: 450px;
font-size: 1.1em;
line-height: 1.5em;
}
/* line 27, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-content h1, .vex.vex-theme-plain .vex-content h2, .vex.vex-theme-plain .vex-content h3, .vex.vex-theme-plain .vex-content h4, .vex.vex-theme-plain .vex-content h5, .vex.vex-theme-plain .vex-content h6, .vex.vex-theme-plain .vex-content p, .vex.vex-theme-plain .vex-content ul, .vex.vex-theme-plain .vex-content li {
color: inherit;
}
/* line 30, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-close {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 36, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-close:before {
position: absolute;
content: "\00D7";
font-size: 26px;
font-weight: normal;
line-height: 31px;
height: 30px;
width: 30px;
text-align: center;
top: 3px;
right: 3px;
color: #bbbbbb;
background: transparent;
}
/* line 50, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-close:hover:before, .vex.vex-theme-plain .vex-close:active:before {
color: #777777;
background: #e0e0e0;
}
/* line 56, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 59, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
/* line 62, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="week"] {
background: #f0f0f0;
width: 100%;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
}
/* line 73, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-plain .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
-moz-box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.2);
outline: none;
}
/* line 77, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-plain .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 80, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-button {
-webkit-border-radius: 0;
-moz-border-radius: 0;
-ms-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border: 0;
float: right;
margin: 0 0 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* line 92, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 95, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-button:focus {
animation: vex-pulse 1.1s infinite;
-webkit-animation: vex-pulse 1.1s infinite;
-moz-animation: vex-pulse 1.1s infinite;
-ms-animation: vex-pulse 1.1s infinite;
-o-animation: vex-pulse 1.1s infinite;
-webkit-backface-visibility: hidden;
outline: none;
}
@media (max-width: 568px) {
/* line 95, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-button:focus {
animation: none;
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
-o-animation: none;
-webkit-backface-visibility: hidden;
}
}
/* line 104, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-button.vex-dialog-button-primary {
background: #3288e6;
color: white;
}
/* line 108, ../sass/vex-theme-plain.sass */
.vex.vex-theme-plain .vex-dialog-button.vex-dialog-button-secondary {
background: #e0e0e0;
color: #777777;
}
/* line 112, ../sass/vex-theme-plain.sass */
.vex-loading-spinner.vex-theme-plain {
height: 2.5em;
width: 2.5em;
}

View File

@ -0,0 +1,613 @@
@keyframes vex-dropin {
/* line 51, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 54, ../sass/_keyframes.sass */
1% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 0;
}
/* line 59, ../sass/_keyframes.sass */
2% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 1;
}
/* line 62, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-webkit-keyframes vex-dropin {
/* line 51, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 54, ../sass/_keyframes.sass */
1% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 0;
}
/* line 59, ../sass/_keyframes.sass */
2% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 1;
}
/* line 62, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-moz-keyframes vex-dropin {
/* line 51, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 54, ../sass/_keyframes.sass */
1% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 0;
}
/* line 59, ../sass/_keyframes.sass */
2% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 1;
}
/* line 62, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-ms-keyframes vex-dropin {
/* line 51, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 54, ../sass/_keyframes.sass */
1% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 0;
}
/* line 59, ../sass/_keyframes.sass */
2% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 1;
}
/* line 62, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@-o-keyframes vex-dropin {
/* line 51, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 0;
}
/* line 54, ../sass/_keyframes.sass */
1% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 0;
}
/* line 59, ../sass/_keyframes.sass */
2% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
opacity: 1;
}
/* line 62, ../sass/_keyframes.sass */
100% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
opacity: 1;
}
}
@keyframes vex-dropout {
/* line 68, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 70, ../sass/_keyframes.sass */
100% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
}
}
@-webkit-keyframes vex-dropout {
/* line 68, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 70, ../sass/_keyframes.sass */
100% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
}
}
@-moz-keyframes vex-dropout {
/* line 68, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 70, ../sass/_keyframes.sass */
100% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
}
}
@-ms-keyframes vex-dropout {
/* line 68, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 70, ../sass/_keyframes.sass */
100% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
}
}
@-o-keyframes vex-dropout {
/* line 68, ../sass/_keyframes.sass */
0% {
transform: translateY(0);
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
-ms-transform: translateY(0);
-o-transform: translateY(0);
}
/* line 70, ../sass/_keyframes.sass */
100% {
transform: translateY(-800px);
-webkit-transform: translateY(-800px);
-moz-transform: translateY(-800px);
-ms-transform: translateY(-800px);
-o-transform: translateY(-800px);
}
}
@keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-webkit-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-moz-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-ms-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-o-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
/* line 15, ../sass/vex-theme-top.sass */
.vex.vex-theme-top.vex-closing .vex-content {
animation: vex-dropout 0.5s;
-webkit-animation: vex-dropout 0.5s;
-moz-animation: vex-dropout 0.5s;
-ms-animation: vex-dropout 0.5s;
-o-animation: vex-dropout 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 18, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-content {
animation: vex-dropin 0.5s;
-webkit-animation: vex-dropin 0.5s;
-moz-animation: vex-dropin 0.5s;
-ms-animation: vex-dropin 0.5s;
-o-animation: vex-dropin 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 21, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-content {
-webkit-border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-ms-border-radius: 0 0 5px 5px;
-o-border-radius: 0 0 5px 5px;
border-radius: 0 0 5px 5px;
font-family: "Helvetica Neue", sans-serif;
background: #f0f0f0;
color: #444444;
padding: 1em;
position: relative;
margin: 0 auto;
max-width: 100%;
width: 450px;
font-size: 1.1em;
line-height: 1.5em;
}
/* line 34, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-content h1, .vex.vex-theme-top .vex-content h2, .vex.vex-theme-top .vex-content h3, .vex.vex-theme-top .vex-content h4, .vex.vex-theme-top .vex-content h5, .vex.vex-theme-top .vex-content h6, .vex.vex-theme-top .vex-content p, .vex.vex-theme-top .vex-content ul, .vex.vex-theme-top .vex-content li {
color: inherit;
}
/* line 37, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-close {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 44, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-close:before {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
position: absolute;
content: "\00D7";
font-size: 26px;
font-weight: normal;
line-height: 31px;
height: 30px;
width: 30px;
text-align: center;
top: 3px;
right: 3px;
color: #bbbbbb;
background: transparent;
}
/* line 59, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-close:hover:before, .vex.vex-theme-top .vex-close:active:before {
color: #777777;
background: #e0e0e0;
}
/* line 65, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 68, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
/* line 71, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="week"] {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: white;
width: 100%;
padding: 0.25em 0.67em;
border: 0;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
}
/* line 83, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-top .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-webkit-box-shadow: inset 0 0 0 2px #8dbdf1;
-moz-box-shadow: inset 0 0 0 2px #8dbdf1;
box-shadow: inset 0 0 0 2px #8dbdf1;
outline: none;
}
/* line 87, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-top .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 90, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-button {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
border: 0;
float: right;
margin: 0 0 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* line 102, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 105, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-button:focus {
animation: vex-pulse 1.1s infinite;
-webkit-animation: vex-pulse 1.1s infinite;
-moz-animation: vex-pulse 1.1s infinite;
-ms-animation: vex-pulse 1.1s infinite;
-o-animation: vex-pulse 1.1s infinite;
-webkit-backface-visibility: hidden;
outline: none;
}
@media (max-width: 568px) {
/* line 105, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-button:focus {
animation: none;
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
-o-animation: none;
-webkit-backface-visibility: hidden;
}
}
/* line 114, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-button.vex-dialog-button-primary {
background: #3288e6;
color: white;
}
/* line 118, ../sass/vex-theme-top.sass */
.vex.vex-theme-top .vex-dialog-button.vex-dialog-button-secondary {
background: #e0e0e0;
color: #777777;
}
/* line 122, ../sass/vex-theme-top.sass */
.vex-loading-spinner.vex-theme-top {
-webkit-box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
box-shadow: 0 0 0 0.5em #f0f0f0, 0 0 1px 0.5em rgba(0, 0, 0, 0.3);
-webkit-border-radius: 100%;
-moz-border-radius: 100%;
-ms-border-radius: 100%;
-o-border-radius: 100%;
border-radius: 100%;
background: #f0f0f0;
border: 0.2em solid transparent;
border-top-color: #bbbbbb;
top: -1.1em;
bottom: auto;
}

View File

@ -0,0 +1,262 @@
@keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-webkit-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-moz-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-ms-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
@-o-keyframes vex-pulse {
/* line 136, ../sass/_keyframes.sass */
0% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
/* line 138, ../sass/_keyframes.sass */
70% {
-webkit-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
-moz-box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
box-shadow: inset 0 0 0 300px rgba(255, 255, 255, 0.25);
}
/* line 140, ../sass/_keyframes.sass */
100% {
-webkit-box-shadow: inset 0 0 0 300px transparent;
-moz-box-shadow: inset 0 0 0 300px transparent;
box-shadow: inset 0 0 0 300px transparent;
}
}
/* line 9, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe {
padding-top: 160px;
padding-bottom: 160px;
}
/* line 13, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-overlay {
background: rgba(255, 255, 255, 0.4);
}
/* line 16, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-content {
font-family: "Helvetica Neue", sans-serif;
background: white;
color: black;
border: 2px solid black;
padding: 2em;
position: relative;
margin: 0 auto;
max-width: 100%;
width: 400px;
font-size: 1.1em;
line-height: 1.5em;
}
/* line 29, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-content h1, .vex.vex-theme-wireframe .vex-content h2, .vex.vex-theme-wireframe .vex-content h3, .vex.vex-theme-wireframe .vex-content h4, .vex.vex-theme-wireframe .vex-content h5, .vex.vex-theme-wireframe .vex-content h6, .vex.vex-theme-wireframe .vex-content p, .vex.vex-theme-wireframe .vex-content ul, .vex.vex-theme-wireframe .vex-content li {
color: inherit;
}
/* line 32, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-close {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
/* line 38, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-close:before {
position: absolute;
content: "\00D7";
font-size: 40px;
font-weight: normal;
line-height: 80px;
height: 80px;
width: 80px;
text-align: center;
top: 3px;
right: 3px;
color: black;
}
/* line 51, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-close:hover:before, .vex.vex-theme-wireframe .vex-close:active:before {
color: black;
}
/* line 56, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-message {
margin-bottom: 0.5em;
}
/* line 59, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input {
margin-bottom: 1em;
}
/* line 62, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input textarea, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="date"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime-local"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="email"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="month"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="number"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="password"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="search"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="tel"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="text"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="time"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="url"], .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="week"] {
background: white;
width: 100%;
padding: 0.25em 0.67em;
font-family: inherit;
font-weight: inherit;
font-size: inherit;
min-height: 2.5em;
margin: 0 0 0.25em;
border: 2px solid black;
}
/* line 73, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input textarea:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
border-style: dashed;
outline: none;
}
/* line 77, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-buttons {
*zoom: 1;
}
/* line 38, ../../../../../.rvm/gems/ruby-1.9.3-p194/gems/compass-0.12.2/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
.vex.vex-theme-wireframe .vex-dialog-form .vex-dialog-buttons:after {
content: "";
display: table;
clear: both;
}
/* line 80, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-button {
-webkit-border-radius: 0;
-moz-border-radius: 0;
-ms-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border: 0;
float: right;
margin: 0 0 0 0.5em;
font-family: inherit;
text-transform: uppercase;
letter-spacing: 0.1em;
font-size: 0.8em;
line-height: 1em;
padding: 0.75em 2em;
}
/* line 92, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-button.vex-last {
margin-left: 0;
}
/* line 95, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-button:focus {
animation: vex-pulse 1.1s infinite;
-webkit-animation: vex-pulse 1.1s infinite;
-moz-animation: vex-pulse 1.1s infinite;
-ms-animation: vex-pulse 1.1s infinite;
-o-animation: vex-pulse 1.1s infinite;
-webkit-backface-visibility: hidden;
outline: none;
}
@media (max-width: 568px) {
/* line 95, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-button:focus {
animation: none;
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
-o-animation: none;
-webkit-backface-visibility: hidden;
}
}
/* line 104, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-button.vex-dialog-button-primary {
background: black;
color: white;
border: 2px solid transparent;
}
/* line 109, ../sass/vex-theme-wireframe.sass */
.vex.vex-theme-wireframe .vex-dialog-button.vex-dialog-button-secondary {
background: white;
color: black;
border: 2px solid black;
}
/* line 114, ../sass/vex-theme-wireframe.sass */
.vex-loading-spinner.vex-theme-wireframe {
height: 2.5em;
width: 2.5em;
}

335
css/lib/vex/vex.css Normal file
View File

@ -0,0 +1,335 @@
@keyframes vex-fadein {
/* line 9, ../sass/_keyframes.sass */
0% {
opacity: 0;
}
/* line 11, ../sass/_keyframes.sass */
100% {
opacity: 1;
}
}
@-webkit-keyframes vex-fadein {
/* line 9, ../sass/_keyframes.sass */
0% {
opacity: 0;
}
/* line 11, ../sass/_keyframes.sass */
100% {
opacity: 1;
}
}
@-moz-keyframes vex-fadein {
/* line 9, ../sass/_keyframes.sass */
0% {
opacity: 0;
}
/* line 11, ../sass/_keyframes.sass */
100% {
opacity: 1;
}
}
@-ms-keyframes vex-fadein {
/* line 9, ../sass/_keyframes.sass */
0% {
opacity: 0;
}
/* line 11, ../sass/_keyframes.sass */
100% {
opacity: 1;
}
}
@-o-keyframes vex-fadein {
/* line 9, ../sass/_keyframes.sass */
0% {
opacity: 0;
}
/* line 11, ../sass/_keyframes.sass */
100% {
opacity: 1;
}
}
@keyframes vex-fadeout {
/* line 16, ../sass/_keyframes.sass */
0% {
opacity: 1;
}
/* line 18, ../sass/_keyframes.sass */
100% {
opacity: 0;
}
}
@-webkit-keyframes vex-fadeout {
/* line 16, ../sass/_keyframes.sass */
0% {
opacity: 1;
}
/* line 18, ../sass/_keyframes.sass */
100% {
opacity: 0;
}
}
@-moz-keyframes vex-fadeout {
/* line 16, ../sass/_keyframes.sass */
0% {
opacity: 1;
}
/* line 18, ../sass/_keyframes.sass */
100% {
opacity: 0;
}
}
@-ms-keyframes vex-fadeout {
/* line 16, ../sass/_keyframes.sass */
0% {
opacity: 1;
}
/* line 18, ../sass/_keyframes.sass */
100% {
opacity: 0;
}
}
@-o-keyframes vex-fadeout {
/* line 16, ../sass/_keyframes.sass */
0% {
opacity: 1;
}
/* line 18, ../sass/_keyframes.sass */
100% {
opacity: 0;
}
}
@keyframes vex-rotation {
/* line 127, ../sass/_keyframes.sass */
0% {
transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
/* line 129, ../sass/_keyframes.sass */
100% {
transform: rotate(359deg);
-webkit-transform: rotate(359deg);
-moz-transform: rotate(359deg);
-ms-transform: rotate(359deg);
-o-transform: rotate(359deg);
}
}
@-webkit-keyframes vex-rotation {
/* line 127, ../sass/_keyframes.sass */
0% {
transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
/* line 129, ../sass/_keyframes.sass */
100% {
transform: rotate(359deg);
-webkit-transform: rotate(359deg);
-moz-transform: rotate(359deg);
-ms-transform: rotate(359deg);
-o-transform: rotate(359deg);
}
}
@-moz-keyframes vex-rotation {
/* line 127, ../sass/_keyframes.sass */
0% {
transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
/* line 129, ../sass/_keyframes.sass */
100% {
transform: rotate(359deg);
-webkit-transform: rotate(359deg);
-moz-transform: rotate(359deg);
-ms-transform: rotate(359deg);
-o-transform: rotate(359deg);
}
}
@-ms-keyframes vex-rotation {
/* line 127, ../sass/_keyframes.sass */
0% {
transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
/* line 129, ../sass/_keyframes.sass */
100% {
transform: rotate(359deg);
-webkit-transform: rotate(359deg);
-moz-transform: rotate(359deg);
-ms-transform: rotate(359deg);
-o-transform: rotate(359deg);
}
}
@-o-keyframes vex-rotation {
/* line 127, ../sass/_keyframes.sass */
0% {
transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
/* line 129, ../sass/_keyframes.sass */
100% {
transform: rotate(359deg);
-webkit-transform: rotate(359deg);
-moz-transform: rotate(359deg);
-ms-transform: rotate(359deg);
-o-transform: rotate(359deg);
}
}
/* line 11, ../sass/vex.sass */
.vex, .vex *, .vex *:before, .vex *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* line 14, ../sass/vex.sass */
.vex {
position: fixed;
overflow: auto;
-webkit-overflow-scrolling: touch;
z-index: 1111;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
/* line 25, ../sass/vex.sass */
.vex-overlay {
background: black;
filter: alpha(opacity=40);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
}
/* line 30, ../sass/vex.sass */
.vex-overlay {
animation: vex-fadein 0.5s;
-webkit-animation: vex-fadein 0.5s;
-moz-animation: vex-fadein 0.5s;
-ms-animation: vex-fadein 0.5s;
-o-animation: vex-fadein 0.5s;
-webkit-backface-visibility: hidden;
position: fixed;
background: rgba(0, 0, 0, 0.4);
top: 0;
right: 0;
bottom: 0;
left: 0;
}
/* line 39, ../sass/vex.sass */
.vex.vex-closing .vex-overlay {
animation: vex-fadeout 0.5s;
-webkit-animation: vex-fadeout 0.5s;
-moz-animation: vex-fadeout 0.5s;
-ms-animation: vex-fadeout 0.5s;
-o-animation: vex-fadeout 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 42, ../sass/vex.sass */
.vex-content {
animation: vex-fadein 0.5s;
-webkit-animation: vex-fadein 0.5s;
-moz-animation: vex-fadein 0.5s;
-ms-animation: vex-fadein 0.5s;
-o-animation: vex-fadein 0.5s;
-webkit-backface-visibility: hidden;
background: white;
}
/* line 46, ../sass/vex.sass */
.vex.vex-closing .vex-content {
animation: vex-fadeout 0.5s;
-webkit-animation: vex-fadeout 0.5s;
-moz-animation: vex-fadeout 0.5s;
-ms-animation: vex-fadeout 0.5s;
-o-animation: vex-fadeout 0.5s;
-webkit-backface-visibility: hidden;
}
/* line 49, ../sass/vex.sass */
.vex-close:before {
font-family: Arial, sans-serif;
content: "\00D7";
}
/* line 53, ../sass/vex.sass */
.vex-dialog-form {
margin: 0;
}
/* line 56, ../sass/vex.sass */
.vex-dialog-button {
-webkit-appearance: none;
cursor: pointer;
}
/* line 60, ../sass/vex.sass */
.vex-loading-spinner {
animation: vex-rotation 0.7s linear infinite;
-webkit-animation: vex-rotation 0.7s linear infinite;
-moz-animation: vex-rotation 0.7s linear infinite;
-ms-animation: vex-rotation 0.7s linear infinite;
-o-animation: vex-rotation 0.7s linear infinite;
-webkit-backface-visibility: hidden;
-webkit-box-shadow: 0 0 1em rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 0 1em rgba(0, 0, 0, 0.1);
box-shadow: 0 0 1em rgba(0, 0, 0, 0.1);
position: fixed;
z-index: 1112;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 2em;
width: 2em;
background: white;
}
/* line 76, ../sass/vex.sass */
body.vex-open {
overflow: hidden;
}

458
css/piano.css Normal file
View File

@ -0,0 +1,458 @@
body, html, #content {
margin: 0;
padding: 0;
height: 100%;
background: #262626;
font-family: Helvetica, sans-serif;
}
*, *:before, *:after {
box-sizing: border-box;
cursor: default;
}
*:not(input):not(button):not(select):not(textarea) {
-webkit-user-select: none;
}
:focus {
outline: none;
}
a {
cursor: pointer;
color: inherit;
}
/**
* Animations
*/
@-webkit-keyframes reveal-controls {
0% {
transform: translate(-50%, 10em);
}
100% {
transform: translate(-50%, -50%);
}
}
@-webkit-keyframes reveal-notes {
0% {
transform: translate(0, -20em);
}
100% {
transform: translate(0, 0);
}
}
/**
* Main
*/
.main {
position: relative;
width: calc(100% - 65px);
height: 100%;
margin-left: 65px;
}
.main p {
position: relative;
margin: 0;
}
.main .roll {
display: flex;
height: 100%;
flex-direction: column;
}
/** noteboard **/
.main .noteboard {
position: relative;
overflow: hidden;
flex-basis: 100%;
}
.main .noteboard .inner {
backface-visibility: hidden;
perspective: 1000;
}
/* closed controls */
.main .noteboard .controls {
position: absolute;
top: 50%;
left: 50%;
-webkit-animation: reveal-controls 0.5s ease forwards;
width: 100%;
text-align: center;
transform: translate(-50%, 10em);
}
.main .noteboard .controls img {
display: block;
margin: 0 auto 1em auto;
}
/* notes */
.main .noteboard canvas {
-webkit-animation: reveal-notes 0.5s ease;
}
.main .noteboard .note {
display: block;
position: absolute;
left: 0;
bottom: 0;
width: calc(100% / 52);
border: 1px solid #262626;
}
/* black */
.main .noteboard [data-black="true"] {
width: calc(100% / 52 * 0.6);
border-radius: 5px;
margin-left: calc(-100% / 52 * 0.6 / 2);
z-index: 1;
overflow: hidden;
box-shadow: inset 1000em 1000em rgba(0, 0, 0, 0.2);
}
/* percussion */
.main .noteboard [data-channel="9"] {
border-radius: 20px;
min-height: 10px;
}
/** channel colors **/
[data-channel="0"] {
background-color: hsl(225, 49%, 44%) !important;
}
[data-channel="1"] {
background-color: hsl(22.5, 84%, 56%) !important;
}
[data-channel="2"] {
background-color: hsl(45, 53%, 39%) !important;
}
[data-channel="3"] {
background-color: hsl(67.5, 84%, 56%) !important;
}
[data-channel="4"] {
background-color: hsl(90, 84%, 56%) !important;
}
[data-channel="5"] {
background-color: hsl(112.5, 84%, 56%) !important;
}
[data-channel="6"] {
background-color: hsl(135, 84%, 56%) !important;
}
[data-channel="7"] {
background-color: hsl(157.5, 84%, 56%) !important;
}
[data-channel="8"] {
background-color: hsl(180, 84%, 56%) !important;
}
[data-channel="9"] {
background-color: hsl(202.5, 84%, 56%) !important;
}
[data-channel="10"] {
background-color: hsl(247.5, 84%, 56%) !important;
}
[data-channel="11"] {
background-color: hsl(270, 84%, 56%) !important;
}
[data-channel="12"] {
background-color: hsl(292.5, 84%, 56%) !important;
}
[data-channel="13"] {
background-color: hsl(315, 84%, 56%) !important;
}
[data-channel="14"] {
background-color: hsl(337.5, 84%, 56%) !important;
}
[data-channel="15"] {
background-color: hsl(0, 84%, 56%) !important;
}
/** keyboard **/
.main .keyboard {
width: 100%;
padding-bottom: 13%;
}
.main .key {
position: absolute;
left: 0;
bottom: 0;
background: white;
display: inline-block;
height: 100%;
}
.main [data-black="false"]:not(:last-child) {
border-right: 1px solid #262626;
}
.main [data-black="true"] {
bottom: 40%;
background: #262626;
border: 1px solid #262626;
border-top: 0;
margin-left: calc(-100% / 52 * 0.6 / 2);
width: calc(100% / 52 * 0.6);
height: 60%;
}
.main .key:not([data-channel="false"]) {
box-shadow: inset 1000em 1000em rgba(0, 0, 0, 0.1);
}
.main [data-black="true"][data-channel="-1"] {
box-shadow: inset 1000em 1000em rgba(255, 255, 255, 0.1);
}
/** sidebar controls **/
.main .control {
position: absolute;
top: 0;
left: -65px;
height: 100%;
width: 50px;
padding: 9px;
background: #1e1e1e;
text-align: center;
}
.main .control button {
-webkit-appearance: none;
width: 32px;
height: 32px;
border: 0;
cursor: pointer;
color: white;
background: none;
}
.main .control .switch-play-state, .main .control .open-channels-window,
.main .control .close {
background: center center no-repeat;
text-indent: -10000em;
}
.main .control > * {
display: block;
margin: 0 auto 1em auto;
}
/* playback control */
.main .control .switch-play-state {
background-image: url('../images/icons/play.png');
}
.main .control .switch-play-state.pause {
background-image: url('../images/icons/pause.png');
}
/* channels */
.main .control .open-channels-window {
background-image: url('../images/icons/channels.png');
}
/* set play speed */
.main .control .selector {
text-align: center;
line-height: 32px;
border: 1px solid white;
border-radius: 3px;
overflow: hidden;
padding: 0;
}
.main .control .selector:hover {
background: rgba(255, 255, 255, 0.05);
}
.main .control .selector:active {
padding: 1px 0 0 0;
}
.main .control .selector:before {
content: '×';
cursor: pointer;
}
/* close opened file */
.main .control .close {
background-image: url('../images/icons/close.png');
position: absolute;
left: 9px;
bottom: 0;
}
/** scroll **/
.main .scroll {
position: absolute;
top: 0;
left: -15px;
height: 100%;
background: #1e1e1e;
}
/**
* Channels modal
*/
.vex.vex .channels ul {
list-style: none;
padding: 0;
width: calc(100% + 2em);
margin: 0 0 0 -1em;
}
.vex .channels ul li {
display: block;
width: 100%;
padding: 0 0 0 44px;
background-position: 6px center;
background-repeat: no-repeat;
}
.vex .channels ul li span {
display: block;
height: 100%;
padding: 9px;
background: white;
}
.vex .channels ul li:nth-child(2n) span {
background: #e2e2e2;
}
.vex .channels ul li:hover, .vex .channels ul li:hover span {
box-shadow: inset 1000em 1000em rgba(0, 0, 0, 0.15);
}
/** icons **/
.vex .channels ul li.piano {
background-image: url('../images/icons/instruments/piano.png');
}
.vex .channels ul li.percussive {
background-image: url('../images/icons/instruments/percussive.png');
}
.vex .channels ul li.percussion {
background-image: url('../images/icons/instruments/percussion.png');
}
.vex .channels ul li.effect {
background-image: url('../images/icons/instruments/effect.png');
}
.vex .channels ul li.brass {
background-image: url('../images/icons/instruments/brass.png');
}
.vex .channels ul li.pipe {
background-image: url('../images/icons/instruments/pipe.png');
}
.vex .channels ul li.string {
background-image: url('../images/icons/instruments/string.png');
}
.vex .channels ul li.synth {
background-image: url('../images/icons/instruments/synth.png');
}
.vex .channels ul li.guitar {
background-image: url('../images/icons/instruments/guitar.png');
}
.vex .channels ul li.orchestra {
background-image: url('../images/icons/instruments/orchestra.png');
}
.vex .channels ul li.bass {
background-image: url('../images/icons/instruments/bass.png');
}
.vex .channels ul li.organ {
background-image: url('../images/icons/instruments/organ.png');
}
/**
* UI Components
*/
/** scroll **/
.scroll, ::-webkit-scrollbar {
height: 200px;
width: 15px;
overflow: hidden;
position: relative;
}
::-webkit-scrollbar-track {
background: #262626;
}
.scroll .position, ::-webkit-scrollbar-thumb {
display: block;
width: 100%;
position: absolute;
height: 5%;
min-height: 20px;
transform: translate(0, 50%);
background: rgba(255, 255, 255, 0.15);
}
.scroll .position:hover, ::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.3);
}

20
grunt/contrib-clean.js Normal file
View File

@ -0,0 +1,20 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.config('clean.clean-build', [
'build/<%= grunt.task.current.args[0] %>'
]);
grunt.config('clean.clean-files', [
'build/<%= paths.resources[grunt.task.current.args[0]] %>/app'
]);
grunt.config('clean.clean-default', [
'build/<%= paths.resources[grunt.task.current.args[0]] %>/default_app',
'build/<%= grunt.task.current.args[0] %>.zip'
]);
};

13
grunt/contrib-copy.js Normal file
View File

@ -0,0 +1,13 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.config('copy.copy-files', {
expand: true,
dest: 'build/<%= paths.resources[grunt.task.current.args[0]] %>/app',
src: grunt.config.get('files')
});
};

16
grunt/contrib-watch.js Normal file
View File

@ -0,0 +1,16 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.config('watch.watch-changes', {
files: grunt.config.get('files'),
tasks: [
'clean:clean-files:<%= grunt.task.current.args[1] %>',
'copy:copy-files:<%= grunt.task.current.args[1] %>',
'rebrand:rebrand-exe:<%= grunt.task.current.args[1] %>'
]
});
};

12
grunt/curl.js Normal file
View File

@ -0,0 +1,12 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-curl');
grunt.config('curl.fetch-asset', {
src: '<%= asset %>',
dest: 'build/<%= grunt.task.current.args[0] %>.zip'
});
};

67
grunt/http.js Normal file
View File

@ -0,0 +1,67 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-http');
/**
* Select matching asset from last release in releases list
* from GitHub API
*
* @param {releases: array} Releases list
* @return {string|false} Asset download URL, false if none found
*/
function selectAsset(releases) {
var assets, asset, release,
assetsLength, releasesLength,
name, types = grunt.config.get('platforms'),
type = types[grunt.task.current.args[0]],
i, j;
releasesLength = releases.length;
for (i = 0; i < releasesLength; i += 1) {
release = releases[i];
name = 'atom-shell-' + release.tag_name + '-' + type + '.zip';
// we only want stable releases
if (release.prerelease === false && release.draft === false) {
assets = release.assets;
assetsLength = assets.length;
for (j = 0; j < assetsLength; j += 1) {
asset = assets[j];
if (asset.name === name) {
return asset.browser_download_url;
}
}
}
}
return false;
}
grunt.config('http.find-asset', {
options: {
url: '<%= releases %>',
headers: {
'User-Agent': 'Grunt'
},
callback: function (err, res, body) {
if (err) {
throw err;
}
var releases = JSON.parse(body), asset = selectAsset(releases);
if (asset !== false) {
grunt.config.set('asset', asset);
} else {
grunt.fail.warn(new Error('No recent release found'));
}
}
}
});
};

13
grunt/mkdir.js Normal file
View File

@ -0,0 +1,13 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-mkdir');
grunt.config('mkdir.create-build', {
options: {
create: ['build/<%= grunt.task.current.args[0] %>']
}
});
};

33
grunt/rebrand.js Normal file
View File

@ -0,0 +1,33 @@
/*jshint node:true */
'use strict';
var rcedit = require('rcedit');
module.exports = function (grunt) {
grunt.registerMultiTask('rebrand', 'Rebrand .exe', function (platform) {
if (platform !== 'win') {
return;
}
var done = this.async();
rcedit(this.data.src, {
'icon': this.data.icon,
'version-string': this.data.meta
}, function (err) {
if (err) {
grunt.fail.warn(err);
return;
}
done();
});
});
grunt.config('rebrand.rebrand-exe', {
src: 'build/<%= paths.exe[grunt.task.current.args[0]] %>',
icon: 'images/logos/logo.ico',
meta: grunt.config.get('meta')
});
};

12
grunt/rename.js Normal file
View File

@ -0,0 +1,12 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-rename');
grunt.config('rename.rename-exe', {
src: 'build/<%= paths.originalExe[grunt.task.current.args[0]] %>',
dest: 'build/<%= paths.exe[grunt.task.current.args[0]] %>'
});
};

12
grunt/zip.js Normal file
View File

@ -0,0 +1,12 @@
/*jshint node:true */
'use strict';
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-zip');
grunt.config('unzip.extract-asset', {
src: 'build/<%= grunt.task.current.args[0] %>.zip',
dest: 'build/<%= grunt.task.current.args[0] %>/'
});
};

BIN
images/empty.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

BIN
images/icons/channels.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

BIN
images/icons/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

BIN
images/icons/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

BIN
images/icons/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

BIN
images/logos/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

137
images/logos/logo.svg Normal file
View File

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="278"
height="278"
id="svg2">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-79.90625,-324.375)"
id="layer1">
<rect
width="38.003857"
height="148.24254"
x="85.883125"
y="453.24094"
id="rect2985"
style="fill:none;stroke:#000000;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.00386"
height="148.24254"
x="123.91702"
y="453.24091"
id="rect2985-1"
style="fill:#1f2f5d;fill-opacity:1;stroke:#000000;stroke-width:1.75743675;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="161.95093"
y="453.24091"
id="rect2985-1-7"
style="fill:none;stroke:#000000;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="199.98483"
y="453.24091"
id="rect2985-1-7-4"
style="fill:none;stroke:#000000;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="238.01874"
y="453.24091"
id="rect2985-1-7-4-0"
style="fill:none;stroke:#000000;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="115.43273"
y="452.8179"
id="rect2985-1-7-4-0-9"
style="fill:#000000;stroke:#000000;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="153.46332"
y="452.8179"
id="rect2985-1-7-4-0-9-4"
style="fill:#000000;stroke:#000000;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="229.52444"
y="452.8179"
id="rect2985-1-7-4-0-9-4-8"
style="fill:#000000;stroke:#000000;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="276.05264"
y="453.24091"
id="rect2985-1-7-4-0-8"
style="fill:none;stroke:#000000;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="314.08652"
y="453.24091"
id="rect2985-1-7-4-0-8-2"
style="fill:none;stroke:#000000;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="267.55499"
y="452.8179"
id="rect2985-1-7-4-0-9-4-8-4"
style="fill:#000000;stroke:#000000;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="305.5856"
y="452.8179"
id="rect2985-1-7-4-0-9-4-8-4-5"
style="fill:#000000;stroke:#000000;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="265.92264"
height="127.96233"
x="85.925087"
y="325.38101"
id="rect2985-5"
style="fill:#0f0f0f;fill-opacity:1;stroke:#000000;stroke-width:2.03766823;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.764057"
height="78.182381"
x="123.60473"
y="375.271"
id="rect2985-1-1"
style="fill:#3955a7;fill-opacity:1;stroke:#000000;stroke-width:1.81761885;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.722099"
height="78.026169"
x="237.62572"
y="325.34909"
id="rect2985-1-7-4-0-7"
style="fill:#ed7631;fill-opacity:1;stroke:#000000;stroke-width:1.97382998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
images/logos/logo128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/logos/logo16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

BIN
images/logos/logo256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
images/logos/logo32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

BIN
images/logos/logo64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

123
images/logos/logo_u.svg Normal file
View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="278"
height="278"
id="svg2">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(-79.90625,-324.375)"
id="layer1">
<rect
width="38.003857"
height="148.24254"
x="85.883125"
y="453.24094"
id="rect2985"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.00386"
height="148.24254"
x="123.91702"
y="453.24091"
id="rect2985-1"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743675;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="161.95093"
y="453.24091"
id="rect2985-1-7"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="199.98483"
y="453.24091"
id="rect2985-1-7-4"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="238.01874"
y="453.24091"
id="rect2985-1-7-4-0"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="115.43273"
y="452.8179"
id="rect2985-1-7-4-0-9"
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.00784314;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="153.46332"
y="452.8179"
id="rect2985-1-7-4-0-9-4"
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.00784314;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="229.52444"
y="452.8179"
id="rect2985-1-7-4-0-9-4-8"
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.00784314;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="276.05264"
y="453.24091"
id="rect2985-1-7-4-0-8"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="38.003857"
height="148.24254"
x="314.08652"
y="453.24091"
id="rect2985-1-7-4-0-8-2"
style="fill:none;stroke:#e0e0e0;stroke-width:1.75743699;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="267.55499"
y="452.8179"
id="rect2985-1-7-4-0-9-4-8-4"
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.00784314;stroke-dasharray:none" />
<rect
width="17.00919"
height="89.088554"
x="305.5856"
y="452.8179"
id="rect2985-1-7-4-0-9-4-8-4-5"
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:0.91144872;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:0.00784314;stroke-dasharray:none" />
<rect
width="265.92264"
height="127.96233"
x="85.925087"
y="325.38101"
id="rect2985-5"
style="fill:#e0e0e0;fill-opacity:1;stroke:#e0e0e0;stroke-width:2.03766823;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
images/logos/logo_u128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
images/logos/logo_u16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

BIN
images/logos/logo_u256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
images/logos/logo_u32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 B

BIN
images/logos/logo_u64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

43
index.html Normal file
View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Piano</title>
<link rel="stylesheet" href="css/lib/vex/vex.css" />
<link rel="stylesheet" href="css/dialog-theme.css" />
<link rel="stylesheet" href="css/forms.css" />
<link rel="stylesheet" href="css/piano.css" />
</head>
<body>
<div id="content"></div>
<script src="js/init.js"></script>
<script src="js/modal.js"></script>
<!-- Libraries -->
<script src="js/lib/jquery/jquery.min.js"></script>
<script src="js/lib/jasmid/jasmid.min.js"></script>
<script src="js/lib/vex/vex.combined.min.js"></script>
<script src="js/lib/react/react-with-addons.js"></script>
<!-- MIDI -->
<script src="js/midi/file.js"></script>
<script src="js/midi/io.js"></script>
<!-- App -->
<script src="js/components/Channel/Channel.js"></script>
<script src="js/components/Channel/Modal.js"></script>
<script src="js/components/Key/Board.js"></script>
<script src="js/components/Key/Key.js"></script>
<script src="js/components/Note/Board.js"></script>
<script src="js/components/Note/Score.js"></script>
<script src="js/components/UI/Selector.js"></script>
<script src="js/components/UI/Scroll.js"></script>
<script src="js/components/Control.js"></script>
<script src="js/components/Error.js"></script>
<script src="js/components/Main.js"></script>
<script src="js/app.js"></script>
</body>
</html>

96
js/app.js Normal file
View File

@ -0,0 +1,96 @@
/*jshint es5: true */
/*globals MIDI, React, App, $ */
/**
* app.js
*
* Bootstrap app:
* - connect to MIDI device;
* - config vendors;
* - instantiate main component;
* - integrate with shell.
*/
(function () {
'use strict';
var remote, ipc, shell;
// shell integration
if (window.atom) {
remote = window.atom.require('remote');
shell = window.atom.require('shell');
ipc = window.atom.require('ipc');
}
// configs
window.vex.defaultOptions.className = 'dialog-theme';
window.vex.dialog.buttons.YES.text = 'OK';
window.vex.dialog.buttons.NO.text = 'Annuler';
// bootstrap
function bootstrap() {
var main = React.renderComponent(
App.components.Main(),
$('#content')[0]
);
// we're ready to receive shell options
// and to show the window
if (ipc) {
ipc.send('ready');
ipc.on('options', function (options) {
main.setProps({
url: options.file
});
});
ipc.on('visible', function (state) {
if (state) {
main.resume();
} else {
main.halt();
}
});
window.onkeydown = function (e) {
if (e.keyCode === 123 && remote) {
remote.getCurrentWindow().toggleDevTools();
}
};
}
// handle links in default navigator, not in app
if (shell) {
$(document).on('click', 'a', function (e) {
shell.openExternal($(this).attr('href'));
e.preventDefault();
});
}
}
// on error, offer choice to retry or ignore
function error(err) {
var modal = App.components.Error({
title: "Erreur d'initialisation",
error: err,
canRetry: true,
onRetry: function () {
window.location.reload();
},
onClose: function () {
bootstrap();
}
});
ipc.send('ready');
modal.open();
}
// establish connection to MIDI device
App.MIDI.connect()
.then(bootstrap)
.catch(error);
}());

View File

@ -0,0 +1,228 @@
/*globals React, App */
(function () {
'use strict';
/**
* Display channel
*/
App.components.create('Channel', {
displayName: 'Channel',
mixins: [React.addons.PureRenderMixin],
statics: {
programs: [
'Grand piano acoustique',
'Piano acoustique',
'Grand piano électrique',
'Piano bastringue',
'Piano électrique',
'Piano - effet chorus',
'Clavecin',
'Clavinet',
'Celesta',
'Glockenspiel',
'Boîte à musique',
'Vibraphone',
'Marimba',
'Xylophone',
'Cloches tubulaires',
'Tympanon',
'Orgue Hammond',
'Orgue à percussion',
'Orgue - Rock',
'Grandes orgues',
'Harmonium',
'Accordéon',
'Harmonica',
'Accordéon tango',
'Guitare classique',
'Guitare sèche',
'Guitare électrique - Jazz',
'Guitare électrique - son clair',
'Guitare électrique - sourdine',
'Guitare saturée',
'Guitare avec distorsion',
'Harmoniques de guitare',
'Basse acoustique sans frettes',
'Basse électrique',
'Basse électrique - médiator',
'Basse sans frettes',
'Basse - slap 1',
'Basse - slap 2',
'Basse synthé 1',
'Basse synthé 2',
'Violon',
'Violon alto',
'Violoncelle',
'Contrebasse',
'Cordes - trémolo',
'Cordes - pizzicato',
'Harpe',
'Timbales',
'Ensemble acoustique à Cordes 1',
'Ensemble acoustique à Cordes 2',
'Cordes synthé 1',
'Cordes synthé 2',
'Chœur - "Aah"',
'Voix - "Ooh"',
'Voix synthétique',
'Coup d\'orchestre',
'Trompette',
'Trombone',
'Tuba',
'trompette en sourdine',
'Cor d\'harmonie',
'Section de cuivres',
'Cuivres synthé',
'Cuivres synthé',
'Saxophone soprano',
'Saxophone alto',
'Saxophone ténor',
'Saxophone baryton',
'Hautbois',
'Cor anglais',
'Basson',
'Clarinette',
'Piccolo',
'Flûte',
'Flûte à bec',
'Flûte de pan',
'Bouteille - souffle',
'Shakuhachi',
'Sifflet',
'Ocarina',
'Signal carré',
'Signal dents de scie',
'Orgue à vapeur',
'Chiffer',
'Charang',
'Voix solo',
'Signal dent de scie en quinte',
'Basse & Solo',
'Fantaisie',
'Son chaleureux',
'Polysynthé',
'Chœur',
'Archet',
'Métallique',
'Halo',
'Balai',
'Pluie de glace',
'Trames sonores',
'Cristal',
'Atmosphère',
'Brillance',
'Gobelins',
'Échos',
'Espace',
'Sitar',
'Banjo',
'Shamisen',
'Koto',
'Kalimba',
'Cornemuse',
'Viole',
'Shehnai',
'Clochettes',
'Agogo',
'Batterie métallique',
'Planchettes',
'Timbales',
'Tom mélodique',
'Tambour synthétique',
'Cymbale - inversée',
'Guitare - bruit de frette',
'Respiration',
'Rivage',
'Gazouilli',
'Sonnerie de téléphone',
'Hélicoptère',
'Applaudissements',
'Coup de feu'
],
types: [
'piano',
'percussive',
'percussion',
'effect',
'brass',
'pipe',
'string',
'synth',
'guitar',
'orchestra',
'bass',
'organ'
],
getType: function (id) {
var types = App.components.Channel.Channel.types;
if (id >= 0 && id <= 7) {
return types[0];
} else if ((id >= 8 && id <= 15) || (id >= 104 && id <= 119)) {
return types[1];
} else if (id >= 16 && id <= 23) {
return types[11];
} else if (id >= 24 && id <= 31) {
return types[8];
} else if (id >= 32 && id <= 39) {
return types[10];
} else if (id >= 40 && id <= 47) {
return types[6];
} else if (id >= 48 && id <= 55) {
return types[9];
} else if (id >= 56 && id <= 71) {
return types[4];
} else if (id >= 72 && id <= 79) {
return types[5];
} else if (id >= 80 && id <= 95) {
return types[7];
} else if ((id >= 96 && id <= 103) || (id >= 120 && id <= 127)) {
return types[3];
} else {
return '';
}
}
},
propTypes: {
id: React.PropTypes.number.isRequired,
program: React.PropTypes.number.isRequired,
muted: React.PropTypes.bool,
solo: React.PropTypes.bool
},
getDefaultProps: function () {
return {
id: 0,
program: 0,
muted: false,
solo: false
};
},
/**
* Render channel
*/
render: function () {
var title = 'Gestion des canaux', type, name,
channel = App.components.Channel.Channel;
if (this.props.id === 9) {
type = channel.types[2];
name = 'Percussions';
} else {
type = channel.getType(this.props.program);
name = channel.programs[this.props.program];
}
return React.DOM.li({
className: 'channel ' + type,
'data-channel': this.props.id
}, React.DOM.span(null, name));
}
});
}());

View File

@ -0,0 +1,58 @@
/*jshint nomen:true */
/*globals React, App */
(function () {
'use strict';
/**
* Modal for managing channels
*
* @prop {channels: Array} List of channels
* @prop {open: func} Called to open the window
* @prop {close: func} Called to close the window
*/
App.components.modal('Channel', {
displayName: 'Modal',
mixins: [React.addons.PureRenderMixin],
propTypes: {
channels: React.PropTypes.array,
open: React.PropTypes.func,
close: React.PropTypes.func
},
getDefaultProps: function () {
return {
channels: [],
open: function () {},
close: function () {}
};
},
/**
* Render modal
*/
render: function () {
var title = 'Gestion des canaux', channels;
channels = this.props.channels.map(function (channel) {
channel.key = 'channel-' + channel.id;
return App.components.Channel.Channel(channel);
});
return React.DOM.form({
className: 'vex-dialog-form channels'
}, [
React.DOM.h4({
key: 'title',
className: 'main-title'
}, title),
React.DOM.ul({
key: 'channels'
}, channels)
]);
}
});
}());

129
js/components/Control.js Normal file
View File

@ -0,0 +1,129 @@
/*globals App, React */
(function () {
'use strict';
/**
* Sidebar controls
*
* @prop {playing: bool} Whether a song is playing or not
* @prop {opened: bool} Whether a file is opened
* @prop {speed: number} Current speed rate
* @prop {play: function} Called to start playback
* @prop {pause: function} Called to pause playback
* @prop {showChannelsModal: function} Called to show channels manager
* @prop {setPlaySpeed: function} Called to set play speed
* @prop {close: function} Called to close
*/
App.components.create({
displayName: 'Control',
mixins: [React.addons.PureRenderMixin],
propTypes: {
playing: React.PropTypes.bool,
opened: React.PropTypes.bool,
speed: React.PropTypes.number,
play: React.PropTypes.func,
pause: React.PropTypes.func,
showChannelsModal: React.PropTypes.func,
setPlaySpeed: React.PropTypes.func,
close: React.PropTypes.func
},
getDefaultProps: function () {
return {
playing: false,
opened: false,
play: function () {},
pause: function () {},
showChannelsModal: function () {},
setPlaySpeed: function () {},
close: function () {}
};
},
/**
* Keyboard shortcuts
*/
componentDidMount: function () {
window.addEventListener('keyup', this.keyUp);
},
componentWillUnmount: function () {
window.removeEventListener('keyup', this.keyUp);
},
keyUp: function (e) {
var code = e.keyCode, index;
// space: switch state
if (code === 32) {
this.switchPlayState();
e.preventDefault();
}
},
/**
* Delegates
*/
switchPlayState: function () {
if (this.props.playing) {
this.props.pause();
} else {
this.props.play();
}
},
/**
* Render control
*/
render: function () {
var controls = [];
if (this.props.opened) {
controls.push(React.DOM.button({
key: 'switchPlayState',
className: (this.props.playing) ?
'switch-play-state pause' : 'switch-play-state',
onClick: this.switchPlayState
}, 'Play/pause'));
controls.push(React.DOM.button({
key: 'openChannelsWindow',
className: 'open-channels-window',
onClick: this.props.showChannelsModal
}, 'Ouvrir le gestionnaire de canaux'));
controls.push(App.components.UI.Selector({
key: 'setPlaySpeed',
className: 'set-play-speed',
values: [1, 0.5, 0.3, 1, 2, 3],
value: this.props.speed,
onChange: this.props.setPlaySpeed
}));
controls.push(React.DOM.button({
key: 'close',
className: 'close',
onClick: this.props.close
}));
} else {
controls.push(React.DOM.button({
key: 'close',
className: 'close',
onClick: window.close
}));
}
return React.DOM.div({
className: 'control'
}, controls);
}
});
}());

107
js/components/Error.js Normal file
View File

@ -0,0 +1,107 @@
/*jshint nomen:true */
/*globals React, App */
(function () {
'use strict';
/**
* Modal for displaying Error objects
*
* @prop {title: string} Error title, category or extra data
* @prop {error: Error} Error object to format
* @prop {canRetry: bool} Whether the user can ask to recover from this error
* @prop {open: func} Called to open the window
* @prop {close: func} Called to close the window
* @prop {onRetry: func} Called when the user asks for retrying
*/
App.components.modal({
displayName: 'Error',
mixins: [React.addons.PureRenderMixin],
modal: {
showCloseButton: false
},
propTypes: {
title: React.PropTypes.string,
error: React.PropTypes.object,
canRetry: React.PropTypes.bool,
open: React.PropTypes.func,
close: React.PropTypes.func,
onRetry: React.PropTypes.func
},
getDefaultProps: function () {
return {
title: 'Erreur',
error: new Error('Erreur'),
canRetry: false,
open: function () {},
close: function () {},
onRetry: function () {}
};
},
/**
* Retry handler
*/
retry: function (e) {
this.props.onRetry();
e.preventDefault();
},
/**
* Close handler
*/
close: function (e) {
this.props.close();
e.preventDefault();
},
/**
* Render modal
*/
render: function () {
var buttons = [];
buttons = [
React.DOM.button({
key: 'retry',
className: 'bt primary inverse',
style: {
display: (this.props.canRetry) ?
'inline-block' : 'none'
},
onClick: this.retry
}, 'Réessayer'),
React.DOM.button({
key: 'continue',
className: 'bt secondary inverse',
onClick: this.close
}, 'Continuer')
];
return React.DOM.form({
className: 'vex-dialog-form'
}, [
React.DOM.h4({
key: 'title',
className: 'main-title'
}, this.props.title),
React.DOM.p({
key: 'description',
dangerouslySetInnerHTML: {
__html: this.props.error.message
}
}),
React.DOM.p({
key: 'buttons',
className: 'vex-dialog-buttons'
}, buttons)
]);
}
});
}());

163
js/components/Key/Board.js Normal file
View File

@ -0,0 +1,163 @@
/*globals React, App */
(function () {
'use strict';
/**
* Display keyboard
*/
App.components.create('Key', {
displayName: 'Board',
mixins: [React.addons.PureRenderMixin],
clicked: false,
statics: {
offset: 27 + App.MIDI.keyOffset,
keysToNotes: [
65, 50, 90, 51, 69, 82, 53, 84, 54, 89, 55, 85, 73,
57, 79, 48, 80, 87, 83, 88, 68, 67, 70, 86, 66, 72,
78, 74, 188, 190, 76, 191, 77, 223, 192, 16
]
},
/**
* Set given note on given channel
*
* @param {note: number} Note number
* @param {channel: number} Channel ID
* @param {velocity: number} Note velocity
*/
on: function (note, channel, velocity) {
var key = this.refs['key-' + note];
if (key) {
key.on(channel, velocity);
}
},
/**
* Check whether given note plays on given channel
*
* @param {note: number} Note number
* @param {channel: number} Channel ID
*/
isOn: function (note, channel) {
var key = this.refs['key-' + note];
return (key.state.channels.indexOf(channel) > -1);
},
/**
* Set given note off given channel
*
* @param {note: number} Note number
* @param {channel: number} Channel ID
*/
off: function (note, channel) {
var key = this.refs['key-' + note];
if (key) {
key.off(channel);
}
},
/**
* Set all notes off
*/
allOff: function () {
var i, keys = this.refs;
for (i in keys) {
if (keys.hasOwnProperty(i) && i.substr(0, 4) === 'key-') {
keys[i].off();
}
}
},
/**
* Events
*/
componentDidMount: function () {
window.addEventListener('keydown', this.keyDown);
window.addEventListener('keyup', this.keyUp);
window.addEventListener('mouseup', this.release);
},
componentWillUnmount: function () {
window.removeEventListener('keydown', this.keyDown);
window.removeEventListener('keyup', this.keyUp);
window.removeEventListener('mouseup', this.release);
},
/* mouse click */
click: function (e) {
if (e.button !== 0) {
return;
}
this.clicked = true;
},
/* mouse release */
release: function () {
this.clicked = false;
},
/* play keys with keyboard (the real one) */
keyDown: function (e) {
var code = e.keyCode, index,
Keyboard = App.components.Key.Board;
// play note
if ((index = Keyboard.keysToNotes.indexOf(code)) > -1) {
index += Keyboard.offset;
if (!this.isOn(index, -1)) {
this.on(index, -1, 127);
}
e.preventDefault();
}
},
/* release keys */
keyUp: function (e) {
var index, Keyboard = App.components.Key.Board;
if ((index = Keyboard.keysToNotes.indexOf(e.keyCode)) > -1) {
this.off(index + Keyboard.offset, -1);
e.preventDefault();
}
},
/**
* Whether keys should be played on mouse over
*/
canPlay: function () {
return this.clicked;
},
/**
* Render keyboard
*/
render: function () {
var i, offset = App.MIDI.keyOffset,
length = 88 + offset, keys = [];
for (i = offset; i < length; i += 1) {
keys.push(App.components.Key.Key({
key: i,
ref: 'key-' + i,
note: i,
canPlay: this.canPlay
}));
}
return React.DOM.p({
className: 'keyboard',
onMouseDown: this.click
}, keys);
}
});
}());

172
js/components/Key/Key.js Normal file
View File

@ -0,0 +1,172 @@
/*globals React, App */
(function () {
'use strict';
/**
* Displays a key on keyboard
*
* @prop {note: int} MIDI note identifier
* @prop {canPlay: function} Whether the note can be manually played
*/
App.components.create('Key', {
displayName: 'Key',
mixins: [React.addons.PureRenderMixin],
propTypes: {
note: React.PropTypes.number.isRequired
},
getInitialState: function () {
return {
channels: []
};
},
getDefaultProps: function () {
return {
note: 0,
canPlay: function () {}
};
},
/**
* Start playing note on given channel with given velocity
*
* @param {channel: number} Channel ID
* @param {velocity: number} Note velocity
*/
on: function (channel, velocity) {
if (this.state.channels.indexOf(channel) > -1) {
return;
}
App.MIDI.output.noteOn(
(channel === -1) ? 0 : channel,
this.props.note,
velocity,
0
);
this.setState({
channels: this.state.channels.concat([
channel
])
});
},
/**
* Stop playing note on previous channel
*
* @param {channel: number} Channel ID
* @param {channel: Array} Channels IDs (default: all current)
*/
off: function (channels) {
var i, length, channel, current,
index;
current = this.state.channels.slice(0);
if (channels === undefined) {
channels = this.state.channels;
} else if (!Array.isArray(channels)) {
channels = [channels];
}
length = channels.length;
for (i = 0; i < length; i += 1) {
channel = channels[i];
App.MIDI.output.noteOff(
(channel === -1) ? 0 : channel,
this.props.note,
0
);
index = current.indexOf(channel);
// remove channels from current playing
if (index > -1) {
current.splice(index, 1);
}
}
this.setState({
channels: current
});
},
/**
* Start playing note on mouse over
*/
mouseOver: function () {
if (!this.props.canPlay()) {
return;
}
this.mouseDown();
},
/**
* Play on mouse down
*/
mouseDown: function (e) {
if (e && e.button !== 0) {
return;
}
this.on(-1, 127);
},
/**
* Render key
*/
render: function () {
var black = App.components.Note.Board.black, offset,
pianoNote = this.props.note, style, channels, channel,
isBlack = (black.indexOf(this.props.note) > -1);
offset = pianoNote - black.filter(function (el) {
return el < pianoNote;
}).length - App.MIDI.keyOffset;
// if it is a black key, we position it absolutely;
// otherwise we just play on its width to avoid rounding
// errors causing display glitches
if (isBlack) {
style = {
left: 'calc(100% / 52 * ' + offset + ')',
zIndex: App.MIDI.keyOffset + 88
};
} else {
style = {
width: 'calc(100% / 52 * ' + (offset + 1) + ')',
zIndex: App.MIDI.keyOffset + 88 - pianoNote
};
}
// get channel ID
channels = this.state.channels;
if (channels.length > 0) {
channel = channels[channels.length - 1];
} else {
channel = false;
}
return React.DOM.span({
className: 'key',
onMouseDown: this.mouseDown,
onMouseOver: this.mouseOver,
onMouseUp: this.off.bind(this, -1),
onMouseOut: this.off.bind(this, -1),
style: style,
'data-channel': channel,
'data-black': isBlack
});
}
});
}());

464
js/components/Main.js Normal file
View File

@ -0,0 +1,464 @@
/*jshint es5: true */
/*globals App, React */
(function () {
'use strict';
/**
* Display main view
*
* @prop {url: string} URL to MIDI file
*/
App.components.create({
displayName: 'Main',
animation: false,
lastTime: null,
wheeling: false,
wasPlaying: false,
/**
* State and props config
*/
propTypes: {
url: React.PropTypes.string
},
getDefaultProps: function () {
return {
url: ''
};
},
getInitialState: function () {
return {
opened: false,
name: '',
meta: {},
timeline: [],
playing: false,
speed: 1,
time: 0
};
},
/**
* Open a file
*
* @param {url: string} File path
* @param {showDialog: bool} Whether to show an open dialog (will ignore url param)
*/
open: function (url, showDialog) {
var remote, dialog, selection;
if (showDialog === true) {
remote = window.atom.require('remote');
dialog = remote.require('dialog');
selection = dialog.showOpenDialog(remote.getCurrentWindow(), {
title: 'Ouvrir',
filters: [
{
name: 'Fichiers MIDI',
extensions: ['mid', 'midi']
},
{
name: 'Tous les fichiers',
extensions: []
}
]
});
if (!selection || !selection.length) {
return;
} else {
url = selection[0];
}
} else if (url === '') {
this.close();
return;
}
if (this.state.opened) {
this.close();
}
App.MIDI.file.load(url)
.then(App.MIDI.file.parse)
.then(function (data) {
var parts, name;
parts = url.split(/\\|\//g);
name = parts[parts.length - 1];
this.setState({
name: name,
opened: true,
meta: data.meta,
timeline: data.timeline
}, function () {
this.stop();
this.setupChannels();
});
}.bind(this))
.catch(function (err) {
var modal = App.components.Modal.Error({
title: "Erreur d'ouverture du fichier",
error: err
});
modal.open();
});
},
/**
* Create a new file
*/
create: function () {
this.setState({
name: 'Nouvelle composition',
opened: true,
meta: {},
timeline: []
}, function () {
this.stop();
this.setupChannels();
});
},
/**
* Close opened file
*/
close: function () {
this.setState({
name: '',
opened: false,
meta: {},
timeline: []
}, function () {
this.stop();
this.setupChannels();
});
},
/**
* Load file when mounted
* Set up keyboard listener
*/
componentDidMount: function () {
this.open(this.props.url);
window.addEventListener('keyup', this.keyUp);
},
/**
* Remove keyboard listener
*/
componentWillUnmount: function () {
window.removeEventListener('keyup', this.keyUp);
},
/**
* Load file when changed
*/
componentWillReceiveProps: function (props) {
if (props.url !== this.state.url) {
this.open(props.url);
}
},
/**
* Update window title on name change
*/
componentWillUpdate: function (nextProps, nextState) {
var name = nextState.name;
if (nextState.name !== this.state.name) {
if (typeof name === 'string' && name !== '') {
document.title = name + ' - Piano';
} else {
document.title = 'Piano';
}
}
},
/**
* Playback control
*/
/* start playback */
play: function () {
if (this.state.playing || this.state.url === '') {
return;
}
this.wasPlaying = false;
this.startedTime = window.performance.now();
this.animation = window.requestAnimationFrame(this.move);
this.setState({
playing: true
});
},
/* only plays if it was previously paused with halt() */
resume: function () {
if (this.wasPlaying) {
this.wasPlaying = false;
this.play();
}
},
/* pause playing */
pause: function () {
if (!this.state.playing) {
return;
}
window.cancelAnimationFrame(this.animation);
this.animation = false;
this.lastTime = null;
this.setState({
playing: false
});
},
/* halt play for future resuming */
halt: function () {
if (this.state.playing) {
this.wasPlaying = true;
this.pause();
}
},
/* pause and reset time */
stop: function () {
this.pause();
this.setTime(0);
},
/* update current time and play last notes */
move: function () {
var previous = this.state.time, next = previous,
time, speed = this.state.speed;
time = window.performance.now();
if (this.lastTime) {
next += (time - this.lastTime) / 1000 * speed;
}
if (previous > this.state.meta.length) {
this.stop();
return;
}
this.do(previous, next);
this.setState({
time: next
}, function () {
this.animation = window.requestAnimationFrame(this.move);
this.lastTime = time;
}.bind(this));
},
/* set up channel meta */
setupChannels: function () {
var channels = this.state.meta.channels || {}, channel,
length = 16, i;
for (i = 0; i < length; i += 1) {
channel = channels[i] || {};
App.MIDI.output.programChange(
channel.id || i,
channel.program || 0
);
}
},
/* do events in given interval */
do: function (start, end) {
var timeline = this.state.timeline, i,
length = timeline.length, event;
for (i = 0; i < length; i += 1) {
event = timeline[i];
if (event.time >= start && event.time < end) {
switch (event.type) {
case 'noteOn':
this.refs.keyboard.on(
event.note,
event.channel,
event.velocity
);
break;
case 'noteOff':
this.refs.keyboard.off(
event.note,
event.channel
);
break;
case 'noteAftertouch':
this.refs.keyboard.change(
event.note,
event.channel,
event.amount
);
break;
case 'controller':
App.MIDI.output.controller(
event.channel,
event.subtype,
event.value
);
break;
}
}
}
},
/**
* Allow file dropping
*/
dragOver: function (e) {
e.stopPropagation();
e.preventDefault();
},
/**
* Handle drop
*/
drop: function (e) {
var files = e.dataTransfer.files, file,
length = files.length, reader;
if (length) {
this.open(files[0].path);
}
e.stopPropagation();
e.preventDefault();
},
/**
* Delegates
*/
scrollNoteboard: function (delta) {
this.refs.noteboard.scroll(delta);
},
startWheel: function () {
if (this.wheeling !== false) {
clearTimeout(this.wheeling);
}
this.halt();
this.wheeling = setTimeout(this.resume, 250);
},
setPlaySpeed: function (speed) {
this.setState({
speed: speed
});
},
setTime: function (time) {
this.refs.keyboard.allOff();
this.setState({
time: time
});
},
showChannelsModal: function () {
if (this.state.url === '') {
return;
}
var modal = App.components.Channel.Modal({
channels: this.state.meta.channels
});
modal.open();
},
/**
* Render panel
*/
render: function () {
var control, noteboard, keyboard, scroll;
keyboard = App.components.Key.Board({
key: 'keyboard',
ref: 'keyboard'
});
noteboard = App.components.Note.Board({
key: 'noteboard',
ref: 'noteboard',
notes: this.state.meta.notes,
playing: this.state.playing,
speed: this.state.speed,
time: this.state.time,
length: this.state.meta.length,
opened: this.state.opened,
startWheel: this.startWheel,
setTime: this.setTime,
open: this.open,
create: this.create
});
control = App.components.Control({
key: 'control',
ref: 'control',
playing: this.state.playing,
opened: this.state.opened,
speed: this.state.speed,
play: this.play,
pause: this.pause,
showChannelsModal: this.showChannelsModal,
setPlaySpeed: this.setPlaySpeed,
close: this.close
});
scroll = App.components.UI.Scroll({
className: 'scroll',
key: 'scroll',
current: this.state.time,
max: this.state.meta.length,
onChange: this.scrollNoteboard,
onDragStart: this.halt,
onDragEnd: this.resume
});
return React.DOM.div({
className: 'main',
onDragOver: this.dragOver,
onDrop: this.drop
}, [
control,
scroll,
React.DOM.div({
key: 'roll',
className: 'roll'
}, [
noteboard,
keyboard
])
]);
}
});
}());

191
js/components/Note/Board.js Normal file
View File

@ -0,0 +1,191 @@
/*globals React, App */
(function () {
'use strict';
/**
* Displays a noteboard from given notes
*
* @prop {notes: array} Array of notes to show
* @prop {time: int} Playback time
* @prop {length: int} Playback length
* @prop {speed: int} Playback speed
* @prop {opened: bool} Whether a file is opened
* @prop {startWheel: function} Called when wheeling starts
* @prop {setTime: function} Called to change time
* @prop {open: function} Called to load a file
* @child Note
*/
App.components.create('Note', {
displayName: 'Board',
mixins: [React.addons.PureRenderMixin],
statics: {
/**
* List of black keys
*/
black: [22, 25, 27, 30, 32, 34, 37, 39, 42, 44,
46, 49, 51, 54, 56, 58, 61, 63, 66, 68,
70, 73, 75, 78, 80, 82, 85, 87, 90, 92,
94, 97, 99, 102, 104, 106]
},
/**
* State and props config
*/
propTypes: {
notes: React.PropTypes.array.isRequired,
time: React.PropTypes.number,
length: React.PropTypes.number,
speed: React.PropTypes.number,
opened: React.PropTypes.bool,
startWheel: React.PropTypes.func,
setTime: React.PropTypes.func,
open: React.PropTypes.func,
create: React.PropTypes.func
},
getDefaultProps: function () {
return {
notes: [],
playing: false,
time: 0,
length: 0,
speed: 1,
opened: false,
startWheel: function () {},
setTime: function () {},
open: function () {},
create: function () {}
};
},
/**
* Events
*/
componentDidMount: function () {
window.addEventListener('keyup', this.keyUp);
window.addEventListener('keydown', this.keyDown);
},
componentWillUnmount: function () {
window.removeEventListener('keyup', this.keyUp);
window.removeEventListener('keydown', this.keyDown);
},
/* keyboard shortcuts */
keyDown: function (e) {
var code = e.keyCode;
// top arrow: scroll top
if (code === 38) {
this.scroll(-0.5);
e.preventDefault();
}
// bottom arrow: scroll bottom
if (code === 40) {
this.scroll(0.5);
e.preventDefault();
}
},
keyUp: function (e) {
var code = e.keyCode;
// home: go to start
if (code === 36) {
this.props.setTime(0);
e.preventDefault();
}
// end: go to end
if (code === 35) {
this.props.setTime(this.props.length - 1);
e.preventDefault();
}
},
/* scroll noteboard */
scroll: function (delta) {
var nextValue = this.props.time - delta;
if (nextValue < 0) {
nextValue = 0;
}
if (nextValue > this.props.length) {
nextValue = this.props.length;
}
this.props.setTime(nextValue);
},
/* reduce wheel amplitude */
wheel: function (e) {
this.props.startWheel();
this.scroll(e.deltaY * 0.01);
},
/* trigger opening window */
open: function () {
this.props.open('', true);
},
/**
* Render noteboard
*/
render: function () {
var children, notes,
controls = [], id = -1, className = 'noteboard';
if (this.props.opened) {
className += ' opened';
children = App.components.Note.Score({
key: 'score',
className: 'score',
notes: this.props.notes,
time: this.props.time
});
} else {
className += ' closed';
// add opening controls
controls.push(React.DOM.button({
key: 'create',
className: 'bt primary',
onClick: this.props.create
}, 'Composer'));
controls.push(React.DOM.button({
key: 'open',
className: 'bt primary',
onClick: this.open
}, 'Ouvrir un fichier'));
children = React.DOM.p({
key: 'controls',
className: 'controls'
}, [
React.DOM.img({
key: 'image',
src: 'images/logos/logo_u128.png',
alt: 'Aucun fichier ouvert'
})
].concat(controls));
}
return React.DOM.div({
className: className,
onWheel: this.wheel,
onClick: this.click
}, children);
}
});
}());

218
js/components/Note/Score.js Normal file
View File

@ -0,0 +1,218 @@
/*globals React, Kinetic, App */
(function () {
'use strict';
/**
* Display a set of notes
*
* @prop {notes: array} List of notes
* @prop {time: int} Current playing time
*/
App.components.create('Note', {
displayName: 'Score',
statics: {
channels: [
'hsl(225, 49%, 44%)',
'hsl(22.5, 84%, 56%)',
'hsl(45, 53%, 39%)',
'hsl(67.5, 84%, 56%)',
'hsl(90, 84%, 56%)',
'hsl(112.5, 84%, 56%)',
'hsl(135, 84%, 56%)',
'hsl(157.5, 84%, 56%)',
'hsl(180, 84%, 56%)',
'hsl(202.5, 84%, 56%)',
'hsl(247.5, 84%, 56%)',
'hsl(270, 84%, 56%)',
'hsl(292.5, 84%, 56%)',
'hsl(315, 84%, 56%)',
'hsl(337.5, 84%, 56%)',
'hsl(0, 84%, 56%)'
]
},
propTypes: {
notes: React.PropTypes.array.isRequired,
time: React.PropTypes.number
},
getDefaultProps: function () {
return {
notes: [],
time: 0
};
},
getInitialState: function () {
return {
notes: [],
time: 0,
width: 0,
height: 0
};
},
/**
* When component is mounted, create Kinetic stage and
* attach resizing event
*/
componentDidMount: function () {
var notes;
window.addEventListener('resize', this.resize);
notes = this.props.notes;
this.sort(notes);
this.setState({
notes: notes,
time: this.props.time
}, this.resize);
},
componentWillUnmount: function () {
window.removeEventListener('resize', this.resize);
},
/**
* Redraw canvas on each props update
*/
componentWillReceiveProps: function (nextProps) {
if (nextProps.notes !== this.props.notes) {
this.sort();
}
this.setState({
notes: nextProps.notes,
time: nextProps.time
}, this.draw);
},
/**
* Never rebuild canvas element
*/
shouldComponentUpdate: function (props) {
return false;
},
/**
* Set canvas size
*
* @param {callback: func} Called when size is updated
*/
resize: function (callback) {
var canvas = this.getDOMNode(),
parent = canvas.parentNode,
width = parent.clientWidth,
height = parent.clientHeight,
ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
this.setState({
width: width,
height: height
}, this.draw);
},
/**
* Get note offset by note ID
*
* @param {id: int} Note ID
*/
getOffset: function (id) {
return id - App.MIDI.keyOffset -
App.components.Note.Board.black.filter(function (el) {
return el < id;
}).length;
},
/**
* Get whether a note is black or not
*
* @param {id: int} Note ID
*/
isBlack: function (id) {
return (App.components.Note.Board.black.indexOf(id) > -1);
},
/**
* Sort notes by length
*
* @param {notes: array} Notes list
*/
sort: function (notes) {
var length = notes.length, i;
for (i = 0; i < length; i += 1) {
notes[i].id = i;
}
notes.sort(function (a, b) {
if (a.length === b.length) {
return b.start - a.start;
}
return b.length - a.length;
});
},
/**
* Draw notes
*/
draw: function () {
var notes = this.state.notes, time = this.state.time,
width = this.state.width, height = this.state.height,
xUnit = width / 52, yUnit = xUnit * 5,
maxTime = Math.ceil(height / yUnit),
note, length, i, ctx, offset, x, y, noteWidth, noteHeight,
channels = App.components.Note.Score.channels, count = 0;
ctx = this.getDOMNode().getContext('2d');
ctx.clearRect(0, 0, width, height);
ctx.strokeStyle = '#262626';
ctx.lineWidth = 2;
length = notes.length;
for (i = 0; i < length; i += 1) {
note = notes[i];
if (note.start + note.length > time &&
note.start < time + maxTime) {
offset = this.getOffset(note.note);
count += 1;
x = Math.floor(xUnit * offset);
y = Math.floor(height - yUnit * (note.start + note.length - time));
noteWidth = Math.floor(xUnit);
noteHeight = Math.floor(yUnit * note.length);
if (note.channel === 9 && noteHeight < 10) {
noteHeight = 10;
}
if (this.isBlack(note.note)) {
x -= Math.floor(xUnit / 4);
noteWidth = Math.floor(xUnit / 2);
}
ctx.fillStyle = channels[note.channel];
ctx.strokeRect(x, y, noteWidth, noteHeight);
ctx.fillRect(x, y, noteWidth, noteHeight);
}
}
},
/**
* Render score canvas
*/
render: function () {
return React.DOM.canvas();
}
});
}());

156
js/components/UI/Scroll.js Normal file
View File

@ -0,0 +1,156 @@
/*globals React, App */
(function () {
'use strict';
/**
* Display a scrollbar
*
* @prop {current: int} Current position
* @prop {max: int} Maximum number we can reach
* @prop {onChange: function} Called on scrolling attempt
* @prop {onDragStart: function} Called on start of scrolling
* @prop {onDragEnd: function} Called on end of scrolling
*/
App.components.create('UI', {
displayName: 'Scroll',
mixins: [React.addons.PureRenderMixin],
position: null,
dragging: false,
propTypes: {
current: React.PropTypes.number,
max: React.PropTypes.number,
onChange: React.PropTypes.func,
onDragStart: React.PropTypes.func,
onDragEnd: React.PropTypes.func
},
getDefaultProps: function () {
return {
current: 0,
max: 0,
onChange: function () {},
onDragStart: function () {},
onDragEnd: function () {}
};
},
componentDidMount: function () {
window.addEventListener('mousemove', this.mouseMove);
window.addEventListener('mouseup', this.mouseUp);
},
componentWillUnmount: function () {
window.removeEventListener('mousemove', this.mouseMove);
window.removeEventListener('mouseup', this.mouseUp);
},
/**
* Convert distance to value
*/
convert: function (input) {
return input * this.props.max / this.getDOMNode().clientHeight;
},
/**
* Convert value to distance
*/
reverseConvert: function (output) {
return output * this.getDOMNode().clientHeight / this.props.max;
},
/**
* Scroll by given position
*
* @param {position: int} Current position
*/
scrollBy: function (position) {
var current = this.props.max - this.props.current,
delta = this.convert(position - this.reverseConvert(current));
this.props.onChange(delta);
},
/**
* Start scroll dragging
*/
mouseDown: function (e) {
if (e.button !== 0) {
return;
}
this.position = e.clientY;
this.props.onDragStart();
},
/**
* Move scroll
*/
mouseMove: function (e) {
if (this.position === null) {
return;
}
if (Math.abs(e.clientY - this.position) >= 3) {
this.dragging = true;
}
if (!this.dragging) {
return;
}
this.scrollBy(e.clientY);
},
/**
* Mouse release
*/
mouseUp: function (e) {
if (this.dragging) {
this.props.onDragEnd();
this.dragging = false;
this.position = null;
}
},
/**
* Click on track
*/
click: function (e) {
if (e.button === 0) {
this.scrollBy(e.clientY);
}
},
/**
* Render scroll
*/
render: function () {
var bottom;
if (this.props.max === 0) {
bottom = '-100%';
} else {
bottom = 'calc(100% / ' + this.props.max + ' * ' +
this.props.current + ')';
}
return React.DOM.div({
className: 'scroll',
onClick: this.click
}, [
React.DOM.span({
key: 'position',
className: 'position',
onMouseDown: this.mouseDown,
style: {
bottom: bottom
}
})
]);
}
});
}());

View File

@ -0,0 +1,91 @@
/*globals React, App */
(function () {
'use strict';
/**
* Display a value that can be changed on click
*
* @prop {values: array} List of values
* @prop {value: number} Current value
* @prop {onChange: function} Called whenever value changes
*/
App.components.create('UI', {
displayName: 'Selector',
mixins: [React.addons.PureRenderMixin],
propTypes: {
values: React.PropTypes.array.isRequired,
value: React.PropTypes.number,
onChange: React.PropTypes.func
},
getDefaultProps: function () {
return {
value: null,
onChange: function () {}
};
},
getInitialState: function () {
return {
value: null,
index: null
};
},
componentDidMount: function () {
if (this.props.value === null) {
this.setState({
value: this.props.values[0],
index: 0
});
} else {
this.setState({
value: this.props.value,
index: this.props.values.indexOf(this.props.value)
});
}
},
componentWillReceiveProps: function (nextProps) {
if (nextProps.value !== this.state.value) {
this.setState({
value: nextProps.value,
index: nextProps.values.indexOf(nextProps.value)
});
}
},
/**
* Change value on click
*/
click: function () {
var values = this.props.values,
index = this.state.index;
if (index + 1 < values.length) {
index += 1;
} else {
index = 0;
}
this.setState({
value: values[index],
index: index
}, function () {
this.props.onChange(values[index]);
}.bind(this));
},
/**
* Render handle
*/
render: function () {
return React.DOM.button({
className: 'selector',
onClick: this.click
}, this.state.value);
}
});
}());

94
js/init.js Normal file
View File

@ -0,0 +1,94 @@
/*globals React */
/**
* init.js
*
* Initialize app global
*/
(function () {
'use strict';
var App = window.App = {};
// move module methods out of the global namespace to
// prevent libraries like jQuery from creating AMD modules
if (window.module !== undefined) {
window.atom = {
require: window.require,
module: window.module
};
delete window.require;
delete window.module;
}
// components creation
App.components = {
/**
* Add React class to given namespace
*
* @param {namespace: string} Class namespace, skip to assign to global namespace
* @param {options: Object} Class options
* @return {Object} Object containing namespace object and created class
*/
create: function (namespace, options) {
var cclass;
if (typeof namespace === 'object') {
options = namespace;
namespace = App.components;
} else {
if (App.components[namespace] === undefined) {
App.components[namespace] = {};
}
namespace = App.components[namespace];
}
cclass = React.createClass(options);
namespace[options.displayName] = cclass;
return {
namespace: namespace,
cclass: cclass
};
},
/**
* Add Modal class to given namespace
*
* @param {namespace: string} Class namespace, skip to assign to global namespace
* @param {options: Object} Class options
* @return {Object} Object containing namespace object and created modal
*/
modal: function (namespace, options) {
var component, cclass, modal;
if (options === undefined) {
options = namespace;
}
modal = options.modal || {};
delete options.modal;
component = App.components.create(namespace, options);
cclass = function (props) {
return new App.Modal(component.cclass, modal, props);
};
component.namespace[options.displayName] = cclass;
return {
namespace: component.namespace,
cclass: cclass
};
}
};
// other globals
App.lang = navigator.language;
App.MIDI = {
keyOffset: 21
};
}());

24
js/lib/jasmid/LICENSE Normal file
View File

@ -0,0 +1,24 @@
Copyright (c) 2010, Matt Westcott & Ben Firshman
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The names of its contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

308
js/lib/jasmid/jasmid.js Normal file
View File

@ -0,0 +1,308 @@
/* Wrapper for accessing strings through sequential reads */
function Stream(str) {
var position = 0;
function read(length) {
var result = str.substr(position, length);
position += length;
return result;
}
/* read a big-endian 32-bit integer */
function readInt32() {
var result = (
(str.charCodeAt(position) << 24)
+ (str.charCodeAt(position + 1) << 16)
+ (str.charCodeAt(position + 2) << 8)
+ str.charCodeAt(position + 3));
position += 4;
return result;
}
/* read a big-endian 16-bit integer */
function readInt16() {
var result = (
(str.charCodeAt(position) << 8)
+ str.charCodeAt(position + 1));
position += 2;
return result;
}
/* read an 8-bit integer */
function readInt8(signed) {
var result = str.charCodeAt(position);
if (signed && result > 127) result -= 256;
position += 1;
return result;
}
function eof() {
return position >= str.length;
}
/* read a MIDI-style variable-length integer
(big-endian value in groups of 7 bits,
with top bit set to signify that another byte follows)
*/
function readVarInt() {
var result = 0;
while (true) {
var b = readInt8();
if (b & 0x80) {
result += (b & 0x7f);
result <<= 7;
} else {
/* b is the last byte */
return result + b;
}
}
}
return {
'eof': eof,
'read': read,
'readInt32': readInt32,
'readInt16': readInt16,
'readInt8': readInt8,
'readVarInt': readVarInt
}
}
/*
class to parse the .mid file format
(depends on stream.js)
*/
function MidiFile(data) {
function readChunk(stream) {
var id = stream.read(4);
var length = stream.readInt32();
return {
'id': id,
'length': length,
'data': stream.read(length)
};
}
var lastEventTypeByte;
function readEvent(stream) {
var event = {};
event.deltaTime = stream.readVarInt();
var eventTypeByte = stream.readInt8();
if ((eventTypeByte & 0xf0) == 0xf0) {
/* system / meta event */
if (eventTypeByte == 0xff) {
/* meta event */
event.type = 'meta';
var subtypeByte = stream.readInt8();
var length = stream.readVarInt();
switch(subtypeByte) {
case 0x00:
event.subtype = 'sequenceNumber';
if (length != 2) throw "Expected length for sequenceNumber event is 2, got " + length;
event.number = stream.readInt16();
return event;
case 0x01:
event.subtype = 'text';
event.text = stream.read(length);
return event;
case 0x02:
event.subtype = 'copyrightNotice';
event.text = stream.read(length);
return event;
case 0x03:
event.subtype = 'trackName';
event.text = stream.read(length);
return event;
case 0x04:
event.subtype = 'instrumentName';
event.text = stream.read(length);
return event;
case 0x05:
event.subtype = 'lyrics';
event.text = stream.read(length);
return event;
case 0x06:
event.subtype = 'marker';
event.text = stream.read(length);
return event;
case 0x07:
event.subtype = 'cuePoint';
event.text = stream.read(length);
return event;
case 0x20:
event.subtype = 'midiChannelPrefix';
if (length != 1) throw "Expected length for midiChannelPrefix event is 1, got " + length;
event.channel = stream.readInt8();
return event;
case 0x2f:
event.subtype = 'endOfTrack';
if (length != 0) throw "Expected length for endOfTrack event is 0, got " + length;
return event;
case 0x51:
event.subtype = 'setTempo';
if (length != 3) throw "Expected length for setTempo event is 3, got " + length;
event.microsecondsPerBeat = (
(stream.readInt8() << 16)
+ (stream.readInt8() << 8)
+ stream.readInt8()
)
return event;
case 0x54:
event.subtype = 'smpteOffset';
if (length != 5) throw "Expected length for smpteOffset event is 5, got " + length;
var hourByte = stream.readInt8();
event.frameRate = {
0x00: 24, 0x20: 25, 0x40: 29, 0x60: 30
}[hourByte & 0x60];
event.hour = hourByte & 0x1f;
event.min = stream.readInt8();
event.sec = stream.readInt8();
event.frame = stream.readInt8();
event.subframe = stream.readInt8();
return event;
case 0x58:
event.subtype = 'timeSignature';
if (length != 4) throw "Expected length for timeSignature event is 4, got " + length;
event.numerator = stream.readInt8();
event.denominator = Math.pow(2, stream.readInt8());
event.metronome = stream.readInt8();
event.thirtyseconds = stream.readInt8();
return event;
case 0x59:
event.subtype = 'keySignature';
if (length != 2) throw "Expected length for keySignature event is 2, got " + length;
event.key = stream.readInt8(true);
event.scale = stream.readInt8();
return event;
case 0x7f:
event.subtype = 'sequencerSpecific';
event.data = stream.read(length);
return event;
default:
// console.log("Unrecognised meta event subtype: " + subtypeByte);
event.subtype = 'unknown'
event.data = stream.read(length);
return event;
}
event.data = stream.read(length);
return event;
} else if (eventTypeByte == 0xf0) {
event.type = 'sysEx';
var length = stream.readVarInt();
event.data = stream.read(length);
return event;
} else if (eventTypeByte == 0xf7) {
event.type = 'dividedSysEx';
var length = stream.readVarInt();
event.data = stream.read(length);
return event;
} else {
throw "Unrecognised MIDI event type byte: " + eventTypeByte;
}
} else {
/* channel event */
var param1;
if ((eventTypeByte & 0x80) == 0) {
/* running status - reuse lastEventTypeByte as the event type.
eventTypeByte is actually the first parameter
*/
param1 = eventTypeByte;
eventTypeByte = lastEventTypeByte;
} else {
param1 = stream.readInt8();
lastEventTypeByte = eventTypeByte;
}
var eventType = eventTypeByte >> 4;
event.channel = eventTypeByte & 0x0f;
event.type = 'channel';
switch (eventType) {
case 0x08:
event.subtype = 'noteOff';
event.noteNumber = param1;
event.velocity = stream.readInt8();
return event;
case 0x09:
event.noteNumber = param1;
event.velocity = stream.readInt8();
if (event.velocity == 0) {
event.subtype = 'noteOff';
} else {
event.subtype = 'noteOn';
}
return event;
case 0x0a:
event.subtype = 'noteAftertouch';
event.noteNumber = param1;
event.amount = stream.readInt8();
return event;
case 0x0b:
event.subtype = 'controller';
event.controllerType = param1;
event.value = stream.readInt8();
return event;
case 0x0c:
event.subtype = 'programChange';
event.programNumber = param1;
return event;
case 0x0d:
event.subtype = 'channelAftertouch';
event.amount = param1;
return event;
case 0x0e:
event.subtype = 'pitchBend';
event.value = param1 + (stream.readInt8() << 7);
return event;
default:
throw "Unrecognised MIDI event type: " + eventType
/*
console.log("Unrecognised MIDI event type: " + eventType);
stream.readInt8();
event.subtype = 'unknown';
return event;
*/
}
}
}
stream = Stream(data);
var headerChunk = readChunk(stream);
if (headerChunk.id != 'MThd' || headerChunk.length != 6) {
throw "Bad .mid file - header not found";
}
var headerStream = Stream(headerChunk.data);
var formatType = headerStream.readInt16();
var trackCount = headerStream.readInt16();
var timeDivision = headerStream.readInt16();
if (timeDivision & 0x8000) {
throw "Expressing time division in SMTPE frames is not supported yet"
} else {
ticksPerBeat = timeDivision;
}
var header = {
'formatType': formatType,
'trackCount': trackCount,
'ticksPerBeat': ticksPerBeat
}
var tracks = [];
for (var i = 0; i < header.trackCount; i++) {
tracks[i] = [];
var trackChunk = readChunk(stream);
if (trackChunk.id != 'MTrk') {
throw "Unexpected chunk - expected MTrk, got "+ trackChunk.id;
}
var trackStream = Stream(trackChunk.data);
while (!trackStream.eof()) {
var event = readEvent(trackStream);
tracks[i].push(event);
//console.log(event);
}
}
return {
'header': header,
'tracks': tracks
}
}

1
js/lib/jasmid/jasmid.min.js vendored Normal file
View File

@ -0,0 +1 @@
function Stream(e){function n(n){var r=e.substr(t,n);t+=n;return r}function r(){var n=(e.charCodeAt(t)<<24)+(e.charCodeAt(t+1)<<16)+(e.charCodeAt(t+2)<<8)+e.charCodeAt(t+3);t+=4;return n}function i(){var n=(e.charCodeAt(t)<<8)+e.charCodeAt(t+1);t+=2;return n}function s(n){var r=e.charCodeAt(t);if(n&&r>127)r-=256;t+=1;return r}function o(){return t>=e.length}function u(){var e=0;while(true){var t=s();if(t&128){e+=t&127;e<<=7}else{return e+t}}}var t=0;return{eof:o,read:n,readInt32:r,readInt16:i,readInt8:s,readVarInt:u}}function MidiFile(e){function t(e){var t=e.read(4);var n=e.readInt32();return{id:t,length:n,data:e.read(n)}}function r(e){var t={};t.deltaTime=e.readVarInt();var r=e.readInt8();if((r&240)==240){if(r==255){t.type="meta";var i=e.readInt8();var s=e.readVarInt();switch(i){case 0:t.subtype="sequenceNumber";if(s!=2)throw"Expected length for sequenceNumber event is 2, got "+s;t.number=e.readInt16();return t;case 1:t.subtype="text";t.text=e.read(s);return t;case 2:t.subtype="copyrightNotice";t.text=e.read(s);return t;case 3:t.subtype="trackName";t.text=e.read(s);return t;case 4:t.subtype="instrumentName";t.text=e.read(s);return t;case 5:t.subtype="lyrics";t.text=e.read(s);return t;case 6:t.subtype="marker";t.text=e.read(s);return t;case 7:t.subtype="cuePoint";t.text=e.read(s);return t;case 32:t.subtype="midiChannelPrefix";if(s!=1)throw"Expected length for midiChannelPrefix event is 1, got "+s;t.channel=e.readInt8();return t;case 47:t.subtype="endOfTrack";if(s!=0)throw"Expected length for endOfTrack event is 0, got "+s;return t;case 81:t.subtype="setTempo";if(s!=3)throw"Expected length for setTempo event is 3, got "+s;t.microsecondsPerBeat=(e.readInt8()<<16)+(e.readInt8()<<8)+e.readInt8();return t;case 84:t.subtype="smpteOffset";if(s!=5)throw"Expected length for smpteOffset event is 5, got "+s;var o=e.readInt8();t.frameRate={0:24,32:25,64:29,96:30}[o&96];t.hour=o&31;t.min=e.readInt8();t.sec=e.readInt8();t.frame=e.readInt8();t.subframe=e.readInt8();return t;case 88:t.subtype="timeSignature";if(s!=4)throw"Expected length for timeSignature event is 4, got "+s;t.numerator=e.readInt8();t.denominator=Math.pow(2,e.readInt8());t.metronome=e.readInt8();t.thirtyseconds=e.readInt8();return t;case 89:t.subtype="keySignature";if(s!=2)throw"Expected length for keySignature event is 2, got "+s;t.key=e.readInt8(true);t.scale=e.readInt8();return t;case 127:t.subtype="sequencerSpecific";t.data=e.read(s);return t;default:t.subtype="unknown";t.data=e.read(s);return t}t.data=e.read(s);return t}else if(r==240){t.type="sysEx";var s=e.readVarInt();t.data=e.read(s);return t}else if(r==247){t.type="dividedSysEx";var s=e.readVarInt();t.data=e.read(s);return t}else{throw"Unrecognised MIDI event type byte: "+r}}else{var u;if((r&128)==0){u=r;r=n}else{u=e.readInt8();n=r}var a=r>>4;t.channel=r&15;t.type="channel";switch(a){case 8:t.subtype="noteOff";t.noteNumber=u;t.velocity=e.readInt8();return t;case 9:t.noteNumber=u;t.velocity=e.readInt8();if(t.velocity==0){t.subtype="noteOff"}else{t.subtype="noteOn"}return t;case 10:t.subtype="noteAftertouch";t.noteNumber=u;t.amount=e.readInt8();return t;case 11:t.subtype="controller";t.controllerType=u;t.value=e.readInt8();return t;case 12:t.subtype="programChange";t.programNumber=u;return t;case 13:t.subtype="channelAftertouch";t.amount=u;return t;case 14:t.subtype="pitchBend";t.value=u+(e.readInt8()<<7);return t;default:throw"Unrecognised MIDI event type: "+a}}}var n;stream=Stream(e);var i=t(stream);if(i.id!="MThd"||i.length!=6){throw"Bad .mid file - header not found"}var s=Stream(i.data);var o=s.readInt16();var u=s.readInt16();var a=s.readInt16();if(a&32768){throw"Expressing time division in SMTPE frames is not supported yet"}else{ticksPerBeat=a}var f={formatType:o,trackCount:u,ticksPerBeat:ticksPerBeat};var l=[];for(var c=0;c<f.trackCount;c++){l[c]=[];var h=t(stream);if(h.id!="MTrk"){throw"Unexpected chunk - expected MTrk, got "+h.id}var p=Stream(h.data);while(!p.eof()){var d=r(p);l[c].push(d)}}return{header:f,tracks:l}}

10308
js/lib/jquery/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

4
js/lib/jquery/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

20276
js/lib/react/react-with-addons.js vendored Normal file

File diff suppressed because it is too large Load Diff

22
js/lib/react/react-with-addons.min.js vendored Normal file

File diff suppressed because one or more lines are too long

18484
js/lib/react/react.js vendored Normal file

File diff suppressed because it is too large Load Diff

21
js/lib/react/react.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.8/require.min.js
"></script>
<link rel="stylesheet" href="../css/vex.css" />
<link rel="stylesheet" href="../css/vex-theme-os.css" />
<script>
require({
paths: {
jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min'
}
});
</script>
<script>
require(['vex', 'vex.dialog'], function(vex, vexDialog) {
vex.defaultOptions.className = 'vex-theme-os';
vexDialog.alert('Test');
});
</script>
</head>
<body>

View File

@ -0,0 +1,11 @@
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="vex.combined.min.js"></script>
<link rel="stylesheet" href="../css/vex.css" />
<link rel="stylesheet" href="../css/vex-theme-os.css" />
</head>
<body>
<script>
vex.defaultOptions.className = 'vex-theme-os';
vex.dialog.alert('Test');
</script>

2
js/lib/vex/vex.combined.min.js vendored Normal file

File diff suppressed because one or more lines are too long

151
js/lib/vex/vex.dialog.js Normal file
View File

@ -0,0 +1,151 @@
(function() {
var vexDialogFactory;
vexDialogFactory = function($, vex) {
var $formToObject, dialog;
if (vex == null) {
return $.error('Vex is required to use vex.dialog');
}
$formToObject = function($form) {
var object;
object = {};
$.each($form.serializeArray(), function() {
if (object[this.name]) {
if (!object[this.name].push) {
object[this.name] = [object[this.name]];
}
return object[this.name].push(this.value || '');
} else {
return object[this.name] = this.value || '';
}
});
return object;
};
dialog = {};
dialog.buttons = {
YES: {
text: 'OK',
type: 'submit',
className: 'vex-dialog-button-primary'
},
NO: {
text: 'Cancel',
type: 'button',
className: 'vex-dialog-button-secondary',
click: function($vexContent, event) {
$vexContent.data().vex.value = false;
return vex.close($vexContent.data().vex.id);
}
}
};
dialog.defaultOptions = {
callback: function(value) {},
afterOpen: function() {},
message: 'Message',
input: "<input name=\"vex\" type=\"hidden\" value=\"_vex-empty-value\" />",
value: false,
buttons: [dialog.buttons.YES, dialog.buttons.NO],
showCloseButton: false,
onSubmit: function(event) {
var $form, $vexContent;
$form = $(this);
$vexContent = $form.parent();
event.preventDefault();
event.stopPropagation();
$vexContent.data().vex.value = dialog.getFormValueOnSubmit($formToObject($form));
return vex.close($vexContent.data().vex.id);
},
focusFirstInput: true
};
dialog.defaultAlertOptions = {
message: 'Alert',
buttons: [dialog.buttons.YES]
};
dialog.defaultConfirmOptions = {
message: 'Confirm'
};
dialog.open = function(options) {
var $vexContent;
options = $.extend({}, vex.defaultOptions, dialog.defaultOptions, options);
options.content = dialog.buildDialogForm(options);
options.beforeClose = function($vexContent) {
return options.callback($vexContent.data().vex.value);
};
$vexContent = vex.open(options);
if (options.focusFirstInput) {
$vexContent.find('input[type="submit"], textarea, input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"]').first().focus();
}
return $vexContent;
};
dialog.alert = function(options) {
if (typeof options === 'string') {
options = {
message: options
};
}
options = $.extend({}, dialog.defaultAlertOptions, options);
return dialog.open(options);
};
dialog.confirm = function(options) {
if (typeof options === 'string') {
return $.error('dialog.confirm(options) requires options.callback.');
}
options = $.extend({}, dialog.defaultConfirmOptions, options);
return dialog.open(options);
};
dialog.prompt = function(options) {
var defaultPromptOptions;
if (typeof options === 'string') {
return $.error('dialog.prompt(options) requires options.callback.');
}
defaultPromptOptions = {
message: "<label for=\"vex\">" + (options.label || 'Prompt:') + "</label>",
input: "<input name=\"vex\" type=\"text\" class=\"vex-dialog-prompt-input\" placeholder=\"" + (options.placeholder || '') + "\" value=\"" + (options.value || '') + "\" />"
};
options = $.extend({}, defaultPromptOptions, options);
return dialog.open(options);
};
dialog.buildDialogForm = function(options) {
var $form, $input, $message;
$form = $('<form class="vex-dialog-form" />');
$message = $('<div class="vex-dialog-message" />');
$input = $('<div class="vex-dialog-input" />');
$form.append($message.append(options.message)).append($input.append(options.input)).append(dialog.buttonsToDOM(options.buttons)).bind('submit.vex', options.onSubmit);
return $form;
};
dialog.getFormValueOnSubmit = function(formData) {
if (formData.vex || formData.vex === '') {
if (formData.vex === '_vex-empty-value') {
return true;
}
return formData.vex;
} else {
return formData;
}
};
dialog.buttonsToDOM = function(buttons) {
var $buttons;
$buttons = $('<div class="vex-dialog-buttons" />');
$.each(buttons, function(index, button) {
var $button;
$button = $("<input type=\"" + button.type + "\" />").val(button.text).addClass(button.className + ' vex-dialog-button ' + (index === 0 ? 'vex-first ' : '') + (index === buttons.length - 1 ? 'vex-last ' : '')).bind('click.vex', function(e) {
if (button.click) {
return button.click($(this).parents("." + vex.baseClassNames.content), e);
}
});
return $button.appendTo($buttons);
});
return $buttons;
};
return dialog;
};
if (typeof define === 'function' && define.amd) {
define(['jquery', 'vex'], vexDialogFactory);
} else if (typeof exports === 'object') {
module.exports = vexDialogFactory(require('jquery'), require('vex'));
} else {
window.vex.dialog = vexDialogFactory(window.jQuery, window.vex);
}
}).call(this);

2
js/lib/vex/vex.dialog.min.js vendored Normal file
View File

@ -0,0 +1,2 @@
/*! vex.dialog.js 2.2.1 */
(function(){var a;a=function(a,b){var c,d;return null==b?a.error("Vex is required to use vex.dialog"):(c=function(b){var c;return c={},a.each(b.serializeArray(),function(){return c[this.name]?(c[this.name].push||(c[this.name]=[c[this.name]]),c[this.name].push(this.value||"")):c[this.name]=this.value||""}),c},d={},d.buttons={YES:{text:"OK",type:"submit",className:"vex-dialog-button-primary"},NO:{text:"Cancel",type:"button",className:"vex-dialog-button-secondary",click:function(a){return a.data().vex.value=!1,b.close(a.data().vex.id)}}},d.defaultOptions={callback:function(){},afterOpen:function(){},message:"Message",input:'<input name="vex" type="hidden" value="_vex-empty-value" />',value:!1,buttons:[d.buttons.YES,d.buttons.NO],showCloseButton:!1,onSubmit:function(e){var f,g;return f=a(this),g=f.parent(),e.preventDefault(),e.stopPropagation(),g.data().vex.value=d.getFormValueOnSubmit(c(f)),b.close(g.data().vex.id)},focusFirstInput:!0},d.defaultAlertOptions={message:"Alert",buttons:[d.buttons.YES]},d.defaultConfirmOptions={message:"Confirm"},d.open=function(c){var e;return c=a.extend({},b.defaultOptions,d.defaultOptions,c),c.content=d.buildDialogForm(c),c.beforeClose=function(a){return c.callback(a.data().vex.value)},e=b.open(c),c.focusFirstInput&&e.find('input[type="submit"], textarea, input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"]').first().focus(),e},d.alert=function(b){return"string"==typeof b&&(b={message:b}),b=a.extend({},d.defaultAlertOptions,b),d.open(b)},d.confirm=function(b){return"string"==typeof b?a.error("dialog.confirm(options) requires options.callback."):(b=a.extend({},d.defaultConfirmOptions,b),d.open(b))},d.prompt=function(b){var c;return"string"==typeof b?a.error("dialog.prompt(options) requires options.callback."):(c={message:'<label for="vex">'+(b.label||"Prompt:")+"</label>",input:'<input name="vex" type="text" class="vex-dialog-prompt-input" placeholder="'+(b.placeholder||"")+'" value="'+(b.value||"")+'" />'},b=a.extend({},c,b),d.open(b))},d.buildDialogForm=function(b){var c,e,f;return c=a('<form class="vex-dialog-form" />'),f=a('<div class="vex-dialog-message" />'),e=a('<div class="vex-dialog-input" />'),c.append(f.append(b.message)).append(e.append(b.input)).append(d.buttonsToDOM(b.buttons)).bind("submit.vex",b.onSubmit),c},d.getFormValueOnSubmit=function(a){return a.vex||""===a.vex?"_vex-empty-value"===a.vex?!0:a.vex:a},d.buttonsToDOM=function(c){var d;return d=a('<div class="vex-dialog-buttons" />'),a.each(c,function(e,f){var g;return g=a('<input type="'+f.type+'" />').val(f.text).addClass(f.className+" vex-dialog-button "+(0===e?"vex-first ":"")+(e===c.length-1?"vex-last ":"")).bind("click.vex",function(c){return f.click?f.click(a(this).parents("."+b.baseClassNames.content),c):void 0}),g.appendTo(d)}),d},d)},"function"==typeof define&&define.amd?define(["jquery","vex"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("vex")):window.vex.dialog=a(window.jQuery,window.vex)}).call(this);

190
js/lib/vex/vex.js Normal file
View File

@ -0,0 +1,190 @@
(function() {
var vexFactory;
vexFactory = function($) {
var animationEndSupport, vex;
animationEndSupport = false;
$(function() {
var s;
s = (document.body || document.documentElement).style;
animationEndSupport = s.animation !== void 0 || s.WebkitAnimation !== void 0 || s.MozAnimation !== void 0 || s.MsAnimation !== void 0 || s.OAnimation !== void 0;
return $(window).bind('keyup.vex', function(event) {
if (event.keyCode === 27) {
return vex.closeByEscape();
}
});
});
return vex = {
globalID: 1,
animationEndEvent: 'animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend',
baseClassNames: {
vex: 'vex',
content: 'vex-content',
overlay: 'vex-overlay',
close: 'vex-close',
closing: 'vex-closing',
open: 'vex-open'
},
defaultOptions: {
content: '',
showCloseButton: true,
escapeButtonCloses: true,
overlayClosesOnClick: true,
appendLocation: 'body',
className: '',
css: {},
overlayClassName: '',
overlayCSS: {},
contentClassName: '',
contentCSS: {},
closeClassName: '',
closeCSS: {}
},
open: function(options) {
options = $.extend({}, vex.defaultOptions, options);
options.id = vex.globalID;
vex.globalID += 1;
options.$vex = $('<div>').addClass(vex.baseClassNames.vex).addClass(options.className).css(options.css).data({
vex: options
});
options.$vexOverlay = $('<div>').addClass(vex.baseClassNames.overlay).addClass(options.overlayClassName).css(options.overlayCSS).data({
vex: options
});
if (options.overlayClosesOnClick) {
options.$vexOverlay.bind('click.vex', function(e) {
if (e.target !== this) {
return;
}
return vex.close($(this).data().vex.id);
});
}
options.$vex.append(options.$vexOverlay);
options.$vexContent = $('<div>').addClass(vex.baseClassNames.content).addClass(options.contentClassName).css(options.contentCSS).append(options.content).data({
vex: options
});
options.$vex.append(options.$vexContent);
if (options.showCloseButton) {
options.$closeButton = $('<div>').addClass(vex.baseClassNames.close).addClass(options.closeClassName).css(options.closeCSS).data({
vex: options
}).bind('click.vex', function() {
return vex.close($(this).data().vex.id);
});
options.$vexContent.append(options.$closeButton);
}
$(options.appendLocation).append(options.$vex);
vex.setupBodyClassName(options.$vex);
if (options.afterOpen) {
options.afterOpen(options.$vexContent, options);
}
setTimeout((function() {
return options.$vexContent.trigger('vexOpen', options);
}), 0);
return options.$vexContent;
},
getAllVexes: function() {
return $("." + vex.baseClassNames.vex + ":not(\"." + vex.baseClassNames.closing + "\") ." + vex.baseClassNames.content);
},
getVexByID: function(id) {
return vex.getAllVexes().filter(function() {
return $(this).data().vex.id === id;
});
},
close: function(id) {
var $lastVex;
if (!id) {
$lastVex = vex.getAllVexes().last();
if (!$lastVex.length) {
return false;
}
id = $lastVex.data().vex.id;
}
return vex.closeByID(id);
},
closeAll: function() {
var ids;
ids = vex.getAllVexes().map(function() {
return $(this).data().vex.id;
}).toArray();
if (!(ids != null ? ids.length : void 0)) {
return false;
}
$.each(ids.reverse(), function(index, id) {
return vex.closeByID(id);
});
return true;
},
closeByID: function(id) {
var $vex, $vexContent, beforeClose, close, options;
$vexContent = vex.getVexByID(id);
if (!$vexContent.length) {
return;
}
$vex = $vexContent.data().vex.$vex;
options = $.extend({}, $vexContent.data().vex);
beforeClose = function() {
if (options.beforeClose) {
return options.beforeClose($vexContent, options);
}
};
close = function() {
$vexContent.trigger('vexClose', options);
$vex.remove();
$('body').trigger('vexAfterClose', options);
if (options.afterClose) {
return options.afterClose($vexContent, options);
}
};
if (animationEndSupport) {
beforeClose();
$vex.unbind(vex.animationEndEvent).bind(vex.animationEndEvent, function() {
return close();
}).addClass(vex.baseClassNames.closing);
} else {
beforeClose();
close();
}
return true;
},
closeByEscape: function() {
var $lastVex, id, ids;
ids = vex.getAllVexes().map(function() {
return $(this).data().vex.id;
}).toArray();
if (!(ids != null ? ids.length : void 0)) {
return false;
}
id = Math.max.apply(Math, ids);
$lastVex = vex.getVexByID(id);
if ($lastVex.data().vex.escapeButtonCloses !== true) {
return false;
}
return vex.closeByID(id);
},
setupBodyClassName: function($vex) {
return $('body').bind('vexOpen.vex', function() {
return $('body').addClass(vex.baseClassNames.open);
}).bind('vexAfterClose.vex', function() {
if (!vex.getAllVexes().length) {
return $('body').removeClass(vex.baseClassNames.open);
}
});
},
hideLoading: function() {
return $('.vex-loading-spinner').remove();
},
showLoading: function() {
vex.hideLoading();
return $('body').append("<div class=\"vex-loading-spinner " + vex.defaultOptions.className + "\"></div>");
}
};
};
if (typeof define === 'function' && define.amd) {
define(['jquery'], vexFactory);
} else if (typeof exports === 'object') {
module.exports = vexFactory(require('jquery'));
} else {
window.vex = vexFactory(jQuery);
}
}).call(this);

2
js/lib/vex/vex.min.js vendored Normal file
View File

@ -0,0 +1,2 @@
/*! vex.js 2.2.1 */
(function(){var a;a=function(a){var b,c;return b=!1,a(function(){var d;return d=(document.body||document.documentElement).style,b=void 0!==d.animation||void 0!==d.WebkitAnimation||void 0!==d.MozAnimation||void 0!==d.MsAnimation||void 0!==d.OAnimation,a(window).bind("keyup.vex",function(a){return 27===a.keyCode?c.closeByEscape():void 0})}),c={globalID:1,animationEndEvent:"animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend",baseClassNames:{vex:"vex",content:"vex-content",overlay:"vex-overlay",close:"vex-close",closing:"vex-closing",open:"vex-open"},defaultOptions:{content:"",showCloseButton:!0,escapeButtonCloses:!0,overlayClosesOnClick:!0,appendLocation:"body",className:"",css:{},overlayClassName:"",overlayCSS:{},contentClassName:"",contentCSS:{},closeClassName:"",closeCSS:{}},open:function(b){return b=a.extend({},c.defaultOptions,b),b.id=c.globalID,c.globalID+=1,b.$vex=a("<div>").addClass(c.baseClassNames.vex).addClass(b.className).css(b.css).data({vex:b}),b.$vexOverlay=a("<div>").addClass(c.baseClassNames.overlay).addClass(b.overlayClassName).css(b.overlayCSS).data({vex:b}),b.overlayClosesOnClick&&b.$vexOverlay.bind("click.vex",function(b){return b.target===this?c.close(a(this).data().vex.id):void 0}),b.$vex.append(b.$vexOverlay),b.$vexContent=a("<div>").addClass(c.baseClassNames.content).addClass(b.contentClassName).css(b.contentCSS).append(b.content).data({vex:b}),b.$vex.append(b.$vexContent),b.showCloseButton&&(b.$closeButton=a("<div>").addClass(c.baseClassNames.close).addClass(b.closeClassName).css(b.closeCSS).data({vex:b}).bind("click.vex",function(){return c.close(a(this).data().vex.id)}),b.$vexContent.append(b.$closeButton)),a(b.appendLocation).append(b.$vex),c.setupBodyClassName(b.$vex),b.afterOpen&&b.afterOpen(b.$vexContent,b),setTimeout(function(){return b.$vexContent.trigger("vexOpen",b)},0),b.$vexContent},getAllVexes:function(){return a("."+c.baseClassNames.vex+':not(".'+c.baseClassNames.closing+'") .'+c.baseClassNames.content)},getVexByID:function(b){return c.getAllVexes().filter(function(){return a(this).data().vex.id===b})},close:function(a){var b;if(!a){if(b=c.getAllVexes().last(),!b.length)return!1;a=b.data().vex.id}return c.closeByID(a)},closeAll:function(){var b;return b=c.getAllVexes().map(function(){return a(this).data().vex.id}).toArray(),(null!=b?b.length:void 0)?(a.each(b.reverse(),function(a,b){return c.closeByID(b)}),!0):!1},closeByID:function(d){var e,f,g,h,i;return f=c.getVexByID(d),f.length?(e=f.data().vex.$vex,i=a.extend({},f.data().vex),g=function(){return i.beforeClose?i.beforeClose(f,i):void 0},h=function(){return f.trigger("vexClose",i),e.remove(),a("body").trigger("vexAfterClose",i),i.afterClose?i.afterClose(f,i):void 0},b?(g(),e.unbind(c.animationEndEvent).bind(c.animationEndEvent,function(){return h()}).addClass(c.baseClassNames.closing)):(g(),h()),!0):void 0},closeByEscape:function(){var b,d,e;return e=c.getAllVexes().map(function(){return a(this).data().vex.id}).toArray(),(null!=e?e.length:void 0)?(d=Math.max.apply(Math,e),b=c.getVexByID(d),b.data().vex.escapeButtonCloses!==!0?!1:c.closeByID(d)):!1},setupBodyClassName:function(){return a("body").bind("vexOpen.vex",function(){return a("body").addClass(c.baseClassNames.open)}).bind("vexAfterClose.vex",function(){return c.getAllVexes().length?void 0:a("body").removeClass(c.baseClassNames.open)})},hideLoading:function(){return a(".vex-loading-spinner").remove()},showLoading:function(){return c.hideLoading(),a("body").append('<div class="vex-loading-spinner '+c.defaultOptions.className+'"></div>')}}},"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):window.vex=a(jQuery)}).call(this);

349
js/midi/file.js Normal file
View File

@ -0,0 +1,349 @@
/*jshint es5: true, bitwise: true */
/*globals DOMLoader, MidiFile, App */
/**
* file.js
*
* Read MIDI files
*/
(function () {
'use strict';
/**
* Note
*
* Represent a note object
*/
function Note(options) {
options = options || {};
this.note = options.note || 0;
this.channel = options.channel || 0;
this.start = options.start || 0;
this.length = options.length || 1;
}
/**
* Channel
*
* Represent a channel object
*/
function Channel(options) {
options = options || {};
this.id = options.id || 0;
this.meta = options.meta || {};
this.program = options.program || 0;
this.muted = options.muted || false;
this.solo = options.solo || false;
this.pending = options.pending || {};
}
/**
* Convert stained data
*
* @param {data: string}
* @return string
*/
function convertStained(data) {
var converted, length, i;
converted = [];
length = data.length;
for (i = 0; i < length; i += 1) {
converted[i] = String.fromCharCode(
data.charCodeAt(i) & 255
);
}
return converted.join("");
}
/**
* Push note on pending notes stack
*
* @param {meta: Object} Meta object for this song
* @param {event: Object} Event describing noteOn
* @param {time: int} Starting time
*/
function pushNote(meta, event, time) {
var channel = event.channel,
note = event.noteNumber,
data = {
start: time,
channel: channel,
note: note
};
meta.channels[channel].pending[note] = data;
}
/**
* Pop note from given stack and add it to notes list
*
* @param {meta: Object} Meta object for this song
* @param {event: Object} Event describing noteOff
* @param {time: int} Ending time
*/
function popNote(meta, event, time) {
var channel = event.channel,
note = event.noteNumber,
data;
data = meta.channels[channel].pending[note];
if (data === undefined) {
return;
}
data.length = time - data.start;
meta.length = Math.max(
meta.length,
time
);
meta.notes.push(data);
delete meta.channels[channel].pending[note];
}
/**
* Load file
*
* @param {url: string} Path to file
* @return Promise
*/
function loadFile(url) {
return new window.Promise(function (resolve, reject) {
var fetch = new XMLHttpRequest();
fetch.open('GET', url);
fetch.overrideMimeType('text/plain; charset=x-user-defined');
fetch.onreadystatechange = function () {
if (this.readyState === this.DONE) {
// wait for next tick before resolving, since
// not found errors are triggered after readyState
// change event
window.setImmediate(function () {
resolve(fetch.responseText);
});
}
};
fetch.onerror = function () {
reject(new Error(
'Le fichier demandé est introuvable.'
));
};
fetch.send();
});
}
/**
* Import given MIDI file and translate
* MIDI data object
*
* @param {url: string} Path to MIDI file
* @return Promise
*/
function parseData(data) {
return new window.Promise(function (resolve, reject) {
var tracks, events, tracksLength, eventsLength, length,
event, helpLink, i, j,
// parsing data
timeline = [], meta = {},
channelPrefix = null, metaObject,
// timing
time, bpm = 120, tpb,
firstNote = +Infinity, offset;
// check MIDI structure and load events
data = convertStained(data);
try {
data = new MidiFile(data);
} catch (err) {
helpLink = 'http://fr.wikipedia.org/wiki/Fichier_midi';
if (err === 'Bad .mid file - header not found') {
reject(new Error(
'Le fichier n\'est pas un fichier MIDI ' +
'valide. Ce logiciel ne prend en charge ' +
'que les fichiers de type ' +
'<a href="' + helpLink + '">MIDI</a>.'
));
} else {
reject(new Error(
'Le fichier MIDI n\'est pas correctement ' +
'formé. Il contient une erreur qui ' +
'empêche le logiciel de le lire ' +
'correctement. Veuillez rapporter ' +
'ce problème aux auteurs du fichier.'
));
}
}
tracks = data.tracks;
tracksLength = tracks.length;
tpb = data.header.ticksPerBeat;
// prepare meta object
meta = {
names: [],
instruments: [],
channels: [],
notes: [],
markers: [],
copyright: '',
lyrics: '',
length: 0
};
// init channels
length = 16;
for (i = 0; i < length; i += 1) {
meta.channels[i] = new Channel({
id: i
});
}
// parse all events
for (i = 0; i < tracksLength; i += 1) {
time = 0;
events = tracks[i];
eventsLength = events.length;
for (j = 0; j < eventsLength; j += 1) {
event = events[j];
// time of each event is relative from last track event
if (event.deltaTime) {
time += event.deltaTime / tpb / (bpm / 60);
}
if (event.type === 'meta') {
if (event.subtype === 'midiChannelPrefix') {
channelPrefix = event.channel;
} else {
if (channelPrefix !== null) {
metaObject =
meta.channels[channelPrefix];
} else {
metaObject = meta;
}
}
switch (event.subtype) {
case 'trackName':
metaObject.names[i] = event.text;
break;
case 'copyrightNotice':
metaObject.copyright = event.text;
break;
case 'lyrics':
metaObject.lyrics = event.text;
break;
case 'instrumentName':
metaObject.instruments[i] = event.text;
break;
case 'marker':
metaObject.markers.push({
time: time,
text: event.text
});
break;
case 'setTempo':
bpm = 60000000 / event.microsecondsPerBeat;
break;
}
} else if (event.type === 'channel') {
channelPrefix = null;
switch (event.subtype) {
case 'noteOn':
firstNote = Math.min(firstNote, time);
pushNote(meta, event, time);
timeline.push({
type: 'noteOn',
time: time,
note: event.noteNumber,
channel: event.channel,
velocity: event.velocity
});
break;
case 'noteOff':
popNote(meta, event, time);
timeline.push({
type: 'noteOff',
time: time,
note: event.noteNumber,
channel: event.channel
});
break;
case 'noteAftertouch':
timeline.push({
type: 'noteAftertouch',
time: time,
note: event.noteNumber,
channel: event.channel,
amount: event.amount
});
break;
case 'controller':
timeline.push({
type: 'controller',
time: time,
subtype: event.controllerType,
value: event.value,
channel: event.channel
});
break;
case 'programChange':
meta.channels[event.channel].program =
event.programNumber;
break;
}
}
}
}
// normalize starting time: always have 1s delay
if (firstNote < +Infinity) {
offset = 1 - firstNote;
}
meta.length += offset;
length = timeline.length;
for (i = 0; i < length; i += 1) {
event = timeline[i];
if (event.time + offset < 0) {
event.time = 0;
} else {
event.time += offset;
}
}
length = meta.notes.length;
for (i = 0; i < length; i += 1) {
meta.notes[i].start += offset;
}
resolve({
meta: meta,
timeline: timeline
});
});
}
App.MIDI.file = {
load: loadFile,
parse: parseData
};
}());

167
js/midi/io.js Normal file
View File

@ -0,0 +1,167 @@
/*jshint es5: true, bitwise: true */
/*globals App */
/**
* io.js
*
* Handle communication with MIDI inputs and outputs
* Request navigator access to MIDI devices
*/
(function () {
'use strict';
/**
* Wrap around low-level MIDI output
*
* @param {native: MIDIOutput} Native MIDIOutput to wrap around
*/
function Output(native) {
this.native = native || {
send: function () {}
};
}
/**
* List of MIDI channel events
*/
Output.messages = {
noteOff: 0x80,
noteOn: 0x90,
noteAftertouch: 0xA0,
controller: 0xB0,
programChange: 0xC0,
channelAftertouch: 0xD0,
pitchBend: 0xE0
};
/**
* List of controller types
* (not complete)
*/
Output.controllers = {
modulationWheel: 1,
volume: 7,
pan: 10,
expression: 11,
sustainPedal: 64
};
Output.prototype.programChange = function (channel, program, delay) {
this.native.send([
Output.messages.programChange + channel,
program
], (delay || 0) * 1000);
};
Output.prototype.noteOn = function (channel, note, velocity, delay) {
this.native.send([
Output.messages.noteOn + channel,
note,
velocity
], (delay || 0) * 1000);
};
Output.prototype.noteOff = function (channel, note, delay) {
this.native.send([
Output.messages.noteOff + channel,
note,
0
], (delay || 0) * 1000);
};
Output.prototype.noteAftertouch = function (channel, note, amount, delay) {
this.native.send([
Output.messages.noteAftertouch + channel,
note,
amount
], (delay || 0) * 1000);
};
Output.prototype.controller = function (channel, type, value, delay) {
this.native.send([
Output.messages.controller + channel,
type,
value
], (delay || 0) * 1000);
};
Output.prototype.programChange = function (channel, program, delay) {
this.native.send([
Output.messages.programChange + channel,
program
], (delay || 0) * 1000);
};
Output.prototype.channelAftertouch = function (channel, amount, delay) {
this.native.send([
Output.messages.channelAftertouch + channel,
amount
], (delay || 0) * 1000);
};
Output.prototype.pitchBend = function (channel, value, delay) {
var lsb, msb;
value += 8192;
lsb = value & 127;
msb = value >> 7;
this.native.send([
Output.messages.pitchBend + channel,
lsb,
msb
], (delay || 0) * 1000);
};
/**
* Request MIDI access, select first available output
*
* @return Promise
*/
function connect() {
var promise;
promise = new window.Promise(function (resolve, reject) {
var ignoreAlert = "Si vous continuez, " +
"<em>aucun son ne sera émis ou reçu,</em> mais vous " +
"pourrez utiliser les autres fonctionnalités " +
"du logiciel.";
// by default, we use a no-op output
App.MIDI.output = new Output();
navigator.requestMIDIAccess().then(function (access) {
var outputs = access.outputs(),
output;
if (outputs && outputs.length) {
output = new Output(outputs[0]);
App.MIDI.output = output;
resolve(output);
} else {
reject(new Error(
"Aucun synthétiseur MIDI n'est disponible. Sur " +
"systèmes d'exploitation, un synthétiseur " +
"est disponible par défaut. S'il ce n'est pas " +
"votre cas, il faudra utiliser un logiciel " +
"tiers pour synthétiser les sons.<br /><br />" +
ignoreAlert
));
}
}).catch(function () {
reject(new Error(
"Impossible d'obtenir un accès aux contrôleurs " +
"MIDI, il est possible que votre système ne " +
"supporte pas la norme MIDI ou bien que " +
"vous ayez refusé l'accès à ces périphériques. " +
"<br /><br />" + ignoreAlert
));
});
});
return promise;
}
App.MIDI.connect = connect;
}());

67
js/modal.js Normal file
View File

@ -0,0 +1,67 @@
/*globals React, App, $ */
(function () {
'use strict';
/**
* Wrap a component in a modal
*
* @param {component: ReactClass} Component class
* @param {modal: Object} Vex modal options
* @param {props: Object} Modal props
*/
function Modal(cclass, modal, props) {
var component;
this.handlers = {
open: props.onOpen || function () {},
close: props.onClose || function () {}
};
delete props.onOpen;
delete props.onClose;
component = this.component = cclass(props);
component.props.open = this.open.bind(this);
component.props.close = this.close.bind(this);
this.id = null;
this.opened = false;
this.options = modal;
}
/**
* Open the modal
*/
Modal.prototype.open = function () {
if (this.opened) {
return;
}
var $el = window.vex.open(this.options);
React.renderComponent(this.component, $el[0]);
$el.bind('vexClose', this.close.bind(this));
this.id = $el.data().vex.id;
this.opened = true;
this.handlers.open();
};
/**
* Close the modal
*/
Modal.prototype.close = function (propagate) {
if (!this.opened) {
return;
}
window.vex.close(this.id);
this.id = null;
this.opened = false;
this.handlers.close();
};
App.Modal = Modal;
}());

7
main.js Normal file
View File

@ -0,0 +1,7 @@
/*jshint node:true, nomen:true */
'use strict';
var app = new (require('./App'))();
app.start();

32
package.json Normal file
View File

@ -0,0 +1,32 @@
{
"name": "Piano",
"version": "0.1.6",
"description": "A desktop app for playing with MIDI instruments",
"license": "MIT",
"author": {
"name": "Mattéo D",
"email": "matteo.delabre@outlook.fr",
"url": "https://github.com/matteo78"
},
"contributors": [{
"name": "Rémi C",
"url": "https://github.com/remi34660"
}],
"main": "main.js",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-curl": "~2.0.3",
"grunt-zip": "~0.16.2",
"grunt-contrib-copy": "~0.7.0",
"grunt-contrib-clean": "~0.6.0",
"grunt-contrib-watch": "~0.6.1",
"grunt-rename": "~0.1.4",
"grunt-mkdir": "~0.1.2",
"grunt-http": "~1.4.1",
"async": "~0.9.0",
"rcedit": "~0.2.0"
}
}