initial commit

This commit is contained in:
Henrik Joreteg 2013-06-03 15:51:30 -07:00
commit d906a0494b
101 changed files with 56879 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
.DS_Store

4
.jshintignore Normal file
View File

@ -0,0 +1,4 @@
node_modules
clientapp/libraries
clientapp/modules
public

23
.jshintrc Normal file
View File

@ -0,0 +1,23 @@
{
"asi": false,
"expr": true,
"loopfunc": true,
"curly": false,
"evil": true,
"white": true,
"undef": true,
"browser": true,
"es5": true,
"predef": [
"$",
"me",
"confirm",
"alert",
"require",
"__dirname",
"process",
"exports",
"Buffer",
"module"
]
}

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# otalk webrtc capable xmpp, in the browser

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

99
clientapp/app/app.js Normal file
View File

@ -0,0 +1,99 @@
/*global app*/
var Backbone = require('backbone'),
MeModel = require('models/me'),
MainView = require('views/main'),
Conversatio = require('conversat.io'),
SoundEffectManager = require('sound-effect-manager'),
cookies = require('cookie-getter'),
tracking = require('helpers/tracking'),
Router = require('router');
module.exports = {
launch: function () {
window.app = this;
window.me = new MeModel();
// if we're logged in we'll have a cookie
// called "user" to read
var accessToken = cookies('accessToken');
this.view = new MainView({
model: me,
el: document.body
}).render();
// init our api
this.api = window.api = new Conversatio({
token: accessToken,
url: 'http://localhost:3008',
localVideoEl: 'localVideo',
autoRemoveVideos: false,
log: true
});
this.api.on('user', function (user) {
me.set(user);
tracking.identify(me);
});
// when it's ready set a state flag
this.api.on('readyToCall', function () {
tracking.track('readyToCall');
me.readyToCall = true;
});
// handle cases where password is required
this.api.on('passwordRequired', function () {
me.enterPasswordDialog = true;
});
// handle locking/unlocking
this.api.on('locked', function (key) {
me.roomKey = key;
});
this.api.on('unlocked', function () {
me.roomKey = '';
});
new Router();
app.history = Backbone.history;
// we have what we need, we can now start our router and show the appropriate page
app.history.start({pushState: true, root: '/'});
// play some sounds when people come and go
app.sounds = new SoundEffectManager();
app.sounds.loadFile('/online.mp3', 'online');
app.sounds.loadFile('/offline.mp3', 'offline');
tracking.track('webAppLoaded');
},
navigate: function (page) {
var url = (page.charAt(0) === '/') ? page.slice(1) : page;
app.history.navigate(url, true);
},
renderPage: function (view, animation) {
var container = $('#pages');
if (app.currentPage) {
app.currentPage.hide(animation);
}
// we call render, but if animation is none, we want to tell the view
// to start with the active class already before appending to DOM.
container.append(view.render(animation === 'none').el);
view.show(animation);
},
saveRoomDescriptions: function (details) {
me.roomKey = details.key;
me.roomIsReserved = details.reserved;
},
join: function (name) {
app.api.joinRoom(name, function (err, roomInfo) {
if (!err) app.saveRoomDescriptions(roomInfo);
});
},
login: function () {
window.location = '/auth?next=' + window.location.href;
return false;
}
};

View File

@ -0,0 +1,8 @@
// get a property that's a function or direct property
module.exports = function (obj, propName) {
if (obj[propName] instanceof Function) {
return obj[propName]();
} else {
return obj[propName] || '';
}
};

View File

@ -0,0 +1,14 @@
module.exports = function (me) {
window.intercomSettings = {
email: me.email,
created_at: Math.floor(me.created / 1000),
name: me.fullName,
user_id: me.id,
widget: {
activator: '#Intercom',
use_counter: true
},
app_id: "1qnjz20f"
};
$.getScript("https://api.intercom.io/api/js/library.js");
};

View File

@ -0,0 +1,10 @@
// returns an ad message each time its called
module.exports = function () {
var messages = [
'Have more fun, get more done with your team. And Bang is currently in free private beta.',
'And Bang is simple and powerful tasks and chat for teams. Join the free private beta now.',
'Create a culture of shipping, one rocket at a time. And Bang is free while in private beta.',
'An API for what\'s important right now. And Bang is free while in private beta.'
];
return messages[Math.floor(Math.random() * messages.length)];
};

View File

@ -0,0 +1,32 @@
// Module for tracking user events with mix panel analytics.
/*global mixpanel*/
var initIntercom = require('helpers/intercom'),
hostname = window.location.hostname,
isLive = (hostname === 'conversat.io' || hostname === 'beta.conversat.io');
// Identifies the user with the provided unique id.
exports.identify = function (me) {
if (isLive && me && me.authed) {
mixpanel.identify(me.id);
mixpanel.name_tag(me.username);
mixpanel.people.set({
$email: me.email,
$first_name: me.firstName,
$last_name: me.lastName
});
mixpanel.people.increment('web app opened');
// init intercom
initIntercom(me);
}
};
// Logs the given action with the given data.
// action: A string representing the action to be logged.
// dict: A dictionary with additional action information.
exports.track = function (action, dict, cb) {
// allow the dict parameter to be omitted.
if (isLive) {
mixpanel.track(action, dict || {}, cb);
}
};

View File

@ -0,0 +1,47 @@
var StrictModel = require('strictmodel');
module.exports = StrictModel.Model.extend({
props: {
id: 'string',
firstName: 'string',
lastName: 'string',
username: 'string',
email: 'string',
smallPicUrl: '/robot.png'
},
session: {
readyToCall: ['boolean', true, false],
currentRoom: 'string',
muted: ['boolean', true, false],
paused: ['boolean', true, false],
sharingScreen: ['boolean', true, false],
createdRoom: ['boolean', true, false],
gameActive: ['boolean', true, false],
enterPasswordDialog: ['boolean', true, false],
setPasswordDialog: ['boolean', true, false],
roomKey: ['string', true, ''],
roomIsReserved: ['boolean', true, false]
},
url: '/me',
derived: {
name: {
deps: ['firstName', 'lastName'],
fn: function () {
return this.firstName ? (this.firstName + ' ' + this.lastName) : '';
}
},
authed: {
deps: ['firstName'],
fn: function () {
return !!this.firstName;
}
},
roomLocked: {
deps: ['roomKey'],
fn: function () {
return !!this.roomKey;
}
}
}
});

View File

@ -0,0 +1,27 @@
/*global app*/
var BaseView = require('strictview'),
getOrCall = require('helpers/getOrCall');
module.exports = BaseView.extend({
show: function (animation) {
$('body').scrollTop(0);
// set the class so it comes into view
//this.$el.addClass('active');
// store reference to current page
app.currentPage = this;
// set the document title
document.title = getOrCall(this, 'title') + ' • conversat.io';
// trigger an event to the page model in case we want to respond
this.trigger('pageloaded');
return this;
},
hide: function () {
var self = this;
// tell the model we're bailing
this.trigger('pageunloaded');
// unbind all events bound for this view
this.remove();
return this;
}
});

View File

@ -0,0 +1,38 @@
/*global app*/
var BasePage = require('pages/base'),
templates = require('templates'),
tracking = require('helpers/tracking'),
slugger = require('slugger');
module.exports = BasePage.extend({
template: templates.pages.create,
events: {
'submit #createRoom': 'handleFormSubmit'
},
initialize: function (spec) {
this.url = spec.url;
},
render: function () {
this.basicRender();
this.$el.load(this.url);
return this;
},
handleFormSubmit: function () {
var input = this.$('#sessionInput'),
name = slugger(input.val());
app.api.createRoom(name, function (err, description) {
if (err) {
$.showMessage('That room is taken. Please pick another name.');
input.val('').focus();
} else {
me.createdRoom = true;
app.navigate(description.name);
tracking.track('roomCreated', {
name: description.name
});
}
});
return false;
}
});

236
clientapp/app/pages/talk.js Normal file
View File

@ -0,0 +1,236 @@
/*global app, ui*/
var BasePage = require('pages/base'),
templates = require('templates'),
tracking = require('helpers/tracking'),
_ = require('underscore'),
getFluidGridFunction = require('fluidGrid');
module.exports = BasePage.extend({
template: templates.pages.talk,
events: {
'click video': 'handleVideoClick',
'dblclick video': 'handleVideoDoubleClick',
'click #shareScreen': 'handleScreenShareClick',
'click #muteMicrophone': 'handleMuteClick',
'click #pauseVideo': 'handlePauseClick',
'click .lock': 'handleLockClick',
'click .unlock': 'handleUnlockClick'
},
classBindings: {
muted: '#muteMicrophone',
sharingScreen: '#shareScreen',
paused: '#pauseVideo',
gameActive: '#game',
roomLocked: '.lockControls',
roomIsReserved: ''
},
contentBindings: {
currentRoom: '.roomName',
roomKey: '#roomKey'
},
initialize: function () {
var self = this;
this.shuffle = getFluidGridFunction('#remotes >');
app.api.on('readyToCall', _.bind(this.handleReadyToCall, this));
app.api.on('videoAdded', _.bind(this.handleVideoAdded, this));
app.api.on('videoRemoved', _.bind(this.handleVideoRemoved, this));
// recalculate positions on resize
$(window).on('resize', _.bind(this.shuffle, this, ''));
$(window).on('resize', _.debounce(_.bind(this.resetGame, this), 500));
// sneaky easter egg, play game if you hit '&' while talking
$(document).on('keydown', function (e) {
if (e.which === 55) self.startGame(true);
});
// for layout testing on localhost
if (window.location.hostname === 'localhost') this.enableTestMode();
},
render: function () {
$('body').addClass('active');
this.basicRender();
this.start();
return this;
},
handleVideoClick: function (e) {
this.$('video').removeClass('focused');
$(e.target).addClass('focused');
this.shuffle(e.target);
},
handleVideoDoubleClick: function (e) {
e.preventDefault();
var videoEl = $(e.target)[0];
if (videoEl.webkitEnterFullScreen) {
videoEl.webkitEnterFullScreen();
tracking.track('goingFullscreen', {browser: 'webkit'});
} else if (videoEl.mozRequestFullScreen) {
videoEl.mozRequestFullScreen();
tracking.track('goingFullscreen', {browser: 'mozilla'});
}
},
handleScreenShareClick: function () {
if (me.sharingScreen) {
me.sharingScreen = false;
app.api.stopScreenShare();
} else {
me.sharingScreen = true;
app.api.shareScreen();
}
return false;
},
handleMuteClick: function () {
if (me.muted) {
me.muted = false;
app.api.unmute();
tracking.track('unmuting');
} else {
me.muted = true;
app.api.mute();
tracking.track('muting');
}
return false;
},
handlePauseClick: function () {
if (me.paused) {
me.paused = false;
app.api.resume();
tracking.track('resuming');
} else {
me.paused = true;
app.api.pause();
tracking.track('pausing');
}
return false;
},
start: function () {
app.api.startLocalVideo(this.$('#localVideo')[0]);
},
startGame: function (force) {
if (!me.passwordDialog && !this.$('#remotes video').length || force) {
me.gameActive = true;
if (force) {
this.$('#instructions').hide();
} else {
this.$('#instructions').show();
}
$.getScript('/Box2d.min.js', function () {
$.getScript('/out.js');
});
}
},
hideGame: function () {
if (me.gameActive) {
me.gameActive = false;
this.$('canvas').replaceWith(this.$('canvas').clone());
this.$('#instructions').hide();
}
},
resetGame: function () {
this.hideGame();
this.startGame();
},
handleReadyToCall: function () {
// we only want to call join if we didn't just create/join the room
if (!me.createdRoom) {
app.join(me.currentRoom);
}
// wait a sec, then start the game
_.delay(_.bind(this.startGame, this), 1000);
},
handleVideoAdded: function (el, peer) {
this.$('#remotes').append(el);
this.shuffle();
app.sounds.play('online');
this.hideGame();
if (peer) {
tracking.track('videoConnected', {
loggedIn: me.authed,
name: me.currentRoom,
locked: me.roomLocked,
reserved: me.roomIsReserved,
type: peer.type,
peerId: peer.id
});
}
el.videoStartTime = Date.now();
},
handleVideoRemoved: function (el, peer) {
var conversationLength = Date.now() - el.videoStartTime;
$(el).remove();
this.shuffle();
app.sounds.play('offline');
if (peer) {
tracking.track('videoDisconnected', {
duration: conversationLength,
peerId: peer.id,
type: peer.type
});
}
},
handleLockClick: function () {
if (me.authed) {
me.setPasswordDialog = true;
} else {
var dialogEl = $(templates.dialogs.lockingRequiresPaid()),
dialog = ui.dialog(dialogEl[0]).modal().show();
tracking.track('lockDialogShown');
dialogEl.delegate('button', 'click', function () {
switch (this.className) {
case "gopro":
tracking.track('goProButtonClicked', {}, function () {
window.location = 'https://apps.andyet.com/conversat.io';
});
break;
case "login":
tracking.track('loginButtonClicked', {}, function () {
app.login();
});
break;
case "cancel":
dialog.hide();
tracking.track('cancelButtonClicked');
break;
}
return false;
});
}
return false;
},
handleUnlockClick: function () {
app.api.unlockRoom(function (err) {
if (!err) {
tracking.track('roomUnlocked', {
name: me.currentRoom
});
}
});
return false;
},
enableTestMode: function () {
var id = 234234,
self = this;
$(document).keydown(function (e) {
if (self !== app.currentPage) return;
var src = document.getElementById('localVideo').src,
el = document.createElement('video'),
container = self.$('#remotes')[0];
// +
if (e.which === 187) {
el.autoplay = true;
el.id = ++id;
el.src = src;
app.api.emit('videoAdded', el);
}
// -
if (e.which === 189) {
if (container.firstChild) app.api.emit('videoRemoved', container.firstChild);
}
});
}
});

View File

@ -0,0 +1,15 @@
var BasePage = require('pages/base'),
templates = require('templates');
module.exports = BasePage.extend({
template: templates.pages.wrapper,
initialize: function (spec) {
this.url = spec.url;
},
render: function () {
this.basicRender();
this.$el.load(this.url);
return this;
}
});

38
clientapp/app/router.js Normal file
View File

@ -0,0 +1,38 @@
/*global app*/
var Backbone = require('backbone'),
staticPage = function (url) {
return function () {
var View = require('pages/wrapper');
app.renderPage(new View({
url: url
}));
};
};
module.exports = Backbone.Router.extend({
routes: {
'': 'create',
'help': 'help',
'premium': 'premium',
':room': 'talk'
},
// ------- ROUTE HANDLERS ---------
create: function () {
var View = require('pages/create');
app.renderPage(new View({
model: me
}));
},
help: staticPage('/partials/help'),
premium: staticPage('/partials/help'),
talk: function (roomName) {
var View = require('pages/talk');
me.currentRoom = roomName;
app.renderPage(new View({
model: me
}));
}
});

115
clientapp/app/views/main.js Normal file
View File

@ -0,0 +1,115 @@
/*global ui, app*/
var BasePage = require('pages/base'),
templates = require('templates'),
shippyAd = require('helpers/shippyAd');
module.exports = BasePage.extend({
template: templates.layout,
classBindings: {
authed: ''
},
contentBindings: {
name: '.name'
},
hrefBindings: {
smallPicUrl: 'header .avatar'
},
events: {
'click .logIn': 'handleLoginClick'
},
render: function () {
this.$el.html(this.template());
this.startAd();
this.handleBindings();
me.on('change:enterPasswordDialog', this.handleEnterPasswordDialogChange, this);
me.on('change:setPasswordDialog', this.handleSetPasswordDialogChange, this);
return this;
},
startAd: function () {
this.$('#ad').html(shippyAd());
setTimeout(this.startAd.bind(this), 30000);
},
handleLoginClick: function () {
return false;
},
handleEnterPasswordDialogChange: function () {
var form;
function close() {
me.enterPasswordDialog = false;
}
function setMessage(text) {
$('.errorMessage', form).text(text);
}
if (me.enterPasswordDialog) {
form = $(templates.dialogs.enterPassword());
this.enterPasswordDialog = ui.dialog(form[0]).modal().show();
$('button.cancel', form).click(function () {
close();
app.navigate('');
});
form.submit(function (e) {
e.preventDefault();
var val = $('input', form).val();
if (val) {
setMessage('joining...');
app.api.joinRoom({
name: me.currentRoom,
key: val
}, function (err, roomDescription) {
if (!err) {
app.saveRoomDescriptions(roomDescription);
close();
} else {
setMessage('Incorrect, try again.');
}
});
} else {
setMessage('Password required.');
}
return false;
});
} else {
this.enterPasswordDialog && this.enterPasswordDialog.hide();
delete this.enterPasswordDialog;
}
},
handleSetPasswordDialogChange: function () {
var form;
function close() {
me.setPasswordDialog = false;
}
function setMessage(text) {
$('.errorMessage', form).text(text);
}
if (me.setPasswordDialog) {
form = $(templates.dialogs.setPassword());
this.setPasswordDialog = ui.dialog(form[0]).modal().show();
$('button.cancel', form).click(function () {
close();
});
form.submit(function (e) {
e.preventDefault();
var val = $('input', form).val();
if (val) {
setMessage('setting...');
app.api.lockRoom(val, function (err) {
if (!err) {
close();
} else {
setMessage(err);
}
});
} else {
setMessage('Password required.');
}
return false;
});
} else {
this.setPasswordDialog && this.setPasswordDialog.hide();
delete this.setPasswordDialog;
}
}
});

View File

@ -0,0 +1,10 @@
if (!systemRequirements('chrome 26+ or ff 20+')) {
function go() {
window.location = '/system-requirements';
}
if (window.location.hostname === 'conversat.io') {
mixpanel.track('systemRequirementsNotMet', {}, go);
} else {
go();
}
};

View File

@ -0,0 +1,10 @@
$('head').prepend([
'<link rel="stylesheet" href="/style.css">',
'<link rel="stylesheet" href="/fonts.css">',
'<link rel="stylesheet" href="/ui.css">',
'<meta name="google-site-verification" content="OEAv0Phoo4ZRGpC-GIVt-WpSDQU8wtQerm6s9PToCVY" />'
].join(''))
$(function () {
require('app').launch();
});

8755
clientapp/libraries/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
(function($) {
$.showMessage = function(message, options){
// defaults
var settings = jQuery.extend({
id: 'sliding_message_box',
position: 'bottom',
size: '90',
backgroundColor: 'rgb(143, 177, 240)',
delay: 1500,
speed: 500,
fontSize: '30px'
}, options),
el = $('#' + settings.id);
// generate message div if it doesn't exist
if (el.length == 0) {
el = $('<div></div>').attr('id', settings.id);
el.css({
'-moz-transition': 'bottom ' + settings.speed + 'ms',
'-webkit-transition': 'bottom ' + settings.speed + 'ms',
'bottom': '-' + settings.size + 'px',
'z-index': '999',
'background-color': settings.backgroundColor,
'text-align': 'center',
'position': 'fixed',
'left': '0',
'width': '100%',
'line-height': settings.size + 'px',
'font-size': settings.fontSize,
});
$('body').append(el);
}
setTimeout(function () {
el.html(message);
el.css('bottom', 0);
setTimeout(function () {
el.css('bottom', '-' + settings.size + 'px');
}, settings.delay);
}, 10);
}
})(jQuery);

View File

@ -0,0 +1,13 @@
(function(c,a){window.mixpanel=a;var b,d,h,e;b=c.createElement("script");
b.type="text/javascript";b.async=!0;b.src=("https:"===c.location.protocol?"https:":"http:")+
'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';d=c.getElementsByTagName("script")[0];
d.parentNode.insertBefore(b,d);a._i=[];a.init=function(b,c,f){function d(a,b){
var c=b.split(".");2==c.length&&(a=a[c[0]],b=c[1]);a[b]=function(){a.push([b].concat(
Array.prototype.slice.call(arguments,0)))}}var g=a;"undefined"!==typeof f?g=a[f]=[]:
f="mixpanel";g.people=g.people||[];h=['disable','track','track_pageview','track_links',
'track_forms','register','register_once','unregister','identify','alias','name_tag',
'set_config','people.set','people.increment','people.track_charge','people.append'];
for(e=0;e<h.length;e++)d(g,h[e]);a._i.push([b,c,f])};a.__SV=1.2;})(document,window.mixpanel||[]);
mixpanel.init("4f9fd79a6827838ce81d84cd70d535cd");

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
(function () {
var ua = navigator.userAgent,
trim = function(string) {
return string.replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g,'')
},
valid = {
ie: 'msie',
msie: 'msie',
ff: 'firefox',
firefox: 'firefox',
safari: 'safari',
chrome: 'chrome',
opera: 'opera'
};
// from: http://stackoverflow.com/a/5918791/107722
function getVersion() {
var N = navigator.appName,
tem,
M = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2] = tem[1];
M = M? [M[1], M[2]]: [N, navigator.appVersion, '-?'];
return M;
}
var ver = getVersion(),
name = ver[0].toLowerCase(),
version = parseFloat(ver[1]);
function parseBrowserTypes(string) {
var arr = string.split('or'),
passed = false,
i = 0,
l = arr.length,
split,
translatedName,
hasPlus;
for (; i < l; i++) {
split = trim(arr[i]).split(' ');
translatedName = valid[split[0].toLowerCase()];
if (!translatedName) {
throw new Error('Unrecognized browser name:' + split[0]);
}
if (translatedName === name) {
hasPlus = split[1].indexOf('+') !== -1;
if (hasPlus) {
passed = parseFloat(split[1]) <= version;
} else {
passed = parseFloat(split[1]) === version;
}
}
if (passed) break;
}
return passed;
}
window.systemRequirements = function (browserString) {
var passed = false,
failUrl,
i = 0,
l = arguments.length;
if (typeof browserString === 'string') {
if (!parseBrowserTypes(browserString)) {
return false;
}
// incr starting point for loop
i = 1
}
for (; i < l; i++) {
if (arguments[i] instanceof Function) {
if (!arguments[i]()) {
return false;
}
}
}
return true;
};
})();

448
clientapp/libraries/ui.js Normal file
View File

@ -0,0 +1,448 @@
var ui = {};
;(function(exports){
/**
* Expose `Emitter`.
*/
exports.Emitter = Emitter;
/**
* Initialize a new `Emitter`.
*
* @api public
*/
function Emitter() {
this.callbacks = {};
};
/**
* Listen on the given `event` with `fn`.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.on = function(event, fn){
(this.callbacks[event] = this.callbacks[event] || [])
.push(fn);
return this;
};
/**
* Adds an `event` listener that will be invoked a single
* time then automatically removed.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.once = function(event, fn){
var self = this;
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
this.on(event, on);
return this;
};
/**
* Remove the given callback for `event` or all
* registered callbacks.
*
* @param {String} event
* @param {Function} fn
* @return {Emitter}
* @api public
*/
Emitter.prototype.off = function(event, fn){
var callbacks = this.callbacks[event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this.callbacks[event];
return this;
}
// remove specific handler
var i = callbacks.indexOf(fn);
callbacks.splice(i, 1);
return this;
};
/**
* Emit `event` with the given args.
*
* @param {String} event
* @param {Mixed} ...
* @return {Emitter}
*/
Emitter.prototype.emit = function(event){
var args = [].slice.call(arguments, 1)
, callbacks = this.callbacks[event];
if (callbacks) {
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
})(ui);
;(function(exports, html){
/**
* Expose `Overlay`.
*/
exports.Overlay = Overlay;
/**
* Return a new `Overlay` with the given `options`.
*
* @param {Object} options
* @return {Overlay}
* @api public
*/
exports.overlay = function(options){
return new Overlay(options);
};
/**
* Initialize a new `Overlay`.
*
* @param {Object} options
* @api public
*/
function Overlay(options) {
ui.Emitter.call(this);
var self = this;
options = options || {};
this.closable = options.closable;
this.el = $(html);
this.el.appendTo('body');
if (this.closable) {
this.el.click(function(){
self.emit('close');
self.hide();
});
}
}
/**
* Inherit from `Emitter.prototype`.
*/
Overlay.prototype = new ui.Emitter;
/**
* Show the overlay.
*
* Emits "show" event.
*
* @return {Overlay} for chaining
* @api public
*/
Overlay.prototype.show = function(){
this.emit('show');
this.el.removeClass('hide');
return this;
};
/**
* Hide the overlay.
*
* Emits "hide" event.
*
* @return {Overlay} for chaining
* @api public
*/
Overlay.prototype.hide = function(){
var self = this;
this.emit('hide');
this.el.addClass('hide');
setTimeout(function(){
self.el.remove();
}, 2000);
return this;
};
})(ui, "<div id=\"overlay\" class=\"hide\"></div>");
;(function(exports, html){
/**
* Active dialog.
*/
var active;
/**
* Expose `Dialog`.
*/
exports.Dialog = Dialog;
/**
* Return a new `Dialog` with the given
* (optional) `title` and `msg`.
*
* @param {String} title or msg
* @param {String} msg
* @return {Dialog}
* @api public
*/
exports.dialog = function(title, msg){
switch (arguments.length) {
case 2:
return new Dialog({ title: title, message: msg });
case 1:
return new Dialog({ message: title });
}
};
/**
* Initialize a new `Dialog`.
*
* Options:
*
* - `title` dialog title
* - `message` a message to display
*
* Emits:
*
* - `show` when visible
* - `hide` when hidden
*
* @param {Object} options
* @api public
*/
function Dialog(options) {
ui.Emitter.call(this);
options = options || {};
this.template = html;
this.el = $(this.template);
this.render(options);
if (active && !active.hiding) active.hide();
if (Dialog.effect) this.effect(Dialog.effect);
active = this;
};
/**
* Inherit from `Emitter.prototype`.
*/
Dialog.prototype = new ui.Emitter;
/**
* Render with the given `options`.
*
* @param {Object} options
* @api public
*/
Dialog.prototype.render = function(options){
var el = this.el
, title = options.title
, msg = options.message
, self = this;
el.find('.close').click(function(){
self.emit('close');
self.hide();
return false;
});
el.find('h1').text(title);
if (!title) el.find('h1').remove();
// message
if ('string' == typeof msg) {
el.find('p').text(msg);
} else if (msg) {
el.find('p').replaceWith(msg.el || msg);
}
setTimeout(function(){
el.removeClass('hide');
}, 0);
};
/**
* Enable the dialog close link.
*
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.closable = function(){
this.el.addClass('closable');
return this;
};
/**
* Set the effect to `type`.
*
* @param {String} type
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.effect = function(type){
this._effect = type;
this.el.addClass(type);
return this;
};
/**
* Make it modal!
*
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.modal = function(){
this._overlay = ui.overlay();
return this;
};
/**
* Add an overlay.
*
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.overlay = function(){
var self = this;
var overlay = ui.overlay({ closable: true });
overlay.on('hide', function(){
self.closedOverlay = true;
self.hide();
});
overlay.on('close', function(){
self.emit('close');
});
this._overlay = overlay;
return this;
};
/**
* Close the dialog when the escape key is pressed.
*
* @api private
*/
Dialog.prototype.escapable = function(){
var self = this;
$(document).bind('keydown.dialog', function(e){
if (27 != e.which) return;
$(this).unbind('keydown.dialog');
self.emit('escape');
self.hide();
});
};
/**
* Show the dialog.
*
* Emits "show" event.
*
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.show = function(){
var overlay = this._overlay;
this.emit('show');
if (overlay) {
overlay.show();
this.el.addClass('modal');
}
// escape
if (!overlay || overlay.closable) this.escapable();
this.el.appendTo('body');
this.el.css({ marginLeft: -(this.el.width() / 2) + 'px' });
this.emit('show');
return this;
};
/**
* Hide the dialog with optional delay of `ms`,
* otherwise the dialog is removed immediately.
*
* Emits "hide" event.
*
* @return {Number} ms
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.hide = function(ms){
var self = this;
// prevent thrashing
this.hiding = true;
// duration
if (ms) {
setTimeout(function(){
self.hide();
}, ms);
return this;
}
// hide / remove
this.el.addClass('hide');
if (this._effect) {
setTimeout(function(){
self.remove();
}, 500);
} else {
self.remove();
}
// modal
if (this._overlay && !self.closedOverlay) this._overlay.hide();
return this;
};
/**
* Hide the dialog without potential animation.
*
* @return {Dialog} for chaining
* @api public
*/
Dialog.prototype.remove = function(){
this.emit('hide');
this.el.remove();
$(document).unbind('keydown.dialog');
return this;
};
})(ui, "<div id=\"dialog\" class=\"hide\">\n <div class=\"content\">\n <h1>Title</h1>\n <a href=\"#\" class=\"close\">×</a>\n <p>Message</p>\n </div>\n</div>");

View File

@ -0,0 +1,28 @@
// follow @HenrikJoreteg and @andyet if you like this ;)
(function (window) {
var ls = window.localStorage,
out = {},
inNode = typeof process !== 'undefined';
if (inNode) {
module.exports = console;
return;
}
if (ls && ls.debug && window.console) {
out = window.console;
} else {
var methods = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(","),
l = methods.length,
fn = function () {};
while (l--) {
out[methods[l]] = fn;
}
}
if (typeof exports !== 'undefined') {
module.exports = out;
} else {
window.console = out;
}
})(this);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,54 @@
var SimpleWebRTC = require('simplewebrtc');
function Conversatio(spec) {
var opts = {},
self = this,
item;
if (typeof spec === 'object') {
for (item in spec) {
opts[item] = spec[item];
}
}
SimpleWebRTC.call(this, opts);
if (opts.token) {
this.auth(opts.token);
}
this.connection.on('passwordRequired', this.emit.bind(this, 'passwordRequired'));
this.connection.on('passwordFailed', this.emit.bind(this, 'passwordFailed'));
this.connection.on('unlocked', this.emit.bind(this, 'unlocked'));
this.connection.on('locked', this.emit.bind(this, 'locked'));
}
Conversatio.prototype = Object.create(SimpleWebRTC.prototype, {
constructor: {
value: Conversatio
}
});
Conversatio.prototype.auth = function (token, cb) {
var self = this;
this.connection.emit('validateToken', token, function (err, user) {
if (err) {
self.emit('authFailed', err);
} else {
self.emit('user', user);
}
cb && cb(err, user);
});
};
Conversatio.prototype.lockRoom = function (password, cb) {
this.connection.emit('lockRoom', password, cb);
};
Conversatio.prototype.unlockRoom = function (cb) {
this.connection.emit('unlockRoom', cb);
};
module.exports = Conversatio;

View File

@ -0,0 +1,10 @@
// simple commonJS cookie reader, best perf according to http://jsperf.com/cookie-parsing
module.exports = function (name) {
var cookie = document.cookie,
setPos = cookie.indexOf(name + '='),
stopPos = cookie.indexOf(';', setPos),
res;
if (!~setPos) return null;
res = decodeURIComponent(cookie.substring(setPos, ~stopPos ? stopPos : undefined).split('=')[1]);
return (res.charAt(0) === '{') ? JSON.parse(res) : res;
};

View File

@ -0,0 +1,229 @@
(function () {
// reference to our currently focused element
var focusedEl;
function getFluidGridFunction(selector) {
return function (focus) {
reOrganize(selector, focus);
};
}
function biggestBox(container, aspectRatio) {
var aspectRatio = aspectRatio || (3 / 4),
height = (container.width * aspectRatio),
res = {};
if (height > container.height) {
return {
height: container.height,
width: container.height / aspectRatio
};
} else {
return {
width: container.width,
height: container.width * aspectRatio
};
}
}
function reOrganize(selector, focus) {
var floor = Math.floor,
elements = $(selector),
howMany = elements.length,
howManyNonFocused = function () {
var hasFocused = !!elements.find('.focused').length;
if (hasFocused && howMany > 1) {
return howMany - 1;
} else if (hasFocused && howMany === 1) {
return 1;
} else {
return howMany;
}
}(),
totalAvailableWidth = window.innerWidth,
totalAvailableHeight = window.innerHeight - 140,
availableWidth = totalAvailableWidth,
availableHeight = totalAvailableHeight,
container = {
width: availableWidth,
height: availableHeight
},
columnPadding = 15,
minimumWidth = 290,
aspectRatio = 3 / 4,
numberOfColumns,
numberOfRows,
numberOfPaddingColumns,
numberOfPaddingRows,
itemDimensions,
totalWidth,
videoWidth,
leftMargin,
videoHeight,
usedHeight,
topMargin,
// do we have one selected?
// this is because having a single
// focused element is not treated
// differently, but we don't want to
// lose that reference.
haveFocusedEl;
// if we passed in a string here (could be "none")
// then we want to either set or clear our current
// focused element.
if (focus) focusedEl = $(focus)[0];
// make sure our cached focused element is still
// attached.
if (focusedEl && !$(focusedEl).parent().length) focusedEl = undefined;
// figure out if we should consider us as having any
// special focused elements
haveFocusedEl = focusedEl && howManyNonFocused > 1;
elements.height(availableHeight);
// how we want the to stack at different numbers
if (haveFocusedEl) {
numberOfColumns = howManyNonFocused - 1;
numberOfRows = 1;
availableHeight = totalAvailableHeight * .2;
} else if (howManyNonFocused === 0) {
return;
} else if (howManyNonFocused === 1) {
numberOfColumns = 1;
numberOfRows = 1;
} else if (howManyNonFocused === 2) {
if (availableWidth > availableHeight) {
numberOfColumns = 2;
numberOfRows = 1;
} else {
numberOfColumns = 1;
numberOfRows = 2;
}
} else if (howManyNonFocused === 3) {
if (availableWidth > availableHeight) {
numberOfColumns = 3;
numberOfRows = 1;
} else {
numberOfColumns = 1;
numberOfRows = 3;
}
} else if (howManyNonFocused === 4) {
numberOfColumns = 2;
numberOfRows = 2;
} else if (howManyNonFocused === 5) {
numberOfColumns = 3;
numberOfRows = 2;
} else if (howManyNonFocused === 6) {
if (availableWidth > availableHeight) {
numberOfColumns = 3;
numberOfRows = 2;
} else {
numberOfColumns = 2;
numberOfRows = 3;
}
}
itemDimensions = biggestBox({
width: availableWidth / numberOfColumns,
height: availableHeight / numberOfRows
});
numberOfPaddingColumns = numberOfColumns - 1;
numberOfPaddingRows = numberOfRows - 1;
totalWidth = itemDimensions.width * numberOfColumns;
videoWidth = function () {
var totalWidthLessPadding = totalWidth - (columnPadding * numberOfPaddingColumns);
return totalWidthLessPadding / numberOfColumns;
}();
leftMargin = (availableWidth - totalWidth) / 2;
videoHeight = itemDimensions.height - ((numberOfRows > 1) ? (columnPadding / numberOfRows) : 0);
usedHeight = (numberOfRows * videoHeight);
topMargin = (availableHeight - usedHeight) / 2;
if (haveFocusedEl) {
elements = elements.not('.focused');
}
elements.each(function (index) {
var order = index,
row = floor(order / numberOfColumns),
column = order % numberOfColumns,
intensity = 12,
rotation = function () {
if (numberOfColumns === 3) {
if (column === 0) {
return 1;
} else if (column === 1) {
return 0;
} else if (column === 2) {
return -1
}
} else if (numberOfColumns === 2) {
intensity = 5;
return column == 1 ? -1 : 1
} else if (numberOfColumns === 1) {
return 0;
}
}(),
transformation = 'rotateY(' + (rotation * intensity) + 'deg)';
if (rotation === 0) {
transformation += ' scale(.98)';
}
var calculatedTop;
if (haveFocusedEl) {
calculatedTop = (totalAvailableHeight * .8) + topMargin + 'px';
} else {
calculatedTop = (row * itemDimensions.height) + topMargin + 'px';
}
$(this).css({
//transform: transformation,
top: calculatedTop,
left: (column * itemDimensions.width) + leftMargin + 'px',
width: videoWidth + 'px',
height: videoHeight + 'px',
position: 'absolute'
});
});
if (haveFocusedEl) {
var focusSize = biggestBox({
height: (totalAvailableHeight * .8),
width: totalAvailableWidth
}, focusedEl.videoHeight / focusedEl.videoWidth);
$(focusedEl).css({
top: 0,
height: focusSize.height - topMargin,
width: focusSize.width,
left: (totalAvailableWidth / 2) - (focusSize.width / 2)
});
}
}
if (typeof exports !== 'undefined') {
module.exports = getFluidGridFunction;
} else {
window.getFluidGridFunction = getFluidGridFunction;
}
})();

View File

@ -0,0 +1,678 @@
;(function () {
var logger = {
log: function (){},
warn: function (){},
error: function (){}
};
// normalize environment
var RTCPeerConnection = null,
getUserMedia = null,
attachMediaStream = null,
reattachMediaStream = null,
browser = null,
screenSharingSupport = false;
webRTCSupport = true;
if (navigator.mozGetUserMedia) {
logger.log("This appears to be Firefox");
browser = "firefox";
// The RTCPeerConnection object.
RTCPeerConnection = mozRTCPeerConnection;
// The RTCSessionDescription object.
RTCSessionDescription = mozRTCSessionDescription;
// The RTCIceCandidate object.
RTCIceCandidate = mozRTCIceCandidate;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.mozGetUserMedia.bind(navigator);
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
element.mozSrcObject = stream;
element.play();
};
reattachMediaStream = function(to, from) {
to.mozSrcObject = from.mozSrcObject;
to.play();
};
// Fake get{Video,Audio}Tracks
MediaStream.prototype.getVideoTracks = function() {
return [];
};
MediaStream.prototype.getAudioTracks = function() {
return [];
};
} else if (navigator.webkitGetUserMedia) {
browser = "chrome";
screenSharingSupport = navigator.userAgent.match('Chrome') && parseInt(navigator.userAgent.match(/Chrome\/(.*) /)[1]) >= 26
// The RTCPeerConnection object.
RTCPeerConnection = webkitRTCPeerConnection;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
element.autoplay = true;
element.src = webkitURL.createObjectURL(stream);
};
reattachMediaStream = function(to, from) {
to.src = from.src;
};
// The representation of tracks in a stream is changed in M26.
// Unify them for earlier Chrome versions in the coexisting period.
if (!webkitMediaStream.prototype.getVideoTracks) {
webkitMediaStream.prototype.getVideoTracks = function() {
return this.videoTracks;
};
webkitMediaStream.prototype.getAudioTracks = function() {
return this.audioTracks;
};
}
// New syntax of getXXXStreams method in M26.
if (!webkitRTCPeerConnection.prototype.getLocalStreams) {
webkitRTCPeerConnection.prototype.getLocalStreams = function() {
return this.localStreams;
};
webkitRTCPeerConnection.prototype.getRemoteStreams = function() {
return this.remoteStreams;
};
}
} else {
webRTCSupport = false;
throw new Error("Browser does not appear to be WebRTC-capable");
}
// emitter that we use as a base
function WildEmitter() {
this.callbacks = {};
}
// Listen on the given `event` with `fn`. Store a group name if present.
WildEmitter.prototype.on = function (event, groupName, fn) {
var hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
func._groupName = group;
(this.callbacks[event] = this.callbacks[event] || []).push(func);
return this;
};
// Adds an `event` listener that will be invoked a single
// time then automatically removed.
WildEmitter.prototype.once = function (event, fn) {
var self = this;
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
this.on(event, on);
return this;
};
// Unbinds an entire group
WildEmitter.prototype.releaseGroup = function (groupName) {
var item, i, len, handlers;
for (item in this.callbacks) {
handlers = this.callbacks[item];
for (i = 0, len = handlers.length; i < len; i++) {
if (handlers[i]._groupName === groupName) {
handlers.splice(i, 1);
i--;
len--;
}
}
}
return this;
};
// Remove the given callback for `event` or all
// registered callbacks.
WildEmitter.prototype.off = function (event, fn) {
var callbacks = this.callbacks[event],
i;
if (!callbacks) return this;
// remove all handlers
if (arguments.length === 1) {
delete this.callbacks[event];
return this;
}
// remove specific handler
i = callbacks.indexOf(fn);
callbacks.splice(i, 1);
return this;
};
// Emit `event` with the given args.
// also calls any `*` handlers
WildEmitter.prototype.emit = function (event) {
var args = [].slice.call(arguments, 1),
callbacks = this.callbacks[event],
specialCallbacks = this.getWildcardCallbacks(event),
i,
len,
item;
if (callbacks) {
for (i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
if (specialCallbacks) {
for (i = 0, len = specialCallbacks.length; i < len; ++i) {
specialCallbacks[i].apply(this, [event].concat(args));
}
}
return this;
};
// Helper for for finding special wildcard event handlers that match the event
WildEmitter.prototype.getWildcardCallbacks = function (eventName) {
var item,
split,
result = [];
for (item in this.callbacks) {
split = item.split('*');
if (item === '*' || (split.length === 2 && eventName.slice(0, split[1].length) === split[1])) {
result = result.concat(this.callbacks[item]);
}
}
return result;
};
function WebRTC(opts) {
var self = this,
options = opts || {},
config = this.config = {
url: 'http://signaling.simplewebrtc.com:8888',
log: false,
localVideoEl: '',
remoteVideosEl: '',
autoRequestMedia: false,
autoRemoveVideos: true,
// makes the entire PC config overridable
peerConnectionConfig: {
iceServers: browser == 'firefox' ? [{"url":"stun:124.124.124.2"}] : [{"url": "stun:stun.l.google.com:19302"}]
},
peerConnectionContraints: {
optional: [{"DtlsSrtpKeyAgreement": true}]
},
media: {
audio:true,
video: {
mandatory: {},
optional: []
}
}
},
item,
connection;
// check for support
if (!webRTCSupport) {
console.error('Your browser doesn\'t seem to support WebRTC');
}
// expose screensharing check
this.screenSharingSupport = screenSharingSupport;
// set options
for (item in options) {
this.config[item] = options[item];
}
// log if configured to
if (this.config.log) logger = console;
// where we'll store our peer connections
this.peers = [];
// our socket.io connection
connection = this.connection = io.connect(this.config.url);
connection.on('connect', function () {
self.emit('ready', connection.socket.sessionid);
self.sessionReady = true;
self.testReadiness();
});
connection.on('message', function (message) {
var peers = self.getPeers(message.from, message.roomType),
peer;
if (message.type === 'offer') {
peer = self.createPeer({
id: message.from,
type: message.roomType,
sharemyscreen: message.roomType === 'screen' && !message.broadcaster
});
peer.handleMessage(message);
} else if (peers.length) {
peers.forEach(function (peer) {
peer.handleMessage(message);
});
}
});
connection.on('remove', function (room) {
if (room.id !== self.connection.socket.sessionid) {
self.removeForPeerSession(room.id, room.type);
}
});
WildEmitter.call(this);
// log events
this.on('*', function (event, val1, val2) {
logger.log('event:', event, val1, val2);
});
// auto request if configured
if (this.config.autoRequestMedia) this.startLocalVideo();
}
WebRTC.prototype = Object.create(WildEmitter.prototype, {
constructor: {
value: WebRTC
}
});
WebRTC.prototype.getEl = function (idOrEl) {
if (typeof idOrEl === 'string') {
return document.getElementById(idOrEl);
} else {
return idOrEl;
}
};
// this accepts either element ID or element
// and either the video tag itself or a container
// that will be used to put the video tag into.
WebRTC.prototype.getLocalVideoContainer = function () {
var el = this.getEl(this.config.localVideoEl);
if (el && el.tagName === 'VIDEO') {
return el;
} else {
var video = document.createElement('video');
el.appendChild(video);
return video;
}
};
WebRTC.prototype.getRemoteVideoContainer = function () {
return this.getEl(this.config.remoteVideosEl);
};
WebRTC.prototype.createPeer = function (opts) {
var peer;
opts.parent = this;
peer = new Peer(opts);
this.peers.push(peer);
return peer;
};
WebRTC.prototype.createRoom = function (name, cb) {
if (arguments.length === 2) {
this.connection.emit('create', name, cb);
} else {
this.connection.emit('create', name);
}
};
WebRTC.prototype.joinRoom = function (name, cb) {
var self = this;
this.roomName = name;
this.connection.emit('join', name, function (err, roomDescription) {
if (err) {
self.emit('error', err);
} else {
var id,
client,
type,
peer;
for (id in roomDescription.clients) {
client = roomDescription.clients[id];
for (type in client) {
if (client[type]) {
peer = self.createPeer({
id: id,
type: type
});
peer.start();
}
}
}
}
if (cb instanceof Function) cb(err, roomDescription);
});
};
WebRTC.prototype.leaveRoom = function () {
if (this.roomName) {
this.connection.emit('leave', this.roomName);
this.peers.forEach(function (peer) {
peer.end();
});
}
};
WebRTC.prototype.testReadiness = function () {
var self = this;
if (this.localStream && this.sessionReady) {
// This timeout is a workaround for the strange no-audio bug
// as described here: https://code.google.com/p/webrtc/issues/detail?id=1525
// remove timeout when this is fixed.
setTimeout(function () {
self.emit('readyToCall', self.connection.socket.sessionid);
}, 1000);
}
};
WebRTC.prototype.startLocalVideo = function (element) {
var self = this;
getUserMedia(this.config.media, function (stream) {
attachMediaStream(element || self.getLocalVideoContainer(), stream);
element.muted = true;
self.localStream = stream;
self.testReadiness();
}, function () {
throw new Error('Failed to get access to local media.');
});
};
// Audio controls
WebRTC.prototype.mute = function () {
this._audioEnabled(false);
this.emit('audioOff');
};
WebRTC.prototype.unmute = function () {
this._audioEnabled(true);
this.emit('audioOn');
};
// Video controls
WebRTC.prototype.pauseVideo = function () {
this._videoEnabled(false);
this.emit('videoOff');
};
WebRTC.prototype.resumeVideo = function () {
this._videoEnabled(true);
this.emit('videoOn');
};
// Combined controls
WebRTC.prototype.pause = function () {
this.mute();
this.pauseVideo();
};
WebRTC.prototype.resume = function () {
this.unmute();
this.resumeVideo();
};
// Internal methods for enabling/disabling audio/video
WebRTC.prototype._audioEnabled = function (bool) {
this.localStream.getAudioTracks().forEach(function (track) {
track.enabled = !!bool;
});
};
WebRTC.prototype._videoEnabled = function (bool) {
this.localStream.getVideoTracks().forEach(function (track) {
track.enabled = !!bool;
});
};
WebRTC.prototype.shareScreen = function () {
var self = this,
peer;
if (screenSharingSupport) {
getUserMedia({
video: {
mandatory: {
chromeMediaSource: 'screen'
}
}
}, function (stream) {
var item,
el = document.createElement('video'),
container = self.getRemoteVideoContainer();
self.localScreen = stream;
el.id = 'localScreen';
attachMediaStream(el, stream);
if (container) {
container.appendChild(el);
}
// TODO: Once this chrome bug is fixed:
// https://code.google.com/p/chromium/issues/detail?id=227485
// we need to listen for the screenshare stream ending and call
// the "stopScreenShare" method to clean things up.
self.emit('videoAdded', el);
self.connection.emit('shareScreen');
self.peers.forEach(function (existingPeer) {
var peer;
if (existingPeer.type === 'video') {
peer = self.createPeer({
id: existingPeer.id,
type: 'screen',
sharemyscreen: true
});
peer.start();
}
});
}, function () {
throw new Error('Failed to access to screen media.');
});
}
};
WebRTC.prototype.stopScreenShare = function () {
this.connection.emit('unshareScreen');
var videoEl = document.getElementById('localScreen'),
container = this.getRemoteVideoContainer(),
stream = this.localScreen;
if (this.config.autoRemoveVideos && container && videoEl) {
container.removeChild(videoEl);
}
// a hack to emit the event the removes the video
// element that we want
if (videoEl) this.emit('videoRemoved', videoEl);
this.localScreen.stop();
this.peers.forEach(function (peer) {
if (peer.broadcaster) {
peer.end();
}
});
delete this.localScreen;
};
WebRTC.prototype.removeForPeerSession = function (id, type) {
this.getPeers(id, type).forEach(function (peer) {
peer.end();
});
};
// fetches all Peer objects by session id and/or type
WebRTC.prototype.getPeers = function (sessionId, type) {
return this.peers.filter(function (peer) {
return (!sessionId || peer.id === sessionId) && (!type || peer.type === type);
});
};
function Peer(options) {
var self = this;
this.id = options.id;
this.parent = options.parent;
this.type = options.type || 'video';
this.oneway = options.oneway || false;
this.sharemyscreen = options.sharemyscreen || false;
this.stream = options.stream;
// Create an RTCPeerConnection via the polyfill
this.pc = new RTCPeerConnection(this.parent.config.peerConnectionConfig, this.parent.config.peerConnectionContraints);
this.pc.onicecandidate = this.onIceCandidate.bind(this);
if (options.type === 'screen') {
if (this.parent.localScreen && this.sharemyscreen) {
logger.log('adding local screen stream to peer connection')
this.pc.addStream(this.parent.localScreen);
this.broadcaster = this.parent.connection.socket.sessionid;
}
} else {
this.pc.addStream(this.parent.localStream);
}
this.pc.onaddstream = this.handleRemoteStreamAdded.bind(this);
this.pc.onremovestream = this.handleStreamRemoved.bind(this);
// for re-use
this.mediaConstraints = {
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
WildEmitter.call(this);
// proxy events to parent
this.on('*', function (name, value) {
self.parent.emit(name, value, self);
});
}
Peer.prototype = Object.create(WildEmitter.prototype, {
constructor: {
value: Peer
}
});
Peer.prototype.handleMessage = function (message) {
if (message.type === 'offer') {
logger.log('setting remote description');
this.pc.setRemoteDescription(new RTCSessionDescription(message.payload));
this.answer();
} else if (message.type === 'answer') {
logger.log('setting answer');
this.pc.setRemoteDescription(new RTCSessionDescription(message.payload));
} else if (message.type === 'candidate') {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.payload.label,
candidate: message.payload.candidate
});
this.pc.addIceCandidate(candidate);
}
};
Peer.prototype.send = function (type, payload) {
this.parent.connection.emit('message', {
to: this.id,
broadcaster: this.broadcaster,
roomType: this.type,
type: type,
payload: payload
});
};
Peer.prototype.onIceCandidate = function (event) {
if (this.closed) return;
if (event.candidate) {
this.send('candidate', {
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
} else {
logger.log("End of candidates.");
}
};
Peer.prototype.start = function () {
var self = this;
this.pc.createOffer(function (sessionDescription) {
logger.log('setting local description');
self.pc.setLocalDescription(sessionDescription);
logger.log('sending offer', sessionDescription);
self.send('offer', sessionDescription);
}, null, this.mediaConstraints);
};
Peer.prototype.end = function () {
this.pc.close();
this.handleStreamRemoved();
};
Peer.prototype.answer = function () {
var self = this;
logger.log('answer called');
this.pc.createAnswer(function (sessionDescription) {
logger.log('setting local description');
self.pc.setLocalDescription(sessionDescription);
logger.log('sending answer', sessionDescription);
self.send('answer', sessionDescription);
}, null, this.mediaConstraints);
};
Peer.prototype.handleRemoteStreamAdded = function (event) {
var stream = this.stream = event.stream,
el = document.createElement('video'),
container = this.parent.getRemoteVideoContainer();
el.id = this.getDomId();
attachMediaStream(el, stream);
if (container) container.appendChild(el);
this.emit('videoAdded', el);
};
Peer.prototype.handleStreamRemoved = function () {
var video = document.getElementById(this.getDomId()),
container = this.parent.getRemoteVideoContainer();
if (video) {
this.emit('videoRemoved', video);
if (container && this.parent.config.autoRemoveVideos) {
container.removeChild(video);
}
}
this.parent.peers.splice(this.parent.peers.indexOf(this), 1);
this.closed = true;
};
Peer.prototype.getDomId = function () {
return [this.id, this.type, this.broadcaster ? 'broadcasting' : 'incoming'].join('_');
};
// expose WebRTC
if (typeof module !== 'undefined') {
module.exports = WebRTC;
} else {
window.WebRTC = WebRTC;
}
}());

View File

@ -0,0 +1,21 @@
// replaces all whitespace with '-' and removes
// all non-url friendly characters
(function () {
var whitespace = /\s+/g,
nonAscii = /[^A-Za-z0-9_ \-]/g;
function slugger(string, opts) {
var maintainCase = opts && opts.maintainCase || false,
replacement = opts && opts.replacement || '-',
key;
if (typeof string !== 'string') return '';
if (!maintainCase) string = string.toLowerCase();
return string.replace(nonAscii, '').replace(whitespace, replacement);
};
if (typeof module !== 'undefined') {
module.exports = slugger;
} else {
window.slugger = slugger;
}
})();

View File

@ -0,0 +1,140 @@
/*
SoundEffectManager
Loads and plays sound effects useing
HTML5 Web Audio API (as only available in webkit, at the moment).
By @HenrikJoreteg from &yet
*/
/*global webkitAudioContext define*/
(function () {
var root = this;
function SoundEffectManager() {
this.support = !!window.webkitAudioContext;
if (this.support) {
this.context = new webkitAudioContext();
}
this.sounds = {};
}
// async load a file at a given URL, store it as 'name'.
SoundEffectManager.prototype.loadFile = function (url, name, delay, cb) {
if (this.support) {
this._loadWebAudioFile(url, name, delay, cb);
} else {
this._loadWaveFile(url.replace('.mp3', '.wav'), name, delay, 3, cb);
}
};
// async load a file at a given URL, store it as 'name'.
SoundEffectManager.prototype._loadWebAudioFile = function (url, name, delay, cb) {
if (!this.support) return;
var self = this,
request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
request.onload = function () {
self.sounds[name] = self.context.createBuffer(request.response, true);
cb && cb();
};
setTimeout(function () {
request.send();
}, delay || 0);
};
SoundEffectManager.prototype._loadWaveFile = function (url, name, delay, multiplexLimit, cb) {
var self = this,
limit = multiplexLimit || 3;
setTimeout(function () {
var a, i = 0;
self.sounds[name] = [];
while (i < limit) {
a = new Audio();
a.src = url;
// for our callback
if (i === 0 && cb) {
a.addEventListener('canplaythrough', cb, false);
}
a.load();
self.sounds[name][i++] = a;
}
}, delay || 0);
};
SoundEffectManager.prototype._playWebAudio = function (soundName) {
var buffer = this.sounds[soundName],
source;
if (!buffer) return;
// creates a sound source
source = this.context.createBufferSource();
// tell the source which sound to play
source.buffer = buffer;
// connect the source to the context's destination (the speakers)
source.connect(this.context.destination);
// play it
source.noteOn(0);
};
SoundEffectManager.prototype._playWavAudio = function (soundName, loop) {
var self = this,
audio = this.sounds[soundName],
howMany = audio && audio.length || 0,
i = 0,
currSound;
if (!audio) return;
while (i < howMany) {
currSound = audio[i++];
// this covers case where we loaded an unplayable file type
if (currSound.error) return;
if (currSound.currentTime === 0 || currSound.currentTime === currSound.duration) {
currSound.currentTime = 0;
currSound.loop = !!loop;
i = howMany;
return currSound.play();
}
}
};
SoundEffectManager.prototype.play = function (soundName, loop) {
if (this.support) {
this._playWebAudio(soundName, loop);
} else {
return this._playWavAudio(soundName, loop);
}
};
SoundEffectManager.prototype.stop = function (soundName) {
if (this.support) {
// TODO: this
} else {
var soundArray = this.sounds[soundName],
howMany = soundArray && soundArray.length || 0,
i = 0,
currSound;
while (i < howMany) {
currSound = soundArray[i++];
currSound.pause();
currSound.currentTime = 0;
}
}
};
// attach to window or export with commonJS
if (typeof module !== "undefined") {
module.exports = SoundEffectManager;
} else if (typeof root.define === "function" && define.amd) {
root.define(SoundEffectManager);
} else {
root.SoundEffectManager = SoundEffectManager;
}
})();

View File

@ -0,0 +1,565 @@
// (c) 2013 Henrik Joreteg
// MIT Licensed
// For all details and documentation:
// https://github.com/HenrikJoreteg/StrictModel
(function () {
'use strict';
// Initial setup
// -------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both CommonJS and the browser.
var Strict = typeof exports !== 'undefined' ? exports : root.Strict = {},
toString = Object.prototype.toString,
slice = Array.prototype.slice;
// Current version of the library. Keep in sync with `package.json`.
Strict.VERSION = '0.0.1';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
// Require Backbone, if we're on the server, and it's not already present.
var Backbone = root.Backbone;
if (!Backbone && (typeof require !== 'undefined')) Backbone = require('backbone');
// Backbone Collection compatibility fix:
// In backbone, when you add an already instantiated model to a collection
// the collection checks to see if what you're adding is already a model
// the problem is, it does this witn an instanceof check. We're wanting to
// use completely different models so the instanceof will fail even if they
// are "real" models. So we work around this by overwriting this method from
// backbone 1.0.0. The only difference is it compares against our Strict.Model
// instead of backbone's.
Backbone.Collection.prototype._prepareModel = function (attrs, options) {
if (attrs instanceof Strict.Model) {
if (!attrs.collection) attrs.collection = this;
return attrs;
}
options || (options = {});
options.collection = this;
var model = new this.model(attrs, options);
if (!model._validate(attrs, options)) {
this.trigger('invalid', this, attrs, options);
return false;
}
return model;
};
// Helpers
// -------
// Shared empty constructor function to aid in prototype-chain creation.
var Constructor = function () {};
// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var inherits = function (parent, protoProps, staticProps) {
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent's constructor.
if (protoProps && protoProps.hasOwnProperty('constructor')) {
child = protoProps.constructor;
} else {
child = function () { return parent.apply(this, arguments); };
}
// Inherit class (static) properties from parent.
_.extend(child, parent);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
Constructor.prototype = parent.prototype;
child.prototype = new Constructor();
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
// Add static properties to the constructor function, if supplied.
if (staticProps) _.extend(child, staticProps);
// Correctly set child's `prototype.constructor`.
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed later.
child.__super__ = parent.prototype;
return child;
};
var extend = function (protoProps, classProps) {
var child = inherits(this, protoProps, classProps);
child.extend = this.extend;
return child;
};
// Mixins
// ------
// Sugar for defining properties a la ES5.
var Mixins = Strict.Mixins = {
// shortcut for Object.defineProperty
define: function (name, def) {
Object.defineProperty(this, name, def);
},
defineGetter: function (name, handler) {
this.define(name, {
get: handler.bind(this)
});
},
defineSetter: function (name, handler) {
this.define(name, {
set: handler.bind(this)
});
}
};
// Strict.Registry
// ---------------
// Internal storage for models, seperate namespace
// storage from default to prevent collision of matching
// model type+id and namespace name
var Registry = Strict.Registry = function () {
this._cache = {};
this._namespaces = {};
};
// Attach all inheritable methods to the Registry prototype.
_.extend(Registry.prototype, {
// Get the general or namespaced internal cache
_getCache: function (ns) {
if (ns) {
this._namespaces[ns] || (this._namespaces[ns] = {});
return this._namespaces[ns];
}
return this._cache;
},
// Find the cached model
lookup: function (type, id, ns) {
var cache = this._getCache(ns);
return cache && cache[type + id];
},
// Add a model to the cache if it has not already been set
store: function (model) {
var cache = this._getCache(model._namespace),
key = model.type + model.id;
// Prevent overriding a previously stored model
cache[key] = cache[key] || model;
return this;
},
// Remove a stored model from the cache, return `true` if removed
remove: function (type, id, ns) {
var cache = this._getCache(ns);
if (this.lookup.apply(this, arguments)) {
delete cache[type + id];
return true;
}
return false;
},
// Reset internal cache
clear: function () {
this._cache = {};
this._namespaces = {};
}
});
// Create the default Strict.registry.
Strict.registry = new Registry();
// Strict.Model
// ------------
var Model = Strict.Model = function (attrs, options) {
attrs = attrs || {};
options = options || {};
var modelFound,
opts = _.defaults(options || {}, {
seal: true
});
this._namespace = opts.namespace;
this._initted = false;
this._deps = {};
this._initProperties();
this._initCollections();
this._cache = {};
this._verifyRequired();
this.set(attrs, {silent: true});
this.init.apply(this, arguments);
if (attrs.id) Strict.registry.store(this);
this._previous = _.clone(this.attributes); // Should this be set right away?
this._initted = true;
};
// Attach all inheritable methods to the Model prototype.
_.extend(Model.prototype, Backbone.Events, Mixins, {
idAttribute: 'id',
idDefinition: {
type: 'number',
setOnce: true
},
// stubbed out to be overwritten
init: function () {
return this;
},
// Remove model from the registry and unbind events
remove: function () {
if (this.id) {
Strict.registry.remove(this.type, this.id, this._namespace);
}
this.trigger('remove', this);
this.off();
return this;
},
set: function (key, value, options) {
var self = this,
changing = self._changing,
opts,
changes = [],
newType,
interpretedType,
newVal,
def,
attr,
attrs,
val;
self._changing = true;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (_.isObject(key) || key === null) {
attrs = key;
options = value;
} else {
attrs = {};
attrs[key] = value;
}
opts = options || {};
// For each `set` attribute...
for (attr in attrs) {
val = attrs[attr];
newType = typeof val;
newVal = val;
def = this.definition[attr] || {};
// check type if we have one
if (def.type === 'date') {
if (!_.isDate(val)) {
try {
newVal = (new Date(parseInt(val, 10))).valueOf();
newType = 'date';
} catch (e) {
newType = typeof val;
}
} else {
newType = 'date';
newVal = val.valueOf();
}
} else if (def.type === 'array') {
newType = _.isArray(val) ? 'array' : typeof val;
} else if (def.type === 'object') {
// we have to have a way of supporting "missing" objects.
// Null is an object, but setting a value to undefined
// should work too, IMO. We just override it, in that case.
if (typeof val !== 'object' && _.isUndefined(val)) {
newVal = null;
newType = 'object';
}
}
// If we have a defined type and the new type doesn't match, throw error.
// Unless it's not required and the value is undefined.
if (def.type && def.type !== newType && (!def.required && !_.isUndefined(val))) {
throw new TypeError('Property \'' + attr + '\' must be of type ' + def.type + '. Tried to set ' + val);
}
// if trying to set id after it's already been set
// reject that
if (def.setOnce && def.value !== undefined && !_.isEqual(def.value, newVal)) {
throw new TypeError('Property \'' + key + '\' can only be set once.');
}
// only change if different
if (!_.isEqual(def.value, newVal)) {
self._previous && (self._previous[attr] = def.value);
def.value = newVal;
changes.push(attr);
}
}
_.each(changes, function (key) {
if (!opts.silent) {
self.trigger('change:' + key, self, self[key]);
}
// TODO: ensure that all deps are not undefined before triggering a change event
(self._deps[key] || []).forEach(function (derTrigger) {
// blow away our cache
delete self._cache[derTrigger];
if (!opts.silent) self.trigger('change:' + derTrigger, self, self.derived[derTrigger]);
});
});
// fire general change events
if (changes.length) {
if (!opts.silent) self.trigger('change', self);
}
},
get: function (attr) {
return this[attr];
},
// convenience methods for manipulating array properties
addListVal: function (prop, value, prepend) {
var list = _.clone(this[prop]) || [];
if (!_(list).contains(value)) {
list[prepend ? 'unshift' : 'push'](value);
this[prop] = list;
}
return this;
},
previous: function (attr) {
return attr ? this._previous[attr] : _.clone(this._previous);
},
removeListVal: function (prop, value) {
var list = _.clone(this[prop]) || [];
if (_(list).contains(value)) {
this[prop] = _(list).without(value);
}
return this;
},
hasListVal: function (prop, value) {
return _.contains(this[prop] || [], value);
},
// -----------------------------------------------------------------------
_initCollections: function () {
var coll;
if (!this.collections) return;
for (coll in this.collections) {
this[coll] = new this.collections[coll]();
this[coll].parent = this;
}
},
// Check that all required attributes are present
// TODO: should this throw an error or return boolean?
_verifyRequired: function () {
var attrs = this.attributes;
for (var def in this.definition) {
if (this.definition[def].required && typeof attrs[def] === 'undefined') {
return false;
}
}
return true;
},
_initProperties: function () {
var self = this,
definition = this.definition = {},
val,
prop,
item,
type,
filler;
this.cid = _.uniqueId('model');
function addToDef(name, val, isSession) {
var def = definition[name] = {};
if (_.isString(val)) {
// grab our type if all we've got is a string
type = self._ensureValidType(val);
if (type) def.type = type;
} else {
type = self._ensureValidType(val[0] || val.type);
if (type) def.type = type;
if (val[1] || val.required) def.required = true;
// set default if defined
def.value = !_.isUndefined(val[2]) ? val[2] : val.default;
if (isSession) def.session = true;
if (val.setOnce) def.setOnce = true;
}
}
// loop through given properties
for (item in this.props) {
addToDef(item, this.props[item]);
}
// loop through session props
for (prop in this.session) {
addToDef(prop, this.session[prop], true);
}
// always add "id" as a definition or make sure it's 'setOnce'
if (definition.id) {
definition[this.idAttribute].setOnce = true;
} else {
addToDef(this.idAttribute, this.idDefinition);
}
// register derived properties as part of the definition
this._registerDerived();
this._createGettersSetters();
// freeze attributes used to define object
if (this.session) Object.freeze(this.session);
//if (this.derived) Object.freeze(this.derived);
if (this.props) Object.freeze(this.props);
},
// just makes friendlier errors when trying to define a new model
// only used when setting up original property definitions
_ensureValidType: function (type) {
return _.contains(['string', 'number', 'boolean', 'array', 'object', 'date'], type) ? type : undefined;
},
_validate: function () {
return true;
},
_createGettersSetters: function () {
var item, def, desc, self = this;
// create getters/setters based on definitions
for (item in this.definition) {
def = this.definition[item];
desc = {};
// create our setter
desc.set = function (def, item) {
return function (val, options) {
self.set(item, val);
};
}(def, item);
// create our getter
desc.get = function (def, attributes) {
return function (val) {
if (typeof def.value !== 'undefined') {
if (def.type === 'date') {
return new Date(def.value);
}
return def.value;
}
return;
};
}(def);
// define our property
this.define(item, desc);
}
this.defineGetter('attributes', function () {
var res = {};
for (var item in this.definition) res[item] = this[item];
return res;
});
this.defineGetter('keys', function () {
return Object.keys(this.attributes);
});
this.defineGetter('json', function () {
return JSON.stringify(this._getAttributes(false, true));
});
this.defineGetter('derived', function () {
var res = {};
for (var item in this._derived) res[item] = this._derived[item].fn.apply(this);
return res;
});
this.defineGetter('toTemplate', function () {
return _.extend(this._getAttributes(true), this.derived);
});
},
_getAttributes: function (includeSession, raw) {
var res = {};
for (var item in this.definition) {
if (!includeSession) {
if (!this.definition[item].session) {
res[item] = (raw) ? this.definition[item].value : this[item];
}
} else {
res[item] = (raw) ? this.definition[item].value : this[item];
}
}
return res;
},
// stores an object of arrays that specifies the derivedProperties
// that depend on each attribute
_registerDerived: function () {
var self = this, depList;
if (!this.derived) return;
this._derived = this.derived;
for (var key in this.derived) {
depList = this.derived[key].deps || [];
_.each(depList, function (dep) {
self._deps[dep] = _(self._deps[dep] || []).union([key]);
});
// defined a top-level getter for derived keys
this.define(key, {
get: _.bind(function (key) {
// is this a derived property we should cache?
if (this._derived[key].cache) {
// do we have it?
if (this._cache.hasOwnProperty(key)) {
return this._cache[key];
} else {
return this._cache[key] = this._derived[key].fn.apply(this);
}
} else {
return this._derived[key].fn.apply(this);
}
}, this, key),
set: _.bind(function (key) {
var deps = this._derived[key].deps,
msg = '"' + key + '" is a derived property, you can\'t set it directly.';
if (deps && deps.length) {
throw new TypeError(msg + ' It is dependent on "' + deps.join('" and "') + '".');
} else {
throw new TypeError(msg);
}
}, this, key)
});
}
}
});
// Set up inheritance for the model
Strict.Model.extend = extend;
// Overwrite Backbone.Model so that collections don't need to be modified in Backbone core
Backbone.Model = Strict.Model;
}).call(this);

View File

@ -0,0 +1,245 @@
var Backbone = require('backbone'),
_ = require('underscore'),
templates = require('templates');
// the base view we use to build all our other views
module.exports = Backbone.View.extend({
// ###handleBindings
// This makes it simple to bind model attributes to the view.
// To use it, add a `classBindings` and/or a `contentBindings` attribute
// to your view and call `this.handleBindings()` at the end of your view's
// `render` function. It's also used by `basicRender` which lets you do
// a complete attribute-bound views with just this:
//
// var ProfileView = BaseView.extend({
// template: 'profile',
// contentBindings: {
// 'name': '.name'
// },
// classBindings: {
// 'active': ''
// },
// render: function () {
// this.basicRender();
// return this;
// }
// });
handleBindings: function () {
var self = this;
if (this.contentBindings) {
_.each(this.contentBindings, function (selector, key) {
var func = function () {
var el = (selector.length > 0) ? self.$(selector) : $(self.el);
el.html(self.model[key]);
};
self.listenTo(self.model, 'change:' + key, func);
func();
});
}
if (this.imageBindings) {
_.each(this.imageBindings, function (selector, key) {
var func = function () {
var el = (selector.length > 0) ? self.$(selector) : $(self.el);
el.attr('src', self.model[key]);
};
self.listenTo(self.model, 'change:' + key, func);
func();
});
}
if (this.hrefBindings) {
_.each(this.hrefBindings, function (selector, key) {
var func = function () {
var el = (selector.length > 0) ? self.$(selector) : $(self.el);
el.attr('href', self.model[key]);
};
self.listenTo(self.model, 'change:' + key, func);
func();
});
}
if (this.classBindings) {
_.each(this.classBindings, function (selector, key) {
var func = function () {
var newValue = self.model[key],
prevHash = self.model.previous(),
prev = _.isFunction(prevHash) ? prevHash(key) : prevHash[key],
el = (selector.length > 0) ? self.$(selector) : $(self.el);
if (_.isBoolean(newValue)) {
if (newValue) {
el.addClass(key);
} else {
el.removeClass(key);
}
} else {
if (prev) el.removeClass(prev);
el.addClass(newValue);
}
};
self.listenTo(self.model, 'change:' + key, func);
func();
});
}
if (this.inputBindings) {
_.each(this.inputBindings, function (selector, key) {
var func = function () {
var el = (selector.length > 0) ? self.$(selector) : $(self.el);
el.val(self.model[key]);
};
self.listenTo(self.model, 'change:' + key, func);
func();
});
}
return this;
},
// ###desist
// This is method we used to remove/unbind/destroy the view.
// By default we fade it out this seemed like a reasonable default for realtime apps.
// So things to just magically disappear and to give some visual indication that
// it's going away. You can also pass an options hash `{quick: true}` to remove immediately.
desist: function (opts) {
opts || (opts = {});
_.defaults(opts, {
quick: false,
animate: true,
speed: 300,
animationProps: {
height: 0,
opacity: 0
}
});
var el = $(this.el),
kill = _.bind(this.remove, this);
if (this.interval) {
clearInterval(this.interval);
delete this.interval;
}
if (opts.quick) {
kill();
} else if (opts.animate) {
el.animate(opts.animationProps, {
speed: opts.speed,
complete: kill
});
} else {
setTimeout(kill, opts.speed);
}
},
// ###addReferences
// This is a shortcut for adding reference to specific elements within your view for
// access later. This is avoids excessive DOM queries and gives makes it easier to update
// your view if your template changes. You could argue whether this is worth doing or not,
// but I like it.
// In your `render` method. Use it like so:
//
// render: function () {
// this.basicRender();
// this.addReferences({
// pages: '#pages',
// chat: '#teamChat',
// nav: 'nav#views ul',
// me: '#me',
// cheatSheet: '#cheatSheet',
// omniBox: '#awesomeSauce'
// });
// }
//
// Then later you can access elements by reference like so: `this.$pages`, or `this.$chat`.
addReferences: function (hash) {
for (var item in hash) {
this['$' + item] = $(hash[item], this.el);
}
},
// ###basicRender
// All the usual stuff when I render a view. It assumes that the view has a `template` property
// that is the name of the ICanHaz template. You can also specify the template name by passing
// it an options hash like so: `{templateKey: 'profile'}`.
basicRender: function (opts) {
var newEl;
opts || (opts = {});
_.defaults(opts, {
templateFunc: (typeof this.template === 'string') ? templates[opts.templateKey] : this.template,
context: false
});
newEl = $(opts.templateFunc(opts.contex));
$(this.el).replaceWith(newEl);
this.setElement(newEl);
this.handleBindings();
this.delegateEvents();
},
// ###subViewRender
// This is handy for views within collections when you use `collectomatic`. Just like `basicRender` it assumes
// that the view either has a `template` property or that you pass it an options object with the name of the
// `templateKey` name of the ICanHaz template.
// Additionally, it handles appending or prepending the view to its parent container.
// It takes an options arg where you can optionally specify the `templateKey` and `placement` of the element.
// If your collections is stacked newest first, just use `{plaement: 'prepend'}`.
subViewRender: function (opts) {
opts || (opts = {});
_.defaults(opts, {
placement: 'append',
templateFunc: (typeof this.template === 'string') ? templates[opts.templateKey] : this.template
});
var data = _.isFunction(this.model.toTemplate) ? this.model.toTemplate() : this.model.toTemplate,
newEl = $(opts.templateFunc(opts.context))[0];
if (!this.el.parentNode) {
$(this.containerEl)[opts.placement](newEl);
} else {
$(this.el).replaceWith(newEl);
}
this.setElement(newEl);
this.handleBindings();
},
// ### bindomatic
// Shortcut for listening and triggering
bindomatic: function (object, events, handler, opts) {
var bound = _.bind(handler, this);
this.listenTo(object, events, bound);
if (opts && opts.trigger || opts === true) bound();
},
// ###collectomatic
// Shorthand for rendering collections and their invividual views.
// Just pass it the collection, and the view to use for the items in the
// collection. (anything in the `options` arg just gets passed through to
// view. Again, props to @natevw for this.
collectomatic: function (collection, ViewClass, options, desistOptions) {
var views = {},
self = this,
refreshResetHandler;
function addView(model, collection, opts) {
var matches = self.matchesFilters ? self.matchesFilters(model) : true;
if (matches) {
views[model.cid] = new ViewClass(_({model: model}).extend(options));
views[model.cid].parent = self;
}
}
this.listenTo(collection, 'add', addView);
this.listenTo(collection, 'remove', function (model) {
if (views[model.cid]) {
views[model.cid].desist(desistOptions);
delete views[model.cid];
}
});
this.listenTo(collection, 'move', function () {
_(views).each(function (view) {
view.desist({quick: true});
});
views = {};
collection.each(addView);
});
refreshResetHandler = function (opts) {
_(views).each(function (view) {
view.desist({quick: true});
});
views = {};
collection.each(addView);
};
this.listenTo(collection, 'refresh reset sort', refreshResetHandler);
refreshResetHandler();
}
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,124 @@
/*
WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based
on @visionmedia's Emitter from UI Kit.
Why? I wanted it standalone.
I also wanted support for wildcard emitters like this:
emitter.on('*', function (eventName, other, event, payloads) {
});
emitter.on('somenamespace*', function (eventName, payloads) {
});
Please note that callbacks triggered by wildcard registered events also get
the event name as the first argument.
*/
module.exports = WildEmitter;
function WildEmitter() {
this.callbacks = {};
}
// Listen on the given `event` with `fn`. Store a group name if present.
WildEmitter.prototype.on = function (event, groupName, fn) {
var hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
func._groupName = group;
(this.callbacks[event] = this.callbacks[event] || []).push(func);
return this;
};
// Adds an `event` listener that will be invoked a single
// time then automatically removed.
WildEmitter.prototype.once = function (event, fn) {
var self = this;
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
this.on(event, on);
return this;
};
// Unbinds an entire group
WildEmitter.prototype.releaseGroup = function (groupName) {
var item, i, len, handlers;
for (item in this.callbacks) {
handlers = this.callbacks[item];
for (i = 0, len = handlers.length; i < len; i++) {
if (handlers[i]._groupName === groupName) {
//console.log('removing');
// remove it and shorten the array we're looping through
handlers.splice(i, 1);
i--;
len--;
}
}
}
return this;
};
// Remove the given callback for `event` or all
// registered callbacks.
WildEmitter.prototype.off = function (event, fn) {
var callbacks = this.callbacks[event],
i;
if (!callbacks) return this;
// remove all handlers
if (arguments.length === 1) {
delete this.callbacks[event];
return this;
}
// remove specific handler
i = callbacks.indexOf(fn);
callbacks.splice(i, 1);
return this;
};
// Emit `event` with the given args.
// also calls any `*` handlers
WildEmitter.prototype.emit = function (event) {
var args = [].slice.call(arguments, 1),
callbacks = this.callbacks[event],
specialCallbacks = this.getWildcardCallbacks(event),
i,
len,
item;
if (callbacks) {
for (i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
if (specialCallbacks) {
for (i = 0, len = specialCallbacks.length; i < len; ++i) {
specialCallbacks[i].apply(this, [event].concat(args));
}
}
return this;
};
// Helper for for finding special wildcard event handlers that match the event
WildEmitter.prototype.getWildcardCallbacks = function (eventName) {
var item,
split,
result = [];
for (item in this.callbacks) {
split = item.split('*');
if (item === '*' || (split.length === 2 && eventName.slice(0, split[1].length) === split[1])) {
result = result.concat(this.callbacks[item]);
}
}
return result;
};

View File

@ -0,0 +1,6 @@
form.password
h2 This room requires a password:
p.errorMessage
input.type
button.cancel(type="button") Cancel
button.go(type="submit") Join

View File

@ -0,0 +1,5 @@
div.modalDialog
p To lock the room you need to be logged in and have a <a href="/signup">conversat.io pro</a> account.
button.gopro Go pro!
button.login Login
button.cancel Cancel

View File

@ -0,0 +1,6 @@
form.password
h2 Set a password for this room:
p.errorMessage
input.type
button.cancel(type="button") Cancel
button.go(type="submit") Save

View File

@ -0,0 +1,38 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="16px" height="16px" viewBox="0 0 50 50">
<g>
<path d="M46.715,28.074c-0.012-0.022-0.027-0.044-0.039-0.067c-0.439-0.807-0.982-1.538-1.615-2.17l-8.635-8.634
c-0.035-0.036-0.068-0.066-0.098-0.092c-1.102-1.067-2.439-1.85-3.893-2.282c1.676,1.754,2.785,3.946,3.217,6.358
c0.127,0.723,0.193,1.462,0.193,2.197c0,0.293-0.014,0.602-0.039,0.943l5.381,5.382c0.469,0.469,0.816,1.058,1.002,1.706
c0.109,0.372,0.162,0.759,0.162,1.151c0,0.434-0.064,0.862-0.197,1.273c-0.197,0.618-0.521,1.157-0.967,1.602l-3.508,3.508
c-0.752,0.752-1.77,1.166-2.865,1.166s-2.115-0.414-2.865-1.166l-3.346-3.344l-2.164-2.166l-3.125-3.124
c-0.311-0.311-0.569-0.678-0.765-1.092c-0.26-0.546-0.397-1.159-0.397-1.772c0-0.414,0.061-0.824,0.18-1.217
c0.011-0.035,0.024-0.07,0.038-0.105l0.021-0.057c0.051-0.144,0.098-0.261,0.148-0.368c0.029-0.062,0.06-0.123,0.092-0.184
c0.059-0.111,0.125-0.22,0.202-0.337l0.032-0.048c0.023-0.035,0.046-0.071,0.071-0.105c0.128-0.174,0.251-0.32,0.378-0.445
l1.337-1.338c-0.015-0.159-0.051-0.301-0.109-0.422c-0.056-0.118-0.125-0.219-0.206-0.299L21.213,19.4l-0.23-0.23l-1.541,1.542
c-0.149,0.149-0.298,0.31-0.457,0.493c-0.023,0.026-0.045,0.055-0.068,0.083l-0.05,0.061c-0.105,0.125-0.206,0.252-0.304,0.382
c-0.033,0.043-0.064,0.088-0.097,0.132l-0.019,0.026c-0.096,0.134-0.188,0.27-0.276,0.408l-0.024,0.036
c-0.021,0.033-0.042,0.066-0.063,0.099c-0.103,0.169-0.203,0.341-0.292,0.509l-0.014,0.025l-0.013,0.024
c-0.313,0.596-0.564,1.23-0.747,1.889c-0.064,0.234-0.116,0.45-0.158,0.659c-0.128,0.639-0.193,1.283-0.193,1.924
c0,0.563,0.051,1.13,0.148,1.68c0.343,1.929,1.251,3.674,2.624,5.048l1.799,1.8l2.628,2.626l4.208,4.209
c3.715,3.715,9.76,3.715,13.477,0l3.508-3.509c1.201-1.202,2.059-2.72,2.479-4.393c0.199-0.795,0.301-1.584,0.301-2.346
c0-1.506-0.361-3.01-1.045-4.349c-0.008-0.016-0.016-0.032-0.021-0.049c-0.008-0.013-0.012-0.025-0.02-0.038
C46.744,28.116,46.73,28.096,46.715,28.074z"/>
<path d="M30.398,16.544L28.6,14.745l-2.627-2.626l-4.208-4.209c-3.715-3.714-9.76-3.714-13.476,0.001L4.78,11.419
c-1.202,1.2-2.058,2.72-2.479,4.391C2.102,16.605,2,17.394,2,18.157c0,1.505,0.362,3.008,1.045,4.348
c0.008,0.015,0.016,0.033,0.022,0.049c0.006,0.013,0.011,0.026,0.019,0.039c0.011,0.021,0.023,0.042,0.037,0.065
c0.014,0.022,0.027,0.044,0.04,0.068c0.44,0.808,0.984,1.537,1.616,2.168l8.634,8.634c0.036,0.037,0.068,0.067,0.1,0.093
c1.1,1.067,2.437,1.85,3.891,2.281c-1.675-1.755-2.785-3.946-3.214-6.357c-0.129-0.72-0.196-1.46-0.196-2.197
c0-0.291,0.013-0.6,0.039-0.943l-5.382-5.383c-0.468-0.468-0.815-1.058-1.001-1.706c-0.108-0.372-0.163-0.757-0.163-1.15
c0-0.434,0.067-0.863,0.198-1.274c0.198-0.619,0.522-1.158,0.967-1.601l3.509-3.509c1.554-1.554,4.179-1.554,5.731,0l3.345,3.345
l2.165,2.165l3.124,3.125c0.312,0.311,0.568,0.678,0.766,1.092c0.26,0.545,0.396,1.157,0.396,1.772c0,0.415-0.061,0.824-0.18,1.217
c-0.012,0.036-0.023,0.071-0.037,0.107l-0.021,0.055c-0.051,0.145-0.098,0.261-0.148,0.368c-0.027,0.062-0.061,0.123-0.094,0.184
c-0.059,0.112-0.125,0.225-0.199,0.337l-0.031,0.044c-0.021,0.038-0.047,0.074-0.072,0.108c-0.129,0.174-0.252,0.32-0.377,0.446
l-1.339,1.338c0.015,0.159,0.051,0.301,0.11,0.423c0.056,0.117,0.124,0.219,0.205,0.298l3.124,3.125l0.23,0.229l1.541-1.541
c0.146-0.146,0.297-0.309,0.457-0.493c0.023-0.027,0.049-0.056,0.07-0.084l0.047-0.058c0.105-0.127,0.207-0.254,0.305-0.384
c0.039-0.052,0.076-0.104,0.113-0.157c0.098-0.135,0.189-0.271,0.279-0.408l0.029-0.046l0.055-0.089
c0.105-0.168,0.203-0.339,0.295-0.51l0.012-0.022l0.014-0.025c0.312-0.595,0.564-1.229,0.748-1.888
c0.062-0.228,0.113-0.444,0.156-0.661c0.129-0.637,0.193-1.282,0.193-1.922c0-0.564-0.051-1.13-0.148-1.68
C32.68,19.663,31.771,17.918,30.398,16.544z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,6 @@
form.password
h2 This room requires a password:
p.errorMessage
input.type
button.cancel(type="button") Cancel
button.go(type="submit") Join

View File

@ -0,0 +1,13 @@
.wrap
header
.loggedOut
a.logIn(href="#") Log In
.loggedIn
img.avatar
.name
a(href="/logout") Log Out
section#pages
footer
a#ad(href='http://andbang.com', target='_blank')
a#andyet(href='http://andyet.com', target='_blank')
img(src='http://andyet.com/images/logo.png', width='40')

View File

@ -0,0 +1,12 @@
section.page.create
a(href='/')
h1#logo
img(src='conversatio.png', height='64', width='480', alt='Conversat.io')
h2
span#title Get a room.
p.desc Video chat with up to 6 people.
form#createRoom
input#sessionInput(placeholder='Name the conversation', autofocus='autofocus')
button(type='submit') Lets go!
p.about Requires Chrome or Firefox Nightly with peer connection enabled.<br/> conversat.io uses <a href="https://github.com/henrikjoreteg/SimpleWebRTC">the simple WebRTC library</a> from <a href="http://andyet.com">&yet</a> and so can you.

View File

@ -0,0 +1,47 @@
section.page.talk
a(href='/')
h1#logo
img(src='conversatio.png', height='64', width='480', alt='Conversat.io')
h2
span#title.roomName
h3#roomLink
svg(version="1.1", id="Layer_1", xmlns="http://www.w3.org/2000/svg", xmlns:xlink="http://www.w3.org/1999/xlink", x="0px", y="0px", width="16px", height="16px", viewBox="0 0 50 50")
g
path(d="M46.715,28.074c-0.012-0.022-0.027-0.044-0.039-0.067c-0.439-0.807-0.982-1.538-1.615-2.17l-8.635-8.634c-0.035-0.036-0.068-0.066-0.098-0.092c-1.102-1.067-2.439-1.85-3.893-2.282c1.676,1.754,2.785,3.946,3.217,6.358c0.127,0.723,0.193,1.462,0.193,2.197c0,0.293-0.014,0.602-0.039,0.943l5.381,5.382c0.469,0.469,0.816,1.058,1.002,1.706c0.109,0.372,0.162,0.759,0.162,1.151c0,0.434-0.064,0.862-0.197,1.273c-0.197,0.618-0.521,1.157-0.967,1.602l-3.508,3.508c-0.752,0.752-1.77,1.166-2.865,1.166s-2.115-0.414-2.865-1.166l-3.346-3.344l-2.164-2.166l-3.125-3.124c-0.311-0.311-0.569-0.678-0.765-1.092c-0.26-0.546-0.397-1.159-0.397-1.772c0-0.414,0.061-0.824,0.18-1.217c0.011-0.035,0.024-0.07,0.038-0.105l0.021-0.057c0.051-0.144,0.098-0.261,0.148-0.368c0.029-0.062,0.06-0.123,0.092-0.184c0.059-0.111,0.125-0.22,0.202-0.337l0.032-0.048c0.023-0.035,0.046-0.071,0.071-0.105c0.128-0.174,0.251-0.32,0.378-0.445l1.337-1.338c-0.015-0.159-0.051-0.301-0.109-0.422c-0.056-0.118-0.125-0.219-0.206-0.299L21.213,19.4l-0.23-0.23l-1.541,1.542c-0.149,0.149-0.298,0.31-0.457,0.493c-0.023,0.026-0.045,0.055-0.068,0.083l-0.05,0.061c-0.105,0.125-0.206,0.252-0.304,0.382c-0.033,0.043-0.064,0.088-0.097,0.132l-0.019,0.026c-0.096,0.134-0.188,0.27-0.276,0.408l-0.024,0.036c-0.021,0.033-0.042,0.066-0.063,0.099c-0.103,0.169-0.203,0.341-0.292,0.509l-0.014,0.025l-0.013,0.024c-0.313,0.596-0.564,1.23-0.747,1.889c-0.064,0.234-0.116,0.45-0.158,0.659c-0.128,0.639-0.193,1.283-0.193,1.924c0,0.563,0.051,1.13,0.148,1.68c0.343,1.929,1.251,3.674,2.624,5.048l1.799,1.8l2.628,2.626l4.208,4.209c3.715,3.715,9.76,3.715,13.477,0l3.508-3.509c1.201-1.202,2.059-2.72,2.479-4.393c0.199-0.795,0.301-1.584,0.301-2.346c0-1.506-0.361-3.01-1.045-4.349c-0.008-0.016-0.016-0.032-0.021-0.049c-0.008-0.013-0.012-0.025-0.02-0.038C46.744,28.116,46.73,28.096,46.715,28.074z")
path(d="M30.398,16.544L28.6,14.745l-2.627-2.626l-4.208-4.209c-3.715-3.714-9.76-3.714-13.476,0.001L4.78,11.419c-1.202,1.2-2.058,2.72-2.479,4.391C2.102,16.605,2,17.394,2,18.157c0,1.505,0.362,3.008,1.045,4.348c0.008,0.015,0.016,0.033,0.022,0.049c0.006,0.013,0.011,0.026,0.019,0.039c0.011,0.021,0.023,0.042,0.037,0.065c0.014,0.022,0.027,0.044,0.04,0.068c0.44,0.808,0.984,1.537,1.616,2.168l8.634,8.634c0.036,0.037,0.068,0.067,0.1,0.093c1.1,1.067,2.437,1.85,3.891,2.281c-1.675-1.755-2.785-3.946-3.214-6.357c-0.129-0.72-0.196-1.46-0.196-2.197c0-0.291,0.013-0.6,0.039-0.943l-5.382-5.383c-0.468-0.468-0.815-1.058-1.001-1.706c-0.108-0.372-0.163-0.757-0.163-1.15c0-0.434,0.067-0.863,0.198-1.274c0.198-0.619,0.522-1.158,0.967-1.601l3.509-3.509c1.554-1.554,4.179-1.554,5.731,0l3.345,3.345l2.165,2.165l3.124,3.125c0.312,0.311,0.568,0.678,0.766,1.092c0.26,0.545,0.396,1.157,0.396,1.772c0,0.415-0.061,0.824-0.18,1.217c-0.012,0.036-0.023,0.071-0.037,0.107l-0.021,0.055c-0.051,0.145-0.098,0.261-0.148,0.368c-0.027,0.062-0.061,0.123-0.094,0.184c-0.059,0.112-0.125,0.225-0.199,0.337l-0.031,0.044c-0.021,0.038-0.047,0.074-0.072,0.108c-0.129,0.174-0.252,0.32-0.377,0.446l-1.339,1.338c0.015,0.159,0.051,0.301,0.11,0.423c0.056,0.117,0.124,0.219,0.205,0.298l3.124,3.125l0.23,0.229l1.541-1.541c0.146-0.146,0.297-0.309,0.457-0.493c0.023-0.027,0.049-0.056,0.07-0.084l0.047-0.058c0.105-0.127,0.207-0.254,0.305-0.384c0.039-0.052,0.076-0.104,0.113-0.157c0.098-0.135,0.189-0.271,0.279-0.408l0.029-0.046l0.055-0.089c0.105-0.168,0.203-0.339,0.295-0.51l0.012-0.022l0.014-0.025c0.312-0.595,0.564-1.229,0.748-1.888c0.062-0.228,0.113-0.444,0.156-0.661c0.129-0.637,0.193-1.282,0.193-1.922c0-0.564-0.051-1.13-0.148-1.68C32.68,19.663,31.771,17.918,30.398,16.544z")
span#subTitle #{window.location.origin + '/'}<span class="roomName"></span> <span id="roomKey"></span>
.lockControls
a.unlock(href="#") Unlock Room
a.lock(href="#") Lock Room
video#localVideo
.controls
button#shareScreen
span.share
i(class="ss-icon") windows
| Share screen
span.unshare
i(class="ss-icon") windows
| Unshare screen
button#muteMicrophone
span.mute
i(class="ss-icon") volume
| Mute
span.unmute
i(class="ss-icon") volumehigh
| Unmute
button#pauseVideo
span.pause
i(class="ss-icon") pause
| Pause
span.resume
i(class="ss-icon") play
| Resume
#remotes
#game
aside#instructions(style="position: absolute")
h3 Play lander while you wait for people to join.
p Arrow keys control the ship
p <code>r</code> restarts
p <code>x</code> blows up your ship
p Have fun!
canvas#viewport

View File

@ -0,0 +1 @@
.page

14
dev_config.json Normal file
View File

@ -0,0 +1,14 @@
{
"isDev": true,
"auth": {
"id": "conversat.io-dev",
"secret": "conversat.io-dev-secret"
},
"http": {
"baseUrl": "https://localhost:8000",
"port": 8000
},
"session": {
"secret": "shhhhhh don't tell anyone ok?"
}
}

22
fakekeys/cacert.pem Normal file
View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDpTCCAw6gAwIBAgIJAOrnl6uHMbjUMA0GCSqGSIb3DQEBBQUAMIGUMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCV0ExETAPBgNVBAcTCFJpY2hsYW5kMRUwEwYDVQQK
Ewxjb252ZXJzYXQuaW8xFTATBgNVBAsTDGNvbnZlcnNhdC5pbzEVMBMGA1UEAxMM
Y29udmVyc2F0LmlvMSAwHgYJKoZIhvcNAQkBFhF0ZXN0QGNvbnZlcnNhdC5pbzAe
Fw0xMzA1MDcwNTI2MjFaFw0xNjA1MDYwNTI2MjFaMIGUMQswCQYDVQQGEwJVUzEL
MAkGA1UECBMCV0ExETAPBgNVBAcTCFJpY2hsYW5kMRUwEwYDVQQKEwxjb252ZXJz
YXQuaW8xFTATBgNVBAsTDGNvbnZlcnNhdC5pbzEVMBMGA1UEAxMMY29udmVyc2F0
LmlvMSAwHgYJKoZIhvcNAQkBFhF0ZXN0QGNvbnZlcnNhdC5pbzCBnzANBgkqhkiG
9w0BAQEFAAOBjQAwgYkCgYEA0SlMQdaS1UUP3XFBD9adaEyINBqBLzD5erO5AtjK
6MqL5/xWgs7IL8GIbsCHgOqoGKDSJEpFzEEZrX06QbyTajOgO46VFJmLmlIKna4e
RmeRRiY4ABiESQVraL6sZwmh3JgWMZY9KP58Q5s4CuueVgbKO58KYsa827Fd8e2R
uOUCAwEAAaOB/DCB+TAdBgNVHQ4EFgQU/o6yvozYxQh0Tvtm9lmq59GR9KgwgckG
A1UdIwSBwTCBvoAU/o6yvozYxQh0Tvtm9lmq59GR9KihgZqkgZcwgZQxCzAJBgNV
BAYTAlVTMQswCQYDVQQIEwJXQTERMA8GA1UEBxMIUmljaGxhbmQxFTATBgNVBAoT
DGNvbnZlcnNhdC5pbzEVMBMGA1UECxMMY29udmVyc2F0LmlvMRUwEwYDVQQDEwxj
b252ZXJzYXQuaW8xIDAeBgkqhkiG9w0BCQEWEXRlc3RAY29udmVyc2F0LmlvggkA
6ueXq4cxuNQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCv1JoME18K
ylPqfXbOd4mKeTwKFYsR4rEYtyWje07lX41/CiHvR9+sLevLYZubCvc/LrzWqSgt
+/Eab/5nZmAF7z+iaLTh8SxwuI2bBU7SBQeC+fRgFGLEQ14f10ygNm1sXrt3tqE/
QExxebXWQtFROfNbFeA2h5dxC+0ZDU72kA==
-----END CERTIFICATE-----

16
fakekeys/certificate.pem Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICjTCCAfYCCQC8xCdh8aBfxDANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
VVMxEzARBgNVBAgTCldhc2hpbmd0b24xETAPBgNVBAcTCFJpY2hsYW5kMQ0wCwYD
VQQKFAQmeWV0MQswCQYDVQQLFAImITEVMBMGA1UEAxMMTmF0aGFuIEZyaXR6MSAw
HgYJKoZIhvcNAQkBFhFuYXRoYW5AYW5keWV0Lm5ldDAeFw0xMTEwMTkwNjI2Mzha
Fw0xMTExMTgwNjI2MzhaMIGKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
Z3RvbjERMA8GA1UEBxMIUmljaGxhbmQxDTALBgNVBAoUBCZ5ZXQxCzAJBgNVBAsU
AiYhMRUwEwYDVQQDEwxOYXRoYW4gRnJpdHoxIDAeBgkqhkiG9w0BCQEWEW5hdGhh
bkBhbmR5ZXQubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRKUxB1pLV
RQ/dcUEP1p1oTIg0GoEvMPl6s7kC2Mroyovn/FaCzsgvwYhuwIeA6qgYoNIkSkXM
QRmtfTpBvJNqM6A7jpUUmYuaUgqdrh5GZ5FGJjgAGIRJBWtovqxnCaHcmBYxlj0o
/nxDmzgK655WBso7nwpixrzbsV3x7ZG45QIDAQABMA0GCSqGSIb3DQEBBQUAA4GB
ALeMY0Og6SfSNXzvATyR1BYSjJCG19AwR/vafK4vB6ejta37TGEPOM66BdtxH8J7
T3QuMki9Eqid0zPATOttTlAhBeDGzPOzD4ohJu55PwY0jTJ2+qFUiDKmmCuaUbC6
JCt3LWcZMvkkMfsk1HgyUEKat/Lrs/iaVU6TDMFa52v5
-----END CERTIFICATE-----

15
fakekeys/privatekey.pem Normal file
View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDRKUxB1pLVRQ/dcUEP1p1oTIg0GoEvMPl6s7kC2Mroyovn/FaC
zsgvwYhuwIeA6qgYoNIkSkXMQRmtfTpBvJNqM6A7jpUUmYuaUgqdrh5GZ5FGJjgA
GIRJBWtovqxnCaHcmBYxlj0o/nxDmzgK655WBso7nwpixrzbsV3x7ZG45QIDAQAB
AoGBAJQzUtkDlJ6QhKE+8f6q7nVMZOWmMgqiBOMwHNMrkPpJKcCCRzoAEk/kLSts
N5bcraZlrQARsEr9hZgrtu+FEl1ROdKc6B3bJ5B6FigwY7m8/Z3+YdgwqV6NJGQk
3twY4PoJEdeZ7GX2QnX8RDjyFvLaZ12jiDic30Nrn1gwvOCxAkEA9Dp5r9yg4DT/
V4SE5+NPCJmeV7zwfW3XUQHWD4TaFbOCjnjWB/BnrrjXhvd3VNzwajrJvqq/UiM4
bAG4VLz0CwJBANs+IYm3tYfeP5YsYJVMOJ5TcOAZ3T9jMF+QC9/ObwepW4D1woRr
rCYxe01JyZpqqWnfeIUoJ70QL9uP8AgTrM8CQFFqGNymKL71C9XJ6GBA5zzPsPhA
lM7LSgbIHOrJd8XaNIB4CalV28pj9f0ZC5+vkzlmZZB47RRdh1aB8EfXQWcCQGa8
KI8WLNRsCrPeO6v6OZXHV99Lf2eSnTpKj6XiYBjg/WXiw7G1mseS7Ep9RyE61gQs
mZccB/MKQMLMIhhGz/UCQQDog5KBVaMhwrw1hwZ5gDyZs2YrE75522BnAU1ajQj+
VmTkcBwCtfnbXsWcHnYQnLlvz2Bi9ov2JncmJ5F1kiIw
-----END RSA PRIVATE KEY-----

50
package.json Normal file
View File

@ -0,0 +1,50 @@
{
"name": "conversat.io",
"description": "Easiest/best group video chat service on the planet.",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "git@github.com:andyet/conversat.io.git"
},
"dependencies": {
"express": "3.x.x",
"connect": "2.7.6",
"connect-redis": "1.4.5",
"getconfig": "0.0.5",
"andbang-express-auth": "0.0.9",
"yetify": "0.0.1",
"jade": "0.30.0",
"moonboots": "0.0.3",
"clientmodules": "0.0.5",
"backbone": "1.0.0",
"underscore": "1.4.4",
"strictmodel": "0.0.3",
"precommit-hook": "0.3.4",
"sound-effect-manager": "0.0.5",
"andlog": "0.0.3",
"strictview": "0.0.2",
"system-requirements": "0.0.2",
"webrtc.js": "0.0.3",
"semi-static": "",
"slugger": "0.0.1",
"socket.io": "0.9.14",
"node-uuid": "1.4.0",
"cookie-getter": "0.0.2",
"wildemitter": "0.0.3"
},
"clientmodules": [
"backbone",
"strictmodel",
"underscore",
"sound-effect-manager",
"andlog",
"strictview",
"slugger",
"cookie-getter",
"wildemitter"
],
"clientmodulesDir": "clientapp/modules",
"scripts": {
"postinstall": "node node_modules/clientmodules/install.js"
}
}

10866
public/Box2D.js Normal file

File diff suppressed because it is too large Load Diff

445
public/Box2d.min.js vendored Normal file
View File

@ -0,0 +1,445 @@
var Box2D={};
(function(F,G){function K(){}if(!(Object.prototype.defineProperty instanceof Function)&&Object.prototype.__defineGetter__ instanceof Function&&Object.prototype.__defineSetter__ instanceof Function)Object.defineProperty=function(y,w,A){A.get instanceof Function&&y.__defineGetter__(w,A.get);A.set instanceof Function&&y.__defineSetter__(w,A.set)};F.inherit=function(y,w){K.prototype=w.prototype;y.prototype=new K;y.prototype.constructor=y};F.generateCallback=function(y,w){return function(){w.apply(y,arguments)}};
F.NVector=function(y){if(y===G)y=0;for(var w=Array(y||0),A=0;A<y;++A)w[A]=0;return w};F.is=function(y,w){if(y===null)return false;if(w instanceof Function&&y instanceof w)return true;if(y.constructor.__implements!=G&&y.constructor.__implements[w])return true;return false};F.parseUInt=function(y){return Math.abs(parseInt(y))}})(Box2D);var Vector=Array,Vector_a2j_Number=Box2D.NVector;if(typeof Box2D==="undefined")Box2D={};if(typeof Box2D.Collision==="undefined")Box2D.Collision={};
if(typeof Box2D.Collision.Shapes==="undefined")Box2D.Collision.Shapes={};if(typeof Box2D.Common==="undefined")Box2D.Common={};if(typeof Box2D.Common.Math==="undefined")Box2D.Common.Math={};if(typeof Box2D.Dynamics==="undefined")Box2D.Dynamics={};if(typeof Box2D.Dynamics.Contacts==="undefined")Box2D.Dynamics.Contacts={};if(typeof Box2D.Dynamics.Controllers==="undefined")Box2D.Dynamics.Controllers={};if(typeof Box2D.Dynamics.Joints==="undefined")Box2D.Dynamics.Joints={};
(function(){function F(){F.b2AABB.apply(this,arguments)}function G(){G.b2Bound.apply(this,arguments)}function K(){K.b2BoundValues.apply(this,arguments);this.constructor===K&&this.b2BoundValues.apply(this,arguments)}function y(){y.b2Collision.apply(this,arguments)}function w(){w.b2ContactID.apply(this,arguments);this.constructor===w&&this.b2ContactID.apply(this,arguments)}function A(){A.b2ContactPoint.apply(this,arguments)}function U(){U.b2Distance.apply(this,arguments)}function p(){p.b2DistanceInput.apply(this,
arguments)}function B(){B.b2DistanceOutput.apply(this,arguments)}function Q(){Q.b2DistanceProxy.apply(this,arguments)}function V(){V.b2DynamicTree.apply(this,arguments);this.constructor===V&&this.b2DynamicTree.apply(this,arguments)}function M(){M.b2DynamicTreeBroadPhase.apply(this,arguments)}function L(){L.b2DynamicTreeNode.apply(this,arguments)}function I(){I.b2DynamicTreePair.apply(this,arguments)}function W(){W.b2Manifold.apply(this,arguments);this.constructor===W&&this.b2Manifold.apply(this,arguments)}
function Y(){Y.b2ManifoldPoint.apply(this,arguments);this.constructor===Y&&this.b2ManifoldPoint.apply(this,arguments)}function k(){k.b2Point.apply(this,arguments)}function z(){z.b2RayCastInput.apply(this,arguments);this.constructor===z&&this.b2RayCastInput.apply(this,arguments)}function u(){u.b2RayCastOutput.apply(this,arguments)}function D(){D.b2Segment.apply(this,arguments)}function H(){H.b2SeparationFunction.apply(this,arguments)}function O(){O.b2Simplex.apply(this,arguments);this.constructor===
O&&this.b2Simplex.apply(this,arguments)}function E(){E.b2SimplexCache.apply(this,arguments)}function R(){R.b2SimplexVertex.apply(this,arguments)}function N(){N.b2TimeOfImpact.apply(this,arguments)}function S(){S.b2TOIInput.apply(this,arguments)}function aa(){aa.b2WorldManifold.apply(this,arguments);this.constructor===aa&&this.b2WorldManifold.apply(this,arguments)}function Z(){Z.ClipVertex.apply(this,arguments)}function d(){d.Features.apply(this,arguments)}function h(){h.b2CircleShape.apply(this,arguments);
this.constructor===h&&this.b2CircleShape.apply(this,arguments)}function l(){l.b2EdgeChainDef.apply(this,arguments);this.constructor===l&&this.b2EdgeChainDef.apply(this,arguments)}function j(){j.b2EdgeShape.apply(this,arguments);this.constructor===j&&this.b2EdgeShape.apply(this,arguments)}function o(){o.b2MassData.apply(this,arguments)}function q(){q.b2PolygonShape.apply(this,arguments);this.constructor===q&&this.b2PolygonShape.apply(this,arguments)}function n(){n.b2Shape.apply(this,arguments);this.constructor===
n&&this.b2Shape.apply(this,arguments)}function a(){a.b2Color.apply(this,arguments);this.constructor===a&&this.b2Color.apply(this,arguments)}function c(){c.b2Settings.apply(this,arguments)}function g(){g.b2Mat22.apply(this,arguments);this.constructor===g&&this.b2Mat22.apply(this,arguments)}function b(){b.b2Mat33.apply(this,arguments);this.constructor===b&&this.b2Mat33.apply(this,arguments)}function e(){e.b2Math.apply(this,arguments)}function f(){f.b2Sweep.apply(this,arguments)}function m(){m.b2Transform.apply(this,
arguments);this.constructor===m&&this.b2Transform.apply(this,arguments)}function r(){r.b2Vec2.apply(this,arguments);this.constructor===r&&this.b2Vec2.apply(this,arguments)}function s(){s.b2Vec3.apply(this,arguments);this.constructor===s&&this.b2Vec3.apply(this,arguments)}function v(){v.b2Body.apply(this,arguments);this.constructor===v&&this.b2Body.apply(this,arguments)}function t(){t.b2BodyDef.apply(this,arguments);this.constructor===t&&this.b2BodyDef.apply(this,arguments)}function x(){x.b2ContactFilter.apply(this,
arguments)}function C(){C.b2ContactImpulse.apply(this,arguments)}function J(){J.b2ContactListener.apply(this,arguments)}function T(){T.b2ContactManager.apply(this,arguments);this.constructor===T&&this.b2ContactManager.apply(this,arguments)}function P(){P.b2DebugDraw.apply(this,arguments);this.constructor===P&&this.b2DebugDraw.apply(this,arguments)}function X(){X.b2DestructionListener.apply(this,arguments)}function $(){$.b2FilterData.apply(this,arguments)}function ba(){ba.b2Fixture.apply(this,arguments);
this.constructor===ba&&this.b2Fixture.apply(this,arguments)}function ca(){ca.b2FixtureDef.apply(this,arguments);this.constructor===ca&&this.b2FixtureDef.apply(this,arguments)}function da(){da.b2Island.apply(this,arguments);this.constructor===da&&this.b2Island.apply(this,arguments)}function Fa(){Fa.b2TimeStep.apply(this,arguments)}function ea(){ea.b2World.apply(this,arguments);this.constructor===ea&&this.b2World.apply(this,arguments)}function Ga(){Ga.b2CircleContact.apply(this,arguments)}function fa(){fa.b2Contact.apply(this,
arguments);this.constructor===fa&&this.b2Contact.apply(this,arguments)}function ga(){ga.b2ContactConstraint.apply(this,arguments);this.constructor===ga&&this.b2ContactConstraint.apply(this,arguments)}function Ha(){Ha.b2ContactConstraintPoint.apply(this,arguments)}function Ia(){Ia.b2ContactEdge.apply(this,arguments)}function ha(){ha.b2ContactFactory.apply(this,arguments);this.constructor===ha&&this.b2ContactFactory.apply(this,arguments)}function Ja(){Ja.b2ContactRegister.apply(this,arguments)}function Ka(){Ka.b2ContactResult.apply(this,
arguments)}function ia(){ia.b2ContactSolver.apply(this,arguments);this.constructor===ia&&this.b2ContactSolver.apply(this,arguments)}function La(){La.b2EdgeAndCircleContact.apply(this,arguments)}function ja(){ja.b2NullContact.apply(this,arguments);this.constructor===ja&&this.b2NullContact.apply(this,arguments)}function Ma(){Ma.b2PolyAndCircleContact.apply(this,arguments)}function Na(){Na.b2PolyAndEdgeContact.apply(this,arguments)}function Oa(){Oa.b2PolygonContact.apply(this,arguments)}function ka(){ka.b2PositionSolverManifold.apply(this,
arguments);this.constructor===ka&&this.b2PositionSolverManifold.apply(this,arguments)}function Pa(){Pa.b2BuoyancyController.apply(this,arguments)}function Qa(){Qa.b2ConstantAccelController.apply(this,arguments)}function Ra(){Ra.b2ConstantForceController.apply(this,arguments)}function Sa(){Sa.b2Controller.apply(this,arguments)}function Ta(){Ta.b2ControllerEdge.apply(this,arguments)}function Ua(){Ua.b2GravityController.apply(this,arguments)}function Va(){Va.b2TensorDampingController.apply(this,arguments)}
function la(){la.b2DistanceJoint.apply(this,arguments);this.constructor===la&&this.b2DistanceJoint.apply(this,arguments)}function ma(){ma.b2DistanceJointDef.apply(this,arguments);this.constructor===ma&&this.b2DistanceJointDef.apply(this,arguments)}function na(){na.b2FrictionJoint.apply(this,arguments);this.constructor===na&&this.b2FrictionJoint.apply(this,arguments)}function oa(){oa.b2FrictionJointDef.apply(this,arguments);this.constructor===oa&&this.b2FrictionJointDef.apply(this,arguments)}function pa(){pa.b2GearJoint.apply(this,
arguments);this.constructor===pa&&this.b2GearJoint.apply(this,arguments)}function qa(){qa.b2GearJointDef.apply(this,arguments);this.constructor===qa&&this.b2GearJointDef.apply(this,arguments)}function Wa(){Wa.b2Jacobian.apply(this,arguments)}function ra(){ra.b2Joint.apply(this,arguments);this.constructor===ra&&this.b2Joint.apply(this,arguments)}function sa(){sa.b2JointDef.apply(this,arguments);this.constructor===sa&&this.b2JointDef.apply(this,arguments)}function Xa(){Xa.b2JointEdge.apply(this,arguments)}
function ta(){ta.b2LineJoint.apply(this,arguments);this.constructor===ta&&this.b2LineJoint.apply(this,arguments)}function ua(){ua.b2LineJointDef.apply(this,arguments);this.constructor===ua&&this.b2LineJointDef.apply(this,arguments)}function va(){va.b2MouseJoint.apply(this,arguments);this.constructor===va&&this.b2MouseJoint.apply(this,arguments)}function wa(){wa.b2MouseJointDef.apply(this,arguments);this.constructor===wa&&this.b2MouseJointDef.apply(this,arguments)}function xa(){xa.b2PrismaticJoint.apply(this,
arguments);this.constructor===xa&&this.b2PrismaticJoint.apply(this,arguments)}function ya(){ya.b2PrismaticJointDef.apply(this,arguments);this.constructor===ya&&this.b2PrismaticJointDef.apply(this,arguments)}function za(){za.b2PulleyJoint.apply(this,arguments);this.constructor===za&&this.b2PulleyJoint.apply(this,arguments)}function Aa(){Aa.b2PulleyJointDef.apply(this,arguments);this.constructor===Aa&&this.b2PulleyJointDef.apply(this,arguments)}function Ba(){Ba.b2RevoluteJoint.apply(this,arguments);
this.constructor===Ba&&this.b2RevoluteJoint.apply(this,arguments)}function Ca(){Ca.b2RevoluteJointDef.apply(this,arguments);this.constructor===Ca&&this.b2RevoluteJointDef.apply(this,arguments)}function Da(){Da.b2WeldJoint.apply(this,arguments);this.constructor===Da&&this.b2WeldJoint.apply(this,arguments)}function Ea(){Ea.b2WeldJointDef.apply(this,arguments);this.constructor===Ea&&this.b2WeldJointDef.apply(this,arguments)}Box2D.Collision.IBroadPhase="Box2D.Collision.IBroadPhase";Box2D.Collision.b2AABB=
F;Box2D.Collision.b2Bound=G;Box2D.Collision.b2BoundValues=K;Box2D.Collision.b2Collision=y;Box2D.Collision.b2ContactID=w;Box2D.Collision.b2ContactPoint=A;Box2D.Collision.b2Distance=U;Box2D.Collision.b2DistanceInput=p;Box2D.Collision.b2DistanceOutput=B;Box2D.Collision.b2DistanceProxy=Q;Box2D.Collision.b2DynamicTree=V;Box2D.Collision.b2DynamicTreeBroadPhase=M;Box2D.Collision.b2DynamicTreeNode=L;Box2D.Collision.b2DynamicTreePair=I;Box2D.Collision.b2Manifold=W;Box2D.Collision.b2ManifoldPoint=Y;Box2D.Collision.b2Point=
k;Box2D.Collision.b2RayCastInput=z;Box2D.Collision.b2RayCastOutput=u;Box2D.Collision.b2Segment=D;Box2D.Collision.b2SeparationFunction=H;Box2D.Collision.b2Simplex=O;Box2D.Collision.b2SimplexCache=E;Box2D.Collision.b2SimplexVertex=R;Box2D.Collision.b2TimeOfImpact=N;Box2D.Collision.b2TOIInput=S;Box2D.Collision.b2WorldManifold=aa;Box2D.Collision.ClipVertex=Z;Box2D.Collision.Features=d;Box2D.Collision.Shapes.b2CircleShape=h;Box2D.Collision.Shapes.b2EdgeChainDef=l;Box2D.Collision.Shapes.b2EdgeShape=j;Box2D.Collision.Shapes.b2MassData=
o;Box2D.Collision.Shapes.b2PolygonShape=q;Box2D.Collision.Shapes.b2Shape=n;Box2D.Common.b2internal="Box2D.Common.b2internal";Box2D.Common.b2Color=a;Box2D.Common.b2Settings=c;Box2D.Common.Math.b2Mat22=g;Box2D.Common.Math.b2Mat33=b;Box2D.Common.Math.b2Math=e;Box2D.Common.Math.b2Sweep=f;Box2D.Common.Math.b2Transform=m;Box2D.Common.Math.b2Vec2=r;Box2D.Common.Math.b2Vec3=s;Box2D.Dynamics.b2Body=v;Box2D.Dynamics.b2BodyDef=t;Box2D.Dynamics.b2ContactFilter=x;Box2D.Dynamics.b2ContactImpulse=C;Box2D.Dynamics.b2ContactListener=
J;Box2D.Dynamics.b2ContactManager=T;Box2D.Dynamics.b2DebugDraw=P;Box2D.Dynamics.b2DestructionListener=X;Box2D.Dynamics.b2FilterData=$;Box2D.Dynamics.b2Fixture=ba;Box2D.Dynamics.b2FixtureDef=ca;Box2D.Dynamics.b2Island=da;Box2D.Dynamics.b2TimeStep=Fa;Box2D.Dynamics.b2World=ea;Box2D.Dynamics.Contacts.b2CircleContact=Ga;Box2D.Dynamics.Contacts.b2Contact=fa;Box2D.Dynamics.Contacts.b2ContactConstraint=ga;Box2D.Dynamics.Contacts.b2ContactConstraintPoint=Ha;Box2D.Dynamics.Contacts.b2ContactEdge=Ia;Box2D.Dynamics.Contacts.b2ContactFactory=
ha;Box2D.Dynamics.Contacts.b2ContactRegister=Ja;Box2D.Dynamics.Contacts.b2ContactResult=Ka;Box2D.Dynamics.Contacts.b2ContactSolver=ia;Box2D.Dynamics.Contacts.b2EdgeAndCircleContact=La;Box2D.Dynamics.Contacts.b2NullContact=ja;Box2D.Dynamics.Contacts.b2PolyAndCircleContact=Ma;Box2D.Dynamics.Contacts.b2PolyAndEdgeContact=Na;Box2D.Dynamics.Contacts.b2PolygonContact=Oa;Box2D.Dynamics.Contacts.b2PositionSolverManifold=ka;Box2D.Dynamics.Controllers.b2BuoyancyController=Pa;Box2D.Dynamics.Controllers.b2ConstantAccelController=
Qa;Box2D.Dynamics.Controllers.b2ConstantForceController=Ra;Box2D.Dynamics.Controllers.b2Controller=Sa;Box2D.Dynamics.Controllers.b2ControllerEdge=Ta;Box2D.Dynamics.Controllers.b2GravityController=Ua;Box2D.Dynamics.Controllers.b2TensorDampingController=Va;Box2D.Dynamics.Joints.b2DistanceJoint=la;Box2D.Dynamics.Joints.b2DistanceJointDef=ma;Box2D.Dynamics.Joints.b2FrictionJoint=na;Box2D.Dynamics.Joints.b2FrictionJointDef=oa;Box2D.Dynamics.Joints.b2GearJoint=pa;Box2D.Dynamics.Joints.b2GearJointDef=qa;
Box2D.Dynamics.Joints.b2Jacobian=Wa;Box2D.Dynamics.Joints.b2Joint=ra;Box2D.Dynamics.Joints.b2JointDef=sa;Box2D.Dynamics.Joints.b2JointEdge=Xa;Box2D.Dynamics.Joints.b2LineJoint=ta;Box2D.Dynamics.Joints.b2LineJointDef=ua;Box2D.Dynamics.Joints.b2MouseJoint=va;Box2D.Dynamics.Joints.b2MouseJointDef=wa;Box2D.Dynamics.Joints.b2PrismaticJoint=xa;Box2D.Dynamics.Joints.b2PrismaticJointDef=ya;Box2D.Dynamics.Joints.b2PulleyJoint=za;Box2D.Dynamics.Joints.b2PulleyJointDef=Aa;Box2D.Dynamics.Joints.b2RevoluteJoint=
Ba;Box2D.Dynamics.Joints.b2RevoluteJointDef=Ca;Box2D.Dynamics.Joints.b2WeldJoint=Da;Box2D.Dynamics.Joints.b2WeldJointDef=Ea})();Box2D.postDefs=[];
(function(){var F=Box2D.Collision.Shapes.b2CircleShape,G=Box2D.Collision.Shapes.b2PolygonShape,K=Box2D.Collision.Shapes.b2Shape,y=Box2D.Common.b2Settings,w=Box2D.Common.Math.b2Math,A=Box2D.Common.Math.b2Sweep,U=Box2D.Common.Math.b2Transform,p=Box2D.Common.Math.b2Vec2,B=Box2D.Collision.b2AABB,Q=Box2D.Collision.b2Bound,V=Box2D.Collision.b2BoundValues,M=Box2D.Collision.b2Collision,L=Box2D.Collision.b2ContactID,I=Box2D.Collision.b2ContactPoint,W=Box2D.Collision.b2Distance,Y=Box2D.Collision.b2DistanceInput,
k=Box2D.Collision.b2DistanceOutput,z=Box2D.Collision.b2DistanceProxy,u=Box2D.Collision.b2DynamicTree,D=Box2D.Collision.b2DynamicTreeBroadPhase,H=Box2D.Collision.b2DynamicTreeNode,O=Box2D.Collision.b2DynamicTreePair,E=Box2D.Collision.b2Manifold,R=Box2D.Collision.b2ManifoldPoint,N=Box2D.Collision.b2Point,S=Box2D.Collision.b2RayCastInput,aa=Box2D.Collision.b2RayCastOutput,Z=Box2D.Collision.b2Segment,d=Box2D.Collision.b2SeparationFunction,h=Box2D.Collision.b2Simplex,l=Box2D.Collision.b2SimplexCache,j=
Box2D.Collision.b2SimplexVertex,o=Box2D.Collision.b2TimeOfImpact,q=Box2D.Collision.b2TOIInput,n=Box2D.Collision.b2WorldManifold,a=Box2D.Collision.ClipVertex,c=Box2D.Collision.Features,g=Box2D.Collision.IBroadPhase;B.b2AABB=function(){this.lowerBound=new p;this.upperBound=new p};B.prototype.IsValid=function(){var b=this.upperBound.y-this.lowerBound.y;return b=(b=this.upperBound.x-this.lowerBound.x>=0&&b>=0)&&this.lowerBound.IsValid()&&this.upperBound.IsValid()};B.prototype.GetCenter=function(){return new p((this.lowerBound.x+
this.upperBound.x)/2,(this.lowerBound.y+this.upperBound.y)/2)};B.prototype.GetExtents=function(){return new p((this.upperBound.x-this.lowerBound.x)/2,(this.upperBound.y-this.lowerBound.y)/2)};B.prototype.Contains=function(b){var e=true;return e=(e=(e=(e=e&&this.lowerBound.x<=b.lowerBound.x)&&this.lowerBound.y<=b.lowerBound.y)&&b.upperBound.x<=this.upperBound.x)&&b.upperBound.y<=this.upperBound.y};B.prototype.RayCast=function(b,e){var f=-Number.MAX_VALUE,m=Number.MAX_VALUE,r=e.p1.x,s=e.p1.y,v=e.p2.x-
e.p1.x,t=e.p2.y-e.p1.y,x=Math.abs(t),C=b.normal,J=0,T=0,P=J=0;P=0;if(Math.abs(v)<Number.MIN_VALUE){if(r<this.lowerBound.x||this.upperBound.x<r)return false}else{J=1/v;T=(this.lowerBound.x-r)*J;J=(this.upperBound.x-r)*J;P=-1;if(T>J){P=T;T=J;J=P;P=1}if(T>f){C.x=P;C.y=0;f=T}m=Math.min(m,J);if(f>m)return false}if(x<Number.MIN_VALUE){if(s<this.lowerBound.y||this.upperBound.y<s)return false}else{J=1/t;T=(this.lowerBound.y-s)*J;J=(this.upperBound.y-s)*J;P=-1;if(T>J){P=T;T=J;J=P;P=1}if(T>f){C.y=P;C.x=0;f=
T}m=Math.min(m,J);if(f>m)return false}b.fraction=f;return true};B.prototype.TestOverlap=function(b){var e=b.lowerBound.y-this.upperBound.y,f=this.lowerBound.y-b.upperBound.y;if(b.lowerBound.x-this.upperBound.x>0||e>0)return false;if(this.lowerBound.x-b.upperBound.x>0||f>0)return false;return true};B.Combine=function(b,e){var f=new B;f.Combine(b,e);return f};B.prototype.Combine=function(b,e){this.lowerBound.x=Math.min(b.lowerBound.x,e.lowerBound.x);this.lowerBound.y=Math.min(b.lowerBound.y,e.lowerBound.y);
this.upperBound.x=Math.max(b.upperBound.x,e.upperBound.x);this.upperBound.y=Math.max(b.upperBound.y,e.upperBound.y)};Q.b2Bound=function(){};Q.prototype.IsLower=function(){return(this.value&1)==0};Q.prototype.IsUpper=function(){return(this.value&1)==1};Q.prototype.Swap=function(b){var e=this.value,f=this.proxy,m=this.stabbingCount;this.value=b.value;this.proxy=b.proxy;this.stabbingCount=b.stabbingCount;b.value=e;b.proxy=f;b.stabbingCount=m};V.b2BoundValues=function(){};V.prototype.b2BoundValues=function(){this.lowerValues=
new Vector_a2j_Number;this.lowerValues[0]=0;this.lowerValues[1]=0;this.upperValues=new Vector_a2j_Number;this.upperValues[0]=0;this.upperValues[1]=0};M.b2Collision=function(){};M.ClipSegmentToLine=function(b,e,f,m){if(m===undefined)m=0;var r,s=0;r=e[0];var v=r.v;r=e[1];var t=r.v,x=f.x*v.x+f.y*v.y-m;r=f.x*t.x+f.y*t.y-m;x<=0&&b[s++].Set(e[0]);r<=0&&b[s++].Set(e[1]);if(x*r<0){f=x/(x-r);r=b[s];r=r.v;r.x=v.x+f*(t.x-v.x);r.y=v.y+f*(t.y-v.y);r=b[s];r.id=(x>0?e[0]:e[1]).id;++s}return s};M.EdgeSeparation=
function(b,e,f,m,r){if(f===undefined)f=0;parseInt(b.m_vertexCount);var s=b.m_vertices;b=b.m_normals;var v=parseInt(m.m_vertexCount),t=m.m_vertices,x,C;x=e.R;C=b[f];b=x.col1.x*C.x+x.col2.x*C.y;m=x.col1.y*C.x+x.col2.y*C.y;x=r.R;var J=x.col1.x*b+x.col1.y*m;x=x.col2.x*b+x.col2.y*m;for(var T=0,P=Number.MAX_VALUE,X=0;X<v;++X){C=t[X];C=C.x*J+C.y*x;if(C<P){P=C;T=X}}C=s[f];x=e.R;f=e.position.x+(x.col1.x*C.x+x.col2.x*C.y);e=e.position.y+(x.col1.y*C.x+x.col2.y*C.y);C=t[T];x=r.R;s=r.position.x+(x.col1.x*C.x+
x.col2.x*C.y);r=r.position.y+(x.col1.y*C.x+x.col2.y*C.y);s-=f;r-=e;return s*b+r*m};M.FindMaxSeparation=function(b,e,f,m,r){var s=parseInt(e.m_vertexCount),v=e.m_normals,t,x;x=r.R;t=m.m_centroid;var C=r.position.x+(x.col1.x*t.x+x.col2.x*t.y),J=r.position.y+(x.col1.y*t.x+x.col2.y*t.y);x=f.R;t=e.m_centroid;C-=f.position.x+(x.col1.x*t.x+x.col2.x*t.y);J-=f.position.y+(x.col1.y*t.x+x.col2.y*t.y);x=C*f.R.col1.x+J*f.R.col1.y;J=C*f.R.col2.x+J*f.R.col2.y;C=0;for(var T=-Number.MAX_VALUE,P=0;P<s;++P){t=v[P];
t=t.x*x+t.y*J;if(t>T){T=t;C=P}}v=M.EdgeSeparation(e,f,C,m,r);t=parseInt(C-1>=0?C-1:s-1);x=M.EdgeSeparation(e,f,t,m,r);J=parseInt(C+1<s?C+1:0);T=M.EdgeSeparation(e,f,J,m,r);var X=P=0,$=0;if(x>v&&x>T){$=-1;P=t;X=x}else if(T>v){$=1;P=J;X=T}else{b[0]=C;return v}for(;;){C=$==-1?P-1>=0?P-1:s-1:P+1<s?P+1:0;v=M.EdgeSeparation(e,f,C,m,r);if(v>X){P=C;X=v}else break}b[0]=P;return X};M.FindIncidentEdge=function(b,e,f,m,r,s){if(m===undefined)m=0;parseInt(e.m_vertexCount);var v=e.m_normals,t=parseInt(r.m_vertexCount);
e=r.m_vertices;r=r.m_normals;var x;x=f.R;f=v[m];v=x.col1.x*f.x+x.col2.x*f.y;var C=x.col1.y*f.x+x.col2.y*f.y;x=s.R;f=x.col1.x*v+x.col1.y*C;C=x.col2.x*v+x.col2.y*C;v=f;x=0;for(var J=Number.MAX_VALUE,T=0;T<t;++T){f=r[T];f=v*f.x+C*f.y;if(f<J){J=f;x=T}}r=parseInt(x);v=parseInt(r+1<t?r+1:0);t=b[0];f=e[r];x=s.R;t.v.x=s.position.x+(x.col1.x*f.x+x.col2.x*f.y);t.v.y=s.position.y+(x.col1.y*f.x+x.col2.y*f.y);t.id.features.referenceEdge=m;t.id.features.incidentEdge=r;t.id.features.incidentVertex=0;t=b[1];f=e[v];
x=s.R;t.v.x=s.position.x+(x.col1.x*f.x+x.col2.x*f.y);t.v.y=s.position.y+(x.col1.y*f.x+x.col2.y*f.y);t.id.features.referenceEdge=m;t.id.features.incidentEdge=v;t.id.features.incidentVertex=1};M.MakeClipPointVector=function(){var b=new Vector(2);b[0]=new a;b[1]=new a;return b};M.CollidePolygons=function(b,e,f,m,r){var s;b.m_pointCount=0;var v=e.m_radius+m.m_radius;s=0;M.s_edgeAO[0]=s;var t=M.FindMaxSeparation(M.s_edgeAO,e,f,m,r);s=M.s_edgeAO[0];if(!(t>v)){var x=0;M.s_edgeBO[0]=x;var C=M.FindMaxSeparation(M.s_edgeBO,
m,r,e,f);x=M.s_edgeBO[0];if(!(C>v)){var J=0,T=0;if(C>0.98*t+0.0010){t=m;m=e;e=r;f=f;J=x;b.m_type=E.e_faceB;T=1}else{t=e;m=m;e=f;f=r;J=s;b.m_type=E.e_faceA;T=0}s=M.s_incidentEdge;M.FindIncidentEdge(s,t,e,J,m,f);x=parseInt(t.m_vertexCount);r=t.m_vertices;t=r[J];var P;P=J+1<x?r[parseInt(J+1)]:r[0];J=M.s_localTangent;J.Set(P.x-t.x,P.y-t.y);J.Normalize();r=M.s_localNormal;r.x=J.y;r.y=-J.x;m=M.s_planePoint;m.Set(0.5*(t.x+P.x),0.5*(t.y+P.y));C=M.s_tangent;x=e.R;C.x=x.col1.x*J.x+x.col2.x*J.y;C.y=x.col1.y*
J.x+x.col2.y*J.y;var X=M.s_tangent2;X.x=-C.x;X.y=-C.y;J=M.s_normal;J.x=C.y;J.y=-C.x;var $=M.s_v11,ba=M.s_v12;$.x=e.position.x+(x.col1.x*t.x+x.col2.x*t.y);$.y=e.position.y+(x.col1.y*t.x+x.col2.y*t.y);ba.x=e.position.x+(x.col1.x*P.x+x.col2.x*P.y);ba.y=e.position.y+(x.col1.y*P.x+x.col2.y*P.y);e=J.x*$.x+J.y*$.y;x=C.x*ba.x+C.y*ba.y+v;P=M.s_clipPoints1;t=M.s_clipPoints2;ba=0;ba=M.ClipSegmentToLine(P,s,X,-C.x*$.x-C.y*$.y+v);if(!(ba<2)){ba=M.ClipSegmentToLine(t,P,C,x);if(!(ba<2)){b.m_localPlaneNormal.SetV(r);
b.m_localPoint.SetV(m);for(m=r=0;m<y.b2_maxManifoldPoints;++m){s=t[m];if(J.x*s.v.x+J.y*s.v.y-e<=v){C=b.m_points[r];x=f.R;X=s.v.x-f.position.x;$=s.v.y-f.position.y;C.m_localPoint.x=X*x.col1.x+$*x.col1.y;C.m_localPoint.y=X*x.col2.x+$*x.col2.y;C.m_id.Set(s.id);C.m_id.features.flip=T;++r}}b.m_pointCount=r}}}}};M.CollideCircles=function(b,e,f,m,r){b.m_pointCount=0;var s,v;s=f.R;v=e.m_p;var t=f.position.x+(s.col1.x*v.x+s.col2.x*v.y);f=f.position.y+(s.col1.y*v.x+s.col2.y*v.y);s=r.R;v=m.m_p;t=r.position.x+
(s.col1.x*v.x+s.col2.x*v.y)-t;r=r.position.y+(s.col1.y*v.x+s.col2.y*v.y)-f;s=e.m_radius+m.m_radius;if(!(t*t+r*r>s*s)){b.m_type=E.e_circles;b.m_localPoint.SetV(e.m_p);b.m_localPlaneNormal.SetZero();b.m_pointCount=1;b.m_points[0].m_localPoint.SetV(m.m_p);b.m_points[0].m_id.key=0}};M.CollidePolygonAndCircle=function(b,e,f,m,r){var s=b.m_pointCount=0,v=0,t,x;x=r.R;t=m.m_p;var C=r.position.y+(x.col1.y*t.x+x.col2.y*t.y);s=r.position.x+(x.col1.x*t.x+x.col2.x*t.y)-f.position.x;v=C-f.position.y;x=f.R;f=s*
x.col1.x+v*x.col1.y;x=s*x.col2.x+v*x.col2.y;var J=0;C=-Number.MAX_VALUE;r=e.m_radius+m.m_radius;var T=parseInt(e.m_vertexCount),P=e.m_vertices;e=e.m_normals;for(var X=0;X<T;++X){t=P[X];s=f-t.x;v=x-t.y;t=e[X];s=t.x*s+t.y*v;if(s>r)return;if(s>C){C=s;J=X}}s=parseInt(J);v=parseInt(s+1<T?s+1:0);t=P[s];P=P[v];if(C<Number.MIN_VALUE){b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.SetV(e[J]);b.m_localPoint.x=0.5*(t.x+P.x);b.m_localPoint.y=0.5*(t.y+P.y)}else{C=(f-P.x)*(t.x-P.x)+(x-P.y)*(t.y-P.y);
if((f-t.x)*(P.x-t.x)+(x-t.y)*(P.y-t.y)<=0){if((f-t.x)*(f-t.x)+(x-t.y)*(x-t.y)>r*r)return;b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.x=f-t.x;b.m_localPlaneNormal.y=x-t.y;b.m_localPlaneNormal.Normalize();b.m_localPoint.SetV(t)}else if(C<=0){if((f-P.x)*(f-P.x)+(x-P.y)*(x-P.y)>r*r)return;b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.x=f-P.x;b.m_localPlaneNormal.y=x-P.y;b.m_localPlaneNormal.Normalize();b.m_localPoint.SetV(P)}else{J=0.5*(t.x+P.x);t=0.5*(t.y+P.y);C=(f-J)*e[s].x+
(x-t)*e[s].y;if(C>r)return;b.m_pointCount=1;b.m_type=E.e_faceA;b.m_localPlaneNormal.x=e[s].x;b.m_localPlaneNormal.y=e[s].y;b.m_localPlaneNormal.Normalize();b.m_localPoint.Set(J,t)}}b.m_points[0].m_localPoint.SetV(m.m_p);b.m_points[0].m_id.key=0};M.TestOverlap=function(b,e){var f=e.lowerBound,m=b.upperBound,r=f.x-m.x,s=f.y-m.y;f=b.lowerBound;m=e.upperBound;var v=f.y-m.y;if(r>0||s>0)return false;if(f.x-m.x>0||v>0)return false;return true};Box2D.postDefs.push(function(){Box2D.Collision.b2Collision.s_incidentEdge=
M.MakeClipPointVector();Box2D.Collision.b2Collision.s_clipPoints1=M.MakeClipPointVector();Box2D.Collision.b2Collision.s_clipPoints2=M.MakeClipPointVector();Box2D.Collision.b2Collision.s_edgeAO=new Vector_a2j_Number(1);Box2D.Collision.b2Collision.s_edgeBO=new Vector_a2j_Number(1);Box2D.Collision.b2Collision.s_localTangent=new p;Box2D.Collision.b2Collision.s_localNormal=new p;Box2D.Collision.b2Collision.s_planePoint=new p;Box2D.Collision.b2Collision.s_normal=new p;Box2D.Collision.b2Collision.s_tangent=
new p;Box2D.Collision.b2Collision.s_tangent2=new p;Box2D.Collision.b2Collision.s_v11=new p;Box2D.Collision.b2Collision.s_v12=new p;Box2D.Collision.b2Collision.b2CollidePolyTempVec=new p;Box2D.Collision.b2Collision.b2_nullFeature=255});L.b2ContactID=function(){this.features=new c};L.prototype.b2ContactID=function(){this.features._m_id=this};L.prototype.Set=function(b){this.key=b._key};L.prototype.Copy=function(){var b=new L;b.key=this.key;return b};Object.defineProperty(L.prototype,"key",{enumerable:false,
configurable:true,get:function(){return this._key}});Object.defineProperty(L.prototype,"key",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._key=b;this.features._referenceEdge=this._key&255;this.features._incidentEdge=(this._key&65280)>>8&255;this.features._incidentVertex=(this._key&16711680)>>16&255;this.features._flip=(this._key&4278190080)>>24&255}});I.b2ContactPoint=function(){this.position=new p;this.velocity=new p;this.normal=new p;this.id=new L};W.b2Distance=
function(){};W.Distance=function(b,e,f){++W.b2_gjkCalls;var m=f.proxyA,r=f.proxyB,s=f.transformA,v=f.transformB,t=W.s_simplex;t.ReadCache(e,m,s,r,v);var x=t.m_vertices,C=W.s_saveA,J=W.s_saveB,T=0;t.GetClosestPoint().LengthSquared();for(var P=0,X,$=0;$<20;){T=t.m_count;for(P=0;P<T;P++){C[P]=x[P].indexA;J[P]=x[P].indexB}switch(t.m_count){case 1:break;case 2:t.Solve2();break;case 3:t.Solve3();break;default:y.b2Assert(false)}if(t.m_count==3)break;X=t.GetClosestPoint();X.LengthSquared();P=t.GetSearchDirection();
if(P.LengthSquared()<Number.MIN_VALUE*Number.MIN_VALUE)break;X=x[t.m_count];X.indexA=m.GetSupport(w.MulTMV(s.R,P.GetNegative()));X.wA=w.MulX(s,m.GetVertex(X.indexA));X.indexB=r.GetSupport(w.MulTMV(v.R,P));X.wB=w.MulX(v,r.GetVertex(X.indexB));X.w=w.SubtractVV(X.wB,X.wA);++$;++W.b2_gjkIters;var ba=false;for(P=0;P<T;P++)if(X.indexA==C[P]&&X.indexB==J[P]){ba=true;break}if(ba)break;++t.m_count}W.b2_gjkMaxIters=w.Max(W.b2_gjkMaxIters,$);t.GetWitnessPoints(b.pointA,b.pointB);b.distance=w.SubtractVV(b.pointA,
b.pointB).Length();b.iterations=$;t.WriteCache(e);if(f.useRadii){e=m.m_radius;r=r.m_radius;if(b.distance>e+r&&b.distance>Number.MIN_VALUE){b.distance-=e+r;f=w.SubtractVV(b.pointB,b.pointA);f.Normalize();b.pointA.x+=e*f.x;b.pointA.y+=e*f.y;b.pointB.x-=r*f.x;b.pointB.y-=r*f.y}else{X=new p;X.x=0.5*(b.pointA.x+b.pointB.x);X.y=0.5*(b.pointA.y+b.pointB.y);b.pointA.x=b.pointB.x=X.x;b.pointA.y=b.pointB.y=X.y;b.distance=0}}};Box2D.postDefs.push(function(){Box2D.Collision.b2Distance.s_simplex=new h;Box2D.Collision.b2Distance.s_saveA=
new Vector_a2j_Number(3);Box2D.Collision.b2Distance.s_saveB=new Vector_a2j_Number(3)});Y.b2DistanceInput=function(){};k.b2DistanceOutput=function(){this.pointA=new p;this.pointB=new p};z.b2DistanceProxy=function(){};z.prototype.Set=function(b){switch(b.GetType()){case K.e_circleShape:b=b instanceof F?b:null;this.m_vertices=new Vector(1,true);this.m_vertices[0]=b.m_p;this.m_count=1;this.m_radius=b.m_radius;break;case K.e_polygonShape:b=b instanceof G?b:null;this.m_vertices=b.m_vertices;this.m_count=
b.m_vertexCount;this.m_radius=b.m_radius;break;default:y.b2Assert(false)}};z.prototype.GetSupport=function(b){for(var e=0,f=this.m_vertices[0].x*b.x+this.m_vertices[0].y*b.y,m=1;m<this.m_count;++m){var r=this.m_vertices[m].x*b.x+this.m_vertices[m].y*b.y;if(r>f){e=m;f=r}}return e};z.prototype.GetSupportVertex=function(b){for(var e=0,f=this.m_vertices[0].x*b.x+this.m_vertices[0].y*b.y,m=1;m<this.m_count;++m){var r=this.m_vertices[m].x*b.x+this.m_vertices[m].y*b.y;if(r>f){e=m;f=r}}return this.m_vertices[e]};
z.prototype.GetVertexCount=function(){return this.m_count};z.prototype.GetVertex=function(b){if(b===undefined)b=0;y.b2Assert(0<=b&&b<this.m_count);return this.m_vertices[b]};u.b2DynamicTree=function(){};u.prototype.b2DynamicTree=function(){this.m_freeList=this.m_root=null;this.m_insertionCount=this.m_path=0};u.prototype.CreateProxy=function(b,e){var f=this.AllocateNode(),m=y.b2_aabbExtension,r=y.b2_aabbExtension;f.aabb.lowerBound.x=b.lowerBound.x-m;f.aabb.lowerBound.y=b.lowerBound.y-r;f.aabb.upperBound.x=
b.upperBound.x+m;f.aabb.upperBound.y=b.upperBound.y+r;f.userData=e;this.InsertLeaf(f);return f};u.prototype.DestroyProxy=function(b){this.RemoveLeaf(b);this.FreeNode(b)};u.prototype.MoveProxy=function(b,e,f){y.b2Assert(b.IsLeaf());if(b.aabb.Contains(e))return false;this.RemoveLeaf(b);var m=y.b2_aabbExtension+y.b2_aabbMultiplier*(f.x>0?f.x:-f.x);f=y.b2_aabbExtension+y.b2_aabbMultiplier*(f.y>0?f.y:-f.y);b.aabb.lowerBound.x=e.lowerBound.x-m;b.aabb.lowerBound.y=e.lowerBound.y-f;b.aabb.upperBound.x=e.upperBound.x+
m;b.aabb.upperBound.y=e.upperBound.y+f;this.InsertLeaf(b);return true};u.prototype.Rebalance=function(b){if(b===undefined)b=0;if(this.m_root!=null)for(var e=0;e<b;e++){for(var f=this.m_root,m=0;f.IsLeaf()==false;){f=this.m_path>>m&1?f.child2:f.child1;m=m+1&31}++this.m_path;this.RemoveLeaf(f);this.InsertLeaf(f)}};u.prototype.GetFatAABB=function(b){return b.aabb};u.prototype.GetUserData=function(b){return b.userData};u.prototype.Query=function(b,e){if(this.m_root!=null){var f=new Vector,m=0;for(f[m++]=
this.m_root;m>0;){var r=f[--m];if(r.aabb.TestOverlap(e))if(r.IsLeaf()){if(!b(r))break}else{f[m++]=r.child1;f[m++]=r.child2}}}};u.prototype.RayCast=function(b,e){if(this.m_root!=null){var f=e.p1,m=e.p2,r=w.SubtractVV(f,m);r.Normalize();r=w.CrossFV(1,r);var s=w.AbsV(r),v=e.maxFraction,t=new B,x=0,C=0;x=f.x+v*(m.x-f.x);C=f.y+v*(m.y-f.y);t.lowerBound.x=Math.min(f.x,x);t.lowerBound.y=Math.min(f.y,C);t.upperBound.x=Math.max(f.x,x);t.upperBound.y=Math.max(f.y,C);var J=new Vector,T=0;for(J[T++]=this.m_root;T>
0;){v=J[--T];if(v.aabb.TestOverlap(t)!=false){x=v.aabb.GetCenter();C=v.aabb.GetExtents();if(!(Math.abs(r.x*(f.x-x.x)+r.y*(f.y-x.y))-s.x*C.x-s.y*C.y>0))if(v.IsLeaf()){x=new S;x.p1=e.p1;x.p2=e.p2;x.maxFraction=e.maxFraction;v=b(x,v);if(v==0)break;if(v>0){x=f.x+v*(m.x-f.x);C=f.y+v*(m.y-f.y);t.lowerBound.x=Math.min(f.x,x);t.lowerBound.y=Math.min(f.y,C);t.upperBound.x=Math.max(f.x,x);t.upperBound.y=Math.max(f.y,C)}}else{J[T++]=v.child1;J[T++]=v.child2}}}}};u.prototype.AllocateNode=function(){if(this.m_freeList){var b=
this.m_freeList;this.m_freeList=b.parent;b.parent=null;b.child1=null;b.child2=null;return b}return new H};u.prototype.FreeNode=function(b){b.parent=this.m_freeList;this.m_freeList=b};u.prototype.InsertLeaf=function(b){++this.m_insertionCount;if(this.m_root==null){this.m_root=b;this.m_root.parent=null}else{var e=b.aabb.GetCenter(),f=this.m_root;if(f.IsLeaf()==false){do{var m=f.child1;f=f.child2;f=Math.abs((m.aabb.lowerBound.x+m.aabb.upperBound.x)/2-e.x)+Math.abs((m.aabb.lowerBound.y+m.aabb.upperBound.y)/
2-e.y)<Math.abs((f.aabb.lowerBound.x+f.aabb.upperBound.x)/2-e.x)+Math.abs((f.aabb.lowerBound.y+f.aabb.upperBound.y)/2-e.y)?m:f}while(f.IsLeaf()==false)}e=f.parent;m=this.AllocateNode();m.parent=e;m.userData=null;m.aabb.Combine(b.aabb,f.aabb);if(e){if(f.parent.child1==f)e.child1=m;else e.child2=m;m.child1=f;m.child2=b;f.parent=m;b.parent=m;do{if(e.aabb.Contains(m.aabb))break;e.aabb.Combine(e.child1.aabb,e.child2.aabb);m=e;e=e.parent}while(e)}else{m.child1=f;m.child2=b;f.parent=m;this.m_root=b.parent=
m}}};u.prototype.RemoveLeaf=function(b){if(b==this.m_root)this.m_root=null;else{var e=b.parent,f=e.parent;b=e.child1==b?e.child2:e.child1;if(f){if(f.child1==e)f.child1=b;else f.child2=b;b.parent=f;for(this.FreeNode(e);f;){e=f.aabb;f.aabb=B.Combine(f.child1.aabb,f.child2.aabb);if(e.Contains(f.aabb))break;f=f.parent}}else{this.m_root=b;b.parent=null;this.FreeNode(e)}}};D.b2DynamicTreeBroadPhase=function(){this.m_tree=new u;this.m_moveBuffer=new Vector;this.m_pairBuffer=new Vector;this.m_pairCount=0};
D.prototype.CreateProxy=function(b,e){var f=this.m_tree.CreateProxy(b,e);++this.m_proxyCount;this.BufferMove(f);return f};D.prototype.DestroyProxy=function(b){this.UnBufferMove(b);--this.m_proxyCount;this.m_tree.DestroyProxy(b)};D.prototype.MoveProxy=function(b,e,f){this.m_tree.MoveProxy(b,e,f)&&this.BufferMove(b)};D.prototype.TestOverlap=function(b,e){var f=this.m_tree.GetFatAABB(b),m=this.m_tree.GetFatAABB(e);return f.TestOverlap(m)};D.prototype.GetUserData=function(b){return this.m_tree.GetUserData(b)};
D.prototype.GetFatAABB=function(b){return this.m_tree.GetFatAABB(b)};D.prototype.GetProxyCount=function(){return this.m_proxyCount};D.prototype.UpdatePairs=function(b){var e=this;var f=e.m_pairCount=0,m;for(f=0;f<e.m_moveBuffer.length;++f){m=e.m_moveBuffer[f];var r=e.m_tree.GetFatAABB(m);e.m_tree.Query(function(t){if(t==m)return true;if(e.m_pairCount==e.m_pairBuffer.length)e.m_pairBuffer[e.m_pairCount]=new O;var x=e.m_pairBuffer[e.m_pairCount];x.proxyA=t<m?t:m;x.proxyB=t>=m?t:m;++e.m_pairCount;return true},
r)}for(f=e.m_moveBuffer.length=0;f<e.m_pairCount;){r=e.m_pairBuffer[f];var s=e.m_tree.GetUserData(r.proxyA),v=e.m_tree.GetUserData(r.proxyB);b(s,v);for(++f;f<e.m_pairCount;){s=e.m_pairBuffer[f];if(s.proxyA!=r.proxyA||s.proxyB!=r.proxyB)break;++f}}};D.prototype.Query=function(b,e){this.m_tree.Query(b,e)};D.prototype.RayCast=function(b,e){this.m_tree.RayCast(b,e)};D.prototype.Validate=function(){};D.prototype.Rebalance=function(b){if(b===undefined)b=0;this.m_tree.Rebalance(b)};D.prototype.BufferMove=
function(b){this.m_moveBuffer[this.m_moveBuffer.length]=b};D.prototype.UnBufferMove=function(b){this.m_moveBuffer.splice(parseInt(this.m_moveBuffer.indexOf(b)),1)};D.prototype.ComparePairs=function(){return 0};D.__implements={};D.__implements[g]=true;H.b2DynamicTreeNode=function(){this.aabb=new B};H.prototype.IsLeaf=function(){return this.child1==null};O.b2DynamicTreePair=function(){};E.b2Manifold=function(){this.m_pointCount=0};E.prototype.b2Manifold=function(){this.m_points=new Vector(y.b2_maxManifoldPoints);
for(var b=0;b<y.b2_maxManifoldPoints;b++)this.m_points[b]=new R;this.m_localPlaneNormal=new p;this.m_localPoint=new p};E.prototype.Reset=function(){for(var b=0;b<y.b2_maxManifoldPoints;b++)(this.m_points[b]instanceof R?this.m_points[b]:null).Reset();this.m_localPlaneNormal.SetZero();this.m_localPoint.SetZero();this.m_pointCount=this.m_type=0};E.prototype.Set=function(b){this.m_pointCount=b.m_pointCount;for(var e=0;e<y.b2_maxManifoldPoints;e++)(this.m_points[e]instanceof R?this.m_points[e]:null).Set(b.m_points[e]);
this.m_localPlaneNormal.SetV(b.m_localPlaneNormal);this.m_localPoint.SetV(b.m_localPoint);this.m_type=b.m_type};E.prototype.Copy=function(){var b=new E;b.Set(this);return b};Box2D.postDefs.push(function(){Box2D.Collision.b2Manifold.e_circles=1;Box2D.Collision.b2Manifold.e_faceA=2;Box2D.Collision.b2Manifold.e_faceB=4});R.b2ManifoldPoint=function(){this.m_localPoint=new p;this.m_id=new L};R.prototype.b2ManifoldPoint=function(){this.Reset()};R.prototype.Reset=function(){this.m_localPoint.SetZero();this.m_tangentImpulse=
this.m_normalImpulse=0;this.m_id.key=0};R.prototype.Set=function(b){this.m_localPoint.SetV(b.m_localPoint);this.m_normalImpulse=b.m_normalImpulse;this.m_tangentImpulse=b.m_tangentImpulse;this.m_id.Set(b.m_id)};N.b2Point=function(){this.p=new p};N.prototype.Support=function(){return this.p};N.prototype.GetFirstVertex=function(){return this.p};S.b2RayCastInput=function(){this.p1=new p;this.p2=new p};S.prototype.b2RayCastInput=function(b,e,f){if(b===undefined)b=null;if(e===undefined)e=null;if(f===undefined)f=
1;b&&this.p1.SetV(b);e&&this.p2.SetV(e);this.maxFraction=f};aa.b2RayCastOutput=function(){this.normal=new p};Z.b2Segment=function(){this.p1=new p;this.p2=new p};Z.prototype.TestSegment=function(b,e,f,m){if(m===undefined)m=0;var r=f.p1,s=f.p2.x-r.x,v=f.p2.y-r.y;f=this.p2.y-this.p1.y;var t=-(this.p2.x-this.p1.x),x=100*Number.MIN_VALUE,C=-(s*f+v*t);if(C>x){var J=r.x-this.p1.x,T=r.y-this.p1.y;r=J*f+T*t;if(0<=r&&r<=m*C){m=-s*T+v*J;if(-x*C<=m&&m<=C*(1+x)){r/=C;m=Math.sqrt(f*f+t*t);f/=m;t/=m;b[0]=r;e.Set(f,
t);return true}}}return false};Z.prototype.Extend=function(b){this.ExtendForward(b);this.ExtendBackward(b)};Z.prototype.ExtendForward=function(b){var e=this.p2.x-this.p1.x,f=this.p2.y-this.p1.y;b=Math.min(e>0?(b.upperBound.x-this.p1.x)/e:e<0?(b.lowerBound.x-this.p1.x)/e:Number.POSITIVE_INFINITY,f>0?(b.upperBound.y-this.p1.y)/f:f<0?(b.lowerBound.y-this.p1.y)/f:Number.POSITIVE_INFINITY);this.p2.x=this.p1.x+e*b;this.p2.y=this.p1.y+f*b};Z.prototype.ExtendBackward=function(b){var e=-this.p2.x+this.p1.x,
f=-this.p2.y+this.p1.y;b=Math.min(e>0?(b.upperBound.x-this.p2.x)/e:e<0?(b.lowerBound.x-this.p2.x)/e:Number.POSITIVE_INFINITY,f>0?(b.upperBound.y-this.p2.y)/f:f<0?(b.lowerBound.y-this.p2.y)/f:Number.POSITIVE_INFINITY);this.p1.x=this.p2.x+e*b;this.p1.y=this.p2.y+f*b};d.b2SeparationFunction=function(){this.m_localPoint=new p;this.m_axis=new p};d.prototype.Initialize=function(b,e,f,m,r){this.m_proxyA=e;this.m_proxyB=m;var s=parseInt(b.count);y.b2Assert(0<s&&s<3);var v,t,x,C,J=C=x=m=e=0,T=0;J=0;if(s==
1){this.m_type=d.e_points;v=this.m_proxyA.GetVertex(b.indexA[0]);t=this.m_proxyB.GetVertex(b.indexB[0]);s=v;b=f.R;e=f.position.x+(b.col1.x*s.x+b.col2.x*s.y);m=f.position.y+(b.col1.y*s.x+b.col2.y*s.y);s=t;b=r.R;x=r.position.x+(b.col1.x*s.x+b.col2.x*s.y);C=r.position.y+(b.col1.y*s.x+b.col2.y*s.y);this.m_axis.x=x-e;this.m_axis.y=C-m;this.m_axis.Normalize()}else{if(b.indexB[0]==b.indexB[1]){this.m_type=d.e_faceA;e=this.m_proxyA.GetVertex(b.indexA[0]);m=this.m_proxyA.GetVertex(b.indexA[1]);t=this.m_proxyB.GetVertex(b.indexB[0]);
this.m_localPoint.x=0.5*(e.x+m.x);this.m_localPoint.y=0.5*(e.y+m.y);this.m_axis=w.CrossVF(w.SubtractVV(m,e),1);this.m_axis.Normalize();s=this.m_axis;b=f.R;J=b.col1.x*s.x+b.col2.x*s.y;T=b.col1.y*s.x+b.col2.y*s.y;s=this.m_localPoint;b=f.R;e=f.position.x+(b.col1.x*s.x+b.col2.x*s.y);m=f.position.y+(b.col1.y*s.x+b.col2.y*s.y);s=t;b=r.R;x=r.position.x+(b.col1.x*s.x+b.col2.x*s.y);C=r.position.y+(b.col1.y*s.x+b.col2.y*s.y);J=(x-e)*J+(C-m)*T}else if(b.indexA[0]==b.indexA[0]){this.m_type=d.e_faceB;x=this.m_proxyB.GetVertex(b.indexB[0]);
C=this.m_proxyB.GetVertex(b.indexB[1]);v=this.m_proxyA.GetVertex(b.indexA[0]);this.m_localPoint.x=0.5*(x.x+C.x);this.m_localPoint.y=0.5*(x.y+C.y);this.m_axis=w.CrossVF(w.SubtractVV(C,x),1);this.m_axis.Normalize();s=this.m_axis;b=r.R;J=b.col1.x*s.x+b.col2.x*s.y;T=b.col1.y*s.x+b.col2.y*s.y;s=this.m_localPoint;b=r.R;x=r.position.x+(b.col1.x*s.x+b.col2.x*s.y);C=r.position.y+(b.col1.y*s.x+b.col2.y*s.y);s=v;b=f.R;e=f.position.x+(b.col1.x*s.x+b.col2.x*s.y);m=f.position.y+(b.col1.y*s.x+b.col2.y*s.y);J=(e-
x)*J+(m-C)*T}else{e=this.m_proxyA.GetVertex(b.indexA[0]);m=this.m_proxyA.GetVertex(b.indexA[1]);x=this.m_proxyB.GetVertex(b.indexB[0]);C=this.m_proxyB.GetVertex(b.indexB[1]);w.MulX(f,v);v=w.MulMV(f.R,w.SubtractVV(m,e));w.MulX(r,t);J=w.MulMV(r.R,w.SubtractVV(C,x));r=v.x*v.x+v.y*v.y;t=J.x*J.x+J.y*J.y;b=w.SubtractVV(J,v);f=v.x*b.x+v.y*b.y;b=J.x*b.x+J.y*b.y;v=v.x*J.x+v.y*J.y;T=r*t-v*v;J=0;if(T!=0)J=w.Clamp((v*b-f*t)/T,0,1);if((v*J+b)/t<0)J=w.Clamp((v-f)/r,0,1);v=new p;v.x=e.x+J*(m.x-e.x);v.y=e.y+J*(m.y-
e.y);t=new p;t.x=x.x+J*(C.x-x.x);t.y=x.y+J*(C.y-x.y);if(J==0||J==1){this.m_type=d.e_faceB;this.m_axis=w.CrossVF(w.SubtractVV(C,x),1);this.m_axis.Normalize();this.m_localPoint=t}else{this.m_type=d.e_faceA;this.m_axis=w.CrossVF(w.SubtractVV(m,e),1);this.m_localPoint=v}}J<0&&this.m_axis.NegativeSelf()}};d.prototype.Evaluate=function(b,e){var f,m,r=0;switch(this.m_type){case d.e_points:f=w.MulTMV(b.R,this.m_axis);m=w.MulTMV(e.R,this.m_axis.GetNegative());f=this.m_proxyA.GetSupportVertex(f);m=this.m_proxyB.GetSupportVertex(m);
f=w.MulX(b,f);m=w.MulX(e,m);return r=(m.x-f.x)*this.m_axis.x+(m.y-f.y)*this.m_axis.y;case d.e_faceA:r=w.MulMV(b.R,this.m_axis);f=w.MulX(b,this.m_localPoint);m=w.MulTMV(e.R,r.GetNegative());m=this.m_proxyB.GetSupportVertex(m);m=w.MulX(e,m);return r=(m.x-f.x)*r.x+(m.y-f.y)*r.y;case d.e_faceB:r=w.MulMV(e.R,this.m_axis);m=w.MulX(e,this.m_localPoint);f=w.MulTMV(b.R,r.GetNegative());f=this.m_proxyA.GetSupportVertex(f);f=w.MulX(b,f);return r=(f.x-m.x)*r.x+(f.y-m.y)*r.y;default:y.b2Assert(false);return 0}};
Box2D.postDefs.push(function(){Box2D.Collision.b2SeparationFunction.e_points=1;Box2D.Collision.b2SeparationFunction.e_faceA=2;Box2D.Collision.b2SeparationFunction.e_faceB=4});h.b2Simplex=function(){this.m_v1=new j;this.m_v2=new j;this.m_v3=new j;this.m_vertices=new Vector(3)};h.prototype.b2Simplex=function(){this.m_vertices[0]=this.m_v1;this.m_vertices[1]=this.m_v2;this.m_vertices[2]=this.m_v3};h.prototype.ReadCache=function(b,e,f,m,r){y.b2Assert(0<=b.count&&b.count<=3);var s,v;this.m_count=b.count;
for(var t=this.m_vertices,x=0;x<this.m_count;x++){var C=t[x];C.indexA=b.indexA[x];C.indexB=b.indexB[x];s=e.GetVertex(C.indexA);v=m.GetVertex(C.indexB);C.wA=w.MulX(f,s);C.wB=w.MulX(r,v);C.w=w.SubtractVV(C.wB,C.wA);C.a=0}if(this.m_count>1){b=b.metric;s=this.GetMetric();if(s<0.5*b||2*b<s||s<Number.MIN_VALUE)this.m_count=0}if(this.m_count==0){C=t[0];C.indexA=0;C.indexB=0;s=e.GetVertex(0);v=m.GetVertex(0);C.wA=w.MulX(f,s);C.wB=w.MulX(r,v);C.w=w.SubtractVV(C.wB,C.wA);this.m_count=1}};h.prototype.WriteCache=
function(b){b.metric=this.GetMetric();b.count=Box2D.parseUInt(this.m_count);for(var e=this.m_vertices,f=0;f<this.m_count;f++){b.indexA[f]=Box2D.parseUInt(e[f].indexA);b.indexB[f]=Box2D.parseUInt(e[f].indexB)}};h.prototype.GetSearchDirection=function(){switch(this.m_count){case 1:return this.m_v1.w.GetNegative();case 2:var b=w.SubtractVV(this.m_v2.w,this.m_v1.w);return w.CrossVV(b,this.m_v1.w.GetNegative())>0?w.CrossFV(1,b):w.CrossVF(b,1);default:y.b2Assert(false);return new p}};h.prototype.GetClosestPoint=
function(){switch(this.m_count){case 0:y.b2Assert(false);return new p;case 1:return this.m_v1.w;case 2:return new p(this.m_v1.a*this.m_v1.w.x+this.m_v2.a*this.m_v2.w.x,this.m_v1.a*this.m_v1.w.y+this.m_v2.a*this.m_v2.w.y);default:y.b2Assert(false);return new p}};h.prototype.GetWitnessPoints=function(b,e){switch(this.m_count){case 0:y.b2Assert(false);break;case 1:b.SetV(this.m_v1.wA);e.SetV(this.m_v1.wB);break;case 2:b.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x;b.y=this.m_v1.a*this.m_v1.wA.y+
this.m_v2.a*this.m_v2.wA.y;e.x=this.m_v1.a*this.m_v1.wB.x+this.m_v2.a*this.m_v2.wB.x;e.y=this.m_v1.a*this.m_v1.wB.y+this.m_v2.a*this.m_v2.wB.y;break;case 3:e.x=b.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x+this.m_v3.a*this.m_v3.wA.x;e.y=b.y=this.m_v1.a*this.m_v1.wA.y+this.m_v2.a*this.m_v2.wA.y+this.m_v3.a*this.m_v3.wA.y;break;default:y.b2Assert(false)}};h.prototype.GetMetric=function(){switch(this.m_count){case 0:y.b2Assert(false);return 0;case 1:return 0;case 2:return w.SubtractVV(this.m_v1.w,
this.m_v2.w).Length();case 3:return w.CrossVV(w.SubtractVV(this.m_v2.w,this.m_v1.w),w.SubtractVV(this.m_v3.w,this.m_v1.w));default:y.b2Assert(false);return 0}};h.prototype.Solve2=function(){var b=this.m_v1.w,e=this.m_v2.w,f=w.SubtractVV(e,b);b=-(b.x*f.x+b.y*f.y);if(b<=0)this.m_count=this.m_v1.a=1;else{e=e.x*f.x+e.y*f.y;if(e<=0){this.m_count=this.m_v2.a=1;this.m_v1.Set(this.m_v2)}else{f=1/(e+b);this.m_v1.a=e*f;this.m_v2.a=b*f;this.m_count=2}}};h.prototype.Solve3=function(){var b=this.m_v1.w,e=this.m_v2.w,
f=this.m_v3.w,m=w.SubtractVV(e,b),r=w.Dot(b,m),s=w.Dot(e,m);r=-r;var v=w.SubtractVV(f,b),t=w.Dot(b,v),x=w.Dot(f,v);t=-t;var C=w.SubtractVV(f,e),J=w.Dot(e,C);C=w.Dot(f,C);J=-J;v=w.CrossVV(m,v);m=v*w.CrossVV(e,f);f=v*w.CrossVV(f,b);b=v*w.CrossVV(b,e);if(r<=0&&t<=0)this.m_count=this.m_v1.a=1;else if(s>0&&r>0&&b<=0){x=1/(s+r);this.m_v1.a=s*x;this.m_v2.a=r*x;this.m_count=2}else if(x>0&&t>0&&f<=0){s=1/(x+t);this.m_v1.a=x*s;this.m_v3.a=t*s;this.m_count=2;this.m_v2.Set(this.m_v3)}else if(s<=0&&J<=0){this.m_count=
this.m_v2.a=1;this.m_v1.Set(this.m_v2)}else if(x<=0&&C<=0){this.m_count=this.m_v3.a=1;this.m_v1.Set(this.m_v3)}else if(C>0&&J>0&&m<=0){s=1/(C+J);this.m_v2.a=C*s;this.m_v3.a=J*s;this.m_count=2;this.m_v1.Set(this.m_v3)}else{s=1/(m+f+b);this.m_v1.a=m*s;this.m_v2.a=f*s;this.m_v3.a=b*s;this.m_count=3}};l.b2SimplexCache=function(){this.indexA=new Vector_a2j_Number(3);this.indexB=new Vector_a2j_Number(3)};j.b2SimplexVertex=function(){};j.prototype.Set=function(b){this.wA.SetV(b.wA);this.wB.SetV(b.wB);this.w.SetV(b.w);
this.a=b.a;this.indexA=b.indexA;this.indexB=b.indexB};o.b2TimeOfImpact=function(){};o.TimeOfImpact=function(b){++o.b2_toiCalls;var e=b.proxyA,f=b.proxyB,m=b.sweepA,r=b.sweepB;y.b2Assert(m.t0==r.t0);y.b2Assert(1-m.t0>Number.MIN_VALUE);var s=e.m_radius+f.m_radius;b=b.tolerance;var v=0,t=0,x=0;o.s_cache.count=0;for(o.s_distanceInput.useRadii=false;;){m.GetTransform(o.s_xfA,v);r.GetTransform(o.s_xfB,v);o.s_distanceInput.proxyA=e;o.s_distanceInput.proxyB=f;o.s_distanceInput.transformA=o.s_xfA;o.s_distanceInput.transformB=
o.s_xfB;W.Distance(o.s_distanceOutput,o.s_cache,o.s_distanceInput);if(o.s_distanceOutput.distance<=0){v=1;break}o.s_fcn.Initialize(o.s_cache,e,o.s_xfA,f,o.s_xfB);var C=o.s_fcn.Evaluate(o.s_xfA,o.s_xfB);if(C<=0){v=1;break}if(t==0)x=C>s?w.Max(s-b,0.75*s):w.Max(C-b,0.02*s);if(C-x<0.5*b){if(t==0){v=1;break}break}var J=v,T=v,P=1;C=C;m.GetTransform(o.s_xfA,P);r.GetTransform(o.s_xfB,P);var X=o.s_fcn.Evaluate(o.s_xfA,o.s_xfB);if(X>=x){v=1;break}for(var $=0;;){var ba=0;ba=$&1?T+(x-C)*(P-T)/(X-C):0.5*(T+P);
m.GetTransform(o.s_xfA,ba);r.GetTransform(o.s_xfB,ba);var ca=o.s_fcn.Evaluate(o.s_xfA,o.s_xfB);if(w.Abs(ca-x)<0.025*b){J=ba;break}if(ca>x){T=ba;C=ca}else{P=ba;X=ca}++$;++o.b2_toiRootIters;if($==50)break}o.b2_toiMaxRootIters=w.Max(o.b2_toiMaxRootIters,$);if(J<(1+100*Number.MIN_VALUE)*v)break;v=J;t++;++o.b2_toiIters;if(t==1E3)break}o.b2_toiMaxIters=w.Max(o.b2_toiMaxIters,t);return v};Box2D.postDefs.push(function(){Box2D.Collision.b2TimeOfImpact.b2_toiCalls=0;Box2D.Collision.b2TimeOfImpact.b2_toiIters=
0;Box2D.Collision.b2TimeOfImpact.b2_toiMaxIters=0;Box2D.Collision.b2TimeOfImpact.b2_toiRootIters=0;Box2D.Collision.b2TimeOfImpact.b2_toiMaxRootIters=0;Box2D.Collision.b2TimeOfImpact.s_cache=new l;Box2D.Collision.b2TimeOfImpact.s_distanceInput=new Y;Box2D.Collision.b2TimeOfImpact.s_xfA=new U;Box2D.Collision.b2TimeOfImpact.s_xfB=new U;Box2D.Collision.b2TimeOfImpact.s_fcn=new d;Box2D.Collision.b2TimeOfImpact.s_distanceOutput=new k});q.b2TOIInput=function(){this.proxyA=new z;this.proxyB=new z;this.sweepA=
new A;this.sweepB=new A};n.b2WorldManifold=function(){this.m_normal=new p};n.prototype.b2WorldManifold=function(){this.m_points=new Vector(y.b2_maxManifoldPoints);for(var b=0;b<y.b2_maxManifoldPoints;b++)this.m_points[b]=new p};n.prototype.Initialize=function(b,e,f,m,r){if(f===undefined)f=0;if(r===undefined)r=0;if(b.m_pointCount!=0){var s=0,v,t,x=0,C=0,J=0,T=0,P=0;v=0;switch(b.m_type){case E.e_circles:t=e.R;v=b.m_localPoint;s=e.position.x+t.col1.x*v.x+t.col2.x*v.y;e=e.position.y+t.col1.y*v.x+t.col2.y*
v.y;t=m.R;v=b.m_points[0].m_localPoint;b=m.position.x+t.col1.x*v.x+t.col2.x*v.y;m=m.position.y+t.col1.y*v.x+t.col2.y*v.y;v=b-s;t=m-e;x=v*v+t*t;if(x>Number.MIN_VALUE*Number.MIN_VALUE){x=Math.sqrt(x);this.m_normal.x=v/x;this.m_normal.y=t/x}else{this.m_normal.x=1;this.m_normal.y=0}v=e+f*this.m_normal.y;m=m-r*this.m_normal.y;this.m_points[0].x=0.5*(s+f*this.m_normal.x+(b-r*this.m_normal.x));this.m_points[0].y=0.5*(v+m);break;case E.e_faceA:t=e.R;v=b.m_localPlaneNormal;x=t.col1.x*v.x+t.col2.x*v.y;C=t.col1.y*
v.x+t.col2.y*v.y;t=e.R;v=b.m_localPoint;J=e.position.x+t.col1.x*v.x+t.col2.x*v.y;T=e.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_normal.x=x;this.m_normal.y=C;for(s=0;s<b.m_pointCount;s++){t=m.R;v=b.m_points[s].m_localPoint;P=m.position.x+t.col1.x*v.x+t.col2.x*v.y;v=m.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_points[s].x=P+0.5*(f-(P-J)*x-(v-T)*C-r)*x;this.m_points[s].y=v+0.5*(f-(P-J)*x-(v-T)*C-r)*C}break;case E.e_faceB:t=m.R;v=b.m_localPlaneNormal;x=t.col1.x*v.x+t.col2.x*v.y;C=t.col1.y*v.x+t.col2.y*
v.y;t=m.R;v=b.m_localPoint;J=m.position.x+t.col1.x*v.x+t.col2.x*v.y;T=m.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_normal.x=-x;this.m_normal.y=-C;for(s=0;s<b.m_pointCount;s++){t=e.R;v=b.m_points[s].m_localPoint;P=e.position.x+t.col1.x*v.x+t.col2.x*v.y;v=e.position.y+t.col1.y*v.x+t.col2.y*v.y;this.m_points[s].x=P+0.5*(r-(P-J)*x-(v-T)*C-f)*x;this.m_points[s].y=v+0.5*(r-(P-J)*x-(v-T)*C-f)*C}}}};a.ClipVertex=function(){this.v=new p;this.id=new L};a.prototype.Set=function(b){this.v.SetV(b.v);this.id.Set(b.id)};
c.Features=function(){};Object.defineProperty(c.prototype,"referenceEdge",{enumerable:false,configurable:true,get:function(){return this._referenceEdge}});Object.defineProperty(c.prototype,"referenceEdge",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._referenceEdge=b;this._m_id._key=this._m_id._key&4294967040|this._referenceEdge&255}});Object.defineProperty(c.prototype,"incidentEdge",{enumerable:false,configurable:true,get:function(){return this._incidentEdge}});Object.defineProperty(c.prototype,
"incidentEdge",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._incidentEdge=b;this._m_id._key=this._m_id._key&4294902015|this._incidentEdge<<8&65280}});Object.defineProperty(c.prototype,"incidentVertex",{enumerable:false,configurable:true,get:function(){return this._incidentVertex}});Object.defineProperty(c.prototype,"incidentVertex",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._incidentVertex=b;this._m_id._key=this._m_id._key&4278255615|
this._incidentVertex<<16&16711680}});Object.defineProperty(c.prototype,"flip",{enumerable:false,configurable:true,get:function(){return this._flip}});Object.defineProperty(c.prototype,"flip",{enumerable:false,configurable:true,set:function(b){if(b===undefined)b=0;this._flip=b;this._m_id._key=this._m_id._key&16777215|this._flip<<24&4278190080}})})();
(function(){var F=Box2D.Common.b2Settings,G=Box2D.Collision.Shapes.b2CircleShape,K=Box2D.Collision.Shapes.b2EdgeChainDef,y=Box2D.Collision.Shapes.b2EdgeShape,w=Box2D.Collision.Shapes.b2MassData,A=Box2D.Collision.Shapes.b2PolygonShape,U=Box2D.Collision.Shapes.b2Shape,p=Box2D.Common.Math.b2Mat22,B=Box2D.Common.Math.b2Math,Q=Box2D.Common.Math.b2Transform,V=Box2D.Common.Math.b2Vec2,M=Box2D.Collision.b2Distance,L=Box2D.Collision.b2DistanceInput,I=Box2D.Collision.b2DistanceOutput,W=Box2D.Collision.b2DistanceProxy,
Y=Box2D.Collision.b2SimplexCache;Box2D.inherit(G,Box2D.Collision.Shapes.b2Shape);G.prototype.__super=Box2D.Collision.Shapes.b2Shape.prototype;G.b2CircleShape=function(){Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this,arguments);this.m_p=new V};G.prototype.Copy=function(){var k=new G;k.Set(this);return k};G.prototype.Set=function(k){this.__super.Set.call(this,k);if(Box2D.is(k,G))this.m_p.SetV((k instanceof G?k:null).m_p)};G.prototype.TestPoint=function(k,z){var u=k.R,D=k.position.x+(u.col1.x*this.m_p.x+
u.col2.x*this.m_p.y);u=k.position.y+(u.col1.y*this.m_p.x+u.col2.y*this.m_p.y);D=z.x-D;u=z.y-u;return D*D+u*u<=this.m_radius*this.m_radius};G.prototype.RayCast=function(k,z,u){var D=u.R,H=z.p1.x-(u.position.x+(D.col1.x*this.m_p.x+D.col2.x*this.m_p.y));u=z.p1.y-(u.position.y+(D.col1.y*this.m_p.x+D.col2.y*this.m_p.y));D=z.p2.x-z.p1.x;var O=z.p2.y-z.p1.y,E=H*D+u*O,R=D*D+O*O,N=E*E-R*(H*H+u*u-this.m_radius*this.m_radius);if(N<0||R<Number.MIN_VALUE)return false;E=-(E+Math.sqrt(N));if(0<=E&&E<=z.maxFraction*
R){E/=R;k.fraction=E;k.normal.x=H+E*D;k.normal.y=u+E*O;k.normal.Normalize();return true}return false};G.prototype.ComputeAABB=function(k,z){var u=z.R,D=z.position.x+(u.col1.x*this.m_p.x+u.col2.x*this.m_p.y);u=z.position.y+(u.col1.y*this.m_p.x+u.col2.y*this.m_p.y);k.lowerBound.Set(D-this.m_radius,u-this.m_radius);k.upperBound.Set(D+this.m_radius,u+this.m_radius)};G.prototype.ComputeMass=function(k,z){if(z===undefined)z=0;k.mass=z*F.b2_pi*this.m_radius*this.m_radius;k.center.SetV(this.m_p);k.I=k.mass*
(0.5*this.m_radius*this.m_radius+(this.m_p.x*this.m_p.x+this.m_p.y*this.m_p.y))};G.prototype.ComputeSubmergedArea=function(k,z,u,D){if(z===undefined)z=0;u=B.MulX(u,this.m_p);var H=-(B.Dot(k,u)-z);if(H<-this.m_radius+Number.MIN_VALUE)return 0;if(H>this.m_radius){D.SetV(u);return Math.PI*this.m_radius*this.m_radius}z=this.m_radius*this.m_radius;var O=H*H;H=z*(Math.asin(H/this.m_radius)+Math.PI/2)+H*Math.sqrt(z-O);z=-2/3*Math.pow(z-O,1.5)/H;D.x=u.x+k.x*z;D.y=u.y+k.y*z;return H};G.prototype.GetLocalPosition=
function(){return this.m_p};G.prototype.SetLocalPosition=function(k){this.m_p.SetV(k)};G.prototype.GetRadius=function(){return this.m_radius};G.prototype.SetRadius=function(k){if(k===undefined)k=0;this.m_radius=k};G.prototype.b2CircleShape=function(k){if(k===undefined)k=0;this.__super.b2Shape.call(this);this.m_type=U.e_circleShape;this.m_radius=k};K.b2EdgeChainDef=function(){};K.prototype.b2EdgeChainDef=function(){this.vertexCount=0;this.isALoop=true;this.vertices=[]};Box2D.inherit(y,Box2D.Collision.Shapes.b2Shape);
y.prototype.__super=Box2D.Collision.Shapes.b2Shape.prototype;y.b2EdgeShape=function(){Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this,arguments);this.s_supportVec=new V;this.m_v1=new V;this.m_v2=new V;this.m_coreV1=new V;this.m_coreV2=new V;this.m_normal=new V;this.m_direction=new V;this.m_cornerDir1=new V;this.m_cornerDir2=new V};y.prototype.TestPoint=function(){return false};y.prototype.RayCast=function(k,z,u){var D,H=z.p2.x-z.p1.x,O=z.p2.y-z.p1.y;D=u.R;var E=u.position.x+(D.col1.x*this.m_v1.x+
D.col2.x*this.m_v1.y),R=u.position.y+(D.col1.y*this.m_v1.x+D.col2.y*this.m_v1.y),N=u.position.y+(D.col1.y*this.m_v2.x+D.col2.y*this.m_v2.y)-R;u=-(u.position.x+(D.col1.x*this.m_v2.x+D.col2.x*this.m_v2.y)-E);D=100*Number.MIN_VALUE;var S=-(H*N+O*u);if(S>D){E=z.p1.x-E;var aa=z.p1.y-R;R=E*N+aa*u;if(0<=R&&R<=z.maxFraction*S){z=-H*aa+O*E;if(-D*S<=z&&z<=S*(1+D)){R/=S;k.fraction=R;z=Math.sqrt(N*N+u*u);k.normal.x=N/z;k.normal.y=u/z;return true}}}return false};y.prototype.ComputeAABB=function(k,z){var u=z.R,
D=z.position.x+(u.col1.x*this.m_v1.x+u.col2.x*this.m_v1.y),H=z.position.y+(u.col1.y*this.m_v1.x+u.col2.y*this.m_v1.y),O=z.position.x+(u.col1.x*this.m_v2.x+u.col2.x*this.m_v2.y);u=z.position.y+(u.col1.y*this.m_v2.x+u.col2.y*this.m_v2.y);if(D<O){k.lowerBound.x=D;k.upperBound.x=O}else{k.lowerBound.x=O;k.upperBound.x=D}if(H<u){k.lowerBound.y=H;k.upperBound.y=u}else{k.lowerBound.y=u;k.upperBound.y=H}};y.prototype.ComputeMass=function(k){k.mass=0;k.center.SetV(this.m_v1);k.I=0};y.prototype.ComputeSubmergedArea=
function(k,z,u,D){if(z===undefined)z=0;var H=new V(k.x*z,k.y*z),O=B.MulX(u,this.m_v1);u=B.MulX(u,this.m_v2);var E=B.Dot(k,O)-z;k=B.Dot(k,u)-z;if(E>0)if(k>0)return 0;else{O.x=-k/(E-k)*O.x+E/(E-k)*u.x;O.y=-k/(E-k)*O.y+E/(E-k)*u.y}else if(k>0){u.x=-k/(E-k)*O.x+E/(E-k)*u.x;u.y=-k/(E-k)*O.y+E/(E-k)*u.y}D.x=(H.x+O.x+u.x)/3;D.y=(H.y+O.y+u.y)/3;return 0.5*((O.x-H.x)*(u.y-H.y)-(O.y-H.y)*(u.x-H.x))};y.prototype.GetLength=function(){return this.m_length};y.prototype.GetVertex1=function(){return this.m_v1};y.prototype.GetVertex2=
function(){return this.m_v2};y.prototype.GetCoreVertex1=function(){return this.m_coreV1};y.prototype.GetCoreVertex2=function(){return this.m_coreV2};y.prototype.GetNormalVector=function(){return this.m_normal};y.prototype.GetDirectionVector=function(){return this.m_direction};y.prototype.GetCorner1Vector=function(){return this.m_cornerDir1};y.prototype.GetCorner2Vector=function(){return this.m_cornerDir2};y.prototype.Corner1IsConvex=function(){return this.m_cornerConvex1};y.prototype.Corner2IsConvex=
function(){return this.m_cornerConvex2};y.prototype.GetFirstVertex=function(k){var z=k.R;return new V(k.position.x+(z.col1.x*this.m_coreV1.x+z.col2.x*this.m_coreV1.y),k.position.y+(z.col1.y*this.m_coreV1.x+z.col2.y*this.m_coreV1.y))};y.prototype.GetNextEdge=function(){return this.m_nextEdge};y.prototype.GetPrevEdge=function(){return this.m_prevEdge};y.prototype.Support=function(k,z,u){if(z===undefined)z=0;if(u===undefined)u=0;var D=k.R,H=k.position.x+(D.col1.x*this.m_coreV1.x+D.col2.x*this.m_coreV1.y),
O=k.position.y+(D.col1.y*this.m_coreV1.x+D.col2.y*this.m_coreV1.y),E=k.position.x+(D.col1.x*this.m_coreV2.x+D.col2.x*this.m_coreV2.y);k=k.position.y+(D.col1.y*this.m_coreV2.x+D.col2.y*this.m_coreV2.y);if(H*z+O*u>E*z+k*u){this.s_supportVec.x=H;this.s_supportVec.y=O}else{this.s_supportVec.x=E;this.s_supportVec.y=k}return this.s_supportVec};y.prototype.b2EdgeShape=function(k,z){this.__super.b2Shape.call(this);this.m_type=U.e_edgeShape;this.m_nextEdge=this.m_prevEdge=null;this.m_v1=k;this.m_v2=z;this.m_direction.Set(this.m_v2.x-
this.m_v1.x,this.m_v2.y-this.m_v1.y);this.m_length=this.m_direction.Normalize();this.m_normal.Set(this.m_direction.y,-this.m_direction.x);this.m_coreV1.Set(-F.b2_toiSlop*(this.m_normal.x-this.m_direction.x)+this.m_v1.x,-F.b2_toiSlop*(this.m_normal.y-this.m_direction.y)+this.m_v1.y);this.m_coreV2.Set(-F.b2_toiSlop*(this.m_normal.x+this.m_direction.x)+this.m_v2.x,-F.b2_toiSlop*(this.m_normal.y+this.m_direction.y)+this.m_v2.y);this.m_cornerDir1=this.m_normal;this.m_cornerDir2.Set(-this.m_normal.x,-this.m_normal.y)};
y.prototype.SetPrevEdge=function(k,z,u,D){this.m_prevEdge=k;this.m_coreV1=z;this.m_cornerDir1=u;this.m_cornerConvex1=D};y.prototype.SetNextEdge=function(k,z,u,D){this.m_nextEdge=k;this.m_coreV2=z;this.m_cornerDir2=u;this.m_cornerConvex2=D};w.b2MassData=function(){this.mass=0;this.center=new V(0,0);this.I=0};Box2D.inherit(A,Box2D.Collision.Shapes.b2Shape);A.prototype.__super=Box2D.Collision.Shapes.b2Shape.prototype;A.b2PolygonShape=function(){Box2D.Collision.Shapes.b2Shape.b2Shape.apply(this,arguments)};
A.prototype.Copy=function(){var k=new A;k.Set(this);return k};A.prototype.Set=function(k){this.__super.Set.call(this,k);if(Box2D.is(k,A)){k=k instanceof A?k:null;this.m_centroid.SetV(k.m_centroid);this.m_vertexCount=k.m_vertexCount;this.Reserve(this.m_vertexCount);for(var z=0;z<this.m_vertexCount;z++){this.m_vertices[z].SetV(k.m_vertices[z]);this.m_normals[z].SetV(k.m_normals[z])}}};A.prototype.SetAsArray=function(k,z){if(z===undefined)z=0;var u=new Vector,D=0,H;for(D=0;D<k.length;++D){H=k[D];u.push(H)}this.SetAsVector(u,
z)};A.AsArray=function(k,z){if(z===undefined)z=0;var u=new A;u.SetAsArray(k,z);return u};A.prototype.SetAsVector=function(k,z){if(z===undefined)z=0;if(z==0)z=k.length;F.b2Assert(2<=z);this.m_vertexCount=z;this.Reserve(z);var u=0;for(u=0;u<this.m_vertexCount;u++)this.m_vertices[u].SetV(k[u]);for(u=0;u<this.m_vertexCount;++u){var D=parseInt(u),H=parseInt(u+1<this.m_vertexCount?u+1:0);D=B.SubtractVV(this.m_vertices[H],this.m_vertices[D]);F.b2Assert(D.LengthSquared()>Number.MIN_VALUE);this.m_normals[u].SetV(B.CrossVF(D,
1));this.m_normals[u].Normalize()}this.m_centroid=A.ComputeCentroid(this.m_vertices,this.m_vertexCount)};A.AsVector=function(k,z){if(z===undefined)z=0;var u=new A;u.SetAsVector(k,z);return u};A.prototype.SetAsBox=function(k,z){if(k===undefined)k=0;if(z===undefined)z=0;this.m_vertexCount=4;this.Reserve(4);this.m_vertices[0].Set(-k,-z);this.m_vertices[1].Set(k,-z);this.m_vertices[2].Set(k,z);this.m_vertices[3].Set(-k,z);this.m_normals[0].Set(0,-1);this.m_normals[1].Set(1,0);this.m_normals[2].Set(0,
1);this.m_normals[3].Set(-1,0);this.m_centroid.SetZero()};A.AsBox=function(k,z){if(k===undefined)k=0;if(z===undefined)z=0;var u=new A;u.SetAsBox(k,z);return u};A.prototype.SetAsOrientedBox=function(k,z,u,D){if(k===undefined)k=0;if(z===undefined)z=0;if(u===undefined)u=null;if(D===undefined)D=0;this.m_vertexCount=4;this.Reserve(4);this.m_vertices[0].Set(-k,-z);this.m_vertices[1].Set(k,-z);this.m_vertices[2].Set(k,z);this.m_vertices[3].Set(-k,z);this.m_normals[0].Set(0,-1);this.m_normals[1].Set(1,0);
this.m_normals[2].Set(0,1);this.m_normals[3].Set(-1,0);this.m_centroid=u;k=new Q;k.position=u;k.R.Set(D);for(u=0;u<this.m_vertexCount;++u){this.m_vertices[u]=B.MulX(k,this.m_vertices[u]);this.m_normals[u]=B.MulMV(k.R,this.m_normals[u])}};A.AsOrientedBox=function(k,z,u,D){if(k===undefined)k=0;if(z===undefined)z=0;if(u===undefined)u=null;if(D===undefined)D=0;var H=new A;H.SetAsOrientedBox(k,z,u,D);return H};A.prototype.SetAsEdge=function(k,z){this.m_vertexCount=2;this.Reserve(2);this.m_vertices[0].SetV(k);
this.m_vertices[1].SetV(z);this.m_centroid.x=0.5*(k.x+z.x);this.m_centroid.y=0.5*(k.y+z.y);this.m_normals[0]=B.CrossVF(B.SubtractVV(z,k),1);this.m_normals[0].Normalize();this.m_normals[1].x=-this.m_normals[0].x;this.m_normals[1].y=-this.m_normals[0].y};A.AsEdge=function(k,z){var u=new A;u.SetAsEdge(k,z);return u};A.prototype.TestPoint=function(k,z){var u;u=k.R;for(var D=z.x-k.position.x,H=z.y-k.position.y,O=D*u.col1.x+H*u.col1.y,E=D*u.col2.x+H*u.col2.y,R=0;R<this.m_vertexCount;++R){u=this.m_vertices[R];
D=O-u.x;H=E-u.y;u=this.m_normals[R];if(u.x*D+u.y*H>0)return false}return true};A.prototype.RayCast=function(k,z,u){var D=0,H=z.maxFraction,O=0,E=0,R,N;O=z.p1.x-u.position.x;E=z.p1.y-u.position.y;R=u.R;var S=O*R.col1.x+E*R.col1.y,aa=O*R.col2.x+E*R.col2.y;O=z.p2.x-u.position.x;E=z.p2.y-u.position.y;R=u.R;z=O*R.col1.x+E*R.col1.y-S;R=O*R.col2.x+E*R.col2.y-aa;for(var Z=parseInt(-1),d=0;d<this.m_vertexCount;++d){N=this.m_vertices[d];O=N.x-S;E=N.y-aa;N=this.m_normals[d];O=N.x*O+N.y*E;E=N.x*z+N.y*R;if(E==
0){if(O<0)return false}else if(E<0&&O<D*E){D=O/E;Z=d}else if(E>0&&O<H*E)H=O/E;if(H<D-Number.MIN_VALUE)return false}if(Z>=0){k.fraction=D;R=u.R;N=this.m_normals[Z];k.normal.x=R.col1.x*N.x+R.col2.x*N.y;k.normal.y=R.col1.y*N.x+R.col2.y*N.y;return true}return false};A.prototype.ComputeAABB=function(k,z){for(var u=z.R,D=this.m_vertices[0],H=z.position.x+(u.col1.x*D.x+u.col2.x*D.y),O=z.position.y+(u.col1.y*D.x+u.col2.y*D.y),E=H,R=O,N=1;N<this.m_vertexCount;++N){D=this.m_vertices[N];var S=z.position.x+(u.col1.x*
D.x+u.col2.x*D.y);D=z.position.y+(u.col1.y*D.x+u.col2.y*D.y);H=H<S?H:S;O=O<D?O:D;E=E>S?E:S;R=R>D?R:D}k.lowerBound.x=H-this.m_radius;k.lowerBound.y=O-this.m_radius;k.upperBound.x=E+this.m_radius;k.upperBound.y=R+this.m_radius};A.prototype.ComputeMass=function(k,z){if(z===undefined)z=0;if(this.m_vertexCount==2){k.center.x=0.5*(this.m_vertices[0].x+this.m_vertices[1].x);k.center.y=0.5*(this.m_vertices[0].y+this.m_vertices[1].y);k.mass=0;k.I=0}else{for(var u=0,D=0,H=0,O=0,E=1/3,R=0;R<this.m_vertexCount;++R){var N=
this.m_vertices[R],S=R+1<this.m_vertexCount?this.m_vertices[parseInt(R+1)]:this.m_vertices[0],aa=N.x-0,Z=N.y-0,d=S.x-0,h=S.y-0,l=aa*h-Z*d,j=0.5*l;H+=j;u+=j*E*(0+N.x+S.x);D+=j*E*(0+N.y+S.y);N=aa;Z=Z;d=d;h=h;O+=l*(E*(0.25*(N*N+d*N+d*d)+(0*N+0*d))+0+(E*(0.25*(Z*Z+h*Z+h*h)+(0*Z+0*h))+0))}k.mass=z*H;u*=1/H;D*=1/H;k.center.Set(u,D);k.I=z*O}};A.prototype.ComputeSubmergedArea=function(k,z,u,D){if(z===undefined)z=0;var H=B.MulTMV(u.R,k),O=z-B.Dot(k,u.position),E=new Vector_a2j_Number,R=0,N=parseInt(-1);z=
parseInt(-1);var S=false;for(k=k=0;k<this.m_vertexCount;++k){E[k]=B.Dot(H,this.m_vertices[k])-O;var aa=E[k]<-Number.MIN_VALUE;if(k>0)if(aa){if(!S){N=k-1;R++}}else if(S){z=k-1;R++}S=aa}switch(R){case 0:if(S){k=new w;this.ComputeMass(k,1);D.SetV(B.MulX(u,k.center));return k.mass}else return 0;case 1:if(N==-1)N=this.m_vertexCount-1;else z=this.m_vertexCount-1}k=parseInt((N+1)%this.m_vertexCount);H=parseInt((z+1)%this.m_vertexCount);O=(0-E[N])/(E[k]-E[N]);E=(0-E[z])/(E[H]-E[z]);N=new V(this.m_vertices[N].x*
(1-O)+this.m_vertices[k].x*O,this.m_vertices[N].y*(1-O)+this.m_vertices[k].y*O);z=new V(this.m_vertices[z].x*(1-E)+this.m_vertices[H].x*E,this.m_vertices[z].y*(1-E)+this.m_vertices[H].y*E);E=0;O=new V;R=this.m_vertices[k];for(k=k;k!=H;){k=(k+1)%this.m_vertexCount;S=k==H?z:this.m_vertices[k];aa=0.5*((R.x-N.x)*(S.y-N.y)-(R.y-N.y)*(S.x-N.x));E+=aa;O.x+=aa*(N.x+R.x+S.x)/3;O.y+=aa*(N.y+R.y+S.y)/3;R=S}O.Multiply(1/E);D.SetV(B.MulX(u,O));return E};A.prototype.GetVertexCount=function(){return this.m_vertexCount};
A.prototype.GetVertices=function(){return this.m_vertices};A.prototype.GetNormals=function(){return this.m_normals};A.prototype.GetSupport=function(k){for(var z=0,u=this.m_vertices[0].x*k.x+this.m_vertices[0].y*k.y,D=1;D<this.m_vertexCount;++D){var H=this.m_vertices[D].x*k.x+this.m_vertices[D].y*k.y;if(H>u){z=D;u=H}}return z};A.prototype.GetSupportVertex=function(k){for(var z=0,u=this.m_vertices[0].x*k.x+this.m_vertices[0].y*k.y,D=1;D<this.m_vertexCount;++D){var H=this.m_vertices[D].x*k.x+this.m_vertices[D].y*
k.y;if(H>u){z=D;u=H}}return this.m_vertices[z]};A.prototype.Validate=function(){return false};A.prototype.b2PolygonShape=function(){this.__super.b2Shape.call(this);this.m_type=U.e_polygonShape;this.m_centroid=new V;this.m_vertices=new Vector;this.m_normals=new Vector};A.prototype.Reserve=function(k){if(k===undefined)k=0;for(var z=parseInt(this.m_vertices.length);z<k;z++){this.m_vertices[z]=new V;this.m_normals[z]=new V}};A.ComputeCentroid=function(k,z){if(z===undefined)z=0;for(var u=new V,D=0,H=1/
3,O=0;O<z;++O){var E=k[O],R=O+1<z?k[parseInt(O+1)]:k[0],N=0.5*((E.x-0)*(R.y-0)-(E.y-0)*(R.x-0));D+=N;u.x+=N*H*(0+E.x+R.x);u.y+=N*H*(0+E.y+R.y)}u.x*=1/D;u.y*=1/D;return u};A.ComputeOBB=function(k,z,u){if(u===undefined)u=0;var D=0,H=new Vector(u+1);for(D=0;D<u;++D)H[D]=z[D];H[u]=H[0];z=Number.MAX_VALUE;for(D=1;D<=u;++D){var O=H[parseInt(D-1)],E=H[D].x-O.x,R=H[D].y-O.y,N=Math.sqrt(E*E+R*R);E/=N;R/=N;for(var S=-R,aa=E,Z=N=Number.MAX_VALUE,d=-Number.MAX_VALUE,h=-Number.MAX_VALUE,l=0;l<u;++l){var j=H[l].x-
O.x,o=H[l].y-O.y,q=E*j+R*o;j=S*j+aa*o;if(q<N)N=q;if(j<Z)Z=j;if(q>d)d=q;if(j>h)h=j}l=(d-N)*(h-Z);if(l<0.95*z){z=l;k.R.col1.x=E;k.R.col1.y=R;k.R.col2.x=S;k.R.col2.y=aa;E=0.5*(N+d);R=0.5*(Z+h);S=k.R;k.center.x=O.x+(S.col1.x*E+S.col2.x*R);k.center.y=O.y+(S.col1.y*E+S.col2.y*R);k.extents.x=0.5*(d-N);k.extents.y=0.5*(h-Z)}}};Box2D.postDefs.push(function(){Box2D.Collision.Shapes.b2PolygonShape.s_mat=new p});U.b2Shape=function(){};U.prototype.Copy=function(){return null};U.prototype.Set=function(k){this.m_radius=
k.m_radius};U.prototype.GetType=function(){return this.m_type};U.prototype.TestPoint=function(){return false};U.prototype.RayCast=function(){return false};U.prototype.ComputeAABB=function(){};U.prototype.ComputeMass=function(){};U.prototype.ComputeSubmergedArea=function(){return 0};U.TestOverlap=function(k,z,u,D){var H=new L;H.proxyA=new W;H.proxyA.Set(k);H.proxyB=new W;H.proxyB.Set(u);H.transformA=z;H.transformB=D;H.useRadii=true;k=new Y;k.count=0;z=new I;M.Distance(z,k,H);return z.distance<10*Number.MIN_VALUE};
U.prototype.b2Shape=function(){this.m_type=U.e_unknownShape;this.m_radius=F.b2_linearSlop};Box2D.postDefs.push(function(){Box2D.Collision.Shapes.b2Shape.e_unknownShape=parseInt(-1);Box2D.Collision.Shapes.b2Shape.e_circleShape=0;Box2D.Collision.Shapes.b2Shape.e_polygonShape=1;Box2D.Collision.Shapes.b2Shape.e_edgeShape=2;Box2D.Collision.Shapes.b2Shape.e_shapeTypeCount=3;Box2D.Collision.Shapes.b2Shape.e_hitCollide=1;Box2D.Collision.Shapes.b2Shape.e_missCollide=0;Box2D.Collision.Shapes.b2Shape.e_startsInsideCollide=
parseInt(-1)})})();
(function(){var F=Box2D.Common.b2Color,G=Box2D.Common.b2Settings,K=Box2D.Common.Math.b2Math;F.b2Color=function(){this._b=this._g=this._r=0};F.prototype.b2Color=function(y,w,A){if(y===undefined)y=0;if(w===undefined)w=0;if(A===undefined)A=0;this._r=Box2D.parseUInt(255*K.Clamp(y,0,1));this._g=Box2D.parseUInt(255*K.Clamp(w,0,1));this._b=Box2D.parseUInt(255*K.Clamp(A,0,1))};F.prototype.Set=function(y,w,A){if(y===undefined)y=0;if(w===undefined)w=0;if(A===undefined)A=0;this._r=Box2D.parseUInt(255*K.Clamp(y,
0,1));this._g=Box2D.parseUInt(255*K.Clamp(w,0,1));this._b=Box2D.parseUInt(255*K.Clamp(A,0,1))};Object.defineProperty(F.prototype,"r",{enumerable:false,configurable:true,set:function(y){if(y===undefined)y=0;this._r=Box2D.parseUInt(255*K.Clamp(y,0,1))}});Object.defineProperty(F.prototype,"g",{enumerable:false,configurable:true,set:function(y){if(y===undefined)y=0;this._g=Box2D.parseUInt(255*K.Clamp(y,0,1))}});Object.defineProperty(F.prototype,"b",{enumerable:false,configurable:true,set:function(y){if(y===
undefined)y=0;this._b=Box2D.parseUInt(255*K.Clamp(y,0,1))}});Object.defineProperty(F.prototype,"color",{enumerable:false,configurable:true,get:function(){return this._r<<16|this._g<<8|this._b}});G.b2Settings=function(){};G.b2MixFriction=function(y,w){if(y===undefined)y=0;if(w===undefined)w=0;return Math.sqrt(y*w)};G.b2MixRestitution=function(y,w){if(y===undefined)y=0;if(w===undefined)w=0;return y>w?y:w};G.b2Assert=function(y){if(!y)throw"Assertion Failed";};Box2D.postDefs.push(function(){Box2D.Common.b2Settings.VERSION=
"2.1alpha";Box2D.Common.b2Settings.USHRT_MAX=65535;Box2D.Common.b2Settings.b2_pi=Math.PI;Box2D.Common.b2Settings.b2_maxManifoldPoints=2;Box2D.Common.b2Settings.b2_aabbExtension=0.1;Box2D.Common.b2Settings.b2_aabbMultiplier=2;Box2D.Common.b2Settings.b2_polygonRadius=2*G.b2_linearSlop;Box2D.Common.b2Settings.b2_linearSlop=0.0050;Box2D.Common.b2Settings.b2_angularSlop=2/180*G.b2_pi;Box2D.Common.b2Settings.b2_toiSlop=8*G.b2_linearSlop;Box2D.Common.b2Settings.b2_maxTOIContactsPerIsland=32;Box2D.Common.b2Settings.b2_maxTOIJointsPerIsland=
32;Box2D.Common.b2Settings.b2_velocityThreshold=1;Box2D.Common.b2Settings.b2_maxLinearCorrection=0.2;Box2D.Common.b2Settings.b2_maxAngularCorrection=8/180*G.b2_pi;Box2D.Common.b2Settings.b2_maxTranslation=2;Box2D.Common.b2Settings.b2_maxTranslationSquared=G.b2_maxTranslation*G.b2_maxTranslation;Box2D.Common.b2Settings.b2_maxRotation=0.5*G.b2_pi;Box2D.Common.b2Settings.b2_maxRotationSquared=G.b2_maxRotation*G.b2_maxRotation;Box2D.Common.b2Settings.b2_contactBaumgarte=0.2;Box2D.Common.b2Settings.b2_timeToSleep=
0.5;Box2D.Common.b2Settings.b2_linearSleepTolerance=0.01;Box2D.Common.b2Settings.b2_angularSleepTolerance=2/180*G.b2_pi})})();
(function(){var F=Box2D.Common.Math.b2Mat22,G=Box2D.Common.Math.b2Mat33,K=Box2D.Common.Math.b2Math,y=Box2D.Common.Math.b2Sweep,w=Box2D.Common.Math.b2Transform,A=Box2D.Common.Math.b2Vec2,U=Box2D.Common.Math.b2Vec3;F.b2Mat22=function(){this.col1=new A;this.col2=new A};F.prototype.b2Mat22=function(){this.SetIdentity()};F.FromAngle=function(p){if(p===undefined)p=0;var B=new F;B.Set(p);return B};F.FromVV=function(p,B){var Q=new F;Q.SetVV(p,B);return Q};F.prototype.Set=function(p){if(p===undefined)p=0;
var B=Math.cos(p);p=Math.sin(p);this.col1.x=B;this.col2.x=-p;this.col1.y=p;this.col2.y=B};F.prototype.SetVV=function(p,B){this.col1.SetV(p);this.col2.SetV(B)};F.prototype.Copy=function(){var p=new F;p.SetM(this);return p};F.prototype.SetM=function(p){this.col1.SetV(p.col1);this.col2.SetV(p.col2)};F.prototype.AddM=function(p){this.col1.x+=p.col1.x;this.col1.y+=p.col1.y;this.col2.x+=p.col2.x;this.col2.y+=p.col2.y};F.prototype.SetIdentity=function(){this.col1.x=1;this.col2.x=0;this.col1.y=0;this.col2.y=
1};F.prototype.SetZero=function(){this.col1.x=0;this.col2.x=0;this.col1.y=0;this.col2.y=0};F.prototype.GetAngle=function(){return Math.atan2(this.col1.y,this.col1.x)};F.prototype.GetInverse=function(p){var B=this.col1.x,Q=this.col2.x,V=this.col1.y,M=this.col2.y,L=B*M-Q*V;if(L!=0)L=1/L;p.col1.x=L*M;p.col2.x=-L*Q;p.col1.y=-L*V;p.col2.y=L*B;return p};F.prototype.Solve=function(p,B,Q){if(B===undefined)B=0;if(Q===undefined)Q=0;var V=this.col1.x,M=this.col2.x,L=this.col1.y,I=this.col2.y,W=V*I-M*L;if(W!=
0)W=1/W;p.x=W*(I*B-M*Q);p.y=W*(V*Q-L*B);return p};F.prototype.Abs=function(){this.col1.Abs();this.col2.Abs()};G.b2Mat33=function(){this.col1=new U;this.col2=new U;this.col3=new U};G.prototype.b2Mat33=function(p,B,Q){if(p===undefined)p=null;if(B===undefined)B=null;if(Q===undefined)Q=null;if(!p&&!B&&!Q){this.col1.SetZero();this.col2.SetZero();this.col3.SetZero()}else{this.col1.SetV(p);this.col2.SetV(B);this.col3.SetV(Q)}};G.prototype.SetVVV=function(p,B,Q){this.col1.SetV(p);this.col2.SetV(B);this.col3.SetV(Q)};
G.prototype.Copy=function(){return new G(this.col1,this.col2,this.col3)};G.prototype.SetM=function(p){this.col1.SetV(p.col1);this.col2.SetV(p.col2);this.col3.SetV(p.col3)};G.prototype.AddM=function(p){this.col1.x+=p.col1.x;this.col1.y+=p.col1.y;this.col1.z+=p.col1.z;this.col2.x+=p.col2.x;this.col2.y+=p.col2.y;this.col2.z+=p.col2.z;this.col3.x+=p.col3.x;this.col3.y+=p.col3.y;this.col3.z+=p.col3.z};G.prototype.SetIdentity=function(){this.col1.x=1;this.col2.x=0;this.col3.x=0;this.col1.y=0;this.col2.y=
1;this.col3.y=0;this.col1.z=0;this.col2.z=0;this.col3.z=1};G.prototype.SetZero=function(){this.col1.x=0;this.col2.x=0;this.col3.x=0;this.col1.y=0;this.col2.y=0;this.col3.y=0;this.col1.z=0;this.col2.z=0;this.col3.z=0};G.prototype.Solve22=function(p,B,Q){if(B===undefined)B=0;if(Q===undefined)Q=0;var V=this.col1.x,M=this.col2.x,L=this.col1.y,I=this.col2.y,W=V*I-M*L;if(W!=0)W=1/W;p.x=W*(I*B-M*Q);p.y=W*(V*Q-L*B);return p};G.prototype.Solve33=function(p,B,Q,V){if(B===undefined)B=0;if(Q===undefined)Q=0;
if(V===undefined)V=0;var M=this.col1.x,L=this.col1.y,I=this.col1.z,W=this.col2.x,Y=this.col2.y,k=this.col2.z,z=this.col3.x,u=this.col3.y,D=this.col3.z,H=M*(Y*D-k*u)+L*(k*z-W*D)+I*(W*u-Y*z);if(H!=0)H=1/H;p.x=H*(B*(Y*D-k*u)+Q*(k*z-W*D)+V*(W*u-Y*z));p.y=H*(M*(Q*D-V*u)+L*(V*z-B*D)+I*(B*u-Q*z));p.z=H*(M*(Y*V-k*Q)+L*(k*B-W*V)+I*(W*Q-Y*B));return p};K.b2Math=function(){};K.IsValid=function(p){if(p===undefined)p=0;return isFinite(p)};K.Dot=function(p,B){return p.x*B.x+p.y*B.y};K.CrossVV=function(p,B){return p.x*
B.y-p.y*B.x};K.CrossVF=function(p,B){if(B===undefined)B=0;return new A(B*p.y,-B*p.x)};K.CrossFV=function(p,B){if(p===undefined)p=0;return new A(-p*B.y,p*B.x)};K.MulMV=function(p,B){return new A(p.col1.x*B.x+p.col2.x*B.y,p.col1.y*B.x+p.col2.y*B.y)};K.MulTMV=function(p,B){return new A(K.Dot(B,p.col1),K.Dot(B,p.col2))};K.MulX=function(p,B){var Q=K.MulMV(p.R,B);Q.x+=p.position.x;Q.y+=p.position.y;return Q};K.MulXT=function(p,B){var Q=K.SubtractVV(B,p.position),V=Q.x*p.R.col1.x+Q.y*p.R.col1.y;Q.y=Q.x*
p.R.col2.x+Q.y*p.R.col2.y;Q.x=V;return Q};K.AddVV=function(p,B){return new A(p.x+B.x,p.y+B.y)};K.SubtractVV=function(p,B){return new A(p.x-B.x,p.y-B.y)};K.Distance=function(p,B){var Q=p.x-B.x,V=p.y-B.y;return Math.sqrt(Q*Q+V*V)};K.DistanceSquared=function(p,B){var Q=p.x-B.x,V=p.y-B.y;return Q*Q+V*V};K.MulFV=function(p,B){if(p===undefined)p=0;return new A(p*B.x,p*B.y)};K.AddMM=function(p,B){return F.FromVV(K.AddVV(p.col1,B.col1),K.AddVV(p.col2,B.col2))};K.MulMM=function(p,B){return F.FromVV(K.MulMV(p,
B.col1),K.MulMV(p,B.col2))};K.MulTMM=function(p,B){var Q=new A(K.Dot(p.col1,B.col1),K.Dot(p.col2,B.col1)),V=new A(K.Dot(p.col1,B.col2),K.Dot(p.col2,B.col2));return F.FromVV(Q,V)};K.Abs=function(p){if(p===undefined)p=0;return p>0?p:-p};K.AbsV=function(p){return new A(K.Abs(p.x),K.Abs(p.y))};K.AbsM=function(p){return F.FromVV(K.AbsV(p.col1),K.AbsV(p.col2))};K.Min=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;return p<B?p:B};K.MinV=function(p,B){return new A(K.Min(p.x,B.x),K.Min(p.y,B.y))};
K.Max=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;return p>B?p:B};K.MaxV=function(p,B){return new A(K.Max(p.x,B.x),K.Max(p.y,B.y))};K.Clamp=function(p,B,Q){if(p===undefined)p=0;if(B===undefined)B=0;if(Q===undefined)Q=0;return p<B?B:p>Q?Q:p};K.ClampV=function(p,B,Q){return K.MaxV(B,K.MinV(p,Q))};K.Swap=function(p,B){var Q=p[0];p[0]=B[0];B[0]=Q};K.Random=function(){return Math.random()*2-1};K.RandomRange=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;var Q=Math.random();return Q=
(B-p)*Q+p};K.NextPowerOfTwo=function(p){if(p===undefined)p=0;p|=p>>1&2147483647;p|=p>>2&1073741823;p|=p>>4&268435455;p|=p>>8&16777215;p|=p>>16&65535;return p+1};K.IsPowerOfTwo=function(p){if(p===undefined)p=0;return p>0&&(p&p-1)==0};Box2D.postDefs.push(function(){Box2D.Common.Math.b2Math.b2Vec2_zero=new A(0,0);Box2D.Common.Math.b2Math.b2Mat22_identity=F.FromVV(new A(1,0),new A(0,1));Box2D.Common.Math.b2Math.b2Transform_identity=new w(K.b2Vec2_zero,K.b2Mat22_identity)});y.b2Sweep=function(){this.localCenter=
new A;this.c0=new A;this.c=new A};y.prototype.Set=function(p){this.localCenter.SetV(p.localCenter);this.c0.SetV(p.c0);this.c.SetV(p.c);this.a0=p.a0;this.a=p.a;this.t0=p.t0};y.prototype.Copy=function(){var p=new y;p.localCenter.SetV(this.localCenter);p.c0.SetV(this.c0);p.c.SetV(this.c);p.a0=this.a0;p.a=this.a;p.t0=this.t0;return p};y.prototype.GetTransform=function(p,B){if(B===undefined)B=0;p.position.x=(1-B)*this.c0.x+B*this.c.x;p.position.y=(1-B)*this.c0.y+B*this.c.y;p.R.Set((1-B)*this.a0+B*this.a);
var Q=p.R;p.position.x-=Q.col1.x*this.localCenter.x+Q.col2.x*this.localCenter.y;p.position.y-=Q.col1.y*this.localCenter.x+Q.col2.y*this.localCenter.y};y.prototype.Advance=function(p){if(p===undefined)p=0;if(this.t0<p&&1-this.t0>Number.MIN_VALUE){var B=(p-this.t0)/(1-this.t0);this.c0.x=(1-B)*this.c0.x+B*this.c.x;this.c0.y=(1-B)*this.c0.y+B*this.c.y;this.a0=(1-B)*this.a0+B*this.a;this.t0=p}};w.b2Transform=function(){this.position=new A;this.R=new F};w.prototype.b2Transform=function(p,B){if(p===undefined)p=
null;if(B===undefined)B=null;if(p){this.position.SetV(p);this.R.SetM(B)}};w.prototype.Initialize=function(p,B){this.position.SetV(p);this.R.SetM(B)};w.prototype.SetIdentity=function(){this.position.SetZero();this.R.SetIdentity()};w.prototype.Set=function(p){this.position.SetV(p.position);this.R.SetM(p.R)};w.prototype.GetAngle=function(){return Math.atan2(this.R.col1.y,this.R.col1.x)};A.b2Vec2=function(){};A.prototype.b2Vec2=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;this.x=p;this.y=B};
A.prototype.SetZero=function(){this.y=this.x=0};A.prototype.Set=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;this.x=p;this.y=B};A.prototype.SetV=function(p){this.x=p.x;this.y=p.y};A.prototype.GetNegative=function(){return new A(-this.x,-this.y)};A.prototype.NegativeSelf=function(){this.x=-this.x;this.y=-this.y};A.Make=function(p,B){if(p===undefined)p=0;if(B===undefined)B=0;return new A(p,B)};A.prototype.Copy=function(){return new A(this.x,this.y)};A.prototype.Add=function(p){this.x+=p.x;
this.y+=p.y};A.prototype.Subtract=function(p){this.x-=p.x;this.y-=p.y};A.prototype.Multiply=function(p){if(p===undefined)p=0;this.x*=p;this.y*=p};A.prototype.MulM=function(p){var B=this.x;this.x=p.col1.x*B+p.col2.x*this.y;this.y=p.col1.y*B+p.col2.y*this.y};A.prototype.MulTM=function(p){var B=K.Dot(this,p.col1);this.y=K.Dot(this,p.col2);this.x=B};A.prototype.CrossVF=function(p){if(p===undefined)p=0;var B=this.x;this.x=p*this.y;this.y=-p*B};A.prototype.CrossFV=function(p){if(p===undefined)p=0;var B=
this.x;this.x=-p*this.y;this.y=p*B};A.prototype.MinV=function(p){this.x=this.x<p.x?this.x:p.x;this.y=this.y<p.y?this.y:p.y};A.prototype.MaxV=function(p){this.x=this.x>p.x?this.x:p.x;this.y=this.y>p.y?this.y:p.y};A.prototype.Abs=function(){if(this.x<0)this.x=-this.x;if(this.y<0)this.y=-this.y};A.prototype.Length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)};A.prototype.LengthSquared=function(){return this.x*this.x+this.y*this.y};A.prototype.Normalize=function(){var p=Math.sqrt(this.x*this.x+
this.y*this.y);if(p<Number.MIN_VALUE)return 0;var B=1/p;this.x*=B;this.y*=B;return p};A.prototype.IsValid=function(){return K.IsValid(this.x)&&K.IsValid(this.y)};U.b2Vec3=function(){};U.prototype.b2Vec3=function(p,B,Q){if(p===undefined)p=0;if(B===undefined)B=0;if(Q===undefined)Q=0;this.x=p;this.y=B;this.z=Q};U.prototype.SetZero=function(){this.x=this.y=this.z=0};U.prototype.Set=function(p,B,Q){if(p===undefined)p=0;if(B===undefined)B=0;if(Q===undefined)Q=0;this.x=p;this.y=B;this.z=Q};U.prototype.SetV=
function(p){this.x=p.x;this.y=p.y;this.z=p.z};U.prototype.GetNegative=function(){return new U(-this.x,-this.y,-this.z)};U.prototype.NegativeSelf=function(){this.x=-this.x;this.y=-this.y;this.z=-this.z};U.prototype.Copy=function(){return new U(this.x,this.y,this.z)};U.prototype.Add=function(p){this.x+=p.x;this.y+=p.y;this.z+=p.z};U.prototype.Subtract=function(p){this.x-=p.x;this.y-=p.y;this.z-=p.z};U.prototype.Multiply=function(p){if(p===undefined)p=0;this.x*=p;this.y*=p;this.z*=p}})();
(function(){var F=Box2D.Common.Math.b2Math,G=Box2D.Common.Math.b2Sweep,K=Box2D.Common.Math.b2Transform,y=Box2D.Common.Math.b2Vec2,w=Box2D.Common.b2Color,A=Box2D.Common.b2Settings,U=Box2D.Collision.b2AABB,p=Box2D.Collision.b2ContactPoint,B=Box2D.Collision.b2DynamicTreeBroadPhase,Q=Box2D.Collision.b2RayCastInput,V=Box2D.Collision.b2RayCastOutput,M=Box2D.Collision.Shapes.b2CircleShape,L=Box2D.Collision.Shapes.b2EdgeShape,I=Box2D.Collision.Shapes.b2MassData,W=Box2D.Collision.Shapes.b2PolygonShape,Y=Box2D.Collision.Shapes.b2Shape,
k=Box2D.Dynamics.b2Body,z=Box2D.Dynamics.b2BodyDef,u=Box2D.Dynamics.b2ContactFilter,D=Box2D.Dynamics.b2ContactImpulse,H=Box2D.Dynamics.b2ContactListener,O=Box2D.Dynamics.b2ContactManager,E=Box2D.Dynamics.b2DebugDraw,R=Box2D.Dynamics.b2DestructionListener,N=Box2D.Dynamics.b2FilterData,S=Box2D.Dynamics.b2Fixture,aa=Box2D.Dynamics.b2FixtureDef,Z=Box2D.Dynamics.b2Island,d=Box2D.Dynamics.b2TimeStep,h=Box2D.Dynamics.b2World,l=Box2D.Dynamics.Contacts.b2Contact,j=Box2D.Dynamics.Contacts.b2ContactFactory,
o=Box2D.Dynamics.Contacts.b2ContactSolver,q=Box2D.Dynamics.Joints.b2Joint,n=Box2D.Dynamics.Joints.b2PulleyJoint;k.b2Body=function(){this.m_xf=new K;this.m_sweep=new G;this.m_linearVelocity=new y;this.m_force=new y};k.prototype.connectEdges=function(a,c,g){if(g===undefined)g=0;var b=Math.atan2(c.GetDirectionVector().y,c.GetDirectionVector().x);g=F.MulFV(Math.tan((b-g)*0.5),c.GetDirectionVector());g=F.SubtractVV(g,c.GetNormalVector());g=F.MulFV(A.b2_toiSlop,g);g=F.AddVV(g,c.GetVertex1());var e=F.AddVV(a.GetDirectionVector(),
c.GetDirectionVector());e.Normalize();var f=F.Dot(a.GetDirectionVector(),c.GetNormalVector())>0;a.SetNextEdge(c,g,e,f);c.SetPrevEdge(a,g,e,f);return b};k.prototype.CreateFixture=function(a){if(this.m_world.IsLocked()==true)return null;var c=new S;c.Create(this,this.m_xf,a);this.m_flags&k.e_activeFlag&&c.CreateProxy(this.m_world.m_contactManager.m_broadPhase,this.m_xf);c.m_next=this.m_fixtureList;this.m_fixtureList=c;++this.m_fixtureCount;c.m_body=this;c.m_density>0&&this.ResetMassData();this.m_world.m_flags|=
h.e_newFixture;return c};k.prototype.CreateFixture2=function(a,c){if(c===undefined)c=0;var g=new aa;g.shape=a;g.density=c;return this.CreateFixture(g)};k.prototype.DestroyFixture=function(a){if(this.m_world.IsLocked()!=true){for(var c=this.m_fixtureList,g=null;c!=null;){if(c==a){if(g)g.m_next=a.m_next;else this.m_fixtureList=a.m_next;break}g=c;c=c.m_next}for(c=this.m_contactList;c;){g=c.contact;c=c.next;var b=g.GetFixtureA(),e=g.GetFixtureB();if(a==b||a==e)this.m_world.m_contactManager.Destroy(g)}this.m_flags&
k.e_activeFlag&&a.DestroyProxy(this.m_world.m_contactManager.m_broadPhase);a.Destroy();a.m_body=null;a.m_next=null;--this.m_fixtureCount;this.ResetMassData()}};k.prototype.SetPositionAndAngle=function(a,c){if(c===undefined)c=0;var g;if(this.m_world.IsLocked()!=true){this.m_xf.R.Set(c);this.m_xf.position.SetV(a);g=this.m_xf.R;var b=this.m_sweep.localCenter;this.m_sweep.c.x=g.col1.x*b.x+g.col2.x*b.y;this.m_sweep.c.y=g.col1.y*b.x+g.col2.y*b.y;this.m_sweep.c.x+=this.m_xf.position.x;this.m_sweep.c.y+=
this.m_xf.position.y;this.m_sweep.c0.SetV(this.m_sweep.c);this.m_sweep.a0=this.m_sweep.a=c;b=this.m_world.m_contactManager.m_broadPhase;for(g=this.m_fixtureList;g;g=g.m_next)g.Synchronize(b,this.m_xf,this.m_xf);this.m_world.m_contactManager.FindNewContacts()}};k.prototype.SetTransform=function(a){this.SetPositionAndAngle(a.position,a.GetAngle())};k.prototype.GetTransform=function(){return this.m_xf};k.prototype.GetPosition=function(){return this.m_xf.position};k.prototype.SetPosition=function(a){this.SetPositionAndAngle(a,
this.GetAngle())};k.prototype.GetAngle=function(){return this.m_sweep.a};k.prototype.SetAngle=function(a){if(a===undefined)a=0;this.SetPositionAndAngle(this.GetPosition(),a)};k.prototype.GetWorldCenter=function(){return this.m_sweep.c};k.prototype.GetLocalCenter=function(){return this.m_sweep.localCenter};k.prototype.SetLinearVelocity=function(a){this.m_type!=k.b2_staticBody&&this.m_linearVelocity.SetV(a)};k.prototype.GetLinearVelocity=function(){return this.m_linearVelocity};k.prototype.SetAngularVelocity=
function(a){if(a===undefined)a=0;if(this.m_type!=k.b2_staticBody)this.m_angularVelocity=a};k.prototype.GetAngularVelocity=function(){return this.m_angularVelocity};k.prototype.GetDefinition=function(){var a=new z;a.type=this.GetType();a.allowSleep=(this.m_flags&k.e_allowSleepFlag)==k.e_allowSleepFlag;a.angle=this.GetAngle();a.angularDamping=this.m_angularDamping;a.angularVelocity=this.m_angularVelocity;a.fixedRotation=(this.m_flags&k.e_fixedRotationFlag)==k.e_fixedRotationFlag;a.bullet=(this.m_flags&
k.e_bulletFlag)==k.e_bulletFlag;a.awake=(this.m_flags&k.e_awakeFlag)==k.e_awakeFlag;a.linearDamping=this.m_linearDamping;a.linearVelocity.SetV(this.GetLinearVelocity());a.position=this.GetPosition();a.userData=this.GetUserData();return a};k.prototype.ApplyForce=function(a,c){if(this.m_type==k.b2_dynamicBody){this.IsAwake()==false&&this.SetAwake(true);this.m_force.x+=a.x;this.m_force.y+=a.y;this.m_torque+=(c.x-this.m_sweep.c.x)*a.y-(c.y-this.m_sweep.c.y)*a.x}};k.prototype.ApplyTorque=function(a){if(a===
undefined)a=0;if(this.m_type==k.b2_dynamicBody){this.IsAwake()==false&&this.SetAwake(true);this.m_torque+=a}};k.prototype.ApplyImpulse=function(a,c){if(this.m_type==k.b2_dynamicBody){this.IsAwake()==false&&this.SetAwake(true);this.m_linearVelocity.x+=this.m_invMass*a.x;this.m_linearVelocity.y+=this.m_invMass*a.y;this.m_angularVelocity+=this.m_invI*((c.x-this.m_sweep.c.x)*a.y-(c.y-this.m_sweep.c.y)*a.x)}};k.prototype.Split=function(a){for(var c=this.GetLinearVelocity().Copy(),g=this.GetAngularVelocity(),
b=this.GetWorldCenter(),e=this.m_world.CreateBody(this.GetDefinition()),f,m=this.m_fixtureList;m;)if(a(m)){var r=m.m_next;if(f)f.m_next=r;else this.m_fixtureList=r;this.m_fixtureCount--;m.m_next=e.m_fixtureList;e.m_fixtureList=m;e.m_fixtureCount++;m.m_body=e;m=r}else{f=m;m=m.m_next}this.ResetMassData();e.ResetMassData();f=this.GetWorldCenter();a=e.GetWorldCenter();f=F.AddVV(c,F.CrossFV(g,F.SubtractVV(f,b)));c=F.AddVV(c,F.CrossFV(g,F.SubtractVV(a,b)));this.SetLinearVelocity(f);e.SetLinearVelocity(c);
this.SetAngularVelocity(g);e.SetAngularVelocity(g);this.SynchronizeFixtures();e.SynchronizeFixtures();return e};k.prototype.Merge=function(a){var c;for(c=a.m_fixtureList;c;){var g=c.m_next;a.m_fixtureCount--;c.m_next=this.m_fixtureList;this.m_fixtureList=c;this.m_fixtureCount++;c.m_body=e;c=g}b.m_fixtureCount=0;var b=this,e=a;b.GetWorldCenter();e.GetWorldCenter();b.GetLinearVelocity().Copy();e.GetLinearVelocity().Copy();b.GetAngularVelocity();e.GetAngularVelocity();b.ResetMassData();this.SynchronizeFixtures()};
k.prototype.GetMass=function(){return this.m_mass};k.prototype.GetInertia=function(){return this.m_I};k.prototype.GetMassData=function(a){a.mass=this.m_mass;a.I=this.m_I;a.center.SetV(this.m_sweep.localCenter)};k.prototype.SetMassData=function(a){A.b2Assert(this.m_world.IsLocked()==false);if(this.m_world.IsLocked()!=true)if(this.m_type==k.b2_dynamicBody){this.m_invI=this.m_I=this.m_invMass=0;this.m_mass=a.mass;if(this.m_mass<=0)this.m_mass=1;this.m_invMass=1/this.m_mass;if(a.I>0&&(this.m_flags&k.e_fixedRotationFlag)==
0){this.m_I=a.I-this.m_mass*(a.center.x*a.center.x+a.center.y*a.center.y);this.m_invI=1/this.m_I}var c=this.m_sweep.c.Copy();this.m_sweep.localCenter.SetV(a.center);this.m_sweep.c0.SetV(F.MulX(this.m_xf,this.m_sweep.localCenter));this.m_sweep.c.SetV(this.m_sweep.c0);this.m_linearVelocity.x+=this.m_angularVelocity*-(this.m_sweep.c.y-c.y);this.m_linearVelocity.y+=this.m_angularVelocity*+(this.m_sweep.c.x-c.x)}};k.prototype.ResetMassData=function(){this.m_invI=this.m_I=this.m_invMass=this.m_mass=0;this.m_sweep.localCenter.SetZero();
if(!(this.m_type==k.b2_staticBody||this.m_type==k.b2_kinematicBody)){for(var a=y.Make(0,0),c=this.m_fixtureList;c;c=c.m_next)if(c.m_density!=0){var g=c.GetMassData();this.m_mass+=g.mass;a.x+=g.center.x*g.mass;a.y+=g.center.y*g.mass;this.m_I+=g.I}if(this.m_mass>0){this.m_invMass=1/this.m_mass;a.x*=this.m_invMass;a.y*=this.m_invMass}else this.m_invMass=this.m_mass=1;if(this.m_I>0&&(this.m_flags&k.e_fixedRotationFlag)==0){this.m_I-=this.m_mass*(a.x*a.x+a.y*a.y);this.m_I*=this.m_inertiaScale;A.b2Assert(this.m_I>
0);this.m_invI=1/this.m_I}else this.m_invI=this.m_I=0;c=this.m_sweep.c.Copy();this.m_sweep.localCenter.SetV(a);this.m_sweep.c0.SetV(F.MulX(this.m_xf,this.m_sweep.localCenter));this.m_sweep.c.SetV(this.m_sweep.c0);this.m_linearVelocity.x+=this.m_angularVelocity*-(this.m_sweep.c.y-c.y);this.m_linearVelocity.y+=this.m_angularVelocity*+(this.m_sweep.c.x-c.x)}};k.prototype.GetWorldPoint=function(a){var c=this.m_xf.R;a=new y(c.col1.x*a.x+c.col2.x*a.y,c.col1.y*a.x+c.col2.y*a.y);a.x+=this.m_xf.position.x;
a.y+=this.m_xf.position.y;return a};k.prototype.GetWorldVector=function(a){return F.MulMV(this.m_xf.R,a)};k.prototype.GetLocalPoint=function(a){return F.MulXT(this.m_xf,a)};k.prototype.GetLocalVector=function(a){return F.MulTMV(this.m_xf.R,a)};k.prototype.GetLinearVelocityFromWorldPoint=function(a){return new y(this.m_linearVelocity.x-this.m_angularVelocity*(a.y-this.m_sweep.c.y),this.m_linearVelocity.y+this.m_angularVelocity*(a.x-this.m_sweep.c.x))};k.prototype.GetLinearVelocityFromLocalPoint=function(a){var c=
this.m_xf.R;a=new y(c.col1.x*a.x+c.col2.x*a.y,c.col1.y*a.x+c.col2.y*a.y);a.x+=this.m_xf.position.x;a.y+=this.m_xf.position.y;return new y(this.m_linearVelocity.x-this.m_angularVelocity*(a.y-this.m_sweep.c.y),this.m_linearVelocity.y+this.m_angularVelocity*(a.x-this.m_sweep.c.x))};k.prototype.GetLinearDamping=function(){return this.m_linearDamping};k.prototype.SetLinearDamping=function(a){if(a===undefined)a=0;this.m_linearDamping=a};k.prototype.GetAngularDamping=function(){return this.m_angularDamping};
k.prototype.SetAngularDamping=function(a){if(a===undefined)a=0;this.m_angularDamping=a};k.prototype.SetType=function(a){if(a===undefined)a=0;if(this.m_type!=a){this.m_type=a;this.ResetMassData();if(this.m_type==k.b2_staticBody){this.m_linearVelocity.SetZero();this.m_angularVelocity=0}this.SetAwake(true);this.m_force.SetZero();this.m_torque=0;for(a=this.m_contactList;a;a=a.next)a.contact.FlagForFiltering()}};k.prototype.GetType=function(){return this.m_type};k.prototype.SetBullet=function(a){if(a)this.m_flags|=
k.e_bulletFlag;else this.m_flags&=~k.e_bulletFlag};k.prototype.IsBullet=function(){return(this.m_flags&k.e_bulletFlag)==k.e_bulletFlag};k.prototype.SetSleepingAllowed=function(a){if(a)this.m_flags|=k.e_allowSleepFlag;else{this.m_flags&=~k.e_allowSleepFlag;this.SetAwake(true)}};k.prototype.SetAwake=function(a){if(a){this.m_flags|=k.e_awakeFlag;this.m_sleepTime=0}else{this.m_flags&=~k.e_awakeFlag;this.m_sleepTime=0;this.m_linearVelocity.SetZero();this.m_angularVelocity=0;this.m_force.SetZero();this.m_torque=
0}};k.prototype.IsAwake=function(){return(this.m_flags&k.e_awakeFlag)==k.e_awakeFlag};k.prototype.SetFixedRotation=function(a){if(a)this.m_flags|=k.e_fixedRotationFlag;else this.m_flags&=~k.e_fixedRotationFlag;this.ResetMassData()};k.prototype.IsFixedRotation=function(){return(this.m_flags&k.e_fixedRotationFlag)==k.e_fixedRotationFlag};k.prototype.SetActive=function(a){if(a!=this.IsActive()){var c;if(a){this.m_flags|=k.e_activeFlag;a=this.m_world.m_contactManager.m_broadPhase;for(c=this.m_fixtureList;c;c=
c.m_next)c.CreateProxy(a,this.m_xf)}else{this.m_flags&=~k.e_activeFlag;a=this.m_world.m_contactManager.m_broadPhase;for(c=this.m_fixtureList;c;c=c.m_next)c.DestroyProxy(a);for(a=this.m_contactList;a;){c=a;a=a.next;this.m_world.m_contactManager.Destroy(c.contact)}this.m_contactList=null}}};k.prototype.IsActive=function(){return(this.m_flags&k.e_activeFlag)==k.e_activeFlag};k.prototype.IsSleepingAllowed=function(){return(this.m_flags&k.e_allowSleepFlag)==k.e_allowSleepFlag};k.prototype.GetFixtureList=
function(){return this.m_fixtureList};k.prototype.GetJointList=function(){return this.m_jointList};k.prototype.GetControllerList=function(){return this.m_controllerList};k.prototype.GetContactList=function(){return this.m_contactList};k.prototype.GetNext=function(){return this.m_next};k.prototype.GetUserData=function(){return this.m_userData};k.prototype.SetUserData=function(a){this.m_userData=a};k.prototype.GetWorld=function(){return this.m_world};k.prototype.b2Body=function(a,c){this.m_flags=0;
if(a.bullet)this.m_flags|=k.e_bulletFlag;if(a.fixedRotation)this.m_flags|=k.e_fixedRotationFlag;if(a.allowSleep)this.m_flags|=k.e_allowSleepFlag;if(a.awake)this.m_flags|=k.e_awakeFlag;if(a.active)this.m_flags|=k.e_activeFlag;this.m_world=c;this.m_xf.position.SetV(a.position);this.m_xf.R.Set(a.angle);this.m_sweep.localCenter.SetZero();this.m_sweep.t0=1;this.m_sweep.a0=this.m_sweep.a=a.angle;var g=this.m_xf.R,b=this.m_sweep.localCenter;this.m_sweep.c.x=g.col1.x*b.x+g.col2.x*b.y;this.m_sweep.c.y=g.col1.y*
b.x+g.col2.y*b.y;this.m_sweep.c.x+=this.m_xf.position.x;this.m_sweep.c.y+=this.m_xf.position.y;this.m_sweep.c0.SetV(this.m_sweep.c);this.m_contactList=this.m_controllerList=this.m_jointList=null;this.m_controllerCount=0;this.m_next=this.m_prev=null;this.m_linearVelocity.SetV(a.linearVelocity);this.m_angularVelocity=a.angularVelocity;this.m_linearDamping=a.linearDamping;this.m_angularDamping=a.angularDamping;this.m_force.Set(0,0);this.m_sleepTime=this.m_torque=0;this.m_type=a.type;if(this.m_type==
k.b2_dynamicBody)this.m_invMass=this.m_mass=1;else this.m_invMass=this.m_mass=0;this.m_invI=this.m_I=0;this.m_inertiaScale=a.inertiaScale;this.m_userData=a.userData;this.m_fixtureList=null;this.m_fixtureCount=0};k.prototype.SynchronizeFixtures=function(){var a=k.s_xf1;a.R.Set(this.m_sweep.a0);var c=a.R,g=this.m_sweep.localCenter;a.position.x=this.m_sweep.c0.x-(c.col1.x*g.x+c.col2.x*g.y);a.position.y=this.m_sweep.c0.y-(c.col1.y*g.x+c.col2.y*g.y);g=this.m_world.m_contactManager.m_broadPhase;for(c=this.m_fixtureList;c;c=
c.m_next)c.Synchronize(g,a,this.m_xf)};k.prototype.SynchronizeTransform=function(){this.m_xf.R.Set(this.m_sweep.a);var a=this.m_xf.R,c=this.m_sweep.localCenter;this.m_xf.position.x=this.m_sweep.c.x-(a.col1.x*c.x+a.col2.x*c.y);this.m_xf.position.y=this.m_sweep.c.y-(a.col1.y*c.x+a.col2.y*c.y)};k.prototype.ShouldCollide=function(a){if(this.m_type!=k.b2_dynamicBody&&a.m_type!=k.b2_dynamicBody)return false;for(var c=this.m_jointList;c;c=c.next)if(c.other==a)if(c.joint.m_collideConnected==false)return false;
return true};k.prototype.Advance=function(a){if(a===undefined)a=0;this.m_sweep.Advance(a);this.m_sweep.c.SetV(this.m_sweep.c0);this.m_sweep.a=this.m_sweep.a0;this.SynchronizeTransform()};Box2D.postDefs.push(function(){Box2D.Dynamics.b2Body.s_xf1=new K;Box2D.Dynamics.b2Body.e_islandFlag=1;Box2D.Dynamics.b2Body.e_awakeFlag=2;Box2D.Dynamics.b2Body.e_allowSleepFlag=4;Box2D.Dynamics.b2Body.e_bulletFlag=8;Box2D.Dynamics.b2Body.e_fixedRotationFlag=16;Box2D.Dynamics.b2Body.e_activeFlag=32;Box2D.Dynamics.b2Body.b2_staticBody=
0;Box2D.Dynamics.b2Body.b2_kinematicBody=1;Box2D.Dynamics.b2Body.b2_dynamicBody=2});z.b2BodyDef=function(){this.position=new y;this.linearVelocity=new y};z.prototype.b2BodyDef=function(){this.userData=null;this.position.Set(0,0);this.angle=0;this.linearVelocity.Set(0,0);this.angularDamping=this.linearDamping=this.angularVelocity=0;this.awake=this.allowSleep=true;this.bullet=this.fixedRotation=false;this.type=k.b2_staticBody;this.active=true;this.inertiaScale=1};u.b2ContactFilter=function(){};u.prototype.ShouldCollide=
function(a,c){var g=a.GetFilterData(),b=c.GetFilterData();if(g.groupIndex==b.groupIndex&&g.groupIndex!=0)return g.groupIndex>0;return(g.maskBits&b.categoryBits)!=0&&(g.categoryBits&b.maskBits)!=0};u.prototype.RayCollide=function(a,c){if(!a)return true;return this.ShouldCollide(a instanceof S?a:null,c)};Box2D.postDefs.push(function(){Box2D.Dynamics.b2ContactFilter.b2_defaultFilter=new u});D.b2ContactImpulse=function(){this.normalImpulses=new Vector_a2j_Number(A.b2_maxManifoldPoints);this.tangentImpulses=
new Vector_a2j_Number(A.b2_maxManifoldPoints)};H.b2ContactListener=function(){};H.prototype.BeginContact=function(){};H.prototype.EndContact=function(){};H.prototype.PreSolve=function(){};H.prototype.PostSolve=function(){};Box2D.postDefs.push(function(){Box2D.Dynamics.b2ContactListener.b2_defaultListener=new H});O.b2ContactManager=function(){};O.prototype.b2ContactManager=function(){this.m_world=null;this.m_contactCount=0;this.m_contactFilter=u.b2_defaultFilter;this.m_contactListener=H.b2_defaultListener;
this.m_contactFactory=new j(this.m_allocator);this.m_broadPhase=new B};O.prototype.AddPair=function(a,c){var g=a instanceof S?a:null,b=c instanceof S?c:null,e=g.GetBody(),f=b.GetBody();if(e!=f){for(var m=f.GetContactList();m;){if(m.other==e){var r=m.contact.GetFixtureA(),s=m.contact.GetFixtureB();if(r==g&&s==b)return;if(r==b&&s==g)return}m=m.next}if(f.ShouldCollide(e)!=false)if(this.m_contactFilter.ShouldCollide(g,b)!=false){m=this.m_contactFactory.Create(g,b);g=m.GetFixtureA();b=m.GetFixtureB();
e=g.m_body;f=b.m_body;m.m_prev=null;m.m_next=this.m_world.m_contactList;if(this.m_world.m_contactList!=null)this.m_world.m_contactList.m_prev=m;this.m_world.m_contactList=m;m.m_nodeA.contact=m;m.m_nodeA.other=f;m.m_nodeA.prev=null;m.m_nodeA.next=e.m_contactList;if(e.m_contactList!=null)e.m_contactList.prev=m.m_nodeA;e.m_contactList=m.m_nodeA;m.m_nodeB.contact=m;m.m_nodeB.other=e;m.m_nodeB.prev=null;m.m_nodeB.next=f.m_contactList;if(f.m_contactList!=null)f.m_contactList.prev=m.m_nodeB;f.m_contactList=
m.m_nodeB;++this.m_world.m_contactCount}}};O.prototype.FindNewContacts=function(){this.m_broadPhase.UpdatePairs(Box2D.generateCallback(this,this.AddPair))};O.prototype.Destroy=function(a){var c=a.GetFixtureA(),g=a.GetFixtureB();c=c.GetBody();g=g.GetBody();a.IsTouching()&&this.m_contactListener.EndContact(a);if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(a==this.m_world.m_contactList)this.m_world.m_contactList=a.m_next;if(a.m_nodeA.prev)a.m_nodeA.prev.next=a.m_nodeA.next;
if(a.m_nodeA.next)a.m_nodeA.next.prev=a.m_nodeA.prev;if(a.m_nodeA==c.m_contactList)c.m_contactList=a.m_nodeA.next;if(a.m_nodeB.prev)a.m_nodeB.prev.next=a.m_nodeB.next;if(a.m_nodeB.next)a.m_nodeB.next.prev=a.m_nodeB.prev;if(a.m_nodeB==g.m_contactList)g.m_contactList=a.m_nodeB.next;this.m_contactFactory.Destroy(a);--this.m_contactCount};O.prototype.Collide=function(){for(var a=this.m_world.m_contactList;a;){var c=a.GetFixtureA(),g=a.GetFixtureB(),b=c.GetBody(),e=g.GetBody();if(b.IsAwake()==false&&e.IsAwake()==
false)a=a.GetNext();else{if(a.m_flags&l.e_filterFlag){if(e.ShouldCollide(b)==false){c=a;a=c.GetNext();this.Destroy(c);continue}if(this.m_contactFilter.ShouldCollide(c,g)==false){c=a;a=c.GetNext();this.Destroy(c);continue}a.m_flags&=~l.e_filterFlag}if(this.m_broadPhase.TestOverlap(c.m_proxy,g.m_proxy)==false){c=a;a=c.GetNext();this.Destroy(c)}else{a.Update(this.m_contactListener);a=a.GetNext()}}}};Box2D.postDefs.push(function(){Box2D.Dynamics.b2ContactManager.s_evalCP=new p});E.b2DebugDraw=function(){};
E.prototype.b2DebugDraw=function(){};E.prototype.SetFlags=function(){};E.prototype.GetFlags=function(){};E.prototype.AppendFlags=function(){};E.prototype.ClearFlags=function(){};E.prototype.SetSprite=function(){};E.prototype.GetSprite=function(){};E.prototype.SetDrawScale=function(){};E.prototype.GetDrawScale=function(){};E.prototype.SetLineThickness=function(){};E.prototype.GetLineThickness=function(){};E.prototype.SetAlpha=function(){};E.prototype.GetAlpha=function(){};E.prototype.SetFillAlpha=
function(){};E.prototype.GetFillAlpha=function(){};E.prototype.SetXFormScale=function(){};E.prototype.GetXFormScale=function(){};E.prototype.DrawPolygon=function(){};E.prototype.DrawSolidPolygon=function(){};E.prototype.DrawCircle=function(){};E.prototype.DrawSolidCircle=function(){};E.prototype.DrawSegment=function(){};E.prototype.DrawTransform=function(){};Box2D.postDefs.push(function(){Box2D.Dynamics.b2DebugDraw.e_shapeBit=1;Box2D.Dynamics.b2DebugDraw.e_jointBit=2;Box2D.Dynamics.b2DebugDraw.e_aabbBit=
4;Box2D.Dynamics.b2DebugDraw.e_pairBit=8;Box2D.Dynamics.b2DebugDraw.e_centerOfMassBit=16;Box2D.Dynamics.b2DebugDraw.e_controllerBit=32});R.b2DestructionListener=function(){};R.prototype.SayGoodbyeJoint=function(){};R.prototype.SayGoodbyeFixture=function(){};N.b2FilterData=function(){this.categoryBits=1;this.maskBits=65535;this.groupIndex=0};N.prototype.Copy=function(){var a=new N;a.categoryBits=this.categoryBits;a.maskBits=this.maskBits;a.groupIndex=this.groupIndex;return a};S.b2Fixture=function(){this.m_filter=
new N};S.prototype.GetType=function(){return this.m_shape.GetType()};S.prototype.GetShape=function(){return this.m_shape};S.prototype.SetSensor=function(a){if(this.m_isSensor!=a){this.m_isSensor=a;if(this.m_body!=null)for(a=this.m_body.GetContactList();a;){var c=a.contact,g=c.GetFixtureA(),b=c.GetFixtureB();if(g==this||b==this)c.SetSensor(g.IsSensor()||b.IsSensor());a=a.next}}};S.prototype.IsSensor=function(){return this.m_isSensor};S.prototype.SetFilterData=function(a){this.m_filter=a.Copy();if(!this.m_body)for(a=
this.m_body.GetContactList();a;){var c=a.contact,g=c.GetFixtureA(),b=c.GetFixtureB();if(g==this||b==this)c.FlagForFiltering();a=a.next}};S.prototype.GetFilterData=function(){return this.m_filter.Copy()};S.prototype.GetBody=function(){return this.m_body};S.prototype.GetNext=function(){return this.m_next};S.prototype.GetUserData=function(){return this.m_userData};S.prototype.SetUserData=function(a){this.m_userData=a};S.prototype.TestPoint=function(a){return this.m_shape.TestPoint(this.m_body.GetTransform(),
a)};S.prototype.RayCast=function(a,c){return this.m_shape.RayCast(a,c,this.m_body.GetTransform())};S.prototype.GetMassData=function(a){if(a===undefined)a=null;if(a==null)a=new I;this.m_shape.ComputeMass(a,this.m_density);return a};S.prototype.SetDensity=function(a){if(a===undefined)a=0;this.m_density=a};S.prototype.GetDensity=function(){return this.m_density};S.prototype.GetFriction=function(){return this.m_friction};S.prototype.SetFriction=function(a){if(a===undefined)a=0;this.m_friction=a};S.prototype.GetRestitution=
function(){return this.m_restitution};S.prototype.SetRestitution=function(a){if(a===undefined)a=0;this.m_restitution=a};S.prototype.GetAABB=function(){return this.m_aabb};S.prototype.b2Fixture=function(){this.m_aabb=new U;this.m_shape=this.m_next=this.m_body=this.m_userData=null;this.m_restitution=this.m_friction=this.m_density=0};S.prototype.Create=function(a,c,g){this.m_userData=g.userData;this.m_friction=g.friction;this.m_restitution=g.restitution;this.m_body=a;this.m_next=null;this.m_filter=g.filter.Copy();
this.m_isSensor=g.isSensor;this.m_shape=g.shape.Copy();this.m_density=g.density};S.prototype.Destroy=function(){this.m_shape=null};S.prototype.CreateProxy=function(a,c){this.m_shape.ComputeAABB(this.m_aabb,c);this.m_proxy=a.CreateProxy(this.m_aabb,this)};S.prototype.DestroyProxy=function(a){if(this.m_proxy!=null){a.DestroyProxy(this.m_proxy);this.m_proxy=null}};S.prototype.Synchronize=function(a,c,g){if(this.m_proxy){var b=new U,e=new U;this.m_shape.ComputeAABB(b,c);this.m_shape.ComputeAABB(e,g);
this.m_aabb.Combine(b,e);c=F.SubtractVV(g.position,c.position);a.MoveProxy(this.m_proxy,this.m_aabb,c)}};aa.b2FixtureDef=function(){this.filter=new N};aa.prototype.b2FixtureDef=function(){this.userData=this.shape=null;this.friction=0.2;this.density=this.restitution=0;this.filter.categoryBits=1;this.filter.maskBits=65535;this.filter.groupIndex=0;this.isSensor=false};Z.b2Island=function(){};Z.prototype.b2Island=function(){this.m_bodies=new Vector;this.m_contacts=new Vector;this.m_joints=new Vector};
Z.prototype.Initialize=function(a,c,g,b,e,f){if(a===undefined)a=0;if(c===undefined)c=0;if(g===undefined)g=0;var m=0;this.m_bodyCapacity=a;this.m_contactCapacity=c;this.m_jointCapacity=g;this.m_jointCount=this.m_contactCount=this.m_bodyCount=0;this.m_allocator=b;this.m_listener=e;this.m_contactSolver=f;for(m=this.m_bodies.length;m<a;m++)this.m_bodies[m]=null;for(m=this.m_contacts.length;m<c;m++)this.m_contacts[m]=null;for(m=this.m_joints.length;m<g;m++)this.m_joints[m]=null};Z.prototype.Clear=function(){this.m_jointCount=
this.m_contactCount=this.m_bodyCount=0};Z.prototype.Solve=function(a,c,g){var b=0,e=0,f;for(b=0;b<this.m_bodyCount;++b){e=this.m_bodies[b];if(e.GetType()==k.b2_dynamicBody){e.m_linearVelocity.x+=a.dt*(c.x+e.m_invMass*e.m_force.x);e.m_linearVelocity.y+=a.dt*(c.y+e.m_invMass*e.m_force.y);e.m_angularVelocity+=a.dt*e.m_invI*e.m_torque;e.m_linearVelocity.Multiply(F.Clamp(1-a.dt*e.m_linearDamping,0,1));e.m_angularVelocity*=F.Clamp(1-a.dt*e.m_angularDamping,0,1)}}this.m_contactSolver.Initialize(a,this.m_contacts,
this.m_contactCount,this.m_allocator);c=this.m_contactSolver;c.InitVelocityConstraints(a);for(b=0;b<this.m_jointCount;++b){f=this.m_joints[b];f.InitVelocityConstraints(a)}for(b=0;b<a.velocityIterations;++b){for(e=0;e<this.m_jointCount;++e){f=this.m_joints[e];f.SolveVelocityConstraints(a)}c.SolveVelocityConstraints()}for(b=0;b<this.m_jointCount;++b){f=this.m_joints[b];f.FinalizeVelocityConstraints()}c.FinalizeVelocityConstraints();for(b=0;b<this.m_bodyCount;++b){e=this.m_bodies[b];if(e.GetType()!=
k.b2_staticBody){var m=a.dt*e.m_linearVelocity.x,r=a.dt*e.m_linearVelocity.y;if(m*m+r*r>A.b2_maxTranslationSquared){e.m_linearVelocity.Normalize();e.m_linearVelocity.x*=A.b2_maxTranslation*a.inv_dt;e.m_linearVelocity.y*=A.b2_maxTranslation*a.inv_dt}m=a.dt*e.m_angularVelocity;if(m*m>A.b2_maxRotationSquared)e.m_angularVelocity=e.m_angularVelocity<0?-A.b2_maxRotation*a.inv_dt:A.b2_maxRotation*a.inv_dt;e.m_sweep.c0.SetV(e.m_sweep.c);e.m_sweep.a0=e.m_sweep.a;e.m_sweep.c.x+=a.dt*e.m_linearVelocity.x;e.m_sweep.c.y+=
a.dt*e.m_linearVelocity.y;e.m_sweep.a+=a.dt*e.m_angularVelocity;e.SynchronizeTransform()}}for(b=0;b<a.positionIterations;++b){m=c.SolvePositionConstraints(A.b2_contactBaumgarte);r=true;for(e=0;e<this.m_jointCount;++e){f=this.m_joints[e];f=f.SolvePositionConstraints(A.b2_contactBaumgarte);r=r&&f}if(m&&r)break}this.Report(c.m_constraints);if(g){g=Number.MAX_VALUE;c=A.b2_linearSleepTolerance*A.b2_linearSleepTolerance;m=A.b2_angularSleepTolerance*A.b2_angularSleepTolerance;for(b=0;b<this.m_bodyCount;++b){e=
this.m_bodies[b];if(e.GetType()!=k.b2_staticBody){if((e.m_flags&k.e_allowSleepFlag)==0)g=e.m_sleepTime=0;if((e.m_flags&k.e_allowSleepFlag)==0||e.m_angularVelocity*e.m_angularVelocity>m||F.Dot(e.m_linearVelocity,e.m_linearVelocity)>c)g=e.m_sleepTime=0;else{e.m_sleepTime+=a.dt;g=F.Min(g,e.m_sleepTime)}}}if(g>=A.b2_timeToSleep)for(b=0;b<this.m_bodyCount;++b){e=this.m_bodies[b];e.SetAwake(false)}}};Z.prototype.SolveTOI=function(a){var c=0,g=0;this.m_contactSolver.Initialize(a,this.m_contacts,this.m_contactCount,
this.m_allocator);var b=this.m_contactSolver;for(c=0;c<this.m_jointCount;++c)this.m_joints[c].InitVelocityConstraints(a);for(c=0;c<a.velocityIterations;++c){b.SolveVelocityConstraints();for(g=0;g<this.m_jointCount;++g)this.m_joints[g].SolveVelocityConstraints(a)}for(c=0;c<this.m_bodyCount;++c){g=this.m_bodies[c];if(g.GetType()!=k.b2_staticBody){var e=a.dt*g.m_linearVelocity.x,f=a.dt*g.m_linearVelocity.y;if(e*e+f*f>A.b2_maxTranslationSquared){g.m_linearVelocity.Normalize();g.m_linearVelocity.x*=A.b2_maxTranslation*
a.inv_dt;g.m_linearVelocity.y*=A.b2_maxTranslation*a.inv_dt}e=a.dt*g.m_angularVelocity;if(e*e>A.b2_maxRotationSquared)g.m_angularVelocity=g.m_angularVelocity<0?-A.b2_maxRotation*a.inv_dt:A.b2_maxRotation*a.inv_dt;g.m_sweep.c0.SetV(g.m_sweep.c);g.m_sweep.a0=g.m_sweep.a;g.m_sweep.c.x+=a.dt*g.m_linearVelocity.x;g.m_sweep.c.y+=a.dt*g.m_linearVelocity.y;g.m_sweep.a+=a.dt*g.m_angularVelocity;g.SynchronizeTransform()}}for(c=0;c<a.positionIterations;++c){e=b.SolvePositionConstraints(0.75);f=true;for(g=0;g<
this.m_jointCount;++g){var m=this.m_joints[g].SolvePositionConstraints(A.b2_contactBaumgarte);f=f&&m}if(e&&f)break}this.Report(b.m_constraints)};Z.prototype.Report=function(a){if(this.m_listener!=null)for(var c=0;c<this.m_contactCount;++c){for(var g=this.m_contacts[c],b=a[c],e=0;e<b.pointCount;++e){Z.s_impulse.normalImpulses[e]=b.points[e].normalImpulse;Z.s_impulse.tangentImpulses[e]=b.points[e].tangentImpulse}this.m_listener.PostSolve(g,Z.s_impulse)}};Z.prototype.AddBody=function(a){a.m_islandIndex=
this.m_bodyCount;this.m_bodies[this.m_bodyCount++]=a};Z.prototype.AddContact=function(a){this.m_contacts[this.m_contactCount++]=a};Z.prototype.AddJoint=function(a){this.m_joints[this.m_jointCount++]=a};Box2D.postDefs.push(function(){Box2D.Dynamics.b2Island.s_impulse=new D});d.b2TimeStep=function(){};d.prototype.Set=function(a){this.dt=a.dt;this.inv_dt=a.inv_dt;this.positionIterations=a.positionIterations;this.velocityIterations=a.velocityIterations;this.warmStarting=a.warmStarting};h.b2World=function(){this.s_stack=
new Vector;this.m_contactManager=new O;this.m_contactSolver=new o;this.m_island=new Z};h.prototype.b2World=function(a,c){this.m_controllerList=this.m_jointList=this.m_contactList=this.m_bodyList=this.m_debugDraw=this.m_destructionListener=null;this.m_controllerCount=this.m_jointCount=this.m_contactCount=this.m_bodyCount=0;h.m_warmStarting=true;h.m_continuousPhysics=true;this.m_allowSleep=c;this.m_gravity=a;this.m_inv_dt0=0;this.m_contactManager.m_world=this;this.m_groundBody=this.CreateBody(new z)};
h.prototype.SetDestructionListener=function(a){this.m_destructionListener=a};h.prototype.SetContactFilter=function(a){this.m_contactManager.m_contactFilter=a};h.prototype.SetContactListener=function(a){this.m_contactManager.m_contactListener=a};h.prototype.SetDebugDraw=function(a){this.m_debugDraw=a};h.prototype.SetBroadPhase=function(a){var c=this.m_contactManager.m_broadPhase;this.m_contactManager.m_broadPhase=a;for(var g=this.m_bodyList;g;g=g.m_next)for(var b=g.m_fixtureList;b;b=b.m_next)b.m_proxy=
a.CreateProxy(c.GetFatAABB(b.m_proxy),b)};h.prototype.Validate=function(){this.m_contactManager.m_broadPhase.Validate()};h.prototype.GetProxyCount=function(){return this.m_contactManager.m_broadPhase.GetProxyCount()};h.prototype.CreateBody=function(a){if(this.IsLocked()==true)return null;a=new k(a,this);a.m_prev=null;if(a.m_next=this.m_bodyList)this.m_bodyList.m_prev=a;this.m_bodyList=a;++this.m_bodyCount;return a};h.prototype.DestroyBody=function(a){if(this.IsLocked()!=true){for(var c=a.m_jointList;c;){var g=
c;c=c.next;this.m_destructionListener&&this.m_destructionListener.SayGoodbyeJoint(g.joint);this.DestroyJoint(g.joint)}for(c=a.m_controllerList;c;){g=c;c=c.nextController;g.controller.RemoveBody(a)}for(c=a.m_contactList;c;){g=c;c=c.next;this.m_contactManager.Destroy(g.contact)}a.m_contactList=null;for(c=a.m_fixtureList;c;){g=c;c=c.m_next;this.m_destructionListener&&this.m_destructionListener.SayGoodbyeFixture(g);g.DestroyProxy(this.m_contactManager.m_broadPhase);g.Destroy()}a.m_fixtureList=null;a.m_fixtureCount=
0;if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(a==this.m_bodyList)this.m_bodyList=a.m_next;--this.m_bodyCount}};h.prototype.CreateJoint=function(a){var c=q.Create(a,null);c.m_prev=null;if(c.m_next=this.m_jointList)this.m_jointList.m_prev=c;this.m_jointList=c;++this.m_jointCount;c.m_edgeA.joint=c;c.m_edgeA.other=c.m_bodyB;c.m_edgeA.prev=null;if(c.m_edgeA.next=c.m_bodyA.m_jointList)c.m_bodyA.m_jointList.prev=c.m_edgeA;c.m_bodyA.m_jointList=c.m_edgeA;c.m_edgeB.joint=c;
c.m_edgeB.other=c.m_bodyA;c.m_edgeB.prev=null;if(c.m_edgeB.next=c.m_bodyB.m_jointList)c.m_bodyB.m_jointList.prev=c.m_edgeB;c.m_bodyB.m_jointList=c.m_edgeB;var g=a.bodyA,b=a.bodyB;if(a.collideConnected==false)for(a=b.GetContactList();a;){a.other==g&&a.contact.FlagForFiltering();a=a.next}return c};h.prototype.DestroyJoint=function(a){var c=a.m_collideConnected;if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(a==this.m_jointList)this.m_jointList=a.m_next;var g=a.m_bodyA,b=
a.m_bodyB;g.SetAwake(true);b.SetAwake(true);if(a.m_edgeA.prev)a.m_edgeA.prev.next=a.m_edgeA.next;if(a.m_edgeA.next)a.m_edgeA.next.prev=a.m_edgeA.prev;if(a.m_edgeA==g.m_jointList)g.m_jointList=a.m_edgeA.next;a.m_edgeA.prev=null;a.m_edgeA.next=null;if(a.m_edgeB.prev)a.m_edgeB.prev.next=a.m_edgeB.next;if(a.m_edgeB.next)a.m_edgeB.next.prev=a.m_edgeB.prev;if(a.m_edgeB==b.m_jointList)b.m_jointList=a.m_edgeB.next;a.m_edgeB.prev=null;a.m_edgeB.next=null;q.Destroy(a,null);--this.m_jointCount;if(c==false)for(a=
b.GetContactList();a;){a.other==g&&a.contact.FlagForFiltering();a=a.next}};h.prototype.AddController=function(a){a.m_next=this.m_controllerList;a.m_prev=null;this.m_controllerList=a;a.m_world=this;this.m_controllerCount++;return a};h.prototype.RemoveController=function(a){if(a.m_prev)a.m_prev.m_next=a.m_next;if(a.m_next)a.m_next.m_prev=a.m_prev;if(this.m_controllerList==a)this.m_controllerList=a.m_next;this.m_controllerCount--};h.prototype.CreateController=function(a){if(a.m_world!=this)throw Error("Controller can only be a member of one world");
a.m_next=this.m_controllerList;a.m_prev=null;if(this.m_controllerList)this.m_controllerList.m_prev=a;this.m_controllerList=a;++this.m_controllerCount;a.m_world=this;return a};h.prototype.DestroyController=function(a){a.Clear();if(a.m_next)a.m_next.m_prev=a.m_prev;if(a.m_prev)a.m_prev.m_next=a.m_next;if(a==this.m_controllerList)this.m_controllerList=a.m_next;--this.m_controllerCount};h.prototype.SetWarmStarting=function(a){h.m_warmStarting=a};h.prototype.SetContinuousPhysics=function(a){h.m_continuousPhysics=
a};h.prototype.GetBodyCount=function(){return this.m_bodyCount};h.prototype.GetJointCount=function(){return this.m_jointCount};h.prototype.GetContactCount=function(){return this.m_contactCount};h.prototype.SetGravity=function(a){this.m_gravity=a};h.prototype.GetGravity=function(){return this.m_gravity};h.prototype.GetGroundBody=function(){return this.m_groundBody};h.prototype.Step=function(a,c,g){if(a===undefined)a=0;if(c===undefined)c=0;if(g===undefined)g=0;if(this.m_flags&h.e_newFixture){this.m_contactManager.FindNewContacts();
this.m_flags&=~h.e_newFixture}this.m_flags|=h.e_locked;var b=h.s_timestep2;b.dt=a;b.velocityIterations=c;b.positionIterations=g;b.inv_dt=a>0?1/a:0;b.dtRatio=this.m_inv_dt0*a;b.warmStarting=h.m_warmStarting;this.m_contactManager.Collide();b.dt>0&&this.Solve(b);h.m_continuousPhysics&&b.dt>0&&this.SolveTOI(b);if(b.dt>0)this.m_inv_dt0=b.inv_dt;this.m_flags&=~h.e_locked};h.prototype.ClearForces=function(){for(var a=this.m_bodyList;a;a=a.m_next){a.m_force.SetZero();a.m_torque=0}};h.prototype.DrawDebugData=
function(){if(this.m_debugDraw!=null){this.m_debugDraw.m_sprite.graphics.clear();var a=this.m_debugDraw.GetFlags(),c,g,b;new y;new y;new y;var e;new U;new U;e=[new y,new y,new y,new y];var f=new w(0,0,0);if(a&E.e_shapeBit)for(c=this.m_bodyList;c;c=c.m_next){e=c.m_xf;for(g=c.GetFixtureList();g;g=g.m_next){b=g.GetShape();if(c.IsActive()==false)f.Set(0.5,0.5,0.3);else if(c.GetType()==k.b2_staticBody)f.Set(0.5,0.9,0.5);else if(c.GetType()==k.b2_kinematicBody)f.Set(0.5,0.5,0.9);else c.IsAwake()==false?
f.Set(0.6,0.6,0.6):f.Set(0.9,0.7,0.7);this.DrawShape(b,e,f)}}if(a&E.e_jointBit)for(c=this.m_jointList;c;c=c.m_next)this.DrawJoint(c);if(a&E.e_controllerBit)for(c=this.m_controllerList;c;c=c.m_next)c.Draw(this.m_debugDraw);if(a&E.e_pairBit){f.Set(0.3,0.9,0.9);for(c=this.m_contactManager.m_contactList;c;c=c.GetNext()){b=c.GetFixtureA();g=c.GetFixtureB();b=b.GetAABB().GetCenter();g=g.GetAABB().GetCenter();this.m_debugDraw.DrawSegment(b,g,f)}}if(a&E.e_aabbBit){b=this.m_contactManager.m_broadPhase;e=[new y,
new y,new y,new y];for(c=this.m_bodyList;c;c=c.GetNext())if(c.IsActive()!=false)for(g=c.GetFixtureList();g;g=g.GetNext()){var m=b.GetFatAABB(g.m_proxy);e[0].Set(m.lowerBound.x,m.lowerBound.y);e[1].Set(m.upperBound.x,m.lowerBound.y);e[2].Set(m.upperBound.x,m.upperBound.y);e[3].Set(m.lowerBound.x,m.upperBound.y);this.m_debugDraw.DrawPolygon(e,4,f)}}if(a&E.e_centerOfMassBit)for(c=this.m_bodyList;c;c=c.m_next){e=h.s_xf;e.R=c.m_xf.R;e.position=c.GetWorldCenter();this.m_debugDraw.DrawTransform(e)}}};h.prototype.QueryAABB=
function(a,c){var g=this.m_contactManager.m_broadPhase;g.Query(function(b){return a(g.GetUserData(b))},c)};h.prototype.QueryShape=function(a,c,g){if(g===undefined)g=null;if(g==null){g=new K;g.SetIdentity()}var b=this.m_contactManager.m_broadPhase,e=new U;c.ComputeAABB(e,g);b.Query(function(f){f=b.GetUserData(f)instanceof S?b.GetUserData(f):null;if(Y.TestOverlap(c,g,f.GetShape(),f.GetBody().GetTransform()))return a(f);return true},e)};h.prototype.QueryPoint=function(a,c){var g=this.m_contactManager.m_broadPhase,
b=new U;b.lowerBound.Set(c.x-A.b2_linearSlop,c.y-A.b2_linearSlop);b.upperBound.Set(c.x+A.b2_linearSlop,c.y+A.b2_linearSlop);g.Query(function(e){e=g.GetUserData(e)instanceof S?g.GetUserData(e):null;if(e.TestPoint(c))return a(e);return true},b)};h.prototype.RayCast=function(a,c,g){var b=this.m_contactManager.m_broadPhase,e=new V,f=new Q(c,g);b.RayCast(function(m,r){var s=b.GetUserData(r);s=s instanceof S?s:null;if(s.RayCast(e,m)){var v=e.fraction,t=new y((1-v)*c.x+v*g.x,(1-v)*c.y+v*g.y);return a(s,
t,e.normal,v)}return m.maxFraction},f)};h.prototype.RayCastOne=function(a,c){var g;this.RayCast(function(b,e,f,m){if(m===undefined)m=0;g=b;return m},a,c);return g};h.prototype.RayCastAll=function(a,c){var g=new Vector;this.RayCast(function(b){g[g.length]=b;return 1},a,c);return g};h.prototype.GetBodyList=function(){return this.m_bodyList};h.prototype.GetJointList=function(){return this.m_jointList};h.prototype.GetContactList=function(){return this.m_contactList};h.prototype.IsLocked=function(){return(this.m_flags&
h.e_locked)>0};h.prototype.Solve=function(a){for(var c,g=this.m_controllerList;g;g=g.m_next)g.Step(a);g=this.m_island;g.Initialize(this.m_bodyCount,this.m_contactCount,this.m_jointCount,null,this.m_contactManager.m_contactListener,this.m_contactSolver);for(c=this.m_bodyList;c;c=c.m_next)c.m_flags&=~k.e_islandFlag;for(var b=this.m_contactList;b;b=b.m_next)b.m_flags&=~l.e_islandFlag;for(b=this.m_jointList;b;b=b.m_next)b.m_islandFlag=false;parseInt(this.m_bodyCount);b=this.s_stack;for(var e=this.m_bodyList;e;e=
e.m_next)if(!(e.m_flags&k.e_islandFlag))if(!(e.IsAwake()==false||e.IsActive()==false))if(e.GetType()!=k.b2_staticBody){g.Clear();var f=0;b[f++]=e;for(e.m_flags|=k.e_islandFlag;f>0;){c=b[--f];g.AddBody(c);c.IsAwake()==false&&c.SetAwake(true);if(c.GetType()!=k.b2_staticBody){for(var m,r=c.m_contactList;r;r=r.next)if(!(r.contact.m_flags&l.e_islandFlag))if(!(r.contact.IsSensor()==true||r.contact.IsEnabled()==false||r.contact.IsTouching()==false)){g.AddContact(r.contact);r.contact.m_flags|=l.e_islandFlag;
m=r.other;if(!(m.m_flags&k.e_islandFlag)){b[f++]=m;m.m_flags|=k.e_islandFlag}}for(c=c.m_jointList;c;c=c.next)if(c.joint.m_islandFlag!=true){m=c.other;if(m.IsActive()!=false){g.AddJoint(c.joint);c.joint.m_islandFlag=true;if(!(m.m_flags&k.e_islandFlag)){b[f++]=m;m.m_flags|=k.e_islandFlag}}}}}g.Solve(a,this.m_gravity,this.m_allowSleep);for(f=0;f<g.m_bodyCount;++f){c=g.m_bodies[f];if(c.GetType()==k.b2_staticBody)c.m_flags&=~k.e_islandFlag}}for(f=0;f<b.length;++f){if(!b[f])break;b[f]=null}for(c=this.m_bodyList;c;c=
c.m_next)c.IsAwake()==false||c.IsActive()==false||c.GetType()!=k.b2_staticBody&&c.SynchronizeFixtures();this.m_contactManager.FindNewContacts()};h.prototype.SolveTOI=function(a){var c,g,b,e=this.m_island;e.Initialize(this.m_bodyCount,A.b2_maxTOIContactsPerIsland,A.b2_maxTOIJointsPerIsland,null,this.m_contactManager.m_contactListener,this.m_contactSolver);var f=h.s_queue;for(c=this.m_bodyList;c;c=c.m_next){c.m_flags&=~k.e_islandFlag;c.m_sweep.t0=0}for(b=this.m_contactList;b;b=b.m_next)b.m_flags&=~(l.e_toiFlag|
l.e_islandFlag);for(b=this.m_jointList;b;b=b.m_next)b.m_islandFlag=false;for(;;){var m=null,r=1;for(b=this.m_contactList;b;b=b.m_next)if(!(b.IsSensor()==true||b.IsEnabled()==false||b.IsContinuous()==false)){c=1;if(b.m_flags&l.e_toiFlag)c=b.m_toi;else{c=b.m_fixtureA;g=b.m_fixtureB;c=c.m_body;g=g.m_body;if((c.GetType()!=k.b2_dynamicBody||c.IsAwake()==false)&&(g.GetType()!=k.b2_dynamicBody||g.IsAwake()==false))continue;var s=c.m_sweep.t0;if(c.m_sweep.t0<g.m_sweep.t0){s=g.m_sweep.t0;c.m_sweep.Advance(s)}else if(g.m_sweep.t0<
c.m_sweep.t0){s=c.m_sweep.t0;g.m_sweep.Advance(s)}c=b.ComputeTOI(c.m_sweep,g.m_sweep);A.b2Assert(0<=c&&c<=1);if(c>0&&c<1){c=(1-c)*s+c;if(c>1)c=1}b.m_toi=c;b.m_flags|=l.e_toiFlag}if(Number.MIN_VALUE<c&&c<r){m=b;r=c}}if(m==null||1-100*Number.MIN_VALUE<r)break;c=m.m_fixtureA;g=m.m_fixtureB;c=c.m_body;g=g.m_body;h.s_backupA.Set(c.m_sweep);h.s_backupB.Set(g.m_sweep);c.Advance(r);g.Advance(r);m.Update(this.m_contactManager.m_contactListener);m.m_flags&=~l.e_toiFlag;if(m.IsSensor()==true||m.IsEnabled()==
false){c.m_sweep.Set(h.s_backupA);g.m_sweep.Set(h.s_backupB);c.SynchronizeTransform();g.SynchronizeTransform()}else if(m.IsTouching()!=false){c=c;if(c.GetType()!=k.b2_dynamicBody)c=g;e.Clear();m=b=0;f[b+m++]=c;for(c.m_flags|=k.e_islandFlag;m>0;){c=f[b++];--m;e.AddBody(c);c.IsAwake()==false&&c.SetAwake(true);if(c.GetType()==k.b2_dynamicBody){for(g=c.m_contactList;g;g=g.next){if(e.m_contactCount==e.m_contactCapacity)break;if(!(g.contact.m_flags&l.e_islandFlag))if(!(g.contact.IsSensor()==true||g.contact.IsEnabled()==
false||g.contact.IsTouching()==false)){e.AddContact(g.contact);g.contact.m_flags|=l.e_islandFlag;s=g.other;if(!(s.m_flags&k.e_islandFlag)){if(s.GetType()!=k.b2_staticBody){s.Advance(r);s.SetAwake(true)}f[b+m]=s;++m;s.m_flags|=k.e_islandFlag}}}for(c=c.m_jointList;c;c=c.next)if(e.m_jointCount!=e.m_jointCapacity)if(c.joint.m_islandFlag!=true){s=c.other;if(s.IsActive()!=false){e.AddJoint(c.joint);c.joint.m_islandFlag=true;if(!(s.m_flags&k.e_islandFlag)){if(s.GetType()!=k.b2_staticBody){s.Advance(r);s.SetAwake(true)}f[b+
m]=s;++m;s.m_flags|=k.e_islandFlag}}}}}b=h.s_timestep;b.warmStarting=false;b.dt=(1-r)*a.dt;b.inv_dt=1/b.dt;b.dtRatio=0;b.velocityIterations=a.velocityIterations;b.positionIterations=a.positionIterations;e.SolveTOI(b);for(r=r=0;r<e.m_bodyCount;++r){c=e.m_bodies[r];c.m_flags&=~k.e_islandFlag;if(c.IsAwake()!=false)if(c.GetType()==k.b2_dynamicBody){c.SynchronizeFixtures();for(g=c.m_contactList;g;g=g.next)g.contact.m_flags&=~l.e_toiFlag}}for(r=0;r<e.m_contactCount;++r){b=e.m_contacts[r];b.m_flags&=~(l.e_toiFlag|
l.e_islandFlag)}for(r=0;r<e.m_jointCount;++r){b=e.m_joints[r];b.m_islandFlag=false}this.m_contactManager.FindNewContacts()}}};h.prototype.DrawJoint=function(a){var c=a.GetBodyA(),g=a.GetBodyB(),b=c.m_xf.position,e=g.m_xf.position,f=a.GetAnchorA(),m=a.GetAnchorB(),r=h.s_jointColor;switch(a.m_type){case q.e_distanceJoint:this.m_debugDraw.DrawSegment(f,m,r);break;case q.e_pulleyJoint:c=a instanceof n?a:null;a=c.GetGroundAnchorA();c=c.GetGroundAnchorB();this.m_debugDraw.DrawSegment(a,f,r);this.m_debugDraw.DrawSegment(c,
m,r);this.m_debugDraw.DrawSegment(a,c,r);break;case q.e_mouseJoint:this.m_debugDraw.DrawSegment(f,m,r);break;default:c!=this.m_groundBody&&this.m_debugDraw.DrawSegment(b,f,r);this.m_debugDraw.DrawSegment(f,m,r);g!=this.m_groundBody&&this.m_debugDraw.DrawSegment(e,m,r)}};h.prototype.DrawShape=function(a,c,g){switch(a.m_type){case Y.e_circleShape:var b=a instanceof M?a:null;this.m_debugDraw.DrawSolidCircle(F.MulX(c,b.m_p),b.m_radius,c.R.col1,g);break;case Y.e_polygonShape:b=0;b=a instanceof W?a:null;
a=parseInt(b.GetVertexCount());var e=b.GetVertices(),f=new Vector(a);for(b=0;b<a;++b)f[b]=F.MulX(c,e[b]);this.m_debugDraw.DrawSolidPolygon(f,a,g);break;case Y.e_edgeShape:b=a instanceof L?a:null;this.m_debugDraw.DrawSegment(F.MulX(c,b.GetVertex1()),F.MulX(c,b.GetVertex2()),g)}};Box2D.postDefs.push(function(){Box2D.Dynamics.b2World.s_timestep2=new d;Box2D.Dynamics.b2World.s_xf=new K;Box2D.Dynamics.b2World.s_backupA=new G;Box2D.Dynamics.b2World.s_backupB=new G;Box2D.Dynamics.b2World.s_timestep=new d;
Box2D.Dynamics.b2World.s_queue=new Vector;Box2D.Dynamics.b2World.s_jointColor=new w(0.5,0.8,0.8);Box2D.Dynamics.b2World.e_newFixture=1;Box2D.Dynamics.b2World.e_locked=2})})();
(function(){var F=Box2D.Collision.Shapes.b2CircleShape,G=Box2D.Collision.Shapes.b2EdgeShape,K=Box2D.Collision.Shapes.b2PolygonShape,y=Box2D.Collision.Shapes.b2Shape,w=Box2D.Dynamics.Contacts.b2CircleContact,A=Box2D.Dynamics.Contacts.b2Contact,U=Box2D.Dynamics.Contacts.b2ContactConstraint,p=Box2D.Dynamics.Contacts.b2ContactConstraintPoint,B=Box2D.Dynamics.Contacts.b2ContactEdge,Q=Box2D.Dynamics.Contacts.b2ContactFactory,V=Box2D.Dynamics.Contacts.b2ContactRegister,M=Box2D.Dynamics.Contacts.b2ContactResult,
L=Box2D.Dynamics.Contacts.b2ContactSolver,I=Box2D.Dynamics.Contacts.b2EdgeAndCircleContact,W=Box2D.Dynamics.Contacts.b2NullContact,Y=Box2D.Dynamics.Contacts.b2PolyAndCircleContact,k=Box2D.Dynamics.Contacts.b2PolyAndEdgeContact,z=Box2D.Dynamics.Contacts.b2PolygonContact,u=Box2D.Dynamics.Contacts.b2PositionSolverManifold,D=Box2D.Dynamics.b2Body,H=Box2D.Dynamics.b2TimeStep,O=Box2D.Common.b2Settings,E=Box2D.Common.Math.b2Mat22,R=Box2D.Common.Math.b2Math,N=Box2D.Common.Math.b2Vec2,S=Box2D.Collision.b2Collision,
aa=Box2D.Collision.b2ContactID,Z=Box2D.Collision.b2Manifold,d=Box2D.Collision.b2TimeOfImpact,h=Box2D.Collision.b2TOIInput,l=Box2D.Collision.b2WorldManifold;Box2D.inherit(w,Box2D.Dynamics.Contacts.b2Contact);w.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;w.b2CircleContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};w.Create=function(){return new w};w.Destroy=function(){};w.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o)};w.prototype.Evaluate=
function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();S.CollideCircles(this.m_manifold,this.m_fixtureA.GetShape()instanceof F?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof F?this.m_fixtureB.GetShape():null,o.m_xf)};A.b2Contact=function(){this.m_nodeA=new B;this.m_nodeB=new B;this.m_manifold=new Z;this.m_oldManifold=new Z};A.prototype.GetManifold=function(){return this.m_manifold};A.prototype.GetWorldManifold=function(j){var o=this.m_fixtureA.GetBody(),
q=this.m_fixtureB.GetBody(),n=this.m_fixtureA.GetShape(),a=this.m_fixtureB.GetShape();j.Initialize(this.m_manifold,o.GetTransform(),n.m_radius,q.GetTransform(),a.m_radius)};A.prototype.IsTouching=function(){return(this.m_flags&A.e_touchingFlag)==A.e_touchingFlag};A.prototype.IsContinuous=function(){return(this.m_flags&A.e_continuousFlag)==A.e_continuousFlag};A.prototype.SetSensor=function(j){if(j)this.m_flags|=A.e_sensorFlag;else this.m_flags&=~A.e_sensorFlag};A.prototype.IsSensor=function(){return(this.m_flags&
A.e_sensorFlag)==A.e_sensorFlag};A.prototype.SetEnabled=function(j){if(j)this.m_flags|=A.e_enabledFlag;else this.m_flags&=~A.e_enabledFlag};A.prototype.IsEnabled=function(){return(this.m_flags&A.e_enabledFlag)==A.e_enabledFlag};A.prototype.GetNext=function(){return this.m_next};A.prototype.GetFixtureA=function(){return this.m_fixtureA};A.prototype.GetFixtureB=function(){return this.m_fixtureB};A.prototype.FlagForFiltering=function(){this.m_flags|=A.e_filterFlag};A.prototype.b2Contact=function(){};
A.prototype.Reset=function(j,o){if(j===undefined)j=null;if(o===undefined)o=null;this.m_flags=A.e_enabledFlag;if(!j||!o)this.m_fixtureB=this.m_fixtureA=null;else{if(j.IsSensor()||o.IsSensor())this.m_flags|=A.e_sensorFlag;var q=j.GetBody(),n=o.GetBody();if(q.GetType()!=D.b2_dynamicBody||q.IsBullet()||n.GetType()!=D.b2_dynamicBody||n.IsBullet())this.m_flags|=A.e_continuousFlag;this.m_fixtureA=j;this.m_fixtureB=o;this.m_manifold.m_pointCount=0;this.m_next=this.m_prev=null;this.m_nodeA.contact=null;this.m_nodeA.prev=
null;this.m_nodeA.next=null;this.m_nodeA.other=null;this.m_nodeB.contact=null;this.m_nodeB.prev=null;this.m_nodeB.next=null;this.m_nodeB.other=null}};A.prototype.Update=function(j){var o=this.m_oldManifold;this.m_oldManifold=this.m_manifold;this.m_manifold=o;this.m_flags|=A.e_enabledFlag;var q=false;o=(this.m_flags&A.e_touchingFlag)==A.e_touchingFlag;var n=this.m_fixtureA.m_body,a=this.m_fixtureB.m_body,c=this.m_fixtureA.m_aabb.TestOverlap(this.m_fixtureB.m_aabb);if(this.m_flags&A.e_sensorFlag){if(c){q=
this.m_fixtureA.GetShape();c=this.m_fixtureB.GetShape();n=n.GetTransform();a=a.GetTransform();q=y.TestOverlap(q,n,c,a)}this.m_manifold.m_pointCount=0}else{if(n.GetType()!=D.b2_dynamicBody||n.IsBullet()||a.GetType()!=D.b2_dynamicBody||a.IsBullet())this.m_flags|=A.e_continuousFlag;else this.m_flags&=~A.e_continuousFlag;if(c){this.Evaluate();q=this.m_manifold.m_pointCount>0;for(c=0;c<this.m_manifold.m_pointCount;++c){var g=this.m_manifold.m_points[c];g.m_normalImpulse=0;g.m_tangentImpulse=0;for(var b=
g.m_id,e=0;e<this.m_oldManifold.m_pointCount;++e){var f=this.m_oldManifold.m_points[e];if(f.m_id.key==b.key){g.m_normalImpulse=f.m_normalImpulse;g.m_tangentImpulse=f.m_tangentImpulse;break}}}}else this.m_manifold.m_pointCount=0;if(q!=o){n.SetAwake(true);a.SetAwake(true)}}if(q)this.m_flags|=A.e_touchingFlag;else this.m_flags&=~A.e_touchingFlag;o==false&&q==true&&j.BeginContact(this);o==true&&q==false&&j.EndContact(this);(this.m_flags&A.e_sensorFlag)==0&&j.PreSolve(this,this.m_oldManifold)};A.prototype.Evaluate=
function(){};A.prototype.ComputeTOI=function(j,o){A.s_input.proxyA.Set(this.m_fixtureA.GetShape());A.s_input.proxyB.Set(this.m_fixtureB.GetShape());A.s_input.sweepA=j;A.s_input.sweepB=o;A.s_input.tolerance=O.b2_linearSlop;return d.TimeOfImpact(A.s_input)};Box2D.postDefs.push(function(){Box2D.Dynamics.Contacts.b2Contact.e_sensorFlag=1;Box2D.Dynamics.Contacts.b2Contact.e_continuousFlag=2;Box2D.Dynamics.Contacts.b2Contact.e_islandFlag=4;Box2D.Dynamics.Contacts.b2Contact.e_toiFlag=8;Box2D.Dynamics.Contacts.b2Contact.e_touchingFlag=
16;Box2D.Dynamics.Contacts.b2Contact.e_enabledFlag=32;Box2D.Dynamics.Contacts.b2Contact.e_filterFlag=64;Box2D.Dynamics.Contacts.b2Contact.s_input=new h});U.b2ContactConstraint=function(){this.localPlaneNormal=new N;this.localPoint=new N;this.normal=new N;this.normalMass=new E;this.K=new E};U.prototype.b2ContactConstraint=function(){this.points=new Vector(O.b2_maxManifoldPoints);for(var j=0;j<O.b2_maxManifoldPoints;j++)this.points[j]=new p};p.b2ContactConstraintPoint=function(){this.localPoint=new N;
this.rA=new N;this.rB=new N};B.b2ContactEdge=function(){};Q.b2ContactFactory=function(){};Q.prototype.b2ContactFactory=function(j){this.m_allocator=j;this.InitializeRegisters()};Q.prototype.AddType=function(j,o,q,n){if(q===undefined)q=0;if(n===undefined)n=0;this.m_registers[q][n].createFcn=j;this.m_registers[q][n].destroyFcn=o;this.m_registers[q][n].primary=true;if(q!=n){this.m_registers[n][q].createFcn=j;this.m_registers[n][q].destroyFcn=o;this.m_registers[n][q].primary=false}};Q.prototype.InitializeRegisters=
function(){this.m_registers=new Vector(y.e_shapeTypeCount);for(var j=0;j<y.e_shapeTypeCount;j++){this.m_registers[j]=new Vector(y.e_shapeTypeCount);for(var o=0;o<y.e_shapeTypeCount;o++)this.m_registers[j][o]=new V}this.AddType(w.Create,w.Destroy,y.e_circleShape,y.e_circleShape);this.AddType(Y.Create,Y.Destroy,y.e_polygonShape,y.e_circleShape);this.AddType(z.Create,z.Destroy,y.e_polygonShape,y.e_polygonShape);this.AddType(I.Create,I.Destroy,y.e_edgeShape,y.e_circleShape);this.AddType(k.Create,k.Destroy,
y.e_polygonShape,y.e_edgeShape)};Q.prototype.Create=function(j,o){var q=parseInt(j.GetType()),n=parseInt(o.GetType());q=this.m_registers[q][n];if(q.pool){n=q.pool;q.pool=n.m_next;q.poolCount--;n.Reset(j,o);return n}n=q.createFcn;if(n!=null){if(q.primary){n=n(this.m_allocator);n.Reset(j,o)}else{n=n(this.m_allocator);n.Reset(o,j)}return n}else return null};Q.prototype.Destroy=function(j){if(j.m_manifold.m_pointCount>0){j.m_fixtureA.m_body.SetAwake(true);j.m_fixtureB.m_body.SetAwake(true)}var o=parseInt(j.m_fixtureA.GetType()),
q=parseInt(j.m_fixtureB.GetType());o=this.m_registers[o][q];o.poolCount++;j.m_next=o.pool;o.pool=j;o=o.destroyFcn;o(j,this.m_allocator)};V.b2ContactRegister=function(){};M.b2ContactResult=function(){this.position=new N;this.normal=new N;this.id=new aa};L.b2ContactSolver=function(){this.m_step=new H;this.m_constraints=new Vector};L.prototype.b2ContactSolver=function(){};L.prototype.Initialize=function(j,o,q,n){if(q===undefined)q=0;var a;this.m_step.Set(j);this.m_allocator=n;j=0;for(this.m_constraintCount=
q;this.m_constraints.length<this.m_constraintCount;)this.m_constraints[this.m_constraints.length]=new U;for(j=0;j<q;++j){a=o[j];n=a.m_fixtureA;var c=a.m_fixtureB,g=n.m_shape.m_radius,b=c.m_shape.m_radius,e=n.m_body,f=c.m_body,m=a.GetManifold(),r=O.b2MixFriction(n.GetFriction(),c.GetFriction()),s=O.b2MixRestitution(n.GetRestitution(),c.GetRestitution()),v=e.m_linearVelocity.x,t=e.m_linearVelocity.y,x=f.m_linearVelocity.x,C=f.m_linearVelocity.y,J=e.m_angularVelocity,T=f.m_angularVelocity;O.b2Assert(m.m_pointCount>
0);L.s_worldManifold.Initialize(m,e.m_xf,g,f.m_xf,b);c=L.s_worldManifold.m_normal.x;a=L.s_worldManifold.m_normal.y;n=this.m_constraints[j];n.bodyA=e;n.bodyB=f;n.manifold=m;n.normal.x=c;n.normal.y=a;n.pointCount=m.m_pointCount;n.friction=r;n.restitution=s;n.localPlaneNormal.x=m.m_localPlaneNormal.x;n.localPlaneNormal.y=m.m_localPlaneNormal.y;n.localPoint.x=m.m_localPoint.x;n.localPoint.y=m.m_localPoint.y;n.radius=g+b;n.type=m.m_type;for(g=0;g<n.pointCount;++g){r=m.m_points[g];b=n.points[g];b.normalImpulse=
r.m_normalImpulse;b.tangentImpulse=r.m_tangentImpulse;b.localPoint.SetV(r.m_localPoint);r=b.rA.x=L.s_worldManifold.m_points[g].x-e.m_sweep.c.x;s=b.rA.y=L.s_worldManifold.m_points[g].y-e.m_sweep.c.y;var P=b.rB.x=L.s_worldManifold.m_points[g].x-f.m_sweep.c.x,X=b.rB.y=L.s_worldManifold.m_points[g].y-f.m_sweep.c.y,$=r*a-s*c,ba=P*a-X*c;$*=$;ba*=ba;b.normalMass=1/(e.m_invMass+f.m_invMass+e.m_invI*$+f.m_invI*ba);var ca=e.m_mass*e.m_invMass+f.m_mass*f.m_invMass;ca+=e.m_mass*e.m_invI*$+f.m_mass*f.m_invI*ba;
b.equalizedMass=1/ca;ba=a;ca=-c;$=r*ca-s*ba;ba=P*ca-X*ba;$*=$;ba*=ba;b.tangentMass=1/(e.m_invMass+f.m_invMass+e.m_invI*$+f.m_invI*ba);b.velocityBias=0;r=n.normal.x*(x+-T*X-v- -J*s)+n.normal.y*(C+T*P-t-J*r);if(r<-O.b2_velocityThreshold)b.velocityBias+=-n.restitution*r}if(n.pointCount==2){C=n.points[0];x=n.points[1];m=e.m_invMass;e=e.m_invI;v=f.m_invMass;f=f.m_invI;t=C.rA.x*a-C.rA.y*c;C=C.rB.x*a-C.rB.y*c;J=x.rA.x*a-x.rA.y*c;x=x.rB.x*a-x.rB.y*c;c=m+v+e*t*t+f*C*C;a=m+v+e*J*J+f*x*x;f=m+v+e*t*J+f*C*x;if(c*
c<100*(c*a-f*f)){n.K.col1.Set(c,f);n.K.col2.Set(f,a);n.K.GetInverse(n.normalMass)}else n.pointCount=1}}};L.prototype.InitVelocityConstraints=function(j){for(var o=0;o<this.m_constraintCount;++o){var q=this.m_constraints[o],n=q.bodyA,a=q.bodyB,c=n.m_invMass,g=n.m_invI,b=a.m_invMass,e=a.m_invI,f=q.normal.x,m=q.normal.y,r=m,s=-f,v=0,t=0;if(j.warmStarting){t=q.pointCount;for(v=0;v<t;++v){var x=q.points[v];x.normalImpulse*=j.dtRatio;x.tangentImpulse*=j.dtRatio;var C=x.normalImpulse*f+x.tangentImpulse*
r,J=x.normalImpulse*m+x.tangentImpulse*s;n.m_angularVelocity-=g*(x.rA.x*J-x.rA.y*C);n.m_linearVelocity.x-=c*C;n.m_linearVelocity.y-=c*J;a.m_angularVelocity+=e*(x.rB.x*J-x.rB.y*C);a.m_linearVelocity.x+=b*C;a.m_linearVelocity.y+=b*J}}else{t=q.pointCount;for(v=0;v<t;++v){n=q.points[v];n.normalImpulse=0;n.tangentImpulse=0}}}};L.prototype.SolveVelocityConstraints=function(){for(var j=0,o,q=0,n=0,a=0,c=n=n=q=q=0,g=q=q=0,b=q=a=0,e=0,f,m=0;m<this.m_constraintCount;++m){a=this.m_constraints[m];var r=a.bodyA,
s=a.bodyB,v=r.m_angularVelocity,t=s.m_angularVelocity,x=r.m_linearVelocity,C=s.m_linearVelocity,J=r.m_invMass,T=r.m_invI,P=s.m_invMass,X=s.m_invI;b=a.normal.x;var $=e=a.normal.y;f=-b;g=a.friction;for(j=0;j<a.pointCount;j++){o=a.points[j];q=C.x-t*o.rB.y-x.x+v*o.rA.y;n=C.y+t*o.rB.x-x.y-v*o.rA.x;q=q*$+n*f;q=o.tangentMass*-q;n=g*o.normalImpulse;n=R.Clamp(o.tangentImpulse+q,-n,n);q=n-o.tangentImpulse;c=q*$;q=q*f;x.x-=J*c;x.y-=J*q;v-=T*(o.rA.x*q-o.rA.y*c);C.x+=P*c;C.y+=P*q;t+=X*(o.rB.x*q-o.rB.y*c);o.tangentImpulse=
n}parseInt(a.pointCount);if(a.pointCount==1){o=a.points[0];q=C.x+-t*o.rB.y-x.x- -v*o.rA.y;n=C.y+t*o.rB.x-x.y-v*o.rA.x;a=q*b+n*e;q=-o.normalMass*(a-o.velocityBias);n=o.normalImpulse+q;n=n>0?n:0;q=n-o.normalImpulse;c=q*b;q=q*e;x.x-=J*c;x.y-=J*q;v-=T*(o.rA.x*q-o.rA.y*c);C.x+=P*c;C.y+=P*q;t+=X*(o.rB.x*q-o.rB.y*c);o.normalImpulse=n}else{o=a.points[0];j=a.points[1];q=o.normalImpulse;g=j.normalImpulse;var ba=(C.x-t*o.rB.y-x.x+v*o.rA.y)*b+(C.y+t*o.rB.x-x.y-v*o.rA.x)*e,ca=(C.x-t*j.rB.y-x.x+v*j.rA.y)*b+(C.y+
t*j.rB.x-x.y-v*j.rA.x)*e;n=ba-o.velocityBias;c=ca-j.velocityBias;f=a.K;n-=f.col1.x*q+f.col2.x*g;for(c-=f.col1.y*q+f.col2.y*g;;){f=a.normalMass;$=-(f.col1.x*n+f.col2.x*c);f=-(f.col1.y*n+f.col2.y*c);if($>=0&&f>=0){q=$-q;g=f-g;a=q*b;q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}$=-o.normalMass*n;f=0;ca=a.K.col1.y*$+c;if($>=0&&ca>=0){q=$-q;g=f-g;a=q*b;
q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}$=0;f=-j.normalMass*c;ba=a.K.col2.x*f+n;if(f>=0&&ba>=0){q=$-q;g=f-g;a=q*b;q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}f=$=0;ba=n;ca=c;if(ba>=0&&ca>=0){q=
$-q;g=f-g;a=q*b;q=q*e;b=g*b;e=g*e;x.x-=J*(a+b);x.y-=J*(q+e);v-=T*(o.rA.x*q-o.rA.y*a+j.rA.x*e-j.rA.y*b);C.x+=P*(a+b);C.y+=P*(q+e);t+=X*(o.rB.x*q-o.rB.y*a+j.rB.x*e-j.rB.y*b);o.normalImpulse=$;j.normalImpulse=f;break}break}}r.m_angularVelocity=v;s.m_angularVelocity=t}};L.prototype.FinalizeVelocityConstraints=function(){for(var j=0;j<this.m_constraintCount;++j)for(var o=this.m_constraints[j],q=o.manifold,n=0;n<o.pointCount;++n){var a=q.m_points[n],c=o.points[n];a.m_normalImpulse=c.normalImpulse;a.m_tangentImpulse=
c.tangentImpulse}};L.prototype.SolvePositionConstraints=function(j){if(j===undefined)j=0;for(var o=0,q=0;q<this.m_constraintCount;q++){var n=this.m_constraints[q],a=n.bodyA,c=n.bodyB,g=a.m_mass*a.m_invMass,b=a.m_mass*a.m_invI,e=c.m_mass*c.m_invMass,f=c.m_mass*c.m_invI;L.s_psm.Initialize(n);for(var m=L.s_psm.m_normal,r=0;r<n.pointCount;r++){var s=n.points[r],v=L.s_psm.m_points[r],t=L.s_psm.m_separations[r],x=v.x-a.m_sweep.c.x,C=v.y-a.m_sweep.c.y,J=v.x-c.m_sweep.c.x;v=v.y-c.m_sweep.c.y;o=o<t?o:t;t=
R.Clamp(j*(t+O.b2_linearSlop),-O.b2_maxLinearCorrection,0);t=-s.equalizedMass*t;s=t*m.x;t=t*m.y;a.m_sweep.c.x-=g*s;a.m_sweep.c.y-=g*t;a.m_sweep.a-=b*(x*t-C*s);a.SynchronizeTransform();c.m_sweep.c.x+=e*s;c.m_sweep.c.y+=e*t;c.m_sweep.a+=f*(J*t-v*s);c.SynchronizeTransform()}}return o>-1.5*O.b2_linearSlop};Box2D.postDefs.push(function(){Box2D.Dynamics.Contacts.b2ContactSolver.s_worldManifold=new l;Box2D.Dynamics.Contacts.b2ContactSolver.s_psm=new u});Box2D.inherit(I,Box2D.Dynamics.Contacts.b2Contact);
I.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;I.b2EdgeAndCircleContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};I.Create=function(){return new I};I.Destroy=function(){};I.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o)};I.prototype.Evaluate=function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();this.b2CollideEdgeAndCircle(this.m_manifold,this.m_fixtureA.GetShape()instanceof G?this.m_fixtureA.GetShape():null,j.m_xf,
this.m_fixtureB.GetShape()instanceof F?this.m_fixtureB.GetShape():null,o.m_xf)};I.prototype.b2CollideEdgeAndCircle=function(){};Box2D.inherit(W,Box2D.Dynamics.Contacts.b2Contact);W.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;W.b2NullContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};W.prototype.b2NullContact=function(){this.__super.b2Contact.call(this)};W.prototype.Evaluate=function(){};Box2D.inherit(Y,Box2D.Dynamics.Contacts.b2Contact);Y.prototype.__super=
Box2D.Dynamics.Contacts.b2Contact.prototype;Y.b2PolyAndCircleContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};Y.Create=function(){return new Y};Y.Destroy=function(){};Y.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o);O.b2Assert(j.GetType()==y.e_polygonShape);O.b2Assert(o.GetType()==y.e_circleShape)};Y.prototype.Evaluate=function(){var j=this.m_fixtureA.m_body,o=this.m_fixtureB.m_body;S.CollidePolygonAndCircle(this.m_manifold,this.m_fixtureA.GetShape()instanceof
K?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof F?this.m_fixtureB.GetShape():null,o.m_xf)};Box2D.inherit(k,Box2D.Dynamics.Contacts.b2Contact);k.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;k.b2PolyAndEdgeContact=function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};k.Create=function(){return new k};k.Destroy=function(){};k.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o);O.b2Assert(j.GetType()==y.e_polygonShape);
O.b2Assert(o.GetType()==y.e_edgeShape)};k.prototype.Evaluate=function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();this.b2CollidePolyAndEdge(this.m_manifold,this.m_fixtureA.GetShape()instanceof K?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof G?this.m_fixtureB.GetShape():null,o.m_xf)};k.prototype.b2CollidePolyAndEdge=function(){};Box2D.inherit(z,Box2D.Dynamics.Contacts.b2Contact);z.prototype.__super=Box2D.Dynamics.Contacts.b2Contact.prototype;z.b2PolygonContact=
function(){Box2D.Dynamics.Contacts.b2Contact.b2Contact.apply(this,arguments)};z.Create=function(){return new z};z.Destroy=function(){};z.prototype.Reset=function(j,o){this.__super.Reset.call(this,j,o)};z.prototype.Evaluate=function(){var j=this.m_fixtureA.GetBody(),o=this.m_fixtureB.GetBody();S.CollidePolygons(this.m_manifold,this.m_fixtureA.GetShape()instanceof K?this.m_fixtureA.GetShape():null,j.m_xf,this.m_fixtureB.GetShape()instanceof K?this.m_fixtureB.GetShape():null,o.m_xf)};u.b2PositionSolverManifold=
function(){};u.prototype.b2PositionSolverManifold=function(){this.m_normal=new N;this.m_separations=new Vector_a2j_Number(O.b2_maxManifoldPoints);this.m_points=new Vector(O.b2_maxManifoldPoints);for(var j=0;j<O.b2_maxManifoldPoints;j++)this.m_points[j]=new N};u.prototype.Initialize=function(j){O.b2Assert(j.pointCount>0);var o=0,q=0,n=0,a,c=0,g=0;switch(j.type){case Z.e_circles:a=j.bodyA.m_xf.R;n=j.localPoint;o=j.bodyA.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);q=j.bodyA.m_xf.position.y+(a.col1.y*
n.x+a.col2.y*n.y);a=j.bodyB.m_xf.R;n=j.points[0].localPoint;c=j.bodyB.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);a=j.bodyB.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);n=c-o;g=a-q;var b=n*n+g*g;if(b>Number.MIN_VALUE*Number.MIN_VALUE){b=Math.sqrt(b);this.m_normal.x=n/b;this.m_normal.y=g/b}else{this.m_normal.x=1;this.m_normal.y=0}this.m_points[0].x=0.5*(o+c);this.m_points[0].y=0.5*(q+a);this.m_separations[0]=n*this.m_normal.x+g*this.m_normal.y-j.radius;break;case Z.e_faceA:a=j.bodyA.m_xf.R;n=j.localPlaneNormal;
this.m_normal.x=a.col1.x*n.x+a.col2.x*n.y;this.m_normal.y=a.col1.y*n.x+a.col2.y*n.y;a=j.bodyA.m_xf.R;n=j.localPoint;c=j.bodyA.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);g=j.bodyA.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);a=j.bodyB.m_xf.R;for(o=0;o<j.pointCount;++o){n=j.points[o].localPoint;q=j.bodyB.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);n=j.bodyB.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);this.m_separations[o]=(q-c)*this.m_normal.x+(n-g)*this.m_normal.y-j.radius;this.m_points[o].x=q;this.m_points[o].y=
n}break;case Z.e_faceB:a=j.bodyB.m_xf.R;n=j.localPlaneNormal;this.m_normal.x=a.col1.x*n.x+a.col2.x*n.y;this.m_normal.y=a.col1.y*n.x+a.col2.y*n.y;a=j.bodyB.m_xf.R;n=j.localPoint;c=j.bodyB.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);g=j.bodyB.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);a=j.bodyA.m_xf.R;for(o=0;o<j.pointCount;++o){n=j.points[o].localPoint;q=j.bodyA.m_xf.position.x+(a.col1.x*n.x+a.col2.x*n.y);n=j.bodyA.m_xf.position.y+(a.col1.y*n.x+a.col2.y*n.y);this.m_separations[o]=(q-c)*this.m_normal.x+
(n-g)*this.m_normal.y-j.radius;this.m_points[o].Set(q,n)}this.m_normal.x*=-1;this.m_normal.y*=-1}};Box2D.postDefs.push(function(){Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointA=new N;Box2D.Dynamics.Contacts.b2PositionSolverManifold.circlePointB=new N})})();
(function(){var F=Box2D.Common.Math.b2Mat22,G=Box2D.Common.Math.b2Math,K=Box2D.Common.Math.b2Vec2,y=Box2D.Common.b2Color,w=Box2D.Dynamics.Controllers.b2BuoyancyController,A=Box2D.Dynamics.Controllers.b2ConstantAccelController,U=Box2D.Dynamics.Controllers.b2ConstantForceController,p=Box2D.Dynamics.Controllers.b2Controller,B=Box2D.Dynamics.Controllers.b2ControllerEdge,Q=Box2D.Dynamics.Controllers.b2GravityController,V=Box2D.Dynamics.Controllers.b2TensorDampingController;Box2D.inherit(w,Box2D.Dynamics.Controllers.b2Controller);
w.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;w.b2BuoyancyController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.normal=new K(0,-1);this.density=this.offset=0;this.velocity=new K(0,0);this.linearDrag=2;this.angularDrag=1;this.useDensity=false;this.useWorldGravity=true;this.gravity=null};w.prototype.Step=function(){if(this.m_bodyList){if(this.useWorldGravity)this.gravity=this.GetWorld().GetGravity().Copy();for(var M=this.m_bodyList;M;M=
M.nextBody){var L=M.body;if(L.IsAwake()!=false){for(var I=new K,W=new K,Y=0,k=0,z=L.GetFixtureList();z;z=z.GetNext()){var u=new K,D=z.GetShape().ComputeSubmergedArea(this.normal,this.offset,L.GetTransform(),u);Y+=D;I.x+=D*u.x;I.y+=D*u.y;var H=0;H=1;k+=D*H;W.x+=D*u.x*H;W.y+=D*u.y*H}I.x/=Y;I.y/=Y;W.x/=k;W.y/=k;if(!(Y<Number.MIN_VALUE)){k=this.gravity.GetNegative();k.Multiply(this.density*Y);L.ApplyForce(k,W);W=L.GetLinearVelocityFromWorldPoint(I);W.Subtract(this.velocity);W.Multiply(-this.linearDrag*
Y);L.ApplyForce(W,I);L.ApplyTorque(-L.GetInertia()/L.GetMass()*Y*L.GetAngularVelocity()*this.angularDrag)}}}}};w.prototype.Draw=function(M){var L=new K,I=new K;L.x=this.normal.x*this.offset+this.normal.y*1E3;L.y=this.normal.y*this.offset-this.normal.x*1E3;I.x=this.normal.x*this.offset-this.normal.y*1E3;I.y=this.normal.y*this.offset+this.normal.x*1E3;var W=new y(0,0,1);M.DrawSegment(L,I,W)};Box2D.inherit(A,Box2D.Dynamics.Controllers.b2Controller);A.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;
A.b2ConstantAccelController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.A=new K(0,0)};A.prototype.Step=function(M){M=new K(this.A.x*M.dt,this.A.y*M.dt);for(var L=this.m_bodyList;L;L=L.nextBody){var I=L.body;I.IsAwake()&&I.SetLinearVelocity(new K(I.GetLinearVelocity().x+M.x,I.GetLinearVelocity().y+M.y))}};Box2D.inherit(U,Box2D.Dynamics.Controllers.b2Controller);U.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;U.b2ConstantForceController=
function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.F=new K(0,0)};U.prototype.Step=function(){for(var M=this.m_bodyList;M;M=M.nextBody){var L=M.body;L.IsAwake()&&L.ApplyForce(this.F,L.GetWorldCenter())}};p.b2Controller=function(){};p.prototype.Step=function(){};p.prototype.Draw=function(){};p.prototype.AddBody=function(M){var L=new B;L.controller=this;L.body=M;L.nextBody=this.m_bodyList;L.prevBody=null;this.m_bodyList=L;if(L.nextBody)L.nextBody.prevBody=L;this.m_bodyCount++;
L.nextController=M.m_controllerList;L.prevController=null;M.m_controllerList=L;if(L.nextController)L.nextController.prevController=L;M.m_controllerCount++};p.prototype.RemoveBody=function(M){for(var L=M.m_controllerList;L&&L.controller!=this;)L=L.nextController;if(L.prevBody)L.prevBody.nextBody=L.nextBody;if(L.nextBody)L.nextBody.prevBody=L.prevBody;if(L.nextController)L.nextController.prevController=L.prevController;if(L.prevController)L.prevController.nextController=L.nextController;if(this.m_bodyList==
L)this.m_bodyList=L.nextBody;if(M.m_controllerList==L)M.m_controllerList=L.nextController;M.m_controllerCount--;this.m_bodyCount--};p.prototype.Clear=function(){for(;this.m_bodyList;)this.RemoveBody(this.m_bodyList.body)};p.prototype.GetNext=function(){return this.m_next};p.prototype.GetWorld=function(){return this.m_world};p.prototype.GetBodyList=function(){return this.m_bodyList};B.b2ControllerEdge=function(){};Box2D.inherit(Q,Box2D.Dynamics.Controllers.b2Controller);Q.prototype.__super=Box2D.Dynamics.Controllers.b2Controller.prototype;
Q.b2GravityController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.G=1;this.invSqr=true};Q.prototype.Step=function(){var M=null,L=null,I=null,W=0,Y=null,k=null,z=null,u=0,D=0,H=0;u=null;if(this.invSqr)for(M=this.m_bodyList;M;M=M.nextBody){L=M.body;I=L.GetWorldCenter();W=L.GetMass();for(Y=this.m_bodyList;Y!=M;Y=Y.nextBody){k=Y.body;z=k.GetWorldCenter();u=z.x-I.x;D=z.y-I.y;H=u*u+D*D;if(!(H<Number.MIN_VALUE)){u=new K(u,D);u.Multiply(this.G/H/Math.sqrt(H)*
W*k.GetMass());L.IsAwake()&&L.ApplyForce(u,I);u.Multiply(-1);k.IsAwake()&&k.ApplyForce(u,z)}}}else for(M=this.m_bodyList;M;M=M.nextBody){L=M.body;I=L.GetWorldCenter();W=L.GetMass();for(Y=this.m_bodyList;Y!=M;Y=Y.nextBody){k=Y.body;z=k.GetWorldCenter();u=z.x-I.x;D=z.y-I.y;H=u*u+D*D;if(!(H<Number.MIN_VALUE)){u=new K(u,D);u.Multiply(this.G/H*W*k.GetMass());L.IsAwake()&&L.ApplyForce(u,I);u.Multiply(-1);k.IsAwake()&&k.ApplyForce(u,z)}}}};Box2D.inherit(V,Box2D.Dynamics.Controllers.b2Controller);V.prototype.__super=
Box2D.Dynamics.Controllers.b2Controller.prototype;V.b2TensorDampingController=function(){Box2D.Dynamics.Controllers.b2Controller.b2Controller.apply(this,arguments);this.T=new F;this.maxTimestep=0};V.prototype.SetAxisAligned=function(M,L){if(M===undefined)M=0;if(L===undefined)L=0;this.T.col1.x=-M;this.T.col1.y=0;this.T.col2.x=0;this.T.col2.y=-L;this.maxTimestep=M>0||L>0?1/Math.max(M,L):0};V.prototype.Step=function(M){M=M.dt;if(!(M<=Number.MIN_VALUE)){if(M>this.maxTimestep&&this.maxTimestep>0)M=this.maxTimestep;
for(var L=this.m_bodyList;L;L=L.nextBody){var I=L.body;if(I.IsAwake()){var W=I.GetWorldVector(G.MulMV(this.T,I.GetLocalVector(I.GetLinearVelocity())));I.SetLinearVelocity(new K(I.GetLinearVelocity().x+W.x*M,I.GetLinearVelocity().y+W.y*M))}}}}})();
(function(){var F=Box2D.Common.b2Settings,G=Box2D.Common.Math.b2Mat22,K=Box2D.Common.Math.b2Mat33,y=Box2D.Common.Math.b2Math,w=Box2D.Common.Math.b2Vec2,A=Box2D.Common.Math.b2Vec3,U=Box2D.Dynamics.Joints.b2DistanceJoint,p=Box2D.Dynamics.Joints.b2DistanceJointDef,B=Box2D.Dynamics.Joints.b2FrictionJoint,Q=Box2D.Dynamics.Joints.b2FrictionJointDef,V=Box2D.Dynamics.Joints.b2GearJoint,M=Box2D.Dynamics.Joints.b2GearJointDef,L=Box2D.Dynamics.Joints.b2Jacobian,I=Box2D.Dynamics.Joints.b2Joint,W=Box2D.Dynamics.Joints.b2JointDef,
Y=Box2D.Dynamics.Joints.b2JointEdge,k=Box2D.Dynamics.Joints.b2LineJoint,z=Box2D.Dynamics.Joints.b2LineJointDef,u=Box2D.Dynamics.Joints.b2MouseJoint,D=Box2D.Dynamics.Joints.b2MouseJointDef,H=Box2D.Dynamics.Joints.b2PrismaticJoint,O=Box2D.Dynamics.Joints.b2PrismaticJointDef,E=Box2D.Dynamics.Joints.b2PulleyJoint,R=Box2D.Dynamics.Joints.b2PulleyJointDef,N=Box2D.Dynamics.Joints.b2RevoluteJoint,S=Box2D.Dynamics.Joints.b2RevoluteJointDef,aa=Box2D.Dynamics.Joints.b2WeldJoint,Z=Box2D.Dynamics.Joints.b2WeldJointDef;
Box2D.inherit(U,Box2D.Dynamics.Joints.b2Joint);U.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;U.b2DistanceJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_u=new w};U.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};U.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};U.prototype.GetReactionForce=function(d){if(d===undefined)d=
0;return new w(d*this.m_impulse*this.m_u.x,d*this.m_impulse*this.m_u.y)};U.prototype.GetReactionTorque=function(){return 0};U.prototype.GetLength=function(){return this.m_length};U.prototype.SetLength=function(d){if(d===undefined)d=0;this.m_length=d};U.prototype.GetFrequency=function(){return this.m_frequencyHz};U.prototype.SetFrequency=function(d){if(d===undefined)d=0;this.m_frequencyHz=d};U.prototype.GetDampingRatio=function(){return this.m_dampingRatio};U.prototype.SetDampingRatio=function(d){if(d===
undefined)d=0;this.m_dampingRatio=d};U.prototype.b2DistanceJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_length=d.length;this.m_frequencyHz=d.frequencyHz;this.m_dampingRatio=d.dampingRatio;this.m_bias=this.m_gamma=this.m_impulse=0};U.prototype.InitVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB;h=j.m_xf.R;var q=this.m_localAnchor1.x-j.m_sweep.localCenter.x,n=this.m_localAnchor1.y-
j.m_sweep.localCenter.y;l=h.col1.x*q+h.col2.x*n;n=h.col1.y*q+h.col2.y*n;q=l;h=o.m_xf.R;var a=this.m_localAnchor2.x-o.m_sweep.localCenter.x,c=this.m_localAnchor2.y-o.m_sweep.localCenter.y;l=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=l;this.m_u.x=o.m_sweep.c.x+a-j.m_sweep.c.x-q;this.m_u.y=o.m_sweep.c.y+c-j.m_sweep.c.y-n;l=Math.sqrt(this.m_u.x*this.m_u.x+this.m_u.y*this.m_u.y);l>F.b2_linearSlop?this.m_u.Multiply(1/l):this.m_u.SetZero();h=q*this.m_u.y-n*this.m_u.x;var g=a*this.m_u.y-c*this.m_u.x;
h=j.m_invMass+j.m_invI*h*h+o.m_invMass+o.m_invI*g*g;this.m_mass=h!=0?1/h:0;if(this.m_frequencyHz>0){l=l-this.m_length;g=2*Math.PI*this.m_frequencyHz;var b=this.m_mass*g*g;this.m_gamma=d.dt*(2*this.m_mass*this.m_dampingRatio*g+d.dt*b);this.m_gamma=this.m_gamma!=0?1/this.m_gamma:0;this.m_bias=l*d.dt*b*this.m_gamma;this.m_mass=h+this.m_gamma;this.m_mass=this.m_mass!=0?1/this.m_mass:0}if(d.warmStarting){this.m_impulse*=d.dtRatio;d=this.m_impulse*this.m_u.x;h=this.m_impulse*this.m_u.y;j.m_linearVelocity.x-=
j.m_invMass*d;j.m_linearVelocity.y-=j.m_invMass*h;j.m_angularVelocity-=j.m_invI*(q*h-n*d);o.m_linearVelocity.x+=o.m_invMass*d;o.m_linearVelocity.y+=o.m_invMass*h;o.m_angularVelocity+=o.m_invI*(a*h-c*d)}else this.m_impulse=0};U.prototype.SolveVelocityConstraints=function(){var d,h=this.m_bodyA,l=this.m_bodyB;d=h.m_xf.R;var j=this.m_localAnchor1.x-h.m_sweep.localCenter.x,o=this.m_localAnchor1.y-h.m_sweep.localCenter.y,q=d.col1.x*j+d.col2.x*o;o=d.col1.y*j+d.col2.y*o;j=q;d=l.m_xf.R;var n=this.m_localAnchor2.x-
l.m_sweep.localCenter.x,a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;q=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=q;q=-this.m_mass*(this.m_u.x*(l.m_linearVelocity.x+-l.m_angularVelocity*a-(h.m_linearVelocity.x+-h.m_angularVelocity*o))+this.m_u.y*(l.m_linearVelocity.y+l.m_angularVelocity*n-(h.m_linearVelocity.y+h.m_angularVelocity*j))+this.m_bias+this.m_gamma*this.m_impulse);this.m_impulse+=q;d=q*this.m_u.x;q=q*this.m_u.y;h.m_linearVelocity.x-=h.m_invMass*d;h.m_linearVelocity.y-=h.m_invMass*
q;h.m_angularVelocity-=h.m_invI*(j*q-o*d);l.m_linearVelocity.x+=l.m_invMass*d;l.m_linearVelocity.y+=l.m_invMass*q;l.m_angularVelocity+=l.m_invI*(n*q-a*d)};U.prototype.SolvePositionConstraints=function(){var d;if(this.m_frequencyHz>0)return true;var h=this.m_bodyA,l=this.m_bodyB;d=h.m_xf.R;var j=this.m_localAnchor1.x-h.m_sweep.localCenter.x,o=this.m_localAnchor1.y-h.m_sweep.localCenter.y,q=d.col1.x*j+d.col2.x*o;o=d.col1.y*j+d.col2.y*o;j=q;d=l.m_xf.R;var n=this.m_localAnchor2.x-l.m_sweep.localCenter.x,
a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;q=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=q;q=l.m_sweep.c.x+n-h.m_sweep.c.x-j;var c=l.m_sweep.c.y+a-h.m_sweep.c.y-o;d=Math.sqrt(q*q+c*c);q/=d;c/=d;d=d-this.m_length;d=y.Clamp(d,-F.b2_maxLinearCorrection,F.b2_maxLinearCorrection);var g=-this.m_mass*d;this.m_u.Set(q,c);q=g*this.m_u.x;c=g*this.m_u.y;h.m_sweep.c.x-=h.m_invMass*q;h.m_sweep.c.y-=h.m_invMass*c;h.m_sweep.a-=h.m_invI*(j*c-o*q);l.m_sweep.c.x+=l.m_invMass*q;l.m_sweep.c.y+=l.m_invMass*c;
l.m_sweep.a+=l.m_invI*(n*c-a*q);h.SynchronizeTransform();l.SynchronizeTransform();return y.Abs(d)<F.b2_linearSlop};Box2D.inherit(p,Box2D.Dynamics.Joints.b2JointDef);p.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;p.b2DistanceJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w};p.prototype.b2DistanceJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_distanceJoint;this.length=1;this.dampingRatio=
this.frequencyHz=0};p.prototype.Initialize=function(d,h,l,j){this.bodyA=d;this.bodyB=h;this.localAnchorA.SetV(this.bodyA.GetLocalPoint(l));this.localAnchorB.SetV(this.bodyB.GetLocalPoint(j));d=j.x-l.x;l=j.y-l.y;this.length=Math.sqrt(d*d+l*l);this.dampingRatio=this.frequencyHz=0};Box2D.inherit(B,Box2D.Dynamics.Joints.b2Joint);B.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;B.b2FrictionJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchorA=new w;
this.m_localAnchorB=new w;this.m_linearMass=new G;this.m_linearImpulse=new w};B.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA)};B.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB)};B.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_linearImpulse.x,d*this.m_linearImpulse.y)};B.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_angularImpulse};B.prototype.SetMaxForce=
function(d){if(d===undefined)d=0;this.m_maxForce=d};B.prototype.GetMaxForce=function(){return this.m_maxForce};B.prototype.SetMaxTorque=function(d){if(d===undefined)d=0;this.m_maxTorque=d};B.prototype.GetMaxTorque=function(){return this.m_maxTorque};B.prototype.b2FrictionJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchorA.SetV(d.localAnchorA);this.m_localAnchorB.SetV(d.localAnchorB);this.m_linearMass.SetZero();this.m_angularMass=0;this.m_linearImpulse.SetZero();this.m_angularImpulse=
0;this.m_maxForce=d.maxForce;this.m_maxTorque=d.maxTorque};B.prototype.InitVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB;h=j.m_xf.R;var q=this.m_localAnchorA.x-j.m_sweep.localCenter.x,n=this.m_localAnchorA.y-j.m_sweep.localCenter.y;l=h.col1.x*q+h.col2.x*n;n=h.col1.y*q+h.col2.y*n;q=l;h=o.m_xf.R;var a=this.m_localAnchorB.x-o.m_sweep.localCenter.x,c=this.m_localAnchorB.y-o.m_sweep.localCenter.y;l=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=l;h=j.m_invMass;l=o.m_invMass;
var g=j.m_invI,b=o.m_invI,e=new G;e.col1.x=h+l;e.col2.x=0;e.col1.y=0;e.col2.y=h+l;e.col1.x+=g*n*n;e.col2.x+=-g*q*n;e.col1.y+=-g*q*n;e.col2.y+=g*q*q;e.col1.x+=b*c*c;e.col2.x+=-b*a*c;e.col1.y+=-b*a*c;e.col2.y+=b*a*a;e.GetInverse(this.m_linearMass);this.m_angularMass=g+b;if(this.m_angularMass>0)this.m_angularMass=1/this.m_angularMass;if(d.warmStarting){this.m_linearImpulse.x*=d.dtRatio;this.m_linearImpulse.y*=d.dtRatio;this.m_angularImpulse*=d.dtRatio;d=this.m_linearImpulse;j.m_linearVelocity.x-=h*d.x;
j.m_linearVelocity.y-=h*d.y;j.m_angularVelocity-=g*(q*d.y-n*d.x+this.m_angularImpulse);o.m_linearVelocity.x+=l*d.x;o.m_linearVelocity.y+=l*d.y;o.m_angularVelocity+=b*(a*d.y-c*d.x+this.m_angularImpulse)}else{this.m_linearImpulse.SetZero();this.m_angularImpulse=0}};B.prototype.SolveVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB,q=j.m_linearVelocity,n=j.m_angularVelocity,a=o.m_linearVelocity,c=o.m_angularVelocity,g=j.m_invMass,b=o.m_invMass,e=j.m_invI,f=o.m_invI;h=j.m_xf.R;var m=
this.m_localAnchorA.x-j.m_sweep.localCenter.x,r=this.m_localAnchorA.y-j.m_sweep.localCenter.y;l=h.col1.x*m+h.col2.x*r;r=h.col1.y*m+h.col2.y*r;m=l;h=o.m_xf.R;var s=this.m_localAnchorB.x-o.m_sweep.localCenter.x,v=this.m_localAnchorB.y-o.m_sweep.localCenter.y;l=h.col1.x*s+h.col2.x*v;v=h.col1.y*s+h.col2.y*v;s=l;h=0;l=-this.m_angularMass*(c-n);var t=this.m_angularImpulse;h=d.dt*this.m_maxTorque;this.m_angularImpulse=y.Clamp(this.m_angularImpulse+l,-h,h);l=this.m_angularImpulse-t;n-=e*l;c+=f*l;h=y.MulMV(this.m_linearMass,
new w(-(a.x-c*v-q.x+n*r),-(a.y+c*s-q.y-n*m)));l=this.m_linearImpulse.Copy();this.m_linearImpulse.Add(h);h=d.dt*this.m_maxForce;if(this.m_linearImpulse.LengthSquared()>h*h){this.m_linearImpulse.Normalize();this.m_linearImpulse.Multiply(h)}h=y.SubtractVV(this.m_linearImpulse,l);q.x-=g*h.x;q.y-=g*h.y;n-=e*(m*h.y-r*h.x);a.x+=b*h.x;a.y+=b*h.y;c+=f*(s*h.y-v*h.x);j.m_angularVelocity=n;o.m_angularVelocity=c};B.prototype.SolvePositionConstraints=function(){return true};Box2D.inherit(Q,Box2D.Dynamics.Joints.b2JointDef);
Q.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;Q.b2FrictionJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w};Q.prototype.b2FrictionJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_frictionJoint;this.maxTorque=this.maxForce=0};Q.prototype.Initialize=function(d,h,l){this.bodyA=d;this.bodyB=h;this.localAnchorA.SetV(this.bodyA.GetLocalPoint(l));this.localAnchorB.SetV(this.bodyB.GetLocalPoint(l))};
Box2D.inherit(V,Box2D.Dynamics.Joints.b2Joint);V.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;V.b2GearJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_groundAnchor1=new w;this.m_groundAnchor2=new w;this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_J=new L};V.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};V.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};V.prototype.GetReactionForce=
function(d){if(d===undefined)d=0;return new w(d*this.m_impulse*this.m_J.linearB.x,d*this.m_impulse*this.m_J.linearB.y)};V.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;var h=this.m_bodyB.m_xf.R,l=this.m_localAnchor1.x-this.m_bodyB.m_sweep.localCenter.x,j=this.m_localAnchor1.y-this.m_bodyB.m_sweep.localCenter.y,o=h.col1.x*l+h.col2.x*j;j=h.col1.y*l+h.col2.y*j;l=o;return d*(this.m_impulse*this.m_J.angularB-l*this.m_impulse*this.m_J.linearB.y+j*this.m_impulse*this.m_J.linearB.x)};V.prototype.GetRatio=
function(){return this.m_ratio};V.prototype.SetRatio=function(d){if(d===undefined)d=0;this.m_ratio=d};V.prototype.b2GearJoint=function(d){this.__super.b2Joint.call(this,d);var h=parseInt(d.joint1.m_type),l=parseInt(d.joint2.m_type);this.m_prismatic2=this.m_revolute2=this.m_prismatic1=this.m_revolute1=null;var j=0,o=0;this.m_ground1=d.joint1.GetBodyA();this.m_bodyA=d.joint1.GetBodyB();if(h==I.e_revoluteJoint){this.m_revolute1=d.joint1 instanceof N?d.joint1:null;this.m_groundAnchor1.SetV(this.m_revolute1.m_localAnchor1);
this.m_localAnchor1.SetV(this.m_revolute1.m_localAnchor2);j=this.m_revolute1.GetJointAngle()}else{this.m_prismatic1=d.joint1 instanceof H?d.joint1:null;this.m_groundAnchor1.SetV(this.m_prismatic1.m_localAnchor1);this.m_localAnchor1.SetV(this.m_prismatic1.m_localAnchor2);j=this.m_prismatic1.GetJointTranslation()}this.m_ground2=d.joint2.GetBodyA();this.m_bodyB=d.joint2.GetBodyB();if(l==I.e_revoluteJoint){this.m_revolute2=d.joint2 instanceof N?d.joint2:null;this.m_groundAnchor2.SetV(this.m_revolute2.m_localAnchor1);
this.m_localAnchor2.SetV(this.m_revolute2.m_localAnchor2);o=this.m_revolute2.GetJointAngle()}else{this.m_prismatic2=d.joint2 instanceof H?d.joint2:null;this.m_groundAnchor2.SetV(this.m_prismatic2.m_localAnchor1);this.m_localAnchor2.SetV(this.m_prismatic2.m_localAnchor2);o=this.m_prismatic2.GetJointTranslation()}this.m_ratio=d.ratio;this.m_constant=j+this.m_ratio*o;this.m_impulse=0};V.prototype.InitVelocityConstraints=function(d){var h=this.m_ground1,l=this.m_ground2,j=this.m_bodyA,o=this.m_bodyB,
q=0,n=0,a=0,c=0,g=a=0,b=0;this.m_J.SetZero();if(this.m_revolute1){this.m_J.angularA=-1;b+=j.m_invI}else{h=h.m_xf.R;n=this.m_prismatic1.m_localXAxis1;q=h.col1.x*n.x+h.col2.x*n.y;n=h.col1.y*n.x+h.col2.y*n.y;h=j.m_xf.R;a=this.m_localAnchor1.x-j.m_sweep.localCenter.x;c=this.m_localAnchor1.y-j.m_sweep.localCenter.y;g=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=g;a=a*n-c*q;this.m_J.linearA.Set(-q,-n);this.m_J.angularA=-a;b+=j.m_invMass+j.m_invI*a*a}if(this.m_revolute2){this.m_J.angularB=-this.m_ratio;
b+=this.m_ratio*this.m_ratio*o.m_invI}else{h=l.m_xf.R;n=this.m_prismatic2.m_localXAxis1;q=h.col1.x*n.x+h.col2.x*n.y;n=h.col1.y*n.x+h.col2.y*n.y;h=o.m_xf.R;a=this.m_localAnchor2.x-o.m_sweep.localCenter.x;c=this.m_localAnchor2.y-o.m_sweep.localCenter.y;g=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=g;a=a*n-c*q;this.m_J.linearB.Set(-this.m_ratio*q,-this.m_ratio*n);this.m_J.angularB=-this.m_ratio*a;b+=this.m_ratio*this.m_ratio*(o.m_invMass+o.m_invI*a*a)}this.m_mass=b>0?1/b:0;if(d.warmStarting){j.m_linearVelocity.x+=
j.m_invMass*this.m_impulse*this.m_J.linearA.x;j.m_linearVelocity.y+=j.m_invMass*this.m_impulse*this.m_J.linearA.y;j.m_angularVelocity+=j.m_invI*this.m_impulse*this.m_J.angularA;o.m_linearVelocity.x+=o.m_invMass*this.m_impulse*this.m_J.linearB.x;o.m_linearVelocity.y+=o.m_invMass*this.m_impulse*this.m_J.linearB.y;o.m_angularVelocity+=o.m_invI*this.m_impulse*this.m_J.angularB}else this.m_impulse=0};V.prototype.SolveVelocityConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l=-this.m_mass*this.m_J.Compute(d.m_linearVelocity,
d.m_angularVelocity,h.m_linearVelocity,h.m_angularVelocity);this.m_impulse+=l;d.m_linearVelocity.x+=d.m_invMass*l*this.m_J.linearA.x;d.m_linearVelocity.y+=d.m_invMass*l*this.m_J.linearA.y;d.m_angularVelocity+=d.m_invI*l*this.m_J.angularA;h.m_linearVelocity.x+=h.m_invMass*l*this.m_J.linearB.x;h.m_linearVelocity.y+=h.m_invMass*l*this.m_J.linearB.y;h.m_angularVelocity+=h.m_invI*l*this.m_J.angularB};V.prototype.SolvePositionConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l=0,j=0;l=this.m_revolute1?
this.m_revolute1.GetJointAngle():this.m_prismatic1.GetJointTranslation();j=this.m_revolute2?this.m_revolute2.GetJointAngle():this.m_prismatic2.GetJointTranslation();l=-this.m_mass*(this.m_constant-(l+this.m_ratio*j));d.m_sweep.c.x+=d.m_invMass*l*this.m_J.linearA.x;d.m_sweep.c.y+=d.m_invMass*l*this.m_J.linearA.y;d.m_sweep.a+=d.m_invI*l*this.m_J.angularA;h.m_sweep.c.x+=h.m_invMass*l*this.m_J.linearB.x;h.m_sweep.c.y+=h.m_invMass*l*this.m_J.linearB.y;h.m_sweep.a+=h.m_invI*l*this.m_J.angularB;d.SynchronizeTransform();
h.SynchronizeTransform();return 0<F.b2_linearSlop};Box2D.inherit(M,Box2D.Dynamics.Joints.b2JointDef);M.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;M.b2GearJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments)};M.prototype.b2GearJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_gearJoint;this.joint2=this.joint1=null;this.ratio=1};L.b2Jacobian=function(){this.linearA=new w;this.linearB=new w};L.prototype.SetZero=function(){this.linearA.SetZero();
this.angularA=0;this.linearB.SetZero();this.angularB=0};L.prototype.Set=function(d,h,l,j){if(h===undefined)h=0;if(j===undefined)j=0;this.linearA.SetV(d);this.angularA=h;this.linearB.SetV(l);this.angularB=j};L.prototype.Compute=function(d,h,l,j){if(h===undefined)h=0;if(j===undefined)j=0;return this.linearA.x*d.x+this.linearA.y*d.y+this.angularA*h+(this.linearB.x*l.x+this.linearB.y*l.y)+this.angularB*j};I.b2Joint=function(){this.m_edgeA=new Y;this.m_edgeB=new Y;this.m_localCenterA=new w;this.m_localCenterB=
new w};I.prototype.GetType=function(){return this.m_type};I.prototype.GetAnchorA=function(){return null};I.prototype.GetAnchorB=function(){return null};I.prototype.GetReactionForce=function(){return null};I.prototype.GetReactionTorque=function(){return 0};I.prototype.GetBodyA=function(){return this.m_bodyA};I.prototype.GetBodyB=function(){return this.m_bodyB};I.prototype.GetNext=function(){return this.m_next};I.prototype.GetUserData=function(){return this.m_userData};I.prototype.SetUserData=function(d){this.m_userData=
d};I.prototype.IsActive=function(){return this.m_bodyA.IsActive()&&this.m_bodyB.IsActive()};I.Create=function(d){var h=null;switch(d.type){case I.e_distanceJoint:h=new U(d instanceof p?d:null);break;case I.e_mouseJoint:h=new u(d instanceof D?d:null);break;case I.e_prismaticJoint:h=new H(d instanceof O?d:null);break;case I.e_revoluteJoint:h=new N(d instanceof S?d:null);break;case I.e_pulleyJoint:h=new E(d instanceof R?d:null);break;case I.e_gearJoint:h=new V(d instanceof M?d:null);break;case I.e_lineJoint:h=
new k(d instanceof z?d:null);break;case I.e_weldJoint:h=new aa(d instanceof Z?d:null);break;case I.e_frictionJoint:h=new B(d instanceof Q?d:null)}return h};I.Destroy=function(){};I.prototype.b2Joint=function(d){F.b2Assert(d.bodyA!=d.bodyB);this.m_type=d.type;this.m_next=this.m_prev=null;this.m_bodyA=d.bodyA;this.m_bodyB=d.bodyB;this.m_collideConnected=d.collideConnected;this.m_islandFlag=false;this.m_userData=d.userData};I.prototype.InitVelocityConstraints=function(){};I.prototype.SolveVelocityConstraints=
function(){};I.prototype.FinalizeVelocityConstraints=function(){};I.prototype.SolvePositionConstraints=function(){return false};Box2D.postDefs.push(function(){Box2D.Dynamics.Joints.b2Joint.e_unknownJoint=0;Box2D.Dynamics.Joints.b2Joint.e_revoluteJoint=1;Box2D.Dynamics.Joints.b2Joint.e_prismaticJoint=2;Box2D.Dynamics.Joints.b2Joint.e_distanceJoint=3;Box2D.Dynamics.Joints.b2Joint.e_pulleyJoint=4;Box2D.Dynamics.Joints.b2Joint.e_mouseJoint=5;Box2D.Dynamics.Joints.b2Joint.e_gearJoint=6;Box2D.Dynamics.Joints.b2Joint.e_lineJoint=
7;Box2D.Dynamics.Joints.b2Joint.e_weldJoint=8;Box2D.Dynamics.Joints.b2Joint.e_frictionJoint=9;Box2D.Dynamics.Joints.b2Joint.e_inactiveLimit=0;Box2D.Dynamics.Joints.b2Joint.e_atLowerLimit=1;Box2D.Dynamics.Joints.b2Joint.e_atUpperLimit=2;Box2D.Dynamics.Joints.b2Joint.e_equalLimits=3});W.b2JointDef=function(){};W.prototype.b2JointDef=function(){this.type=I.e_unknownJoint;this.bodyB=this.bodyA=this.userData=null;this.collideConnected=false};Y.b2JointEdge=function(){};Box2D.inherit(k,Box2D.Dynamics.Joints.b2Joint);
k.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;k.b2LineJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_localXAxis1=new w;this.m_localYAxis1=new w;this.m_axis=new w;this.m_perp=new w;this.m_K=new G;this.m_impulse=new w};k.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};k.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};k.prototype.GetReactionForce=
function(d){if(d===undefined)d=0;return new w(d*(this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.y)*this.m_axis.x),d*(this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.y)*this.m_axis.y))};k.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_impulse.y};k.prototype.GetJointTranslation=function(){var d=this.m_bodyA,h=this.m_bodyB,l=d.GetWorldPoint(this.m_localAnchor1),j=h.GetWorldPoint(this.m_localAnchor2);h=j.x-l.x;l=j.y-l.y;d=d.GetWorldVector(this.m_localXAxis1);
return d.x*h+d.y*l};k.prototype.GetJointSpeed=function(){var d=this.m_bodyA,h=this.m_bodyB,l;l=d.m_xf.R;var j=this.m_localAnchor1.x-d.m_sweep.localCenter.x,o=this.m_localAnchor1.y-d.m_sweep.localCenter.y,q=l.col1.x*j+l.col2.x*o;o=l.col1.y*j+l.col2.y*o;j=q;l=h.m_xf.R;var n=this.m_localAnchor2.x-h.m_sweep.localCenter.x,a=this.m_localAnchor2.y-h.m_sweep.localCenter.y;q=l.col1.x*n+l.col2.x*a;a=l.col1.y*n+l.col2.y*a;n=q;l=h.m_sweep.c.x+n-(d.m_sweep.c.x+j);q=h.m_sweep.c.y+a-(d.m_sweep.c.y+o);var c=d.GetWorldVector(this.m_localXAxis1),
g=d.m_linearVelocity,b=h.m_linearVelocity;d=d.m_angularVelocity;h=h.m_angularVelocity;return l*-d*c.y+q*d*c.x+(c.x*(b.x+-h*a-g.x- -d*o)+c.y*(b.y+h*n-g.y-d*j))};k.prototype.IsLimitEnabled=function(){return this.m_enableLimit};k.prototype.EnableLimit=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableLimit=d};k.prototype.GetLowerLimit=function(){return this.m_lowerTranslation};k.prototype.GetUpperLimit=function(){return this.m_upperTranslation};k.prototype.SetLimits=function(d,
h){if(d===undefined)d=0;if(h===undefined)h=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_lowerTranslation=d;this.m_upperTranslation=h};k.prototype.IsMotorEnabled=function(){return this.m_enableMotor};k.prototype.EnableMotor=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableMotor=d};k.prototype.SetMotorSpeed=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_motorSpeed=d};k.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};
k.prototype.SetMaxMotorForce=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_maxMotorForce=d};k.prototype.GetMaxMotorForce=function(){return this.m_maxMotorForce};k.prototype.GetMotorForce=function(){return this.m_motorImpulse};k.prototype.b2LineJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_localXAxis1.SetV(d.localAxisA);this.m_localYAxis1.x=-this.m_localXAxis1.y;
this.m_localYAxis1.y=this.m_localXAxis1.x;this.m_impulse.SetZero();this.m_motorImpulse=this.m_motorMass=0;this.m_lowerTranslation=d.lowerTranslation;this.m_upperTranslation=d.upperTranslation;this.m_maxMotorForce=d.maxMotorForce;this.m_motorSpeed=d.motorSpeed;this.m_enableLimit=d.enableLimit;this.m_enableMotor=d.enableMotor;this.m_limitState=I.e_inactiveLimit;this.m_axis.SetZero();this.m_perp.SetZero()};k.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j,o=0;this.m_localCenterA.SetV(h.GetLocalCenter());
this.m_localCenterB.SetV(l.GetLocalCenter());var q=h.GetTransform();l.GetTransform();j=h.m_xf.R;var n=this.m_localAnchor1.x-this.m_localCenterA.x,a=this.m_localAnchor1.y-this.m_localCenterA.y;o=j.col1.x*n+j.col2.x*a;a=j.col1.y*n+j.col2.y*a;n=o;j=l.m_xf.R;var c=this.m_localAnchor2.x-this.m_localCenterB.x,g=this.m_localAnchor2.y-this.m_localCenterB.y;o=j.col1.x*c+j.col2.x*g;g=j.col1.y*c+j.col2.y*g;c=o;j=l.m_sweep.c.x+c-h.m_sweep.c.x-n;o=l.m_sweep.c.y+g-h.m_sweep.c.y-a;this.m_invMassA=h.m_invMass;this.m_invMassB=
l.m_invMass;this.m_invIA=h.m_invI;this.m_invIB=l.m_invI;this.m_axis.SetV(y.MulMV(q.R,this.m_localXAxis1));this.m_a1=(j+n)*this.m_axis.y-(o+a)*this.m_axis.x;this.m_a2=c*this.m_axis.y-g*this.m_axis.x;this.m_motorMass=this.m_invMassA+this.m_invMassB+this.m_invIA*this.m_a1*this.m_a1+this.m_invIB*this.m_a2*this.m_a2;this.m_motorMass=this.m_motorMass>Number.MIN_VALUE?1/this.m_motorMass:0;this.m_perp.SetV(y.MulMV(q.R,this.m_localYAxis1));this.m_s1=(j+n)*this.m_perp.y-(o+a)*this.m_perp.x;this.m_s2=c*this.m_perp.y-
g*this.m_perp.x;q=this.m_invMassA;n=this.m_invMassB;a=this.m_invIA;c=this.m_invIB;this.m_K.col1.x=q+n+a*this.m_s1*this.m_s1+c*this.m_s2*this.m_s2;this.m_K.col1.y=a*this.m_s1*this.m_a1+c*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=q+n+a*this.m_a1*this.m_a1+c*this.m_a2*this.m_a2;if(this.m_enableLimit){j=this.m_axis.x*j+this.m_axis.y*o;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop)this.m_limitState=I.e_equalLimits;else if(j<=this.m_lowerTranslation){if(this.m_limitState!=
I.e_atLowerLimit){this.m_limitState=I.e_atLowerLimit;this.m_impulse.y=0}}else if(j>=this.m_upperTranslation){if(this.m_limitState!=I.e_atUpperLimit){this.m_limitState=I.e_atUpperLimit;this.m_impulse.y=0}}else{this.m_limitState=I.e_inactiveLimit;this.m_impulse.y=0}}else this.m_limitState=I.e_inactiveLimit;if(this.m_enableMotor==false)this.m_motorImpulse=0;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_motorImpulse*=d.dtRatio;d=this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+
this.m_impulse.y)*this.m_axis.x;j=this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.y)*this.m_axis.y;o=this.m_impulse.x*this.m_s1+(this.m_motorImpulse+this.m_impulse.y)*this.m_a1;q=this.m_impulse.x*this.m_s2+(this.m_motorImpulse+this.m_impulse.y)*this.m_a2;h.m_linearVelocity.x-=this.m_invMassA*d;h.m_linearVelocity.y-=this.m_invMassA*j;h.m_angularVelocity-=this.m_invIA*o;l.m_linearVelocity.x+=this.m_invMassB*d;l.m_linearVelocity.y+=this.m_invMassB*j;l.m_angularVelocity+=this.m_invIB*
q}else{this.m_impulse.SetZero();this.m_motorImpulse=0}};k.prototype.SolveVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j=h.m_linearVelocity,o=h.m_angularVelocity,q=l.m_linearVelocity,n=l.m_angularVelocity,a=0,c=0,g=0,b=0;if(this.m_enableMotor&&this.m_limitState!=I.e_equalLimits){b=this.m_motorMass*(this.m_motorSpeed-(this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o));a=this.m_motorImpulse;c=d.dt*this.m_maxMotorForce;this.m_motorImpulse=y.Clamp(this.m_motorImpulse+
b,-c,c);b=this.m_motorImpulse-a;a=b*this.m_axis.x;c=b*this.m_axis.y;g=b*this.m_a1;b=b*this.m_a2;j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b}c=this.m_perp.x*(q.x-j.x)+this.m_perp.y*(q.y-j.y)+this.m_s2*n-this.m_s1*o;if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){g=this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o;a=this.m_impulse.Copy();d=this.m_K.Solve(new w,-c,-g);this.m_impulse.Add(d);
if(this.m_limitState==I.e_atLowerLimit)this.m_impulse.y=y.Max(this.m_impulse.y,0);else if(this.m_limitState==I.e_atUpperLimit)this.m_impulse.y=y.Min(this.m_impulse.y,0);c=-c-(this.m_impulse.y-a.y)*this.m_K.col2.x;g=0;g=this.m_K.col1.x!=0?c/this.m_K.col1.x+a.x:a.x;this.m_impulse.x=g;d.x=this.m_impulse.x-a.x;d.y=this.m_impulse.y-a.y;a=d.x*this.m_perp.x+d.y*this.m_axis.x;c=d.x*this.m_perp.y+d.y*this.m_axis.y;g=d.x*this.m_s1+d.y*this.m_a1;b=d.x*this.m_s2+d.y*this.m_a2}else{d=0;d=this.m_K.col1.x!=0?-c/
this.m_K.col1.x:0;this.m_impulse.x+=d;a=d*this.m_perp.x;c=d*this.m_perp.y;g=d*this.m_s1;b=d*this.m_s2}j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b;h.m_linearVelocity.SetV(j);h.m_angularVelocity=o;l.m_linearVelocity.SetV(q);l.m_angularVelocity=n};k.prototype.SolvePositionConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l=d.m_sweep.c,j=d.m_sweep.a,o=h.m_sweep.c,q=h.m_sweep.a,n,a=0,c=0,g=0,b=0,e=n=0,f=0;c=false;
var m=0,r=G.FromAngle(j);g=G.FromAngle(q);n=r;f=this.m_localAnchor1.x-this.m_localCenterA.x;var s=this.m_localAnchor1.y-this.m_localCenterA.y;a=n.col1.x*f+n.col2.x*s;s=n.col1.y*f+n.col2.y*s;f=a;n=g;g=this.m_localAnchor2.x-this.m_localCenterB.x;b=this.m_localAnchor2.y-this.m_localCenterB.y;a=n.col1.x*g+n.col2.x*b;b=n.col1.y*g+n.col2.y*b;g=a;n=o.x+g-l.x-f;a=o.y+b-l.y-s;if(this.m_enableLimit){this.m_axis=y.MulMV(r,this.m_localXAxis1);this.m_a1=(n+f)*this.m_axis.y-(a+s)*this.m_axis.x;this.m_a2=g*this.m_axis.y-
b*this.m_axis.x;var v=this.m_axis.x*n+this.m_axis.y*a;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop){m=y.Clamp(v,-F.b2_maxLinearCorrection,F.b2_maxLinearCorrection);e=y.Abs(v);c=true}else if(v<=this.m_lowerTranslation){m=y.Clamp(v-this.m_lowerTranslation+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);e=this.m_lowerTranslation-v;c=true}else if(v>=this.m_upperTranslation){m=y.Clamp(v-this.m_upperTranslation+F.b2_linearSlop,0,F.b2_maxLinearCorrection);e=v-this.m_upperTranslation;
c=true}}this.m_perp=y.MulMV(r,this.m_localYAxis1);this.m_s1=(n+f)*this.m_perp.y-(a+s)*this.m_perp.x;this.m_s2=g*this.m_perp.y-b*this.m_perp.x;r=new w;s=this.m_perp.x*n+this.m_perp.y*a;e=y.Max(e,y.Abs(s));f=0;if(c){c=this.m_invMassA;g=this.m_invMassB;b=this.m_invIA;n=this.m_invIB;this.m_K.col1.x=c+g+b*this.m_s1*this.m_s1+n*this.m_s2*this.m_s2;this.m_K.col1.y=b*this.m_s1*this.m_a1+n*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=c+g+b*this.m_a1*this.m_a1+n*this.m_a2*this.m_a2;this.m_K.Solve(r,
-s,-m)}else{c=this.m_invMassA;g=this.m_invMassB;b=this.m_invIA;n=this.m_invIB;m=c+g+b*this.m_s1*this.m_s1+n*this.m_s2*this.m_s2;c=0;c=m!=0?-s/m:0;r.x=c;r.y=0}m=r.x*this.m_perp.x+r.y*this.m_axis.x;c=r.x*this.m_perp.y+r.y*this.m_axis.y;s=r.x*this.m_s1+r.y*this.m_a1;r=r.x*this.m_s2+r.y*this.m_a2;l.x-=this.m_invMassA*m;l.y-=this.m_invMassA*c;j-=this.m_invIA*s;o.x+=this.m_invMassB*m;o.y+=this.m_invMassB*c;q+=this.m_invIB*r;d.m_sweep.a=j;h.m_sweep.a=q;d.SynchronizeTransform();h.SynchronizeTransform();return e<=
F.b2_linearSlop&&f<=F.b2_angularSlop};Box2D.inherit(z,Box2D.Dynamics.Joints.b2JointDef);z.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;z.b2LineJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w;this.localAxisA=new w};z.prototype.b2LineJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_lineJoint;this.localAxisA.Set(1,0);this.enableLimit=false;this.upperTranslation=this.lowerTranslation=
0;this.enableMotor=false;this.motorSpeed=this.maxMotorForce=0};z.prototype.Initialize=function(d,h,l,j){this.bodyA=d;this.bodyB=h;this.localAnchorA=this.bodyA.GetLocalPoint(l);this.localAnchorB=this.bodyB.GetLocalPoint(l);this.localAxisA=this.bodyA.GetLocalVector(j)};Box2D.inherit(u,Box2D.Dynamics.Joints.b2Joint);u.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;u.b2MouseJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.K=new G;this.K1=new G;this.K2=new G;
this.m_localAnchor=new w;this.m_target=new w;this.m_impulse=new w;this.m_mass=new G;this.m_C=new w};u.prototype.GetAnchorA=function(){return this.m_target};u.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor)};u.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_impulse.x,d*this.m_impulse.y)};u.prototype.GetReactionTorque=function(){return 0};u.prototype.GetTarget=function(){return this.m_target};u.prototype.SetTarget=function(d){this.m_bodyB.IsAwake()==
false&&this.m_bodyB.SetAwake(true);this.m_target=d};u.prototype.GetMaxForce=function(){return this.m_maxForce};u.prototype.SetMaxForce=function(d){if(d===undefined)d=0;this.m_maxForce=d};u.prototype.GetFrequency=function(){return this.m_frequencyHz};u.prototype.SetFrequency=function(d){if(d===undefined)d=0;this.m_frequencyHz=d};u.prototype.GetDampingRatio=function(){return this.m_dampingRatio};u.prototype.SetDampingRatio=function(d){if(d===undefined)d=0;this.m_dampingRatio=d};u.prototype.b2MouseJoint=
function(d){this.__super.b2Joint.call(this,d);this.m_target.SetV(d.target);var h=this.m_target.x-this.m_bodyB.m_xf.position.x,l=this.m_target.y-this.m_bodyB.m_xf.position.y,j=this.m_bodyB.m_xf.R;this.m_localAnchor.x=h*j.col1.x+l*j.col1.y;this.m_localAnchor.y=h*j.col2.x+l*j.col2.y;this.m_maxForce=d.maxForce;this.m_impulse.SetZero();this.m_frequencyHz=d.frequencyHz;this.m_dampingRatio=d.dampingRatio;this.m_gamma=this.m_beta=0};u.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyB,l=h.GetMass(),
j=2*Math.PI*this.m_frequencyHz,o=l*j*j;this.m_gamma=d.dt*(2*l*this.m_dampingRatio*j+d.dt*o);this.m_gamma=this.m_gamma!=0?1/this.m_gamma:0;this.m_beta=d.dt*o*this.m_gamma;o=h.m_xf.R;l=this.m_localAnchor.x-h.m_sweep.localCenter.x;j=this.m_localAnchor.y-h.m_sweep.localCenter.y;var q=o.col1.x*l+o.col2.x*j;j=o.col1.y*l+o.col2.y*j;l=q;o=h.m_invMass;q=h.m_invI;this.K1.col1.x=o;this.K1.col2.x=0;this.K1.col1.y=0;this.K1.col2.y=o;this.K2.col1.x=q*j*j;this.K2.col2.x=-q*l*j;this.K2.col1.y=-q*l*j;this.K2.col2.y=
q*l*l;this.K.SetM(this.K1);this.K.AddM(this.K2);this.K.col1.x+=this.m_gamma;this.K.col2.y+=this.m_gamma;this.K.GetInverse(this.m_mass);this.m_C.x=h.m_sweep.c.x+l-this.m_target.x;this.m_C.y=h.m_sweep.c.y+j-this.m_target.y;h.m_angularVelocity*=0.98;this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;h.m_linearVelocity.x+=o*this.m_impulse.x;h.m_linearVelocity.y+=o*this.m_impulse.y;h.m_angularVelocity+=q*(l*this.m_impulse.y-j*this.m_impulse.x)};u.prototype.SolveVelocityConstraints=function(d){var h=
this.m_bodyB,l,j=0,o=0;l=h.m_xf.R;var q=this.m_localAnchor.x-h.m_sweep.localCenter.x,n=this.m_localAnchor.y-h.m_sweep.localCenter.y;j=l.col1.x*q+l.col2.x*n;n=l.col1.y*q+l.col2.y*n;q=j;j=h.m_linearVelocity.x+-h.m_angularVelocity*n;var a=h.m_linearVelocity.y+h.m_angularVelocity*q;l=this.m_mass;j=j+this.m_beta*this.m_C.x+this.m_gamma*this.m_impulse.x;o=a+this.m_beta*this.m_C.y+this.m_gamma*this.m_impulse.y;a=-(l.col1.x*j+l.col2.x*o);o=-(l.col1.y*j+l.col2.y*o);l=this.m_impulse.x;j=this.m_impulse.y;this.m_impulse.x+=
a;this.m_impulse.y+=o;d=d.dt*this.m_maxForce;this.m_impulse.LengthSquared()>d*d&&this.m_impulse.Multiply(d/this.m_impulse.Length());a=this.m_impulse.x-l;o=this.m_impulse.y-j;h.m_linearVelocity.x+=h.m_invMass*a;h.m_linearVelocity.y+=h.m_invMass*o;h.m_angularVelocity+=h.m_invI*(q*o-n*a)};u.prototype.SolvePositionConstraints=function(){return true};Box2D.inherit(D,Box2D.Dynamics.Joints.b2JointDef);D.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;D.b2MouseJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,
arguments);this.target=new w};D.prototype.b2MouseJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_mouseJoint;this.maxForce=0;this.frequencyHz=5;this.dampingRatio=0.7};Box2D.inherit(H,Box2D.Dynamics.Joints.b2Joint);H.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;H.b2PrismaticJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_localXAxis1=new w;this.m_localYAxis1=new w;this.m_axis=new w;
this.m_perp=new w;this.m_K=new K;this.m_impulse=new A};H.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};H.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};H.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*(this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.x),d*(this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.y))};H.prototype.GetReactionTorque=
function(d){if(d===undefined)d=0;return d*this.m_impulse.y};H.prototype.GetJointTranslation=function(){var d=this.m_bodyA,h=this.m_bodyB,l=d.GetWorldPoint(this.m_localAnchor1),j=h.GetWorldPoint(this.m_localAnchor2);h=j.x-l.x;l=j.y-l.y;d=d.GetWorldVector(this.m_localXAxis1);return d.x*h+d.y*l};H.prototype.GetJointSpeed=function(){var d=this.m_bodyA,h=this.m_bodyB,l;l=d.m_xf.R;var j=this.m_localAnchor1.x-d.m_sweep.localCenter.x,o=this.m_localAnchor1.y-d.m_sweep.localCenter.y,q=l.col1.x*j+l.col2.x*o;
o=l.col1.y*j+l.col2.y*o;j=q;l=h.m_xf.R;var n=this.m_localAnchor2.x-h.m_sweep.localCenter.x,a=this.m_localAnchor2.y-h.m_sweep.localCenter.y;q=l.col1.x*n+l.col2.x*a;a=l.col1.y*n+l.col2.y*a;n=q;l=h.m_sweep.c.x+n-(d.m_sweep.c.x+j);q=h.m_sweep.c.y+a-(d.m_sweep.c.y+o);var c=d.GetWorldVector(this.m_localXAxis1),g=d.m_linearVelocity,b=h.m_linearVelocity;d=d.m_angularVelocity;h=h.m_angularVelocity;return l*-d*c.y+q*d*c.x+(c.x*(b.x+-h*a-g.x- -d*o)+c.y*(b.y+h*n-g.y-d*j))};H.prototype.IsLimitEnabled=function(){return this.m_enableLimit};
H.prototype.EnableLimit=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableLimit=d};H.prototype.GetLowerLimit=function(){return this.m_lowerTranslation};H.prototype.GetUpperLimit=function(){return this.m_upperTranslation};H.prototype.SetLimits=function(d,h){if(d===undefined)d=0;if(h===undefined)h=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_lowerTranslation=d;this.m_upperTranslation=h};H.prototype.IsMotorEnabled=function(){return this.m_enableMotor};
H.prototype.EnableMotor=function(d){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_enableMotor=d};H.prototype.SetMotorSpeed=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_motorSpeed=d};H.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};H.prototype.SetMaxMotorForce=function(d){if(d===undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_maxMotorForce=d};H.prototype.GetMotorForce=function(){return this.m_motorImpulse};
H.prototype.b2PrismaticJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_localXAxis1.SetV(d.localAxisA);this.m_localYAxis1.x=-this.m_localXAxis1.y;this.m_localYAxis1.y=this.m_localXAxis1.x;this.m_refAngle=d.referenceAngle;this.m_impulse.SetZero();this.m_motorImpulse=this.m_motorMass=0;this.m_lowerTranslation=d.lowerTranslation;this.m_upperTranslation=d.upperTranslation;this.m_maxMotorForce=d.maxMotorForce;this.m_motorSpeed=
d.motorSpeed;this.m_enableLimit=d.enableLimit;this.m_enableMotor=d.enableMotor;this.m_limitState=I.e_inactiveLimit;this.m_axis.SetZero();this.m_perp.SetZero()};H.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j,o=0;this.m_localCenterA.SetV(h.GetLocalCenter());this.m_localCenterB.SetV(l.GetLocalCenter());var q=h.GetTransform();l.GetTransform();j=h.m_xf.R;var n=this.m_localAnchor1.x-this.m_localCenterA.x,a=this.m_localAnchor1.y-this.m_localCenterA.y;o=j.col1.x*n+j.col2.x*
a;a=j.col1.y*n+j.col2.y*a;n=o;j=l.m_xf.R;var c=this.m_localAnchor2.x-this.m_localCenterB.x,g=this.m_localAnchor2.y-this.m_localCenterB.y;o=j.col1.x*c+j.col2.x*g;g=j.col1.y*c+j.col2.y*g;c=o;j=l.m_sweep.c.x+c-h.m_sweep.c.x-n;o=l.m_sweep.c.y+g-h.m_sweep.c.y-a;this.m_invMassA=h.m_invMass;this.m_invMassB=l.m_invMass;this.m_invIA=h.m_invI;this.m_invIB=l.m_invI;this.m_axis.SetV(y.MulMV(q.R,this.m_localXAxis1));this.m_a1=(j+n)*this.m_axis.y-(o+a)*this.m_axis.x;this.m_a2=c*this.m_axis.y-g*this.m_axis.x;this.m_motorMass=
this.m_invMassA+this.m_invMassB+this.m_invIA*this.m_a1*this.m_a1+this.m_invIB*this.m_a2*this.m_a2;if(this.m_motorMass>Number.MIN_VALUE)this.m_motorMass=1/this.m_motorMass;this.m_perp.SetV(y.MulMV(q.R,this.m_localYAxis1));this.m_s1=(j+n)*this.m_perp.y-(o+a)*this.m_perp.x;this.m_s2=c*this.m_perp.y-g*this.m_perp.x;q=this.m_invMassA;n=this.m_invMassB;a=this.m_invIA;c=this.m_invIB;this.m_K.col1.x=q+n+a*this.m_s1*this.m_s1+c*this.m_s2*this.m_s2;this.m_K.col1.y=a*this.m_s1+c*this.m_s2;this.m_K.col1.z=a*
this.m_s1*this.m_a1+c*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=a+c;this.m_K.col2.z=a*this.m_a1+c*this.m_a2;this.m_K.col3.x=this.m_K.col1.z;this.m_K.col3.y=this.m_K.col2.z;this.m_K.col3.z=q+n+a*this.m_a1*this.m_a1+c*this.m_a2*this.m_a2;if(this.m_enableLimit){j=this.m_axis.x*j+this.m_axis.y*o;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop)this.m_limitState=I.e_equalLimits;else if(j<=this.m_lowerTranslation){if(this.m_limitState!=I.e_atLowerLimit){this.m_limitState=
I.e_atLowerLimit;this.m_impulse.z=0}}else if(j>=this.m_upperTranslation){if(this.m_limitState!=I.e_atUpperLimit){this.m_limitState=I.e_atUpperLimit;this.m_impulse.z=0}}else{this.m_limitState=I.e_inactiveLimit;this.m_impulse.z=0}}else this.m_limitState=I.e_inactiveLimit;if(this.m_enableMotor==false)this.m_motorImpulse=0;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_motorImpulse*=d.dtRatio;d=this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.x;
j=this.m_impulse.x*this.m_perp.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_axis.y;o=this.m_impulse.x*this.m_s1+this.m_impulse.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_a1;q=this.m_impulse.x*this.m_s2+this.m_impulse.y+(this.m_motorImpulse+this.m_impulse.z)*this.m_a2;h.m_linearVelocity.x-=this.m_invMassA*d;h.m_linearVelocity.y-=this.m_invMassA*j;h.m_angularVelocity-=this.m_invIA*o;l.m_linearVelocity.x+=this.m_invMassB*d;l.m_linearVelocity.y+=this.m_invMassB*j;l.m_angularVelocity+=this.m_invIB*
q}else{this.m_impulse.SetZero();this.m_motorImpulse=0}};H.prototype.SolveVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j=h.m_linearVelocity,o=h.m_angularVelocity,q=l.m_linearVelocity,n=l.m_angularVelocity,a=0,c=0,g=0,b=0;if(this.m_enableMotor&&this.m_limitState!=I.e_equalLimits){b=this.m_motorMass*(this.m_motorSpeed-(this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o));a=this.m_motorImpulse;d=d.dt*this.m_maxMotorForce;this.m_motorImpulse=y.Clamp(this.m_motorImpulse+
b,-d,d);b=this.m_motorImpulse-a;a=b*this.m_axis.x;c=b*this.m_axis.y;g=b*this.m_a1;b=b*this.m_a2;j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b}g=this.m_perp.x*(q.x-j.x)+this.m_perp.y*(q.y-j.y)+this.m_s2*n-this.m_s1*o;c=n-o;if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){d=this.m_axis.x*(q.x-j.x)+this.m_axis.y*(q.y-j.y)+this.m_a2*n-this.m_a1*o;a=this.m_impulse.Copy();d=this.m_K.Solve33(new A,-g,-c,-d);this.m_impulse.Add(d);
if(this.m_limitState==I.e_atLowerLimit)this.m_impulse.z=y.Max(this.m_impulse.z,0);else if(this.m_limitState==I.e_atUpperLimit)this.m_impulse.z=y.Min(this.m_impulse.z,0);g=-g-(this.m_impulse.z-a.z)*this.m_K.col3.x;c=-c-(this.m_impulse.z-a.z)*this.m_K.col3.y;c=this.m_K.Solve22(new w,g,c);c.x+=a.x;c.y+=a.y;this.m_impulse.x=c.x;this.m_impulse.y=c.y;d.x=this.m_impulse.x-a.x;d.y=this.m_impulse.y-a.y;d.z=this.m_impulse.z-a.z;a=d.x*this.m_perp.x+d.z*this.m_axis.x;c=d.x*this.m_perp.y+d.z*this.m_axis.y;g=d.x*
this.m_s1+d.y+d.z*this.m_a1;b=d.x*this.m_s2+d.y+d.z*this.m_a2}else{d=this.m_K.Solve22(new w,-g,-c);this.m_impulse.x+=d.x;this.m_impulse.y+=d.y;a=d.x*this.m_perp.x;c=d.x*this.m_perp.y;g=d.x*this.m_s1+d.y;b=d.x*this.m_s2+d.y}j.x-=this.m_invMassA*a;j.y-=this.m_invMassA*c;o-=this.m_invIA*g;q.x+=this.m_invMassB*a;q.y+=this.m_invMassB*c;n+=this.m_invIB*b;h.m_linearVelocity.SetV(j);h.m_angularVelocity=o;l.m_linearVelocity.SetV(q);l.m_angularVelocity=n};H.prototype.SolvePositionConstraints=function(){var d=
this.m_bodyA,h=this.m_bodyB,l=d.m_sweep.c,j=d.m_sweep.a,o=h.m_sweep.c,q=h.m_sweep.a,n,a=0,c=0,g=0,b=a=n=0,e=0;c=false;var f=0,m=G.FromAngle(j),r=G.FromAngle(q);n=m;e=this.m_localAnchor1.x-this.m_localCenterA.x;var s=this.m_localAnchor1.y-this.m_localCenterA.y;a=n.col1.x*e+n.col2.x*s;s=n.col1.y*e+n.col2.y*s;e=a;n=r;r=this.m_localAnchor2.x-this.m_localCenterB.x;g=this.m_localAnchor2.y-this.m_localCenterB.y;a=n.col1.x*r+n.col2.x*g;g=n.col1.y*r+n.col2.y*g;r=a;n=o.x+r-l.x-e;a=o.y+g-l.y-s;if(this.m_enableLimit){this.m_axis=
y.MulMV(m,this.m_localXAxis1);this.m_a1=(n+e)*this.m_axis.y-(a+s)*this.m_axis.x;this.m_a2=r*this.m_axis.y-g*this.m_axis.x;var v=this.m_axis.x*n+this.m_axis.y*a;if(y.Abs(this.m_upperTranslation-this.m_lowerTranslation)<2*F.b2_linearSlop){f=y.Clamp(v,-F.b2_maxLinearCorrection,F.b2_maxLinearCorrection);b=y.Abs(v);c=true}else if(v<=this.m_lowerTranslation){f=y.Clamp(v-this.m_lowerTranslation+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);b=this.m_lowerTranslation-v;c=true}else if(v>=this.m_upperTranslation){f=
y.Clamp(v-this.m_upperTranslation+F.b2_linearSlop,0,F.b2_maxLinearCorrection);b=v-this.m_upperTranslation;c=true}}this.m_perp=y.MulMV(m,this.m_localYAxis1);this.m_s1=(n+e)*this.m_perp.y-(a+s)*this.m_perp.x;this.m_s2=r*this.m_perp.y-g*this.m_perp.x;m=new A;s=this.m_perp.x*n+this.m_perp.y*a;r=q-j-this.m_refAngle;b=y.Max(b,y.Abs(s));e=y.Abs(r);if(c){c=this.m_invMassA;g=this.m_invMassB;n=this.m_invIA;a=this.m_invIB;this.m_K.col1.x=c+g+n*this.m_s1*this.m_s1+a*this.m_s2*this.m_s2;this.m_K.col1.y=n*this.m_s1+
a*this.m_s2;this.m_K.col1.z=n*this.m_s1*this.m_a1+a*this.m_s2*this.m_a2;this.m_K.col2.x=this.m_K.col1.y;this.m_K.col2.y=n+a;this.m_K.col2.z=n*this.m_a1+a*this.m_a2;this.m_K.col3.x=this.m_K.col1.z;this.m_K.col3.y=this.m_K.col2.z;this.m_K.col3.z=c+g+n*this.m_a1*this.m_a1+a*this.m_a2*this.m_a2;this.m_K.Solve33(m,-s,-r,-f)}else{c=this.m_invMassA;g=this.m_invMassB;n=this.m_invIA;a=this.m_invIB;f=n*this.m_s1+a*this.m_s2;v=n+a;this.m_K.col1.Set(c+g+n*this.m_s1*this.m_s1+a*this.m_s2*this.m_s2,f,0);this.m_K.col2.Set(f,
v,0);f=this.m_K.Solve22(new w,-s,-r);m.x=f.x;m.y=f.y;m.z=0}f=m.x*this.m_perp.x+m.z*this.m_axis.x;c=m.x*this.m_perp.y+m.z*this.m_axis.y;s=m.x*this.m_s1+m.y+m.z*this.m_a1;m=m.x*this.m_s2+m.y+m.z*this.m_a2;l.x-=this.m_invMassA*f;l.y-=this.m_invMassA*c;j-=this.m_invIA*s;o.x+=this.m_invMassB*f;o.y+=this.m_invMassB*c;q+=this.m_invIB*m;d.m_sweep.a=j;h.m_sweep.a=q;d.SynchronizeTransform();h.SynchronizeTransform();return b<=F.b2_linearSlop&&e<=F.b2_angularSlop};Box2D.inherit(O,Box2D.Dynamics.Joints.b2JointDef);
O.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;O.b2PrismaticJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w;this.localAxisA=new w};O.prototype.b2PrismaticJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_prismaticJoint;this.localAxisA.Set(1,0);this.referenceAngle=0;this.enableLimit=false;this.upperTranslation=this.lowerTranslation=0;this.enableMotor=false;this.motorSpeed=this.maxMotorForce=
0};O.prototype.Initialize=function(d,h,l,j){this.bodyA=d;this.bodyB=h;this.localAnchorA=this.bodyA.GetLocalPoint(l);this.localAnchorB=this.bodyB.GetLocalPoint(l);this.localAxisA=this.bodyA.GetLocalVector(j);this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()};Box2D.inherit(E,Box2D.Dynamics.Joints.b2Joint);E.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;E.b2PulleyJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_groundAnchor1=new w;this.m_groundAnchor2=
new w;this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_u1=new w;this.m_u2=new w};E.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};E.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};E.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_impulse*this.m_u2.x,d*this.m_impulse*this.m_u2.y)};E.prototype.GetReactionTorque=function(){return 0};E.prototype.GetGroundAnchorA=function(){var d=
this.m_ground.m_xf.position.Copy();d.Add(this.m_groundAnchor1);return d};E.prototype.GetGroundAnchorB=function(){var d=this.m_ground.m_xf.position.Copy();d.Add(this.m_groundAnchor2);return d};E.prototype.GetLength1=function(){var d=this.m_bodyA.GetWorldPoint(this.m_localAnchor1),h=d.x-(this.m_ground.m_xf.position.x+this.m_groundAnchor1.x);d=d.y-(this.m_ground.m_xf.position.y+this.m_groundAnchor1.y);return Math.sqrt(h*h+d*d)};E.prototype.GetLength2=function(){var d=this.m_bodyB.GetWorldPoint(this.m_localAnchor2),
h=d.x-(this.m_ground.m_xf.position.x+this.m_groundAnchor2.x);d=d.y-(this.m_ground.m_xf.position.y+this.m_groundAnchor2.y);return Math.sqrt(h*h+d*d)};E.prototype.GetRatio=function(){return this.m_ratio};E.prototype.b2PulleyJoint=function(d){this.__super.b2Joint.call(this,d);this.m_ground=this.m_bodyA.m_world.m_groundBody;this.m_groundAnchor1.x=d.groundAnchorA.x-this.m_ground.m_xf.position.x;this.m_groundAnchor1.y=d.groundAnchorA.y-this.m_ground.m_xf.position.y;this.m_groundAnchor2.x=d.groundAnchorB.x-
this.m_ground.m_xf.position.x;this.m_groundAnchor2.y=d.groundAnchorB.y-this.m_ground.m_xf.position.y;this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_ratio=d.ratio;this.m_constant=d.lengthA+this.m_ratio*d.lengthB;this.m_maxLength1=y.Min(d.maxLengthA,this.m_constant-this.m_ratio*E.b2_minPulleyLength);this.m_maxLength2=y.Min(d.maxLengthB,(this.m_constant-E.b2_minPulleyLength)/this.m_ratio);this.m_limitImpulse2=this.m_limitImpulse1=this.m_impulse=0};E.prototype.InitVelocityConstraints=
function(d){var h=this.m_bodyA,l=this.m_bodyB,j;j=h.m_xf.R;var o=this.m_localAnchor1.x-h.m_sweep.localCenter.x,q=this.m_localAnchor1.y-h.m_sweep.localCenter.y,n=j.col1.x*o+j.col2.x*q;q=j.col1.y*o+j.col2.y*q;o=n;j=l.m_xf.R;var a=this.m_localAnchor2.x-l.m_sweep.localCenter.x,c=this.m_localAnchor2.y-l.m_sweep.localCenter.y;n=j.col1.x*a+j.col2.x*c;c=j.col1.y*a+j.col2.y*c;a=n;j=l.m_sweep.c.x+a;n=l.m_sweep.c.y+c;var g=this.m_ground.m_xf.position.x+this.m_groundAnchor2.x,b=this.m_ground.m_xf.position.y+
this.m_groundAnchor2.y;this.m_u1.Set(h.m_sweep.c.x+o-(this.m_ground.m_xf.position.x+this.m_groundAnchor1.x),h.m_sweep.c.y+q-(this.m_ground.m_xf.position.y+this.m_groundAnchor1.y));this.m_u2.Set(j-g,n-b);j=this.m_u1.Length();n=this.m_u2.Length();j>F.b2_linearSlop?this.m_u1.Multiply(1/j):this.m_u1.SetZero();n>F.b2_linearSlop?this.m_u2.Multiply(1/n):this.m_u2.SetZero();if(this.m_constant-j-this.m_ratio*n>0){this.m_state=I.e_inactiveLimit;this.m_impulse=0}else this.m_state=I.e_atUpperLimit;if(j<this.m_maxLength1){this.m_limitState1=
I.e_inactiveLimit;this.m_limitImpulse1=0}else this.m_limitState1=I.e_atUpperLimit;if(n<this.m_maxLength2){this.m_limitState2=I.e_inactiveLimit;this.m_limitImpulse2=0}else this.m_limitState2=I.e_atUpperLimit;j=o*this.m_u1.y-q*this.m_u1.x;n=a*this.m_u2.y-c*this.m_u2.x;this.m_limitMass1=h.m_invMass+h.m_invI*j*j;this.m_limitMass2=l.m_invMass+l.m_invI*n*n;this.m_pulleyMass=this.m_limitMass1+this.m_ratio*this.m_ratio*this.m_limitMass2;this.m_limitMass1=1/this.m_limitMass1;this.m_limitMass2=1/this.m_limitMass2;
this.m_pulleyMass=1/this.m_pulleyMass;if(d.warmStarting){this.m_impulse*=d.dtRatio;this.m_limitImpulse1*=d.dtRatio;this.m_limitImpulse2*=d.dtRatio;d=(-this.m_impulse-this.m_limitImpulse1)*this.m_u1.x;j=(-this.m_impulse-this.m_limitImpulse1)*this.m_u1.y;n=(-this.m_ratio*this.m_impulse-this.m_limitImpulse2)*this.m_u2.x;g=(-this.m_ratio*this.m_impulse-this.m_limitImpulse2)*this.m_u2.y;h.m_linearVelocity.x+=h.m_invMass*d;h.m_linearVelocity.y+=h.m_invMass*j;h.m_angularVelocity+=h.m_invI*(o*j-q*d);l.m_linearVelocity.x+=
l.m_invMass*n;l.m_linearVelocity.y+=l.m_invMass*g;l.m_angularVelocity+=l.m_invI*(a*g-c*n)}else this.m_limitImpulse2=this.m_limitImpulse1=this.m_impulse=0};E.prototype.SolveVelocityConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l;l=d.m_xf.R;var j=this.m_localAnchor1.x-d.m_sweep.localCenter.x,o=this.m_localAnchor1.y-d.m_sweep.localCenter.y,q=l.col1.x*j+l.col2.x*o;o=l.col1.y*j+l.col2.y*o;j=q;l=h.m_xf.R;var n=this.m_localAnchor2.x-h.m_sweep.localCenter.x,a=this.m_localAnchor2.y-h.m_sweep.localCenter.y;
q=l.col1.x*n+l.col2.x*a;a=l.col1.y*n+l.col2.y*a;n=q;var c=q=l=0,g=0;l=g=l=g=c=q=l=0;if(this.m_state==I.e_atUpperLimit){l=d.m_linearVelocity.x+-d.m_angularVelocity*o;q=d.m_linearVelocity.y+d.m_angularVelocity*j;c=h.m_linearVelocity.x+-h.m_angularVelocity*a;g=h.m_linearVelocity.y+h.m_angularVelocity*n;l=-(this.m_u1.x*l+this.m_u1.y*q)-this.m_ratio*(this.m_u2.x*c+this.m_u2.y*g);g=this.m_pulleyMass*-l;l=this.m_impulse;this.m_impulse=y.Max(0,this.m_impulse+g);g=this.m_impulse-l;l=-g*this.m_u1.x;q=-g*this.m_u1.y;
c=-this.m_ratio*g*this.m_u2.x;g=-this.m_ratio*g*this.m_u2.y;d.m_linearVelocity.x+=d.m_invMass*l;d.m_linearVelocity.y+=d.m_invMass*q;d.m_angularVelocity+=d.m_invI*(j*q-o*l);h.m_linearVelocity.x+=h.m_invMass*c;h.m_linearVelocity.y+=h.m_invMass*g;h.m_angularVelocity+=h.m_invI*(n*g-a*c)}if(this.m_limitState1==I.e_atUpperLimit){l=d.m_linearVelocity.x+-d.m_angularVelocity*o;q=d.m_linearVelocity.y+d.m_angularVelocity*j;l=-(this.m_u1.x*l+this.m_u1.y*q);g=-this.m_limitMass1*l;l=this.m_limitImpulse1;this.m_limitImpulse1=
y.Max(0,this.m_limitImpulse1+g);g=this.m_limitImpulse1-l;l=-g*this.m_u1.x;q=-g*this.m_u1.y;d.m_linearVelocity.x+=d.m_invMass*l;d.m_linearVelocity.y+=d.m_invMass*q;d.m_angularVelocity+=d.m_invI*(j*q-o*l)}if(this.m_limitState2==I.e_atUpperLimit){c=h.m_linearVelocity.x+-h.m_angularVelocity*a;g=h.m_linearVelocity.y+h.m_angularVelocity*n;l=-(this.m_u2.x*c+this.m_u2.y*g);g=-this.m_limitMass2*l;l=this.m_limitImpulse2;this.m_limitImpulse2=y.Max(0,this.m_limitImpulse2+g);g=this.m_limitImpulse2-l;c=-g*this.m_u2.x;
g=-g*this.m_u2.y;h.m_linearVelocity.x+=h.m_invMass*c;h.m_linearVelocity.y+=h.m_invMass*g;h.m_angularVelocity+=h.m_invI*(n*g-a*c)}};E.prototype.SolvePositionConstraints=function(){var d=this.m_bodyA,h=this.m_bodyB,l,j=this.m_ground.m_xf.position.x+this.m_groundAnchor1.x,o=this.m_ground.m_xf.position.y+this.m_groundAnchor1.y,q=this.m_ground.m_xf.position.x+this.m_groundAnchor2.x,n=this.m_ground.m_xf.position.y+this.m_groundAnchor2.y,a=0,c=0,g=0,b=0,e=l=0,f=0,m=0,r=e=m=l=e=l=0;if(this.m_state==I.e_atUpperLimit){l=
d.m_xf.R;a=this.m_localAnchor1.x-d.m_sweep.localCenter.x;c=this.m_localAnchor1.y-d.m_sweep.localCenter.y;e=l.col1.x*a+l.col2.x*c;c=l.col1.y*a+l.col2.y*c;a=e;l=h.m_xf.R;g=this.m_localAnchor2.x-h.m_sweep.localCenter.x;b=this.m_localAnchor2.y-h.m_sweep.localCenter.y;e=l.col1.x*g+l.col2.x*b;b=l.col1.y*g+l.col2.y*b;g=e;l=d.m_sweep.c.x+a;e=d.m_sweep.c.y+c;f=h.m_sweep.c.x+g;m=h.m_sweep.c.y+b;this.m_u1.Set(l-j,e-o);this.m_u2.Set(f-q,m-n);l=this.m_u1.Length();e=this.m_u2.Length();l>F.b2_linearSlop?this.m_u1.Multiply(1/
l):this.m_u1.SetZero();e>F.b2_linearSlop?this.m_u2.Multiply(1/e):this.m_u2.SetZero();l=this.m_constant-l-this.m_ratio*e;r=y.Max(r,-l);l=y.Clamp(l+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);m=-this.m_pulleyMass*l;l=-m*this.m_u1.x;e=-m*this.m_u1.y;f=-this.m_ratio*m*this.m_u2.x;m=-this.m_ratio*m*this.m_u2.y;d.m_sweep.c.x+=d.m_invMass*l;d.m_sweep.c.y+=d.m_invMass*e;d.m_sweep.a+=d.m_invI*(a*e-c*l);h.m_sweep.c.x+=h.m_invMass*f;h.m_sweep.c.y+=h.m_invMass*m;h.m_sweep.a+=h.m_invI*(g*m-b*f);d.SynchronizeTransform();
h.SynchronizeTransform()}if(this.m_limitState1==I.e_atUpperLimit){l=d.m_xf.R;a=this.m_localAnchor1.x-d.m_sweep.localCenter.x;c=this.m_localAnchor1.y-d.m_sweep.localCenter.y;e=l.col1.x*a+l.col2.x*c;c=l.col1.y*a+l.col2.y*c;a=e;l=d.m_sweep.c.x+a;e=d.m_sweep.c.y+c;this.m_u1.Set(l-j,e-o);l=this.m_u1.Length();if(l>F.b2_linearSlop){this.m_u1.x*=1/l;this.m_u1.y*=1/l}else this.m_u1.SetZero();l=this.m_maxLength1-l;r=y.Max(r,-l);l=y.Clamp(l+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);m=-this.m_limitMass1*l;
l=-m*this.m_u1.x;e=-m*this.m_u1.y;d.m_sweep.c.x+=d.m_invMass*l;d.m_sweep.c.y+=d.m_invMass*e;d.m_sweep.a+=d.m_invI*(a*e-c*l);d.SynchronizeTransform()}if(this.m_limitState2==I.e_atUpperLimit){l=h.m_xf.R;g=this.m_localAnchor2.x-h.m_sweep.localCenter.x;b=this.m_localAnchor2.y-h.m_sweep.localCenter.y;e=l.col1.x*g+l.col2.x*b;b=l.col1.y*g+l.col2.y*b;g=e;f=h.m_sweep.c.x+g;m=h.m_sweep.c.y+b;this.m_u2.Set(f-q,m-n);e=this.m_u2.Length();if(e>F.b2_linearSlop){this.m_u2.x*=1/e;this.m_u2.y*=1/e}else this.m_u2.SetZero();
l=this.m_maxLength2-e;r=y.Max(r,-l);l=y.Clamp(l+F.b2_linearSlop,-F.b2_maxLinearCorrection,0);m=-this.m_limitMass2*l;f=-m*this.m_u2.x;m=-m*this.m_u2.y;h.m_sweep.c.x+=h.m_invMass*f;h.m_sweep.c.y+=h.m_invMass*m;h.m_sweep.a+=h.m_invI*(g*m-b*f);h.SynchronizeTransform()}return r<F.b2_linearSlop};Box2D.postDefs.push(function(){Box2D.Dynamics.Joints.b2PulleyJoint.b2_minPulleyLength=2});Box2D.inherit(R,Box2D.Dynamics.Joints.b2JointDef);R.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;R.b2PulleyJointDef=
function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.groundAnchorA=new w;this.groundAnchorB=new w;this.localAnchorA=new w;this.localAnchorB=new w};R.prototype.b2PulleyJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_pulleyJoint;this.groundAnchorA.Set(-1,1);this.groundAnchorB.Set(1,1);this.localAnchorA.Set(-1,0);this.localAnchorB.Set(1,0);this.maxLengthB=this.lengthB=this.maxLengthA=this.lengthA=0;this.ratio=1;this.collideConnected=true};R.prototype.Initialize=
function(d,h,l,j,o,q,n){if(n===undefined)n=0;this.bodyA=d;this.bodyB=h;this.groundAnchorA.SetV(l);this.groundAnchorB.SetV(j);this.localAnchorA=this.bodyA.GetLocalPoint(o);this.localAnchorB=this.bodyB.GetLocalPoint(q);d=o.x-l.x;l=o.y-l.y;this.lengthA=Math.sqrt(d*d+l*l);l=q.x-j.x;j=q.y-j.y;this.lengthB=Math.sqrt(l*l+j*j);this.ratio=n;n=this.lengthA+this.ratio*this.lengthB;this.maxLengthA=n-this.ratio*E.b2_minPulleyLength;this.maxLengthB=(n-E.b2_minPulleyLength)/this.ratio};Box2D.inherit(N,Box2D.Dynamics.Joints.b2Joint);
N.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;N.b2RevoluteJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.K=new G;this.K1=new G;this.K2=new G;this.K3=new G;this.impulse3=new A;this.impulse2=new w;this.reduced=new w;this.m_localAnchor1=new w;this.m_localAnchor2=new w;this.m_impulse=new A;this.m_mass=new K};N.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchor1)};N.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchor2)};
N.prototype.GetReactionForce=function(d){if(d===undefined)d=0;return new w(d*this.m_impulse.x,d*this.m_impulse.y)};N.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_impulse.z};N.prototype.GetJointAngle=function(){return this.m_bodyB.m_sweep.a-this.m_bodyA.m_sweep.a-this.m_referenceAngle};N.prototype.GetJointSpeed=function(){return this.m_bodyB.m_angularVelocity-this.m_bodyA.m_angularVelocity};N.prototype.IsLimitEnabled=function(){return this.m_enableLimit};N.prototype.EnableLimit=
function(d){this.m_enableLimit=d};N.prototype.GetLowerLimit=function(){return this.m_lowerAngle};N.prototype.GetUpperLimit=function(){return this.m_upperAngle};N.prototype.SetLimits=function(d,h){if(d===undefined)d=0;if(h===undefined)h=0;this.m_lowerAngle=d;this.m_upperAngle=h};N.prototype.IsMotorEnabled=function(){this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);return this.m_enableMotor};N.prototype.EnableMotor=function(d){this.m_enableMotor=d};N.prototype.SetMotorSpeed=function(d){if(d===
undefined)d=0;this.m_bodyA.SetAwake(true);this.m_bodyB.SetAwake(true);this.m_motorSpeed=d};N.prototype.GetMotorSpeed=function(){return this.m_motorSpeed};N.prototype.SetMaxMotorTorque=function(d){if(d===undefined)d=0;this.m_maxMotorTorque=d};N.prototype.GetMotorTorque=function(){return this.m_maxMotorTorque};N.prototype.b2RevoluteJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchor1.SetV(d.localAnchorA);this.m_localAnchor2.SetV(d.localAnchorB);this.m_referenceAngle=d.referenceAngle;
this.m_impulse.SetZero();this.m_motorImpulse=0;this.m_lowerAngle=d.lowerAngle;this.m_upperAngle=d.upperAngle;this.m_maxMotorTorque=d.maxMotorTorque;this.m_motorSpeed=d.motorSpeed;this.m_enableLimit=d.enableLimit;this.m_enableMotor=d.enableMotor;this.m_limitState=I.e_inactiveLimit};N.prototype.InitVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j,o=0;j=h.m_xf.R;var q=this.m_localAnchor1.x-h.m_sweep.localCenter.x,n=this.m_localAnchor1.y-h.m_sweep.localCenter.y;o=j.col1.x*q+j.col2.x*
n;n=j.col1.y*q+j.col2.y*n;q=o;j=l.m_xf.R;var a=this.m_localAnchor2.x-l.m_sweep.localCenter.x,c=this.m_localAnchor2.y-l.m_sweep.localCenter.y;o=j.col1.x*a+j.col2.x*c;c=j.col1.y*a+j.col2.y*c;a=o;j=h.m_invMass;o=l.m_invMass;var g=h.m_invI,b=l.m_invI;this.m_mass.col1.x=j+o+n*n*g+c*c*b;this.m_mass.col2.x=-n*q*g-c*a*b;this.m_mass.col3.x=-n*g-c*b;this.m_mass.col1.y=this.m_mass.col2.x;this.m_mass.col2.y=j+o+q*q*g+a*a*b;this.m_mass.col3.y=q*g+a*b;this.m_mass.col1.z=this.m_mass.col3.x;this.m_mass.col2.z=this.m_mass.col3.y;
this.m_mass.col3.z=g+b;this.m_motorMass=1/(g+b);if(this.m_enableMotor==false)this.m_motorImpulse=0;if(this.m_enableLimit){var e=l.m_sweep.a-h.m_sweep.a-this.m_referenceAngle;if(y.Abs(this.m_upperAngle-this.m_lowerAngle)<2*F.b2_angularSlop)this.m_limitState=I.e_equalLimits;else if(e<=this.m_lowerAngle){if(this.m_limitState!=I.e_atLowerLimit)this.m_impulse.z=0;this.m_limitState=I.e_atLowerLimit}else if(e>=this.m_upperAngle){if(this.m_limitState!=I.e_atUpperLimit)this.m_impulse.z=0;this.m_limitState=
I.e_atUpperLimit}else{this.m_limitState=I.e_inactiveLimit;this.m_impulse.z=0}}else this.m_limitState=I.e_inactiveLimit;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_motorImpulse*=d.dtRatio;d=this.m_impulse.x;e=this.m_impulse.y;h.m_linearVelocity.x-=j*d;h.m_linearVelocity.y-=j*e;h.m_angularVelocity-=g*(q*e-n*d+this.m_motorImpulse+this.m_impulse.z);l.m_linearVelocity.x+=o*d;l.m_linearVelocity.y+=o*e;l.m_angularVelocity+=b*(a*e-c*d+this.m_motorImpulse+this.m_impulse.z)}else{this.m_impulse.SetZero();
this.m_motorImpulse=0}};N.prototype.SolveVelocityConstraints=function(d){var h=this.m_bodyA,l=this.m_bodyB,j=0,o=j=0,q=0,n=0,a=0,c=h.m_linearVelocity,g=h.m_angularVelocity,b=l.m_linearVelocity,e=l.m_angularVelocity,f=h.m_invMass,m=l.m_invMass,r=h.m_invI,s=l.m_invI;if(this.m_enableMotor&&this.m_limitState!=I.e_equalLimits){o=this.m_motorMass*-(e-g-this.m_motorSpeed);q=this.m_motorImpulse;n=d.dt*this.m_maxMotorTorque;this.m_motorImpulse=y.Clamp(this.m_motorImpulse+o,-n,n);o=this.m_motorImpulse-q;g-=
r*o;e+=s*o}if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){d=h.m_xf.R;o=this.m_localAnchor1.x-h.m_sweep.localCenter.x;q=this.m_localAnchor1.y-h.m_sweep.localCenter.y;j=d.col1.x*o+d.col2.x*q;q=d.col1.y*o+d.col2.y*q;o=j;d=l.m_xf.R;n=this.m_localAnchor2.x-l.m_sweep.localCenter.x;a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;j=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=j;d=b.x+-e*a-c.x- -g*q;var v=b.y+e*n-c.y-g*o;this.m_mass.Solve33(this.impulse3,-d,-v,-(e-g));if(this.m_limitState==
I.e_equalLimits)this.m_impulse.Add(this.impulse3);else if(this.m_limitState==I.e_atLowerLimit){j=this.m_impulse.z+this.impulse3.z;if(j<0){this.m_mass.Solve22(this.reduced,-d,-v);this.impulse3.x=this.reduced.x;this.impulse3.y=this.reduced.y;this.impulse3.z=-this.m_impulse.z;this.m_impulse.x+=this.reduced.x;this.m_impulse.y+=this.reduced.y;this.m_impulse.z=0}}else if(this.m_limitState==I.e_atUpperLimit){j=this.m_impulse.z+this.impulse3.z;if(j>0){this.m_mass.Solve22(this.reduced,-d,-v);this.impulse3.x=
this.reduced.x;this.impulse3.y=this.reduced.y;this.impulse3.z=-this.m_impulse.z;this.m_impulse.x+=this.reduced.x;this.m_impulse.y+=this.reduced.y;this.m_impulse.z=0}}c.x-=f*this.impulse3.x;c.y-=f*this.impulse3.y;g-=r*(o*this.impulse3.y-q*this.impulse3.x+this.impulse3.z);b.x+=m*this.impulse3.x;b.y+=m*this.impulse3.y;e+=s*(n*this.impulse3.y-a*this.impulse3.x+this.impulse3.z)}else{d=h.m_xf.R;o=this.m_localAnchor1.x-h.m_sweep.localCenter.x;q=this.m_localAnchor1.y-h.m_sweep.localCenter.y;j=d.col1.x*o+
d.col2.x*q;q=d.col1.y*o+d.col2.y*q;o=j;d=l.m_xf.R;n=this.m_localAnchor2.x-l.m_sweep.localCenter.x;a=this.m_localAnchor2.y-l.m_sweep.localCenter.y;j=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=j;this.m_mass.Solve22(this.impulse2,-(b.x+-e*a-c.x- -g*q),-(b.y+e*n-c.y-g*o));this.m_impulse.x+=this.impulse2.x;this.m_impulse.y+=this.impulse2.y;c.x-=f*this.impulse2.x;c.y-=f*this.impulse2.y;g-=r*(o*this.impulse2.y-q*this.impulse2.x);b.x+=m*this.impulse2.x;b.y+=m*this.impulse2.y;e+=s*(n*this.impulse2.y-
a*this.impulse2.x)}h.m_linearVelocity.SetV(c);h.m_angularVelocity=g;l.m_linearVelocity.SetV(b);l.m_angularVelocity=e};N.prototype.SolvePositionConstraints=function(){var d=0,h,l=this.m_bodyA,j=this.m_bodyB,o=0,q=h=0,n=0,a=0;if(this.m_enableLimit&&this.m_limitState!=I.e_inactiveLimit){d=j.m_sweep.a-l.m_sweep.a-this.m_referenceAngle;var c=0;if(this.m_limitState==I.e_equalLimits){d=y.Clamp(d-this.m_lowerAngle,-F.b2_maxAngularCorrection,F.b2_maxAngularCorrection);c=-this.m_motorMass*d;o=y.Abs(d)}else if(this.m_limitState==
I.e_atLowerLimit){d=d-this.m_lowerAngle;o=-d;d=y.Clamp(d+F.b2_angularSlop,-F.b2_maxAngularCorrection,0);c=-this.m_motorMass*d}else if(this.m_limitState==I.e_atUpperLimit){o=d=d-this.m_upperAngle;d=y.Clamp(d-F.b2_angularSlop,0,F.b2_maxAngularCorrection);c=-this.m_motorMass*d}l.m_sweep.a-=l.m_invI*c;j.m_sweep.a+=j.m_invI*c;l.SynchronizeTransform();j.SynchronizeTransform()}h=l.m_xf.R;c=this.m_localAnchor1.x-l.m_sweep.localCenter.x;d=this.m_localAnchor1.y-l.m_sweep.localCenter.y;q=h.col1.x*c+h.col2.x*
d;d=h.col1.y*c+h.col2.y*d;c=q;h=j.m_xf.R;var g=this.m_localAnchor2.x-j.m_sweep.localCenter.x,b=this.m_localAnchor2.y-j.m_sweep.localCenter.y;q=h.col1.x*g+h.col2.x*b;b=h.col1.y*g+h.col2.y*b;g=q;n=j.m_sweep.c.x+g-l.m_sweep.c.x-c;a=j.m_sweep.c.y+b-l.m_sweep.c.y-d;var e=n*n+a*a;h=Math.sqrt(e);q=l.m_invMass;var f=j.m_invMass,m=l.m_invI,r=j.m_invI,s=10*F.b2_linearSlop;if(e>s*s){e=1/(q+f);n=e*-n;a=e*-a;l.m_sweep.c.x-=0.5*q*n;l.m_sweep.c.y-=0.5*q*a;j.m_sweep.c.x+=0.5*f*n;j.m_sweep.c.y+=0.5*f*a;n=j.m_sweep.c.x+
g-l.m_sweep.c.x-c;a=j.m_sweep.c.y+b-l.m_sweep.c.y-d}this.K1.col1.x=q+f;this.K1.col2.x=0;this.K1.col1.y=0;this.K1.col2.y=q+f;this.K2.col1.x=m*d*d;this.K2.col2.x=-m*c*d;this.K2.col1.y=-m*c*d;this.K2.col2.y=m*c*c;this.K3.col1.x=r*b*b;this.K3.col2.x=-r*g*b;this.K3.col1.y=-r*g*b;this.K3.col2.y=r*g*g;this.K.SetM(this.K1);this.K.AddM(this.K2);this.K.AddM(this.K3);this.K.Solve(N.tImpulse,-n,-a);n=N.tImpulse.x;a=N.tImpulse.y;l.m_sweep.c.x-=l.m_invMass*n;l.m_sweep.c.y-=l.m_invMass*a;l.m_sweep.a-=l.m_invI*(c*
a-d*n);j.m_sweep.c.x+=j.m_invMass*n;j.m_sweep.c.y+=j.m_invMass*a;j.m_sweep.a+=j.m_invI*(g*a-b*n);l.SynchronizeTransform();j.SynchronizeTransform();return h<=F.b2_linearSlop&&o<=F.b2_angularSlop};Box2D.postDefs.push(function(){Box2D.Dynamics.Joints.b2RevoluteJoint.tImpulse=new w});Box2D.inherit(S,Box2D.Dynamics.Joints.b2JointDef);S.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;S.b2RevoluteJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=
new w;this.localAnchorB=new w};S.prototype.b2RevoluteJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_revoluteJoint;this.localAnchorA.Set(0,0);this.localAnchorB.Set(0,0);this.motorSpeed=this.maxMotorTorque=this.upperAngle=this.lowerAngle=this.referenceAngle=0;this.enableMotor=this.enableLimit=false};S.prototype.Initialize=function(d,h,l){this.bodyA=d;this.bodyB=h;this.localAnchorA=this.bodyA.GetLocalPoint(l);this.localAnchorB=this.bodyB.GetLocalPoint(l);this.referenceAngle=this.bodyB.GetAngle()-
this.bodyA.GetAngle()};Box2D.inherit(aa,Box2D.Dynamics.Joints.b2Joint);aa.prototype.__super=Box2D.Dynamics.Joints.b2Joint.prototype;aa.b2WeldJoint=function(){Box2D.Dynamics.Joints.b2Joint.b2Joint.apply(this,arguments);this.m_localAnchorA=new w;this.m_localAnchorB=new w;this.m_impulse=new A;this.m_mass=new K};aa.prototype.GetAnchorA=function(){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA)};aa.prototype.GetAnchorB=function(){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB)};aa.prototype.GetReactionForce=
function(d){if(d===undefined)d=0;return new w(d*this.m_impulse.x,d*this.m_impulse.y)};aa.prototype.GetReactionTorque=function(d){if(d===undefined)d=0;return d*this.m_impulse.z};aa.prototype.b2WeldJoint=function(d){this.__super.b2Joint.call(this,d);this.m_localAnchorA.SetV(d.localAnchorA);this.m_localAnchorB.SetV(d.localAnchorB);this.m_referenceAngle=d.referenceAngle;this.m_impulse.SetZero();this.m_mass=new K};aa.prototype.InitVelocityConstraints=function(d){var h,l=0,j=this.m_bodyA,o=this.m_bodyB;
h=j.m_xf.R;var q=this.m_localAnchorA.x-j.m_sweep.localCenter.x,n=this.m_localAnchorA.y-j.m_sweep.localCenter.y;l=h.col1.x*q+h.col2.x*n;n=h.col1.y*q+h.col2.y*n;q=l;h=o.m_xf.R;var a=this.m_localAnchorB.x-o.m_sweep.localCenter.x,c=this.m_localAnchorB.y-o.m_sweep.localCenter.y;l=h.col1.x*a+h.col2.x*c;c=h.col1.y*a+h.col2.y*c;a=l;h=j.m_invMass;l=o.m_invMass;var g=j.m_invI,b=o.m_invI;this.m_mass.col1.x=h+l+n*n*g+c*c*b;this.m_mass.col2.x=-n*q*g-c*a*b;this.m_mass.col3.x=-n*g-c*b;this.m_mass.col1.y=this.m_mass.col2.x;
this.m_mass.col2.y=h+l+q*q*g+a*a*b;this.m_mass.col3.y=q*g+a*b;this.m_mass.col1.z=this.m_mass.col3.x;this.m_mass.col2.z=this.m_mass.col3.y;this.m_mass.col3.z=g+b;if(d.warmStarting){this.m_impulse.x*=d.dtRatio;this.m_impulse.y*=d.dtRatio;this.m_impulse.z*=d.dtRatio;j.m_linearVelocity.x-=h*this.m_impulse.x;j.m_linearVelocity.y-=h*this.m_impulse.y;j.m_angularVelocity-=g*(q*this.m_impulse.y-n*this.m_impulse.x+this.m_impulse.z);o.m_linearVelocity.x+=l*this.m_impulse.x;o.m_linearVelocity.y+=l*this.m_impulse.y;
o.m_angularVelocity+=b*(a*this.m_impulse.y-c*this.m_impulse.x+this.m_impulse.z)}else this.m_impulse.SetZero()};aa.prototype.SolveVelocityConstraints=function(){var d,h=0,l=this.m_bodyA,j=this.m_bodyB,o=l.m_linearVelocity,q=l.m_angularVelocity,n=j.m_linearVelocity,a=j.m_angularVelocity,c=l.m_invMass,g=j.m_invMass,b=l.m_invI,e=j.m_invI;d=l.m_xf.R;var f=this.m_localAnchorA.x-l.m_sweep.localCenter.x,m=this.m_localAnchorA.y-l.m_sweep.localCenter.y;h=d.col1.x*f+d.col2.x*m;m=d.col1.y*f+d.col2.y*m;f=h;d=
j.m_xf.R;var r=this.m_localAnchorB.x-j.m_sweep.localCenter.x,s=this.m_localAnchorB.y-j.m_sweep.localCenter.y;h=d.col1.x*r+d.col2.x*s;s=d.col1.y*r+d.col2.y*s;r=h;d=n.x-a*s-o.x+q*m;h=n.y+a*r-o.y-q*f;var v=a-q,t=new A;this.m_mass.Solve33(t,-d,-h,-v);this.m_impulse.Add(t);o.x-=c*t.x;o.y-=c*t.y;q-=b*(f*t.y-m*t.x+t.z);n.x+=g*t.x;n.y+=g*t.y;a+=e*(r*t.y-s*t.x+t.z);l.m_angularVelocity=q;j.m_angularVelocity=a};aa.prototype.SolvePositionConstraints=function(){var d,h=0,l=this.m_bodyA,j=this.m_bodyB;d=l.m_xf.R;
var o=this.m_localAnchorA.x-l.m_sweep.localCenter.x,q=this.m_localAnchorA.y-l.m_sweep.localCenter.y;h=d.col1.x*o+d.col2.x*q;q=d.col1.y*o+d.col2.y*q;o=h;d=j.m_xf.R;var n=this.m_localAnchorB.x-j.m_sweep.localCenter.x,a=this.m_localAnchorB.y-j.m_sweep.localCenter.y;h=d.col1.x*n+d.col2.x*a;a=d.col1.y*n+d.col2.y*a;n=h;d=l.m_invMass;h=j.m_invMass;var c=l.m_invI,g=j.m_invI,b=j.m_sweep.c.x+n-l.m_sweep.c.x-o,e=j.m_sweep.c.y+a-l.m_sweep.c.y-q,f=j.m_sweep.a-l.m_sweep.a-this.m_referenceAngle,m=10*F.b2_linearSlop,
r=Math.sqrt(b*b+e*e),s=y.Abs(f);if(r>m){c*=1;g*=1}this.m_mass.col1.x=d+h+q*q*c+a*a*g;this.m_mass.col2.x=-q*o*c-a*n*g;this.m_mass.col3.x=-q*c-a*g;this.m_mass.col1.y=this.m_mass.col2.x;this.m_mass.col2.y=d+h+o*o*c+n*n*g;this.m_mass.col3.y=o*c+n*g;this.m_mass.col1.z=this.m_mass.col3.x;this.m_mass.col2.z=this.m_mass.col3.y;this.m_mass.col3.z=c+g;m=new A;this.m_mass.Solve33(m,-b,-e,-f);l.m_sweep.c.x-=d*m.x;l.m_sweep.c.y-=d*m.y;l.m_sweep.a-=c*(o*m.y-q*m.x+m.z);j.m_sweep.c.x+=h*m.x;j.m_sweep.c.y+=h*m.y;
j.m_sweep.a+=g*(n*m.y-a*m.x+m.z);l.SynchronizeTransform();j.SynchronizeTransform();return r<=F.b2_linearSlop&&s<=F.b2_angularSlop};Box2D.inherit(Z,Box2D.Dynamics.Joints.b2JointDef);Z.prototype.__super=Box2D.Dynamics.Joints.b2JointDef.prototype;Z.b2WeldJointDef=function(){Box2D.Dynamics.Joints.b2JointDef.b2JointDef.apply(this,arguments);this.localAnchorA=new w;this.localAnchorB=new w};Z.prototype.b2WeldJointDef=function(){this.__super.b2JointDef.call(this);this.type=I.e_weldJoint;this.referenceAngle=
0};Z.prototype.Initialize=function(d,h,l){this.bodyA=d;this.bodyB=h;this.localAnchorA.SetV(this.bodyA.GetLocalPoint(l));this.localAnchorB.SetV(this.bodyB.GetLocalPoint(l));this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()}})();
(function(){var F=Box2D.Dynamics.b2DebugDraw;F.b2DebugDraw=function(){this.m_xformScale=this.m_fillAlpha=this.m_alpha=this.m_lineThickness=this.m_drawScale=1;var G=this;this.m_sprite={graphics:{clear:function(){G.m_ctx.clearRect(0,0,G.m_ctx.canvas.width,G.m_ctx.canvas.height)}}}};F.prototype._color=function(G,K){return"rgba("+((G&16711680)>>16)+","+((G&65280)>>8)+","+(G&255)+","+K+")"};F.prototype.b2DebugDraw=function(){this.m_drawFlags=0};F.prototype.SetFlags=function(G){if(G===undefined)G=0;this.m_drawFlags=
G};F.prototype.GetFlags=function(){return this.m_drawFlags};F.prototype.AppendFlags=function(G){if(G===undefined)G=0;this.m_drawFlags|=G};F.prototype.ClearFlags=function(G){if(G===undefined)G=0;this.m_drawFlags&=~G};F.prototype.SetSprite=function(G){this.m_ctx=G};F.prototype.GetSprite=function(){return this.m_ctx};F.prototype.SetDrawScale=function(G){if(G===undefined)G=0;this.m_drawScale=G};F.prototype.GetDrawScale=function(){return this.m_drawScale};F.prototype.SetLineThickness=function(G){if(G===
undefined)G=0;this.m_lineThickness=G;this.m_ctx.strokeWidth=G};F.prototype.GetLineThickness=function(){return this.m_lineThickness};F.prototype.SetAlpha=function(G){if(G===undefined)G=0;this.m_alpha=G};F.prototype.GetAlpha=function(){return this.m_alpha};F.prototype.SetFillAlpha=function(G){if(G===undefined)G=0;this.m_fillAlpha=G};F.prototype.GetFillAlpha=function(){return this.m_fillAlpha};F.prototype.SetXFormScale=function(G){if(G===undefined)G=0;this.m_xformScale=G};F.prototype.GetXFormScale=function(){return this.m_xformScale};
F.prototype.DrawPolygon=function(G,K,y){if(K){var w=this.m_ctx,A=this.m_drawScale;w.beginPath();w.strokeStyle=this._color(y.color,this.m_alpha);w.moveTo(G[0].x*A,G[0].y*A);for(y=1;y<K;y++)w.lineTo(G[y].x*A,G[y].y*A);w.lineTo(G[0].x*A,G[0].y*A);w.closePath();w.stroke()}};F.prototype.DrawSolidPolygon=function(G,K,y){if(K){var w=this.m_ctx,A=this.m_drawScale;w.beginPath();w.strokeStyle=this._color(y.color,this.m_alpha);w.fillStyle=this._color(y.color,this.m_fillAlpha);w.moveTo(G[0].x*A,G[0].y*A);for(y=
1;y<K;y++)w.lineTo(G[y].x*A,G[y].y*A);w.lineTo(G[0].x*A,G[0].y*A);w.closePath();w.fill();w.stroke()}};F.prototype.DrawCircle=function(G,K,y){if(K){var w=this.m_ctx,A=this.m_drawScale;w.beginPath();w.strokeStyle=this._color(y.color,this.m_alpha);w.arc(G.x*A,G.y*A,K*A,0,Math.PI*2,true);w.closePath();w.stroke()}};F.prototype.DrawSolidCircle=function(G,K,y,w){if(K){var A=this.m_ctx,U=this.m_drawScale,p=G.x*U,B=G.y*U;A.moveTo(0,0);A.beginPath();A.strokeStyle=this._color(w.color,this.m_alpha);A.fillStyle=
this._color(w.color,this.m_fillAlpha);A.arc(p,B,K*U,0,Math.PI*2,true);A.moveTo(p,B);A.lineTo((G.x+y.x*K)*U,(G.y+y.y*K)*U);A.closePath();A.fill();A.stroke()}};F.prototype.DrawSegment=function(G,K,y){var w=this.m_ctx,A=this.m_drawScale;w.strokeStyle=this._color(y.color,this.m_alpha);w.beginPath();w.moveTo(G.x*A,G.y*A);w.lineTo(K.x*A,K.y*A);w.closePath();w.stroke()};F.prototype.DrawTransform=function(G){var K=this.m_ctx,y=this.m_drawScale;K.beginPath();K.strokeStyle=this._color(16711680,this.m_alpha);
K.moveTo(G.position.x*y,G.position.y*y);K.lineTo((G.position.x+this.m_xformScale*G.R.col1.x)*y,(G.position.y+this.m_xformScale*G.R.col1.y)*y);K.strokeStyle=this._color(65280,this.m_alpha);K.moveTo(G.position.x*y,G.position.y*y);K.lineTo((G.position.x+this.m_xformScale*G.R.col2.x)*y,(G.position.y+this.m_xformScale*G.R.col2.y)*y);K.closePath();K.stroke()}})();var i;for(i=0;i<Box2D.postDefs.length;++i)Box2D.postDefs[i]();delete Box2D.postDefs;

105
public/_define.styl Normal file
View File

@ -0,0 +1,105 @@
helv()
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif
shadow($color, $x, $y, $blur)
-webkit-box-shadow: color $x $y $blur
-moz-box-shadow: $color $x $y $blur
box-shadow: $color $x $y $blur
innerShadow($color, $x, $y, $blur)
box-shadow: inset $color $x $y $blurpx
-moz-box-shadow: inset $color $x $y $blurpx
-webkit-box-shadow: inset $color $x $y $blur
gradient($top, $bottom)
background-image: $top
background-image: -moz-linear-gradient(top, $top, $bottom)
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, $top),color-stop(1, $bottom))
radial($inner, $outer)
background: $inner
background-image: -webkit-radial-gradient(center center, circle cover, $inner, $outer)
background-image: -moz-radial-gradient(center center, circle cover, $inner, $outer)
background-image: -ms-radial-gradient(center center, circle cover, $inner, $outer)
background-image: -o-radial-gradient(center center, circle cover, $inner, $outer)
background-image: radial-gradient(center center, circle cover, $inner, $outer)
roundall($round)
-moz-border-radius: $round
-webkit-border-radius: $round
-khtml-border-radius: $round
-o-border-radius: $round
-border-radius: $round
border-radius: $round
round($roundtl, $roundtr, $roundbr, $roundbl)
-webkit-border-top-left-radius: $roundtl
-webkit-border-top-right-radius: $roundtr
-webkit-border-bottom-left-radius: $roundbl
-webkit-border-bottom-right-radius: $roundbr
-moz-border-radius-topleft: $roundtl
-moz-border-radius-topright: $roundtr
-moz-border-radius-bottomleft: $roundbl
-moz-border-radius-bottomright: $roundbr
-border-top-left-radius: $roundtl
-border-top-right-radius: $roundtr
-border-bottom-left-radius: $roundbl
-border-bottom-right-radius: $roundbr
border-top-left-radius: $roundtl
border-top-right-radius: $roundtr
border-bottom-left-radius: $roundbl
border-bottom-right-radius: $roundbr
textShadow($color, $x, $y, $blur)
text-shadow: $color $x $y $blur
noselect()
-webkit-touch-callout: none
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
user-select: none
turn($deg)
-moz-transform: rotate($deg)
-webkit-transform: rotate($deg)
-o-transform: rotate($deg)
transform: rotate($deg)
transform($param)
-webkit-transform: $param
-moz-transform: $param
-ms-transform: $param
transform: $param
transition($attr, $dur, $timing, $delay)
-webkit-transition: $attr $dur $timing $delay
-moz-transition: $attr $dur $timing $delay
-o-transition: $attr $dur $timing $delay
transition: $attr $dur $timing $delay
flip-horizontal()
-moz-transform: scaleX(-1)
-webkit-transform: scaleX(-1)
-o-transform: scaleX(-1)
transform: scaleX(-1)
-ms-filter: fliph
filter: fliph
flip-vertical()
-moz-transform: scaleY(-1)
-webkit-transform: scaleY(-1)
-o-transform: scaleY(-1)
transform: scaleY(-1)
-ms-filter: flipv
filter: flipv
colorDot($color)
display: block
height: 10px
width: 10px
gradient: $color + #777 $color + #000
border-radius: 25px
border-bottom: 1px solid rgba(0,0,0,1)
border-top: 1px solid rgba(255,255,255,.9)

247
public/_reset.css Normal file
View File

@ -0,0 +1,247 @@
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section {
display: block;
}
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
audio:not([controls]) {
display: none;
}
[hidden] {
display: none;
}
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
button,
input,
select,
textarea {
font-family: sans-serif;
color: #222;
}
body {
margin: 0;
font-size: 1em;
line-height: 1.4;
}
a {
color: #00e;
}
a:visited {
color: #551a8b;
}
a:hover {
color: #06e;
}
a:focus {
outline: thin dotted;
}
a:hover,
a:active {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
blockquote {
margin: 1em 40px;
}
dfn {
font-style: italic;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
ins {
background: #ff9;
color: #000;
text-decoration: none;
}
mark {
background: #ff0;
color: #000;
font-style: italic;
font-weight: bold;
}
pre,
code,
kbd,
samp {
font-family: monospace, serif;
_font-family: 'courier new', monospace;
font-size: 1em;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
q {
quotes: none;
}
q:before,
q:after {
content: none;
}
small {
font-size: 85%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
ul,
ol {
margin: 1em 0;
padding: 0 0 0 40px;
}
dd {
margin: 0 0 0 40px;
}
nav ul,
nav ol {
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
img {
border: 0;
-ms-interpolation-mode: bicubic;
vertical-align: middle;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 0;
}
form {
margin: 0;
}
fieldset {
border: 0;
margin: 0;
padding: 0;
}
label {
cursor: pointer;
}
legend {
border: 0;
*margin-left: -7px;
padding: 0;
white-space: normal;
}
button,
input,
select,
textarea {
font-size: 100%;
margin: 0;
vertical-align: baseline;
*vertical-align: middle;
}
button,
input {
line-height: normal;
}
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer;
-webkit-appearance: button;
*overflow: visible;
}
button[disabled],
input[disabled] {
cursor: default;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
*width: 13px;
*height: 13px;
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
vertical-align: top;
resize: vertical;
}
input:valid,
textarea:valid,
input:invalid,
textarea:invalid {
background-color: #f0dddd;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
td {
vertical-align: top;
}
.clearfix:before,
.clearfix:after {
content: "\0020";
display: block;
height: 0;
visibility: hidden;
}
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1;
}

210
public/_reset.styl Normal file
View File

@ -0,0 +1,210 @@
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section
display: block
audio, canvas, video
display: inline-block
*display: inline
*zoom: 1
audio:not([controls])
display: none
[hidden]
display: none
html
font-size: 100%
-webkit-text-size-adjust: 100%
-ms-text-size-adjust: 100%
html, button, input, select, textarea
font-family: sans-serif
color: #222
body
margin: 0
font-size: 1em
line-height: 1.4
a
color: #00e
a:visited
color: #551a8b
a:hover
color: #06e
a:focus
outline: thin dotted
a:hover, a:active
outline: 0
abbr[title]
border-bottom: 1px dotted
b, strong
font-weight: bold
blockquote
margin: 1em 40px
dfn
font-style: italic
hr
display: block
height: 1px
border: 0
border-top: 1px solid #ccc
margin: 1em 0
padding: 0
ins
background: #ff9
color: #000
text-decoration: none
mark
background: #ff0
color: #000
font-style: italic
font-weight: bold
pre, code, kbd, samp
font-family: monospace, serif
_font-family: 'courier new', monospace
font-size: 1em
pre
white-space: pre-wrap
word-wrap: break-word
q
quotes: none
q:before, q:after
content: none
small
font-size: 85%
sub, sup
font-size: 75%
line-height: 0
position: relative
vertical-align: baseline
sup
top: -0.5em
sub
bottom: -0.25em
ul, ol
margin: 1em 0
padding: 0 0 0 40px
dd
margin: 0 0 0 40px
nav ul, nav ol
list-style: none
list-style-image: none
margin: 0
padding: 0
img
border: 0
-ms-interpolation-mode: bicubic
vertical-align: middle
svg:not(:root)
overflow: hidden
figure
margin: 0
form
margin: 0
fieldset
border: 0
margin: 0
padding: 0
label
cursor: pointer
legend
border: 0
*margin-left: -7px
padding: 0
white-space: normal
button, input, select, textarea
font-size: 100%
margin: 0
vertical-align: baseline
*vertical-align: middle
button, input
line-height: normal
button, input[type="button"], input[type="reset"], input[type="submit"]
cursor: pointer
-webkit-appearance: button
*overflow: visible
button[disabled], input[disabled]
cursor: default
input[type="checkbox"], input[type="radio"]
box-sizing: border-box
padding: 0
*width: 13px
*height: 13px
input[type="search"]
-webkit-appearance: textfield
-moz-box-sizing: content-box
-webkit-box-sizing: content-box
box-sizing: content-box
input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button
-webkit-appearance: none
button::-moz-focus-inner, input::-moz-focus-inner
border: 0
padding: 0
textarea
overflow: auto
vertical-align: top
resize: vertical
input:valid, textarea:valid
input:invalid, textarea:invalid
background-color: #f0dddd
table
border-collapse: collapse
border-spacing: 0
td
vertical-align: top
.clearfix:before, .clearfix:after
content: "\0020"
display: block
height: 0
visibility: hidden
.clearfix:after
clear: both
.clearfix
zoom: 1

View File

@ -0,0 +1,16 @@
// picks a random thing from this list (html is fine) and shows it.
function showAd() {
var messages = [
'Have more fun, get more done with your team. And Bang is currently in free private beta.',
'And Bang is simple and powerful tasks and chat for teams. Join the free private beta now.',
'Create a culture of shipping, one rocket at a time. And Bang is free while in private beta.',
'An API for what\'s important right now. And Bang is free while in private beta.'
],
message = messages[Math.floor(Math.random()*messages.length)];
$('#ad').html(message);
setTimeout(showAd, 30000);
}
showAd();

13
public/box.js Normal file
View File

@ -0,0 +1,13 @@
module.exports = {
Vec2: Box2D.Common.Math.b2Vec2,
Math: Box2D.Common.Math.b2Math,
BodyDef: Box2D.Dynamics.b2BodyDef,
Body: Box2D.Dynamics.b2Body,
FixtureDef: Box2D.Dynamics.b2FixtureDef,
Fixture: Box2D.Dynamics.b2Fixture,
World: Box2D.Dynamics.b2World,
MassData: Box2D.Collision.Shapes.b2MassData,
PolygonShape: Box2D.Collision.Shapes.b2PolygonShape,
CircleShape: Box2D.Collision.Shapes.b2CircleShape,
DebugDraw: Box2D.Dynamics.b2DebugDraw
};

BIN
public/cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
public/conversatio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
public/conversatio@2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
public/fireball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
public/flame.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

229
public/fluidgrid.js Normal file
View File

@ -0,0 +1,229 @@
(function () {
// reference to our currently focused element
var focusedEl;
function getFluidGridFunction(selector) {
return function (focus) {
reOrganize(selector, focus);
};
}
function biggestBox(container, aspectRatio) {
var aspectRatio = aspectRatio || (3 / 4),
height = (container.width * aspectRatio),
res = {};
if (height > container.height) {
return {
height: container.height,
width: container.height / aspectRatio
};
} else {
return {
width: container.width,
height: container.width * aspectRatio
};
}
}
function reOrganize(selector, focus) {
var floor = Math.floor,
elements = $(selector),
howMany = elements.length,
howManyNonFocused = function () {
var hasFocused = !!elements.find('.focused').length;
if (hasFocused && howMany > 1) {
return howMany - 1;
} else if (hasFocused && howMany === 1) {
return 1;
} else {
return howMany;
}
}(),
totalAvailableWidth = window.innerWidth,
totalAvailableHeight = window.innerHeight - 140,
availableWidth = totalAvailableWidth,
availableHeight = totalAvailableHeight,
container = {
width: availableWidth,
height: availableHeight
},
columnPadding = 15,
minimumWidth = 290,
aspectRatio = 3 / 4,
numberOfColumns,
numberOfRows,
numberOfPaddingColumns,
numberOfPaddingRows,
itemDimensions,
totalWidth,
videoWidth,
leftMargin,
videoHeight,
usedHeight,
topMargin,
// do we have one selected?
// this is because having a single
// focused element is not treated
// differently, but we don't want to
// lose that reference.
haveFocusedEl;
// if we passed in a string here (could be "none")
// then we want to either set or clear our current
// focused element.
if (focus) focusedEl = $(focus)[0];
// make sure our cached focused element is still
// attached.
if (focusedEl && !$(focusedEl).parent().length) focusedEl = undefined;
// figure out if we should consider us as having any
// special focused elements
haveFocusedEl = focusedEl && howManyNonFocused > 1;
elements.height(availableHeight);
// how we want the to stack at different numbers
if (haveFocusedEl) {
numberOfColumns = howManyNonFocused - 1;
numberOfRows = 1;
availableHeight = totalAvailableHeight * .2;
} else if (howManyNonFocused === 0) {
return;
} else if (howManyNonFocused === 1) {
numberOfColumns = 1;
numberOfRows = 1;
} else if (howManyNonFocused === 2) {
if (availableWidth > availableHeight) {
numberOfColumns = 2;
numberOfRows = 1;
} else {
numberOfColumns = 1;
numberOfRows = 2;
}
} else if (howManyNonFocused === 3) {
if (availableWidth > availableHeight) {
numberOfColumns = 3;
numberOfRows = 1;
} else {
numberOfColumns = 1;
numberOfRows = 3;
}
} else if (howManyNonFocused === 4) {
numberOfColumns = 2;
numberOfRows = 2;
} else if (howManyNonFocused === 5) {
numberOfColumns = 3;
numberOfRows = 2;
} else if (howManyNonFocused === 6) {
if (availableWidth > availableHeight) {
numberOfColumns = 3;
numberOfRows = 2;
} else {
numberOfColumns = 2;
numberOfRows = 3;
}
}
itemDimensions = biggestBox({
width: availableWidth / numberOfColumns,
height: availableHeight / numberOfRows
});
numberOfPaddingColumns = numberOfColumns - 1;
numberOfPaddingRows = numberOfRows - 1;
totalWidth = itemDimensions.width * numberOfColumns;
videoWidth = function () {
var totalWidthLessPadding = totalWidth - (columnPadding * numberOfPaddingColumns);
return totalWidthLessPadding / numberOfColumns;
}();
leftMargin = (availableWidth - totalWidth) / 2;
videoHeight = itemDimensions.height - ((numberOfRows > 1) ? (columnPadding / numberOfRows) : 0);
usedHeight = (numberOfRows * videoHeight);
topMargin = (availableHeight - usedHeight) / 2;
if (haveFocusedEl) {
elements = elements.not('.focused');
}
elements.each(function (index) {
var order = index,
row = floor(order / numberOfColumns),
column = order % numberOfColumns,
intensity = 12,
rotation = function () {
if (numberOfColumns === 3) {
if (column === 0) {
return 1;
} else if (column === 1) {
return 0;
} else if (column === 2) {
return -1
}
} else if (numberOfColumns === 2) {
intensity = 5;
return column == 1 ? -1 : 1
} else if (numberOfColumns === 1) {
return 0;
}
}(),
transformation = 'rotateY(' + (rotation * intensity) + 'deg)';
if (rotation === 0) {
transformation += ' scale(.98)';
}
var calculatedTop;
if (haveFocusedEl) {
calculatedTop = (totalAvailableHeight * .8) + topMargin + 'px';
} else {
calculatedTop = (row * itemDimensions.height) + topMargin + 'px';
}
$(this).css({
//transform: transformation,
top: calculatedTop,
left: (column * itemDimensions.width) + leftMargin + 'px',
width: videoWidth + 'px',
height: videoHeight + 'px',
position: 'absolute'
});
});
if (haveFocusedEl) {
var focusSize = biggestBox({
height: (totalAvailableHeight * .8),
width: totalAvailableWidth
}, focusedEl.videoHeight / focusedEl.videoWidth);
$(focusedEl).css({
top: 0,
height: focusSize.height - topMargin,
width: focusSize.width,
left: (totalAvailableWidth / 2) - (focusSize.width / 2)
});
}
}
if (typeof exports !== 'undefined') {
module.exports = getFluidGridFunction;
} else {
window.getFluidGridFunction = getFluidGridFunction;
}
})();

53
public/fonts.css Normal file

File diff suppressed because one or more lines are too long

243
public/game.js Normal file
View File

@ -0,0 +1,243 @@
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
console.log(window.requestAnimFrame);
var Rocket = require('./rocket');
var particle = require('./particle');
var box = require('./box');
var b2Vec2 = Box2D.Common.Math.b2Vec2;
var b2Math = Box2D.Common.Math.b2Math;
var b2BodyDef = Box2D.Dynamics.b2BodyDef;
var b2Body = Box2D.Dynamics.b2Body;
var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
var b2Fixture = Box2D.Dynamics.b2Fixture;
var b2World = Box2D.Dynamics.b2World;
var b2MassData = Box2D.Collision.Shapes.b2MassData;
var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
var Game = function() {
this.canvas = document.getElementById('viewport');
console.log(this.canvas.parentNode.clientWidth, this.canvas.parentNode.clientHeight);
this.canvas.width = this.canvas.parentNode.clientWidth;
this.canvas.height = this.canvas.parentNode.clientHeight;
this.ctx = this.canvas.getContext('2d');
this.world = new b2World(
//new b2Vec2(0, 50), //gravity
new b2Vec2(0,50),
false //allow sleep
);
this.scale = 10;
this.smoke = new Image;
this.smoke.src = 'cloud.png';
this.rocket = new Rocket(this, this.canvas.width / 2 / this.scale, (this.canvas.height - 20) / this.scale, .01);
this.last_update = Date.now();
this.shraps = [];
this.keys = {};
document.addEventListener('keydown', function(e) {
//console.log(e.keyCode);
this.keys[e.keyCode] = true;
}.bind(this));
document.addEventListener('keyup', function(e) {
this.keys[e.keyCode] = false;
}.bind(this));
this.update();
};
(function() {
var avg = 0;
var avgt = 0;
var average = 0;
this.update = function() {
var now = Date.now();
var dt = (now - this.last_update);
avg += dt;
avgt++;
if (avgt === 20) {
average = (1000/(avg/20)).toFixed(2);
avgt = 0;
avg = 0;
}
/*
var gra = Math.atan2(this.rocket.y - 400, -(this.rocket.x - 400)) + Math.PI/2;
if(this.rocket.active) {
this.rocket.body.ApplyImpulse(new b2Vec2(Math.sin(gra) * (dt/5), Math.cos(gra) * (dt/5)), this.rocket.body.GetWorldCenter());
}
*/
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.globalAlpha = 1.0;
//ctx.fillStyle = 'white'
//ctx.fillRect(0, 0, canvas.width, canvas.height);
this.ctx.fillStyle = 'gray'
this.ctx.fillRect(0,this.canvas.height - 20, this.canvas.width, 20);
//this.world.DrawDebugData();
this.ctx.globalAlpha = 1.0;
this.ctx.fillStyle = 'black';
this.ctx.fillText("FPS: " + (average), 10, this.canvas.height - 30);
this.rocket.animate(dt);
for(var sidx in this.shraps) {
this.shraps[sidx].animate(dt, now);
}
dt = dt/1000;
for(var pidx in particle.particles) {
particle.particles[pidx].animate(dt, now);
}
this.world.Step(
dt
//frame-rate
, 10 //velocity iterations
, 10 //position iterations
);
//this.world.ClearForces();
requestAnimFrame(this.update.bind(this));
this.last_update = now;
};
this.makeBody = function (x, y, points, p) {
var pidx = 0;
while(pidx < points.length) {
points[pidx] = new box.Vec2(points[pidx][0], points[pidx][1]);
pidx++;
}
var fixDef = new box.FixtureDef;
fixDef.density = 1.0;
fixDef.friction = .8;
fixDef.restitution = 0.2;
fixDef.shape = new box.PolygonShape;
fixDef.shape.SetAsArray(points, points.length);
fixDef.par = p;
var bodyDef = new box.BodyDef;
if(p) {
bodyDef.userData = p;
}
bodyDef.type = box.Body.b2_dynamicBody;
bodyDef.position.x = x;
bodyDef.position.y = y;
var body = this.world.CreateBody(bodyDef);
var fixt = body.CreateFixture(fixDef);
return body;
}
}).call(Game.prototype);
var game = new Game;
/*
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(game.ctx);
debugDraw.SetDrawScale(game.scale);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
game.world.SetDebugDraw(debugDraw);
*/
var fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = .8;
fixDef.restitution = 0.2;
var bodyDef = new b2BodyDef;
//create ground
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = game.canvas.width / 2 / game.scale;
bodyDef.position.y = game.canvas.height / game.scale;
bodyDef.userData = "ground";
//fixDef.shape = new b2CircleShape(20);
fixDef.shape = new b2PolygonShape
fixDef.shape.SetAsBox(game.canvas.width / 2 / game.scale, 2);
game.world.CreateBody(bodyDef).CreateFixture(fixDef);
flame = new Image();
flame.src = 'flame.gif';
fireball = new Image();
fireball.src = 'fireball.png';
shrap = new Image();
shrap.src = 'shrapenel.png';
var shraps = [];
var last_update = Date.now();
var last_particle = Date.now();
var mouse_x = 0;
var mouse_y = 0;
function normalizeAngle(angle) {
if(angle == 0) { return 0; }
if(angle < 0 || angle > Math.PI * 2) return Math.abs((Math.PI * 2) - Math.abs(angle));
}
var contactListener = new Box2D.Dynamics.b2ContactListener;
contactListener.PreSolve = function(contact, manifold) {
var a = contact.GetFixtureA();
var ab = a.GetBody();
var b = contact.GetFixtureB();
var bb = b.GetBody();
var au = ab.GetUserData();
var bu = bb.GetUserData();
if((au instanceof Rocket && bu == 'ground') || au == 'ground' && bu instanceof Rocket) {
var av = ab.GetLinearVelocity();
var bv = bb.GetLinearVelocity();
var f = b2Math.Distance(bv, av);
var r = null;
if(au instanceof Rocket) r = au;
if(bu instanceof Rocket) r = bu;
if(r && f > 25) {
setTimeout(
r.explode.bind(r), 0);
/*
au.explode();
bu.explode();
*/
} else if (r.body) {
var a = r.body.GetAngle();
a = Box2D.Common.Math.b2Mat22.FromAngle(a);
a = Math.abs(Math.atan2(a.col1.y, a.col1.x));
if(a > 1.5) {
setTimeout(
r.explode.bind(r), 0);
}
}
}
// rocket.explode();
//do some stuff
};
game.world.SetContactListener(contactListener);

View File

@ -0,0 +1,44 @@
(function($) {
$.showMessage = function(message, options){
// defaults
var settings = jQuery.extend({
id: 'sliding_message_box',
position: 'bottom',
size: '90',
backgroundColor: 'rgb(143, 177, 240)',
delay: 1500,
speed: 500,
fontSize: '30px'
}, options),
el = $('#' + settings.id);
// generate message div if it doesn't exist
if (el.length == 0) {
el = $('<div></div>').attr('id', settings.id);
el.css({
'-moz-transition': 'bottom ' + settings.speed + 'ms',
'-webkit-transition': 'bottom ' + settings.speed + 'ms',
'bottom': '-' + settings.size + 'px',
'z-index': '999',
'background-color': settings.backgroundColor,
'text-align': 'center',
'position': 'fixed',
'left': '0',
'width': '100%',
'line-height': settings.size + 'px',
'font-size': settings.fontSize,
});
$('body').append(el);
}
setTimeout(function () {
el.html(message);
el.css('bottom', 0);
setTimeout(function () {
el.css('bottom', '-' + settings.size + 'px');
}, settings.delay);
}, 10);
}
})(jQuery);

9
public/metrics.js Normal file
View File

@ -0,0 +1,9 @@
// some metrics
if (location.hostname === 'conversat.io') {
(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!== typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
mixpanel.init("4f9fd79a6827838ce81d84cd70d535cd");
// a handler to track # of videos connected
webrtc.on('videoAdded', function () {
mixpanel.track('videoConnected');
});
}

BIN
public/offline.mp3 Normal file

Binary file not shown.

BIN
public/offline.wav Executable file

Binary file not shown.

BIN
public/online.mp3 Normal file

Binary file not shown.

BIN
public/online.wav Executable file

Binary file not shown.

964
public/out.js Normal file
View File

@ -0,0 +1,964 @@
(function(){var require = function (file, cwd) {
var resolved = require.resolve(file, cwd || '/');
var mod = require.modules[resolved];
if (!mod) throw new Error(
'Failed to resolve module ' + file + ', tried ' + resolved
);
var cached = require.cache[resolved];
var res = cached? cached.exports : mod();
return res;
};
require.paths = [];
require.modules = {};
require.cache = {};
require.extensions = [".js",".coffee",".json"];
require._core = {
'assert': true,
'events': true,
'fs': true,
'path': true,
'vm': true
};
require.resolve = (function () {
return function (x, cwd) {
if (!cwd) cwd = '/';
if (require._core[x]) return x;
var path = require.modules.path();
cwd = path.resolve('/', cwd);
var y = cwd || '/';
if (x.match(/^(?:\.\.?\/|\/)/)) {
var m = loadAsFileSync(path.resolve(y, x))
|| loadAsDirectorySync(path.resolve(y, x));
if (m) return m;
}
var n = loadNodeModulesSync(x, y);
if (n) return n;
throw new Error("Cannot find module '" + x + "'");
function loadAsFileSync (x) {
x = path.normalize(x);
if (require.modules[x]) {
return x;
}
for (var i = 0; i < require.extensions.length; i++) {
var ext = require.extensions[i];
if (require.modules[x + ext]) return x + ext;
}
}
function loadAsDirectorySync (x) {
x = x.replace(/\/+$/, '');
var pkgfile = path.normalize(x + '/package.json');
if (require.modules[pkgfile]) {
var pkg = require.modules[pkgfile]();
var b = pkg.browserify;
if (typeof b === 'object' && b.main) {
var m = loadAsFileSync(path.resolve(x, b.main));
if (m) return m;
}
else if (typeof b === 'string') {
var m = loadAsFileSync(path.resolve(x, b));
if (m) return m;
}
else if (pkg.main) {
var m = loadAsFileSync(path.resolve(x, pkg.main));
if (m) return m;
}
}
return loadAsFileSync(x + '/index');
}
function loadNodeModulesSync (x, start) {
var dirs = nodeModulesPathsSync(start);
for (var i = 0; i < dirs.length; i++) {
var dir = dirs[i];
var m = loadAsFileSync(dir + '/' + x);
if (m) return m;
var n = loadAsDirectorySync(dir + '/' + x);
if (n) return n;
}
var m = loadAsFileSync(x);
if (m) return m;
}
function nodeModulesPathsSync (start) {
var parts;
if (start === '/') parts = [ '' ];
else parts = path.normalize(start).split('/');
var dirs = [];
for (var i = parts.length - 1; i >= 0; i--) {
if (parts[i] === 'node_modules') continue;
var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
dirs.push(dir);
}
return dirs;
}
};
})();
require.alias = function (from, to) {
var path = require.modules.path();
var res = null;
try {
res = require.resolve(from + '/package.json', '/');
}
catch (err) {
res = require.resolve(from, '/');
}
var basedir = path.dirname(res);
var keys = (Object.keys || function (obj) {
var res = [];
for (var key in obj) res.push(key);
return res;
})(require.modules);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key.slice(0, basedir.length + 1) === basedir + '/') {
var f = key.slice(basedir.length);
require.modules[to + f] = require.modules[basedir + f];
}
else if (key === basedir) {
require.modules[to] = require.modules[basedir];
}
}
};
(function () {
var process = {};
var global = typeof window !== 'undefined' ? window : {};
var definedProcess = false;
require.define = function (filename, fn) {
if (!definedProcess && require.modules.__browserify_process) {
process = require.modules.__browserify_process();
definedProcess = true;
}
var dirname = require._core[filename]
? ''
: require.modules.path().dirname(filename)
;
var require_ = function (file) {
var requiredModule = require(file, dirname);
var cached = require.cache[require.resolve(file, dirname)];
if (cached && cached.parent === null) {
cached.parent = module_;
}
return requiredModule;
};
require_.resolve = function (name) {
return require.resolve(name, dirname);
};
require_.modules = require.modules;
require_.define = require.define;
require_.cache = require.cache;
var module_ = {
id : filename,
filename: filename,
exports : {},
loaded : false,
parent: null
};
require.modules[filename] = function () {
require.cache[filename] = module_;
fn.call(
module_.exports,
require_,
module_,
module_.exports,
dirname,
filename,
process,
global
);
module_.loaded = true;
return module_.exports;
};
};
})();
require.define("path",function(require,module,exports,__dirname,__filename,process,global){function filter (xs, fn) {
var res = [];
for (var i = 0; i < xs.length; i++) {
if (fn(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Regex to split a filename into [*, dir, basename, ext]
// posix version
var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0)
? arguments[i]
: process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
return p && typeof p === 'string';
}).join('/'));
};
exports.dirname = function(path) {
var dir = splitPathRe.exec(path)[1] || '';
var isWindows = false;
if (!dir) {
// No dirname
return '.';
} else if (dir.length === 1 ||
(isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
// It is just a slash or a drive letter with a slash
return dir;
} else {
// It is a full dirname, strip trailing slash
return dir.substring(0, dir.length - 1);
}
};
exports.basename = function(path, ext) {
var f = splitPathRe.exec(path)[2] || '';
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPathRe.exec(path)[3] || '';
};
});
require.define("__browserify_process",function(require,module,exports,__dirname,__filename,process,global){var process = module.exports = {};
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canSetImmediate) {
return window.setImmediate;
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
if (ev.source === window && ev.data === 'browserify-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('browserify-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.binding = function (name) {
if (name === 'evals') return (require)('vm')
else throw new Error('No such module. (Possibly not yet loaded)')
};
(function () {
var cwd = '/';
var path;
process.cwd = function () { return cwd };
process.chdir = function (dir) {
if (!path) path = require('path');
cwd = path.resolve(dir, cwd);
};
})();
});
require.define("/rocket.js",function(require,module,exports,__dirname,__filename,process,global){var box = require('./box');
//var util = require('./utils');
var particle = require('./particle');
var Shrapnel = require('./shrapnel');
var rimg = new Image();
rimg.src = 'ship2.png';
var Rocket = function(game, x, y, a) {
this.game = game;
this.x = x;
this.y = y;
this.a = a;
this.my = 0;
this.go = false;
this.start = Date.now();
this.body = this.game.makeBody(x, y, [[0,-2],[1.2,1.8],[-1.2,1.8]], this);
this.active = true;
this.last_particle = Date.now();
this.last_shot = Date.now();
this.explode = function() {
if(!this.active) { return; }
var pos = this.body.GetPosition();
var vel = this.body.GetLinearVelocity();
var idx = 0;
var a = Math.random() * Math.PI;
while(idx < 4) {
idx++;
var s = new Shrapnel(this.game, pos.x, pos.y, .01, true);
s.body.SetAngularVelocity(Math.random() * 50 - 25);
var af = Math.random() * 100 + 50;
s.body.SetLinearVelocity(this.body.GetLinearVelocity());
var f = new box.Vec2(Math.sin(a) * af, Math.cos(a) * af);
s.body.ApplyImpulse(f, pos);
this.game.shraps.push(s);
a += Math.PI/2;
}
var pidx = 0;
while (pidx < 10) {
var p = new particle.Particle(this.game, fireball);
p.reset(pos.x * this.game.scale, pos.y * this.game.scale,
vel.x + Math.random() * 50 -25 , vel.y + Math.random() * 50 - 25,
1, 200 * Math.random(), 1, -.5,
Math.random() * 360,
Math.random() * 2- 1);
pidx++;
}
this.game.world.DestroyBody(this.body);
this.active = false;
}
this.animate = function(dt, now) {
var ctx = this.game.ctx;
var now = Date.now();
if(this.active == false && this.game.keys[82] == true) {
this.body = this.game.makeBody(40, 78, [[0,-2],[1.2,1.8],[-1.2,1.8]], this);
this.body.SetPosition(new box.Vec2(this.game.canvas.width / 2 / this.game.scale, (this.game.canvas.height - 20) / this.game.scale));
this.body.SetAngle(0);
this.body.SetAngularVelocity(0);
this.body.SetLinearVelocity(new box.Vec2(0, 0));
for(var s in this.game.shraps) {
this.game.shraps[s].destroy();
}
this.game.shraps = [];
this.active = true;
console.log('reset');
}
if(this.active) {
if(this.game.keys[88] == true) {
this.explode();
return;
}
var pos = this.body.GetPosition();
if(pos.x * this.game.scale > this.game.canvas.width) {
pos.x = 0;
this.body.SetPosition(pos);
} else if (pos.x < 0) {
pos.x = this.game.canvas.width / this.game.scale;
this.body.SetPosition(pos);
}
this.angle = this.body.GetAngle();
if(this.game.keys[32] == true) {
if(now - this.last_shot > 100) {
var pos = this.body.GetPosition();
npos = pos.Copy();
var angle = this.body.GetAngle();
npos.x += Math.sin(angle) * 3;
npos.y -= Math.cos(angle) * 3;
var vel = this.body.GetLinearVelocity();
var force = new box.Vec2(Math.sin(angle) * 150, Math.cos(angle) * -150);
var s = new Shrapnel(this.game, npos.x, npos.y, .01, false);
//s.body.SetAngularVelocity(Math.random() * 50 - 25);
s.body.SetLinearVelocity(vel);
s.body.ApplyImpulse(force, s.body.GetPosition());
this.game.shraps.push(s);
this.last_shot = now;
}
}
if(this.game.keys[38] == true) {
var cp = pos.Copy();
cp.x += Math.sin(this.angle) * -2;
cp.y += Math.cos(this.angle) * 2;
//ctx.fillRect(cp.x * scale - 10, cp.y * scale - 10, 20, 20);
var force = new box.Vec2(Math.sin(this.angle), Math.cos(this.angle))
force.x *= dt / 3;
force.y *= -dt / 3;
this.body.ApplyImpulse(force, cp);
vel = this.body.GetLinearVelocity();
if(now - this.last_particle > 50) {
var p = new particle.Particle(this.game, this.game.smoke);
p.reset(
cp.x * this.game.scale,
cp.y * this.game.scale,
Math.sin(this.angle) * -(-vel.x + 60 + (30 * Math.random())),
Math.cos(this.angle) *(vel.y + 60 + (30 * Math.random())) ,
10, 25, 1, -.5,
Math.random() * 360,
Math.random() * 10 - 5);
this.last_particle = now;
}
var ctx = this.game.ctx;
ctx.save();
ctx.translate(cp.x * this.game.scale, cp.y * this.game.scale);
ctx.rotate(this.angle + Math.PI);
ctx.drawImage(flame, -7.5, -9.5, 15, 19);
ctx.restore();
}
if(this.game.keys[39] == true) {
var cp = pos.Copy();
cp.x -= Math.sin(this.angle) * -1.5;
cp.y -= Math.cos(this.angle) * 1.5;
//ctx.fillStyle = 'red'
//ctx.fillRect(cp.x * scale - 10, cp.y * scale - 10, 20, 20);
var force = new box.Vec2(Math.sin(this.angle + Math.PI/2) * .20, Math.cos(this.angle - Math.PI/2) * .20)
//ctx.fillRect(cp.x * scale - force.x * scale * 2 - 5, cp.y * scale - force.y * scale * 2 - 5, 10, 10);
ctx.save();
ctx.translate(cp.x * this.game.scale - force.x * this.game.scale, cp.y * this.game.scale - force.y * this.game.scale );
ctx.rotate(this.angle - Math.PI/2);
ctx.drawImage(flame, -7.5, -9.5, 15,19);
ctx.restore();
this.body.ApplyImpulse(force, cp);
}
if(this.game.keys[37] == true) {
var cp = pos.Copy();
cp.x += Math.sin(this.angle) * 1.5;
cp.y += Math.cos(this.angle) * -1.5;
ctx.fillStyle = 'blue'
//ctx.fillRect(cp.x * scale - 10, cp.y * scale - 10, 20, 20);
var force = new box.Vec2(Math.sin(this.angle - Math.PI/2) * .20, Math.cos(this.angle + Math.PI/2) * .20)
ctx.save();
ctx.translate(cp.x * this.game.scale - force.x * this.game.scale, cp.y * this.game.scale - force.y * this.game.scale);
ctx.rotate(this.angle + Math.PI/2);
ctx.drawImage(flame, -7.5, -9.5, 15, 19);
ctx.restore();
//ctx.fillRect(cp.x * scale - force.x * scale*2 - 5, cp.y * scale - force.y * scale * 2- 5, 10, 10);
this.body.ApplyImpulse(force, cp);
}
this.x = pos.x * this.game.scale;
this.y = pos.y * this.game.scale;
if(this.y < -10) {
var vel = this.body.GetLinearVelocity();
ctx.save();
ctx.translate(this.x, 20);
ctx.fillText("Velocity: " + (vel.y.toFixed(2)), -40, 30);
ctx.fillText("Distance: " + ((Math.abs(pos.y)).toFixed(2)), -40, 45);
ctx.rotate(this.angle);
ctx.globalAlpha = .5;
ctx.drawImage(rimg, -11, -18);
ctx.globalAlpha = 1.0;
ctx.restore();
} else {
ctx.save();
ctx.translate(this.x , this.y);
ctx.rotate(this.angle);
ctx.drawImage(rimg, -11, -18);
ctx.restore();
}
}
};
};
module.exports = Rocket;
});
require.define("/box.js",function(require,module,exports,__dirname,__filename,process,global){module.exports = {
Vec2: Box2D.Common.Math.b2Vec2,
Math: Box2D.Common.Math.b2Math,
BodyDef: Box2D.Dynamics.b2BodyDef,
Body: Box2D.Dynamics.b2Body,
FixtureDef: Box2D.Dynamics.b2FixtureDef,
Fixture: Box2D.Dynamics.b2Fixture,
World: Box2D.Dynamics.b2World,
MassData: Box2D.Collision.Shapes.b2MassData,
PolygonShape: Box2D.Collision.Shapes.b2PolygonShape,
CircleShape: Box2D.Collision.Shapes.b2CircleShape,
DebugDraw: Box2D.Dynamics.b2DebugDraw
};
});
require.define("/particle.js",function(require,module,exports,__dirname,__filename,process,global){var pcount = 0;
var particles = {};
var Particle = function(game, img) {
this.idx = pcount++;
particles[this.idx] = this;
this.start = Date.now();
this.img = img;
this.game = game;
};
(function() {
this.reset = function(x, y, mx, my, s, ms, o, mo, a, ma) {
this.start = Date.now();
this.x = x;
this.y = y;
this.mx = mx;
this.my = my;
this.s = s;
this.ms = ms;
this.o = o;
this.mo = mo;
this.a = a;
this.ma = ma;
};
this.animate = function(dt, now) {
var ctx = this.game.ctx;
this.x = this.x + this.mx * dt / .6;
this.y = this.y + this.my * dt / .6;
this.s = this.s + this.ms * dt;
this.o = this.o + this.mo * dt;
this.a = this.a + this.ma * dt;
ctx.globalAlpha = this.o;
if(this.y > this.game.canvas.height - 20) {
this.my = 0;
this.mx = this.mx = Math.random() * 100 - 50;
this.y = this.game.canvas.height - 20;
//delete particles[pcount];
}
if(now - this.start > 5000 || this.o <= 0) {
delete particles[this.idx];
return;
}
ctx.save();
ctx.translate(this.x , this.y);
ctx.rotate(this.a);
//ctx.translate(this.x, this.y + this.s/2);
ctx.drawImage(this.img, -this.s/2, -this.s/2, this.s, this.s);
ctx.restore();
}
}).call(Particle.prototype);
module.exports = {Particle: Particle, particles: particles};
});
require.define("/shrapnel.js",function(require,module,exports,__dirname,__filename,process,global){var particle = require('./particle');
var Shrapnel = function(game,x, y, a, add_smoke) {
this.add_smoke = add_smoke;
this.x = x;
this.y = y;
this.a = a;
this.my = 0;
this.go = false;
this.start = Date.now();
this.body = game.makeBody(x, y, [[-.8,-.5],[-.5, -1], [1, -.4], [.4,.5], [-.8, 1]]);
this.last_particle = Date.now();
//this.body.m_body.SetPosition(200,200);
//this.body.x = x;
//this.body.y = y;
this.animate = function(dt, now) {
var pos = this.body.GetPosition();
if(pos.x * game.scale > game.canvas.width) {
pos.x = 0;
this.body.SetPosition(pos);
} else if (pos.x < 0) {
pos.x = game.canvas.width / game.scale;
this.body.SetPosition(pos);
}
var vel = this.body.GetLinearVelocity();
var now = Date.now();
if(this.add_smoke && now - this.start < 1200 && now - this.last_particle > 50) {
var p = new particle.Particle(game, game.smoke);
p.reset(
pos.x * game.scale,
pos.y * game.scale,
Math.random() * 50 - 25,
Math.random() * 50 - 25,
10, 25, .5, -.2,
Math.random() * 360,
Math.random() * 10 - 5);
this.last_particle = now;
}
this.angle = this.body.GetAngle();
this.x = pos.x * game.scale;
this.y = pos.y * game.scale;
game.ctx.save();
game.ctx.translate(this.x , this.y);
game.ctx.rotate(this.angle);
game.ctx.drawImage(shrap, -10, -10);
game.ctx.restore();
};
this.destroy = function() {
game.world.DestroyBody(this.body);
}
};
module.exports = Shrapnel;
});
require.define("/game.js",function(require,module,exports,__dirname,__filename,process,global){
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
console.log(window.requestAnimFrame);
var Rocket = require('./rocket');
var particle = require('./particle');
var box = require('./box');
var b2Vec2 = Box2D.Common.Math.b2Vec2;
var b2Math = Box2D.Common.Math.b2Math;
var b2BodyDef = Box2D.Dynamics.b2BodyDef;
var b2Body = Box2D.Dynamics.b2Body;
var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
var b2Fixture = Box2D.Dynamics.b2Fixture;
var b2World = Box2D.Dynamics.b2World;
var b2MassData = Box2D.Collision.Shapes.b2MassData;
var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape;
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
var Game = function() {
this.canvas = document.getElementById('viewport');
console.log(this.canvas.parentNode.clientWidth, this.canvas.parentNode.clientHeight);
this.canvas.width = this.canvas.parentNode.clientWidth;
this.canvas.height = this.canvas.parentNode.clientHeight;
this.ctx = this.canvas.getContext('2d');
this.world = new b2World(
//new b2Vec2(0, 50), //gravity
new b2Vec2(0,50),
false //allow sleep
);
this.scale = 10;
this.smoke = new Image;
this.smoke.src = 'cloud.png';
this.rocket = new Rocket(this, this.canvas.width / 2 / this.scale, (this.canvas.height - 20) / this.scale, .01);
this.last_update = Date.now();
this.shraps = [];
this.keys = {};
document.addEventListener('keydown', function(e) {
//console.log(e.keyCode);
this.keys[e.keyCode] = true;
}.bind(this));
document.addEventListener('keyup', function(e) {
this.keys[e.keyCode] = false;
}.bind(this));
this.update();
};
(function() {
var avg = 0;
var avgt = 0;
var average = 0;
this.update = function() {
var now = Date.now();
var dt = (now - this.last_update);
avg += dt;
avgt++;
if (avgt === 20) {
average = (1000/(avg/20)).toFixed(2);
avgt = 0;
avg = 0;
}
/*
var gra = Math.atan2(this.rocket.y - 400, -(this.rocket.x - 400)) + Math.PI/2;
if(this.rocket.active) {
this.rocket.body.ApplyImpulse(new b2Vec2(Math.sin(gra) * (dt/5), Math.cos(gra) * (dt/5)), this.rocket.body.GetWorldCenter());
}
*/
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.globalAlpha = 1.0;
//ctx.fillStyle = 'white'
//ctx.fillRect(0, 0, canvas.width, canvas.height);
this.ctx.fillStyle = 'gray'
this.ctx.fillRect(0,this.canvas.height - 20, this.canvas.width, 20);
//this.world.DrawDebugData();
this.ctx.globalAlpha = 1.0;
this.ctx.fillStyle = 'black';
this.ctx.fillText("FPS: " + (average), 10, this.canvas.height - 30);
this.rocket.animate(dt);
for(var sidx in this.shraps) {
this.shraps[sidx].animate(dt, now);
}
dt = dt/1000;
for(var pidx in particle.particles) {
particle.particles[pidx].animate(dt, now);
}
this.world.Step(
dt
//frame-rate
, 10 //velocity iterations
, 10 //position iterations
);
//this.world.ClearForces();
requestAnimFrame(this.update.bind(this));
this.last_update = now;
};
this.makeBody = function (x, y, points, p) {
var pidx = 0;
while(pidx < points.length) {
points[pidx] = new box.Vec2(points[pidx][0], points[pidx][1]);
pidx++;
}
var fixDef = new box.FixtureDef;
fixDef.density = 1.0;
fixDef.friction = .8;
fixDef.restitution = 0.2;
fixDef.shape = new box.PolygonShape;
fixDef.shape.SetAsArray(points, points.length);
fixDef.par = p;
var bodyDef = new box.BodyDef;
if(p) {
bodyDef.userData = p;
}
bodyDef.type = box.Body.b2_dynamicBody;
bodyDef.position.x = x;
bodyDef.position.y = y;
var body = this.world.CreateBody(bodyDef);
var fixt = body.CreateFixture(fixDef);
return body;
}
}).call(Game.prototype);
var game = new Game;
/*
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(game.ctx);
debugDraw.SetDrawScale(game.scale);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
game.world.SetDebugDraw(debugDraw);
*/
var fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = .8;
fixDef.restitution = 0.2;
var bodyDef = new b2BodyDef;
//create ground
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = game.canvas.width / 2 / game.scale;
bodyDef.position.y = game.canvas.height / game.scale;
bodyDef.userData = "ground";
//fixDef.shape = new b2CircleShape(20);
fixDef.shape = new b2PolygonShape
fixDef.shape.SetAsBox(game.canvas.width / 2 / game.scale, 2);
game.world.CreateBody(bodyDef).CreateFixture(fixDef);
flame = new Image();
flame.src = 'flame.gif';
fireball = new Image();
fireball.src = 'fireball.png';
shrap = new Image();
shrap.src = 'shrapenel.png';
var shraps = [];
var last_update = Date.now();
var last_particle = Date.now();
var mouse_x = 0;
var mouse_y = 0;
function normalizeAngle(angle) {
if(angle == 0) { return 0; }
if(angle < 0 || angle > Math.PI * 2) return Math.abs((Math.PI * 2) - Math.abs(angle));
}
var contactListener = new Box2D.Dynamics.b2ContactListener;
contactListener.PreSolve = function(contact, manifold) {
var a = contact.GetFixtureA();
var ab = a.GetBody();
var b = contact.GetFixtureB();
var bb = b.GetBody();
var au = ab.GetUserData();
var bu = bb.GetUserData();
if((au instanceof Rocket && bu == 'ground') || au == 'ground' && bu instanceof Rocket) {
var av = ab.GetLinearVelocity();
var bv = bb.GetLinearVelocity();
var f = b2Math.Distance(bv, av);
var r = null;
if(au instanceof Rocket) r = au;
if(bu instanceof Rocket) r = bu;
if(r && f > 25) {
setTimeout(
r.explode.bind(r), 0);
/*
au.explode();
bu.explode();
*/
} else if (r.body) {
var a = r.body.GetAngle();
a = Box2D.Common.Math.b2Mat22.FromAngle(a);
a = Math.abs(Math.atan2(a.col1.y, a.col1.x));
if(a > 1.5) {
setTimeout(
r.explode.bind(r), 0);
}
}
}
// rocket.explode();
//do some stuff
};
game.world.SetContactListener(contactListener);
});
require("/game.js");
})();

54
public/particle.js Normal file
View File

@ -0,0 +1,54 @@
var pcount = 0;
var particles = {};
var Particle = function(game, img) {
this.idx = pcount++;
particles[this.idx] = this;
this.start = Date.now();
this.img = img;
this.game = game;
};
(function() {
this.reset = function(x, y, mx, my, s, ms, o, mo, a, ma) {
this.start = Date.now();
this.x = x;
this.y = y;
this.mx = mx;
this.my = my;
this.s = s;
this.ms = ms;
this.o = o;
this.mo = mo;
this.a = a;
this.ma = ma;
};
this.animate = function(dt, now) {
var ctx = this.game.ctx;
this.x = this.x + this.mx * dt / .6;
this.y = this.y + this.my * dt / .6;
this.s = this.s + this.ms * dt;
this.o = this.o + this.mo * dt;
this.a = this.a + this.ma * dt;
ctx.globalAlpha = this.o;
if(this.y > this.game.canvas.height - 20) {
this.my = 0;
this.mx = this.mx = Math.random() * 100 - 50;
this.y = this.game.canvas.height - 20;
//delete particles[pcount];
}
if(now - this.start > 5000 || this.o <= 0) {
delete particles[this.idx];
return;
}
ctx.save();
ctx.translate(this.x , this.y);
ctx.rotate(this.a);
//ctx.translate(this.x, this.y + this.s/2);
ctx.drawImage(this.img, -this.s/2, -this.s/2, this.s, this.s);
ctx.restore();
}
}).call(Particle.prototype);
module.exports = {Particle: Particle, particles: particles};

142
public/retina.js Normal file
View File

@ -0,0 +1,142 @@
(function() {
var root = (typeof exports == 'undefined' ? window : exports);
var config = {
// Ensure Content-Type is an image before trying to load @2x image
// https://github.com/imulus/retinajs/pull/45)
check_mime_type: true
};
root.Retina = Retina;
function Retina() {}
Retina.configure = function(options) {
if (options == null) options = {};
for (var prop in options) config[prop] = options[prop];
};
Retina.init = function(context) {
if (context == null) context = root;
var existing_onload = context.onload || new Function;
context.onload = function() {
var images = document.getElementsByTagName("img"), retinaImages = [], i, image;
for (i = 0; i < images.length; i++) {
image = images[i];
retinaImages.push(new RetinaImage(image));
}
existing_onload();
}
};
Retina.isRetina = function(){
var mediaQuery = "(-webkit-min-device-pixel-ratio: 1.5),\
(min--moz-device-pixel-ratio: 1.5),\
(-o-min-device-pixel-ratio: 3/2),\
(min-resolution: 1.5dppx)";
if (root.devicePixelRatio > 1)
return true;
if (root.matchMedia && root.matchMedia(mediaQuery).matches)
return true;
return false;
};
root.RetinaImagePath = RetinaImagePath;
function RetinaImagePath(path, at_2x_path) {
this.path = path;
if (typeof at_2x_path !== "undefined" && at_2x_path !== null) {
this.at_2x_path = at_2x_path;
this.perform_check = false;
} else {
this.at_2x_path = path.replace(/\.\w+$/, function(match) { return "@2x" + match; });
this.perform_check = true;
}
}
RetinaImagePath.confirmed_paths = [];
RetinaImagePath.prototype.is_external = function() {
return !!(this.path.match(/^https?\:/i) && !this.path.match('//' + document.domain) )
}
RetinaImagePath.prototype.check_2x_variant = function(callback) {
var http, that = this;
if (this.is_external()) {
return callback(false);
} else if (!this.perform_check && typeof this.at_2x_path !== "undefined" && this.at_2x_path !== null) {
return callback(true);
} else if (this.at_2x_path in RetinaImagePath.confirmed_paths) {
return callback(true);
} else {
http = new XMLHttpRequest;
http.open('HEAD', this.at_2x_path);
http.onreadystatechange = function() {
if (http.readyState != 4) {
return callback(false);
}
if (http.status >= 200 && http.status <= 399) {
if (config.check_mime_type) {
var type = http.getResponseHeader('Content-Type');
if (type == null || !type.match(/^image/i)) {
return callback(false);
}
}
RetinaImagePath.confirmed_paths.push(that.at_2x_path);
return callback(true);
} else {
return callback(false);
}
}
http.send();
}
}
function RetinaImage(el) {
this.el = el;
this.path = new RetinaImagePath(this.el.getAttribute('src'), this.el.getAttribute('data-at2x'));
var that = this;
this.path.check_2x_variant(function(hasVariant) {
if (hasVariant) that.swap();
});
}
root.RetinaImage = RetinaImage;
RetinaImage.prototype.swap = function(path) {
if (typeof path == 'undefined') path = this.path.at_2x_path;
var that = this;
function load() {
if (! that.el.complete) {
setTimeout(load, 5);
} else {
that.el.setAttribute('width', that.el.offsetWidth);
that.el.setAttribute('height', that.el.offsetHeight);
that.el.setAttribute('src', path);
}
}
load();
}
if (Retina.isRetina()) {
Retina.init(root);
}
})();

BIN
public/robot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

190
public/rocket.js Normal file
View File

@ -0,0 +1,190 @@
var box = require('./box');
//var util = require('./utils');
var particle = require('./particle');
var Shrapnel = require('./shrapnel');
var rimg = new Image();
rimg.src = 'ship2.png';
var Rocket = function(game, x, y, a) {
this.game = game;
this.x = x;
this.y = y;
this.a = a;
this.my = 0;
this.go = false;
this.start = Date.now();
this.body = this.game.makeBody(x, y, [[0,-2],[1.2,1.8],[-1.2,1.8]], this);
this.active = true;
this.last_particle = Date.now();
this.last_shot = Date.now();
this.explode = function() {
if(!this.active) { return; }
var pos = this.body.GetPosition();
var vel = this.body.GetLinearVelocity();
var idx = 0;
var a = Math.random() * Math.PI;
while(idx < 4) {
idx++;
var s = new Shrapnel(this.game, pos.x, pos.y, .01, true);
s.body.SetAngularVelocity(Math.random() * 50 - 25);
var af = Math.random() * 100 + 50;
s.body.SetLinearVelocity(this.body.GetLinearVelocity());
var f = new box.Vec2(Math.sin(a) * af, Math.cos(a) * af);
s.body.ApplyImpulse(f, pos);
this.game.shraps.push(s);
a += Math.PI/2;
}
var pidx = 0;
while (pidx < 10) {
var p = new particle.Particle(this.game, fireball);
p.reset(pos.x * this.game.scale, pos.y * this.game.scale,
vel.x + Math.random() * 50 -25 , vel.y + Math.random() * 50 - 25,
1, 200 * Math.random(), 1, -.5,
Math.random() * 360,
Math.random() * 2- 1);
pidx++;
}
this.game.world.DestroyBody(this.body);
this.active = false;
}
this.animate = function(dt, now) {
var ctx = this.game.ctx;
var now = Date.now();
if(this.active == false && this.game.keys[82] == true) {
this.body = this.game.makeBody(40, 78, [[0,-2],[1.2,1.8],[-1.2,1.8]], this);
this.body.SetPosition(new box.Vec2(this.game.canvas.width / 2 / this.game.scale, (this.game.canvas.height - 20) / this.game.scale));
this.body.SetAngle(0);
this.body.SetAngularVelocity(0);
this.body.SetLinearVelocity(new box.Vec2(0, 0));
for(var s in this.game.shraps) {
this.game.shraps[s].destroy();
}
this.game.shraps = [];
this.active = true;
console.log('reset');
}
if(this.active) {
if(this.game.keys[88] == true) {
this.explode();
return;
}
var pos = this.body.GetPosition();
if(pos.x * this.game.scale > this.game.canvas.width) {
pos.x = 0;
this.body.SetPosition(pos);
} else if (pos.x < 0) {
pos.x = this.game.canvas.width / this.game.scale;
this.body.SetPosition(pos);
}
this.angle = this.body.GetAngle();
if(this.game.keys[32] == true) {
if(now - this.last_shot > 100) {
var pos = this.body.GetPosition();
npos = pos.Copy();
var angle = this.body.GetAngle();
npos.x += Math.sin(angle) * 3;
npos.y -= Math.cos(angle) * 3;
var vel = this.body.GetLinearVelocity();
var force = new box.Vec2(Math.sin(angle) * 150, Math.cos(angle) * -150);
var s = new Shrapnel(this.game, npos.x, npos.y, .01, false);
//s.body.SetAngularVelocity(Math.random() * 50 - 25);
s.body.SetLinearVelocity(vel);
s.body.ApplyImpulse(force, s.body.GetPosition());
this.game.shraps.push(s);
this.last_shot = now;
}
}
if(this.game.keys[38] == true) {
var cp = pos.Copy();
cp.x += Math.sin(this.angle) * -2;
cp.y += Math.cos(this.angle) * 2;
//ctx.fillRect(cp.x * scale - 10, cp.y * scale - 10, 20, 20);
var force = new box.Vec2(Math.sin(this.angle), Math.cos(this.angle))
force.x *= dt / 3;
force.y *= -dt / 3;
this.body.ApplyImpulse(force, cp);
vel = this.body.GetLinearVelocity();
if(now - this.last_particle > 50) {
var p = new particle.Particle(this.game, this.game.smoke);
p.reset(
cp.x * this.game.scale,
cp.y * this.game.scale,
Math.sin(this.angle) * -(-vel.x + 60 + (30 * Math.random())),
Math.cos(this.angle) *(vel.y + 60 + (30 * Math.random())) ,
10, 25, 1, -.5,
Math.random() * 360,
Math.random() * 10 - 5);
this.last_particle = now;
}
var ctx = this.game.ctx;
ctx.save();
ctx.translate(cp.x * this.game.scale, cp.y * this.game.scale);
ctx.rotate(this.angle + Math.PI);
ctx.drawImage(flame, -7.5, -9.5, 15, 19);
ctx.restore();
}
if(this.game.keys[39] == true) {
var cp = pos.Copy();
cp.x -= Math.sin(this.angle) * -1.5;
cp.y -= Math.cos(this.angle) * 1.5;
//ctx.fillStyle = 'red'
//ctx.fillRect(cp.x * scale - 10, cp.y * scale - 10, 20, 20);
var force = new box.Vec2(Math.sin(this.angle + Math.PI/2) * .20, Math.cos(this.angle - Math.PI/2) * .20)
//ctx.fillRect(cp.x * scale - force.x * scale * 2 - 5, cp.y * scale - force.y * scale * 2 - 5, 10, 10);
ctx.save();
ctx.translate(cp.x * this.game.scale - force.x * this.game.scale, cp.y * this.game.scale - force.y * this.game.scale );
ctx.rotate(this.angle - Math.PI/2);
ctx.drawImage(flame, -7.5, -9.5, 15,19);
ctx.restore();
this.body.ApplyImpulse(force, cp);
}
if(this.game.keys[37] == true) {
var cp = pos.Copy();
cp.x += Math.sin(this.angle) * 1.5;
cp.y += Math.cos(this.angle) * -1.5;
ctx.fillStyle = 'blue'
//ctx.fillRect(cp.x * scale - 10, cp.y * scale - 10, 20, 20);
var force = new box.Vec2(Math.sin(this.angle - Math.PI/2) * .20, Math.cos(this.angle + Math.PI/2) * .20)
ctx.save();
ctx.translate(cp.x * this.game.scale - force.x * this.game.scale, cp.y * this.game.scale - force.y * this.game.scale);
ctx.rotate(this.angle + Math.PI/2);
ctx.drawImage(flame, -7.5, -9.5, 15, 19);
ctx.restore();
//ctx.fillRect(cp.x * scale - force.x * scale*2 - 5, cp.y * scale - force.y * scale * 2- 5, 10, 10);
this.body.ApplyImpulse(force, cp);
}
this.x = pos.x * this.game.scale;
this.y = pos.y * this.game.scale;
if(this.y < -10) {
var vel = this.body.GetLinearVelocity();
ctx.save();
ctx.translate(this.x, 20);
ctx.fillText("Velocity: " + (vel.y.toFixed(2)), -40, 30);
ctx.fillText("Distance: " + ((Math.abs(pos.y)).toFixed(2)), -40, 45);
ctx.rotate(this.angle);
ctx.globalAlpha = .5;
ctx.drawImage(rimg, -11, -18);
ctx.globalAlpha = 1.0;
ctx.restore();
} else {
ctx.save();
ctx.translate(this.x , this.y);
ctx.rotate(this.angle);
ctx.drawImage(rimg, -11, -18);
ctx.restore();
}
}
};
};
module.exports = Rocket;

BIN
public/rocket.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

53
public/ship.svg Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="ship"
x="0px"
y="0px"
xml:space="preserve"
inkscape:version="0.48.2 r9819"
width="100%"
height="100%"
sodipodi:docname="ship.svg"><metadata
id="metadata3134"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs3132" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="887"
inkscape:window-height="708"
id="namedview3130"
showgrid="false"
inkscape:zoom="7.0847604"
inkscape:cx="41.215997"
inkscape:cy="1003.5875"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g3124" />
<g
id="g3124"
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-12.842404,32.822117)">
<path
d="m 48.921908,16.495906 c -7.96e-4,-0.235169 -0.171507,-0.41824 -0.407014,-0.436469 -4.332912,-0.307404 -8.687353,0.230951 -12.638207,2.106216 -2.96082,1.404524 -5.483343,3.581816 -7.49713,6.148099 -1.9816,0.03989 -3.868475,0.662396 -5.665481,1.462168 -1.123138,0.500107 -2.093541,0.924501 -2.808213,1.934173 -1.574659,2.226401 -2.248594,5.27874 -2.635702,7.939853 -0.03279,0.221986 0.242119,0.344659 0.414295,0.256614 1.721044,-0.85946 3.787414,-1.120502 5.713068,-1.134307 -0.100308,0.436764 -0.193576,0.872775 -0.269861,1.309379 -0.01,0.05669 -0.01893,0.111406 -0.02786,0.166126 -0.03994,0.08365 -0.05019,0.176356 -0.01635,0.267592 0.02204,0.113838 0.09633,0.19248 0.190921,0.234805 0.04751,0.04369 0.09405,0.08634 0.141584,0.12902 -0.160464,0.411652 -0.31893,0.823372 -0.479395,1.235022 -0.03195,0.08394 -0.0076,0.216869 0.06243,0.275347 1.213898,1.026989 2.427796,2.053979 3.642694,3.081005 0.09717,0.08245 0.217883,0.12168 0.338257,0.05584 0.304994,-0.166457 0.608954,-0.33195 0.912951,-0.498441 0.321412,0.194335 0.650174,0.292868 0.973365,0.207097 0.290859,-0.07691 0.578897,-0.158893 0.867004,-0.242891 0.0754,1.823743 -0.08269,3.743396 -0.778389,5.413133 -0.191141,0.66588 -0.283323,0.68243 -0.08877,0.641194 2.565924,-0.554788 5.84464,-1.711969 7.953883,-3.315334 0.975468,-0.741409 1.282471,-1.481146 1.737794,-2.599937 0.702823,-1.730526 1.226259,-3.596395 1.262818,-5.474263 0.352577,-0.296876 0.697295,-0.598029 1.03451,-0.913452 4.437222,-4.169684 7.088581,-10.007708 7.887074,-15.99649 0.105865,-0.795787 0.181026,-1.459573 0.179669,-2.251101 z M 38.842671,27.73099 c -1.800904,-0.06289 -3.208062,-1.572918 -3.145208,-3.372821 0.06289,-1.800901 1.571954,-3.209093 3.372856,-3.146205 1.800903,0.06289 3.20806,1.572919 3.145172,3.373821 -0.06286,1.799902 -1.571919,3.208095 -3.37282,3.145205 z"
id="path3126"
inkscape:connector-curvature="0"
style="fill:#00adee;fill-opacity:1"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccsssss" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/ship2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

BIN
public/shrapenel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

54
public/shrapnel.js Normal file
View File

@ -0,0 +1,54 @@
var particle = require('./particle');
var Shrapnel = function(game,x, y, a, add_smoke) {
this.add_smoke = add_smoke;
this.x = x;
this.y = y;
this.a = a;
this.my = 0;
this.go = false;
this.start = Date.now();
this.body = game.makeBody(x, y, [[-.8,-.5],[-.5, -1], [1, -.4], [.4,.5], [-.8, 1]]);
this.last_particle = Date.now();
//this.body.m_body.SetPosition(200,200);
//this.body.x = x;
//this.body.y = y;
this.animate = function(dt, now) {
var pos = this.body.GetPosition();
if(pos.x * game.scale > game.canvas.width) {
pos.x = 0;
this.body.SetPosition(pos);
} else if (pos.x < 0) {
pos.x = game.canvas.width / game.scale;
this.body.SetPosition(pos);
}
var vel = this.body.GetLinearVelocity();
var now = Date.now();
if(this.add_smoke && now - this.start < 1200 && now - this.last_particle > 50) {
var p = new particle.Particle(game, game.smoke);
p.reset(
pos.x * game.scale,
pos.y * game.scale,
Math.random() * 50 - 25,
Math.random() * 50 - 25,
10, 25, .5, -.2,
Math.random() * 360,
Math.random() * 10 - 5);
this.last_particle = now;
}
this.angle = this.body.GetAngle();
this.x = pos.x * game.scale;
this.y = pos.y * game.scale;
game.ctx.save();
game.ctx.translate(this.x , this.y);
game.ctx.rotate(this.angle);
game.ctx.drawImage(shrap, -10, -10);
game.ctx.restore();
};
this.destroy = function() {
game.world.DestroyBody(this.body);
}
};
module.exports = Shrapnel;

657
public/simplewebrtc.js Normal file
View File

@ -0,0 +1,657 @@
;(function () {
var logger = {
log: function (){},
warn: function (){},
error: function (){}
};
// normalize environment
var RTCPeerConnection = null,
getUserMedia = null,
attachMediaStream = null,
reattachMediaStream = null,
browser = null,
screenSharingSupport = false;
webRTCSupport = true;
if (navigator.mozGetUserMedia) {
logger.log("This appears to be Firefox");
browser = "firefox";
// The RTCPeerConnection object.
RTCPeerConnection = mozRTCPeerConnection;
// The RTCSessionDescription object.
RTCSessionDescription = mozRTCSessionDescription;
// The RTCIceCandidate object.
RTCIceCandidate = mozRTCIceCandidate;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.mozGetUserMedia.bind(navigator);
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
element.mozSrcObject = stream;
element.play();
};
reattachMediaStream = function(to, from) {
to.mozSrcObject = from.mozSrcObject;
to.play();
};
// Fake get{Video,Audio}Tracks
MediaStream.prototype.getVideoTracks = function() {
return [];
};
MediaStream.prototype.getAudioTracks = function() {
return [];
};
} else if (navigator.webkitGetUserMedia) {
browser = "chrome";
screenSharingSupport = navigator.userAgent.match('Chrome') && parseInt(navigator.userAgent.match(/Chrome\/(.*) /)[1]) >= 26
// The RTCPeerConnection object.
RTCPeerConnection = webkitRTCPeerConnection;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
element.autoplay = true;
element.src = webkitURL.createObjectURL(stream);
};
reattachMediaStream = function(to, from) {
to.src = from.src;
};
// The representation of tracks in a stream is changed in M26.
// Unify them for earlier Chrome versions in the coexisting period.
if (!webkitMediaStream.prototype.getVideoTracks) {
webkitMediaStream.prototype.getVideoTracks = function() {
return this.videoTracks;
};
webkitMediaStream.prototype.getAudioTracks = function() {
return this.audioTracks;
};
}
// New syntax of getXXXStreams method in M26.
if (!webkitRTCPeerConnection.prototype.getLocalStreams) {
webkitRTCPeerConnection.prototype.getLocalStreams = function() {
return this.localStreams;
};
webkitRTCPeerConnection.prototype.getRemoteStreams = function() {
return this.remoteStreams;
};
}
} else {
webRTCSupport = false;
throw new Error("Browser does not appear to be WebRTC-capable");
}
// emitter that we use as a base
function WildEmitter() {
this.callbacks = {};
}
// Listen on the given `event` with `fn`. Store a group name if present.
WildEmitter.prototype.on = function (event, groupName, fn) {
var hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
func._groupName = group;
(this.callbacks[event] = this.callbacks[event] || []).push(func);
return this;
};
// Adds an `event` listener that will be invoked a single
// time then automatically removed.
WildEmitter.prototype.once = function (event, fn) {
var self = this;
function on() {
self.off(event, on);
fn.apply(this, arguments);
}
this.on(event, on);
return this;
};
// Unbinds an entire group
WildEmitter.prototype.releaseGroup = function (groupName) {
var item, i, len, handlers;
for (item in this.callbacks) {
handlers = this.callbacks[item];
for (i = 0, len = handlers.length; i < len; i++) {
if (handlers[i]._groupName === groupName) {
handlers.splice(i, 1);
i--;
len--;
}
}
}
return this;
};
// Remove the given callback for `event` or all
// registered callbacks.
WildEmitter.prototype.off = function (event, fn) {
var callbacks = this.callbacks[event],
i;
if (!callbacks) return this;
// remove all handlers
if (arguments.length === 1) {
delete this.callbacks[event];
return this;
}
// remove specific handler
i = callbacks.indexOf(fn);
callbacks.splice(i, 1);
return this;
};
// Emit `event` with the given args.
// also calls any `*` handlers
WildEmitter.prototype.emit = function (event) {
var args = [].slice.call(arguments, 1),
callbacks = this.callbacks[event],
specialCallbacks = this.getWildcardCallbacks(event),
i,
len,
item;
if (callbacks) {
for (i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
if (specialCallbacks) {
for (i = 0, len = specialCallbacks.length; i < len; ++i) {
specialCallbacks[i].apply(this, [event].concat(args));
}
}
return this;
};
// Helper for for finding special wildcard event handlers that match the event
WildEmitter.prototype.getWildcardCallbacks = function (eventName) {
var item,
split,
result = [];
for (item in this.callbacks) {
split = item.split('*');
if (item === '*' || (split.length === 2 && eventName.slice(0, split[1].length) === split[1])) {
result = result.concat(this.callbacks[item]);
}
}
return result;
};
function WebRTC(opts) {
var self = this,
options = opts || {},
config = this.config = {
url: 'http://signaling.simplewebrtc.com:8888',
log: false,
localVideoEl: '',
remoteVideosEl: '',
autoRequestMedia: false,
// makes the entire PC config overridable
peerConnectionConfig: {
iceServers: browser == 'firefox' ? [{"url":"stun:124.124.124.2"}] : [{"url": "stun:stun.l.google.com:19302"}]
},
peerConnectionContraints: {
optional: [{"DtlsSrtpKeyAgreement": true}]
},
media: {
audio:true,
video: {
mandatory: {},
optional: []
}
}
},
item,
connection;
// check for support
if (!webRTCSupport) {
console.error('Your browser doesn\'t seem to support WebRTC');
}
// expose screensharing check
this.screenSharingSupport = screenSharingSupport;
// set options
for (item in options) {
this.config[item] = options[item];
}
// log if configured to
if (this.config.log) logger = console;
// where we'll store our peer connections
this.peers = [];
// our socket.io connection
connection = this.connection = io.connect(this.config.url);
connection.on('connect', function () {
self.emit('ready', connection.socket.sessionid);
self.sessionReady = true;
self.testReadiness();
});
connection.on('message', function (message) {
var peers = self.getPeers(message.from, message.roomType),
peer;
if (message.type === 'offer') {
peer = self.createPeer({
id: message.from,
type: message.roomType,
sharemyscreen: message.roomType === 'screen' && !message.broadcaster
});
peer.handleMessage(message);
} else if (peers.length) {
peers.forEach(function (peer) {
peer.handleMessage(message);
});
}
});
connection.on('remove', function (room) {
if (room.id !== self.connection.socket.sessionid) {
self.removeForPeerSession(room.id, room.type);
}
});
WildEmitter.call(this);
// log events
this.on('*', function (event, val1, val2) {
logger.log('event:', event, val1, val2);
});
// auto request if configured
if (this.config.autoRequestMedia) this.startLocalVideo();
}
WebRTC.prototype = Object.create(WildEmitter.prototype, {
constructor: {
value: WebRTC
}
});
WebRTC.prototype.getEl = function (idOrEl) {
if (typeof idOrEl == 'string') {
return document.getElementById(idOrEl);
} else {
return idOrEl;
}
};
// this accepts either element ID or element
// and either the video tag itself or a container
// that will be used to put the video tag into.
WebRTC.prototype.getLocalVideoContainer = function () {
var el = this.getEl(this.config.localVideoEl);
if (el && el.tagName === 'VIDEO') {
return el;
} else {
var video = document.createElement('video');
el.appendChild(video);
return video;
}
};
WebRTC.prototype.getRemoteVideoContainer = function () {
return this.getEl(this.config.remoteVideosEl);
};
WebRTC.prototype.createPeer = function (opts) {
var peer;
opts.parent = this;
peer = new Peer(opts);
this.peers.push(peer);
return peer;
};
WebRTC.prototype.createRoom = function (name, cb) {
if (arguments.length === 2) {
this.connection.emit('create', name, cb);
} else {
this.connection.emit('create', name);
}
};
WebRTC.prototype.joinRoom = function (name) {
var self = this;
this.roomName = name;
this.connection.emit('join', name, function (roomDescription) {
var id,
client,
type,
peer;
for (id in roomDescription) {
client = roomDescription[id];
for (type in client) {
if (client[type]) {
peer = self.createPeer({
id: id,
type: type
});
peer.start();
}
}
}
});
};
WebRTC.prototype.leaveRoom = function () {
if (this.roomName) {
this.connection.emit('leave', this.roomName);
this.peers.forEach(function (peer) {
peer.end();
});
}
};
WebRTC.prototype.testReadiness = function () {
var self = this;
if (this.localStream && this.sessionReady) {
// This timeout is a workaround for the strange no-audio bug
// as described here: https://code.google.com/p/webrtc/issues/detail?id=1525
// remove timeout when this is fixed.
setTimeout(function () {
self.emit('readyToCall', self.connection.socket.sessionid);
}, 1000);
}
};
WebRTC.prototype.startLocalVideo = function (element) {
var self = this;
getUserMedia(this.config.media, function (stream) {
attachMediaStream(element || self.getLocalVideoContainer(), stream);
self.localStream = stream;
self.testReadiness();
}, function () {
throw new Error('Failed to get access to local media.');
});
};
// Audio controls
WebRTC.prototype.mute = function () {
this._audioEnabled(false);
this.emit('audioOff');
};
WebRTC.prototype.unmute = function () {
this._audioEnabled(true);
this.emit('audioOn');
};
// Video controls
WebRTC.prototype.pauseVideo = function () {
this._videoEnabled(false);
this.emit('videoOff');
};
WebRTC.prototype.resumeVideo = function () {
this._videoEnabled(true);
this.emit('videoOn');
};
// Combined controls
WebRTC.prototype.pause = function () {
this.mute();
this.pauseVideo();
};
WebRTC.prototype.resume = function () {
this.unmute();
this.resumeVideo();
};
// Internal methods for enabling/disabling audio/video
WebRTC.prototype._audioEnabled = function (bool) {
this.localStream.getAudioTracks().forEach(function (track) {
track.enabled = !!bool;
});
};
WebRTC.prototype._videoEnabled = function (bool) {
this.localStream.getVideoTracks().forEach(function (track) {
track.enabled = !!bool;
});
};
WebRTC.prototype.shareScreen = function () {
var self = this,
peer;
if (screenSharingSupport) {
getUserMedia({
video: {
mandatory: {
chromeMediaSource: 'screen'
}
}
}, function (stream) {
var item,
el = document.createElement('video'),
container = self.getRemoteVideoContainer();
self.localScreen = stream;
el.id = 'localScreen';
attachMediaStream(el, stream);
if (container) {
container.appendChild(el);
}
self.emit('videoAdded', el);
self.connection.emit('shareScreen');
self.peers.forEach(function (existingPeer) {
var peer;
if (existingPeer.type === 'video') {
peer = self.createPeer({
id: existingPeer.id,
type: 'screen',
sharemyscreen: true
});
peer.start();
}
});
}, function () {
throw new Error('Failed to access to screen media.');
});
}
};
WebRTC.prototype.stopScreenShare = function () {
this.connection.emit('unshareScreen');
var videoEl = document.getElementById('localScreen'),
container = this.getRemoteVideoContainer(),
stream = this.localScreen;
if (container && videoEl) {
container.removeChild(videoEl);
}
this.localScreen.stop();
this.peers.forEach(function (peer) {
if (peer.broadcaster) {
peer.end();
// a hack to emit the event the removes the video
// element that we want
peer.emit('videoRemoved', videoEl);
}
});
delete this.localScreen;
};
WebRTC.prototype.removeForPeerSession = function (id, type) {
this.getPeers(id, type).forEach(function (peer) {
peer.end();
});
};
// fetches all Peer objects by session id and/or type
WebRTC.prototype.getPeers = function (sessionId, type) {
return this.peers.filter(function (peer) {
return (!sessionId || peer.id === sessionId) && (!type || peer.type === type);
});
};
function Peer(options) {
var self = this;
this.id = options.id;
this.parent = options.parent;
this.type = options.type || 'video';
this.oneway = options.oneway || false;
this.sharemyscreen = options.sharemyscreen || false;
this.stream = options.stream;
// Create an RTCPeerConnection via the polyfill
this.pc = new RTCPeerConnection(this.parent.config.peerConnectionConfig, this.parent.config.peerConnectionContraints);
this.pc.onicecandidate = this.onIceCandidate.bind(this);
if (options.type === 'screen') {
if (this.parent.localScreen && this.sharemyscreen) {
logger.log('adding local screen stream to peer connection')
this.pc.addStream(this.parent.localScreen);
this.broadcaster = this.parent.connection.socket.sessionid;
}
} else {
this.pc.addStream(this.parent.localStream);
}
this.pc.onaddstream = this.handleRemoteStreamAdded.bind(this);
this.pc.onremovestream = this.handleStreamRemoved.bind(this);
// for re-use
this.mediaConstraints = {
mandatory: {
OfferToReceiveAudio: true,
OfferToReceiveVideo: true
}
};
WildEmitter.call(this);
// proxy events to parent
this.on('*', function (name, value) {
self.parent.emit(name, value, self);
});
}
Peer.prototype = Object.create(WildEmitter.prototype, {
constructor: {
value: Peer
}
});
Peer.prototype.handleMessage = function (message) {
if (message.type === 'offer') {
logger.log('setting remote description');
this.pc.setRemoteDescription(new RTCSessionDescription(message.payload));
this.answer();
} else if (message.type === 'answer') {
logger.log('setting answer');
this.pc.setRemoteDescription(new RTCSessionDescription(message.payload));
} else if (message.type === 'candidate') {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.payload.label,
candidate: message.payload.candidate
});
this.pc.addIceCandidate(candidate);
}
};
Peer.prototype.send = function (type, payload) {
this.parent.connection.emit('message', {
to: this.id,
broadcaster: this.broadcaster,
roomType: this.type,
type: type,
payload: payload
});
};
Peer.prototype.onIceCandidate = function (event) {
if (this.closed) return;
if (event.candidate) {
this.send('candidate', {
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate
});
} else {
logger.log("End of candidates.");
}
};
Peer.prototype.start = function () {
var self = this;
this.pc.createOffer(function (sessionDescription) {
logger.log('setting local description');
self.pc.setLocalDescription(sessionDescription);
logger.log('sending offer', sessionDescription);
self.send('offer', sessionDescription);
}, null, this.mediaConstraints);
};
Peer.prototype.end = function () {
this.pc.close();
this.handleStreamRemoved();
};
Peer.prototype.answer = function () {
var self = this;
logger.log('answer called');
this.pc.createAnswer(function (sessionDescription) {
logger.log('setting local description');
self.pc.setLocalDescription(sessionDescription);
logger.log('sending answer', sessionDescription);
self.send('answer', sessionDescription);
}, null, this.mediaConstraints);
};
Peer.prototype.handleRemoteStreamAdded = function (event) {
var stream = this.stream = event.stream,
el = document.createElement('video'),
container = this.parent.getRemoteVideoContainer();
el.id = this.getDomId();
attachMediaStream(el, stream);
if (container) container.appendChild(el);
this.emit('videoAdded', el);
};
Peer.prototype.handleStreamRemoved = function () {
var video = document.getElementById(this.getDomId()),
container = this.parent.getRemoteVideoContainer();
if (video && container) {
container.removeChild(video);
this.emit('videoRemoved', video);
}
this.parent.peers.splice(this.parent.peers.indexOf(this), 1);
this.closed = true;
};
Peer.prototype.getDomId = function () {
return [this.id, this.type, this.broadcaster ? 'broadcasting' : 'incoming'].join('_');
};
// expose WebRTC
window.WebRTC = WebRTC;
}());

BIN
public/smoke.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

3325
public/socket.io.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,135 @@
/*
SoundEffectManager
Loads and plays sound effects useing
HTML5 Web Audio API (as only available in webkit, at the moment).
By @HenrikJoreteg from &yet
*/
/*global webkitAudioContext define*/
(function () {
var root = this;
function SoundEffectManager() {
this.support = !!window.webkitAudioContext;
if (this.support) {
this.context = new webkitAudioContext();
}
this.sounds = {};
}
// async load a file at a given URL, store it as 'name'.
SoundEffectManager.prototype.loadFile = function (url, name, delay) {
if (this.support) {
this._loadWebAudioFile(url, name, delay);
} else {
this._loadWaveFile(url.replace('.mp3', '.wav'), name, delay);
}
};
// async load a file at a given URL, store it as 'name'.
SoundEffectManager.prototype._loadWebAudioFile = function (url, name, delay) {
if (!this.support) return;
var self = this,
request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
request.onload = function () {
self.sounds[name] = self.context.createBuffer(request.response, true);
};
setTimeout(function () {
request.send();
}, delay || 0);
};
SoundEffectManager.prototype._loadWaveFile = function (url, name, delay, multiplexLimit) {
var self = this,
limit = multiplexLimit || 3;
setTimeout(function () {
var a, i = 0;
self.sounds[name] = [];
while (i < limit) {
a = new Audio();
a.src = url;
a.load();
self.sounds[name][i++] = a;
}
}, delay || 0);
};
SoundEffectManager.prototype._playWebAudio = function (soundName) {
var buffer = this.sounds[soundName],
source;
if (!buffer) return;
// creates a sound source
source = this.context.createBufferSource();
// tell the source which sound to play
source.buffer = buffer;
// connect the source to the context's destination (the speakers)
source.connect(this.context.destination);
// play it
source.noteOn(0);
};
SoundEffectManager.prototype._playWavAudio = function (soundName, loop) {
var self = this,
audio = this.sounds[soundName],
howMany = audio && audio.length || 0,
i = 0,
currSound;
if (!audio) return;
while (i < howMany) {
currSound = audio[i++];
// this covers case where we loaded an unplayable file type
if (currSound.error) return;
if (currSound.currentTime === 0 || currSound.currentTime === currSound.duration) {
currSound.currentTime = 0;
currSound.loop = !!loop;
i = howMany;
return currSound.play();
}
}
};
SoundEffectManager.prototype.play = function (soundName, loop) {
if (this.support) {
this._playWebAudio(soundName, loop);
} else {
return this._playWavAudio(soundName, loop);
}
};
SoundEffectManager.prototype.stop = function (soundName) {
if (this.support) {
// TODO: this
} else {
var soundArray = this.sounds[soundName],
howMany = soundArray && soundArray.length || 0,
i = 0,
currSound;
while (i < howMany) {
currSound = soundArray[i++];
currSound.pause();
currSound.currentTime = 0;
}
}
};
// attach to window or export with commonJS
if (typeof module !== "undefined") {
module.exports = SoundEffectManager;
} else if (typeof root.define === "function" && define.amd) {
root.define(SoundEffectManager);
} else {
root.SoundEffectManager = SoundEffectManager;
}
})();

BIN
public/ss-standard.eot Executable file

Binary file not shown.

334
public/ss-standard.svg Executable file
View File

@ -0,0 +1,334 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata></metadata>
<defs>
<font id="SSStandard" >
<font-face font-family="SS Standard" units-per-em="864" ascent="918" descent="-270" />
<missing-glyph d="M0 864h864v-864h-864v864zM680 756h-496l248 -248zM108 680v-496l248 248zM184 108h496l-248 248zM756 184v496l-248 -248z" />
<glyph horiz-adv-x="864" d="M0 864h864v-864h-864v864zM680 756h-496l248 -248zM108 680v-496l248 248zM184 108h496l-248 248zM756 184v496l-248 -248z" />
<glyph unicode="+" horiz-adv-x="864" d="M522 0h-180q-8 0 -13 5t-5 13v306h-306q-8 0 -13 5t-5 13v180q0 8 5 13t13 5h306v306q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-306h306q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-306v-306q0 -8 -5 -13t-13 -5z" />
<glyph unicode="-" horiz-adv-x="864" d="M846 324h-828q-8 0 -13 5t-5 13v180q0 8 5 13t13 5h828q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5z" />
<glyph unicode="&#x201c;" horiz-adv-x="864" d="M702 378h108q22 0 38 -16t16 -38v-216q0 -22 -16 -38t-38 -16h-270q-22 0 -38 16t-16 38v270q0 190 99.5 311t260.5 121q8 0 13 -5t5 -13v-163q0 -16 -16 -18q-70 -5 -108 -65t-38 -168zM216 378h108q22 0 38 -16t16 -38v-216q0 -22 -16 -38t-38 -16h-270q-22 0 -38 16
t-16 38v270q0 190 99.5 311t260.5 121q8 0 13 -5t5 -13v-163q0 -16 -16 -18q-70 -5 -108 -65t-38 -168z" />
<glyph unicode="&#x2026;" horiz-adv-x="864" d="M324 432q0 45 31.5 76.5t76.5 31.5t76.5 -31.5t31.5 -76.5t-31.5 -76.5t-76.5 -31.5t-76.5 31.5t-31.5 76.5zM0 432q0 45 31.5 76.5t76.5 31.5t76.5 -31.5t31.5 -76.5t-31.5 -76.5t-76.5 -31.5t-76.5 31.5t-31.5 76.5zM648 432q0 45 31.5 76.5t76.5 31.5t76.5 -31.5
t31.5 -76.5t-31.5 -76.5t-76.5 -31.5t-76.5 31.5t-31.5 76.5z" />
<glyph unicode="&#x2139;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM486 162v306h-108v-306h108zM432 558q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21z" />
<glyph unicode="&#x21a9;" horiz-adv-x="864" d="M830 171q-47 59 -152 88t-246 29v-162q0 -11 -10 -16q-6 -2 -8 -2q-7 0 -11 4l-396 306q-7 5 -7 14t7 14l396 306q9 7 19 2t10 -16v-162q200 0 312.5 -106t119.5 -291q0 -13 -14 -17h-4q-7 0 -16 9z" />
<glyph unicode="&#x21aa;" horiz-adv-x="864" d="M34 171q-9 -9 -16 -9h-4q-14 4 -14 17q7 185 119.5 291t312.5 106v162q0 11 10 16t19 -2l396 -306q7 -5 7 -14t-7 -14l-396 -306q-4 -4 -11 -4q-2 0 -8 2q-10 5 -10 16v162q-141 0 -246 -29t-152 -88z" />
<glyph unicode="&#x21ba;" horiz-adv-x="864" d="M828 432q0 -164 -116 -280t-280 -116q-153 0 -266 103h-1v1q-5 5 -5 12q0 8 4 12l1 1l77 77q12 12 24 0q72 -62 166 -62q104 0 178 74t74 178t-74 178t-178 74q-95 0 -165 -62l106 -105q8 -8 4 -20q-5 -11 -17 -11h-342q-8 0 -13 5t-5 13v342q0 12 11 17q12 4 20 -4
l134 -135q114 104 267 104q164 0 280 -116t116 -280z" />
<glyph unicode="&#x21bb;" horiz-adv-x="864" d="M864 846v-342q0 -8 -5 -13t-13 -5h-342q-12 0 -17 11q-4 12 4 20l106 105q-70 62 -165 62q-104 0 -178 -74t-74 -178t74 -178t178 -74q93 0 166 62q12 12 24 0l77 -77v-1q5 -4 5 -12q0 -7 -5 -12q0 -1 -1 -1q-113 -103 -266 -103q-164 0 -280 116t-116 280t116 280
t280 116q153 0 267 -104l134 135q8 8 20 4q11 -5 11 -17z" />
<glyph unicode="&#x21c6;" horiz-adv-x="864" d="M841 635l-162 -162q-8 -8 -20 -4q-11 5 -11 17v90h-576q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h576v90q0 12 11 17q12 4 20 -4l162 -162q13 -13 0 -26zM810 270v-108q0 -8 -5 -13t-13 -5h-576v-90q0 -12 -11 -17q-12 -4 -20 4l-162 162q-13 13 0 26l162 162q8 8 20 4
q11 -5 11 -17v-90h576q8 0 13 -5t5 -13z" />
<glyph unicode="&#x22c6;" horiz-adv-x="864" d="M859 509l-210 -209l53 -279q2 -12 -8 -18q-4 -3 -10 -3t-10 3l-242 156l-242 -156q-10 -7 -20 0q-10 6 -8 18l53 279l-210 209q-8 8 -4 20q5 11 17 11h276l121 312q5 12 17 12t17 -12l121 -312h276q12 0 17 -11q4 -12 -4 -20z" />
<glyph unicode="&#x2302;" horiz-adv-x="864" d="M863 425q-5 -11 -17 -11h-90v-396q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v306h-216v-306q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v396h-90q-12 0 -17 11q-3 11 4 20l414 414q13 13 26 0l414 -414q7 -9 4 -20z" />
<glyph unicode="&#x2316;" horiz-adv-x="864" d="M846 486q8 0 13 -5t5 -13v-72q0 -8 -5 -13t-13 -5h-95q-16 -102 -89.5 -175.5t-175.5 -90.5v-94q0 -8 -5 -13t-13 -5h-72q-8 0 -13 5t-5 13v94q-102 17 -175.5 90.5t-90.5 175.5h-94q-8 0 -13 5t-5 13v72q0 8 5 13t13 5h94q17 102 90.5 175.5t175.5 89.5v95q0 8 5 13
t13 5h72q8 0 13 -5t5 -13v-95q102 -17 175 -90t90 -175h95zM432 216q89 0 152.5 63.5t63.5 152.5t-63.5 152.5t-152.5 63.5t-152.5 -63.5t-63.5 -152.5t63.5 -152.5t152.5 -63.5z" />
<glyph unicode="&#x232b;" horiz-adv-x="864" d="M810 756q22 0 38 -16t16 -38v-540q0 -22 -16 -38t-38 -16h-502q-6 0 -13 5l-279 281q-16 16 -16 38t16 38l279 281q7 5 13 5h502zM756 288l-144 144l144 144l-72 72l-144 -144l-144 144l-72 -72l144 -144l-144 -144l72 -72l144 144l144 -144z" />
<glyph unicode="&#x2399;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-432q0 -22 -16 -38t-38 -16h-90v180h-576v-180h-90q-22 0 -38 16t-16 38v432q0 22 16 38t38 16h756zM702 648q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16zM216 432v-414q0 -8 5 -13t13 -5h396q8 0 13 5t5 13v414h-432z
" />
<glyph unicode="&#x23cf;" horiz-adv-x="864" d="M18 0q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h828q8 0 13 -5t5 -13v-108q0 -8 -5 -13t-13 -5h-828zM18 324q-11 0 -16 10q-5 11 2 19l414 504q4 7 14 7q8 0 14 -7l414 -504q4 -4 4 -11q0 -2 -2 -8q-5 -10 -16 -10h-828z" />
<glyph unicode="&#x23e9;" horiz-adv-x="864" d="M864 432q0 -10 -7 -14l-504 -414q-8 -7 -19 -2q-10 5 -10 16v228l-295 -242q-8 -7 -19 -2q-10 5 -10 16v828q0 11 10 16q6 2 8 2q7 0 11 -4l295 -242v228q0 11 10 16q6 2 8 2q7 0 11 -4l504 -414q7 -6 7 -14z" />
<glyph unicode="&#x23ea;" horiz-adv-x="864" d="M0 432q0 8 7 14l504 414q4 4 11 4q2 0 8 -2q10 -5 10 -16v-228l295 242q4 4 11 4q2 0 8 -2q10 -5 10 -16v-828q0 -11 -10 -16q-11 -5 -19 2l-295 242v-228q0 -11 -10 -16q-11 -5 -19 2l-504 414q-7 4 -7 14z" />
<glyph unicode="&#x23ed;" horiz-adv-x="864" d="M666 846q0 8 5 13t13 5h108q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v828zM54 846q0 11 10 16q11 5 19 -2l504 -414q7 -6 7 -14q0 -10 -7 -14l-504 -414q-4 -4 -11 -4q-2 0 -8 2q-10 5 -10 16v828z" />
<glyph unicode="&#x23ee;" horiz-adv-x="864" d="M198 846v-828q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v828q0 8 5 13t13 5h108q8 0 13 -5t5 -13zM810 846v-828q0 -11 -10 -16q-6 -2 -8 -2q-7 0 -11 4l-504 414q-7 4 -7 14q0 8 7 14l504 414q8 7 19 2q10 -5 10 -16z" />
<glyph unicode="&#x23f1;" horiz-adv-x="864" d="M805 648l-60 -59q65 -95 65 -211q0 -157 -110.5 -267.5t-267.5 -110.5t-267.5 110.5t-110.5 267.5q0 127 76 227t194 135v106q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-106q58 -17 103 -49l60 59q13 12 25 0l77 -77q13 -13 0 -25zM504 378v270h-72l-70 -254q-2 -10 -2 -16
q0 -30 21 -51t51 -21t51 21t21 51z" />
<glyph unicode="&#x23f2;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM623 241l51 51l-176 176l-66 288h-72v-324q0 -30 21 -51q4 -4 12 -10z" />
<glyph unicode="&#x2421;" horiz-adv-x="864" d="M806 211q5 -7 5 -13t-5 -13l-127 -127q-7 -5 -13 -5t-13 5l-221 221l-221 -221q-7 -5 -13 -5t-13 5l-127 127q-5 7 -5 13t5 13l221 221l-221 221q-5 7 -5 13t5 13l127 127q7 5 13 5t13 -5l221 -221l221 221q7 5 13 5t13 -5l127 -127q5 -7 5 -13t-5 -13l-221 -221z" />
<glyph unicode="&#x25a0;" horiz-adv-x="864" d="M864 18q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v828q0 8 5 13t13 5h828q8 0 13 -5t5 -13v-828z" />
<glyph unicode="&#x25b4;" horiz-adv-x="864" d="M860 191q7 -8 2 -19q-5 -10 -16 -10h-828q-11 0 -16 10q-5 11 2 19l414 504q4 7 14 7q8 0 14 -7z" />
<glyph unicode="&#x25b6;" horiz-adv-x="864" d="M18 0q-5 0 -10 3q-8 5 -8 15v828q0 10 8 15q9 6 18 1l828 -414q10 -5 10 -16t-10 -16l-828 -414q-6 -2 -8 -2z" />
<glyph unicode="&#x25b9;" horiz-adv-x="864" d="M191 860l504 -414q7 -6 7 -14q0 -10 -7 -14l-504 -414q-8 -7 -19 -2q-10 5 -10 16v828q0 11 10 16q11 5 19 -2z" />
<glyph unicode="&#x25bb;" horiz-adv-x="864" d="M288 864q6 0 13 -5l414 -414q13 -13 0 -26l-414 -414q-13 -13 -26 0l-126 126q-13 13 0 26l275 275l-275 275q-13 13 0 26l126 126q7 5 13 5z" />
<glyph unicode="&#x25be;" horiz-adv-x="864" d="M860 673l-414 -504q-6 -7 -14 -7q-10 0 -14 7l-414 504q-7 8 -2 19q5 10 16 10h828q11 0 16 -10q5 -11 -2 -19z" />
<glyph unicode="&#x25c3;" horiz-adv-x="864" d="M673 860q8 7 19 2q10 -5 10 -16v-828q0 -11 -10 -16q-11 -5 -19 2l-504 414q-7 4 -7 14q0 8 7 14z" />
<glyph unicode="&#x25c5;" horiz-adv-x="864" d="M576 0q-6 0 -13 5l-414 414q-13 13 0 26l414 414q13 13 26 0l126 -126q13 -13 0 -26l-276 -275l276 -275q13 -13 0 -26l-126 -126q-7 -5 -13 -5z" />
<glyph unicode="&#x25ce;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM432 144q119 0 203.5 84.5t84.5 203.5t-84.5 203.5t-203.5 84.5t-203.5 -84.5t-84.5 -203.5t84.5 -203.5t203.5 -84.5zM288 432
q0 -60 42 -102t102 -42q59 0 101.5 42t42.5 102q0 59 -42.5 101.5t-101.5 42.5q-60 0 -102 -42.5t-42 -101.5z" />
<glyph unicode="&#x25cf;" horiz-adv-x="864" d="M864 432q0 -179 -126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5t305.5 -126.5t126.5 -305.5z" />
<glyph unicode="&#x2601;" horiz-adv-x="864" d="M864 324q0 -89 -63.5 -152.5t-152.5 -63.5h-459q-78 0 -133.5 55.5t-55.5 133.5q0 71 46.5 124t115.5 63v2q0 112 79 191t191 79q99 0 174 -63.5t92 -158.5q72 -17 119 -75.5t47 -134.5z" />
<glyph unicode="&#x2665;" horiz-adv-x="864" d="M744 357l-299 -300q-7 -5 -13 -5q-8 0 -13 5l-299 300q-70 70 -99.5 142t-18 133t57.5 107q68 68 165 68t165 -68q25 -25 42 -56q17 31 42 56q68 69 165 69t166 -69q46 -46 57 -107t-18.5 -133t-99.5 -142z" />
<glyph unicode="&#x266b;" horiz-adv-x="864" d="M864 820v-496q0 -79 -54.5 -137.5t-134.5 -73.5q-78 -16 -133.5 15.5t-55.5 91.5t56 115.5t133 70.5q42 8 73 8h26v216l-396 -90v-324q0 -79 -54.5 -137.5t-134.5 -73.5q-78 -16 -133.5 15.5t-55.5 91.5t56 115.5t133 70.5q42 8 73 8h26v388q0 22 15.5 41.5t37.5 24.5
l470 103q22 5 37.5 -8t15.5 -35z" />
<glyph unicode="&#x2691;" horiz-adv-x="864" d="M756 798v-392q0 -9 -10 -16q-57 -30 -125 -30q-61 0 -189 36t-189 36q-5 0 -14 -0.5t-13 -0.5v-413q0 -8 -5 -13t-13 -5h-72q-8 0 -13 5t-5 13v800q0 10 9 15q56 31 126 31q61 0 189 -36t189 -36q60 0 110 23q10 4 17 -2q8 -5 8 -15z" />
<glyph unicode="&#x2699;" horiz-adv-x="864" d="M752 382l83 -72q10 -7 5 -19q-25 -77 -82 -142q-8 -10 -19 -5l-104 36q-40 -32 -86 -50l-21 -108q-2 -12 -14 -14q-43 -8 -82 -8t-82 8q-12 2 -14 14l-21 108q-49 19 -86 50l-104 -36q-11 -5 -19 5q-57 65 -82 142q-5 12 5 19l83 72q-4 21 -4 50t4 50l-83 72q-10 7 -5 19
q25 77 82 142q8 10 19 5l104 -36q37 31 86 50l21 108q2 12 14 14q82 17 164 0q12 -2 14 -14l21 -108q46 -18 86 -50l104 36q11 5 19 -5q57 -65 82 -142q5 -12 -5 -19l-83 -72q4 -21 4 -50t-4 -50zM432 270q67 0 114.5 47.5t47.5 114.5t-47.5 114.5t-114.5 47.5t-114.5 -47.5
t-47.5 -114.5q0 -68 47 -115t115 -47z" />
<glyph unicode="&#x26a0;" horiz-adv-x="864" d="M854 130q23 -45 -3 -87q-27 -43 -77 -43h-684q-50 0 -77 43q-25 41 -4 87l342 684q26 50 81 50q56 0 80 -50zM378 630v-306h108v306h-108zM432 90q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21z" />
<glyph unicode="&#x26d4;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM108 324h648v216h-648v-216z" />
<glyph unicode="&#x2709;" horiz-adv-x="864" d="M432 378l-432 324q0 22 16 38t38 16h756q22 0 38 -16t16 -38zM432 281l432 324v-443q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v443z" />
<glyph unicode="&#x270e;" horiz-adv-x="864" d="M702 540l-162 162l-445 -445q-2 -2 -4 -6l-90 -226q-4 -12 4 -20q7 -5 13 -5q4 0 7 1l226 90q4 2 6 4zM848 763q16 -17 16 -39t-16 -38l-92 -92l-162 162l92 92q16 16 38 16t39 -16z" />
<glyph unicode="&#x2710;" horiz-adv-x="864" d="M162 324l445 445q3 3 6 4l226 90q2 1 7 1q6 0 13 -5q8 -8 4 -20l-90 -226q-1 -3 -4 -6l-445 -445zM16 101q-16 16 -16 38.5t16 38.5l92 92l162 -162l-92 -92q-16 -16 -38.5 -16t-38.5 16z" />
<glyph unicode="&#x2713;" horiz-adv-x="864" d="M859 617l-522 -522q-7 -5 -13 -5t-13 5l-306 306q-13 13 0 26l126 126q13 13 26 0l167 -168l383 384q13 13 26 0l126 -126q13 -13 0 -26z" />
<glyph unicode="&#x2753;" horiz-adv-x="864" d="M432 864q178 0 305 -127t127 -305q0 -179 -126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM432 108q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21zM486 360q0 14 15 27t36 25.5t42 29t36 46.5t15 70q0 79 -57 129.5
t-141 50.5q-48 0 -93 -22.5t-66 -45.5l-21 -22l72 -72q6 6 16.5 15t39 24t52.5 15q39 0 64.5 -22t25.5 -50q0 -24 -22.5 -43.5t-49.5 -33t-49.5 -40.5t-22.5 -63v-36h108v18z" />
<glyph unicode="&#x27a1;" horiz-adv-x="864" d="M463 841l396 -396q5 -7 5 -13t-5 -13l-396 -396q-8 -8 -20 -4q-11 5 -11 17v234h-414q-8 0 -13 5t-5 13v288q0 8 5 13t13 5h414v234q0 12 11 17q12 4 20 -4z" />
<glyph unicode="&#x2922;" horiz-adv-x="864" d="M457 305l-152 -153l121 -121q6 -4 6 -13q0 -8 -5 -13t-13 -5h-396q-8 0 -13 5t-5 13v396q0 12 11 17q12 4 20 -4l121 -122l153 152q13 13 25 0l127 -127q6 -4 6 -13q0 -7 -6 -12zM864 846v-396q0 -12 -11 -17q-2 -1 -7 -1q-6 0 -13 5l-121 122l-153 -153q-5 -5 -12 -5
q-8 0 -13 5l-128 128q-12 12 0 25l153 153l-122 121q-8 8 -4 20q5 11 17 11h396q8 0 13 -5t5 -13z" />
<glyph unicode="&#x2b05;" horiz-adv-x="864" d="M401 23l-396 396q-5 7 -5 13t5 13l396 396q8 8 20 4q11 -5 11 -17v-234h414q8 0 13 -5t5 -13v-288q0 -8 -5 -13t-13 -5h-414v-234q0 -12 -11 -17q-12 -4 -20 4z" />
<glyph unicode="&#x2b06;" horiz-adv-x="864" d="M23 463l396 396q7 5 13 5t13 -5l396 -396q8 -8 4 -20q-5 -11 -17 -11h-234v-414q0 -8 -5 -13t-13 -5h-288q-8 0 -13 5t-5 13v414h-234q-12 0 -17 11q-4 12 4 20z" />
<glyph unicode="&#x2b07;" horiz-adv-x="864" d="M841 401l-396 -396q-7 -5 -13 -5t-13 5l-396 396q-8 8 -4 20q5 11 17 11h234v414q0 8 5 13t13 5h288q8 0 13 -5t5 -13v-414h234q12 0 17 -11q4 -12 -4 -20z" />
<glyph unicode="&#x2b08;" horiz-adv-x="864" d="M113 337l312 311l-186 185q-8 8 -4 20q5 11 17 11h594q8 0 13 -5t5 -13v-594q0 -12 -11 -17q-12 -4 -20 4l-185 186l-311 -312q-13 -13 -26 0l-198 198q-13 13 0 26z" />
<glyph unicode="&#x2b09;" horiz-adv-x="864" d="M751 337q13 -13 0 -26l-198 -198q-13 -13 -26 0l-311 312l-185 -186q-8 -8 -20 -4q-11 5 -11 17v594q0 8 5 13t13 5h594q12 0 17 -11q4 -12 -4 -20l-186 -185z" />
<glyph unicode="&#x2b0a;" horiz-adv-x="864" d="M113 527q-13 13 0 26l198 198q13 13 26 0l311 -312l185 186q8 8 20 4q11 -5 11 -17v-594q0 -8 -5 -13t-13 -5h-594q-12 0 -17 11q-4 12 4 20l186 185z" />
<glyph unicode="&#x2b0b;" horiz-adv-x="864" d="M751 527l-312 -311l186 -185q8 -8 4 -20q-5 -11 -17 -11h-594q-8 0 -13 5t-5 13v594q0 12 11 17q12 4 20 -4l185 -186l311 312q13 13 26 0l198 -198q13 -13 0 -26z" />
<glyph unicode="&#xe001;" horiz-adv-x="864" d="M701 335q-5 -11 -17 -11h-225l126 -257q9 -16 -8 -24l-81 -41q-16 -9 -24 8l-125 258l-154 -155q-7 -5 -13 -5q-5 0 -7 1q-11 5 -11 17v720q0 12 11 17q12 4 20 -4l504 -504q8 -8 4 -20z" />
<glyph unicode="&#xe002;" horiz-adv-x="864" d="M540 864q134 0 229 -95t95 -229t-95 -229t-229 -95q-95 0 -173 50l-244 -245q-21 -21 -51 -21t-51 21t-21 51t21 51l245 244q-50 78 -50 173q0 134 95 229t229 95zM720 486v108h-126v126h-108v-126h-126v-108h126v-126h108v126h126z" />
<glyph unicode="&#xe003;" horiz-adv-x="864" d="M540 864q134 0 229 -95t95 -229t-95 -229t-229 -95q-95 0 -173 50l-244 -245q-21 -21 -51 -21t-51 21t-21 51t21 51l245 244q-50 78 -50 173q0 134 95 229t229 95zM720 594h-360v-108h360v108z" />
<glyph unicode="&#xe070;" horiz-adv-x="864" d="M859 419l-162 -162q-7 -5 -13 -5q-5 0 -7 1q-11 5 -11 17v90h-162v-162h90q12 0 17 -11q4 -12 -4 -20l-162 -162q-7 -5 -13 -5t-13 5l-162 162q-8 8 -4 20q5 11 17 11h90v162h-162v-90q0 -12 -11 -17q-2 -1 -7 -1q-6 0 -13 5l-162 162q-13 13 0 26l162 162q8 8 20 4
q11 -5 11 -17v-90h162v162h-90q-12 0 -17 11q-4 12 4 20l162 162q13 13 26 0l162 -162q8 -8 4 -20q-5 -11 -17 -11h-90v-162h162v90q0 12 11 17q12 4 20 -4l162 -162q13 -13 0 -26z" />
<glyph unicode="&#xe071;" horiz-adv-x="864" d="M261 423l-166 -166q-2 -2 -4 -6l-90 -226q-4 -12 4 -20q7 -5 13 -5q4 0 7 1l226 90q4 2 6 4l166 166zM795 69q15 15 15 36.5t-15 37.5l-245 245l152 152l-162 162l-152 -152l-246 246q-16 15 -37.5 15t-36.5 -15q-15 -16 -15 -37.5t15 -36.5l653 -653q15 -15 37 -15
t37 15zM848 763q16 -17 16 -39t-16 -38l-92 -92l-162 162l92 92q16 16 38 16t39 -16z" />
<glyph unicode="&#xe0d0;" horiz-adv-x="864" d="M810 864q8 0 13 -5t5 -13v-72q0 -8 -5 -13t-13 -5h-756q-8 0 -13 5t-5 13v72q0 8 5 13t13 5h756zM108 684h648l-54 -668q-2 -16 -18 -16h-504q-16 0 -18 16z" />
<glyph unicode="&#xe100;" horiz-adv-x="864" d="M16 317q-16 16 -16 38.5t16 38.5l465 465q5 5 12 5h317q22 0 38 -16t16 -38v-317q0 -7 -5 -12l-465 -465q-16 -16 -38.5 -16t-38.5 16zM594 675q0 -34 23.5 -57.5t57.5 -23.5t57.5 23.5t23.5 57.5t-23.5 57.5t-57.5 23.5t-57.5 -23.5t-23.5 -57.5z" />
<glyph unicode="&#xe1a0;" horiz-adv-x="432" d="M432 52q-8 0 -13 5l-299 300q-70 70 -99.5 142t-18 133t57.5 107q68 68 165 68t165 -68q25 -25 42 -56v-631z" />
<glyph unicode="&#xe1a1;" horiz-adv-x="432" d="M432 159l-242 -156q-10 -7 -20 0q-10 6 -8 18l53 279l-210 209q-8 8 -4 20q5 11 17 11h276l121 312q5 12 17 12v-705z" />
<glyph unicode="&#xe200;" horiz-adv-x="864" d="M504 360l-144 144l-288 -288q-18 -18 -18 -54t-18 -54l-31 -31q-13 -13 0 -25l47 -47q12 -13 25 0l30 31l1 1q18 17 54 17t54 18zM468 648l179 179q37 37 89.5 37t90.5 -37q37 -38 37 -90.5t-37 -89.5l-179 -179l49 -48q13 -13 0 -26l-48 -47q-13 -13 -25 0l-277 277
q-13 12 0 25l47 48q13 13 26 0z" />
<glyph unicode="&#xe201;" horiz-adv-x="864" d="M702 90h-144v-72q0 -8 5 -13t13 -5h108q8 0 13 5t5 13v72zM18 702q-8 0 -13 -5t-5 -13v-108q0 -8 5 -13t13 -5h72v144h-72zM846 306q8 0 13 -5t5 -13v-108q0 -8 -5 -13t-13 -5h-666q-8 0 -13 5t-5 13v666q0 8 5 13t13 5h108q8 0 13 -5t5 -13v-144h378q8 0 13 -5t5 -13
v-378h144zM306 306h252v252h-252v-252z" />
<glyph unicode="&#xe202;" horiz-adv-x="864" d="M648 702v-90h-396q-45 0 -76.5 -31.5t-31.5 -76.5v-234h-90q-22 0 -38 16t-16 38v378q0 22 16 38t38 16h540q22 0 38 -16t16 -38zM864 486v-324q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v342q0 15 10.5 25.5t25.5 10.5h558q22 0 38 -16t16 -38z" />
<glyph unicode="&#xe240;" horiz-adv-x="864" d="M846 864q8 0 13 -5t5 -13v-504q0 -8 -5 -13t-13 -5h-234v108h144v324h-324v-144h-108v234q0 8 5 13t13 5h504zM522 0q8 0 13 5t5 13v504q0 8 -5 13t-13 5h-504q-8 0 -13 -5t-5 -13v-504q0 -8 5 -13t13 -5h504z" />
<glyph unicode="&#xe241;" horiz-adv-x="864" d="M864 846v-504q0 -8 -5 -13t-13 -5h-234v252q0 15 -10.5 25.5t-25.5 10.5h-252v234q0 8 5 13t13 5h504q8 0 13 -5t5 -13zM522 540q8 0 13 -5t5 -13v-504q0 -8 -5 -13t-13 -5h-504q-8 0 -13 5t-5 13v504q0 8 5 13t13 5h504zM108 108h324v324h-324v-324z" />
<glyph unicode="&#xe300;" horiz-adv-x="864" d="M487 143q-171 -117 -377 -142q-3 -1 -7 -1q-5 0 -7 1q-6 3 -10 10l-85 214q-5 16 9 23l236 118q10 6 21 -3zM864 761q0 -4 -1 -7q-36 -288 -238 -496l170 -169q15 -16 15 -37.5t-15 -36.5t-37 -15t-37 15l-653 653q-15 15 -15 36.5t15 37.5q15 15 36.5 15t37.5 -15
l380 -381q53 55 94 121l-115 115q-9 11 -3 21l118 236q7 14 23 9l214 -85q7 -4 9 -10q2 -4 2 -7z" />
<glyph unicode="&#xe310;" horiz-adv-x="864" d="M270 135q0 -56 -39.5 -95.5t-95.5 -39.5t-95.5 39.5t-39.5 95.5t39.5 95.5t95.5 39.5t95.5 -39.5t39.5 -95.5zM864 18q0 -8 -5 -13t-13 -5h-126q-8 0 -13 5t-5 13q0 139 -54 266t-145.5 218.5t-218.5 145.5t-266 54q-8 0 -13 5t-5 13v126q0 8 5 13t13 5
q230 0 424.5 -113.5t308 -308t113.5 -424.5zM594 18q0 -8 -5 -13t-13 -5h-126q-8 0 -13 5t-5 13q0 172 -121 293t-293 121q-8 0 -13 5t-5 13v126q0 8 5 13t13 5q117 0 223.5 -45.5t184 -123t123 -184t45.5 -223.5z" />
<glyph unicode="&#xe320;" horiz-adv-x="864" d="M486 702q22 0 38 -16t16 -38v-432q0 -22 -16 -38t-38 -16h-432q-22 0 -38 16t-16 38v432q0 22 16 38t38 16h432zM864 684v-504q0 -12 -11 -17q-2 -1 -7 -1q-6 0 -13 5l-226 227q-16 16 -16 38t16 38l226 227q8 8 20 4q11 -5 11 -17z" />
<glyph unicode="&#xe350;" horiz-adv-x="864" d="M864 844l-108 -828q-2 -10 -10 -14q-8 -5 -16 0l-275 137l-99 -132q-5 -7 -14 -7q-4 0 -6 1q-12 3 -12 17v180q0 7 4 11l393 506l-511 -441q-5 -4 -12 -4q-4 0 -8 2l-180 90q-10 5 -10 15q0 11 9 17l828 468q10 5 19 -1q10 -6 8 -17z" />
<glyph unicode="&#xe399;" horiz-adv-x="864" d="M432 810q179 0 305.5 -102.5t126.5 -248.5t-126.5 -248.5t-305.5 -102.5q-35 0 -73 5q-113 -113 -233 -113q-12 0 -17 11q-4 12 4 20q6 6 15.5 18t27 49t22.5 77q-83 49 -130.5 123.5t-47.5 160.5q0 146 126.5 248.5t305.5 102.5zM216 396q30 0 51 21t21 51t-21 51
t-51 21t-51 -21t-21 -51t21 -51t51 -21zM432 396q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21zM648 396q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21z" />
<glyph unicode="&#xe500;" horiz-adv-x="864" d="M252 90q0 38 26 64t64 26t64 -26t26 -64t-26 -64t-64 -26t-64 26t-26 64zM540 90q0 38 26 64t64 26t64 -26t26 -64t-26 -64t-64 -26t-64 26t-26 64zM863 680l-110 -369q-5 -18 -19 -29.5t-33 -11.5h-431q-19 0 -33.5 11.5t-18.5 29.5l-110 445h-54q-22 0 -38 16t-16 38
t16 38t38 16h96q19 0 34 -11.5t19 -29.5l30 -121h613q9 0 14 -7q6 -6 3 -15z" />
<glyph unicode="&#xe570;" horiz-adv-x="864" d="M756 378q0 -157 -110.5 -267.5t-267.5 -110.5t-267.5 110.5t-110.5 267.5t110.5 267.5t267.5 110.5v-378h378zM864 468q0 -8 -5 -13t-13 -5h-396v396q0 8 5 13t13 5q164 0 280 -116t116 -280z" />
<glyph unicode="&#xe602;" horiz-adv-x="864" d="M864 684v-666q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v828q0 8 5 13t13 5h162q8 0 13 -5t5 -13v-356l314 209q8 7 18 1q10 -5 10 -16v-182l296 197q8 7 18 1q10 -5 10 -16z" />
<glyph unicode="&#xe670;" horiz-adv-x="864" d="M450 0h-4q-14 4 -14 18v414h-414q-14 0 -18 14q-2 15 10 20l828 396q11 5 21 -3q8 -10 3 -21l-396 -828q-5 -10 -16 -10z" />
<glyph unicode="&#xe671;" horiz-adv-x="864" d="M748 3q-4 -3 -10 -3q-8 0 -12 4l-294 266l-294 -266q-11 -9 -22 -1q-12 8 -7 21l306 828q5 12 17 12t17 -12l306 -828q5 -13 -7 -21z" />
<glyph unicode="&#xe672;" horiz-adv-x="864" d="M859 311l-90 -90q-7 -5 -13 -5h-684q-8 0 -13 5t-5 13v180q0 8 5 13t13 5h288v90h144v-90h252q6 0 13 -5l90 -90q13 -13 0 -26zM810 792v-180q0 -8 -5 -13t-13 -5h-684q-6 0 -13 5l-90 90q-13 13 0 26l90 90q7 5 13 5h252v36q0 8 5 13t13 5h108q8 0 13 -5t5 -13v-36h288
q8 0 13 -5t5 -13zM504 144v-126q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v126h144z" />
<glyph unicode="&#xe673;" horiz-adv-x="864" d="M856 769q8 -5 8 -14v-612q0 -14 -13 -17l-270 -89q-1 -1 -5 -1q-5 0 -7 1l-282 105l-264 -88q-8 -3 -16 2q-7 7 -7 15v394q11 9 38 25l-38 62v131q0 12 12 17l270 91q6 1 12 0l282 -107l264 88q10 3 16 -3zM97 521q49 20 96 29l-13 71q-59 -11 -111 -34zM357 548l16 70
q-58 12 -116 11l2 -72q51 0 98 -9zM505 480l44 57q-48 37 -102 58l-27 -66q49 -21 85 -49zM554 436q17 -19 31.5 -38.5t20 -29.5t5.5 -11l33 16l32 15q-25 50 -69 97zM702 179q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21z" />
<glyph unicode="&#xe6d0;" horiz-adv-x="864" d="M432 864q119 0 203.5 -84.5t84.5 -203.5q0 -75 -37 -141l-235 -426q-5 -9 -16 -9t-16 9l-235 426q-37 63 -37 141q0 119 84.5 203.5t203.5 84.5zM432 468q45 0 76.5 31.5t31.5 76.5t-31.5 76.5t-76.5 31.5t-76.5 -31.5t-31.5 -76.5t31.5 -76.5t76.5 -31.5z" />
<glyph unicode="&#xe7a0;" horiz-adv-x="864" d="M756 252v-126q0 -47 -97 -86.5t-227 -39.5t-227 39.5t-97 86.5v126q113 -72 324 -72t324 72zM756 504v-144q0 -45 -95 -76.5t-229 -31.5t-229 31.5t-95 76.5v144q113 -72 324 -72t324 72zM756 756v-144q0 -45 -95 -76.5t-229 -31.5t-229 31.5t-95 76.5v144q0 45 95 76.5
t229 31.5t229 -31.5t95 -76.5z" />
<glyph unicode="&#xe7b0;" horiz-adv-x="864" d="M810 324q22 0 38 -16t16 -38v-216q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v216q0 22 16 38t38 16h756zM486 108q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16zM702 108q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16z
M791 818l64 -430q-22 8 -45 8h-756q-23 0 -45 -8l63 430q3 20 18.5 33t35.5 13h612q20 0 35 -13t18 -33z" />
<glyph unicode="&#xe800;" horiz-adv-x="864" d="M810 810q22 0 38 -16t16 -38v-540q0 -22 -16 -38t-38 -16h-89l-108 108h143v432h-648v-432h143l-108 -108h-89q-22 0 -38 16t-16 38v540q0 22 16 38t38 16h756zM684 54q12 0 17 11q4 12 -4 20l-252 252q-13 13 -26 0l-252 -252q-8 -8 -4 -20q5 -11 17 -11h504z" />
<glyph unicode="&#xe8a0;" horiz-adv-x="864" d="M306 0h-288q-8 0 -13 5t-5 13v828q0 8 5 13t13 5h288q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5zM846 0h-288q-8 0 -13 5t-5 13v828q0 8 5 13t13 5h288q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5z" />
<glyph unicode="&#xe9a0;" horiz-adv-x="864" d="M0 846q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM324 846q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM648 846q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5
h-180q-8 0 -13 5t-5 13v180zM0 522q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM324 522q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM648 522q0 8 5 13t13 5h180q8 0 13 -5t5 -13
v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM0 198q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM324 198q0 8 5 13t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180zM648 198q0 8 5 13
t13 5h180q8 0 13 -5t5 -13v-180q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v180z" />
<glyph unicode="&#xe9a1;" horiz-adv-x="864" d="M864 522v-180q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v180q0 8 5 13t13 5h828q8 0 13 -5t5 -13zM864 846v-180q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v180q0 8 5 13t13 5h828q8 0 13 -5t5 -13zM864 198v-180q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v180
q0 8 5 13t13 5h828q8 0 13 -5t5 -13z" />
<glyph unicode="&#xe9a2;" horiz-adv-x="864" d="M342 864h180q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v828q0 8 5 13t13 5zM18 864h180q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v828q0 8 5 13t13 5zM666 864h180q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5h-180
q-8 0 -13 5t-5 13v828q0 8 5 13t13 5z" />
<glyph unicode="&#xe9a3;" horiz-adv-x="864" d="M360 486h-342q-8 0 -13 5t-5 13v342q0 8 5 13t13 5h342q8 0 13 -5t5 -13v-342q0 -8 -5 -13t-13 -5zM846 486h-342q-8 0 -13 5t-5 13v342q0 8 5 13t13 5h342q8 0 13 -5t5 -13v-342q0 -8 -5 -13t-13 -5zM360 0h-342q-8 0 -13 5t-5 13v342q0 8 5 13t13 5h342q8 0 13 -5
t5 -13v-342q0 -8 -5 -13t-13 -5zM846 0h-342q-8 0 -13 5t-5 13v342q0 8 5 13t13 5h342q8 0 13 -5t5 -13v-342q0 -8 -5 -13t-13 -5z" />
<glyph unicode="&#xe9b0;" horiz-adv-x="864" d="M855 780l-315 -465v-297q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v297l-315 465q-18 26 -3 55q16 29 48 29h756q32 0 48 -29q15 -29 -3 -55z" />
<glyph unicode="&#xea00;" horiz-adv-x="864" d="M861 166q3 -3 3 -10v-84q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v84q0 7 3 10l51 77v513q0 22 16 38t38 16h648q22 0 38 -16t16 -38v-513zM162 702v-432h540v432h-540z" />
<glyph unicode="&#xea01;" horiz-adv-x="864" d="M702 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h540zM648 108v648h-432v-648h432z" />
<glyph unicode="&#xea10;" horiz-adv-x="864" d="M540 648v-432h-486q-22 0 -38 16t-16 38v324q0 22 16 38t38 16h486zM864 522v-180q0 -8 -5 -13t-13 -5h-90v-54q0 -22 -16 -38t-38 -16h-54v432h54q22 0 38 -16t16 -38v-54h90q8 0 13 -5t5 -13z" />
<glyph unicode="&#xea11;" horiz-adv-x="864" d="M378 648v-432h-324q-22 0 -38 16t-16 38v324q0 22 16 38t38 16h324zM864 522v-180q0 -8 -5 -13t-13 -5h-90v-54q0 -22 -16 -38t-38 -16h-54v432h54q22 0 38 -16t16 -38v-54h90q8 0 13 -5t5 -13z" />
<glyph unicode="&#xea12;" horiz-adv-x="864" d="M216 648v-432h-162q-22 0 -38 16t-16 38v324q0 22 16 38t38 16h162zM864 522v-180q0 -8 -5 -13t-13 -5h-90v-54q0 -22 -16 -38t-38 -16h-54v432h54q22 0 38 -16t16 -38v-54h90q8 0 13 -5t5 -13z" />
<glyph unicode="&#xea13;" horiz-adv-x="864" d="M108 648v-432h-54q-22 0 -38 16t-16 38v324q0 22 16 38t38 16h54zM864 522v-180q0 -8 -5 -13t-13 -5h-90v-54q0 -22 -16 -38t-38 -16h-54v432h54q22 0 38 -16t16 -38v-54h90q8 0 13 -5t5 -13z" />
<glyph unicode="&#xeb00;" horiz-adv-x="864" d="M864 324q0 -89 -63.5 -152.5t-152.5 -63.5h-182l186 185q8 8 4 20q-5 11 -17 11h-135v182h-144v-182h-135q-12 0 -17 -11q-4 -12 4 -20l186 -185h-209q-78 0 -133.5 55.5t-55.5 133.5q0 71 46.5 124t115.5 63v2q0 112 79 191t191 79q99 0 174 -63.5t92 -158.5
q72 -17 119 -75.5t47 -134.5z" />
<glyph unicode="&#xeb01;" horiz-adv-x="864" d="M792 0h-720q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h720q8 0 13 -5t5 -13v-108q0 -8 -5 -13t-13 -5zM805 581l-360 -360q-7 -5 -13 -5t-13 5l-360 360q-8 8 -4 20q5 11 17 11h198v234q0 8 5 13t13 5h288q8 0 13 -5t5 -13v-234h198q12 0 17 -11q4 -12 -4 -20z" />
<glyph unicode="&#xeb40;" horiz-adv-x="864" d="M864 324q0 -89 -63.5 -152.5t-152.5 -63.5h-144v162h135q12 0 17 11q4 12 -4 20l-220 219l-220 -219q-8 -8 -4 -20q5 -11 17 -11h135v-162h-171q-78 0 -133.5 55.5t-55.5 133.5q0 71 46.5 124t115.5 63v2q0 112 79 191t191 79q99 0 174 -63.5t92 -158.5q72 -17 119 -75.5
t47 -134.5z" />
<glyph unicode="&#xeb41;" horiz-adv-x="864" d="M792 0h-720q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h720q8 0 13 -5t5 -13v-108q0 -8 -5 -13t-13 -5zM59 499l360 360q7 5 13 5t13 -5l360 -360q8 -8 4 -20q-5 -11 -17 -11h-198v-234q0 -8 -5 -13t-13 -5h-288q-8 0 -13 5t-5 13v234h-198q-12 0 -17 11q-4 12 4 20z" />
<glyph unicode="&#xeb80;" horiz-adv-x="864" d="M697 823l162 -162q5 -7 5 -13t-5 -13l-162 -162q-8 -8 -20 -4q-11 5 -11 17v90h-171q-27 0 -43 -22l-92 -122l92 -122q16 -22 43 -22h171v90q0 12 11 17q12 4 20 -4l162 -162q5 -7 5 -13t-5 -13l-162 -162q-8 -8 -20 -4q-11 5 -11 17v90h-172q-98 0 -157 78l-87 116
q-16 22 -43 22h-189q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h189q27 0 43 22l87 116q59 78 157 78h172v90q0 12 11 17q12 4 20 -4z" />
<glyph unicode="&#xeb81;" horiz-adv-x="864" d="M859 419l-162 -162q-7 -5 -13 -5q-5 0 -7 1q-11 5 -11 17v90h-135q-27 0 -43 -22l-87 -116q-59 -78 -157 -78h-226q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h225q27 0 43 22l87 116q1 1 2.5 3t2.5 3q-1 1 -2.5 3t-2.5 3l-87 116q-16 22 -43 22h-225q-8 0 -13 5t-5 13v108
q0 8 5 13t13 5h226q98 0 157 -78l87 -116q16 -22 43 -22h135v90q0 12 11 17q12 4 20 -4l162 -162q13 -13 0 -26z" />
<glyph unicode="&#xeb82;" horiz-adv-x="864" d="M821 357v0q-27 -139 -136.5 -230t-252.5 -91q-153 0 -267 104l-134 -135q-7 -5 -13 -5q-5 0 -7 1q-11 5 -11 17v342q0 8 5 13t13 5h342q12 0 17 -11q4 -12 -4 -20l-106 -105q70 -62 165 -62q86 0 153 52t90 133q3 13 17 13h111q10 0 14 -7q5 -7 4 -14zM43 507v0
q26 138 135.5 229.5t253.5 91.5q153 0 267 -104l134 135q7 5 13 5q5 0 7 -1q11 -5 11 -17v-342q0 -8 -5 -13t-13 -5h-342q-12 0 -17 11q-4 12 4 20l106 105q-70 62 -165 62q-86 0 -153 -52t-90 -133q-3 -13 -17 -13h-111q-9 0 -14 6q-5 9 -4 15z" />
<glyph unicode="&#xeb83;" horiz-adv-x="864" d="M504 792v-126q0 -30 -21 -51t-51 -21t-51 21t-21 51v126q0 30 21 51t51 21t51 -21t21 -51zM504 198v-126q0 -30 -21 -51t-51 -21t-51 21t-21 51v126q0 30 21 51t51 21t51 -21t21 -51zM270 432q0 -30 -21 -51t-51 -21h-126q-30 0 -51 21t-21 51t21 51t51 21h126
q30 0 51 -21t21 -51zM864 432q0 -30 -21 -51t-51 -21h-126q-30 0 -51 21t-21 51t21 51t51 21h126q30 0 51 -21t21 -51zM317 547q-21 -22 -50.5 -22t-50.5 22l-90 89q-21 21 -21 50.5t21 50.5q22 22 51.5 22t50.5 -22l89 -89q22 -21 22 -50.5t-22 -50.5zM737 126
q-21 -21 -50.5 -21t-50.5 21l-89 90q-22 21 -22 50.5t22 50.5q21 22 50.5 22t50.5 -22l89 -89q22 -21 22 -50.5t-22 -51.5zM737 636l-89 -89q-21 -22 -50.5 -22t-50.5 22q-22 21 -22 50.5t22 50.5l89 89q21 22 50.5 22t50.5 -22q22 -21 22 -50.5t-22 -50.5zM317 216l-89 -90
q-21 -21 -50.5 -21t-51.5 21q-21 22 -21 51.5t21 50.5l90 89q21 22 50.5 22t50.5 -22q22 -21 22 -50.5t-22 -50.5z" />
<glyph unicode="&#xeb84;" horiz-adv-x="864" d="M858 536l-76 -76q-2 -2 -6 -4t-7 -2q-7 0 -12 6q-135 134 -325 134t-325 -134q-4 -6 -12 -6q-3 0 -7 2t-6 4l-76 76q-12 12 0 25q116 116 271 157.5t310 0t271 -157.5q12 -13 0 -25zM693 370l-76 -76q-2 -2 -6 -4q-2 -1 -7 -1q-8 0 -13 5q-66 66 -159 66t-159 -66
q-7 -5 -13 -5q-5 0 -7 1q-4 2 -6 4l-76 76q-13 13 0 26q108 108 261 108t261 -108q13 -13 0 -26zM527 205l-82 -83q-13 -13 -26 0l-83 83q-12 13 0 25q40 40 96 40t95 -40q13 -12 0 -25z" />
<glyph unicode="&#xeb85;" horiz-adv-x="864" d="M864 720q0 -39 -19.5 -72.5t-52.5 -52.5v-163q0 -30 -21 -51t-51 -21h-163q-19 -33 -52.5 -52.5t-72.5 -19.5t-72.5 19.5t-52.5 52.5h-91v-91q33 -19 52.5 -52.5t19.5 -72.5q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102q0 39 19.5 72.5t52.5 52.5v163q0 30 21 51
t51 21h163q19 33 52.5 52.5t72.5 19.5t72.5 -19.5t52.5 -52.5h91v91q-33 19 -52.5 52.5t-19.5 72.5q0 59 42 101.5t102 42.5q59 0 101.5 -42.5t42.5 -101.5z" />
<glyph unicode="&#xed00;" horiz-adv-x="864" d="M810 846v-126q0 -8 -5 -13t-13 -5h-252v-684q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v684h-252q-8 0 -13 5t-5 13v126q0 8 5 13t13 5h720q8 0 13 -5t5 -13z" />
<glyph unicode="&#xed01;" horiz-adv-x="864" d="M863 24q3 -9 -2 -17q-7 -7 -15 -7h-180q-14 0 -17 12l-48 150h-342l-48 -150q-3 -12 -17 -12h-176q-8 0 -15 7q-5 8 -2 17l282 828q3 12 17 12h264q12 0 17 -12zM310 324h239l-119 375z" />
<glyph unicode="&#xed50;" horiz-adv-x="864" d="M144 180v-108q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h108q8 0 13 -5t5 -13zM144 486v-108q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h108q8 0 13 -5t5 -13zM144 792v-108q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v108
q0 8 5 13t13 5h108q8 0 13 -5t5 -13zM864 180v-108q0 -8 -5 -13t-13 -5h-612q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h612q8 0 13 -5t5 -13zM864 486v-108q0 -8 -5 -13t-13 -5h-612q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h612q8 0 13 -5t5 -13zM864 792v-108q0 -8 -5 -13t-13 -5
h-612q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h612q8 0 13 -5t5 -13z" />
<glyph unicode="&#xeda0;" horiz-adv-x="864" d="M252 576v-558q0 -8 -5 -13t-13 -5h-216q-8 0 -13 5t-5 13v540q0 8 5 13t13 5h234zM864 558v-540q0 -8 -5 -13t-13 -5h-504q-8 0 -13 5t-5 13v558h522q8 0 13 -5t5 -13zM864 846v-180q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v180q0 8 5 13t13 5h828q8 0 13 -5t5 -13z
" />
<glyph unicode="&#xee00;" horiz-adv-x="864" d="M594 240l108 74v-116q0 -44 -32 -76t-76 -32h-486q-44 0 -76 32t-32 76v432q0 44 32 76t76 32h306v-44q-98 -15 -166 -64h-140v-432h486v42zM856 537q8 -6 8 -15q0 -10 -8 -15l-342 -234q-4 -3 -10 -3q-4 0 -8 2q-10 5 -10 16v127q-58 -1 -106.5 -9.5t-76 -18t-50 -23
t-28.5 -19t-11 -11.5l-1 -1q-5 -9 -15 -9h-4q-12 3 -14 17q0 121 72 197q80 86 234 91v127q0 11 10 16q10 6 18 -1z" />
<glyph unicode="&#xee01;" horiz-adv-x="864" d="M864 450q0 -8 -5 -13t-13 -5h-396q-8 0 -13 5t-5 13v396q0 12 11 17q12 4 20 -4l121 -122l122 122q12 13 25 0l128 -128q13 -13 0 -25l-122 -122l121 -121q6 -4 6 -13zM0 414q0 8 5 13t13 5h396q8 0 13 -5t5 -13v-396q0 -12 -11 -17q-12 -4 -20 4l-121 122l-122 -122
q-12 -13 -25 0l-128 128q-13 13 0 25l122 122l-121 121q-6 5 -6 13z" />
<glyph unicode="&#xee02;" horiz-adv-x="864" d="M756 846v-828q0 -8 -5 -13t-13 -5h-612q-8 0 -13 5t-5 13v342h162v-135q0 -12 11 -17q10 -4 20 4l219 220l-219 220q-9 8 -20 3q-11 -3 -11 -16v-135h-162v342q0 8 5 13t13 5h612q8 0 13 -5t5 -13z" />
<glyph unicode="&#xf000;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM432 540l-70 -362q-2 -10 -2 -16q0 -30 21 -51t51 -21t51 21t21 51v378h-72zM666 432h108q0 142 -100 242t-242 100q-139 0 -239 -97.5
t-103 -236.5q3 116 87 198t201 82q119 0 203.5 -84.5t84.5 -203.5z" />
<glyph unicode="&#xf070;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h72v-108q0 -22 16 -38t38 -16t38 16t16 38v108h396v-108q0 -22 16 -38t38 -16t38 16t16 38v108h72zM612 270v108h-126v126h-108v-126h-126v-108h126v-126h108v126
h126z" />
<glyph unicode="&#xf071;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h72v-108q0 -22 16 -38t38 -16t38 16t16 38v108h396v-108q0 -22 16 -38t38 -16t38 16t16 38v108h72zM612 270v108h-360v-108h360z" />
<glyph unicode="&#xf072;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h72v-108q0 -22 16 -38t38 -16t38 16t16 38v108h396v-108q0 -22 16 -38t38 -16t38 16t16 38v108h72zM378 140l290 290l-76 76l-214 -214l-106 106l-76 -76z" />
<glyph unicode="&#xf073;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h72v-108q0 -22 16 -38t38 -16t38 16t16 38v108h396v-108q0 -22 16 -38t38 -16t38 16t16 38v108h72zM594 234l-90 90l90 90l-72 72l-90 -90l-90 90l-72 -72l90 -90
l-90 -90l72 -72l90 90l90 -90z" />
<glyph unicode="&#xf4c0;" horiz-adv-x="864" d="M847 143q17 -23 17 -53q0 -38 -26 -64t-64 -26h-684q-54 0 -80 48q-25 48 5 92l273 402v304q0 8 5 13t13 5h252q8 0 13 -5t5 -13v-304zM324 144q30 0 51 21t21 51t-21 51t-51 21t-51 -21t-21 -51t21 -51t51 -21zM486 324q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38
t16 -38t38 -16z" />
<glyph unicode="&#xf500;" horiz-adv-x="864" d="M0 288q0 6 5 13l414 414q13 13 26 0l414 -414q13 -13 0 -26l-126 -126q-13 -13 -26 0l-275 275l-275 -275q-13 -13 -26 0l-126 126q-5 7 -5 13z" />
<glyph unicode="&#xf501;" horiz-adv-x="864" d="M864 576q0 -6 -5 -13l-414 -414q-13 -13 -26 0l-414 414q-13 13 0 26l126 126q13 13 26 0l275 -276l275 276q13 13 26 0l126 -126q5 -7 5 -13z" />
<glyph unicode="&#xf600;" horiz-adv-x="864" d="M675 126q0 -8 -5.5 -13t-12.5 -5h-387q-68 0 -115 47t-47 115v162h-90q-12 0 -17 11q-4 12 4 20l162 162q13 13 26 0l162 -162q8 -8 4 -20q-5 -11 -17 -11h-90v-162q0 -8 5 -13t13 -5h279q8 0 13 -5l109 -109q4 -4 4 -12zM859 401l-162 -162q-7 -5 -13 -5t-13 5l-162 162
q-8 8 -4 20q5 11 17 11h90v162q0 8 -5 13t-13 5h-279q-8 0 -13 5l-109 109q-4 4 -4 12t5.5 13t12.5 5h387q67 0 114.5 -47.5t47.5 -114.5v-162h90q12 0 17 -11q4 -12 -4 -20z" />
<glyph unicode="&#x1f304;" horiz-adv-x="864" d="M810 756q22 0 38 -16t16 -38v-540q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v540q0 22 16 38t38 16h756zM189 648q-34 0 -57.5 -23.5t-23.5 -57.5t23.5 -57.5t57.5 -23.5t57.5 23.5t23.5 57.5t-23.5 57.5t-57.5 23.5zM756 216l-216 324l-198 -252l-126 90
l-108 -162h648z" />
<glyph unicode="&#x1f30e;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM486 90q48 0 105 65t57 151q0 52 -37 89t-89 37h-72q-40 0 -65 18t-25 45q0 19 13 32t32 13t35 -18t28 -18q15 0 25.5 10.5t10.5 25.5
q0 36 -34 70q33 63 34 141q0 16 -15 18q-32 5 -57 5q-116 -4 -184 -56t-68 -142q0 -81 58.5 -139.5t139.5 -58.5h3q-3 -14 -3 -27q0 -41 25.5 -73t64.5 -41v-129q0 -8 5 -13t13 -5z" />
<glyph unicode="&#x1f3a4;" horiz-adv-x="864" d="M270 504v198q0 67 47.5 114.5t114.5 47.5t114.5 -47.5t47.5 -114.5v-198q0 -67 -47.5 -114.5t-114.5 -47.5q-68 0 -115 47t-47 115zM774 504q0 -127 -82.5 -222.5t-205.5 -115.5v-148q0 -8 -5 -13t-13 -5h-72q-8 0 -13 5t-5 13v148q-123 20 -205.5 115.5t-82.5 222.5
q0 22 16 38t38 16t38 -16t16 -38q0 -97 68.5 -165.5t165.5 -68.5t165.5 68.5t68.5 165.5q0 22 16 38t38 16t38 -16t16 -38z" />
<glyph unicode="&#x1f3e2;" horiz-adv-x="864" d="M234 0q8 0 13 5t5 13v504q0 8 -5 13t-13 5h-216q-8 0 -13 -5t-5 -13v-504q0 -8 5 -13t13 -5h216zM846 864q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5h-198v162h-108v-162h-198q-8 0 -13 5t-5 13v828q0 8 5 13t13 5h504zM540 324v108h-108v-108h108zM540 594v108h-108
v-108h108zM756 324v108h-108v-108h108zM756 594v108h-108v-108h108z" />
<glyph unicode="&#x1f440;" horiz-adv-x="864" d="M861 442q7 -10 0 -20q-8 -11 -22 -30t-59 -67t-92.5 -84.5t-117.5 -66.5t-138 -30t-137 28.5t-119.5 69.5t-91 82t-60.5 70l-21 28q-7 10 0 20q8 11 22 30t59 67t92.5 84.5t117.5 66.5t138 30t137 -28.5t119 -69t90 -80.5t60 -68l21 -29zM432 270q67 0 114.5 47.5
t47.5 114.5t-47.5 114.5t-114.5 47.5t-114.5 -47.5t-47.5 -114.5q0 -68 47 -115t115 -47z" />
<glyph unicode="&#x1f44d;" horiz-adv-x="864" d="M144 18q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v504q0 8 5 13t13 5h108q8 0 13 -5t5 -13v-504zM864 315q0 -52 -47 -74q11 -20 11 -43q0 -29 -17 -52.5t-44 -32.5q7 -14 7 -32q0 -34 -23.5 -57.5t-57.5 -23.5h-189q-54 0 -103 22l-185 86v378q154 103 203 170t49 154
q0 22 16 38t38 16q32 0 59 -40q31 -43 31 -104q0 -30 -8.5 -69t-17 -62.5t-9.5 -23.5q-3 -9 2 -17t15 -8h189q34 0 57.5 -23.5t23.5 -57.5q0 -50 -44 -72q44 -24 44 -72z" />
<glyph unicode="&#x1f44e;" horiz-adv-x="864" d="M144 846v-504q0 -8 -5 -13t-13 -5h-108q-8 0 -13 5t-5 13v504q0 8 5 13t13 5h108q8 0 13 -5t5 -13zM864 549q0 -50 -44 -72q44 -24 44 -72q0 -34 -23.5 -57.5t-57.5 -23.5h-189q-10 0 -15 -8t-2 -17q1 -1 9 -24t17 -62t9 -69q0 -60 -31 -105q-28 -39 -59 -39
q-22 0 -38 16t-16 38q0 87 -49 154t-203 170v378l185 86q49 22 103 22h189q34 0 57.5 -23.5t23.5 -57.5q0 -18 -7 -32q27 -9 44 -32.5t17 -52.5q0 -24 -11 -43q47 -22 47 -74z" />
<glyph unicode="&#x1f464;" horiz-adv-x="864" d="M864 54v-36q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v36q0 50 33.5 84.5t81 54t95 37t81 45.5t33.5 67q-4 4 -11.5 12.5t-26 38t-33 62.5t-26 85.5t-11.5 107.5q0 89 63.5 152.5t152.5 63.5t152.5 -63.5t63.5 -152.5q0 -55 -11 -107t-27 -86.5t-32 -61t-27 -39.5
l-11 -12q0 -39 33.5 -67t81 -45.5t95 -37t81 -54t33.5 -84.5z" />
<glyph unicode="&#x1f465;" horiz-adv-x="864" d="M864 270v-36q0 -8 -5 -13t-13 -5h-346q-19 6 -34 13.5t-20 12.5l-6 4q7 11 17.5 31t28.5 82.5t18 126.5q0 29 -7 57t-17 46.5t-20.5 33t-17.5 21.5l-7 7v1q-3 24 -3 50q0 67 47.5 114.5t114.5 47.5t114.5 -47.5t47.5 -114.5q0 -66 -18 -123.5t-36 -82.5l-18 -24
q0 -31 18.5 -51.5t45 -32.5t53 -24.5t45 -35.5t18.5 -58zM540 54v-36q0 -8 -5 -13t-13 -5h-504q-8 0 -13 5t-5 13v36q0 34 18.5 57.5t45 36t53 24.5t45 32.5t18.5 51.5q-8 9 -20 26.5t-32 77.5t-20 126q0 67 47.5 114.5t114.5 47.5t114.5 -47.5t47.5 -114.5
q0 -66 -18 -123.5t-36 -82.5l-18 -24q0 -31 18.5 -51.5t45 -32.5t53 -24.5t45 -35.5t18.5 -58z" />
<glyph unicode="&#x1f467;" horiz-adv-x="864" d="M864 54v-36q0 -8 -5 -13t-13 -5h-828q-8 0 -13 5t-5 13v36q0 50 33.5 84.5t81 54t95 37t81 45.5t33.5 67q-48 0 -88.5 18t-57.5 36l-16 18q2 1 5.5 5t13 20.5t16.5 40t13 68.5t6 100q0 89 63.5 152.5t152.5 63.5t152.5 -63.5t63.5 -152.5q0 -55 5.5 -99.5t13.5 -68.5
t16 -40t13 -21l6 -5q-6 -8 -18 -20t-54 -32t-90 -20q0 -39 33.5 -67t81 -45.5t95 -37t81 -54t33.5 -84.5z" />
<glyph unicode="&#x1f4a1;" horiz-adv-x="864" d="M144 576q0 119 84.5 203.5t203.5 84.5t203.5 -84.5t84.5 -203.5q0 -55 -18.5 -102.5t-45 -82t-53 -66t-45 -69t-18.5 -76.5h-216q0 39 -18.5 76.5t-45 69t-53 66t-45 82t-18.5 102.5zM540 108v-54q0 -22 -16 -38t-38 -16h-108q-22 0 -38 16t-16 38v54h216z" />
<glyph unicode="&#x1f4a7;" horiz-adv-x="864" d="M432 0q-119 0 -203.5 84.5t-84.5 203.5q0 78 37 141l235 426q5 9 16 9t16 -9l235 -426q37 -66 37 -141q0 -119 -84.5 -203.5t-203.5 -84.5z" />
<glyph unicode="&#x1f4ac;" horiz-adv-x="864" d="M864 459q0 -146 -126.5 -248.5t-305.5 -102.5q-35 0 -73 5q-113 -113 -233 -113q-12 0 -17 11q-4 12 4 20q6 6 15.5 18t27 49t22.5 77q-83 49 -130.5 123.5t-47.5 160.5q0 146 126.5 248.5t305.5 102.5t305.5 -102.5t126.5 -248.5z" />
<glyph unicode="&#x1f4b2;" horiz-adv-x="864" d="M432 864q179 0 305.5 -126.5t126.5 -305.5t-126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5zM486 166q69 11 115.5 49.5t46.5 108.5q0 55 -24 89.5t-60 46.5t-78 19t-78 9t-60 14.5t-24 37.5q0 26 32 40t76 14q72 0 144 -36l54 90
q-52 39 -144 51v57h-108v-58q-69 -11 -115.5 -49.5t-46.5 -108.5q0 -55 24 -89.5t60 -46.5t78 -19t78 -9t60 -14.5t24 -37.5q0 -26 -32 -40t-76 -14q-72 0 -144 36l-54 -90q52 -39 144 -51v-57h108v58z" />
<glyph unicode="&#x1f4b3;" horiz-adv-x="864" d="M864 702v-54h-864v54q0 22 16 38t38 16h756q22 0 38 -16t16 -38zM0 486h864v-324q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v324z" />
<glyph unicode="&#x1f4bb;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-594q0 -22 -16 -38t-38 -16h-270v-52l151 -76q11 -3 11 -16q0 -8 -5 -13t-13 -5h-504q-14 0 -18 14q-2 14 10 20l152 76v52h-270q-22 0 -38 16t-16 38v594q0 22 16 38t38 16h756zM756 270v486h-648v-486h648z" />
<glyph unicode="&#x1f4bc;" horiz-adv-x="864" d="M810 702q22 0 38 -16t16 -38v-486q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v486q0 22 16 38t38 16h216v90q0 41 43 57q38 15 119 15q82 0 119 -15q43 -16 43 -57v-90h216zM360 774v-72h144v72h-144z" />
<glyph unicode="&#x1f4c1;" horiz-adv-x="864" d="M0 162v540q0 22 16 38t38 16h312q12 0 23.5 -8.5t15.5 -20.5l27 -79h378q22 0 38 -16t16 -38v-432q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38z" />
<glyph unicode="&#x1f4c4;" horiz-adv-x="864" d="M756 576v-522q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h306q6 0 13 -5l270 -270q5 -7 5 -13z" />
<glyph unicode="&#x1f4c5;" horiz-adv-x="864" d="M810 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h72v-108q0 -22 16 -38t38 -16t38 16t16 38v108h396v-108q0 -22 16 -38t38 -16t38 16t16 38v108h72zM270 126v144h-144v-144h144zM270 378v144h-144v-144h144z
M504 126v144h-144v-144h144zM504 378v144h-144v-144h144zM738 126v144h-144v-144h144zM738 378v144h-144v-144h144z" />
<glyph unicode="&#x1f4ca;" horiz-adv-x="864" d="M342 864h180q8 0 13 -5t5 -13v-828q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v828q0 8 5 13t13 5zM18 432h180q8 0 13 -5t5 -13v-396q0 -8 -5 -13t-13 -5h-180q-8 0 -13 5t-5 13v396q0 8 5 13t13 5zM666 648h180q8 0 13 -5t5 -13v-612q0 -8 -5 -13t-13 -5h-180
q-8 0 -13 5t-5 13v612q0 8 5 13t13 5z" />
<glyph unicode="&#x1f4cd;" horiz-adv-x="864" d="M432 288q-30 0 -54 4v-256q0 -4 1.5 -10t15 -16t37.5 -10t37.5 9t14.5 18l2 9v256q-24 -4 -54 -4zM432 864q104 0 178 -74t74 -178t-74 -178t-178 -74t-178 74t-74 178t74 178t178 74zM495 594q34 0 57.5 23.5t23.5 57.5t-23.5 57.5t-57.5 23.5t-57.5 -23.5t-23.5 -57.5
t23.5 -57.5t57.5 -23.5z" />
<glyph unicode="&#x1f4ce;" horiz-adv-x="864" d="M716 538l3 3q37 37 37 89t-37 89t-89 37t-89 -37l-396 -396q-37 -37 -37 -89t37 -89t89 -37t89 37l243 242q10 11 10 26t-10 25t-25 10t-26 -10l-153 -152q-16 -16 -38 -16t-38 16t-16 38t16 38l152 153q43 42 102.5 42t101.5 -42q42 -43 42 -102.5t-42 -101.5l-243 -243
q-68 -68 -165 -68t-166 68q-68 69 -68 166t68 165l396 396q69 69 166 69t165 -69q69 -68 69 -165t-69 -166l-39 -39q-3 61 -40 113z" />
<glyph unicode="&#x1f4d3;" horiz-adv-x="864" d="M756 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v54h-90q-8 0 -13 5t-5 13v72q0 8 5 13t13 5h90v162h-90q-8 0 -13 5t-5 13v72q0 8 5 13t13 5h90v162h-90q-8 0 -13 5t-5 13v72q0 8 5 13t13 5h90v54q0 22 16 38t38 16h540zM648 486v162
h-324v-162h324z" />
<glyph unicode="&#x1f4d5;" horiz-adv-x="864" d="M756 846v-90h-540v-108h522q8 0 13 -5t5 -13v-612q0 -8 -5 -13t-13 -5h-522q-45 0 -76.5 31.5t-31.5 76.5v648q0 45 31.5 76.5t76.5 31.5h522q8 0 13 -5t5 -13z" />
<glyph unicode="&#x1f4d6;" horiz-adv-x="864" d="M378 0q-6 0 -13 5q-39 39 -89 69t-92.5 46t-83.5 26t-60.5 13t-23.5 3q-16 2 -16 18v666q0 8 6 13q4 5 13 5q41 0 130 -28q149 -46 242 -139q5 -7 5 -13v-666q0 -12 -11 -17q-2 -1 -7 -1zM486 0q-5 0 -7 1q-11 5 -11 17v666q0 6 5 13q96 94 242 139q89 28 129 28
q7 0 14 -5q6 -5 6 -13v-666q0 -16 -17 -18q-4 0 -23.5 -3t-60.5 -13t-83 -26t-92.5 -46t-88.5 -69q-7 -5 -13 -5z" />
<glyph unicode="&#x1f4dd;" horiz-adv-x="864" d="M859 733l-49 -49l-126 126l49 49q13 13 25 0l101 -101q13 -12 0 -25zM594 360v-252h-486v540h306l108 108h-414q-44 0 -76 -32t-32 -76v-540q0 -44 32 -76t76 -32h486q44 0 76 32t32 76v360zM630 756l-376 -376q-3 -3 -3 -5l-72 -173l-1 -1q-3 -10 5 -18q5 -6 12 -6
q1 0 3 0.5t3 0.5l1 1l173 72q2 0 5 3l376 376z" />
<glyph unicode="&#x1f4de;" horiz-adv-x="864" d="M864 761q0 -4 -1 -7q-37 -295 -248 -505.5t-505 -247.5q-3 -1 -7 -1q-5 0 -7 1q-6 3 -10 10l-85 214q-5 16 9 23l236 118q10 6 21 -3l115 -116q143 89 234 235l-115 115q-9 11 -3 21l118 236q7 14 23 9l214 -85q7 -4 9 -10q2 -4 2 -7z" />
<glyph unicode="&#x1f4e0;" horiz-adv-x="864" d="M864 54q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v432q0 22 16 38t38 16h90v-180h576v180h90q22 0 38 -16t16 -38v-432zM756 162q0 22 -16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16t38 16t16 38zM216 432v414q0 8 5 13t13 5h396q8 0 13 -5t5 -13v-414h-432z" />
<glyph unicode="&#x1f4e5;" horiz-adv-x="864" d="M863 332q1 -3 1 -8v-270q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v270q0 5 1 8l72 486q2 20 17.5 33t35.5 13h612q20 0 35 -13t18 -33zM173 756l-64 -432h176q12 0 17 -11l35 -86q5 -11 17 -11h156q12 0 17 11l35 86q5 11 17 11h176l-64 432h-518z" />
<glyph unicode="&#x1f4e6;" horiz-adv-x="864" d="M861 611q3 -7 3 -17v-540q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v540q0 10 3 17l72 216q5 16 19.5 26.5t31.5 10.5h612q17 0 31.5 -10.5t19.5 -26.5zM111 594h642l-54 162h-534z" />
<glyph unicode="&#x1f4f0;" horiz-adv-x="864" d="M846 810q8 0 13 -5t5 -13v-630q0 -45 -31.5 -76.5t-76.5 -31.5h-648q-45 0 -76.5 31.5t-31.5 76.5v522q0 8 5 13t13 5h72v-522q0 -15 10.5 -25.5t25.5 -10.5t25.5 10.5t10.5 25.5v612q0 8 5 13t13 5h666zM756 486v162h-324v-162h324z" />
<glyph unicode="&#x1f4f1;" horiz-adv-x="864" d="M648 864q22 0 38 -16t16 -38v-756q0 -22 -16 -38t-38 -16h-432q-22 0 -38 16t-16 38v756q0 22 16 38t38 16h432zM432 54q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16zM612 216v504h-360v-504h360z" />
<glyph unicode="&#x1f4f7;" horiz-adv-x="864" d="M810 648q22 0 38 -16t16 -38v-432q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v432q0 22 16 38t38 16h162l26 79q5 12 16 20.5t24 8.5h300q12 0 23.5 -8.5t15.5 -20.5l27 -79h162zM432 216q67 0 114.5 47.5t47.5 114.5t-47.5 114.5t-114.5 47.5t-114.5 -47.5
t-47.5 -114.5q0 -68 47 -115t115 -47z" />
<glyph unicode="&#x1f4f9;" horiz-adv-x="864" d="M864 684v-504q0 -12 -11 -17q-2 -1 -7 -1q-6 0 -13 5l-185 186v-137q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v432q0 22 16 38t38 16h540q22 0 38 -16t16 -38v-137l185 186q8 8 20 4q11 -5 11 -17z" />
<glyph unicode="&#x1f500;" horiz-adv-x="864" d="M294 615l-90 -120l-44 59q-16 22 -43 22h-99q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h100q98 0 157 -78zM859 203l-162 -162q-7 -5 -13 -5q-5 0 -7 1q-11 5 -11 17v90h-100q-98 0 -157 78l-20 27l90 120l45 -59q16 -22 43 -22h99v90q0 12 11 17q12 4 20 -4l162 -162
q13 -13 0 -26zM859 635l-162 -162q-7 -5 -13 -5q-5 0 -7 1q-11 5 -11 17v90h-99q-27 0 -43 -22l-249 -332q-59 -78 -157 -78h-100q-8 0 -13 5t-5 13v108q0 8 5 13t13 5h99q27 0 43 22l249 332q59 78 157 78h100v90q0 12 11 17q12 4 20 -4l162 -162q13 -13 0 -26z" />
<glyph unicode="&#x1f501;" horiz-adv-x="864" d="M679 661q13 -13 0 -26l-162 -162q-8 -8 -20 -4q-11 5 -11 17v90h-198q-60 0 -102 -42.5t-42 -101.5q0 -50 31 -89q9 -12 -1 -24l-78 -77q-4 -5 -12 -5t-13 6q-71 82 -71 189q0 119 84.5 203.5t203.5 84.5h198v90q0 12 11 17q12 4 20 -4zM185 203q-13 13 0 26l162 162
q8 8 20 4q11 -5 11 -17v-90h198q59 0 101.5 42t42.5 102q0 50 -31 89q-10 12 1 23l78 78q4 5 12 5t13 -6q71 -82 71 -189q0 -119 -84.5 -203.5t-203.5 -84.5h-198v-90q0 -12 -11 -17q-12 -4 -20 4z" />
<glyph unicode="&#x1f508;" horiz-adv-x="864" d="M594 774v-684q0 -12 -11 -17q-12 -4 -20 4l-193 193h-136q-8 0 -13 5t-5 13v288q0 8 5 13t13 5h136l193 193q8 8 20 4q11 -5 11 -17z" />
<glyph unicode="&#x1f509;" horiz-adv-x="864" d="M655 146q-13 -12 -25 0l-51 50q-12 14 0 26q87 87 87 210t-87 210q-13 12 0 25l51 51q12 12 25 0q78 -78 105.5 -182t0 -208t-105.5 -182zM459 774v-684q0 -12 -11 -17q-12 -4 -20 4l-193 193h-136q-7 0 -12.5 5t-5.5 13v288q0 8 5.5 13t12.5 5h136l193 193q8 8 20 4
q11 -5 11 -17z" />
<glyph unicode="&#x1f50a;" horiz-adv-x="864" d="M662 6l-51 50q-12 14 0 26q95 95 128.5 222.5t0 255t-128.5 222.5q-13 12 0 25l51 51q12 12 25 0q116 -116 157.5 -271t0 -310t-157.5 -271q-13 -12 -25 0zM547 146q-13 -12 -25 0l-51 50q-12 14 0 26q87 87 87 210t-87 210q-13 12 0 25l51 51q12 12 25 0
q78 -78 105.5 -182t0 -208t-105.5 -182zM351 774v-684q0 -12 -11 -17q-12 -4 -20 4l-193 193h-136q-7 0 -12.5 5t-5.5 13v288q0 8 5.5 13t12.5 5h136l193 193q8 8 20 4q11 -5 11 -17z" />
<glyph unicode="&#x1f50b;" horiz-adv-x="864" d="M864 522v-180q0 -8 -5 -13t-13 -5h-90v-54q0 -22 -16 -38t-38 -16h-648q-22 0 -38 16t-16 38v324q0 22 16 38t38 16h648q22 0 38 -16t16 -38v-54h90q8 0 13 -5t5 -13z" />
<glyph unicode="&#x1f50e;" horiz-adv-x="864" d="M540 864q134 0 229 -95t95 -229t-95 -229t-229 -95q-95 0 -173 50l-244 -245q-21 -21 -51 -21t-51 21t-21 51t21 51l245 244q-50 78 -50 173q0 134 95 229t229 95zM540 324q89 0 152.5 63.5t63.5 152.5t-63.5 152.5t-152.5 63.5t-152.5 -63.5t-63.5 -152.5t63.5 -152.5
t152.5 -63.5z" />
<glyph unicode="&#x1f511;" horiz-adv-x="864" d="M144 0h-126q-8 0 -13 5t-5 13v136q0 8 5 13l335 335q-16 42 -16 92q0 112 79 191t191 79t191 -79t79 -191t-79 -191t-191 -79q-50 0 -92 16l-119 -119q-5 -5 -13 -5h-100v-90q0 -8 -5 -13t-13 -5h-90v-90q0 -8 -5 -13t-13 -5zM648 729q-34 0 -57.5 -23.5t-23.5 -57.5
t23.5 -57.5t57.5 -23.5t57.5 23.5t23.5 57.5t-23.5 57.5t-57.5 23.5z" />
<glyph unicode="&#x1f512;" horiz-adv-x="864" d="M702 486q22 0 38 -16t16 -38v-378q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v378q0 22 16 38t38 16h54v162q0 89 63.5 152.5t152.5 63.5t152.5 -63.5t63.5 -152.5v-162h54zM324 648v-162h216v162q0 45 -31.5 76.5t-76.5 31.5t-76.5 -31.5t-31.5 -76.5z" />
<glyph unicode="&#x1f513;" horiz-adv-x="864" d="M756 396v252q0 45 -31.5 76.5t-76.5 31.5t-76.5 -31.5t-31.5 -76.5v-162h54q22 0 38 -16t16 -38v-378q0 -22 -16 -38t-38 -16h-540q-22 0 -38 16t-16 38v378q0 22 16 38t38 16h378v162q0 89 63.5 152.5t152.5 63.5t152.5 -63.5t63.5 -152.5v-252q0 -8 -5 -13t-13 -5h-72
q-8 0 -13 5t-5 13z" />
<glyph unicode="&#x1f514;" horiz-adv-x="864" d="M342 90h180q0 -38 -26 -64t-64 -26t-64 26t-26 64zM863 173q-5 -11 -17 -11h-828q-12 0 -17 11q-4 12 4 20l157 156v245q0 112 79 191t191 79t191 -79t79 -191v-245l157 -156q8 -8 4 -20z" />
<glyph unicode="&#x1f515;" horiz-adv-x="864" d="M342 90h180q0 -38 -26 -64t-64 -26t-64 26t-26 64zM162 522l360 -360h-504q-12 0 -17 11q-4 12 4 20l157 156v173zM849 15q-15 -15 -37 -15t-37 15l-760 760q-15 15 -15 36.5t15 37.5q15 15 36.5 15t37.5 -15l113 -114q37 59 97.5 94t132.5 35q112 0 191 -79t79 -191
v-245l157 -156q8 -8 4 -20q-5 -11 -17 -11h-71l74 -73q15 -16 15 -37.5t-15 -36.5z" />
<glyph unicode="&#x1f516;" horiz-adv-x="864" d="M648 810v-792q0 -12 -11 -17q-2 -1 -7 -1q-6 0 -13 5l-185 185l-185 -185q-8 -8 -20 -4q-11 5 -11 17v792q0 22 16 38t38 16h324q22 0 38 -16t16 -38z" />
<glyph unicode="&#x1f517;" horiz-adv-x="864" d="M795 464l-122 -122q6 69 -18 134l64 65q37 37 37 89t-37 89t-89 37t-89 -37l-135 -134q-37 -37 -37 -89t37 -90q16 -16 16 -38t-16 -38t-38 -16t-38 16q-68 69 -68 166t68 165l134 134q69 69 166 69t165 -69q69 -68 69 -165t-69 -166zM534 203l-135 -135
q-68 -68 -165 -68t-166 68q-68 69 -68 166t68 165l123 123q-6 -70 18 -135l-64 -64q-37 -37 -37 -89t37 -89t89 -37t89 37l134 134q37 37 37 89t-37 89q-16 16 -16 38.5t16 38.5t38.5 16t38.5 -16q68 -69 68 -166t-68 -165z" />
<glyph unicode="&#x1f6ab;" horiz-adv-x="864" d="M864 432q0 -179 -126.5 -305.5t-305.5 -126.5t-305.5 126.5t-126.5 305.5t126.5 305.5t305.5 126.5t305.5 -126.5t126.5 -305.5zM144 432q0 -86 45 -154l397 397q-68 45 -154 45q-119 0 -203.5 -84.5t-84.5 -203.5zM675 586l-397 -397q68 -45 154 -45q119 0 203.5 84.5
t84.5 203.5q0 86 -45 154z" />
<glyph />
<glyph horiz-adv-x="288" />
<glyph />
<glyph unicode="&#xd;" />
<glyph unicode=" " horiz-adv-x="216" />
<glyph unicode="A" horiz-adv-x="580" d="M567 0h-92l-61 181h-251l-65 -181h-86l234 624h97zM382 256l-92 276l-100 -276h192z" />
<glyph unicode="B" horiz-adv-x="580" d="M543 187q0 -84 -57 -135.5t-137 -51.5h-287v624h282q69 0 118 -42t50 -116q0 -42 -21 -79t-60 -51q50 -17 81 -56.5t31 -92.5zM429 448q0 51 -26.5 76.5t-92.5 26.5h-162v-192h164q59 0 87 25.5t30 63.5zM459 176q0 57 -30 85t-114 29h-167v-219h195q56 0 85 32t31 73z
" />
<glyph unicode="C" horiz-adv-x="628" d="M592 229q-13 -105 -84 -175.5t-182 -70.5q-63 0 -114 20.5t-83 54t-53.5 78t-30.5 89.5t-9 92q0 83 31 154t97.5 119t157.5 51q29 0 59 -5t64.5 -19.5t62 -36t49 -59t28.5 -85.5h-82q-12 62 -58 95t-111 33q-107 0 -157.5 -68.5t-52.5 -178.5q2 -66 21 -122.5t63.5 -96.5
t108.5 -40q81 0 130.5 45t61.5 126h83z" />
<glyph unicode="D" horiz-adv-x="628" d="M584 334q0 -138 -67 -235t-183 -99h-265v624h262q42 0 83 -16t79.5 -48t63.5 -91t27 -135zM497 327q0 96 -43 160t-135 64h-164v-480h174q76 0 122 73t46 183z" />
<glyph unicode="E" horiz-adv-x="580" d="M534 0h-461v624h456v-76h-371v-190h342v-75h-342v-208h376v-75z" />
<glyph unicode="F" horiz-adv-x="530" d="M505 548h-347v-190h306v-75h-306v-283h-85v624h432v-76z" />
<glyph unicode="G" horiz-adv-x="674" d="M610 0h-54l-20 83q-29 -41 -84 -68t-121 -29q-149 0 -219.5 90t-70.5 241q0 60 18.5 115.5t53.5 101.5t93 74t130 29q100 0 175.5 -53.5t88.5 -149.5h-81q-33 130 -187 130q-89 0 -147 -68t-58 -184q0 -124 56.5 -191.5t148.5 -67.5q72 0 131 45q38 31 52.5 67t16.5 95
h-194v72h272v-332z" />
<glyph unicode="H" horiz-adv-x="628" d="M562 0h-85v290h-326v-290h-85v624h85v-259h326v259h85v-624z" />
<glyph unicode="I" horiz-adv-x="240" d="M163 0h-85v624h85v-624z" />
<glyph unicode="J" horiz-adv-x="434" d="M372 168q0 -96 -49.5 -139.5t-130.5 -45.5q-93 0 -135.5 47.5t-42.5 108.5v61h79v-44q0 -101 94 -101q51 0 74.5 26t24.5 82v461h86v-456z" />
<glyph unicode="K" horiz-adv-x="580" d="M575 0h-109l-219 312l-98 -93v-219h-85v624h85v-304l303 304h116l-260 -252z" />
<glyph unicode="L" horiz-adv-x="484" d="M466 0h-402v624h85v-549h317v-75z" />
<glyph unicode="M" horiz-adv-x="722" d="M661 0h-83v524l-174 -524h-84l-178 523v-523h-80v624h121l180 -529l178 529h120v-624z" />
<glyph unicode="N" horiz-adv-x="628" d="M562 0h-96l-318 503v-503h-82v624h100l314 -505v505h82v-624z" />
<glyph unicode="O" horiz-adv-x="674" d="M641 312q0 -35 -5 -69.5t-23.5 -82.5t-49 -84t-88.5 -62t-136 -27q-76 0 -135.5 27.5t-95 74t-54 103.5t-18.5 120q0 89 31.5 160t101.5 117.5t170 47.5q66 0 119.5 -20.5t86.5 -53.5t55.5 -77t31.5 -87t9 -87zM556 312q0 112 -57.5 180.5t-159.5 69.5q-97 0 -157 -68
t-60 -182q0 -113 58 -181t159 -69q102 0 159.5 68.5t57.5 181.5z" />
<glyph unicode="P" horiz-adv-x="580" d="M539 448q0 -76 -45 -129.5t-140 -55.5h-196v-263h-85v624h281q79 0 131 -46t54 -130zM452 448q0 103 -123 103h-171v-217h168q124 0 126 114z" />
<glyph unicode="Q" horiz-adv-x="674" d="M641 312q0 -150 -91 -240l85 -66l-41 -51l-96 75q-65 -43 -160 -43q-76 0 -135.5 27.5t-95.5 74t-54.5 103.5t-18.5 120q0 138 78 230.5t226 94.5q66 0 119 -20.5t86.5 -53.5t56.5 -77t32 -87t9 -87zM554 312q0 112 -57 180.5t-159 69.5q-98 0 -157.5 -67.5t-59.5 -182.5
q0 -113 58 -181t159 -69q51 0 91 20l-65 49l43 53l80 -61q67 70 67 189z" />
<glyph unicode="R" horiz-adv-x="628" d="M584 0h-95q-11 24 -16 63.5t-6.5 79t-2.5 47.5q-10 75 -102 76h-212v-266h-85v624h299q80 0 137 -43.5t59 -128.5q0 -97 -91 -145q69 -22 77 -101q3 -24 5.5 -66.5t6 -69.5t10.5 -45q7 -17 16 -25zM474 444q0 104 -103 107h-221v-212h214q47 0 78.5 29t31.5 76z" />
<glyph unicode="S" horiz-adv-x="580" d="M537 175q0 -91 -67.5 -139.5t-176.5 -48.5q-249 0 -250 219h78q0 -141 172 -147q69 0 116 24.5t47 80.5q0 54 -38.5 74t-164.5 48q-15 3 -22 5q-76 17 -121.5 51.5t-47.5 103.5q0 82 54.5 136.5t161.5 54.5q65 0 112.5 -16.5t71 -38.5t37.5 -52t17.5 -49t4.5 -37v-5h-78
q0 63 -45.5 93.5t-111.5 33.5q-27 0 -50.5 -5t-45 -16.5t-34 -34t-12.5 -54.5q0 -60 75 -76l178 -41q140 -31 140 -164z" />
<glyph unicode="T" horiz-adv-x="530" d="M519 548h-212v-548h-85v548h-210v76h507v-76z" />
<glyph unicode="U" horiz-adv-x="628" d="M560 205q0 -93 -63.5 -154.5t-188.5 -62.5q-119 0 -178.5 55t-61.5 158v423h85v-407q0 -72 40 -113.5t115 -41.5q76 0 120.5 40t46.5 113v409h85v-419z" />
<glyph unicode="V" horiz-adv-x="580" d="M561 624l-227 -624h-90l-227 624h98l177 -533l184 533h85z" />
<glyph unicode="W" horiz-adv-x="819" d="M806 624l-165 -624h-88l-142 517l-146 -517h-89l-162 624h91l115 -509l143 509h91l143 -509l115 509h94z" />
<glyph unicode="X" horiz-adv-x="580" d="M562 0h-105l-167 256l-173 -256h-101l223 320l-210 304h106l158 -239l159 239h101l-209 -305z" />
<glyph unicode="Y" horiz-adv-x="580" d="M566 624l-235 -375v-249h-84v249l-234 375h102l178 -300l179 300h94z" />
<glyph unicode="Z" horiz-adv-x="530" d="M510 0h-490v69l382 480h-354v75h462v-73l-384 -475h384v-76z" />
<glyph unicode="a" horiz-adv-x="484" d="M461 1v-1q-24 -9 -50 -9q-71 0 -73 68q-65 -70 -164 -73q-64 0 -104 37.5t-40 90.5q0 33 12 58.5t27 40t45 26t48.5 15.5t56.5 10t51 9q64 12 64 55q0 35 -26.5 56t-78.5 21q-47 0 -75 -22.5t-29 -67.5h-71q0 62 47 106t138 45q70 0 121 -34.5t51 -99.5v-243
q0 -17 2.5 -25t14 -13t33.5 5v-55zM332 151v82q-17 -11 -57.5 -19.5t-75 -15t-62.5 -28t-28 -55.5q0 -33 22 -50t59 -17q48 0 95 29t47 74z" />
<glyph unicode="b" horiz-adv-x="484" d="M459 240q2 -45 -8 -88t-32.5 -81.5t-64 -61.5t-96.5 -23q-93 0 -134 70l-6 -56h-69v624h78v-227q50 66 139 69q83 0 136.5 -63t56.5 -163zM379 227q0 84 -33.5 127.5t-93.5 43.5q-35 0 -61 -16t-40 -42.5t-20.5 -54.5t-6.5 -57q0 -171 132 -175q59 0 91 47.5t32 126.5z
" />
<glyph unicode="c" horiz-adv-x="434" d="M418 160q-10 -90 -65.5 -132t-126.5 -42q-86 0 -143.5 67t-57.5 174q0 116 58.5 178t145.5 62q73 0 127 -39t62 -126h-73q-4 45 -35 70.5t-78 25.5q-56 0 -91 -40.5t-35 -130.5q0 -72 35.5 -121.5t90.5 -49.5q94 0 112 104h74z" />
<glyph unicode="d" horiz-adv-x="484" d="M27 240q3 100 56.5 163t136.5 63q88 -3 139 -69v227h78v-624h-69v64q-20 -35 -59 -56.5t-81 -21.5q-55 0 -96.5 23t-64 61.5t-32.5 81.5t-8 88zM107 227q0 -79 32 -126.5t91 -47.5q132 4 132 175q0 65 -31 117.5t-97 52.5q-60 0 -93.5 -43.5t-33.5 -127.5z" />
<glyph unicode="e" horiz-adv-x="484" d="M453 201h-339q0 -64 38.5 -104.5t95.5 -40.5q55 0 88 29.5t33 56.5h78q-13 -73 -68 -114t-135 -41q-96 0 -152.5 65t-58.5 162q0 114 59 184t154 70q101 0 155.5 -73.5t51.5 -193.5zM373 263q0 61 -37 99t-89 38q-54 0 -92.5 -40.5t-40.5 -96.5h259z" />
<glyph unicode="f" horiz-adv-x="240" d="M227 630v-63q-13 2 -32 2q-23 0 -32.5 -10.5t-9.5 -35.5v-69h74v-69h-74v-385h-78v385h-63v69h63v84q0 41 31 69t81 28q23 0 40 -5z" />
<glyph unicode="g" horiz-adv-x="518" d="M458 20q0 -111 -54 -165t-151 -54q-26 0 -52 5.5t-56 19t-49 44t-20 74.5h76q0 -34 29 -53t67 -19q63 0 98.5 35t35.5 107v27q-50 -54 -139 -54q-76 0 -137.5 62.5t-63.5 165.5q0 117 59 184t153 67q41 0 75.5 -18t52.5 -46v55h76v-437zM382 226q0 76 -35 119.5t-96 43.5
q-51 0 -89.5 -41t-38.5 -115q0 -87 39 -132.5t92 -45.5q56 0 91.5 45.5t36.5 125.5z" />
<glyph unicode="h" horiz-adv-x="484" d="M427 0h-78v297q0 101 -89 101q-54 0 -91 -38t-37 -113v-247h-78v624h78v-231q46 70 141 74q64 0 109 -38t45 -127v-302z" />
<glyph unicode="i" horiz-adv-x="194" d="M134 536h-78v86h78v-86zM134 0h-78v454h78v-454z" />
<glyph unicode="j" horiz-adv-x="229" d="M171 -78q0 -45 -29.5 -74t-84.5 -29q-25 0 -39 3v66q19 -4 35 -4q22 0 31 12t9 43v515h78v-532zM171 536h-78v88h78v-88z" />
<glyph unicode="k" horiz-adv-x="434" d="M434 0h-97l-150 222l-55 -54v-168h-78v624h78v-363l194 193h98l-181 -174z" />
<glyph unicode="l" horiz-adv-x="194" d="M135 0h-79v624h79v-624z" />
<glyph unicode="m" horiz-adv-x="722" d="M669 0h-78v293q0 105 -84 105q-46 0 -75 -33t-31 -89v-276h-78v313q0 36 -17.5 60.5t-55.5 24.5q-48 0 -82 -36t-35 -115v-247h-78v454h72v-64q49 76 139 76q84 0 122 -73q47 73 139 73q18 0 35.5 -3.5t37.5 -14t34.5 -27t24.5 -44.5t10 -64v-313z" />
<glyph unicode="n" horiz-adv-x="484" d="M427 0h-78v284q0 114 -89 114q-55 0 -91.5 -37.5t-36.5 -101.5v-259h-78v454h74v-66q15 25 54.5 51.5t90.5 26.5q70 0 112 -40.5t42 -123.5v-302z" />
<glyph unicode="o" horiz-adv-x="484" d="M456 227q0 -98 -57.5 -168t-155.5 -72q-97 0 -154.5 70.5t-57.5 169.5q0 101 57 170.5t155 69.5t155.5 -69.5t57.5 -170.5zM376 227q1 39 -12 76.5t-44.5 66t-76.5 29.5q-65 0 -98.5 -54t-33.5 -118q0 -73 32.5 -123t99.5 -50t98.5 49t34.5 124z" />
<glyph unicode="p" horiz-adv-x="484" d="M460 214q-3 -100 -56.5 -163t-137.5 -63q-87 3 -138 69v-237h-79v634h70v-64q20 35 59 56.5t81 21.5q55 0 96.5 -23t64 -61.5t32.5 -81.5t8 -88zM380 227q0 79 -32 126.5t-91 47.5q-132 -4 -132 -175q0 -65 31 -117.5t97 -52.5q60 0 93.5 43.5t33.5 127.5z" />
<glyph unicode="q" horiz-adv-x="484" d="M19 214q0 46 10 88t32 81t63 62t96 23q92 0 133 -70l7 56h70v-634h-78v237q-52 -66 -139 -69q-85 0 -138.5 60.5t-55.5 165.5zM99 227q0 -83 34 -127t94 -44q45 0 75.5 29t41 65t10.5 76q0 171 -132 175q-59 0 -91 -47.5t-32 -126.5z" />
<glyph unicode="r" horiz-adv-x="288" d="M257 385q-65 0 -105.5 -30t-40.5 -83v-272h-78v454h75v-77q40 87 149 87v-79z" />
<glyph unicode="s" horiz-adv-x="434" d="M405 137q0 -65 -48 -108t-131 -43q-85 0 -137.5 38.5t-58.5 121.5h75q0 -93 121 -93q43 0 73 18t30 53q0 27 -27.5 42.5t-129.5 39.5q-26 6 -43.5 12.5t-39 19.5t-32.5 34t-11 50q0 69 48 107t124 38q52 0 88.5 -15.5t53 -40.5t23.5 -45.5t8 -41.5h-74q0 76 -107 76
q-11 0 -22 -1.5t-28 -7t-28.5 -19.5t-12.5 -36q0 -29 27.5 -41t126.5 -36q62 -17 96.5 -43.5t35.5 -78.5z" />
<glyph unicode="t" horiz-adv-x="240" d="M227 54v-64q-23 -5 -40 -5q-50 0 -81 28t-31 69v303h-59v69h59v128h78v-128h74v-69h-74v-287q0 -25 9.5 -36t32.5 -11q12 0 32 3z" />
<glyph unicode="u" horiz-adv-x="484" d="M49 454h79v-284q0 -114 89 -114q55 0 91.5 37.5t36.5 101.5v259h78v-454h-75v66q-15 -25 -54.5 -51.5t-90.5 -26.5q-70 0 -112 40.5t-42 123.5v302z" />
<glyph unicode="v" horiz-adv-x="434" d="M417 454l-173 -454h-82l-165 454h87l124 -372l127 372h82z" />
<glyph unicode="w" horiz-adv-x="628" d="M615 454l-131 -454h-80l-91 351l-91 -351h-80l-130 454h83l86 -358l93 358h85l89 -358l91 358h76z" />
<glyph unicode="x" horiz-adv-x="434" d="M425 0h-98l-112 171l-110 -171h-96l160 234l-152 220h98l105 -161l106 161h92l-153 -221z" />
<glyph unicode="y" horiz-adv-x="434" d="M425 454q-70 -199 -133 -365t-77 -195q-28 -56 -63 -72t-99 -2v70q69 -26 96 24l31 72l-170 468h86l124 -371l123 371h82z" />
<glyph unicode="z" horiz-adv-x="434" d="M407 0h-380v59l273 331h-252v64h350v-63l-271 -329h280v-62z" />
<glyph unicode="&#xe7b7;" horiz-adv-x="864" d="M810 324q22 0 38 -16t16 -38v-216q0 -22 -16 -38t-38 -16h-756q-22 0 -38 16t-16 38v216q0 22 16 38t38 16h756zM486 108q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16zM702 108q22 0 38 16t16 38t-16 38t-38 16t-38 -16t-16 -38t16 -38t38 -16z
M791 818l64 -430q-22 8 -45 8h-756q-23 0 -45 -8l64 430q2 20 17.5 33t35.5 13h234v-110h-135q-12 0 -17 -11q-4 -12 4 -20l220 -219l220 219q8 8 4 20q-5 11 -17 11h-135v110h234q20 0 35 -13t18 -33z" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 62 KiB

BIN
public/ss-standard.ttf Executable file

Binary file not shown.

BIN
public/ss-standard.woff Executable file

Binary file not shown.

600
public/style.css Normal file
View File

@ -0,0 +1,600 @@
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section {
display: block;
}
audio,
canvas,
video {
display: inline-block;
*display: inline;
*zoom: 1;
}
audio:not([controls]) {
display: none;
}
[hidden] {
display: none;
}
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
html,
button,
input,
select,
textarea {
font-family: sans-serif;
color: #222;
}
body {
margin: 0;
font-size: 1em;
line-height: 1.4;
}
a {
color: #00e;
}
a:visited {
color: #551a8b;
}
a:hover {
color: #06e;
}
a:focus {
outline: thin dotted;
}
a:hover,
a:active {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
blockquote {
margin: 1em 40px;
}
dfn {
font-style: italic;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
ins {
background: #ff9;
color: #000;
text-decoration: none;
}
mark {
background: #ff0;
color: #000;
font-style: italic;
font-weight: bold;
}
pre,
code,
kbd,
samp {
font-family: monospace, serif;
_font-family: 'courier new', monospace;
font-size: 1em;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
q {
quotes: none;
}
q:before,
q:after {
content: none;
}
small {
font-size: 85%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
ul,
ol {
margin: 1em 0;
padding: 0 0 0 40px;
}
dd {
margin: 0 0 0 40px;
}
nav ul,
nav ol {
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
img {
border: 0;
-ms-interpolation-mode: bicubic;
vertical-align: middle;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 0;
}
form {
margin: 0;
}
fieldset {
border: 0;
margin: 0;
padding: 0;
}
label {
cursor: pointer;
}
legend {
border: 0;
*margin-left: -7px;
padding: 0;
white-space: normal;
}
button,
input,
select,
textarea {
font-size: 100%;
margin: 0;
vertical-align: baseline;
*vertical-align: middle;
}
button,
input {
line-height: normal;
}
button,
input[type="button"],
input[type="reset"],
input[type="submit"] {
cursor: pointer;
-webkit-appearance: button;
*overflow: visible;
}
button[disabled],
input[disabled] {
cursor: default;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
*width: 13px;
*height: 13px;
}
input[type="search"] {
-webkit-appearance: textfield;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
textarea {
overflow: auto;
vertical-align: top;
resize: vertical;
}
input:valid,
textarea:valid,
input:invalid,
textarea:invalid {
background-color: #f0dddd;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
td {
vertical-align: top;
}
.clearfix:before,
.clearfix:after {
content: "\0020";
display: block;
height: 0;
visibility: hidden;
}
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
::-webkit-input-placeholder {
color: #aaa;
font-weight: 200;
}
:-moz-placeholder {
color: #aaa;
font-weight: 200;
}
::-moz-placeholder {
color: #aaa;
font-weight: 200;
}
body {
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
background: url("http://andyet.com/images/header.png");
background-position: top center;
background-repeat: no-repeat;
overflow: hidden;
}
body .loggedIn {
display: none;
}
body.authed .loggedOut {
display: none;
}
body.authed .loggedIn {
display: block;
}
#logo {
height: 64px;
display: block;
margin-bottom: 80px;
position: relative;
top: 60px;
}
#logo img {
position: absolute;
top: 0;
left: 50%;
margin-left: -240px;
}
h2 {
font-weight: 600;
color: #333;
font-size: 40px;
text-align: center;
margin: 0;
}
h3 {
display: none;
}
header {
position: absolute;
top: 20px;
right: 20px;
}
.page.talk .controls {
top: 75px;
position: absolute;
left: 20px;
top: 100px;
margin: 0 auto;
z-index: 10;
}
.page.talk .controls button {
padding: 0 1em 0 2em;
height: 35px;
line-height: 31px;
}
.page.talk .controls #shareScreen .unshare {
display: none;
}
.page.talk .controls #shareScreen.sharingScreen {
background: #ec008c;
}
.page.talk .controls #shareScreen.sharingScreen .unshare {
display: block;
}
.page.talk .controls #shareScreen.sharingScreen .share {
display: none;
}
.page.talk .controls #muteMicrophone .unmute {
display: none;
}
.page.talk .controls #muteMicrophone.muted {
background: #ec008c;
}
.page.talk .controls #muteMicrophone.muted .unmute {
display: block;
}
.page.talk .controls #muteMicrophone.muted .mute {
display: none;
}
.page.talk .controls #pauseVideo .resume {
display: none;
}
.page.talk .controls #pauseVideo.paused .resume {
display: block;
}
.page.talk .controls #pauseVideo.paused .pause {
display: none;
}
.page.talk .lockControls {
display: inline;
}
.page.talk .lockControls .unlock {
display: none;
}
.page.talk .lockControls.roomLocked .unlock {
display: inline;
}
.page.talk .lockControls.roomLocked .lock {
display: none;
}
.page.talk h2 {
position: relative;
margin: 0;
line-height: 1;
top: -20px;
}
.page.talk h2 svg {
fill: #12acef;
}
.page.talk #logo {
width: 100px;
margin: 0 auto;
position: fixed;
left: 20px;
top: 20px;
overflow: hidden;
}
.page.talk #logo img {
left: 240px;
}
.page.talk section {
padding: 0;
}
.page.talk h3 {
display: block;
font-size: 13px;
font-weight: normal;
margin: 0;
position: relative;
top: -20px;
text-align: center;
color: #aaa;
}
.page.talk h3 svg {
position: relative;
top: 3px;
fill: #aaa;
}
a:link,
a:visited {
color: #12acef;
}
.desc {
text-align: center;
font-size: 18px;
margin-top: 0;
margin-bottom: 40px;
color: #555;
font-weight: 200;
}
.about {
text-align: center;
width: 450px;
font-size: 13px;
margin: 80px auto;
color: #444;
position: relative;
z-index: 10;
}
footer {
text-align: center;
color: #777;
font-size: 14px;
position: fixed;
bottom: 10px;
margin: 0;
left: 50%;
width: 500px;
margin-left: -250px;
z-index: 100;
}
section {
margin: 0 auto;
width: 100%;
padding: 20px 0;
}
#createRoom {
margin: 0 auto;
width: 400px;
position: relative;
z-index: 10;
}
#createRoom input {
width: 380px;
height: 40px;
border: 0px none;
display: inline-block;
font-size: 16px;
padding: 0 10px;
background: #eaebeb;
border-radius: 3px;
font-weight: 100;
line-height: 40px;
color: #333;
font-weight: bold;
margin: 0 0 10px 0;
text-align: left;
}
#createRoom button {
position: relative;
width: 380px;
}
#localVideo {
position: fixed;
top: 15px;
right: 15px;
border: 5px solid #777;
outline: 0px;
height: 70px;
-o-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-moz-transform: scaleX(-1);
-ms-transform: scaleX(-1);
transform: scaleX(-1);
}
#remotes {
width: 100%;
height: 100%;
position: absolute;
top: 100px;
-webkit-perspective: 2000px;
-moz-perspective: 2000px;
z-index: 1;
}
#remotes video {
position: absolute;
left: 4000px;
height: 200px;
-moz-transition: all 1s;
-moz-box-sizing: border-box;
-webkit-transition: all 1s;
-webkit-box-sizing: border-box;
}
#ad {
cursor: pointer;
}
a#ad:link,
a#ad:visited {
color: #555;
text-decoration: none;
font-weight: 300;
font-size: 16px;
border-top: 1px solid #f0f0f0;
background-color: #fafafa;
width: 100%;
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 0px;
line-height: 2.5;
text-align: left;
height: 40px;
}
a#ad:link:before,
a#ad:visited:before {
content: "";
display: inline-block;
float: left;
background-image: url("https://andbang.com/images/AndBangHeader.png");
width: 35px;
height: 35px;
background-size: 40px;
background-repeat: no-repeat;
margin-right: 10px;
}
#andyet {
position: fixed;
bottom: 10px;
right: 10px;
z-index: 10;
}
#game {
display: none;
}
#game.gameActive {
display: block;
}
#game,
#viewport {
position: fixed;
display: block;
z-index: -1;
height: calc(100% - 20px);
height: -moz-calc(100% - 20px);
width: 100%;
top: 0;
}
#instructions {
display: none;
background-color: rgba(0,0,0,0.02);
border: 1px solid #eee;
padding: 10px;
top: 150px;
left: 20px;
width: 230px;
text-align: left;
}
#instructions h3 {
font-size: 16px;
color: #333;
font-weight: bold;
text-align: left;
margin-bottom: 20px;
}
#instructions p {
font-size: 13px;
margin: 10px 0 0 0;
}
button {
border: none;
height: 40px;
padding: 0 1em;
position: relative;
border-radius: 3px;
font-weight: bold;
color: #fff;
line-height: 40px;
background: #00aeef;
}
button#pauseVideo {
background: #ec008c;
}
button#pauseVideo:hover {
background: #d4007e;
}
button:hover {
background: #009dd7;
}
button .ss-icon {
font-size: 12px;
position: absolute;
top: 3px;
left: 12px;
}

351
public/style.styl Normal file
View File

@ -0,0 +1,351 @@
// style.styl
@import _define
@import _reset
// variables
accentColor = #ec008c
baseColor = #00aeef
*
-webkit-box-sizing: border-box
-moz-box-sizing: border-box
::-webkit-input-placeholder
color: #aaa
font-weight: 200
:-moz-placeholder
color: #aaa
font-weight: 200
::-moz-placeholder
color: #aaa
font-weight: 200
body
helv()
background: url(http://andyet.com/images/header.png)
background-position: top center
background-repeat: no-repeat
overflow: hidden
.loggedIn
display: none
&.authed
.loggedOut
display: none
.loggedIn
display: block
#logo
height: 64px
display: block
margin-bottom: 80px
position: relative
top: 60px
img
position: absolute
top: 0
left: 50%
margin-left: -240px
h2
font-weight: 600
color: #333
font-size: 40px
text-align: center
margin: 0
h3
display: none
header
position: absolute
top: 20px
right: 20px
.page.talk
.controls
top: 75px
position: absolute
left: 20px
top: 100px
margin: 0 auto
z-index: 10
button
padding: 0 1em 0 2em
height: 35px
line-height: 31px
#shareScreen
.unshare
display: none
&.sharingScreen
background: accentColor
.unshare
display: block
.share
display: none
#muteMicrophone
.unmute
display: none
&.muted
background: accentColor
.unmute
display: block
.mute
display: none
#pauseVideo
.resume
display: none
&.paused
.resume
display: block
.pause
display: none
.lockControls
display: inline
.unlock
display: none
&.roomLocked
.unlock
display: inline
.lock
display: none
h2
position: relative
margin: 0
line-height: 1
top: -20px
svg
// green fill: #72B14D
fill: #12ACEF
#logo
width: 100px
margin: 0 auto
position: fixed
left: 20px
top: 20px
overflow: hidden
img
left: 240px
section
padding: 0
h3
display: block
font-size: 13px
font-weight: normal
margin: 0
position: relative
top: -20px
text-align: center
color: #aaa
svg
position: relative
top: 3px
fill: #aaa
a:link, a:visited
color: #12ACEF
.desc
text-align: center
font-size: 18px
margin-top: 0
margin-bottom: 40px
color: #555
font-weight: 200
.about
text-align: center
width: 450px
font-size: 13px
margin: 80px auto
color: #444
position: relative
z-index: 10
footer
text-align: center
color: #777
font-size: 14px
position: fixed
bottom: 10px
margin: 0
left: 50%
width: 500px
margin-left: -250px
z-index: 100
section
margin: 0 auto
width: 100%
padding: 20px 0
#createRoom
margin: 0 auto
width: 400px
position: relative
z-index: 10
input
width: 380px
height: 40px
border: 0px none
display: inline-block
font-size: 16px
padding: 0 10px
background: #eaebeb
border-radius: 3px
font-weight: 100
line-height: 40px
color: #333
font-weight: bold
margin: 0 0 10px 0
text-align: left
button
position: relative
width: 380px
#localVideo
position: fixed
top: 15px
right: 15px
border: 5px solid #777
outline: 0px
height: 70px
-o-transform: scaleX(-1)
transform: scaleX(-1)
#remotes
width: 100%
height: 100%
position: absolute
top: 100px
-webkit-perspective: 2000px
-moz-perspective: 2000px
z-index: 1
video
position: absolute
left: 4000px
height: 200px
-moz-transition: all 1s
-moz-box-sizing: border-box
-webkit-transition: all 1s
-webkit-box-sizing: border-box
#ad
cursor: pointer
a#ad:link, a#ad:visited
color: #555
text-decoration: none
font-weight: 300
font-size: 16px
border-top: 1px solid #f0f0f0
background-color: #fafafa
width: 100%
position: fixed
left: 0
right: 0
bottom: 0
padding: 0px
line-height: 2.5
text-align: left
height: 40px
&:before
content: ""
display: inline-block
float: left
background-image: url(https://andbang.com/images/AndBangHeader.png)
width: 35px
height: 35px
background-size: 40px
background-repeat: no-repeat
margin-right: 10px
#andyet
position: fixed
bottom: 10px
right: 10px
z-index: 10
#game
display: none
#game.gameActive
display: block
#game, #viewport
position: fixed
display: block
z-index: -1
height: calc(100% \- 20px)
height: -moz-calc(100% \- 20px)
width: 100%
top: 0
#instructions
display: none
background-color: rgba(0,0,0,.02)
border: 1px solid #eee
padding: 10px
top: 150px
left: 20px
width: 230px
text-align: left
h3
font-size: 16px
color: #333
font-weight: bold
text-align: left
margin-bottom: 20px
p
font-size: 13px
margin: 10px 0 0 0
button
border: none
height: 40px
padding: 0 1em
position: relative
border-radius: 3px
font-weight: bold
color: white
line-height: 40px
background: baseColor
&#pauseVideo
background: accentColor
&:hover
background: darken(accentColor, 10%)
&:hover
background: darken(baseColor, 10%)
.ss-icon
font-size: 12px
position: absolute
top: 3px
left: 12px

107
public/ui.css Normal file
View File

@ -0,0 +1,107 @@
#overlay {
position: fixed;
top: 0;
left: 0;
opacity: 1;
width: 100%;
height: 100%;
background: rgba(0,0,0,.75);
transition: opacity 300ms;
z-index: 500;
}
#overlay.hide {
pointer-events: none;
opacity: 0;
}#dialog {
position: fixed;
left: 50%;
top: 150px;
max-width: 600px;
min-width: 250px;
border: 1px solid #eee;
background: white;
z-index: 1000;
}
#dialog .content {
padding: 15px 20px;
}
#dialog h1 {
margin: 0 0 5px 0;
font-size: 16px;
font-weight: normal;
}
#dialog p {
margin: 0;
padding: 0;
font-size: .9em;
}
#dialog.modal {
box-shadow: 0 1px 8px 0 black;
}
/* close */
#dialog .close {
position: absolute;
top: 3px;
right: 10px;
text-decoration: none;
color: #888;
font-size: 16px;
font-weight: bold;
display: none;
}
#dialog.closable .close {
display: block;
}
#dialog .close:hover {
color: black;
}
#dialog .close:active {
margin-top: 1px;
}
/* slide */
#dialog.slide {
-webkit-transition: opacity 300ms, top 300ms;
-moz-transition: opacity 300ms, top 300ms;
}
#dialog.slide.hide {
opacity: 0;
top: -500px;
}
/* fade */
#dialog.fade {
-webkit-transition: opacity 300ms;
-moz-transition: opacity 300ms;
}
#dialog.fade.hide {
opacity: 0;
}
/* scale */
#dialog.scale {
-webkit-transition: -webkit-transform 300ms;
-moz-transition: -moz-transform 300ms;
-webkit-transform: scale(1);
-moz-transform: scale(1);
}
#dialog.scale.hide {
-webkit-transform: scale(0);
-moz-transform: scale(0);
}

74
server.js Normal file
View File

@ -0,0 +1,74 @@
/*global console*/
var fs = require('fs'),
privateKey = fs.readFileSync('fakekeys/privatekey.pem').toString(),
certificate = fs.readFileSync('fakekeys/certificate.pem').toString(),
express = require('express'),
app = express(),
server = require('https').createServer({key: privateKey, cert: certificate}, app),
connect = require('connect'),
RedisStore = require('connect-redis')(connect),
https = require('https'),
andbangAuth = require('andbang-express-auth'),
Moonboots = require('moonboots'),
config = require('getconfig'),
yetify = require('yetify'),
semiStatic = require('semi-static'),
uuid = require('node-uuid');
app.use(express.static(__dirname + '/public'));
app.enable('trust proxy');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
proxy: true,
secret: config.session.secret,
store: new RedisStore({
host: config.session.host,
port: config.session.port,
db: config.session.db
}),
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 90, // 90 days
secure: config.session.secure
},
key: 'c.io'
}));
app.use(andbangAuth.middleware({
app: app,
clientId: config.auth.id,
clientSecret: config.auth.secret,
defaultRedirect: '/',
local: config.isDev
}));
var clientApp = new Moonboots({
fileName: 'conversat.io',
dir: __dirname + '/clientapp',
developmentMode: config.isDev,
libraries: [
'system-requirements.js',
'mixpanel.js',
'check-system.js',
'jquery.js',
'jquery.slidingmessage.js',
'ui.js',
'socket.io.js',
'init.js'
],
server: app
});
// the help mini-site
app.get('/help*', semiStatic({
folderPath: __dirname + '/templates/help-site',
root: '/help'
}));
// serves app on every other url
app.get('*', clientApp.html());
server.listen(config.http.port);
console.log('conversat.io, by ' + yetify.logo() + ' running at: ' + config.http.baseUrl);

View File

@ -0,0 +1,25 @@
!!! 5
html
head
body
h1 conversat.io help
p conversat.io uses cutting edge web technology called WebRTC that is only available in <a href="http://chrome.com">chrome</a> and <a href="https://nightly.mozilla.org/">firefox 24+</a>.
h2#screensharing Screensharing
p Screensharing is currently only available in chrome and requires that you change a setting. If you're in chrome you can click right here:
ol
li download and open chrome.
li go to <a href="chrome://flags">chrome://flags</a> (click that link, or type it into the url bar.
li Scroll all the way to the bottom. And make sure that "enable screen capture support in getUserMedia()" is enabled:
p <img src="http://f.cl.ly/items/1v1x463V180530472p45/Screen%20Shot%202013-05-14%20at%2010.25.57%20AM.png" alt="screensharing setting screenshot" />
li click the "relaunch now" button at the bottom of the page.
li you should now be able to share your screen.
p note: you won't have to do these steps in a bit, when Google considers this feature stable enough. But hey, we can do screensharing now, so why not!? :)
h2#feedback We'd love to hear from you
p We'd love to hear from you: <a href="mailto:support@conversat.io">support@conversat.io</a>.

View File

@ -0,0 +1,38 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="16px" height="16px" viewBox="0 0 50 50">
<g>
<path d="M46.715,28.074c-0.012-0.022-0.027-0.044-0.039-0.067c-0.439-0.807-0.982-1.538-1.615-2.17l-8.635-8.634
c-0.035-0.036-0.068-0.066-0.098-0.092c-1.102-1.067-2.439-1.85-3.893-2.282c1.676,1.754,2.785,3.946,3.217,6.358
c0.127,0.723,0.193,1.462,0.193,2.197c0,0.293-0.014,0.602-0.039,0.943l5.381,5.382c0.469,0.469,0.816,1.058,1.002,1.706
c0.109,0.372,0.162,0.759,0.162,1.151c0,0.434-0.064,0.862-0.197,1.273c-0.197,0.618-0.521,1.157-0.967,1.602l-3.508,3.508
c-0.752,0.752-1.77,1.166-2.865,1.166s-2.115-0.414-2.865-1.166l-3.346-3.344l-2.164-2.166l-3.125-3.124
c-0.311-0.311-0.569-0.678-0.765-1.092c-0.26-0.546-0.397-1.159-0.397-1.772c0-0.414,0.061-0.824,0.18-1.217
c0.011-0.035,0.024-0.07,0.038-0.105l0.021-0.057c0.051-0.144,0.098-0.261,0.148-0.368c0.029-0.062,0.06-0.123,0.092-0.184
c0.059-0.111,0.125-0.22,0.202-0.337l0.032-0.048c0.023-0.035,0.046-0.071,0.071-0.105c0.128-0.174,0.251-0.32,0.378-0.445
l1.337-1.338c-0.015-0.159-0.051-0.301-0.109-0.422c-0.056-0.118-0.125-0.219-0.206-0.299L21.213,19.4l-0.23-0.23l-1.541,1.542
c-0.149,0.149-0.298,0.31-0.457,0.493c-0.023,0.026-0.045,0.055-0.068,0.083l-0.05,0.061c-0.105,0.125-0.206,0.252-0.304,0.382
c-0.033,0.043-0.064,0.088-0.097,0.132l-0.019,0.026c-0.096,0.134-0.188,0.27-0.276,0.408l-0.024,0.036
c-0.021,0.033-0.042,0.066-0.063,0.099c-0.103,0.169-0.203,0.341-0.292,0.509l-0.014,0.025l-0.013,0.024
c-0.313,0.596-0.564,1.23-0.747,1.889c-0.064,0.234-0.116,0.45-0.158,0.659c-0.128,0.639-0.193,1.283-0.193,1.924
c0,0.563,0.051,1.13,0.148,1.68c0.343,1.929,1.251,3.674,2.624,5.048l1.799,1.8l2.628,2.626l4.208,4.209
c3.715,3.715,9.76,3.715,13.477,0l3.508-3.509c1.201-1.202,2.059-2.72,2.479-4.393c0.199-0.795,0.301-1.584,0.301-2.346
c0-1.506-0.361-3.01-1.045-4.349c-0.008-0.016-0.016-0.032-0.021-0.049c-0.008-0.013-0.012-0.025-0.02-0.038
C46.744,28.116,46.73,28.096,46.715,28.074z"/>
<path d="M30.398,16.544L28.6,14.745l-2.627-2.626l-4.208-4.209c-3.715-3.714-9.76-3.714-13.476,0.001L4.78,11.419
c-1.202,1.2-2.058,2.72-2.479,4.391C2.102,16.605,2,17.394,2,18.157c0,1.505,0.362,3.008,1.045,4.348
c0.008,0.015,0.016,0.033,0.022,0.049c0.006,0.013,0.011,0.026,0.019,0.039c0.011,0.021,0.023,0.042,0.037,0.065
c0.014,0.022,0.027,0.044,0.04,0.068c0.44,0.808,0.984,1.537,1.616,2.168l8.634,8.634c0.036,0.037,0.068,0.067,0.1,0.093
c1.1,1.067,2.437,1.85,3.891,2.281c-1.675-1.755-2.785-3.946-3.214-6.357c-0.129-0.72-0.196-1.46-0.196-2.197
c0-0.291,0.013-0.6,0.039-0.943l-5.382-5.383c-0.468-0.468-0.815-1.058-1.001-1.706c-0.108-0.372-0.163-0.757-0.163-1.15
c0-0.434,0.067-0.863,0.198-1.274c0.198-0.619,0.522-1.158,0.967-1.601l3.509-3.509c1.554-1.554,4.179-1.554,5.731,0l3.345,3.345
l2.165,2.165l3.124,3.125c0.312,0.311,0.568,0.678,0.766,1.092c0.26,0.545,0.396,1.157,0.396,1.772c0,0.415-0.061,0.824-0.18,1.217
c-0.012,0.036-0.023,0.071-0.037,0.107l-0.021,0.055c-0.051,0.145-0.098,0.261-0.148,0.368c-0.027,0.062-0.061,0.123-0.094,0.184
c-0.059,0.112-0.125,0.225-0.199,0.337l-0.031,0.044c-0.021,0.038-0.047,0.074-0.072,0.108c-0.129,0.174-0.252,0.32-0.377,0.446
l-1.339,1.338c0.015,0.159,0.051,0.301,0.11,0.423c0.056,0.117,0.124,0.219,0.205,0.298l3.124,3.125l0.23,0.229l1.541-1.541
c0.146-0.146,0.297-0.309,0.457-0.493c0.023-0.027,0.049-0.056,0.07-0.084l0.047-0.058c0.105-0.127,0.207-0.254,0.305-0.384
c0.039-0.052,0.076-0.104,0.113-0.157c0.098-0.135,0.189-0.271,0.279-0.408l0.029-0.046l0.055-0.089
c0.105-0.168,0.203-0.339,0.295-0.51l0.012-0.022l0.014-0.025c0.312-0.595,0.564-1.229,0.748-1.888
c0.062-0.228,0.113-0.444,0.156-0.661c0.129-0.637,0.193-1.282,0.193-1.922c0-0.564-0.051-1.13-0.148-1.68
C32.68,19.663,31.771,17.918,30.398,16.544z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

64
templates/join.jade Normal file
View File

@ -0,0 +1,64 @@
extends layout
block content
a(href='/')
h1#logo
img(src='conversatio.png', height='64', width='480', alt='Conversat.io')
h2
span#title Get a room.
p.desc Video chat with up to 6 people.
h3#roomLink
| include includes/link.svg
span#subTitle
form#createRoom
input#sessionInput(placeholder='Name the conversation', autofocus='autofocus')
button(type='submit') Lets go!
p.about
| Requires Chrome or Firefox Nightly with peer connection enabled.
br
| conversat.io uses
a(href='https://github.com/henrikjoreteg/SimpleWebRTC') the simple WebRTC library
| from
a(href='http://andyet.com') &yet
| and so can you.
video#localVideo
.controls
button#shareScreen
span.share
i.ss-icon windows
| Share screen
span.unshare
i.ss-icon windows
| Unshare screen
button#muteMicrophone
span.mute
i.ss-icon volume
| Mute
span.unmute
i.ss-icon volumehigh
| Unmute
button#pauseVideo
span.pause
i.ss-icon pause
| Pause
span.resume
i.ss-icon play
| Resume
//
controls
#remotes
#game
aside#instructions(style='position: absolute;')
h3 Play lander while you wait for people to join.
p Arrow keys control the ship
p
code r
| restarts
p
code x
| blows up your ship
p Have fun!
canvas#viewport

26
templates/layout.jade Normal file
View File

@ -0,0 +1,26 @@
!!! 5
html
head
title conversat.io
meta(charset='utf-8')
link(rel='stylesheet', href='style.css')
link(rel='stylesheet', href='fonts.css')
meta(name='google-site-verification', content='OEAv0Phoo4ZRGpC-GIVt-WpSDQU8wtQerm6s9PToCVY')
script(src='//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js')
script(src='socket.io.js')
script(src='fluidgrid.js')
script(src='sound-effect-manager.js')
script(src='jquery.slidingmessage.js')
script(src='retina.js')
script(src='simplewebrtc.js')
script(src='conversat.io.js')
script(async='async', src='awesome-andbang-ad.js')
script(async='async', src='metrics.js')
body
.wrap
section
block content
footer
a#ad(href='http://andbang.com', target='_blank')
a#andyet(href='http://andyet.com', target='_blank')
img(src='http://andyet.com/images/logo.png', width='40')

Some files were not shown because too many files have changed in this diff Show More