<commit_before>app = Sammy('#main', function (sam) {

    /**
     * Sammy Configuration
     *
     */
    // Plugins
    sam.use('Mustache', 'ms');

    // Initialize storage
    var store = new Sammy.Store({name: 'storage', type: 'session'});

    /**
     * Helpers
     *
     */
    sam.helpers({

        // Flash helper to diplay instant notifications
        flash: function (level, message) {
            flashs = store.get('flash');
            if (!flashs) { flashs = {'info': [], 'fail': [], 'success': [] } }
            flashs[level].push(message);
            store.set('flash', flashs);

            html = '';
            for(lvl in flashs) {
                flashs[lvl].forEach( function(msg) {
                    html += '
'+ msg +'
';
                });
            }
            if      (level == 'fail')    { alertClass = 'alert-danger'; }
            else if (level == 'success') { alertClass = 'alert-success'; }
            else                         { alertClass = 'alert-info'; }

            $('#flash').removeClass().addClass('alert '+ alertClass).html(html).fadeIn();
        },

        // API connection helper
        api: function (uri, callback, method, data) {
            c = this;
            method = typeof method !== 'undefined' ? method : 'GET';
            data   = typeof data   !== 'undefined' ? data   : {};
            auth   = "Basic "+ btoa(store.get('user') +':'+ atob(store.get('password')));
            jQuery.ajax({
                url: store.get('url') + uri,
                type: method,
                crossdomain: true,
                data: data,
                traditional: true,
                dataType: 'json',
                beforeSend: function(req) {
                    req.setRequestHeader('Authorization', auth);
                }
            })
            .success(function(data) {
                data = typeof data !== 'undefined' ? data : {};
                if (typeof data.win !== 'undefined') {
                    $.each(data.win, function(k, v) {
                        c.flash('success', v);
                    });
                }
                callback(data);
            })
            .fail(function(xhr) {
                console.log(xhr);
                if (xhr.status == 401) {
                    c.flash('fail', 'Wrong password');
                } else if (typeof xhr.responseJSON !== 'undefined') {
                    c.flash('fail', xhr.responseJSON.error);
                } else {
                    c.flash('fail', 'Server error');
                }
                store.clear('slide');
                c.redirect(store.get('path-1'));
            })
            .done(function(data) {
                console.log(data);
            });
        },

        // Render view (cross-browser)
        view: function (view, data) {
            rendered = this.render('views/'+ view +'.ms', data);

            enableSlide = true; // Change to false to disable animation

            if (enableSlide) {
                function leSwap() {
                    rendered.swap(function() {
                        $('.slide').on('click', function() {
                            $(this).addClass('active');
                            if ($(this).hasClass('back')) {
                                store.set('slide', 'back');
                            } else {
                                store.set('slide', 'to');
                            }
                        });
                    });
                }

                blockSize = $('#slider').width();

                // Slide back effect
                if (store.get('slide') == 'back') {
                    store.clear('slide');
                    $('#slideBack').css('display', 'none');
                    $('#slider-container').removeClass('move').css('margin-left', '-'+ blockSize +'px');
                    $('#slideTo').show().html($('#main').html());
                    leSwap();
                    $('#slider-container').addClass('move').css('margin-left', '0px');

                // Slide to effect
                } else if (store.get('slide') == 'to') {
                    store.clear('slide');
                    $('#slideTo').css('display', 'none');
                    $('#slider-container').removeClass('move').css('margin-left', '-'+ blockSize +'px');
                    $('#slider-container').removeClass('move').css('margin-left', '0px');
                    $('#slideBack').show().html($('#main').html());
                    leSwap();
                    $('#slider-container').addClass('move').css('margin-left', '-'+ blockSize +'px');

                } else {
                    leSwap();
                }
            } else {
                rendered.swap();
            }
        }
    });

    /**
     * Filters
     *
     */
    sam.before({except: {path: ['#/login', '#/postinstall']}}, function (req) {

        // Store path for further redirections
        store.set('path-1', store.get('path'));
        store.set('path', req.path);

        // Redirect to login page if no credentials stored
        if (!store.get('connected') && window.localStorage.getItem("isConnected") != 'true') {
            req.redirect('#/login');
            return false;
        }

        // Clear flash display
        if (!store.get('flash')) {
            $('#flash').fadeOut(function() { $('#flash').html(''); });
        }
    });

    sam.after(function () {

        // Clear flash notifications
        store.clear('flash');
    });

    /**
     * Routes
     *
     * Note: var "c" is Sammy's route context
     * @doc http://sammyjs.org/docs/api/#Sammy.EventContext
     *
     */
    sam.get('#/', function (c) {
        c.view('home');
    });

    sam.get('#/login', function (c) {
        $('#logout-button').hide();
        store.set('path-1', '#/login');

        // Check if te client is hosted on a yunohost node
        domain = window.location.hostname
        $.ajax({
            url: 'https://'+ domain +':6767/api',
            timeout: 3000
        })
        .success(function() {
            $.getJSON('https://'+ domain +':6767/installed', function(data) {
                if (!data.installed) {
                    c.redirect('#/postinstall');
                } else {
                    c.view('login', { 'domain': domain });
                }
            });
        })
        .fail(function() {
            c.view('login');
        });
    });

    sam.post('#/login', function (c) {
        store.set('url', 'https://'+ c.params['domain'] +':6767');
        store.set('user', 'admin');
        store.set('password', btoa(c.params['password']));
        c.api('/api', function(data) {
            if (data.apiVersion == '0.1') {
                c.api('/users', function(data) {
                    store.set('connected', true);
                    window.localStorage.setItem("isConnected", "true");
                    $('#logout-button').fadeIn();
                    c.flash('success', 'Logged in');
                    if (store.get('path')) {
                        c.redirect(store.get('path'));
                    } else {
                        c.redirect('#/');
                    }
                });
            } else {
                c.flash('fail', 'Non-compatible API (0.1 required)');
                c.redirect('#/login');
            }
        });
    });

    sam.get('#/logout', function (c) {
        store.clear('url');
        store.clear('user');
        store.clear('password');
        store.clear('connected');
        store.set('path', '#/');
        c.flash('success', 'Logged out');
        c.redirect('#/login');
    });

    sam.get('#/postinstall', function(c) {
        c.view('postinstall', {'DDomains': ['.nohost.me', '.noho.st']});
    });

    sam.post('#/postinstall', function (c) {
        if (c.params['password'] == c.params['confirmation']) {
            if (c.params['domain'] == '') {
                if (c.params['ddomain'] == '') {
                    c.flash('fail', "You should indicate a domain");
                    store.clear('slide');
                    c.redirect('#/postinstall');
                } else {
                    params = { 'domain': c.params['ddomain'] + c.params['ddomain-ext'] }
                }
            } else {
                params = { 'domain': c.params['domain'] }
            }

            params['password'] = c.params['password']

            store.set('url', 'https://'+ window.location.hostname +':6767');
            store.set('user', 'admin');
            store.set('password', btoa('yunohost'));
            c.api('/postinstall', function(data) { // http://api.yunohost.org/#!/tools/tools_postinstall_post_0
                c.redirect('#/');
            }, 'POST', params);
        } else {
            c.flash('fail', "Passwords don't match");
        }
    });

    /**
     * Users
     *
     */

    sam.get('#/users', function (c) {
        c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_list_get_3
            c.view('user_list', data);
        });
    });

    sam.get('#/users/create', function (c) {
        c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
            c.view('user_create', data);
        });
    });

    sam.post('#/users', function (c) {
        if (c.params['password'] == c.params['confirmation']) {
            c.params['mail'] = c.params['email'] + c.params['domain'];
            c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_create_post_2
                c.redirect('#/users');
            }, 'POST', c.params.toHash());
        } else {
            c.flash('fail', "Passwords don't match");
            store.clear('slide');
            //c.redirect('#/users/create');
        }
    });

    sam.get('#/users/:user', function (c) {
        c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
            c.view('user_info', data);
        });
    });

    sam.get('#/users/:user/edit', function (c) {
        c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
            c.view('user_edit', data);
        });
    });

    sam.put('#/users/:user', function (c) {
        params = {}
        $.each(c.params.toHash(), function(key, value) {
            if (value !== '' && value !== 'user') { params[key] = value; }
        });
        if ($.isEmptyObject(params)) {
            c.flash('fail', 'You should modify something');
            store.clear('slide');
            c.redirect('#/users/'+ c.params['user'] + '/edit');
        } else {
            c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_update_put_1
                c.redirect('#/users/'+ c.params['user']);
            }, 'PUT', params);
        }
    });

    sam.get('#/users/:user/delete', function (c) {
        if (confirm('Are you sure you want to delete '+ c.params['user'] +' ?')) {
            c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_delete_delete_4
                c.redirect('#/users');
            }, 'DELETE');
        } else {
            store.clear('slide');
            c.redirect('#/users/'+ c.params['user']);
        }
    });

    /**
     * Domains
     *
     */

    sam.get('#/domains', function (c) {
        c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
            c.view('domain_list', data);
        });
    });

    sam.get('#/domains/add', function (c) {
        c.view('domain_add', {'DDomains': ['.nohost.me', '.noho.st']});
    });

    sam.post('#/domains', function (c) {
        if (c.params['domain'] == '') {
            if (c.params['ddomain'] == '') {
                c.flash('fail', "You should indicate a domain");
                store.clear('slide');
                c.redirect('#/domains/add');
            }
            params = { 'domains': c.params['ddomain'] + c.params['ddomain-ext'] }
        } else {
            params = { 'domains': c.params['domain'] }
        }

        c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_add_post_1
            c.redirect('#/domains');
        }, 'POST', params);
    });

    /**
     * Apps
     *
     */

    sam.get('#/apps', function (c) {
        c.api('/app/list', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
            // Keep only installed apps
            data2 = { 'Apps': [], 'Installed': true }
            $.each(data['Apps'], function(k, v) {
                if (v['Installed'] !== 'No') data2['Apps'].push(v);
            });
            c.view('app_list', data2);
        });
    });

    sam.get('#/apps/install', function (c) {
        c.api('/app/list', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
            // Keep only uninstalled apps
            data2 = { 'Apps': [] }
            $.each(data['Apps'], function(k, v) {
                if (v['Installed'] !== 'Yes') data2['Apps'].push(v);
            });
            c.view('app_list', data2);
        });
    });

    sam.get('#/apps/refresh', function (c) {
        c.api('/app/lists', function(data) { // http://api.yunohost.org/#!/app/app_fetchlist_put_5
            c.redirect(store.get('path'));
        }, 'PUT');
    });
});

/**
 * Run the app
 *
 */
$(document).ready(function () {
    app.run('#/');

    // Fixes for sliding effect
    $('#slider-container').width(2*$('#slider').width() +'px');
    $(window).resize(function() {
        $('#slideBack').css('display', 'none');
        $('#slideTo').css('display', 'none');
        $('#slider-container').width(2*$('#slider').width() +'px').removeClass('move').css('margin-left', '0px');
    });
});
<commit_msg>Treat postinstall right<commit_after>app = Sammy('#main', function (sam) {

    /**
     * Sammy Configuration
     *
     */
    // Plugins
    sam.use('Mustache', 'ms');

    // Initialize storage
    var store = new Sammy.Store({name: 'storage', type: 'session'});

    /**
     * Helpers
     *
     */
    sam.helpers({

        // Flash helper to diplay instant notifications
        flash: function (level, message) {
            flashs = store.get('flash');
            if (!flashs) { flashs = {'info': [], 'fail': [], 'success': [] } }
            flashs[level].push(message);
            store.set('flash', flashs);

            html = '';
            for(lvl in flashs) {
                flashs[lvl].forEach( function(msg) {
                    html += '
'+ msg +'
';
                });
            }
            if      (level == 'fail')    { alertClass = 'alert-danger'; }
            else if (level == 'success') { alertClass = 'alert-success'; }
            else                         { alertClass = 'alert-info'; }

            $('#flash').removeClass().addClass('alert '+ alertClass).html(html).fadeIn();
        },

        // API connection helper
        api: function (uri, callback, method, data) {
            c = this;
            method = typeof method !== 'undefined' ? method : 'GET';
            data   = typeof data   !== 'undefined' ? data   : {};
            auth   = "Basic "+ btoa(store.get('user') +':'+ atob(store.get('password')));
            if (uri == '/postinstall') {
                var installing = false;

                check = setInterval(function () {
                    installing = true;
                }, 4000);
            }
            jQuery.ajax({
                url: store.get('url') + uri,
                type: method,
                crossdomain: true,
                data: data,
                traditional: true,
                dataType: 'json',
                beforeSend: function(req) {
                    req.setRequestHeader('Authorization', auth);
                }
            })
            .success(function(data) {
                data = typeof data !== 'undefined' ? data : {};
                if (typeof data.win !== 'undefined') {
                    $.each(data.win, function(k, v) {
                        c.flash('success', v);
                    });
                }
                callback(data);
            })
            .fail(function(xhr) {
                console.log(xhr);
                if (xhr.status == 401) {
                    c.flash('fail', 'Wrong password');
                } else if (typeof xhr.responseJSON !== 'undefined') {
                    c.flash('fail', xhr.responseJSON.error);
                } else {
                    if (uri == '/postinstall') {
                        if (installing) {
                            window.location.replace('https://'+ data['domain'] +'/ynhadmin');
                        }
                    }
                    c.flash('fail', 'Server error');
                }
                store.clear('slide');
                c.redirect(store.get('path-1'));
            })
            .done(function(data) {
                console.log(data);
            });
        },

        // Render view (cross-browser)
        view: function (view, data) {
            rendered = this.render('views/'+ view +'.ms', data);

            enableSlide = true; // Change to false to disable animation

            if (enableSlide) {
                function leSwap() {
                    rendered.swap(function() {
                        $('.slide').on('click', function() {
                            $(this).addClass('active');
                            if ($(this).hasClass('back')) {
                                store.set('slide', 'back');
                            } else {
                                store.set('slide', 'to');
                            }
                        });
                    });
                }

                blockSize = $('#slider').width();

                // Slide back effect
                if (store.get('slide') == 'back') {
                    store.clear('slide');
                    $('#slideBack').css('display', 'none');
                    $('#slider-container').removeClass('move').css('margin-left', '-'+ blockSize +'px');
                    $('#slideTo').show().html($('#main').html());
                    leSwap();
                    $('#slider-container').addClass('move').css('margin-left', '0px');

                // Slide to effect
                } else if (store.get('slide') == 'to') {
                    store.clear('slide');
                    $('#slideTo').css('display', 'none');
                    $('#slider-container').removeClass('move').css('margin-left', '-'+ blockSize +'px');
                    $('#slider-container').removeClass('move').css('margin-left', '0px');
                    $('#slideBack').show().html($('#main').html());
                    leSwap();
                    $('#slider-container').addClass('move').css('margin-left', '-'+ blockSize +'px');

                } else {
                    leSwap();
                }
            } else {
                rendered.swap();
            }
        }
    });

    /**
     * Filters
     *
     */
    sam.before({except: {path: ['#/login', '#/postinstall']}}, function (req) {

        // Store path for further redirections
        store.set('path-1', store.get('path'));
        store.set('path', req.path);

        // Redirect to login page if no credentials stored
        if (!store.get('connected') && window.localStorage.getItem("isConnected") != 'true') {
            req.redirect('#/login');
            return false;
        }

        // Clear flash display
        if (!store.get('flash')) {
            $('#flash').fadeOut(function() { $('#flash').html(''); });
        }
    });

    sam.after(function () {

        // Clear flash notifications
        store.clear('flash');
    });

    /**
     * Routes
     *
     * Note: var "c" is Sammy's route context
     * @doc http://sammyjs.org/docs/api/#Sammy.EventContext
     *
     */
    sam.get('#/', function (c) {
        c.view('home');
    });

    sam.get('#/login', function (c) {
        $('#logout-button').hide();
        store.set('path-1', '#/login');

        // Check if te client is hosted on a yunohost node
        domain = window.location.hostname
        $.ajax({
            url: 'https://'+ domain +':6767/api',
            timeout: 3000
        })
        .success(function() {
            $.getJSON('https://'+ domain +':6767/installed', function(data) {
                if (!data.installed) {
                    c.redirect('#/postinstall');
                } else {
                    c.view('login', { 'domain': domain });
                }
            });
        })
        .fail(function() {
            c.view('login');
        });
    });

    sam.post('#/login', function (c) {
        store.set('url', 'https://'+ c.params['domain'] +':6767');
        store.set('user', 'admin');
        store.set('password', btoa(c.params['password']));
        c.api('/api', function(data) {
            if (data.apiVersion == '0.1') {
                c.api('/users', function(data) {
                    store.set('connected', true);
                    window.localStorage.setItem("isConnected", "true");
                    $('#logout-button').fadeIn();
                    c.flash('success', 'Logged in');
                    if (store.get('path')) {
                        c.redirect(store.get('path'));
                    } else {
                        c.redirect('#/');
                    }
                });
            } else {
                c.flash('fail', 'Non-compatible API (0.1 required)');
                c.redirect('#/login');
            }
        });
    });

    sam.get('#/logout', function (c) {
        store.clear('url');
        store.clear('user');
        store.clear('password');
        store.clear('connected');
        store.set('path', '#/');
        c.flash('success', 'Logged out');
        c.redirect('#/login');
    });

    sam.get('#/postinstall', function(c) {
        c.view('postinstall', {'DDomains': ['.nohost.me', '.noho.st']});
    });

    sam.post('#/postinstall', function (c) {
        if (c.params['password'] == c.params['confirmation']) {
            if (c.params['domain'] == '') {
                if (c.params['ddomain'] == '') {
                    c.flash('fail', "You should indicate a domain");
                    store.clear('slide');
                    c.redirect('#/postinstall');
                } else {
                    params = { 'domain': c.params['ddomain'] + c.params['ddomain-ext'] }
                }
            } else {
                params = { 'domain': c.params['domain'] }
            }

            params['password'] = c.params['password']

            store.set('url', 'https://'+ window.location.hostname +':6767');
            store.set('user', 'admin');
            store.set('password', btoa('yunohost'));
            c.api('/postinstall', function(data) { // http://api.yunohost.org/#!/tools/tools_postinstall_post_0
                c.redirect('#/');
            }, 'POST', params);
        } else {
            c.flash('fail', "Passwords don't match");
        }
    });

    /**
     * Users
     *
     */

    sam.get('#/users', function (c) {
        c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_list_get_3
            c.view('user_list', data);
        });
    });

    sam.get('#/users/create', function (c) {
        c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
            c.view('user_create', data);
        });
    });

    sam.post('#/users', function (c) {
        if (c.params['password'] == c.params['confirmation']) {
            c.params['mail'] = c.params['email'] + c.params['domain'];
            c.api('/users', function(data) { // http://api.yunohost.org/#!/user/user_create_post_2
                c.redirect('#/users');
            }, 'POST', c.params.toHash());
        } else {
            c.flash('fail', "Passwords don't match");
            store.clear('slide');
            //c.redirect('#/users/create');
        }
    });

    sam.get('#/users/:user', function (c) {
        c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
            c.view('user_info', data);
        });
    });

    sam.get('#/users/:user/edit', function (c) {
        c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_info_get_0
            c.view('user_edit', data);
        });
    });

    sam.put('#/users/:user', function (c) {
        params = {}
        $.each(c.params.toHash(), function(key, value) {
            if (value !== '' && value !== 'user') { params[key] = value; }
        });
        if ($.isEmptyObject(params)) {
            c.flash('fail', 'You should modify something');
            store.clear('slide');
            c.redirect('#/users/'+ c.params['user'] + '/edit');
        } else {
            c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_update_put_1
                c.redirect('#/users/'+ c.params['user']);
            }, 'PUT', params);
        }
    });

    sam.get('#/users/:user/delete', function (c) {
        if (confirm('Are you sure you want to delete '+ c.params['user'] +' ?')) {
            c.api('/users/'+ c.params['user'], function(data) { // http://api.yunohost.org/#!/user/user_delete_delete_4
                c.redirect('#/users');
            }, 'DELETE');
        } else {
            store.clear('slide');
            c.redirect('#/users/'+ c.params['user']);
        }
    });

    /**
     * Domains
     *
     */

    sam.get('#/domains', function (c) {
        c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_list_get_2
            c.view('domain_list', data);
        });
    });

    sam.get('#/domains/add', function (c) {
        c.view('domain_add', {'DDomains': ['.nohost.me', '.noho.st']});
    });

    sam.post('#/domains', function (c) {
        if (c.params['domain'] == '') {
            if (c.params['ddomain'] == '') {
                c.flash('fail', "You should indicate a domain");
                store.clear('slide');
                c.redirect('#/domains/add');
            }
            params = { 'domains': c.params['ddomain'] + c.params['ddomain-ext'] }
        } else {
            params = { 'domains': c.params['domain'] }
        }

        c.api('/domains', function(data) { // http://api.yunohost.org/#!/domain/domain_add_post_1
            c.redirect('#/domains');
        }, 'POST', params);
    });

    /**
     * Apps
     *
     */

    sam.get('#/apps', function (c) {
        c.api('/app/list', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
            // Keep only installed apps
            data2 = { 'Apps': [], 'Installed': true }
            $.each(data['Apps'], function(k, v) {
                if (v['Installed'] !== 'No') data2['Apps'].push(v);
            });
            c.view('app_list', data2);
        });
    });

    sam.get('#/apps/install', function (c) {
        c.api('/app/list', function(data) { // http://api.yunohost.org/#!/app/app_list_get_8
            // Keep only uninstalled apps
            data2 = { 'Apps': [] }
            $.each(data['Apps'], function(k, v) {
                if (v['Installed'] !== 'Yes') data2['Apps'].push(v);
            });
            c.view('app_list', data2);
        });
    });

    sam.get('#/apps/refresh', function (c) {
        c.api('/app/lists', function(data) { // http://api.yunohost.org/#!/app/app_fetchlist_put_5
            c.redirect(store.get('path'));
        }, 'PUT');
    });
});

/**
 * Run the app
 *
 */
$(document).ready(function () {
    app.run('#/');

    // Fixes for sliding effect
    $('#slider-container').width(2*$('#slider').width() +'px');
    $(window).resize(function() {
        $('#slideBack').css('display', 'none');
        $('#slideTo').css('display', 'none');
        $('#slider-container').width(2*$('#slider').width() +'px').removeClass('move').css('margin-left', '0px');
    });
});
<|endoftext|>


<commit_before>(function(){
    //initiate the client
    var oh = Ohmage("/app", "campaign-manager")

    //debugging
    window.oh = oh;

    //attach global callbacks
    oh.callback("done", function(x, status, req){
        //for debugging only
        //console.log(x);
    })

    //global error handler. In ohmage 200 means unauthenticated
    oh.callback("error", function(msg, code, req){
        (code == 200) ? window.location.replace("../web/#login") : message("Error! " + msg);
    });

    //prevent timeout
    oh.keepalive();

    //get data
    oh.user.whoami().done(function(username){
        updateProgress(10)
        oh.campaign.readall().done(function(data){
            updateProgress(15)
            $("#progressdiv").removeClass("hidden");
            var urns = Object.keys(data);
            var progress = 0;
            var total = 0;
            var requests = $.map(urns.sort(), function(urn, i){
                var roles = data[urn]["user_roles"];
                if($.inArray("author", roles) > -1 || $.inArray("supervisor", roles) > -1) {

                    var count = -1;
                    total++;

                    var tr = $("
").appendTo("#campaigntablebody")
                    var td5 = $("").appendTo(tr);
                    var td1 = $("").appendTo(tr).text(data[urn].name);
                    var td2 = $("").appendTo(tr).text(data[urn].creation_timestamp);
                    var td3 = $("").appendTo(tr).text(data[urn].running_state);
                    var td4 = $("").appendTo(tr);

                    var btn = $("
").addClass("btn-group").append('\
                        <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown"> \
                        </button>').appendTo(td5);

                    var ul = $("
").addClass("dropdown-menu").attr("role", "menu").appendTo(btn);

                    var a2 = $("").appendTo($("
").appendTo(ul)).append(' Surveys').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count > 0){
                            message("Campaign " + urn + " has existing responses and can therefore not be modified.")
                        } else {
                            window.location.href = '../surveytool/#' + urn;
                        }
                    });

                    var a3 = $("").appendTo($("
").appendTo(ul)).append(' Visualize').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count === 0){
                            message("Campaign " + urn + " has no existing responses. Nothing to visualize.")
                        } else {
                            window.location.href = '../navbar/dashboard/#' + urn;
                        }
                    });

                    var a4 = $("").appendTo($("
").appendTo(ul)).append(' Download XML').attr("href", "#").click(function(e){
                        e.preventDefault();
                        $("#hiddenurn").val(urn)
                        $("#hiddenform").submit()
                    });

                    var a5 = $("").appendTo($("
").appendTo(ul)).append(' Export Data')
                        .attr("href", "../../app/survey_response/read?campaign_urn=" + urn + "&privacy_state=shared&client=manager&user_list=urn:ohmage:special:all&prompt_id_list=urn:ohmage:special:all&output_format=csv&sort_oder=timestamp&column_list=urn:ohmage:user:id,urn:ohmage:context:timestamp,urn:ohmage:prompt:response,urn:ohmage:context:location:latitude,urn:ohmage:context:location:longitude&suppress_metadata=true")

                    ul.append($("
").addClass('divider'))

                    var a1 = $("").appendTo($("
").appendTo(ul)).append(' Settings').attr("href", "#").click(function(e){
                        e.preventDefault();
                        populateModal();
                    });

                    function populateModal(){
                        oh.campaign.readall({
                            campaign_urn_list : urn,
                            output_format:"long"
                        }).done(function(x){
                            var longdata = x[urn];
                            $("#campaign_name").val(longdata.name);
                            $("#campaign_description").val(longdata.description);
                            $("#campaign_urn").val(urn);

                            //$("#campaign_running")[0].checked = (data["running_state"] == "running");
                            //$("#campaign_privacy")[0].checked = (data["privacy_state"] == "shared");
                            $("#campaign_privacy").bootstrapSwitch("state", longdata["privacy_state"] == "shared");
                            $("#campaign_running").bootstrapSwitch("state", longdata["running_state"] == "running");

                            $("#campaign_class option").each(function(i){
                                $(this).prop("selected", $.inArray($(this).attr("value"), longdata.classes) > -1);
                            });
                            $("#campaign_class").trigger("chosen:updated");

                            if(count > 0){
                                $(".xml-upload-form").hide();
                            } else {
                                $(".xml-upload-form").show();
                            }

                            $('#myModal').modal("show").on("shown.bs.modal", function(){
                                $("#campaign_class").chosen({search_contains:true, no_results_text: "Class not found."});
                            });

                            $("input.xml-file-input").unbind("change").on("change", function(){
                                var f = this.files[0];
                                if(f){
                                    var r = new FileReader();
                                    r.onload = function(e) {
                                        xmldata = r.result;
                                    }
                                    r.readAsText(f);
                                } else {
                                    xmldata = null;
                                }
                            })

                            $("#campaign_save_button").unbind("click").click(function(e){
                                e.preventDefault();
                                var btn = $(this).attr("disabled", "disabled");
                                var running_state = $("#campaign_running")[0].checked ? "running" : "stopped";
                                var privacy_state = $("#campaign_privacy")[0].checked ? "shared" : "private";
                                var args = {
                                    campaign_urn : urn,
                                    running_state : running_state,
                                    privacy_state : privacy_state,
                                    description : $("#campaign_description").val(),
                                    class_list_remove : longdata.classes,
                                    class_list_add : $("#campaign_class").val()
                                }

                                //update xml only if selected
                                if(xmldata){
                                    args.xml = xmldata;
                                }

                                oh.campaign.update(args).done(function(){
                                    $('#myModal').modal("hide")
                                }).always(function(){
                                    btn.removeAttr("disabled");
                                });
                            });
                        });
                    }

                    return oh.survey.count(urn).done(function(counts){
                        if(!Object.keys(counts).length){
                            //no existing responses found
                            count = 0;
                        } else {
                            count = $.map(counts, function(val, key) {
                                return val[0].count;
                            }).reduce(function(previousValue, currentValue) {
                                return previousValue + currentValue;
                            });
                        }
                        td4.text(count);
                    }).always(function(){
                        updateProgress((progress++/total) * 75 + 25);
                    });
                }
            });

            //data tables widget
            function initTable(){
                $('#campaigntable').dataTable( {
                    "dom" : '<"pull-right"l><"pull-left"f>tip',
                    "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
                    "aoColumnDefs": [
                       { 'bSortable': false, 'aTargets': [ 0 ] }
                    ]
                });
            }

            //init temporary datatable
            initTable()

            //reinit final datatable after counts have been updated
            $.when.apply($, requests).always(function() {
                $("#progressdiv").addClass("hidden");
                $('#campaigntable').dataTable().fnDestroy();
                initTable();
            });
        });

        //get users
        oh.user.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, name ) {
                //$("#campaign_author").append($("<option />").text(name));
            });
        });

        //get classes
        oh.class.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, urn ) {
                $("#campaign_class").append($("<option />").text(urn).attr("value", urn));
            });
        });
    });

    updateProgress = _.throttle(function(pct){
        $(".progress-bar").css("width", + pct + "%");
    }, 300);

    function message(msg, type){
        // type must be one of success, info, warning, danger
        type = type || "danger"
        $("#errordiv").empty().append('
×' + msg + '
');
        $('html, body').animate({
           scrollTop: 100
        }, 200);
    }
})();
<commit_msg>hack in the campaignName and campaignUrn<commit_after>(function(){
    //initiate the client
    var oh = Ohmage("/app", "campaign-manager")

    //debugging
    window.oh = oh;

    //attach global callbacks
    oh.callback("done", function(x, status, req){
        //for debugging only
        //console.log(x);
    })

    //global error handler. In ohmage 200 means unauthenticated
    oh.callback("error", function(msg, code, req){
        (code == 200) ? window.location.replace("../web/#login") : message("Error! " + msg);
    });

    //prevent timeout
    oh.keepalive();

    //get data
    oh.user.whoami().done(function(username){
        updateProgress(10)
        oh.campaign.readall().done(function(data){
            updateProgress(15)
            $("#progressdiv").removeClass("hidden");
            var urns = Object.keys(data);
            var progress = 0;
            var total = 0;
            var requests = $.map(urns.sort(), function(urn, i){
                var roles = data[urn]["user_roles"];
                if($.inArray("author", roles) > -1 || $.inArray("supervisor", roles) > -1) {

                    var count = -1;
                    total++;

                    var tr = $("
").appendTo("#campaigntablebody")
                    var td5 = $("").appendTo(tr);
                    var td1 = $("").appendTo(tr).text(data[urn].name);
                    var td2 = $("").appendTo(tr).text(data[urn].creation_timestamp);
                    var td3 = $("").appendTo(tr).text(data[urn].running_state);
                    var td4 = $("").appendTo(tr);

                    var btn = $("
").addClass("btn-group").append('\
                        <button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown"> \
                        </button>').appendTo(td5);

                    var ul = $("
").addClass("dropdown-menu").attr("role", "menu").appendTo(btn);

                    var a2 = $("").appendTo($("
").appendTo(ul)).append(' Surveys').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count > 0){
                            message("Campaign " + urn + " has existing responses and can therefore not be modified.")
                        } else {
                            window.location.href = '../surveytool/#' + urn;
                        }
                    });

                    var a3 = $("").appendTo($("
").appendTo(ul)).append(' Visualize').attr("href", "#").click(function(e){
                        e.preventDefault();
                        if(count < 0){
                            message("Loading campaign info, please be patient.", "info")
                        } else if(count === 0){
                            message("Campaign " + urn + " has no existing responses. Nothing to visualize.")
                        } else {
                            window.location.href = '../navbar/dashboard/#' + urn;
                        }
                    });

                    var a4 = $("").appendTo($("
").appendTo(ul)).append(' Download XML').attr("href", "#").click(function(e){
                        e.preventDefault();
                        $("#hiddenurn").val(urn)
                        $("#hiddenform").submit()
                    });

                    var a5 = $("").appendTo($("
").appendTo(ul)).append(' Export Data')
                        .attr("href", "../../app/survey_response/read?campaign_urn=" + urn + "&privacy_state=shared&client=manager&user_list=urn:ohmage:special:all&prompt_id_list=urn:ohmage:special:all&output_format=csv&sort_oder=timestamp&column_list=urn:ohmage:user:id,urn:ohmage:context:timestamp,urn:ohmage:prompt:response,urn:ohmage:context:location:latitude,urn:ohmage:context:location:longitude&suppress_metadata=true")

                    ul.append($("
").addClass('divider'))

                    var a1 = $("").appendTo($("
").appendTo(ul)).append(' Settings').attr("href", "#").click(function(e){
                        e.preventDefault();
                        populateModal();
                    });

                    function populateModal(){
                        oh.campaign.readall({
                            campaign_urn_list : urn,
                            output_format:"long"
                        }).done(function(x){
                            var longdata = x[urn];
                            $("#campaign_name").val(longdata.name);
                            $("#campaign_description").val(longdata.description);
                            $("#campaign_urn").val(urn);

                            //$("#campaign_running")[0].checked = (data["running_state"] == "running");
                            //$("#campaign_privacy")[0].checked = (data["privacy_state"] == "shared");
                            $("#campaign_privacy").bootstrapSwitch("state", longdata["privacy_state"] == "shared");
                            $("#campaign_running").bootstrapSwitch("state", longdata["running_state"] == "running");

                            $("#campaign_class option").each(function(i){
                                $(this).prop("selected", $.inArray($(this).attr("value"), longdata.classes) > -1);
                            });
                            $("#campaign_class").trigger("chosen:updated");

                            if(count > 0){
                                $(".xml-upload-form").hide();
                            } else {
                                $(".xml-upload-form").show();
                            }

                            $('#myModal').modal("show").on("shown.bs.modal", function(){
                                $("#campaign_class").chosen({search_contains:true, no_results_text: "Class not found."});
                            });

                            var xmldata;
                            $("input.xml-file-input").unbind("change").on("change", function(){
                                var f = this.files[0];
                                if(f){
                                    var r = new FileReader();
                                    r.onload = function(e) {
                                        xmldata = r.result;
                                    }
                                    r.readAsText(f);
                                } else {
                                    xmldata = null;
                                }
                            })

                            $("#campaign_save_button").unbind("click").click(function(e){
                                e.preventDefault();
                                var btn = $(this).attr("disabled", "disabled");
                                var running_state = $("#campaign_running")[0].checked ? "running" : "stopped";
                                var privacy_state = $("#campaign_privacy")[0].checked ? "shared" : "private";
                                var args = {
                                    campaign_urn : urn,
                                    running_state : running_state,
                                    privacy_state : privacy_state,
                                    description : $("#campaign_description").val(),
                                    class_list_remove : longdata.classes,
                                    class_list_add : $("#campaign_class").val()
                                }

                                //update xml only if selected
                                if(xmldata){
                                    args.xml = fixxml(xmldata, longdata.name ,urn);
                                }

                                oh.campaign.update(args).done(function(){
                                    $('#myModal').modal("hide")
                                }).always(function(){
                                    btn.removeAttr("disabled");
                                });
                            });
                        });
                    }

                    return oh.survey.count(urn).done(function(counts){
                        if(!Object.keys(counts).length){
                            //no existing responses found
                            count = 0;
                        } else {
                            count = $.map(counts, function(val, key) {
                                return val[0].count;
                            }).reduce(function(previousValue, currentValue) {
                                return previousValue + currentValue;
                            });
                        }
                        td4.text(count);
                    }).always(function(){
                        updateProgress((progress++/total) * 75 + 25);
                    });
                }
            });

            //data tables widget
            function initTable(){
                $('#campaigntable').dataTable( {
                    "dom" : '<"pull-right"l><"pull-left"f>tip',
                    "lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
                    "aoColumnDefs": [
                       { 'bSortable': false, 'aTargets': [ 0 ] }
                    ]
                });
            }

            //init temporary datatable
            initTable()

            //reinit final datatable after counts have been updated
            $.when.apply($, requests).always(function() {
                $("#progressdiv").addClass("hidden");
                $('#campaigntable').dataTable().fnDestroy();
                initTable();
            });
        });

        //get users
        oh.user.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, name ) {
                //$("#campaign_author").append($("<option />").text(name));
            });
        });

        //get classes
        oh.class.read().done(function(x){
            $.each(Object.keys(x).sort(), function( i, urn ) {
                $("#campaign_class").append($("<option />").text(urn).attr("value", urn));
            });
        });
    });

    updateProgress = _.throttle(function(pct){
        $(".progress-bar").css("width", + pct + "%");
    }, 300);

    function message(msg, type){
        // type must be one of success, info, warning, danger
        type = type || "danger"
        $("#errordiv").empty().append('
×' + msg + '
');
        $('html, body').animate({
           scrollTop: 100
        }, 200);
    }

    //XML parser for mixed case tag names (HTML only supports lowercase tags)
    var parse = (function(parser, jQuery){
        return function(str) {
            return jQuery(parser.parseFromString(str, "text/xml").documentElement)
        }
    })(new DOMParser(), jQuery)

    function fixxml(input, name, urn){
        var xml = $.parseXML(input);
        var campaign = $("campaign", xml);
        campaign.children("campaignName").remove();
        campaign.children("campaignUrn").remove();
        campaign.prepend(parse("<campaignName/>").text(name))
        campaign.prepend(parse("<campaignUrn/>").text(urn))
        return (new XMLSerializer()).serializeToString(xml);
    }

})();
<|endoftext|>


<commit_before>// DOMContentLoaded is fired once the document has been loaded and parsed,
// but without waiting for other external resources to load (css/images/etc)
// That makes the app more responsive and perceived as faster.
// https://developer.mozilla.org/Web/Reference/Events/DOMContentLoaded
window.addEventListener('DOMContentLoaded', function() {

  // We'll ask the browser to use strict code to help us catch errors earlier.
  // https://developer.mozilla.org/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
  'use strict';

  // setup variables
  // element variables
  // result variables

  // attach function calls on elements' event

  // We want to wait until the localisations library has loaded all the strings.
  // So we'll tell it to let us know once it's ready.
  navigator.mozL10n.once(search);

  // ---
  // define functions here

});
<commit_msg>update localisation callback<commit_after>// DOMContentLoaded is fired once the document has been loaded and parsed,
// but without waiting for other external resources to load (css/images/etc)
// That makes the app more responsive and perceived as faster.
// https://developer.mozilla.org/Web/Reference/Events/DOMContentLoaded
window.addEventListener('DOMContentLoaded', function() {

  // We'll ask the browser to use strict code to help us catch errors earlier.
  // https://developer.mozilla.org/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
  'use strict';

  // setup variables
  // element variables
  // result variables

  // attach function calls on elements' event

  // We want to wait until the localisations library has loaded all the strings.
  // So we'll tell it to let us know once it's ready.
  navigator.mozL10n.once( localisations_load_callback );

  // ---
  // define functions here
  function localisations_load_callback () {
    // navigator.mozL10n.language.code = 'ph';
    console.log('localisations loaded');
  }

});
<|endoftext|>


<commit_before>// Enemies our player must avoid
var Enemy = function(x,y, speed) {
    // Variables applied to each of our instances go here,
    // we've provided one for you to get started

    // The image/sprite for our enemies, this uses
    // a helper we've provided to easily load images
    this.sprite = 'images/enemy-bug.png';
    //this.width  = 110;
    //this.height = 70;
    this.x = x;
    this.y = y;
    this.speed = speed;
};

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    // You should multiply any movement by the dt parameter
    // which will ensure the game runs at the same speed for
    // all computers.
    dt = 20;
    if (this.x >= 500 ){
        this.x = 10;
    }
    this.x += this.speed;
    this.checkCollission();
};

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

var enemy1 = new Enemy(10, 60, 7);
var enemy2 = new Enemy(10, 145, 5);
var enemy3 = new Enemy(10, 225, 2);

// Now write your own player class
// This class requires an update(), render() and
// a handleInput() method.
// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
var allEnemies = [enemy1, enemy2, enemy3];
// Place the player object in a variable called player
var Player = function(x,y,score) {
    this.image = 'images/char-cat-girl.png';
    this.x = x;
    this.y = y;
    this.score = 0;
};
// Update the player's position, required method for game
// Parameter: dt, a time delta between ticks
Player.prototype.update = function(dt) {
    dt = 20;
};
// Draw the player on the screen, required method for game
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.image), this.x, this.y);
    player.scoreCount();
};
//score.
Player.prototype.scoreCount = function() {
    ctx.font="30px Arial";
    ctx.fillStyle = 'red';
    ctx.fillText('SCORE : '+ player.score, 0, 40);
};
//text to show if player wins or collision occurs.
Player.prototype.showText = function() {
    ctx.font = "48px sans serif";
    if (this.y <= 0) {
        ctx.fillText('You Won!', 300, 40);
        setTimeout( function() { ctx.clearRect(300, 4, 250, 45);  }, 1000);
    } else {
        ctx.fillText('!!collision!!', 270, 40);
        setTimeout( function() { ctx.clearRect(270, 4, 250, 45);  }, 1000);
    }
};

//to reset player's position.
Player.prototype.reset = function() {
    this.x = 200;
    this.y = 390;
    this.update();
};
var player = new Player(200, 390);
// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
 document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };

    player.handleInput(allowedKeys[e.keyCode]);
});

// movment of player using arrow keys..
Player.prototype.handleInput = function (key) {
    switch (key) {
        case 'up' :
        this.y -= 83 ;
        break;
        case 'down' :
        this.y += 83 ;
        break;
        case 'left' :
        this.x -= 100 ;
        break;
        case 'right' :
        this.x += 103 ;
        break;
    }
        if (this.y < 0) {
        this.y = 0;
    }
        if (this.x < 0) {
        this.x = 0;
    }
        if (this.y > 390) {
        this.y = 390;
    }
        if (this.x > 400) {
        this.x = 400;
    }
        if (this.y <= 0) {
        //when player wins show massage and restart the game.
        player.showText();
        player.score += 10 ;
        player.reset();
    }

    //check for collision
        for (var i = 0; i < allEnemies.length; i++) {
        allEnemies[i].checkCollission(i);
    }
};
    Enemy.prototype.checkCollission = function(i) {
        //player dimentions = 80:87  and  enemy dimentions=  100:67
        if (this.x < player.x + 80 && this.x + 80 > player.x && this.y < player.y + 67 && 67 + this.y > player.y) {
            player.showText();
            player.score -= 5;
            player.reset();
        }
    };

<commit_msg>Update app.js<commit_after>// Enemies our player must avoid
var Enemy = function(x,y, speed) {
    // Variables applied to each of our instances go here,
    // we've provided one for you to get started

    // The image/sprite for our enemies, this uses
    // a helper we've provided to easily load images
    this.sprite = 'images/enemy-bug.png';
    this.x = x;
    this.y = y;
    this.speed = speed;
};

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    // You should multiply any movement by the dt parameter
    // which will ensure the game runs at the same speed for
    // all computers.
    dt = 20;
    if (this.x >= 500 ){
        this.x = 10;
    }
    this.x += this.speed;
    this.checkCollission();
};

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

var enemy1 = new Enemy(10, 60, 7);
var enemy2 = new Enemy(10, 145, 5);
var enemy3 = new Enemy(10, 225, 2);

// Now write your own player class
// This class requires an update(), render() and
// a handleInput() method.
// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
var allEnemies = [enemy1, enemy2, enemy3];
// Place the player object in a variable called player
var Player = function(x,y,score) {
    this.image = 'images/char-cat-girl.png';
    this.x = x;
    this.y = y;
    this.score = 0;
};
// Update the player's position, required method for game
// Parameter: dt, a time delta between ticks
Player.prototype.update = function(dt) {
    dt = 20;
};
// Draw the player on the screen, required method for game
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.image), this.x, this.y);
    player.scoreCount();
};
//score.
Player.prototype.scoreCount = function() {
    ctx.font="30px Arial";
    ctx.fillStyle = 'red';
    ctx.fillText('SCORE : '+ player.score, 0, 40);
};
//text to show if player wins or collision occurs.
Player.prototype.showText = function() {
    ctx.font = "48px sans serif";
    if (this.y <= 0) {
        ctx.fillText('You Won!', 300, 40);
        setTimeout( function() { ctx.clearRect(300, 4, 250, 45);  }, 1000);
    } else {
        ctx.fillText('!!collision!!', 270, 40);
        setTimeout( function() { ctx.clearRect(270, 4, 250, 45);  }, 1000);
    }
};

//to reset player's position.
Player.prototype.reset = function() {
    this.x = 200;
    this.y = 390;
    this.update();
};
var player = new Player(200, 390);
// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
 document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };

    player.handleInput(allowedKeys[e.keyCode]);
});

// movment of player using arrow keys..
Player.prototype.handleInput = function (key) {
    switch (key) {
        case 'up' :
        this.y -= 83 ;
        break;
        case 'down' :
        this.y += 83 ;
        break;
        case 'left' :
        this.x -= 100 ;
        break;
        case 'right' :
        this.x += 103 ;
        break;
    }
        if (this.y < 0) {
        this.y = 0;
    }
        if (this.x < 0) {
        this.x = 0;
    }
        if (this.y > 390) {
        this.y = 390;
    }
        if (this.x > 400) {
        this.x = 400;
    }
        if (this.y <= 0) {
        //when player wins show massage and restart the game.
        player.showText();
        player.score += 10 ;
        player.reset();
    }

    //check for collision
        for (var i = 0; i < allEnemies.length; i++) {
        allEnemies[i].checkCollission(i);
    }
};
    Enemy.prototype.checkCollission = function(i) {
        //player dimentions = 80:87  and  enemy dimentions=  100:67
        if (this.x < player.x + 80 && this.x + 80 > player.x && this.y < player.y + 67 && 67 + this.y > player.y) {
            player.showText();
            player.score -= 5;
            player.reset();
        }
    };

<|endoftext|>


<commit_before>var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var GRIDSIZE = 25;
var PI=Math.PI, cos=Math.cos, sin=Math.sin, abs=Math.abs, rad=Snap.rad;

var selected; //"selected"
var running = false;

// Utilities

function randint(max){
    return Math.floor(Math.random() * max);
}

function randcolor(){
    return Snap.hsl(randint(360), 50, 50);
}

function choice(list){
    return list[randint(list.length)];
}

// properly delete from a list
function deleteItem(list, item) {
    var idx = list.indexOf(item);
    if (idx > -1) {
        list.splice(idx, 1);
    }
    return item;
}

function getGroup(id){
    return [].slice.call(Snap.selectAll('path')).filter(function(e){
        return e.attr('group') === id;
    });

}

function rotatePoint(px, py, angle){
    var s = sin(angle);
    var c = cos(angle);
    var x = px * c - py * s;
    var y = px * s + py * c;
    return [x, y];
}

function randomId() {
    // Based on Paul Irish's random hex color:http://www.paulirish.com/2009/random-hex-color-code-snippets/
    // Theoretically could return non-unique values, not going to let that keep me up at night
    return 'k' + Math.floor(Math.random() * 16777215).toString(16); // 'k' because ids have to start with a letter
}

Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
    var prevdx, prevdy;
    function onDrag(dx, dy, x, y, evt){
        if(!running){
            if(evt.shiftKey){
                this.moveTo(Math.round((x-window.innerWidth/2)/25)*25, Math.round((y-window.innerHeight/2)/25)*25);
            }else{
                this.move(dx - prevdx, dy - prevdy);
            }
            prevdx = dx;
            prevdy = dy;
        }
    }

    function onDragStart(x, y, evt){
        var self = this;
        this.adjacent.forEach(function(e){
            deleteItem(e.adjacent, self);
        });
        this.adjacent = [];
        if(!running){
            prevdx = prevdy = 0;
            if (evt.metaKey){
                this.insertBefore(this.clone().setup());
            }
        }
    }

    function onDragEnd(evt){
        if(!running){
            this.snapToGrid();
            this.joinGroup(randcolor());
            selected = this;
        }
    }

    var pathFns = {

        asterisk: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num');
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var path = [];
            var theta = PI * 2 / num;
            for (var i = 0; i < num; i++){
                path.push('M', cx, cy,
                          cos(theta * i + rot) * r * flipH + cx,
                          sin(theta * i + rot) * r  * flipV + cy);
            }
            return path.join(' ');
        },
        polygon: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num');
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var path = ['M'];
            var theta = PI * 2 / num;
            for (var i = 0; i < num; i++){
                path.push(cos(theta * i + rot) * r * flipH + cx,
                          sin(theta * i + rot) * r * flipV + cy);
            }
            path.push('Z');
            return path.join(' ');
        },
        star: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num');
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            // num should be odd and 5 or greater
            var skip = (num - 1) / 2;
            var theta = PI * 2 / num * skip;
            var path = ['M'];
            for (var i = 0; i < num; i++){
                path.push(cos(theta * i + rot) * r * flipH + cx,
                          sin(theta * i + rot) * r * flipV + cy);
            }
            path.push('Z');
            return path.join(' ');
        },
        spiral: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num'), len=e.num('len');
            var theta = PI * 2 / num;
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var dR = r / (num * len);
            var path = ['M'];
            for (var i = 0; i < (num * len); i++){
                path.push(cos(theta * i + rot) * (dR * i) * flipH + cx,
                          sin(theta * i + rot) * (dR * i) * flipV + cy);
            }
            return path.join(' ');
        },
        line: function(e){
            var x1=e.num('cx'), y1=e.num('cy'), x2=e.num('x2')+x1, y2=e.num('y2')+y1;
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var cx = (x1+x2)/2, cy=(y1+y2)/2;
            var p1 = rotatePoint(x1-cx, y1-cy, rot);
            var p2 = rotatePoint(x2-cx, y2-cy, rot);
            return ['M', p1[0] * flipH + cx, p1[1] * flipV + cy,
                         p2[0] * flipH + cx, p2[1] * flipV + cy].join(' ');
        },
        coffin: function(cx, cy, r){
        },
        crescent: function(cx, cy, r){
        },
        trigram: function(cx, cy, r, h){
        },
        leaf: function(cx, cy, r){
        },
        heart: function(cx, cy, r){
        }
    }

    // New path handlers

    Paper.prototype.asterisk = function(cx, cy, r, num){
        return this.path()
            .attr('r', r).attr('num', num).attr('type', 'asterisk')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.rpolygon = function(cx, cy, r, num){
        return this.path()
            .attr('r', r).attr('num', num).attr('type', 'polygon')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.star = function(cx, cy, r, num){
        return this.path()
            .attr('r', r).attr('num', num).attr('type', 'star')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.spiral = function(cx, cy, r, num, len){
        return this.path()
            .attr('r', r).attr('num', num).attr('len', len).attr('type', 'spiral')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.line = function(cx, cy, x2, y2){
        return this.path()
            .attr('x2', x2).attr('y2', y2).attr('type', 'line')
            .moveTo(cx, cy).setup();
    };

    // Element extensions

    Element.prototype.setup = function(){
        this.adjacent = [];
        return this.drag(onDrag, onDragStart, onDragEnd);
    };

    Element.prototype.num = function(name){
        return Number(this.attr(name));
    };

    Element.prototype.rad = function(name){
        return rad(this.num(name));
    };

    Element.prototype.bool = function(name, val){
        if (typeof(val) === 'undefined'){
            return this.attr(name) === 'true';
        }else{
            if (val){
                this.attr(name, 'true');
            }else{
                this.node.removeAttribute(name);
            }
        }
        return this;
    };

    Element.prototype.ease = function(name){
        return mina[this.attr(name)] || mina.easeinout; // get easing
    };

    Element.prototype.update = function(b){
        if(b){
            return this.animate({d: pathFns[this.attr('type')](this)}, 100, this.ease(), this.update)
        }
        return this.attr('d', pathFns[this.attr('type')](this));
    }

    Element.prototype.moveTo = function(cx, cy){
        return this.attr('cx', cx).attr('cy', cy).update();
    };

    Element.prototype.move = function(dx, dy){
        return this.attr('cx', this.num('cx') + dx).attr('cy', this.num('cy') + dy).update();
    };

    Element.prototype.rotateTo = function(deg){
        return this.attr('rot', deg).update();
    };

    Element.prototype.rotate = function(deg){
        return this.attr('rot', this.num('rot') + deg).update(true);
    };

    Element.prototype.flipH = function(){
        if (this.node.hasAttribute('flipH')){
            this.node.removeAttribute('flipH');
        }else{
            this.attr('flipH', true);
        }
        return this.update(true);
    };

    Element.prototype.flipV = function(){
        if (this.node.hasAttribute('flipV')){
            this.node.removeAttribute('flipV');
        }else{
            this.attr('flipV', true);
        }
        return this.update(true);
    };

    Element.prototype.snapToGrid = function(){
        var x = this.num('cx'), y = this.num('cy');
        x = Math.round(x/GRIDSIZE)*GRIDSIZE
        y = Math.round(y/GRIDSIZE)*GRIDSIZE
        /*var dX = x % GRIDSIZE;
        if (dX < GRIDSIZE / 2){
            x -= dX;
        }else{
            x += GRIDSIZE - dX;
        }
        var dY = y % GRIDSIZE;
        if (dY < GRIDSIZE / 2){
            y -= dY;
        }else{
            y += GRIDSIZE - dY;
        }*/
        this.moveTo(x,y);
    };

    Element.prototype.pulse = function(){
        var dur=this.num('dur') || 1000, color=this.attr('color') || '#00F';
        var easing=this.ease('ease');
        this.animate({stroke: color, strokeWidth: 7}, dur, easing, this.unPulse)
    };

    Element.prototype.unPulse = function(){
        var dur=this.num('dur') || 1000, color='#000';
        var easing=this.ease('ease');
        this.animate({stroke: color, strokeWidth: 5}, dur, easing, this.endPulse);
    };

    Element.prototype.endPulse = function(){
    };

    function distance(x1, y1, x2, y2){
        var val = Math.sqrt(Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2));
        return val;
    }

    Element.prototype.intersects = function(e){
        var selfType = this.attr('type');
        var otherType = e.attr('type');
        if (selfType === 'line' && otherType === 'line'){
            return !! Snap.path.intersection(this, e).length;
        }else if (selfType === 'line'){
            var x1=this.num('cx'), x2=this.num('x2')+x1, y1=this.num('cy'), y2=this.num('y2')+y1;
            var ex=e.num('cx'), ey=e.num('cy');
            return ((distance(x1, y1, ex, ey) < 30) ||
                    (distance(x2, y2, ex, ey) < 30));
        }else if (otherType === 'line'){
            var x1=e.num('cx'), x2=e.num('x2')+x1, y1=e.num('cy'), y2=e.num('y2')+y1;
            var tx=this.num('cx'), ty=this.num('cy');
            return ((distance(x1, y1, tx, ty) < 30) ||
                    (distance(x2, y2, tx, ty) < 30));
        }else{
            return (distance(this.num('cx'), this.num('cy'), e.num('cx'), e.num('cy')) < 40);
        }
    };

    Element.prototype.joinGroup = function(color){
        var self = this;
        self.attr('stroke', color);
        self.attr('group', '');
        var group = null;
        var connected = [].slice.call(Snap.selectAll('path')).filter(function(e){
            if (self === e){
                return false;
            }
            return self.intersects(e);
        });
        this.adjacent = connected;
        connected.forEach(function(e){
            e.adjacent.push(self);
            if (!group){
                if (e.attr('group')){
                    group = e.attr('group');
                    self.attr('group', group);
                    color = e.attr('stroke');
                    self.attr('stroke', color);
                }else{
                    group = randomId();
                    self.attr('group', group);
                    e.attr('group', group);
                    e.attr('stroke', color);
                }
            }else{
                if (e.attr('group') === group){
                    // do nothing
                }else if (!e.attr('group')){
                    e.attr('group', group);
                    e.attr('stroke', color);
                }else{
                    // adopt group
                    getGroup(e.attr('group')).forEach(function(e){
                        e.attr('group', group);
                        e.attr('stroke', color);
                    });

                }
            }
        });
    };

});

var ATTRS = {
    fill: 'transparent',
    stroke: '#000',
    strokeWidth: 5,
    color: '#00F', // for animation
}
<commit_msg>move distance to utilities<commit_after>var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var GRIDSIZE = 25;
var PI=Math.PI, cos=Math.cos, sin=Math.sin, abs=Math.abs, rad=Snap.rad;

var selected; //"selected"
var running = false;

// Utilities

function randint(max){
    return Math.floor(Math.random() * max);
}

function randcolor(){
    return Snap.hsl(randint(360), 50, 50);
}

function choice(list){
    return list[randint(list.length)];
}

// properly delete from a list
function deleteItem(list, item) {
    var idx = list.indexOf(item);
    if (idx > -1) {
        list.splice(idx, 1);
    }
    return item;
}

function distance(x1, y1, x2, y2){
    var val = Math.sqrt(Math.pow(x2-x1, 2) + Math.pow(y2-y1, 2));
    return val;
}

function getGroup(id){
    return [].slice.call(Snap.selectAll('path')).filter(function(e){
        return e.attr('group') === id;
    });

}

function rotatePoint(px, py, angle){
    var s = sin(angle);
    var c = cos(angle);
    var x = px * c - py * s;
    var y = px * s + py * c;
    return [x, y];
}

function randomId() {
    // Based on Paul Irish's random hex color:http://www.paulirish.com/2009/random-hex-color-code-snippets/
    // Theoretically could return non-unique values, not going to let that keep me up at night
    return 'k' + Math.floor(Math.random() * 16777215).toString(16); // 'k' because ids have to start with a letter
}

Snap.plugin(function (Snap, Element, Paper, global, Fragment) {
    var prevdx, prevdy;
    function onDrag(dx, dy, x, y, evt){
        if(!running){
            if(evt.shiftKey){
                this.moveTo(Math.round((x-window.innerWidth/2)/25)*25, Math.round((y-window.innerHeight/2)/25)*25);
            }else{
                this.move(dx - prevdx, dy - prevdy);
            }
            prevdx = dx;
            prevdy = dy;
        }
    }

    function onDragStart(x, y, evt){
        var self = this;
        this.adjacent.forEach(function(e){
            deleteItem(e.adjacent, self);
        });
        this.adjacent = [];
        if(!running){
            prevdx = prevdy = 0;
            if (evt.metaKey){
                this.insertBefore(this.clone().setup());
            }
        }
    }

    function onDragEnd(evt){
        if(!running){
            this.snapToGrid();
            this.joinGroup(randcolor());
            selected = this;
        }
    }

    var pathFns = {

        asterisk: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num');
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var path = [];
            var theta = PI * 2 / num;
            for (var i = 0; i < num; i++){
                path.push('M', cx, cy,
                          cos(theta * i + rot) * r * flipH + cx,
                          sin(theta * i + rot) * r  * flipV + cy);
            }
            return path.join(' ');
        },
        polygon: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num');
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var path = ['M'];
            var theta = PI * 2 / num;
            for (var i = 0; i < num; i++){
                path.push(cos(theta * i + rot) * r * flipH + cx,
                          sin(theta * i + rot) * r * flipV + cy);
            }
            path.push('Z');
            return path.join(' ');
        },
        star: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num');
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            // num should be odd and 5 or greater
            var skip = (num - 1) / 2;
            var theta = PI * 2 / num * skip;
            var path = ['M'];
            for (var i = 0; i < num; i++){
                path.push(cos(theta * i + rot) * r * flipH + cx,
                          sin(theta * i + rot) * r * flipV + cy);
            }
            path.push('Z');
            return path.join(' ');
        },
        spiral: function(e){
            var cx=e.num('cx'), cy=e.num('cy'), r=e.num('r'), num=e.num('num'), len=e.num('len');
            var theta = PI * 2 / num;
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var dR = r / (num * len);
            var path = ['M'];
            for (var i = 0; i < (num * len); i++){
                path.push(cos(theta * i + rot) * (dR * i) * flipH + cx,
                          sin(theta * i + rot) * (dR * i) * flipV + cy);
            }
            return path.join(' ');
        },
        line: function(e){
            var x1=e.num('cx'), y1=e.num('cy'), x2=e.num('x2')+x1, y2=e.num('y2')+y1;
            var flipH = e.bool('flipH') ? -1 : +1, flipV = e.bool('flipV') ? -1 : +1;
            var rot=e.rad('rot') * flipH * flipV;
            var cx = (x1+x2)/2, cy=(y1+y2)/2;
            var p1 = rotatePoint(x1-cx, y1-cy, rot);
            var p2 = rotatePoint(x2-cx, y2-cy, rot);
            return ['M', p1[0] * flipH + cx, p1[1] * flipV + cy,
                         p2[0] * flipH + cx, p2[1] * flipV + cy].join(' ');
        },
        coffin: function(cx, cy, r){
        },
        crescent: function(cx, cy, r){
        },
        trigram: function(cx, cy, r, h){
        },
        leaf: function(cx, cy, r){
        },
        heart: function(cx, cy, r){
        }
    }

    // New path handlers

    Paper.prototype.asterisk = function(cx, cy, r, num){
        return this.path()
            .attr('r', r).attr('num', num).attr('type', 'asterisk')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.rpolygon = function(cx, cy, r, num){
        return this.path()
            .attr('r', r).attr('num', num).attr('type', 'polygon')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.star = function(cx, cy, r, num){
        return this.path()
            .attr('r', r).attr('num', num).attr('type', 'star')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.spiral = function(cx, cy, r, num, len){
        return this.path()
            .attr('r', r).attr('num', num).attr('len', len).attr('type', 'spiral')
            .moveTo(cx, cy).setup();
    };

    Paper.prototype.line = function(cx, cy, x2, y2){
        return this.path()
            .attr('x2', x2).attr('y2', y2).attr('type', 'line')
            .moveTo(cx, cy).setup();
    };

    // Element extensions

    Element.prototype.setup = function(){
        this.adjacent = [];
        return this.drag(onDrag, onDragStart, onDragEnd);
    };

    Element.prototype.num = function(name){
        return Number(this.attr(name));
    };

    Element.prototype.rad = function(name){
        return rad(this.num(name));
    };

    Element.prototype.bool = function(name, val){
        if (typeof(val) === 'undefined'){
            return this.attr(name) === 'true';
        }else{
            if (val){
                this.attr(name, 'true');
            }else{
                this.node.removeAttribute(name);
            }
        }
        return this;
    };

    Element.prototype.ease = function(name){
        return mina[this.attr(name)] || mina.easeinout; // get easing
    };

    Element.prototype.update = function(b){
        if(b){
            return this.animate({d: pathFns[this.attr('type')](this)}, 100, this.ease(), this.update)
        }
        return this.attr('d', pathFns[this.attr('type')](this));
    }

    Element.prototype.moveTo = function(cx, cy){
        return this.attr('cx', cx).attr('cy', cy).update();
    };

    Element.prototype.move = function(dx, dy){
        return this.attr('cx', this.num('cx') + dx).attr('cy', this.num('cy') + dy).update();
    };

    Element.prototype.rotateTo = function(deg){
        return this.attr('rot', deg).update();
    };

    Element.prototype.rotate = function(deg){
        return this.attr('rot', this.num('rot') + deg).update(true);
    };

    Element.prototype.flipH = function(){
        if (this.node.hasAttribute('flipH')){
            this.node.removeAttribute('flipH');
        }else{
            this.attr('flipH', true);
        }
        return this.update(true);
    };

    Element.prototype.flipV = function(){
        if (this.node.hasAttribute('flipV')){
            this.node.removeAttribute('flipV');
        }else{
            this.attr('flipV', true);
        }
        return this.update(true);
    };

    Element.prototype.snapToGrid = function(){
        var x = this.num('cx'), y = this.num('cy');
        x = Math.round(x/GRIDSIZE)*GRIDSIZE
        y = Math.round(y/GRIDSIZE)*GRIDSIZE
        /*var dX = x % GRIDSIZE;
        if (dX < GRIDSIZE / 2){
            x -= dX;
        }else{
            x += GRIDSIZE - dX;
        }
        var dY = y % GRIDSIZE;
        if (dY < GRIDSIZE / 2){
            y -= dY;
        }else{
            y += GRIDSIZE - dY;
        }*/
        this.moveTo(x,y);
    };

    Element.prototype.pulse = function(){
        var dur=this.num('dur') || 1000, color=this.attr('color') || '#00F';
        var easing=this.ease('ease');
        this.animate({stroke: color, strokeWidth: 7}, dur, easing, this.unPulse)
    };

    Element.prototype.unPulse = function(){
        var dur=this.num('dur') || 1000, color='#000';
        var easing=this.ease('ease');
        this.animate({stroke: color, strokeWidth: 5}, dur, easing, this.endPulse);
    };

    Element.prototype.endPulse = function(){
    };

    Element.prototype.intersects = function(e){
        var selfType = this.attr('type');
        var otherType = e.attr('type');
        if (selfType === 'line' && otherType === 'line'){
            return !! Snap.path.intersection(this, e).length;
        }else if (selfType === 'line'){
            var x1=this.num('cx'), x2=this.num('x2')+x1, y1=this.num('cy'), y2=this.num('y2')+y1;
            var ex=e.num('cx'), ey=e.num('cy');
            return ((distance(x1, y1, ex, ey) < 30) ||
                    (distance(x2, y2, ex, ey) < 30));
        }else if (otherType === 'line'){
            var x1=e.num('cx'), x2=e.num('x2')+x1, y1=e.num('cy'), y2=e.num('y2')+y1;
            var tx=this.num('cx'), ty=this.num('cy');
            return ((distance(x1, y1, tx, ty) < 30) ||
                    (distance(x2, y2, tx, ty) < 30));
        }else{
            return (distance(this.num('cx'), this.num('cy'), e.num('cx'), e.num('cy')) < 40);
        }
    };

    Element.prototype.joinGroup = function(color){
        var self = this;
        self.attr('stroke', color);
        self.attr('group', '');
        var group = null;
        var connected = [].slice.call(Snap.selectAll('path')).filter(function(e){
            if (self === e){
                return false;
            }
            return self.intersects(e);
        });
        this.adjacent = connected;
        connected.forEach(function(e){
            e.adjacent.push(self);
            if (!group){
                if (e.attr('group')){
                    group = e.attr('group');
                    self.attr('group', group);
                    color = e.attr('stroke');
                    self.attr('stroke', color);
                }else{
                    group = randomId();
                    self.attr('group', group);
                    e.attr('group', group);
                    e.attr('stroke', color);
                }
            }else{
                if (e.attr('group') === group){
                    // do nothing
                }else if (!e.attr('group')){
                    e.attr('group', group);
                    e.attr('stroke', color);
                }else{
                    // adopt group
                    getGroup(e.attr('group')).forEach(function(e){
                        e.attr('group', group);
                        e.attr('stroke', color);
                    });

                }
            }
        });
    };

});

var ATTRS = {
    fill: 'transparent',
    stroke: '#000',
    strokeWidth: 5,
    color: '#00F', // for animation
}
<|endoftext|>


<commit_before>define([
    'module',
    'jquery',
    'underscore',
    'tpl!templates/card.html.tpl'
], function(module, $, _, card_tpl) {

    // will cache the course.json file
    var _data, _xhr;
    function _getData( callback ) {
        if(!_data) {
            _xhr = $.getJSON('data/data.json', function( data ) {
                    _data = data;
                    callback && callback(_data);
                });
        }
        else {
            callback && callback(_data);
        }
    }

    var _store_id = 'redjack';

    var _actions,
        _icons,
        _card_types,
        _cards,
        _blitz_cards,
        _action_cards,
        _shuffled_deck,
        _deck,
        _current_card;

    var _blitz_card_amt = null;

    var _$main = $('.main'),
        _$menu = $('.menu'),
        _$difficulty = $('.difficulty'),
        _$deck = $('.deck'),
        _$prompt = $('.prompt'),
        _$notification = $('.notification');

    var _$btnStart = $('.btn-start'),
        _$btnBlitzAmt = $('.btn-amt'),
        _$btnPauseMenu = $('.btn-pause-menu'),
        _$btnPauseMenuClose = $('.btn-close'),
        _$btnShuffle = $('.btn-shuffle');

    var _transEvent;

    function _whichTransitionEvent(){
        var t,
            el = document.createElement('fakeelement'),
            transitions = {
              'transition':'transitionend',
              'OTransition':'oTransitionEnd',
              'MozTransition':'transitionend',
              'WebkitTransition':'webkitTransitionEnd',
              'msTransitionEnd' : 'MSTransitionEnd'
            };

        for(t in transitions){
            if( el.style[t] !== undefined ){
                return transitions[t];
            }
        }
    }

    function _parse( data ) {
        _actions = data.actions;
        _icons = data.icons;
        _card_types = data.enum_card_types;
        _cards = data.cards;
        _blitz_cards = [];

        _.each(_cards, function( card ) {
            var action_ids = card.actions,
                icon_ids = card.icons;

            if(card.type === _card_types.BLITZ) {
                _blitz_cards.push(card);
            }

            card.actions = _.map(action_ids, function( action_id ) { return _.findWhere( _actions, { id : action_id }); });
            card.icons = _.map(icon_ids, function ( icon_id ) { return _.findWhere(_icons, { id : icon_id }); });
        });

        _action_cards = _.difference(_cards, _blitz_cards);
    }

    function _shuffleIntoDeck ( card_obj ) {
        var insertion_point = Math.floor(Math.random()*_shuffled_deck.length);
        _shuffled_deck.splice(insertion_point, 0, card_obj);
    }

    function _showPrompt(text, yesHandler, noHandler) {

        _$prompt.find('p').html(text);

        _$prompt.find('.btn-yes')
                .off()
                .one('click', function() {
                    yesHandler && yesHandler();
                    _$prompt.toggleClass('hidden');
                });
        _$prompt.find('.btn-no')
                .off()
                .one('click', function() {
                    noHandler && noHandler();
                    _$prompt.toggleClass('hidden');
                });

        _$prompt.toggleClass('hidden');
    }

    function _flipCard( card ) {
        card = $(card);
        card.one(_transEvent, function() {
                $(this).one('click', function() {
                    if(_current_card.type === _card_types.BLITZ) {

                        var that = $(this);
                        _showPrompt("Did you reference the decision bit?",
                                    function() {
                                        _shuffleIntoDeck(_current_card);
                                        _tossCard(that);
                                    },
                                    function() {
                                        _tossCard(that);
                                    });
                    }
                    else {
                        _tossCard(this);
                    }
                });
            })
            .toggleClass('flipped');

    }

    function _tossCard ( card ) {
        card = $(card);
        card.one(_transEvent, function () {
                _removeCard(card);
                _nextCard();
              })
              .toggleClass('tossed');
    }

    function _removeCard( card ) {
        card = $(card);
        card.off().remove();
    }

    function _renderCard( card ) {
        var obj = { card : card,  total_cards : _deck.length, card_number: _deck.length - _shuffled_deck.length },
            card_el = $(card_tpl(obj)).prependTo('.deck');

        card_el.one('click', function() {
                _$notification.addClass('hidden');
                _flipCard( this );
            });
    }

    function _nextCard() {
        if(_shuffled_deck.length) {
            _current_card = _shuffled_deck.shift();
           _renderCard(_current_card);
        }
        else {
            _current_card = null;
            _$deck.addClass('empty');
        }
    }

    function _deal() {
        _deck = _action_cards.concat(_.sample(_blitz_cards, _blitz_card_amt));
        _shuffled_deck = _.shuffle(_deck);
        _$notification.removeClass('hidden');
        _nextCard();
    }

    function _restart() {
        $('.card').off().remove();
        _$notification.addClass('hidden');
        _$menu.addClass('hidden');
        _$main.removeClass('paused');
    }

    function _init () {

        _transEvent = _whichTransitionEvent();

        _$btnStart.click(function() {
            _$menu.addClass('hidden');
            _$difficulty.removeClass('hidden');
        });

        _$btnBlitzAmt.click(function() {
            _blitz_card_amt = parseInt($(this).data('amt'),10);
            _$difficulty.addClass('hidden');
            _deal();
        });

        _$btnShuffle.click(function() {
            _$deck.removeClass('empty');
            _deal();
        });
        _$btnPauseMenu.click(function() {
            _$main.addClass('paused');
        });
        _$btnPauseMenuClose.click(function() {
            _$main.removeClass('paused');
        });

        $('.btn-quit').click(function() {
                _showPrompt("Are you sure you want to quit?",
                            function() {
                                _restart();
                            });
            });

        _getData(_parse);
    }

    _init();

    return {
        version : ''
    };
});
<commit_msg>fixed issue where main menu would  not appear on a quit<commit_after>define([
    'module',
    'jquery',
    'underscore',
    'tpl!templates/card.html.tpl'
], function(module, $, _, card_tpl) {

    // will cache the course.json file
    var _data, _xhr;
    function _getData( callback ) {
        if(!_data) {
            _xhr = $.getJSON('data/data.json', function( data ) {
                    _data = data;
                    callback && callback(_data);
                });
        }
        else {
            callback && callback(_data);
        }
    }

    var _store_id = 'redjack';

    var _actions,
        _icons,
        _card_types,
        _cards,
        _blitz_cards,
        _action_cards,
        _shuffled_deck,
        _deck,
        _current_card;

    var _blitz_card_amt = null;

    var _$main = $('.main'),
        _$menu = $('.menu'),
        _$difficulty = $('.difficulty'),
        _$deck = $('.deck'),
        _$prompt = $('.prompt'),
        _$notification = $('.notification');

    var _$btnStart = $('.btn-start'),
        _$btnBlitzAmt = $('.btn-amt'),
        _$btnPauseMenu = $('.btn-pause-menu'),
        _$btnPauseMenuClose = $('.btn-close'),
        _$btnShuffle = $('.btn-shuffle');

    var _transEvent;

    function _whichTransitionEvent(){
        var t,
            el = document.createElement('fakeelement'),
            transitions = {
              'transition':'transitionend',
              'OTransition':'oTransitionEnd',
              'MozTransition':'transitionend',
              'WebkitTransition':'webkitTransitionEnd',
              'msTransitionEnd' : 'MSTransitionEnd'
            };

        for(t in transitions){
            if( el.style[t] !== undefined ){
                return transitions[t];
            }
        }
    }

    function _parse( data ) {
        _actions = data.actions;
        _icons = data.icons;
        _card_types = data.enum_card_types;
        _cards = data.cards;
        _blitz_cards = [];

        _.each(_cards, function( card ) {
            var action_ids = card.actions,
                icon_ids = card.icons;

            if(card.type === _card_types.BLITZ) {
                _blitz_cards.push(card);
            }

            card.actions = _.map(action_ids, function( action_id ) { return _.findWhere( _actions, { id : action_id }); });
            card.icons = _.map(icon_ids, function ( icon_id ) { return _.findWhere(_icons, { id : icon_id }); });
        });

        _action_cards = _.difference(_cards, _blitz_cards);
    }

    function _shuffleIntoDeck ( card_obj ) {
        var insertion_point = Math.floor(Math.random()*_shuffled_deck.length);
        _shuffled_deck.splice(insertion_point, 0, card_obj);
    }

    function _showPrompt(text, yesHandler, noHandler) {

        _$prompt.find('p').html(text);

        _$prompt.find('.btn-yes')
                .off()
                .one('click', function() {
                    yesHandler && yesHandler();
                    _$prompt.toggleClass('hidden');
                });
        _$prompt.find('.btn-no')
                .off()
                .one('click', function() {
                    noHandler && noHandler();
                    _$prompt.toggleClass('hidden');
                });

        _$prompt.toggleClass('hidden');
    }

    function _flipCard( card ) {
        card = $(card);
        card.one(_transEvent, function() {
                $(this).one('click', function() {
                    if(_current_card.type === _card_types.BLITZ) {

                        var that = $(this);
                        _showPrompt("Did you reference the decision bit?",
                                    function() {
                                        _shuffleIntoDeck(_current_card);
                                        _tossCard(that);
                                    },
                                    function() {
                                        _tossCard(that);
                                    });
                    }
                    else {
                        _tossCard(this);
                    }
                });
            })
            .toggleClass('flipped');

    }

    function _tossCard ( card ) {
        card = $(card);
        card.one(_transEvent, function () {
                _removeCard(card);
                _nextCard();
              })
              .toggleClass('tossed');
    }

    function _removeCard( card ) {
        card = $(card);
        card.off().remove();
    }

    function _renderCard( card ) {
        var obj = { card : card,  total_cards : _deck.length, card_number: _deck.length - _shuffled_deck.length },
            card_el = $(card_tpl(obj)).prependTo('.deck');

        card_el.one('click', function() {
                _$notification.addClass('hidden');
                _flipCard( this );
            });
    }

    function _nextCard() {
        if(_shuffled_deck.length) {
            _current_card = _shuffled_deck.shift();
           _renderCard(_current_card);
        }
        else {
            _current_card = null;
            _$deck.addClass('empty');
        }
    }

    function _deal() {
        _deck = _action_cards.concat(_.sample(_blitz_cards, _blitz_card_amt));
        _shuffled_deck = _.shuffle(_deck);
        _$notification.removeClass('hidden');
        _nextCard();
    }

    function _restart() {
        $('.card').off().remove();
        _$notification.addClass('hidden');
        _$menu.removeClass('hidden');
        _$main.removeClass('paused');
    }

    function _init () {

        _transEvent = _whichTransitionEvent();

        _$btnStart.click(function() {
            _$menu.addClass('hidden');
            _$difficulty.removeClass('hidden');
        });

        _$btnBlitzAmt.click(function() {
            _blitz_card_amt = parseInt($(this).data('amt'),10);
            _$difficulty.addClass('hidden');
            _deal();
        });

        _$btnShuffle.click(function() {
            _$deck.removeClass('empty');
            _deal();
        });
        _$btnPauseMenu.click(function() {
            _$main.addClass('paused');
        });
        _$btnPauseMenuClose.click(function() {
            _$main.removeClass('paused');
        });

        $('.btn-quit').click(function() {
                _showPrompt("Are you sure you want to quit?",
                            function() {
                                _restart();
                            });
            });

        _getData(_parse);
    }

    _init();

    return {
        version : ''
    };
});
<|endoftext|>


<commit_before>//harvest nearest source
module.exports = function Dog(creep) {

	var target = creep.room.findNearest(Game.HOSTILE_CREEPS);
	if (creep.body[3].hits > 0) {
     	creep.moveTo(target);
        creep.attack(target);
    }
    else {
        var spawn = creep.pos.findNearest(Game.MY_SPAWNS)
        creep.moveTo(spawn);
    }
};

module.exports.parts = [Game.TOUGH, Game.TOUGH, Game.TOUGH, Game.ATTACK, Game.MOVE];

module.exports.role = "guard";
<commit_msg>Fixed dog bug.<commit_after>//harvest nearest source
module.exports = function Dog(creep) {

	var target = creep.pos.findNearest(Game.HOSTILE_CREEPS);
	if (creep.body[3].hits > 0) {
     	creep.moveTo(target);
        creep.attack(target);
    }
    else {
        var spawn = creep.pos.findNearest(Game.MY_SPAWNS)
        creep.moveTo(spawn);
    }
};

module.exports.parts = [Game.TOUGH, Game.TOUGH, Game.TOUGH, Game.ATTACK, Game.MOVE];

module.exports.role = "guard";
<|endoftext|>