<commit_before>var URIManager = {
    initialPopStateHasRun: false,

    init: function() {
        window.addEventListener('popstate', function(event) {
            // Chrome throws an initial popState, http://dropshado.ws/post/15251622664/ignore-initial-popstate
			var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
            if (isChrome && !URIManager.initialPopStateHasRun) {
                URIManager.initialPopStateHasRun = true;
                return;
            }
            URIManager.loadState();
        });
        URIManager.loadWarnings();
        URIManager.loadState();
    },
    loadWarnings: function() {
        if (window.top !== window.self) {
            Notifications.append('This address is not affiliated with Youtify. Always use www.youtify.com');
        }
    },
    loadState: function() {
        var handlers = [
            [
                '/search',
                function(matches) {
                    var q = '';
                    if (location.search) {
                        q = decodeURI(location.search.match('q=(.*)')[1]);
                    }
                    $('#top .search input').val(q).keyup();
                }
            ],
            [
                '/tracks/(.*)/(.*)',
                function(matches) {
                    vid = new Video({
                        videoId: matches[2],
                        type: matches[1]
                    });
                    if (player.initialized) {
                        player.play(vid);
                    } else {
                        EventSystem.addEventListener('player_manager_initialized', function() {
                            player.play(vid);
                        });
                    }
                }
            ],
            [
                '/toplist/playlists',
                function(matches) {
                    Toplist.popularPlaylistsTab.select();
                }
            ],
            [
                '/playlists/(.*)',
                function(matches) {
                    loadPlaylist(matches[1]);
                }
            ],
            [
                '/profile',
                function(matches) {
                    Menu.profile.select();
                }
            ],
            [
                '/users/(.*)',
                function(matches) {
                    UserManager.doFakeProfileMenuClick();
                    UserManager.loadProfile(matches[1]);
                }
            ],
            [
                '/(.+)',
                function(matches) {
                    UserManager.doFakeProfileMenuClick();
                    UserManager.loadProfile(matches[1]);
                }
            ],
            [
                '/',
                function(matches) {
                    Menu.find('toplist').select();
                }
            ]
        ];

        var i;
        for (i = 0; i < handlers.length; i += 1) {
            var handler = handlers[i];
            var matches = location.pathname.match(handler[0]);
            if (matches) {
                handler[1](matches);
                break;
            }
        }
    }
};

<commit_msg>Add track to queue if opened via direct link<commit_after>var URIManager = {
    initialPopStateHasRun: false,

    init: function() {
        window.addEventListener('popstate', function(event) {
            // Chrome throws an initial popState, http://dropshado.ws/post/15251622664/ignore-initial-popstate
			var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
            if (isChrome && !URIManager.initialPopStateHasRun) {
                URIManager.initialPopStateHasRun = true;
                return;
            }
            URIManager.loadState();
        });
        URIManager.loadWarnings();
        URIManager.loadState();
    },
    loadWarnings: function() {
        if (window.top !== window.self) {
            Notifications.append('This address is not affiliated with Youtify. Always use www.youtify.com');
        }
    },
    loadState: function() {
        var handlers = [
            [
                '/search',
                function(matches) {
                    var q = '';
                    if (location.search) {
                        q = decodeURI(location.search.match('q=(.*)')[1]);
                    }
                    $('#top .search input').val(q).keyup();
                }
            ],
            [
                '/tracks/(.*)/(.*)',
                function(matches) {
                    vid = new Video({
                        videoId: matches[2],
                        type: matches[1]
                    });
                    if (player.initialized) {
                        player.play(vid);
                    } else {
                        EventSystem.addEventListener('player_manager_initialized', function() {
                            player.play(vid);
                        });
                    }
                    EventSystem.addEventListener('video_info_fetched', function(info) {
                        var hasRunOnce = false;
                        if (!hasRunOnce) {
                            hasRunOnce = true;
                            vid.title = info.title;
                            vid.createListView();
                            Queue.setAutoQueue([vid]);
                        }
                    });
                    $('#left .queue').mousedown();
                }
            ],
            [
                '/toplist/playlists',
                function(matches) {
                    Toplist.popularPlaylistsTab.select();
                }
            ],
            [
                '/playlists/(.*)',
                function(matches) {
                    loadPlaylist(matches[1]);
                }
            ],
            [
                '/profile',
                function(matches) {
                    Menu.profile.select();
                }
            ],
            [
                '/users/(.*)',
                function(matches) {
                    UserManager.doFakeProfileMenuClick();
                    UserManager.loadProfile(matches[1]);
                }
            ],
            [
                '/(.+)',
                function(matches) {
                    UserManager.doFakeProfileMenuClick();
                    UserManager.loadProfile(matches[1]);
                }
            ],
            [
                '/',
                function(matches) {
                    Menu.find('toplist').select();
                }
            ]
        ];

        var i;
        for (i = 0; i < handlers.length; i += 1) {
            var handler = handlers[i];
            var matches = location.pathname.match(handler[0]);
            if (matches) {
                handler[1](matches);
                break;
            }
        }
    }
};

<|endoftext|>


<commit_before>const { Koapi, router, middlewares, logger } = require('../lib')
const request = require('supertest')
const internal = []
const { afterAll, describe, it, expect } = global

afterAll(() => internal.forEach(server => server.close()))

const setup = (config) => {
  let app = new Koapi()
  app.compress()
  config(app)
  let server = app.listen(null)
  internal.push(server)
  return {app, server}
}

describe('basic', () => {
  const {server} = setup(app => app)
  it('server should get 404 not found', () => {
    const res = request(server).get('/').set('Accept', 'application/json').then(res => expect(res.status).toBe(404))
    return res
  })
})

describe('advanced', () => {
  let { server } = setup(app => {
    app.use(middlewares.jsonError({emit: false}))
    app.use(async (ctx, next) => {
      try {
        await next()
      } catch (e) { throw e }
    })
    app.routers([
      (new router.Router()).get('/', async ctx => { ctx.body = 'Hello World' }).routes(),
      router.define(router => router.get('/test', async ctx => { ctx.body = 'test' })),
      router.define(router => router.get('/error', async ctx => { throw new Error('error') }))
    ])
  })
  it('should get 200 ok', () =>
    request(server)
      .get('/')
      .then(res => {
        expect(res.status).toBe(200)
        expect(res.text).toBe('Hello World')
      })
  )
  it('should get 500 ok', () => request(server)
                                .get('/error')
                                .then(res => {
                                  expect(res.status).toBe(500)
                                  expect(res.body.message).toBe('error')
                                }))
  it('should get 200 ok', () => request(server)
                                .get('/test')
                                .then(res => {
                                  expect(res.status).toBe(200)
                                  expect(res.text).toBe('test')
                                }))
  it('should have _specs', () => request(server)
                                  .get('/_specs')
                                  .set('Accept', 'application/json')
                                  .then(res => {
                                    expect(res.status).toBe(200)
                                  }))
})

describe('haha', () => {
  let { server } = setup(app => {
    app.routers([
      middlewares.subdomain('api.*', (new router.Router()).get('/', ctx => { ctx.body = 'api' }).routes()),
      (new router.Router()).get('/', ctx => { ctx.body = 'index' }).routes()
    ])
  })

  it('subdomain should get index', () => request(server)
                                .get('/')
                                .then(res => {
                                  expect(res.text).toBe('index')
                                  expect(res.status).toBe(200)
                                }))
  it('subdomain should get api', () => request(server)
                              .get('/')
                              .set('Host', 'api.test.com')
                              .then(res => {
                                expect(res.status).toBe(200)
                                expect(res.text).toBe('api')
                              }))
  it('subdomain should have _specs', () => request(server)
                                  .get('/_specs')
                                  .set('Accept', 'application/json')
                                  .then(res => {
                                    expect(res.status).toBe(200)
                                  }))
})
<commit_msg>tidy up<commit_after>const { Koapi, router, middlewares } = require('../lib')
const request = require('supertest')
const internal = []
const { afterAll, describe, it, expect } = global

afterAll(() => internal.forEach(server => server.close()))

const setup = (config) => {
  let app = new Koapi()
  app.compress()
  config(app)
  let server = app.listen(null)
  internal.push(server)
  return {app, server}
}

describe('basic', () => {
  const {server} = setup(app => app)
  it('server should get 404 not found', () => {
    const res = request(server).get('/').set('Accept', 'application/json').then(res => expect(res.status).toBe(404))
    return res
  })
})

describe('advanced', () => {
  let { server } = setup(app => {
    app.use(middlewares.jsonError({emit: false}))
    app.use(async (ctx, next) => {
      try {
        await next()
      } catch (e) { throw e }
    })
    app.routers([
      (new router.Router()).get('/', async ctx => { ctx.body = 'Hello World' }).routes(),
      router.define(router => router.get('/test', async ctx => { ctx.body = 'test' })),
      router.define(router => router.get('/error', async ctx => { throw new Error('error') }))
    ])
  })
  it('should get 200 ok', () =>
    request(server)
      .get('/')
      .then(res => {
        expect(res.status).toBe(200)
        expect(res.text).toBe('Hello World')
      })
  )
  it('should get 500 ok', () => request(server)
                                .get('/error')
                                .then(res => {
                                  expect(res.status).toBe(500)
                                  expect(res.body.message).toBe('error')
                                }))
  it('should get 200 ok', () => request(server)
                                .get('/test')
                                .then(res => {
                                  expect(res.status).toBe(200)
                                  expect(res.text).toBe('test')
                                }))
  it('should have _specs', () => request(server)
                                  .get('/_specs')
                                  .set('Accept', 'application/json')
                                  .then(res => {
                                    expect(res.status).toBe(200)
                                  }))
})

describe('haha', () => {
  let { server } = setup(app => {
    app.routers([
      middlewares.subdomain('api.*', (new router.Router()).get('/', ctx => { ctx.body = 'api' }).routes()),
      (new router.Router()).get('/', ctx => { ctx.body = 'index' }).routes()
    ])
  })

  it('subdomain should get index', () => request(server)
                                .get('/')
                                .then(res => {
                                  expect(res.text).toBe('index')
                                  expect(res.status).toBe(200)
                                }))
  it('subdomain should get api', () => request(server)
                              .get('/')
                              .set('Host', 'api.test.com')
                              .then(res => {
                                expect(res.status).toBe(200)
                                expect(res.text).toBe('api')
                              }))
  it('subdomain should have _specs', () => request(server)
                                  .get('/_specs')
                                  .set('Accept', 'application/json')
                                  .then(res => {
                                    expect(res.status).toBe(200)
                                  }))
})
<|endoftext|>


<commit_before>/*
Adding new router config.
routerConfig:{
    router:type Object
    publishMethod:type String,
    useDefaultRouter:type Boolean
}*/
var exec = require('cordova/exec'), cordova = require('cordova'),
channel = require('cordova/channel'),
    utils = require('cordova/utils');
    var url,uname,pass,iscls,router = null;
    var isDefault = true;

    exports.connect = function(args){
        //SSL support is coming soon
        //var urgx = /(^(tcp|ssl|local)&?:\/\/[^\s]+\:[^\s]{2,})/g;
        var urgx = /(^(tcp|local)&?:\/\/[^\s]+\:[^\s]{2,})/g;
        if (args.port!==undefined) {
            url = args.url+":"+args.port;
        } else{
            url = args.url;
        };
        if (args.willTopicConfig!==undefined) {
            if(args.willTopicConfig.retain===undefined){
                args.willTopicConfig.retain = true;
            }
        } else {
            args.willTopicConfig = new Object();
        }
        if (args.isCleanSession===undefined) {
            iscls = true;
        } else {
            iscls = args.isCleanSession;
        }
        if (args.routerConfig!==undefined) {
            if(Object.keys(args.routerConfig).length>0){
                if (!args.routerConfig.useDefaultRouter&&args.routerConfig.useDefaultRouter!==undefined) {
                    if(args.routerConfig.router!==undefined){
                        router = args.routerConfig.router;
                        isDefault = useDefaultRouter;
                    } else{
                        console.error("Please set your topic router object");
                    }
                } else {
                    //using default topic router
                    router = new ME();
                }

            }else{
                //setting mqtt-emitter instance as default router
                router = new ME();
            }
        } else {
            router = new ME();
        }
        if(url.length>0&&urgx.exec(url)!==null){
            exec(function(cd){
                switch(cd.call){
                    case "connected":
                        delete cd['call'];
                        if(args.success!==undefined){
                            args.success(cd);
                        };
                        cordova.fireDocumentEvent("connected",cd);
                        console.warn("Cordova Plugin Warning: The eventListner implmentation to read the published payloads shall be discontinued from the 0.3.0 version. Kindly take a note of this change.")
                        break;
                    case "disconnected":
                        delete cd['call'];
                        if(args.error!==undefined){
                            args.error(cd);
                        };
                        cordova.fireDocumentEvent("disconnected",cd);
                        break;
                    case "failure":
                        delete cd['call'];
                        if(args.onConnectionLost!==undefined){
                            args.onConnectionLost(cd);
                        };
                        cordova.fireDocumentEvent("failure",cd);
                        break;
                    case "onPublish":
                        delete cd['call'];
                        if(args.onPublish!==undefined){
                            args.onPublish(cd.topic,cd.payload);
                        }
                        if(router!==null){
                            if (args.routerConfig!==undefined) {
                                if (args.routerConfig.publishMethod!==undefined) {
                                    router[args.routerConfig.publishMethod](cd.topic,cd.payload);
                                }

                            } else {
                                router.emit(cd.topic,cd.payload);
                            }

                        }
                        cordova.fireDocumentEvent(cd.topic,cd);
                        break;
                    default:
                        console.log(cd);
                        break;
                }
            }, function(e){
                console.error(e);
            }, "CordovaMqTTPlugin", "connect", [url,args.clientId,args.keepAlive||60,iscls,args.connectionTimeout||30,args.username, args.password,args.willTopicConfig.topic,args.willTopicConfig.payload,args.willTopicConfig.qos||0,args.willTopicConfig.retain||true,args.version||"3.1.1"]);
        } else{
            console.error("Please provide the URL to connect. If entered then please check the URL format. We support only tcp:// & local:// protocols");
        }

    }
    exports.publish = function(args){
        (args.retain===undefined) ? args.retain=false : args.retain=true;
        if(args.topic.length>0){
            exec(function(data){
                cordova.fireDocumentEvent(data);
                switch(data.call){
                    case "success":
                        delete data['call'];
                        if(args.success!=undefined){
                            args.success(data);
                        }

                        break;
                    case "failure":
                        delete data['call'];
                        if(args.success!=undefined){
                            args.error(data);
                        }
                        break;
                }
            }, function(e){
                if(args.error!=undefined){
                    args.error(e);
                }
            }, "CordovaMqTTPlugin", "publish", [args.topic,args.payload,args.qos||0,args.retain]);
        } else{
            console.error("Please provide a topic string in topic argument");
        }

    }
    exports.subscribe = function(args){
        (args.retain===undefined) ? args.retain=false : args.retain=true;
        if(args.topic.length>0){
            exec(function(data){
                switch(data.call){
                    case "success":
                        delete data['call'];
                        if (args.success!==undefined) {
                            args.success(data);
                        }
                        break;
                    case "failure":
                        delete data['call'];
                        if (args.error!==undefined) {
                            args.error(data);
                        }

                        break;
                }
            }, function(e){
                console.error(e);
                args.error(e);
            }, "CordovaMqTTPlugin", "subscribe", [args.topic,args.qos||0]);
        } else{
            console.error("Please provide a topic string in topic argument");
        }

    }
    exports.unsubscribe = function(args){
        if(args.topic.length > 0){
            exec(function(data){
                switch(data.call){
                    case "success":
                        delete data['call'];
                        if (args.success!==undefined) {
                            args.success(data);
                        }
                        if (router!==null) {
                            router.removeListener(args.topic);
                        }
                        break;
                    case "failure":
                        delete data['call'];
                        if (args.error!==undefined) {
                            args.error(data);
                        }
                        break;
                }
            }, function(e){
                console.error(e);
                args.error(e);
            }, "CordovaMqTTPlugin", "unsubscribe", [args.topic]);
        } else{
            console.error("Please provide a topic string in topic argument");
        }
    }
    exports.disconnect = function(args){
        exec(function(data){
            switch(data.call){
                case "success":
                    delete data['call'];
                    if (args.success!==undefined) {
                        args.success(data);
                    }
                    break;
                case "failure":
                    delete data['call'];
                    if (args.error!==undefined) {
                        args.error(data);
                    }
                    break;
            }
        }, function(e){
            console.error(e);
            args.error(e);
        }, "CordovaMqTTPlugin", "disconnect", []);
    }
    exports.router = function() {
        if (router!==null) {
            return router;
        } else {
            console.error("Router object seems to be destroyed");
        }

    }
    exports.listen = function (topic,cb) {
        if (router!==null) {
            router.on(topic,cb);
        } else {
            console.error("Router object seems to be destroyed");
        }
    }
<commit_msg>Better url regex<commit_after>/*
Adding new router config.
routerConfig:{
    router:type Object
    publishMethod:type String,
    useDefaultRouter:type Boolean
}*/
var exec = require('cordova/exec'), cordova = require('cordova'),
channel = require('cordova/channel'),
    utils = require('cordova/utils');
    var url,uname,pass,iscls,router = null;
    var isDefault = true;

    exports.connect = function(args){
        //SSL support is coming soon
        //var urgx = //(^(tcp|ssl|local)&?:\/\/[^\@_?!]+[^\s]+[^\.]+\:\d{2,})/g;
        var urgx = /(^(tcp|local)&?:\/\/[^\@_?!]+[^\s]+[^\.]+\:\d{2,})/g;
        if (args.port!==undefined) {
            url = args.url+":"+args.port;
        } else{
            url = args.url;
        };
        if (args.willTopicConfig!==undefined) {
            if(args.willTopicConfig.retain===undefined){
                args.willTopicConfig.retain = true;
            }
        } else {
            args.willTopicConfig = new Object();
        }
        if (args.isCleanSession===undefined) {
            iscls = true;
        } else {
            iscls = args.isCleanSession;
        }
        if (args.routerConfig!==undefined) {
            if(Object.keys(args.routerConfig).length>0){
                if (!args.routerConfig.useDefaultRouter&&args.routerConfig.useDefaultRouter!==undefined) {
                    if(args.routerConfig.router!==undefined){
                        router = args.routerConfig.router;
                        isDefault = useDefaultRouter;
                    } else{
                        console.error("Please set your topic router object");
                    }
                } else {
                    //using default topic router
                    router = new ME();
                }

            }else{
                //setting mqtt-emitter instance as default router
                router = new ME();
            }
        } else {
            router = new ME();
        }
        if(url.length>0&&urgx.exec(url)!==null){
            exec(function(cd){
                switch(cd.call){
                    case "connected":
                        delete cd['call'];
                        if(args.success!==undefined){
                            args.success(cd);
                        };
                        cordova.fireDocumentEvent("connected",cd);
                        console.warn("Cordova Plugin Warning: The eventListner implmentation to read the published payloads shall be discontinued from the 0.3.0 version. Kindly take a note of this change.")
                        break;
                    case "disconnected":
                        delete cd['call'];
                        if(args.error!==undefined){
                            args.error(cd);
                        };
                        cordova.fireDocumentEvent("disconnected",cd);
                        break;
                    case "failure":
                        delete cd['call'];
                        if(args.onConnectionLost!==undefined){
                            args.onConnectionLost(cd);
                        };
                        cordova.fireDocumentEvent("failure",cd);
                        break;
                    case "onPublish":
                        delete cd['call'];
                        if(args.onPublish!==undefined){
                            args.onPublish(cd.topic,cd.payload);
                        }
                        if(router!==null){
                            if (args.routerConfig!==undefined) {
                                if (args.routerConfig.publishMethod!==undefined) {
                                    router[args.routerConfig.publishMethod](cd.topic,cd.payload);
                                }

                            } else {
                                router.emit(cd.topic,cd.payload);
                            }

                        }
                        cordova.fireDocumentEvent(cd.topic,cd);
                        break;
                    default:
                        console.log(cd);
                        break;
                }
            }, function(e){
                console.error(e);
            }, "CordovaMqTTPlugin", "connect", [url,args.clientId,args.keepAlive||60,iscls,args.connectionTimeout||30,args.username, args.password,args.willTopicConfig.topic,args.willTopicConfig.payload,args.willTopicConfig.qos||0,args.willTopicConfig.retain||true,args.version||"3.1.1"]);
        } else{
            console.error("Please provide the URL to connect. If entered then please check the URL format. We support only tcp:// & local:// protocols");
        }

    }
    exports.publish = function(args){
        (args.retain===undefined) ? args.retain=false : args.retain=true;
        if(args.topic.length>0){
            exec(function(data){
                cordova.fireDocumentEvent(data);
                switch(data.call){
                    case "success":
                        delete data['call'];
                        if(args.success!=undefined){
                            args.success(data);
                        }

                        break;
                    case "failure":
                        delete data['call'];
                        if(args.success!=undefined){
                            args.error(data);
                        }
                        break;
                }
            }, function(e){
                if(args.error!=undefined){
                    args.error(e);
                }
            }, "CordovaMqTTPlugin", "publish", [args.topic,args.payload,args.qos||0,args.retain]);
        } else{
            console.error("Please provide a topic string in topic argument");
        }

    }
    exports.subscribe = function(args){
        (args.retain===undefined) ? args.retain=false : args.retain=true;
        if(args.topic.length>0){
            exec(function(data){
                switch(data.call){
                    case "success":
                        delete data['call'];
                        if (args.success!==undefined) {
                            args.success(data);
                        }
                        break;
                    case "failure":
                        delete data['call'];
                        if (args.error!==undefined) {
                            args.error(data);
                        }

                        break;
                }
            }, function(e){
                console.error(e);
                args.error(e);
            }, "CordovaMqTTPlugin", "subscribe", [args.topic,args.qos||0]);
        } else{
            console.error("Please provide a topic string in topic argument");
        }

    }
    exports.unsubscribe = function(args){
        if(args.topic.length > 0){
            exec(function(data){
                switch(data.call){
                    case "success":
                        delete data['call'];
                        if (args.success!==undefined) {
                            args.success(data);
                        }
                        if (router!==null) {
                            router.removeListener(args.topic);
                        }
                        break;
                    case "failure":
                        delete data['call'];
                        if (args.error!==undefined) {
                            args.error(data);
                        }
                        break;
                }
            }, function(e){
                console.error(e);
                args.error(e);
            }, "CordovaMqTTPlugin", "unsubscribe", [args.topic]);
        } else{
            console.error("Please provide a topic string in topic argument");
        }
    }
    exports.disconnect = function(args){
        exec(function(data){
            switch(data.call){
                case "success":
                    delete data['call'];
                    if (args.success!==undefined) {
                        args.success(data);
                    }
                    break;
                case "failure":
                    delete data['call'];
                    if (args.error!==undefined) {
                        args.error(data);
                    }
                    break;
            }
        }, function(e){
            console.error(e);
            args.error(e);
        }, "CordovaMqTTPlugin", "disconnect", []);
    }
    exports.router = function() {
        if (router!==null) {
            return router;
        } else {
            console.error("Router object seems to be destroyed");
        }

    }
    exports.listen = function (topic,cb) {
        if (router!==null) {
            router.on(topic,cb);
        } else {
            console.error("Router object seems to be destroyed");
        }
    }
<|endoftext|>


<commit_before>var
// Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,

// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash
rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,

// Alias for function
slice = [].slice,
keys = Object.keys,

// Alias for global variables
doc = document,
win = window,

isString = function(el) {
    return typeof el === "string";
},

isObject = function(el) {
    return el instanceof Object;
},

jBone = function(element, data) {
    if (this instanceof jBone) {
        return init.call(this, element, data);
    } else {
        return new jBone(element, data);
    }
},

init = function(element, data) {
    var elements;

    if (typeof element === "function") {
        element();
    } else if (element instanceof jBone) {
        return element;
    } else if (Array.isArray(element)) {
        elements = element.map(function(el) {
            return getElement(el, data);
        });
    } else if (element) {
        elements = getElement(element, data);
    }

    if (elements instanceof jBone) {
        return elements;
    }

    if (!elements) {
        return this;
    }

    elements = Array.isArray(elements) ? elements : [elements];
    jBone.merge(this, elements);

    if (isObject(data) && !jBone.isElement(data)) {
        this.attr(data);
    }

    return this;
},

getElement = function(element, context) {
    var tag, wraper, fragment = doc.createDocumentFragment();

    if (isString(element) && (tag = rsingleTag.exec(element))) {
        return doc.createElement(tag[1]);
    } else if (isString(element) && (tag = rquickExpr.exec(element)) && tag[1]) {
        wraper = doc.createElement("div");
        wraper.innerHTML = element;
        while(wraper.childNodes.length) {
            fragment.appendChild(wraper.firstChild);
        }
        return slice.call(fragment.childNodes);
    } else if (isString(element)) {
        if (jBone.isElement(context)) {
            return jBone(context).find(element);
        }

        try {
            return slice.call(doc.querySelectorAll(element));
        } catch (e) {
            return;
        }
    }

    return element;
};

jBone.setId = function(el) {
    var jid = el.jid;

    if (el === win) {
        jid = "window";
    } else if (el.jid === undefined) {
        el.jid = jid = ++jBone._cache.jid;
    }

    if (!jBone._cache.events[jid]) {
        jBone._cache.events[jid] = {};
    }
};

jBone.getData = function(el) {
    el = el instanceof jBone ? el[0] : el;

    var jid = el === win ? "window" : el.jid;

    return {
        jid: jid,
        events: jBone._cache.events[jid]
    };
};

jBone.isElement = function(el) {
    return el instanceof jBone || el instanceof HTMLElement || isString(el);
};

jBone._cache = {
    events: {},
    jid: 0
};

jBone.fn = jBone.prototype = [];
<commit_msg>Performance improvements<commit_after>var
// Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,

// A simple way to check for HTML strings
// Prioritize #id over <tag> to avoid XSS via location.hash
rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,

// Alias for function
slice = [].slice,
keys = Object.keys,

// Alias for global variables
doc = document,
win = window,

isString = function(el) {
    return typeof el === "string";
},

isObject = function(el) {
    return el instanceof Object;
},

jBone = function(element, data) {
    return new jBone.fn.init(element, data);
};

jBone.fn = jBone.prototype = [];

jBone.fn.constructor = jBone;

jBone.fn.init = function(element, data) {
    var elements, tag, wraper, fragment;

    if (typeof element === "string") {
        // Create single DOM element
        if (tag = rsingleTag.exec(element)) {
            this[0] = doc.createElement(tag[1]);
            this.length = 1;

            if (isObject(data)) {
                this.attr(data);
            }

            return this;
        }
        // Create DOM collection
        else if ((tag = rquickExpr.exec(element)) && tag[1]) {
            fragment = doc.createDocumentFragment();
            wraper = doc.createElement("div");
            wraper.innerHTML = element;
            while(wraper.childNodes.length) {
                fragment.appendChild(wraper.firstChild);
            }
            elements = slice.call(fragment.childNodes);

            return jBone.merge(this, elements);
        }
        // Find DOM elements with querySelectorAll
        else {
            if (jBone.isElement(data)) {
                return jBone(data).find(element);
            }

            try {
                elements = slice.call(doc.querySelectorAll(element));

                return jBone.merge(this, elements);
            } catch (e) {
                return this;
            }
        }
    }
    // Run function
    else if (typeof element === "function") {
        return element();
    }
    // Return jBone element as is
    else if (element instanceof jBone) {
        return element;
    }
    // Return element wrapped by jBone
    else {
        element = Array.isArray(element) ? element : [element];
        return jBone.merge(this, element);
    }

    return this;
};

jBone.fn.init.prototype = jBone.fn;

jBone.setId = function(el) {
    var jid = el.jid;

    if (el === win) {
        jid = "window";
    } else if (el.jid === undefined) {
        el.jid = jid = ++jBone._cache.jid;
    }

    if (!jBone._cache.events[jid]) {
        jBone._cache.events[jid] = {};
    }
};

jBone.getData = function(el) {
    el = el instanceof jBone ? el[0] : el;

    var jid = el === win ? "window" : el.jid;

    return {
        jid: jid,
        events: jBone._cache.events[jid]
    };
};

jBone.isElement = function(el) {
    return el instanceof jBone || el instanceof HTMLElement || isString(el);
};

jBone._cache = {
    events: {},
    jid: 0
};
<|endoftext|>


<commit_before>// The main logic for your project goes in this file.

var PLANE_MOVE_SPEED = 250;
var ANGLE_FACTOR = 0.1;
var DIRECTION_LEFT = 1;
var DIRECTION_RIGHT = 2;
var UNIT = 30;
var showZoomLevel = true;
/**
 * The {@link Player} object; an {@link Actor} controlled by user input.
 */
var player;
var inProcess=false;
/**
 * Control codes
 * Yiyang
 */
/**
 * Keys used for various directions.
 *
 * The property names of this object indicate actions, and the values are lists
 * of keyboard keys or key combinations that will invoke these actions. Valid
 * keys include anything that {@link jQuery.hotkeys} accepts. The up, down,
 * left, and right properties are required if the `keys` variable exists; if
 * you don't want to use them, just set them to an empty array. {@link Actor}s
 * can have their own {@link Actor#keys keys} which will override the global
 * set.
 */
var keysCustom = {
  up: ['up', 'w'],
  down: ['down', 's'],
  left: ['left', 'a'],
  right: ['right', 'd'],
};

Leap.loop({enableGestures: true}, function(frame) {
    if (!inProcess)
    frame.hands.forEach(function(hand, index) {
        //output.innerHTML = 'Frame: ' + frame.id + ' roll: ' + hand.roll();
        //output.innerHTML = frame.toString() +'
'+hand.toString();
        rotationalAngle=hand.roll();
        MAX_ROTATIONAL_ANGLE=1.2;
        MIN_ROTATIONAL_ANGLE=0.1;
        ROLL_FACTOR=0.2;

        if (rotationalAngle<0) {//right
            if (rotationalAngle<-MAX_ROTATIONAL_ANGLE)
                move(DIRECTION_RIGHT, ANGLE_FACTOR*MAX_ROTATIONAL_ANGLE*MAX_ROTATIONAL_ANGLE*ROLL_FACTOR);
            else if (rotationalAngle<-MIN_ROTATIONAL_ANGLE)
                move(DIRECTION_RIGHT, ANGLE_FACTOR*rotationalAngle*rotationalAngle*ROLL_FACTOR);
        }
        else
            if (rotationalAngle>MAX_ROTATIONAL_ANGLE)
                move(DIRECTION_LEFT, ANGLE_FACTOR*MAX_ROTATIONAL_ANGLE*MAX_ROTATIONAL_ANGLE*ROLL_FACTOR);
            else if (rotationalAngle>MIN_ROTATIONAL_ANGLE)
                move(DIRECTION_LEFT, ANGLE_FACTOR*rotationalAngle*rotationalAngle*ROLL_FACTOR);

        if (hand.pitch()>0.2 && PLANE_MOVE_SPEED>20) PLANE_MOVE_SPEED-=1.1*hand.pitch(); //lift the tip of the hand to slow down
        else if (hand.pitch()<-0.2) PLANE_MOVE_SPEED-=1.1*hand.pitch();
    });

    if(frame.valid && frame.gestures.length > 0 && !inProcess){
        inProcess=true;
        frame.gestures.forEach(function(gesture){
            switch (gesture.type){
                case "circle":
                    console.log("Circle Gesture");
                    tmp=PLANE_MOVE_SPEED;
                    PLANE_MOVE_SPEED=tmp;
                    var clockwise = false;
                    var direction = frame.pointable(pointableID).direction;
                    var dotProduct = Leap.vec3.dot(direction, gesture.normal);
                    if (dotProduct  >  0) clockwise = true;
                    for (i=0;i<10;i++){
                        if (clockwise)
                        move(DIRECTION_RIGHT, 0.005);
                        else move(DIRECTION_LEFT, 0.005);
                        update();
                    }
                    PLANE_MOVE_SPEED=tmp;
                    break;
                case "keyTap":
                    console.log("Key Tap Gesture");
                    break;
                case "screenTap":
                    console.log("Screen Tap Gesture");
                    break;
                case "swipe":
                    console.log("Swipe Gesture");
                    break;
            }
        });
        inProcess=false;
    }

}).use('screenPosition', {scale: 0.5});

/**
 * Resources and Images Part
 * Jinyao
 * @type {Array}
 */
var background;
var mapWidth = 4;   // in 1024x1024 tiles
var mapHeight = 3;  // in 1024x1024 tiles

var preloadables = ['js/app/images/skyTile.png',
                    'js/app/images/aeroMap.png'];

/**
 * Game logic
 * Zhu Liang
 */

/**
 * Actors belonging to a Team that fight other Soldiers.
 */
var Plane = Player.extend({
    MOVEAMOUNT: PLANE_MOVE_SPEED,
    CONTINUOUS_MOVEMENT: true,
    //DEFAULT_WIDTH: SOLDIER_SIZE,
    //DEFAULT_HEIGHT: SOLDIER_SIZE,
    //NEAR_THRESHOLD: SHOOT_NEAR_THRESHOLD,
    //SHOOT_DELAY: RELOAD_DELAY,
    team: null,
    selected: false,
    moveToX: 0,
    moveToY: 0,
    //health: SOLDIER_MAX_HEALTH,
    lastShot: 0,
    //Orientation of the plane, to be multiplied to PI
    orientation: 0,
    init: function(team, x, y) {
        this._super.call(this, x, y);
        this.team = team;
        this.lastShot = App.physicsTimeElapsed;
        this.orientation = 0;
        //if (team != myTeam) return; // Only allow selecting the player's team
        var t = this;
        // Allow selecting soldiers by clicking on them
        this.listen('mousedown.select touchstart.select', function(e) {
            // Left click or touch only
            if (typeof e !== 'undefined' && e.type == 'mousedown' && e.which !== 1) {
                return;
            }
            // Holding down CTRL allows selecting multiple soldiers.
            //if (!jQuery.hotkeys.areKeysDown('ctrl')) {
            //    t.team.soldiers.forEach(function(soldier) {
            //        soldier.selected = false;
            //    });
            //}
            console.log("selected");
            t.toggleSelected.call(t);
            // Don't bubble the event
            e.stopPropagation();
        });
    },
    /**
     * Draw a soldier with colors and a health indicator.
     */
    drawDefault: function(ctx, x, y, w, h) {
        // Draw the soldier
        //this.fillStyle = this.selected ? this.team.soldierSelectedColor :
        //    (this.isHovered() ? this.team.soldierHoverColor : this.team.soldierColor);
        this._super.call(this, ctx, x, y, w, h);

        // Draw the health indicator
        //drawProgressBar(ctx, x, y - 10, w, h*0.2, this.health/SOLDIER_MAX_HEALTH,
        //    '#00DA00', '#EA3311', 'black');
    },
    toggleSelected: function() {
        this.selected = !this.selected;
        // Stop moving
        this.moveToX = this.xC();
        this.moveToY = this.yC();
    },
    moveTo: function(x, y) {
        this.moveToX = x;
        this.moveToY = y;
    },
    /**
     * Choose the best direction in order to move towards the target.
     *
     * Since this is just an example, the algorithm is simple: move directly
     * towards the target. A more sophisticated algorithm should avoid obstacles.
     */
    chooseBestDirection: function() {
        var dir = [];
        if (this.xC() < this.moveToX - 1) dir.push(keys.right[0]);
        else if (this.xC() > this.moveToX + 1) dir.push(keys.left[0]);
        if (this.yC() < this.moveToY - 1) dir.push(keys.down[0]);
        else if (this.yC() > this.moveToY + 1) dir.push(keys.up[0]);
        return dir;
    },
    /**
     * Cause damage to the soldier's health.
     */
    damage: function(dmg) {
        this.health -= dmg;
    },
    /**
     * Whether this soldier is close enough to another soldier to shoot.
     */
    near: function(other) {
        return (this.x-other.x)*(this.x-other.x) +
            (this.y-other.y)*(this.y-other.y) <
            this.NEAR_THRESHOLD*this.NEAR_THRESHOLD;
    },
    /**
     * Shoot at a target soldier.
     */
    shoot: function(target) {
        if (App.physicsTimeElapsed > this.lastShot + this.SHOOT_DELAY) {
            this.lastShot = App.physicsTimeElapsed;
            bullets.add(new Projectile(
                    this.x+this.width*0.5,
                    this.y+this.width*0.5,
                this.team,
                target
            ));
        }
    },
    destroy: function() {
        this._super.apply(this, arguments);
        this.unlisten('.select');
        this.team.soldiers.remove(this);
    }
});

function move(direction, turn_angle) {
    if(direction == DIRECTION_LEFT){
        player.orientation -= turn_angle;
        player.radians-= turn_angle*Math.PI;
    }else{
        player.orientation += turn_angle;
        player.radians+= turn_angle*Math.PI;
    }
    if (player.orientation <= -2 || player.orientation >= 2) {
        player.orientation = 0;
        player.radians = 0;
    }
    console.log(player.orientation);
}
/**
 * Record the last key pressed so the player moves in the correct direction.
 */
jQuery(document).keydown(keysCustom.up.concat(keysCustom.down, keysCustom.left, keysCustom.right).join(' '), function(e) {
    console.log(e.keyPressed);
    if(e.keyPressed == keysCustom.right[1]){
        move(DIRECTION_RIGHT, ANGLE_FACTOR);
    }else if(e.keyPressed == keysCustom.left[1]){
        move(DIRECTION_LEFT, ANGLE_FACTOR);
    }
});

/**
 * A magic-named function where all updates should occur.
 */
function update() {
    //Offset for the default orientation towards the right
    player.setVelocityVector(Math.PI * (player.orientation+1.5), PLANE_MOVE_SPEED);
    player.update();
}

function advanceToLevel(level){
    var $level = jQuery('#level .level').text(level);
}

/**
 * A magic-named function where all drawing should occur.
 */
function draw() {

  // Draw the background layer
  background.draw();

	player.draw();
}

/**
 * Zooming with Leap Motion
 * @param direction
 * <0 means zoom in, >0 means zoom out
 */
function leapZoom(direction) {
    // Avoid overzealous scrolling causing unexpected zooming
    if (lastZoom + Mouse.Zoom.ZOOM_TIMEOUT > App.physicsTimeElapsed) return;
    if (++numScrollEvents < Mouse.Zoom.MIN_SCROLL_EVENTS) return;
    lastZoom = App.physicsTimeElapsed;
    numScrollEvents = 0;

    // Get an indication of the direction of the scroll.
    // Depending on the browser, OS, and device settings, the actual value
    // could be in pixels, lines, pages, degrees, or arbitrary units, so all
    // we can consistently deduce from this is the direction.
    var delta = e.originalEvent.deltaY || -e.originalEvent.wheelDelta;
    // We want to scroll in around the mouse coordinates.
    var mx = player.x,
        my = player.y;
    // Scroll up; zoom in
    if (direction < 0) {
        if (world.scale > Mouse.Zoom.MIN_ZOOM) {
            world.scaleResolution(world.scale - Mouse.Zoom.ZOOM_STEP, mx, my);
            /**
             * @event zoom
             *   Fires on the document when the user zooms in or out.
             *
             * @param {Boolean} zoomIn
             *   Whether the user zoomed in or out.
             *
             * @member global
             */
            jQuery(document).trigger('zoom', true);
        }
    }
    // Scroll down; zoom out
    else {
        if (world.scale < Mouse.Zoom.MAX_ZOOM) {
            world.scaleResolution(world.scale + Mouse.Zoom.ZOOM_STEP, mx, my);
            jQuery(document).trigger('zoom', false);
        }
    }
}

/**
 * A magic-named function for one-time setup.
 *
 * @param {Boolean} first
 *   true if the app is being set up for the first time; false if the app has
 *   been reset and is starting over.
 */
function setup(first) {
  // Change the size of the playable area. Do this before placing items!
  if(first) {
    world.resize(1024 * mapWidth, 1024 * mapHeight);
  }

    //Level related
    jQuery('body').append('
' +
        'Current Level' +
        '0
');
    advanceToLevel(1);

  // Switch from side view to top-down.
  Actor.prototype.GRAVITY = false;

  // Set up the background layer
  background = new Layer();
  background.context.drawPattern('js/app/images/skyTile.png', 0, 0, world.width, world.height);

  // Initialize the player.
  player = new Plane();
  player.src = new SpriteMap('js/app/images/AeroMap.png',
  {stand: [0, 0, 0, 23]},
  {frameW: 256, frameH: 256,
  interval: 20, useTimer: false});

  player.setVelocityVector(Math.PI * player.orientation, PLANE_MOVE_SPEED);
  console.log(player.getVelocityVector());

// Enable zooming, and display the zoom level indicator
    Mouse.Zoom.enable(showZoomLevel);
}
<commit_msg>fix aero* case sensitive<commit_after>// The main logic for your project goes in this file.

var PLANE_MOVE_SPEED = 250;
var ANGLE_FACTOR = 0.1;
var DIRECTION_LEFT = 1;
var DIRECTION_RIGHT = 2;
var UNIT = 30;
var showZoomLevel = true;
/**
 * The {@link Player} object; an {@link Actor} controlled by user input.
 */
var player;
var inProcess=false;
/**
 * Control codes
 * Yiyang
 */
/**
 * Keys used for various directions.
 *
 * The property names of this object indicate actions, and the values are lists
 * of keyboard keys or key combinations that will invoke these actions. Valid
 * keys include anything that {@link jQuery.hotkeys} accepts. The up, down,
 * left, and right properties are required if the `keys` variable exists; if
 * you don't want to use them, just set them to an empty array. {@link Actor}s
 * can have their own {@link Actor#keys keys} which will override the global
 * set.
 */
var keysCustom = {
  up: ['up', 'w'],
  down: ['down', 's'],
  left: ['left', 'a'],
  right: ['right', 'd'],
};

Leap.loop({enableGestures: true}, function(frame) {
    if (!inProcess)
    frame.hands.forEach(function(hand, index) {
        //output.innerHTML = 'Frame: ' + frame.id + ' roll: ' + hand.roll();
        //output.innerHTML = frame.toString() +'
'+hand.toString();
        rotationalAngle=hand.roll();
        MAX_ROTATIONAL_ANGLE=1.2;
        MIN_ROTATIONAL_ANGLE=0.1;
        ROLL_FACTOR=0.2;

        if (rotationalAngle<0) {//right
            if (rotationalAngle<-MAX_ROTATIONAL_ANGLE)
                move(DIRECTION_RIGHT, ANGLE_FACTOR*MAX_ROTATIONAL_ANGLE*MAX_ROTATIONAL_ANGLE*ROLL_FACTOR);
            else if (rotationalAngle<-MIN_ROTATIONAL_ANGLE)
                move(DIRECTION_RIGHT, ANGLE_FACTOR*rotationalAngle*rotationalAngle*ROLL_FACTOR);
        }
        else
            if (rotationalAngle>MAX_ROTATIONAL_ANGLE)
                move(DIRECTION_LEFT, ANGLE_FACTOR*MAX_ROTATIONAL_ANGLE*MAX_ROTATIONAL_ANGLE*ROLL_FACTOR);
            else if (rotationalAngle>MIN_ROTATIONAL_ANGLE)
                move(DIRECTION_LEFT, ANGLE_FACTOR*rotationalAngle*rotationalAngle*ROLL_FACTOR);

        if (hand.pitch()>0.2 && PLANE_MOVE_SPEED>20) PLANE_MOVE_SPEED-=1.1*hand.pitch(); //lift the tip of the hand to slow down
        else if (hand.pitch()<-0.2) PLANE_MOVE_SPEED-=1.1*hand.pitch();
    });

    if(frame.valid && frame.gestures.length > 0 && !inProcess){
        inProcess=true;
        frame.gestures.forEach(function(gesture){
            switch (gesture.type){
                case "circle":
                    console.log("Circle Gesture");
                    tmp=PLANE_MOVE_SPEED;
                    PLANE_MOVE_SPEED=tmp;
                    var clockwise = false;
                    var direction = frame.pointable(pointableID).direction;
                    var dotProduct = Leap.vec3.dot(direction, gesture.normal);
                    if (dotProduct  >  0) clockwise = true;
                    for (i=0;i<10;i++){
                        if (clockwise)
                        move(DIRECTION_RIGHT, 0.005);
                        else move(DIRECTION_LEFT, 0.005);
                        update();
                    }
                    PLANE_MOVE_SPEED=tmp;
                    break;
                case "keyTap":
                    console.log("Key Tap Gesture");
                    break;
                case "screenTap":
                    console.log("Screen Tap Gesture");
                    break;
                case "swipe":
                    console.log("Swipe Gesture");
                    break;
            }
        });
        inProcess=false;
    }

}).use('screenPosition', {scale: 0.5});

/**
 * Resources and Images Part
 * Jinyao
 * @type {Array}
 */
var background;
var mapWidth = 4;   // in 1024x1024 tiles
var mapHeight = 3;  // in 1024x1024 tiles

var preloadables = ['js/app/images/skyTile.png',
                    'js/app/images/AeroMap.png'];

/**
 * Game logic
 * Zhu Liang
 */

/**
 * Actors belonging to a Team that fight other Soldiers.
 */
var Plane = Player.extend({
    MOVEAMOUNT: PLANE_MOVE_SPEED,
    CONTINUOUS_MOVEMENT: true,
    //DEFAULT_WIDTH: SOLDIER_SIZE,
    //DEFAULT_HEIGHT: SOLDIER_SIZE,
    //NEAR_THRESHOLD: SHOOT_NEAR_THRESHOLD,
    //SHOOT_DELAY: RELOAD_DELAY,
    team: null,
    selected: false,
    moveToX: 0,
    moveToY: 0,
    //health: SOLDIER_MAX_HEALTH,
    lastShot: 0,
    //Orientation of the plane, to be multiplied to PI
    orientation: 0,
    init: function(team, x, y) {
        this._super.call(this, x, y);
        this.team = team;
        this.lastShot = App.physicsTimeElapsed;
        this.orientation = 0;
        //if (team != myTeam) return; // Only allow selecting the player's team
        var t = this;
        // Allow selecting soldiers by clicking on them
        this.listen('mousedown.select touchstart.select', function(e) {
            // Left click or touch only
            if (typeof e !== 'undefined' && e.type == 'mousedown' && e.which !== 1) {
                return;
            }
            // Holding down CTRL allows selecting multiple soldiers.
            //if (!jQuery.hotkeys.areKeysDown('ctrl')) {
            //    t.team.soldiers.forEach(function(soldier) {
            //        soldier.selected = false;
            //    });
            //}
            console.log("selected");
            t.toggleSelected.call(t);
            // Don't bubble the event
            e.stopPropagation();
        });
    },
    /**
     * Draw a soldier with colors and a health indicator.
     */
    drawDefault: function(ctx, x, y, w, h) {
        // Draw the soldier
        //this.fillStyle = this.selected ? this.team.soldierSelectedColor :
        //    (this.isHovered() ? this.team.soldierHoverColor : this.team.soldierColor);
        this._super.call(this, ctx, x, y, w, h);

        // Draw the health indicator
        //drawProgressBar(ctx, x, y - 10, w, h*0.2, this.health/SOLDIER_MAX_HEALTH,
        //    '#00DA00', '#EA3311', 'black');
    },
    toggleSelected: function() {
        this.selected = !this.selected;
        // Stop moving
        this.moveToX = this.xC();
        this.moveToY = this.yC();
    },
    moveTo: function(x, y) {
        this.moveToX = x;
        this.moveToY = y;
    },
    /**
     * Choose the best direction in order to move towards the target.
     *
     * Since this is just an example, the algorithm is simple: move directly
     * towards the target. A more sophisticated algorithm should avoid obstacles.
     */
    chooseBestDirection: function() {
        var dir = [];
        if (this.xC() < this.moveToX - 1) dir.push(keys.right[0]);
        else if (this.xC() > this.moveToX + 1) dir.push(keys.left[0]);
        if (this.yC() < this.moveToY - 1) dir.push(keys.down[0]);
        else if (this.yC() > this.moveToY + 1) dir.push(keys.up[0]);
        return dir;
    },
    /**
     * Cause damage to the soldier's health.
     */
    damage: function(dmg) {
        this.health -= dmg;
    },
    /**
     * Whether this soldier is close enough to another soldier to shoot.
     */
    near: function(other) {
        return (this.x-other.x)*(this.x-other.x) +
            (this.y-other.y)*(this.y-other.y) <
            this.NEAR_THRESHOLD*this.NEAR_THRESHOLD;
    },
    /**
     * Shoot at a target soldier.
     */
    shoot: function(target) {
        if (App.physicsTimeElapsed > this.lastShot + this.SHOOT_DELAY) {
            this.lastShot = App.physicsTimeElapsed;
            bullets.add(new Projectile(
                    this.x+this.width*0.5,
                    this.y+this.width*0.5,
                this.team,
                target
            ));
        }
    },
    destroy: function() {
        this._super.apply(this, arguments);
        this.unlisten('.select');
        this.team.soldiers.remove(this);
    }
});

function move(direction, turn_angle) {
    if(direction == DIRECTION_LEFT){
        player.orientation -= turn_angle;
        player.radians-= turn_angle*Math.PI;
    }else{
        player.orientation += turn_angle;
        player.radians+= turn_angle*Math.PI;
    }
    if (player.orientation <= -2 || player.orientation >= 2) {
        player.orientation = 0;
        player.radians = 0;
    }
    console.log(player.orientation);
}
/**
 * Record the last key pressed so the player moves in the correct direction.
 */
jQuery(document).keydown(keysCustom.up.concat(keysCustom.down, keysCustom.left, keysCustom.right).join(' '), function(e) {
    console.log(e.keyPressed);
    if(e.keyPressed == keysCustom.right[1]){
        move(DIRECTION_RIGHT, ANGLE_FACTOR);
    }else if(e.keyPressed == keysCustom.left[1]){
        move(DIRECTION_LEFT, ANGLE_FACTOR);
    }
});

/**
 * A magic-named function where all updates should occur.
 */
function update() {
    //Offset for the default orientation towards the right
    player.setVelocityVector(Math.PI * (player.orientation+1.5), PLANE_MOVE_SPEED);
    player.update();
}

function advanceToLevel(level){
    var $level = jQuery('#level .level').text(level);
}

/**
 * A magic-named function where all drawing should occur.
 */
function draw() {

  // Draw the background layer
  background.draw();

	player.draw();
}

/**
 * Zooming with Leap Motion
 * @param direction
 * <0 means zoom in, >0 means zoom out
 */
function leapZoom(direction) {
    // Avoid overzealous scrolling causing unexpected zooming
    if (lastZoom + Mouse.Zoom.ZOOM_TIMEOUT > App.physicsTimeElapsed) return;
    if (++numScrollEvents < Mouse.Zoom.MIN_SCROLL_EVENTS) return;
    lastZoom = App.physicsTimeElapsed;
    numScrollEvents = 0;

    // Get an indication of the direction of the scroll.
    // Depending on the browser, OS, and device settings, the actual value
    // could be in pixels, lines, pages, degrees, or arbitrary units, so all
    // we can consistently deduce from this is the direction.
    var delta = e.originalEvent.deltaY || -e.originalEvent.wheelDelta;
    // We want to scroll in around the mouse coordinates.
    var mx = player.x,
        my = player.y;
    // Scroll up; zoom in
    if (direction < 0) {
        if (world.scale > Mouse.Zoom.MIN_ZOOM) {
            world.scaleResolution(world.scale - Mouse.Zoom.ZOOM_STEP, mx, my);
            /**
             * @event zoom
             *   Fires on the document when the user zooms in or out.
             *
             * @param {Boolean} zoomIn
             *   Whether the user zoomed in or out.
             *
             * @member global
             */
            jQuery(document).trigger('zoom', true);
        }
    }
    // Scroll down; zoom out
    else {
        if (world.scale < Mouse.Zoom.MAX_ZOOM) {
            world.scaleResolution(world.scale + Mouse.Zoom.ZOOM_STEP, mx, my);
            jQuery(document).trigger('zoom', false);
        }
    }
}

/**
 * A magic-named function for one-time setup.
 *
 * @param {Boolean} first
 *   true if the app is being set up for the first time; false if the app has
 *   been reset and is starting over.
 */
function setup(first) {
  // Change the size of the playable area. Do this before placing items!
  if(first) {
    world.resize(1024 * mapWidth, 1024 * mapHeight);
  }

    //Level related
    jQuery('body').append('
' +
        'Current Level' +
        '0
');
    advanceToLevel(1);

  // Switch from side view to top-down.
  Actor.prototype.GRAVITY = false;

  // Set up the background layer
  background = new Layer();
  background.context.drawPattern('js/app/images/skyTile.png', 0, 0, world.width, world.height);

  // Initialize the player.
  player = new Plane();
  player.src = new SpriteMap('js/app/images/AeroMap.png',
  {stand: [0, 0, 0, 23]},
  {frameW: 256, frameH: 256,
  interval: 20, useTimer: false});

  player.setVelocityVector(Math.PI * player.orientation, PLANE_MOVE_SPEED);
  console.log(player.getVelocityVector());

// Enable zooming, and display the zoom level indicator
    Mouse.Zoom.enable(showZoomLevel);
}
<|endoftext|>


<commit_before>!(function(){
  var width = innerWidth,
      height = innerHeight;

  var canvas = d3.select('#background-canvas').append("canvas")
      .attr({width: width, height: height})

  d3.select(window).on('resize.background', function(){
    width  = innerWidth
    height = innerHeight
    canvas.attr({width: width, height: height})
  })

  var ctx = canvas.node().getContext("2d");

  ctx.fillStyle = '#f94600'
  ctx.fillRect(0, 0, width, height)

  var shapes = [],
      curTime = 0,
      l = 14,
      unload = function(){ shapes = shapes.filter(function(d){ d.start > curTime }) }

  d3.timer(function(t){
    curTime = t

    shapes.forEach(function(s, i){
      if (t < s.start || i > 8000) return

      var u = (t - s.start)/(s.end - s.start)

      if (u > 1){
        u = 1
        s.done = true
      }

      ctx.fillStyle = s.fill
      if (s.type == 'rect'){
        var a0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var a1 = s.sV[1]*(1 - u) + s.eV[1]*u
        var a2 = s.sV[2]*(1 - u) + s.eV[2]*u
        var a3 = s.sV[3]*(1 - u) + s.eV[3]*u
        ctx.fillRect(a0, a1, a2, a3)
      }
      if (s.type == 'circle'){
        var a0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var a1 = s.sV[1]*(1 - u) + s.eV[1]*u
        var a2 = s.sV[2]*(1 - u) + s.eV[2]*u

        ctx.beginPath()
        ctx.arc(a0, a1, a2, 0, Math.PI*2, true)
        ctx.closePath()
        ctx.fill()
      }
      if (s.type == 'triangle'){
        var x0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var y0 = s.sV[1]*(1 - u) + s.eV[1]*u
        var x1 = s.sV[2]*(1 - u) + s.eV[2]*u
        var y1 = s.sV[3]*(1 - u) + s.eV[3]*u
        var x2 = s.sV[4]*(1 - u) + s.eV[4]*u
        var y2 = s.sV[5]*(1 - u) + s.eV[5]*u

        ctx.beginPath()
        ctx.moveTo(x0, y0)
        ctx.lineTo(x1, y1)
        ctx.lineTo(x2, y2)
        ctx.closePath()
        ctx.fill()
      }
    })

    shapes = shapes.filter(function(s){ return !s.done })
  })

  // wave squares
  !(function(){
    var module = {sel: d3.select('.sectionNum4'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(1, 4)
    var offset = 1

    setInterval(function(){
      if (!module.active) return
      var speed = Math.random()*.0003 + .2
      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 4)) return
          if (Math.random() < .3) return
          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + (i + j)*40*speed + Math.random()*200,
              sV: [x, y, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 10 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 800)
  })()
  //sprial squares
  !(function(){
    var module = {sel: d3.select('.sectionNum2'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 2)) return
          if (Math.random() < .3) return

          var d = Math.random() < .5  //shape moves down
          var r = Math.random() < .5  //shape moves left

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + d*1000 + r*1000 + (d && !r)*1000*2 + Math.random()*400,
              sV: [r ? x : x + l, d ? y : y + l, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 18 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 5/4*1000)
  })()

  //triangles
  !(function(){
    var module = {sel: d3.select('.sectionNum7'), active: false, minWidth: 300, onunload: unload}

    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      var x0 = Math.cos(Math.PI/6 + Math.PI*6/3)*l*3
      var y0 = Math.sin(Math.PI/6 + Math.PI*6/3)*l*3
      var x1 = Math.cos(Math.PI/6 + Math.PI*2/3)*l*3
      var y1 = Math.sin(Math.PI/6 + Math.PI*2/3)*l*3
      var x2 = Math.cos(Math.PI/6 + Math.PI*4/3)*l*3
      var y2 = Math.sin(Math.PI/6 + Math.PI*4/3)*l*3

      offset++
      d3.range(0, width + l, l*3).forEach(function(x, i){
        d3.range(0, height + l, l*3).forEach(function(y, j){
          // if (!!((i + j + offset) % 2)) return
          if (Math.random() < .9) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'triangle',
              start: curTime + 1000 - j*30,
              sV: [x, y, x, y, x, y],
              eV: [x + x0, y + y0, x + x1, y + y1, x + x2, y + y2],
              fill: offset % 18 ? colors[offset % 3] : 'white'
            }

          if (offset % 3 == 0){
            shape.sV[0] += x0
            shape.sV[1] += y0
            shape.sV[2] += x1
            shape.sV[3] += y1
          }
          if (offset % 3 == 1){
            shape.sV[2] += x1
            shape.sV[3] += y1
            shape.sV[4] += x2
            shape.sV[5] += y2

          }
          if (offset % 3 == 2){
            shape.sV[0] += x0
            shape.sV[1] += y0

            shape.sV[4] += x2
            shape.sV[5] += y2
          }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 1*1000)
  })()

  //tears
  !(function(){
    var module = {sel: d3.select('.sectionNum6'), active: false, minWidth: 300, onunload: unload}

    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      var size = Math.random()
      d3.range(0, width + l, l*10).forEach(function(x, i){
        d3.range(0, height + l, l*10).forEach(function(y, j){
          // if (!!((i + j + offset) % 2)) return
          if (Math.random() < .7) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'circle',
              start: curTime + Math.random()*1500,
              sV: [x, y - 200 , 0],
              eV: [x, y, l*3 + size*l*5*size],
              fill: offset % 18 ? colors[((Math.random() < .3) + offset) % 3] : 'white'
            }
          shape.end = shape.start + 1500 + size*400
          shapes.push(shape)
        })
      })

    }, 1500)
  })()

  //circles
  !(function(){
    var module = {sel: d3.select('.sectionNum5'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      var size = Math.random()
      d3.range(0, width + l, l*10).forEach(function(x, i){
        d3.range(0, height + l, l*10).forEach(function(y, j){
          // if (!!((i + j + offset) % 2)) return
          // if (Math.random() < .3) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'circle',
              start: curTime + Math.random()*4,
              sV: [x, y, 0],
              eV: [x, y, l*3 + Math.random()*l*5*size],
              fill: offset % 18 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 1500
          shapes.push(shape)
        })
      })

    }, 1500/2.3)
  })()

  //different sized squares
  !(function(){
    var module = {sel: d3.select('#background-hook'), active: false, minWidth: 300, onunload: unload}

    //wait 2 sec to auto play, looks v. laggey otherwise
    setTimeout(function(){
      module.active = true
    }, 2800)

    addModule(module)

    // Object.observe(module, function (changes){
    //   console.log("Changes:");
    //   console.log(changes.name);
    //   if (!module.active) debugger
    // })

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      var sizeI = Math.ceil(Math.random()*3.5 + .5)
      // size = Math.floor((offset % 2) + Math.random()*2.5)
      // size = offset % 5
      var size = sizeI*sizeI*.8
      d3.range(0, width + l, l*size).forEach(function(x, i){
        d3.range(0, height + l, l*size).forEach(function(y, j){
          if (!!((i + j + sizeI + (Math.random() < .1)) % 2)) return
          if (Math.random() < .3) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + Math.random()*4,
              sV: [x + l*size/2, y + l*size/2, 0, 0],
              eV: [x, y, l*size, l*size],
              fill: offset % 18 ? colors[offset % 3] : 'white'
            }
          if (size > 4) shape.fill = colors[Math.floor(Math.random()*3)]
          shape.end = shape.start +800
          shapes.push(shape)
        })
      })

    }, 1/4*1000)
  })()

  //down wave
  !(function(){
    var module = {sel: d3.select('.sectionNum3'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(2, 5)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      var speed = Math.random()*.5 + .5
      speed = 1
      offset++
      var m = offset % 4
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!((i + j + offset) % 5)) return
          if (Math.random() < .6) return

          var stagger = speed*40 + Math.random()*5
          var start = curTime
          var sV = []
          if        (m == 0){
            start += j*stagger
            sV = [x, y, l, 0]
          } else if (m == 1){
            start += (width /l - i)*stagger
            sV = [x + l, y, 0, l]
          } else if (m == 2){
            start += (height/l - j)*stagger
            sV = [x, y + l, l, 0]
          } else if (m == 3){
            start += i*stagger
            sV = [x, y, 0, l]
          }

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: start,
              sV: sV,
              eV: [x, y, l, l],
              fill: offset % 10 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 200*Math.random()
          shapes.push(shape)
        })
      })

    }, 2000)
  })()

})();

<commit_msg>updates first color set<commit_after>!(function(){
  var width = innerWidth,
      height = innerHeight;

  var canvas = d3.select('#background-canvas').append("canvas")
      .attr({width: width, height: height})

  d3.select(window).on('resize.background', function(){
    width  = innerWidth
    height = innerHeight
    canvas.attr({width: width, height: height})
  })

  var ctx = canvas.node().getContext("2d");

  ctx.fillStyle = '#f94600'
  ctx.fillRect(0, 0, width, height)

  var shapes = [],
      curTime = 0,
      l = 14,
      unload = function(){ shapes = shapes.filter(function(d){ d.start > curTime }) }

  d3.timer(function(t){
    curTime = t

    shapes.forEach(function(s, i){
      if (t < s.start || i > 8000) return

      var u = (t - s.start)/(s.end - s.start)

      if (u > 1){
        u = 1
        s.done = true
      }

      ctx.fillStyle = s.fill
      if (s.type == 'rect'){
        var a0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var a1 = s.sV[1]*(1 - u) + s.eV[1]*u
        var a2 = s.sV[2]*(1 - u) + s.eV[2]*u
        var a3 = s.sV[3]*(1 - u) + s.eV[3]*u
        ctx.fillRect(a0, a1, a2, a3)
      }
      if (s.type == 'circle'){
        var a0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var a1 = s.sV[1]*(1 - u) + s.eV[1]*u
        var a2 = s.sV[2]*(1 - u) + s.eV[2]*u

        ctx.beginPath()
        ctx.arc(a0, a1, a2, 0, Math.PI*2, true)
        ctx.closePath()
        ctx.fill()
      }
      if (s.type == 'triangle'){
        var x0 = s.sV[0]*(1 - u) + s.eV[0]*u
        var y0 = s.sV[1]*(1 - u) + s.eV[1]*u
        var x1 = s.sV[2]*(1 - u) + s.eV[2]*u
        var y1 = s.sV[3]*(1 - u) + s.eV[3]*u
        var x2 = s.sV[4]*(1 - u) + s.eV[4]*u
        var y2 = s.sV[5]*(1 - u) + s.eV[5]*u

        ctx.beginPath()
        ctx.moveTo(x0, y0)
        ctx.lineTo(x1, y1)
        ctx.lineTo(x2, y2)
        ctx.closePath()
        ctx.fill()
      }
    })

    shapes = shapes.filter(function(s){ return !s.done })
  })

  // wave squares
  !(function(){
    var module = {sel: d3.select('.sectionNum4'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(1, 4)
    var offset = 1

    setInterval(function(){
      if (!module.active) return
      var speed = Math.random()*.0003 + .2
      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 4)) return
          if (Math.random() < .3) return
          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + (i + j)*40*speed + Math.random()*200,
              sV: [x, y, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 1000 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 800)
  })()
  //sprial squares
  !(function(){
    var module = {sel: d3.select('.sectionNum2'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!!((i + j + offset) % 2)) return
          if (Math.random() < .3) return

          var d = Math.random() < .5  //shape moves down
          var r = Math.random() < .5  //shape moves left

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + d*1000 + r*1000 + (d && !r)*1000*2 + Math.random()*400,
              sV: [r ? x : x + l, d ? y : y + l, 0, 0],
              eV: [x, y, l, l],
              fill: offset % 1800 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 5/4*1000)
  })()

  //triangles
  !(function(){
    var module = {sel: d3.select('.sectionNum7'), active: false, minWidth: 300, onunload: unload}

    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      var x0 = Math.cos(Math.PI/6 + Math.PI*6/3)*l*3
      var y0 = Math.sin(Math.PI/6 + Math.PI*6/3)*l*3
      var x1 = Math.cos(Math.PI/6 + Math.PI*2/3)*l*3
      var y1 = Math.sin(Math.PI/6 + Math.PI*2/3)*l*3
      var x2 = Math.cos(Math.PI/6 + Math.PI*4/3)*l*3
      var y2 = Math.sin(Math.PI/6 + Math.PI*4/3)*l*3

      offset++
      d3.range(0, width + l, l*3).forEach(function(x, i){
        d3.range(0, height + l, l*3).forEach(function(y, j){
          // if (!!((i + j + offset) % 2)) return
          if (Math.random() < .9) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'triangle',
              start: curTime + 1000 - j*30,
              sV: [x, y, x, y, x, y],
              eV: [x + x0, y + y0, x + x1, y + y1, x + x2, y + y2],
              fill: offset % 1800 ? colors[offset % 3] : 'white'
            }

          if (offset % 3 == 0){
            shape.sV[0] += x0
            shape.sV[1] += y0
            shape.sV[2] += x1
            shape.sV[3] += y1
          }
          if (offset % 3 == 1){
            shape.sV[2] += x1
            shape.sV[3] += y1
            shape.sV[4] += x2
            shape.sV[5] += y2

          }
          if (offset % 3 == 2){
            shape.sV[0] += x0
            shape.sV[1] += y0

            shape.sV[4] += x2
            shape.sV[5] += y2
          }
          shape.end = shape.start + 500
          shapes.push(shape)
        })
      })

    }, 1*1000)
  })()

  //tears
  !(function(){
    var module = {sel: d3.select('.sectionNum6'), active: false, minWidth: 300, onunload: unload}

    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      var size = Math.random()
      d3.range(0, width + l, l*10).forEach(function(x, i){
        d3.range(0, height + l, l*10).forEach(function(y, j){
          // if (!!((i + j + offset) % 2)) return
          if (Math.random() < .7) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'circle',
              start: curTime + Math.random()*1500,
              sV: [x, y - 200 , 0],
              eV: [x, y, l*3 + size*l*5*size],
              fill: offset % 1800 ? colors[((Math.random() < .3) + offset) % 3] : 'white'
            }
          shape.end = shape.start + 1500 + size*400
          shapes.push(shape)
        })
      })

    }, 1500)
  })()

  //circles
  !(function(){
    var module = {sel: d3.select('.sectionNum5'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(0, 3)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      var size = Math.random()
      d3.range(0, width + l, l*10).forEach(function(x, i){
        d3.range(0, height + l, l*10).forEach(function(y, j){
          // if (!!((i + j + offset) % 2)) return
          // if (Math.random() < .3) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'circle',
              start: curTime + Math.random()*4,
              sV: [x, y, 0],
              eV: [x, y, l*3 + Math.random()*l*5*size],
              fill: offset % 1800 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 1500
          shapes.push(shape)
        })
      })

    }, 1500/2.3)
  })()

  //different sized squares
  !(function(){
    var module = {sel: d3.select('#background-hook'), active: false, minWidth: 300, onunload: unload}

    //wait 2 sec to auto play, looks v. laggey otherwise
    setTimeout(function(){
      module.active = true
    }, 2800)
    //pause after 5
    setTimeout(function(){
      module.active = false
    }, 10800)

    addModule(module)

    var colors = [red, purple]
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      offset++
      var sizeI = Math.ceil(Math.random()*3.5 + .5)
      // size = Math.floor((offset % 2) + Math.random()*2.5)
      // size = offset % 5
      var size = sizeI*sizeI*.8
      d3.range(0, width + l, l*size).forEach(function(x, i){
        d3.range(0, height + l, l*size).forEach(function(y, j){
          if (!!((i + j + sizeI + (Math.random() < .1)) % 2)) return
          if (Math.random() < .3) return

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: curTime + Math.random()*4,
              sV: [x + l*size/2, y + l*size/2, 0, 0],
              eV: [x, y, l*size, l*size],
              fill: offset % 1800 ? colors[offset % 2] : 'white'
            }
          if (size > 4) shape.fill = colors[Math.floor(Math.random()*2)]
          shape.end = shape.start +800
          shapes.push(shape)
        })
      })

    }, 1/4*1000)
  })()

  //down wave
  !(function(){
    var module = {sel: d3.select('.sectionNum3'), active: false, minWidth: 300, onunload: unload}
    addModule(module)

    var colors = colorArray.slice(2, 5)
    var offset = 1
    setInterval(function(){
      if (!module.active) return

      var speed = Math.random()*.5 + .5
      speed = 1
      offset++
      var m = offset % 4
      d3.range(0, width + l, l).forEach(function(x, i){
        d3.range(0, height + l, l).forEach(function(y, j){
          if (!((i + j + offset) % 5)) return
          if (Math.random() < .6) return

          var stagger = speed*40 + Math.random()*5
          var start = curTime
          var sV = []
          if        (m == 0){
            start += j*stagger
            sV = [x, y, l, 0]
          } else if (m == 1){
            start += (width /l - i)*stagger
            sV = [x + l, y, 0, l]
          } else if (m == 2){
            start += (height/l - j)*stagger
            sV = [x, y + l, l, 0]
          } else if (m == 3){
            start += i*stagger
            sV = [x, y, 0, l]
          }

          var shape =
            { x: x,
              y: y,
              i: i,
              j: j,
              type: 'rect',
              start: start,
              sV: sV,
              eV: [x, y, l, l],
              fill: offset % 1000 ? colors[offset % 3] : 'white'
            }
          shape.end = shape.start + 200*Math.random()
          shapes.push(shape)
        })
      })

    }, 2000)
  })()

})();

<|endoftext|>