<commit_before>#!/usr/bin/env node

var exec = require('child_process').exec;
var spawn = require('child_process').spawn;

// MDM NOTE that node v0.12 or higher is required for this.
var execSync = require('child_process').execSync;
var spawnSync = require('child_process').spawnSync;

var spawnargs = require('spawn-args');

//=========== run_command_sync_to_console: run one command and let output immediately flow to console ============
var run_command_sync_to_console = function (cmd) {
    execSync(cmd, {stdio:[0,1,2]}, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

//=========== run_command_async_to_console: async run one command and dump output to console when complete ============
var run_command_async_to_console = function (cmd) {
    exec(cmd, function(error, stdout, stderr) {
        if (stdout.length > 0 ) console.log(stdout);
        if (stderr.length > 0 ) console.log(stderr);
    });
}

//=========== run_command_quietly: runs without output unless error ============
var run_command_quietly = function (cmd) {
    execSync(cmd, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

// =========== run_command: run one command and get output ============
// Run a command asynchronously and get the output when it finishes in a callback.
// Usage:
// run_command( "ls -l", function(err,text) { console.log (text) });
var run_command = function (cmd, callBack ) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    // DEBUG this works!
    // var args = ["status"];
    // cmd = "git";

    // DEBUG this works!
    // cmd = "git";
    // var args = ["commit","-a","-m",'"synctrouble"'];

    // DEBUG:
    // console.log('cmd args: ' + cmd + ' ----- ' + args);

    var spawn = require('child_process').spawn;

    var child = spawn(cmd, args);
    // var child = spawn(cmd, args, {stdio: "inherit"});

    var resp = "";
    var errr = "";
    child.stdout.on('data', function (buffer) { resp += buffer.toString() });
    child.stderr.on('data', function (buffer) { errr += buffer.toString() });

    child.stdout.on('end', function() { callBack (errr, resp) });
}

// =========== run_command_sync: run one command and get output ============
// Run a command synchronously and get the output when it finishes.
// Usage:
// var lsout = run_command_sync( "ls", ["-l"]);
var run_command_sync = function (cmd) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    var spawnSync = require('child_process').spawnSync;
    var outp = spawnSync(cmd, args, { encoding : 'utf8' });
    return outp.stdout;
}

// =========== runsteps: run a specific set of commands in specific directories ============
// Given: steps, an array of {name,folder,cmd} objects, eg:
//
//      var my_steps =
//      [
//          { name: 'update Project'        , folder: '.'       , cmd: 'git pull'       },
//          { name: 'build Project'         , folder: '.'       , cmd: 'make'           },
//      ];
//
// This function runs the requested steps.
// Verbosity can be:
//		"quiet"		no output
//		undefined	normal output - the command output is logged to console
//		"verbose"	more output - step name, folder, command output
// Define async to get asynchronous execution.
var runsteps = function (steps,verbosity,async) {

    var path = require('path');

    steps.forEach(function(step,i) {

        try {

            if (verbosity == "verbose") {
                console.log('step: ' + step.name);
            }

            process.chdir(path.normalize(step.folder));

            if (async) {

                run_command(step.cmd, function(text) {
                    console.log ('------------------------------');
                    console.log(step.folder);
                    console.log ('------------------------------');
                    console.log (text)
                });

                // Workaround during testing
                // run_command_async_to_console(steps[i].cmd);

            } else if (verbosity != "quiet") {

                if (verbosity == "verbose") {
                    console.log ('------------------------------');
                    console.log(step.folder);
                    console.log ('------------------------------');
                }
        		run_command_sync_to_console(step.cmd);

            } else {
        		run_command_quietly(step.cmd);
        	}
        }
        catch (err) {
            if (verbosity == "verbose") {
            	console.log(err);
            }
        }
    });
}

var combine_params = function(params) {
    var result = "";
    if (params.length > 0)
    {
        params.forEach(function(val,index,array){
            if (index != 0) { result += " "; }
            result += val;
        });
    }
    return result;
}

module.exports.run_command_sync = run_command_sync;
module.exports.run_command_sync_to_console = run_command_sync_to_console;
module.exports.run_command_async_to_console = run_command_async_to_console;
module.exports.run_command_quietly = run_command_quietly;
module.exports.run_command = run_command;
module.exports.runsteps = runsteps;
module.exports.combine_params = combine_params;
<commit_msg>verbose log cleanup<commit_after>#!/usr/bin/env node

var exec = require('child_process').exec;
var spawn = require('child_process').spawn;

// MDM NOTE that node v0.12 or higher is required for this.
var execSync = require('child_process').execSync;
var spawnSync = require('child_process').spawnSync;

var spawnargs = require('spawn-args');

//=========== run_command_sync_to_console: run one command and let output immediately flow to console ============
var run_command_sync_to_console = function (cmd) {
    execSync(cmd, {stdio:[0,1,2]}, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

//=========== run_command_async_to_console: async run one command and dump output to console when complete ============
var run_command_async_to_console = function (cmd) {
    exec(cmd, function(error, stdout, stderr) {
        if (stdout.length > 0 ) console.log(stdout);
        if (stderr.length > 0 ) console.log(stderr);
    });
}

//=========== run_command_quietly: runs without output unless error ============
var run_command_quietly = function (cmd) {
    execSync(cmd, function(error, stdout, stderr) {
        if (error) {
            console.log('======= RUN ERROR =======');
            throw error;
        }
    });
}

// =========== run_command: run one command and get output ============
// Run a command asynchronously and get the output when it finishes in a callback.
// Usage:
// run_command( "ls -l", function(err,text) { console.log (text) });
var run_command = function (cmd, callBack ) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    // DEBUG this works!
    // var args = ["status"];
    // cmd = "git";

    // DEBUG this works!
    // cmd = "git";
    // var args = ["commit","-a","-m",'"synctrouble"'];

    // DEBUG:
    // console.log('cmd args: ' + cmd + ' ----- ' + args);

    var spawn = require('child_process').spawn;

    var child = spawn(cmd, args);
    // var child = spawn(cmd, args, {stdio: "inherit"});

    var resp = "";
    var errr = "";
    child.stdout.on('data', function (buffer) { resp += buffer.toString() });
    child.stderr.on('data', function (buffer) { errr += buffer.toString() });

    child.stdout.on('end', function() { callBack (errr, resp) });
}

// =========== run_command_sync: run one command and get output ============
// Run a command synchronously and get the output when it finishes.
// Usage:
// var lsout = run_command_sync( "ls", ["-l"]);
var run_command_sync = function (cmd) {

    var fullargs = spawnargs(cmd);
    cmd = fullargs[0];
    var args = fullargs.slice(1);

    var spawnSync = require('child_process').spawnSync;
    var outp = spawnSync(cmd, args, { encoding : 'utf8' });
    return outp.stdout;
}

// =========== runsteps: run a specific set of commands in specific directories ============
// Given: steps, an array of {name,folder,cmd} objects, eg:
//
//      var my_steps =
//      [
//          { name: 'update Project'        , folder: '.'       , cmd: 'git pull'       },
//          { name: 'build Project'         , folder: '.'       , cmd: 'make'           },
//      ];
//
// This function runs the requested steps.
// Verbosity can be:
//		"quiet"		no output
//		undefined	normal output - the command output is logged to console
//		"verbose"	more output - step name, folder, command output
// Define async to get asynchronous execution.
var runsteps = function (steps,verbosity,async) {

    var path = require('path');

    steps.forEach(function(step,i) {

        try {

            if (verbosity == "verbose") {
                console.log('step: ' + step.name);
            }

            process.chdir(path.normalize(step.folder));

            if (async) {

                run_command(step.cmd, function(text) {
                    if (verbosity == "verbose") {
                        console.log ('------------------------------');
                        console.log(step.folder);
                        console.log ('------------------------------');
                        console.log(step.folder + '> ' + step.cmd);
                    }
                    console.log (text)
                });

                // Workaround during testing
                // run_command_async_to_console(steps[i].cmd);

            } else if (verbosity != "quiet") {

                if (verbosity == "verbose") {
                    console.log ('------------------------------');
                    console.log('step: ' + step.folder);
                    console.log ('------------------------------');
                    console.log(step.folder + '> ' + step.cmd);
                }
        		run_command_sync_to_console(step.cmd);

            } else {
        		run_command_quietly(step.cmd);
        	}
        }
        catch (err) {
            if (verbosity == "verbose") {
            	console.log(err);
            }
        }
    });
}

var combine_params = function(params) {
    var result = "";
    if (params.length > 0)
    {
        params.forEach(function(val,index,array){
            if (index != 0) { result += " "; }
            result += val;
        });
    }
    return result;
}

module.exports.run_command_sync = run_command_sync;
module.exports.run_command_sync_to_console = run_command_sync_to_console;
module.exports.run_command_async_to_console = run_command_async_to_console;
module.exports.run_command_quietly = run_command_quietly;
module.exports.run_command = run_command;
module.exports.runsteps = runsteps;
module.exports.combine_params = combine_params;
<|endoftext|>


<commit_before>var Episode = function(data, series_data){
  this.id = data.mid
  this.name = data.name.replace('&', '&')
  this.description = data.description
  this.image = data.stills ? data.stills[0].url : data.image
  this.broadcasters = data.broadcasters.join(', ')
  this.genres = data.genres.join(', ')
  this.duration = Math.round(data.duration / 60)
  if(series_data){
    this.series = new Series(series_data)
  }
}

Episode.popular = function(callback) {
  UitzendingGemist.Episode.popular(function(episodes){
    callback(
      episodes.map(function(episode){
        return new Episode(episode, episode.series)
      })
    )
  })
}
Episode.find = function(episode_id, series_id, callback) {
  UitzendingGemist.Series.find(series_id, function(series){
    episode = series.episodes.filter(function(episode){
      return episode.mid == episode_id
    })[0]

    callback(new Episode(episode, series))
  })
}
<commit_msg>Remove the current episode from the series episodes list<commit_after>var Episode = function(data, series_data){
  this.id = data.mid
  this.name = data.name.replace('&', '&')
  this.description = data.description
  this.image = data.stills ? data.stills[0].url : data.image
  this.broadcasters = data.broadcasters.join(', ')
  this.genres = data.genres.join(', ')
  this.duration = Math.round(data.duration / 60)
  if(series_data){
    this.series = new Series(series_data)
  }
}

Episode.popular = function(callback) {
  UitzendingGemist.Episode.popular(function(episodes){
    callback(
      episodes.map(function(episode){
        return new Episode(episode, episode.series)
      })
    )
  })
}

Episode.find = function(episode_id, series_id, callback) {
  UitzendingGemist.Series.find(series_id, function(series){
    episode = series.episodes.filter(function(episode){
      return episode.mid == episode_id
    })[0]

    series.episodes.splice(series.episodes.indexOf(episode), 1)

    callback(new Episode(episode, series))
  })
}
<|endoftext|>


<commit_before>// sum durations
var sum = function () {
    $('.sum').text(function () {
        var sum = 0;
        var table = $(this).parents('table.hours');
        table.find('tbody td:nth-child(4)').each(function (el, cell) {
            sum += parseFloat(cell.innerText);
        });
        return sum;
    });
};

var Tracker = Ractive.extend({
    data: {
        error: [],
        list: [],
        projects: [],
        project: null,
        hours: [],
        own_hours: [],
        active: null,
        duration: 0,
        date: moment().format("YYYY-MM-DD"), // needed for default value - a nice trick by accident
        isodateformat: function (date) {
            if (date) {
                return moment(date).format("YYYY-MM-DD");
            }
        },
        datetimeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LLL');
            }
        },
        dateformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LL');
            }
        },
        timeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('HH:mm');
            }
        },
        humanformat: function (datetime) {
            if (datetime) {
                return moment(datetime).fromNow();
            }
        }
    },

    createProject: function(project){
        return $.ajax({
            type: 'POST',
            url: window.location.href,
            data: project
        });
    },

    updateProject: function (project) {
        return $.ajax({
            type: 'PUT',
            url: window.location.href,
            data: project
        });
    },

    deleteProject: function (project_id) {
        return $.ajax({
            type: 'DELETE',
            url: window.location.href + '/' + project_id
        });
    },

    createHours: function (data) {
        return $.ajax({
            type: 'POST',
            url: '/',
            data: _.pick(data, 'project', 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    updateHours: function (data) {
        return $.ajax({
            type: 'PUT',
            url: '/' + data._id,
            data: _.pick(data, 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    create_timepickers: function (start_element, end_element) {
        var tracker = this;
        var startpicker, endpicker;

        startpicker = start_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var endp = endpicker.pickatime('picker');
                var end = endp.get();
                var start = this.get();
                if (start) {
                    var startarr = _.map(start.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    endp.set('min', startarr);
                    if (end) {
                        var endarr = _.map(end.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
        endpicker = end_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var startp = startpicker.pickatime('picker');
                var start = startp.get();
                var end = this.get();
                if (end) {
                    var endarr = _.map(end.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    startp.set('max', endarr);
                    if (start) {
                        var startarr = _.map(start.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
    }

});

module.exports.simple = function (projects, hours) {
    var tracker = new Tracker({
        el: '#simple',
        template: '#template',
        noIntro: true,
        data: {
            projects: projects,
            hours: hours,
            has_project: function (wants) {
                var u = URI(window.location.href);
                if (u.search(true).project) {
                    return wants;
                }
                else {
                    return !wants;
                }
            }
        }
    });

    tracker.on('toggleNew', function (event) {
        event.original.preventDefault();
        tracker.toggle('expanded');
        if (tracker.get('expanded')) {
            if (!Modernizr.inputtypes.date) {
                $('#date').fdatepicker({language: 'nb', weekStart: 1, format: 'yyyy-mm-dd'});
            }
            if (!Modernizr.touch || !Modernizr.inputtypes.time) {
                tracker.create_timepickers($('#start.timepicker'), $('#end.timepicker'));
            }
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('createHours', function (event) {
        event.original.preventDefault();
        event.context.project = $('#project').val();
        event.context.date = $(event.node).find("#date").val();
        event.context.start = $(event.node).find("#start").val();
        event.context.end = $(event.node).find("#end").val();

        tracker.createHours(event.context)
            .then(function(data){
                // everything ok
                tracker.get('hours').unshift(data);

                // should not reset everything: date and project should stay
                //$('form#createHours').trigger('reset');
                $(event.node).find("#start").val('');
                $(event.node).find("#end").val('');
                $(event.node).find("#duration").val('');
                $(event.node).find("#comment").val('');
                $(event.node).find("#date").focus();
                alerts.get('success').push(data.project.name + ' ' + moment(data.date).format('LL') + ' ' + moment(data.created).fromNow());
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateDuration', function (event) {
        var form = $(event.node).parents('form');
        var start = $(form).find(".start").val() ;
        var end = $(form).find(".end").val();
        var startarr, endarr;

        if (start) {
            startarr = _.map(start.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (end) {
            endarr = _.map(end.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (start && end) {
            var duration = moment.duration({
                hours: endarr[0] - startarr[0],
                minutes: endarr[1] - startarr[1]
            });
            if (duration) {
                tracker.set(event.keypath + '.duration', duration.as('hours'));
            }
        }
    });

    return tracker;
};

module.exports.projects = function (projects) {
    var tracker = new Tracker({
        el: '#projects',
        template: '#template',
        data: {
            projects: projects
        }
    });

    tracker.on('createProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };

        tracker.createProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.get('projects').unshift(data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('deleteProject', function (event) {
        tracker.deleteProject(event.context._id)
            .then(function (data) {
                tracker.get('projects').splice(event.keypath.split('.').pop());
            }, function (xhr, status, err) {
                tracker.get('error').push(xhr.responseText);
            });
    });

    return tracker;
};

module.exports.project = function (project, hours) {
    var all, own;
    var u = URI(window.location.href);
    if (u.hash() === "#all") {
        all = true;
    }
    else {
        own = true;
    }
    var own_hours = _.filter(hours, function (h) {
        return (h.user._id.match(/^gartmann/));
    });
    var tracker = new Tracker({
        el: '#project',
        template: '#template',
        data: {
            project: project,
            hours: hours,
            own_hours: own_hours,
            own: own,
            all: all
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('editToggle', function () {
        tracker.toggle('expanded');
    });

    tracker.on('toggleAll', function (event) {
        tracker.toggle('own');
        tracker.toggle('all');
        sum();
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };
        tracker.updateProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.set('project', data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    sum();

    return tracker;
};

<commit_msg>Fix sum() to work on firefox using jquery.html() instead of innterText<commit_after>// sum durations
var sum = function () {
    $('.sum').text(function () {
        var sum = 0;
        var table = $(this).parents('table.hours');
        table.find('tbody td:nth-child(4)').each(function (el, cell) {
            sum += parseFloat($(cell).html());
        });
        return sum;
    });
};

var Tracker = Ractive.extend({
    data: {
        error: [],
        list: [],
        projects: [],
        project: null,
        hours: [],
        own_hours: [],
        active: null,
        duration: 0,
        date: moment().format("YYYY-MM-DD"), // needed for default value - a nice trick by accident
        isodateformat: function (date) {
            if (date) {
                return moment(date).format("YYYY-MM-DD");
            }
        },
        datetimeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LLL');
            }
        },
        dateformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('LL');
            }
        },
        timeformat: function (datetime) {
            if (datetime) {
                return moment(datetime).format('HH:mm');
            }
        },
        humanformat: function (datetime) {
            if (datetime) {
                return moment(datetime).fromNow();
            }
        }
    },

    createProject: function(project){
        return $.ajax({
            type: 'POST',
            url: window.location.href,
            data: project
        });
    },

    updateProject: function (project) {
        return $.ajax({
            type: 'PUT',
            url: window.location.href,
            data: project
        });
    },

    deleteProject: function (project_id) {
        return $.ajax({
            type: 'DELETE',
            url: window.location.href + '/' + project_id
        });
    },

    createHours: function (data) {
        return $.ajax({
            type: 'POST',
            url: '/',
            data: _.pick(data, 'project', 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    updateHours: function (data) {
        return $.ajax({
            type: 'PUT',
            url: '/' + data._id,
            data: _.pick(data, 'date', 'start', 'end', 'duration', 'comment')
        });
    },

    create_timepickers: function (start_element, end_element) {
        var tracker = this;
        var startpicker, endpicker;

        startpicker = start_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var endp = endpicker.pickatime('picker');
                var end = endp.get();
                var start = this.get();
                if (start) {
                    var startarr = _.map(start.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    endp.set('min', startarr);
                    if (end) {
                        var endarr = _.map(end.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
        endpicker = end_element.pickatime({
            format: 'H:i',
            interval: 15,
            onClose: function () {
                var startp = startpicker.pickatime('picker');
                var start = startp.get();
                var end = this.get();
                if (end) {
                    var endarr = _.map(end.split(":"), function (item) {
                        return parseInt(item, 10);
                    });
                    startp.set('max', endarr);
                    if (start) {
                        var startarr = _.map(start.split(":"), function (item) {
                            return parseInt(item, 10);
                        });
                        var duration = moment.duration({
                            hours: endarr[0] - startarr[0],
                            minutes: endarr[1] - startarr[1]
                        });
                        if (duration) {
                            tracker.set('duration', duration.as('hours'));
                        }
                    }
                }
            }
        });
    }

});

module.exports.simple = function (projects, hours) {
    var tracker = new Tracker({
        el: '#simple',
        template: '#template',
        noIntro: true,
        data: {
            projects: projects,
            hours: hours,
            has_project: function (wants) {
                var u = URI(window.location.href);
                if (u.search(true).project) {
                    return wants;
                }
                else {
                    return !wants;
                }
            }
        }
    });

    tracker.on('toggleNew', function (event) {
        event.original.preventDefault();
        tracker.toggle('expanded');
        if (tracker.get('expanded')) {
            if (!Modernizr.inputtypes.date) {
                $('#date').fdatepicker({language: 'nb', weekStart: 1, format: 'yyyy-mm-dd'});
            }
            if (!Modernizr.touch || !Modernizr.inputtypes.time) {
                tracker.create_timepickers($('#start.timepicker'), $('#end.timepicker'));
            }
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('createHours', function (event) {
        event.original.preventDefault();
        event.context.project = $('#project').val();
        event.context.date = $(event.node).find("#date").val();
        event.context.start = $(event.node).find("#start").val();
        event.context.end = $(event.node).find("#end").val();

        tracker.createHours(event.context)
            .then(function(data){
                // everything ok
                tracker.get('hours').unshift(data);

                // should not reset everything: date and project should stay
                //$('form#createHours').trigger('reset');
                $(event.node).find("#start").val('');
                $(event.node).find("#end").val('');
                $(event.node).find("#duration").val('');
                $(event.node).find("#comment").val('');
                $(event.node).find("#date").focus();
                alerts.get('success').push(data.project.name + ' ' + moment(data.date).format('LL') + ' ' + moment(data.created).fromNow());
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateDuration', function (event) {
        var form = $(event.node).parents('form');
        var start = $(form).find(".start").val() ;
        var end = $(form).find(".end").val();
        var startarr, endarr;

        if (start) {
            startarr = _.map(start.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (end) {
            endarr = _.map(end.split(":"), function (item) {
                return parseInt(item, 10);
            });
        }

        if (start && end) {
            var duration = moment.duration({
                hours: endarr[0] - startarr[0],
                minutes: endarr[1] - startarr[1]
            });
            if (duration) {
                tracker.set(event.keypath + '.duration', duration.as('hours'));
            }
        }
    });

    return tracker;
};

module.exports.projects = function (projects) {
    var tracker = new Tracker({
        el: '#projects',
        template: '#template',
        data: {
            projects: projects
        }
    });

    tracker.on('createProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };

        tracker.createProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.get('projects').unshift(data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    tracker.on('deleteProject', function (event) {
        tracker.deleteProject(event.context._id)
            .then(function (data) {
                tracker.get('projects').splice(event.keypath.split('.').pop());
            }, function (xhr, status, err) {
                tracker.get('error').push(xhr.responseText);
            });
    });

    return tracker;
};

module.exports.project = function (project, hours) {
    var all, own;
    var u = URI(window.location.href);
    if (u.hash() === "#all") {
        all = true;
    }
    else {
        own = true;
    }
    var own_hours = _.filter(hours, function (h) {
        return (h.user._id.match(/^gartmann/));
    });
    var tracker = new Tracker({
        el: '#project',
        template: '#template',
        data: {
            project: project,
            hours: hours,
            own_hours: own_hours,
            own: own,
            all: all
        }
    });

    tracker.on('toggleEdit', function (event) {
        event.original.preventDefault();
        tracker.toggle(event.keypath + '.expanded');
        if (tracker.get(event.keypath + '.expanded')) {
            //tracker.create_timepickers($(event.node).find('.start'), $(event.node).find('.end'));
        }
    });

    tracker.on('editToggle', function () {
        tracker.toggle('expanded');
    });

    tracker.on('toggleAll', function (event) {
        tracker.toggle('own');
        tracker.toggle('all');
        sum();
    });

    tracker.on('updateHours', function (event) {
        event.original.preventDefault();
        event.context.start = $(event.node).find(".start").val();
        event.context.end = $(event.node).find(".end").val();

        tracker.updateHours(event.context)
            .then(function(data) {
                tracker.set(event.keypath, data);
            }, function(xhr, status, err) {
                tracker.get('error').push(err);
            });
    });

    tracker.on('updateProject', function (event) {
        event.original.preventDefault();

        var node = $(event.node),
            project = {
                name: node.find('#name').val(),
                client: node.find('#client').val()
            };
        tracker.updateProject(project)
            .then(function(data){
                // everything ok
                tracker.toggle('expanded');
                tracker.set('project', data);
            }, function(xhr, status, err){
                tracker.get('error').push(err);
            });
        //$('body').animate({scrollTop: 0}, 'fast');
    });

    sum();

    return tracker;
};

<|endoftext|>


<commit_before>// Karma configuration
// Generated on Sun May 29 2016 16:41:41 GMT-0700 (PDT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'karma_bundles/count_tracker/bundle.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  });
};
<commit_msg>adding karma.conf.js change<commit_after>// Karma configuration
// Generated on Sun May 29 2016 16:41:41 GMT-0700 (PDT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'karma_bundles/bundle.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  });
};
<|endoftext|>


<commit_before>// Filtered view manager
// We define local filter objects for each different type of field (SetFilter,
// RangeFilter, dateFilter, etc.). We then define a global `Filter` object whose
// goal is to filter complete documents by using the local filters for each
// fields.

function showFilterSidebar() {
  Sidebar.setView('filter');
}

// Use a "set" filter for a field that is a set of documents uniquely
// identified. For instance `{ labels: ['labelA', 'labelC', 'labelD'] }`.
// use "subField" for searching inside object Fields.
// For instance '{ 'customFields._id': ['field1','field2']} (subField would be: _id)
class SetFilter {
  constructor(subField = '') {
    this._dep = new Tracker.Dependency();
    this._selectedElements = [];
    this.subField = subField;
  }

  isSelected(val) {
    this._dep.depend();
    return this._selectedElements.indexOf(val) > -1;
  }

  add(val) {
    if (this._indexOfVal(val) === -1) {
      this._selectedElements.push(val);
      this._dep.changed();
      showFilterSidebar();
    }
  }

  remove(val) {
    const indexOfVal = this._indexOfVal(val);
    if (this._indexOfVal(val) !== -1) {
      this._selectedElements.splice(indexOfVal, 1);
      this._dep.changed();
    }
  }

  toggle(val) {
    if (this._indexOfVal(val) === -1) {
      this.add(val);
    } else {
      this.remove(val);
    }
  }

  reset() {
    this._selectedElements = [];
    this._dep.changed();
  }

  _indexOfVal(val) {
    return this._selectedElements.indexOf(val);
  }

  _isActive() {
    this._dep.depend();
    return this._selectedElements.length !== 0;
  }

  _getMongoSelector() {
    this._dep.depend();
    return { $in: this._selectedElements };
  }

  _getEmptySelector() {
    this._dep.depend();
    let includeEmpty = false;
    this._selectedElements.forEach((el) => {
      if (el === undefined) {
        includeEmpty = true;
      }
    });
    return includeEmpty ? { $eq: [] } : null;
  }
}

// Advanced filter forms a MongoSelector from a users String.
// Build by: Ignatz 19.05.2018 (github feuerball11)
class AdvancedFilter {
  constructor() {
    this._dep = new Tracker.Dependency();
    this._filter = '';
    this._lastValide = {};
  }

  set(str) {
    this._filter = str;
    this._dep.changed();
  }

  reset() {
    this._filter = '';
    this._lastValide = {};
    this._dep.changed();
  }

  _isActive() {
    this._dep.depend();
    return this._filter !== '';
  }

  _filterToCommands() {
    const commands = [];
    let current = '';
    let string = false;
    let regex = false;
    let wasString = false;
    let ignore = false;
    for (let i = 0; i < this._filter.length; i++) {
      const char = this._filter.charAt(i);
      if (ignore) {
        ignore = false;
        current += char;
        continue;
      }
      if (char === '/'){
        string = !string;
        if (string) regex = true;
        current += char;
        continue;
      }
      if (char === '\'') {
        string = !string;
        if (string) wasString = true;
        continue;
      }
      if (char === '\\' && !string) {
        ignore = true;
        continue;
      }
      if (char === ' ' && !string) {
        commands.push({ 'cmd': current, 'string': wasString, regex});
        wasString = false;
        current = '';
        continue;
      }
      current += char;
    }
    if (current !== '') {
      commands.push({ 'cmd': current, 'string': wasString, regex});
    }
    return commands;
  }

  _fieldNameToId(field) {
    const found = CustomFields.findOne({ 'name': field });
    return found._id;
  }

  _fieldValueToId(field, value)
  {
    const found = CustomFields.findOne({ 'name': field });
    if (found.settings.dropdownItems && found.settings.dropdownItems.length > 0)
    {
      for (let i = 0; i < found.settings.dropdownItems.length; i++)
      {
        if (found.settings.dropdownItems[i].name === value)
        {
          return found.settings.dropdownItems[i]._id;
        }
      }
    }
    return value;
  }

  _arrayToSelector(commands) {
    try {
      //let changed = false;
      this._processSubCommands(commands);
    }
    catch (e) { return this._lastValide; }
    this._lastValide = { $or: commands };
    return { $or: commands };
  }

  _processSubCommands(commands) {
    const subcommands = [];
    let level = 0;
    let start = -1;
    for (let i = 0; i < commands.length; i++) {
      if (commands[i].cmd) {
        switch (commands[i].cmd) {
        case '(':
        {
          level++;
          if (start === -1) start = i;
          continue;
        }
        case ')':
        {
          level--;
          commands.splice(i, 1);
          i--;
          continue;
        }
        default:
        {
          if (level > 0) {
            subcommands.push(commands[i]);
            commands.splice(i, 1);
            i--;
            continue;
          }
        }
        }
      }
    }
    if (start !== -1) {
      this._processSubCommands(subcommands);
      if (subcommands.length === 1)
        commands.splice(start, 0, subcommands[0]);
      else
        commands.splice(start, 0, subcommands);
    }
    this._processConditions(commands);
    this._processLogicalOperators(commands);
  }

  _processConditions(commands) {
    for (let i = 0; i < commands.length; i++) {
      if (!commands[i].string && commands[i].cmd) {
        switch (commands[i].cmd) {
        case '=':
        case '==':
        case '===':
        {
          const field = commands[i - 1].cmd;
          const str = commands[i + 1].cmd;
          if (commands[i + 1].regex)
          {
            const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
            let regex = null;
            if (match.length > 2)
              regex = new RegExp(match[1], match[2]);
            else
              regex = new RegExp(match[1]);
            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': regex };
          }
          else
          {
            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} };
          }
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case '!=':
        case '!==':
        {
          const field = commands[i - 1].cmd;
          const str = commands[i + 1].cmd;
          if (commands[i + 1].regex)
          {
            const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
            let regex = null;
            if (match.length > 2)
              regex = new RegExp(match[1], match[2]);
            else
              regex = new RegExp(match[1]);
            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: regex } };
          }
          else
          {
            commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $not: {$in: [this._fieldValueToId(field, str), parseInt(str, 10)]} } };
          }
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case '>':
        case 'gt':
        case 'Gt':
        case 'GT':
        {
          const field = commands[i - 1].cmd;
          const str = commands[i + 1].cmd;
          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gt: parseInt(str, 10) } };
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case '>=':
        case '>==':
        case 'gte':
        case 'Gte':
        case 'GTE':
        {
          const field = commands[i - 1].cmd;
          const str = commands[i + 1].cmd;
          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $gte:  parseInt(str, 10) } };
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case '<':
        case 'lt':
        case 'Lt':
        case 'LT':
        {
          const field = commands[i - 1].cmd;
          const str = commands[i + 1].cmd;
          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lt:  parseInt(str, 10) } };
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case '<=':
        case '<==':
        case 'lte':
        case 'Lte':
        case 'LTE':
        {
          const field = commands[i - 1].cmd;
          const str = commands[i + 1].cmd;
          commands[i] = { 'customFields._id': this._fieldNameToId(field), 'customFields.value': { $lte:  parseInt(str, 10) } };
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        }
      }
    }
  }

  _processLogicalOperators(commands) {
    for (let i = 0; i < commands.length; i++) {
      if (!commands[i].string && commands[i].cmd) {
        switch (commands[i].cmd) {
        case 'or':
        case 'Or':
        case 'OR':
        case '|':
        case '||':
        {
          const op1 = commands[i - 1];
          const op2 = commands[i + 1];
          commands[i] = { $or: [op1, op2] };
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case 'and':
        case 'And':
        case 'AND':
        case '&':
        case '&&':
        {
          const op1 = commands[i - 1];
          const op2 = commands[i + 1];
          commands[i] = { $and: [op1, op2] };
          commands.splice(i - 1, 1);
          commands.splice(i, 1);
          //changed = true;
          i--;
          break;
        }
        case 'not':
        case 'Not':
        case 'NOT':
        case '!':
        {
          const op1 = commands[i + 1];
          commands[i] = { $not: op1 };
          commands.splice(i + 1, 1);
          //changed = true;
          i--;
          break;
        }
        }
      }
    }
  }

  _getMongoSelector() {
    this._dep.depend();
    const commands = this._filterToCommands();
    return this._arrayToSelector(commands);
  }

}

// The global Filter object.
// XXX It would be possible to re-write this object more elegantly, and removing
// the need to provide a list of `_fields`. We also should move methods into the
// object prototype.
Filter = {
  // XXX I would like to rename this field into `labels` to be consistent with
  // the rest of the schema, but we need to set some migrations architecture
  // before changing the schema.
  labelIds: new SetFilter(),
  members: new SetFilter(),
  customFields: new SetFilter('_id'),
  advanced: new AdvancedFilter(),

  _fields: ['labelIds', 'members', 'customFields'],

  // We don't filter cards that have been added after the last filter change. To
  // implement this we keep the id of these cards in this `_exceptions` fields
  // and use a `$or` condition in the mongo selector we return.
  _exceptions: [],
  _exceptionsDep: new Tracker.Dependency(),

  isActive() {
    return _.any(this._fields, (fieldName) => {
      return this[fieldName]._isActive();
    }) || this.advanced._isActive();
  },

  _getMongoSelector() {
    if (!this.isActive())
      return {};

    const filterSelector = {};
    const emptySelector = {};
    let includeEmptySelectors = false;
    this._fields.forEach((fieldName) => {
      const filter = this[fieldName];
      if (filter._isActive()) {
        if (filter.subField !== '') {
          filterSelector[`${fieldName}.${filter.subField}`] = filter._getMongoSelector();
        }
        else {
          filterSelector[fieldName] = filter._getMongoSelector();
        }
        emptySelector[fieldName] = filter._getEmptySelector();
        if (emptySelector[fieldName] !== null) {
          includeEmptySelectors = true;
        }
      }
    });

    const exceptionsSelector = { _id: { $in: this._exceptions } };
    this._exceptionsDep.depend();

    const selectors = [exceptionsSelector];

    if (_.any(this._fields, (fieldName) => {
      return this[fieldName]._isActive();
    })) selectors.push(filterSelector);
    if (includeEmptySelectors) selectors.push(emptySelector);
    if (this.advanced._isActive()) selectors.push(this.advanced._getMongoSelector());

    return { $or: selectors };
  },

  mongoSelector(additionalSelector) {
    const filterSelector = this._getMongoSelector();
    if (_.isUndefined(additionalSelector))
      return filterSelector;
    else
      return { $and: [filterSelector, additionalSelector] };
  },

  reset() {
    this._fields.forEach((fieldName) => {
      const filter = this[fieldName];
      filter.reset();
    });
    this.advanced.reset();
    this.resetExceptions();
  },

  addException(_id) {
    if (this.isActive()) {
      this._exceptions.push(_id);
      this._exceptionsDep.changed();
      Tracker.flush();
    }
  },

  resetExceptions() {
    this._exceptions = [];
    this._exceptionsDep.changed();
  },
};

Blaze.registerHelper('Filter', Filter);
<commit_msg>Revert eslint changes, because they caused breakage.<commit_after>// Filtered view manager
// We define local filter objects for each different type of field (SetFilter,
// RangeFilter, dateFilter, etc.). We then define a global `Filter` object whose
// goal is to filter complete documents by using the local filters for each
// fields.
function showFilterSidebar() {
    Sidebar.setView('filter');
}

// Use a "set" filter for a field that is a set of documents uniquely
// identified. For instance `{ labels: ['labelA', 'labelC', 'labelD'] }`.
// use "subField" for searching inside object Fields.
// For instance '{ 'customFields._id': ['field1','field2']} (subField would be: _id)
class SetFilter {
    constructor(subField = '') {
        this._dep = new Tracker.Dependency();
        this._selectedElements = [];
        this.subField = subField;
    }

    isSelected(val) {
        this._dep.depend();
        return this._selectedElements.indexOf(val) > -1;
    }

    add(val) {
        if (this._indexOfVal(val) === -1) {
            this._selectedElements.push(val);
            this._dep.changed();
            showFilterSidebar();
        }
    }

    remove(val) {
        const indexOfVal = this._indexOfVal(val);
        if (this._indexOfVal(val) !== -1) {
            this._selectedElements.splice(indexOfVal, 1);
            this._dep.changed();
        }
    }

    toggle(val) {
        if (this._indexOfVal(val) === -1) {
            this.add(val);
        } else {
            this.remove(val);
        }
    }

    reset() {
        this._selectedElements = [];
        this._dep.changed();
    }

    _indexOfVal(val) {
        return this._selectedElements.indexOf(val);
    }

    _isActive() {
        this._dep.depend();
        return this._selectedElements.length !== 0;
    }

    _getMongoSelector() {
        this._dep.depend();
        return {
            $in: this._selectedElements
        };
    }

    _getEmptySelector() {
        this._dep.depend();
        let includeEmpty = false;
        this._selectedElements.forEach((el) => {
            if (el === undefined) {
                includeEmpty = true;
            }
        });
        return includeEmpty ? {
            $eq: []
        } : null;
    }
}

// Advanced filter forms a MongoSelector from a users String.
// Build by: Ignatz 19.05.2018 (github feuerball11)
class AdvancedFilter {
    constructor() {
        this._dep = new Tracker.Dependency();
        this._filter = '';
        this._lastValide = {};
    }

    set(str) {
        this._filter = str;
        this._dep.changed();
    }

    reset() {
        this._filter = '';
        this._lastValide = {};
        this._dep.changed();
    }

    _isActive() {
        this._dep.depend();
        return this._filter !== '';
    }

    _filterToCommands() {
        const commands = [];
        let current = '';
        let string = false;
        let regex = false;
        let wasString = false;
        let ignore = false;
        for (let i = 0; i < this._filter.length; i++) {
            const char = this._filter.charAt(i);
            if (ignore) {
                ignore = false;
                current += char;
                continue;
            }
            if (char === '/') {
                string = !string;
                if (string) regex = true;
                current += char;
                continue;
            }
            if (char === '\'') {
                string = !string;
                if (string) wasString = true;
                continue;
            }
            if (char === '\\' && !string) {
                ignore = true;
                continue;
            }
            if (char === ' ' && !string) {
                commands.push({
                    'cmd': current,
                    'string': wasString,
                    regex
                });
                wasString = false;
                current = '';
                continue;
            }
            current += char;
        }
        if (current !== '') {
            commands.push({
                'cmd': current,
                'string': wasString,
                regex
            });
        }
        return commands;
    }

    _fieldNameToId(field) {
        const found = CustomFields.findOne({
            'name': field
        });
        return found._id;
    }

    _fieldValueToId(field, value) {
        const found = CustomFields.findOne({
            'name': field
        });
        if (found.settings.dropdownItems && found.settings.dropdownItems.length > 0) {
            for (let i = 0; i < found.settings.dropdownItems.length; i++) {
                if (found.settings.dropdownItems[i].name === value) {
                    return found.settings.dropdownItems[i]._id;
                }
            }
        }
        return value;
    }

    _arrayToSelector(commands) {
        try {
            //let changed = false;
            this._processSubCommands(commands);
        } catch (e) {
            return this._lastValide;
        }
        this._lastValide = {
            $or: commands
        };
        return {
            $or: commands
        };
    }

    _processSubCommands(commands) {
        const subcommands = [];
        let level = 0;
        let start = -1;
        for (let i = 0; i < commands.length; i++) {
            if (commands[i].cmd) {
                switch (commands[i].cmd) {
                case '(':
                    {
                        level++;
                        if (start === -1) start = i;
                        continue;
                    }
                case ')':
                    {
                        level--;
                        commands.splice(i, 1);
                        i--;
                        continue;
                    }
                default:
                    {
                        if (level > 0) {
                            subcommands.push(commands[i]);
                            commands.splice(i, 1);
                            i--;
                            continue;
                        }
                    }
                }
            }
        }
        if (start !== -1) {
            this._processSubCommands(subcommands);
            if (subcommands.length === 1)
                commands.splice(start, 0, subcommands[0]);
            else
                commands.splice(start, 0, subcommands);
        }
        this._processConditions(commands);
        this._processLogicalOperators(commands);
    }

    _processConditions(commands) {
        for (let i = 0; i < commands.length; i++) {
            if (!commands[i].string && commands[i].cmd) {
                switch (commands[i].cmd) {
                case '=':
                case '==':
                case '===':
                    {
                        const field = commands[i - 1].cmd;
                        const str = commands[i + 1].cmd;
                        if (commands[i + 1].regex) {
                            const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
                            let regex = null;
                            if (match.length > 2)
                                regex = new RegExp(match[1], match[2]);
                            else
                                regex = new RegExp(match[1]);
                            commands[i] = {
                                'customFields._id': this._fieldNameToId(field),
                                'customFields.value': regex
                            };
                        } else {
                            commands[i] = {
                                'customFields._id': this._fieldNameToId(field),
                                'customFields.value': {
                                    $in: [this._fieldValueToId(field, str), parseInt(str, 10)]
                                }
                            };
                        }
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case '!=':
                case '!==':
                    {
                        const field = commands[i - 1].cmd;
                        const str = commands[i + 1].cmd;
                        if (commands[i + 1].regex) {
                            const match = str.match(new RegExp('^/(.*?)/([gimy]*)$'));
                            let regex = null;
                            if (match.length > 2)
                                regex = new RegExp(match[1], match[2]);
                            else
                                regex = new RegExp(match[1]);
                            commands[i] = {
                                'customFields._id': this._fieldNameToId(field),
                                'customFields.value': {
                                    $not: regex
                                }
                            };
                        } else {
                            commands[i] = {
                                'customFields._id': this._fieldNameToId(field),
                                'customFields.value': {
                                    $not: {
                                        $in: [this._fieldValueToId(field, str), parseInt(str, 10)]
                                    }
                                }
                            };
                        }
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case '>':
                case 'gt':
                case 'Gt':
                case 'GT':
                    {
                        const field = commands[i - 1].cmd;
                        const str = commands[i + 1].cmd;
                        commands[i] = {
                            'customFields._id': this._fieldNameToId(field),
                            'customFields.value': {
                                $gt: parseInt(str, 10)
                            }
                        };
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case '>=':
                case '>==':
                case 'gte':
                case 'Gte':
                case 'GTE':
                    {
                        const field = commands[i - 1].cmd;
                        const str = commands[i + 1].cmd;
                        commands[i] = {
                            'customFields._id': this._fieldNameToId(field),
                            'customFields.value': {
                                $gte: parseInt(str, 10)
                            }
                        };
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case '<':
                case 'lt':
                case 'Lt':
                case 'LT':
                    {
                        const field = commands[i - 1].cmd;
                        const str = commands[i + 1].cmd;
                        commands[i] = {
                            'customFields._id': this._fieldNameToId(field),
                            'customFields.value': {
                                $lt: parseInt(str, 10)
                            }
                        };
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case '<=':
                case '<==':
                case 'lte':
                case 'Lte':
                case 'LTE':
                    {
                        const field = commands[i - 1].cmd;
                        const str = commands[i + 1].cmd;
                        commands[i] = {
                            'customFields._id': this._fieldNameToId(field),
                            'customFields.value': {
                                $lte: parseInt(str, 10)
                            }
                        };
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                }
            }
        }
    }

    _processLogicalOperators(commands) {
        for (let i = 0; i < commands.length; i++) {
            if (!commands[i].string && commands[i].cmd) {
                switch (commands[i].cmd) {
                case 'or':
                case 'Or':
                case 'OR':
                case '|':
                case '||':
                    {
                        const op1 = commands[i - 1];
                        const op2 = commands[i + 1];
                        commands[i] = {
                            $or: [op1, op2]
                        };
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case 'and':
                case 'And':
                case 'AND':
                case '&':
                case '&&':
                    {
                        const op1 = commands[i - 1];
                        const op2 = commands[i + 1];
                        commands[i] = {
                            $and: [op1, op2]
                        };
                        commands.splice(i - 1, 1);
                        commands.splice(i, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                case 'not':
                case 'Not':
                case 'NOT':
                case '!':
                    {
                        const op1 = commands[i + 1];
                        commands[i] = {
                            $not: op1
                        };
                        commands.splice(i + 1, 1);
                        //changed = true;
                        i--;
                        break;
                    }
                }
            }
        }
    }

    _getMongoSelector() {
        this._dep.depend();
        const commands = this._filterToCommands();
        return this._arrayToSelector(commands);
    }

}

// The global Filter object.
// XXX It would be possible to re-write this object more elegantly, and removing
// the need to provide a list of `_fields`. We also should move methods into the
// object prototype.
Filter = {
    // XXX I would like to rename this field into `labels` to be consistent with
    // the rest of the schema, but we need to set some migrations architecture
    // before changing the schema.
    labelIds: new SetFilter(),
    members: new SetFilter(),
    customFields: new SetFilter('_id'),
    advanced: new AdvancedFilter(),

    _fields: ['labelIds', 'members', 'customFields'],

    // We don't filter cards that have been added after the last filter change. To
    // implement this we keep the id of these cards in this `_exceptions` fields
    // and use a `$or` condition in the mongo selector we return.
    _exceptions: [],
    _exceptionsDep: new Tracker.Dependency(),

    isActive() {
        return _.any(this._fields, (fieldName) => {
            return this[fieldName]._isActive();
        }) || this.advanced._isActive();
    },

    _getMongoSelector() {
        if (!this.isActive())
            return {};

        const filterSelector = {};
        const emptySelector = {};
        let includeEmptySelectors = false;
        this._fields.forEach((fieldName) => {
            const filter = this[fieldName];
            if (filter._isActive()) {
                if (filter.subField !== '') {
                    filterSelector[`${fieldName}.${filter.subField}`] = filter._getMongoSelector();
                } else {
                    filterSelector[fieldName] = filter._getMongoSelector();
                }
                emptySelector[fieldName] = filter._getEmptySelector();
                if (emptySelector[fieldName] !== null) {
                    includeEmptySelectors = true;
                }
            }
        });

        const exceptionsSelector = {
            _id: {
                $in: this._exceptions
            }
        };
        this._exceptionsDep.depend();

        const selectors = [exceptionsSelector];

        if (_.any(this._fields, (fieldName) => {
                return this[fieldName]._isActive();
            })) selectors.push(filterSelector);
        if (includeEmptySelectors) selectors.push(emptySelector);
        if (this.advanced._isActive()) selectors.push(this.advanced._getMongoSelector());

        return {
            $or: selectors
        };
    },

    mongoSelector(additionalSelector) {
        const filterSelector = this._getMongoSelector();
        if (_.isUndefined(additionalSelector))
            return filterSelector;
        else
            return {
                $and: [filterSelector, additionalSelector]
            };
    },

    reset() {
        this._fields.forEach((fieldName) => {
            const filter = this[fieldName];
            filter.reset();
        });
        this.advanced.reset();
        this.resetExceptions();
    },

    addException(_id) {
        if (this.isActive()) {
            this._exceptions.push(_id);
            this._exceptionsDep.changed();
            Tracker.flush();
        }
    },

    resetExceptions() {
        this._exceptions = [];
        this._exceptionsDep.changed();
    },
};

Blaze.registerHelper('Filter', Filter);<|endoftext|>


<commit_before>'use strict';
// the only functional programming in the whole project
class Matrix {
	constructor(a, b, c, d, e, f) {
		this.a = a;
		this.b = b;
		this.c = c;
		this.d = d;
		this.e = e;
		this.f = f;
		Object.freeze(this);
	}

	multiply(m2) {
		let a1 = this.a, b1 = this.b, c1 = this.c, d1 = this.d, e1 = this.e, f1 = this.f;
		if(m2 instanceof Array) {
			return [
				(m2[0] * a1) + (m2[1] * c1) + e1,
				(m2[0] * b1) + (m2[1] * d1) + f1
			];
		}
		let a2 = m2.a, b2 = m2.b, c2 = m2.c, d2 = m2.d, e2 = m2.e, f2 = m2.f;
		// https://www.wolframalpha.com/input/?i=%7B%7Ba,c,e%7D,%7Bb,d,f%7D,%7B0,0,1%7D%7D+*+%7B%7BA,C,E%7D,%7BB,D,F%7D,%7B0,0,1%7D%7D
		return new Matrix(
			(a1*a2) + (b2*c1),
			(a2*b1) + (b2*d1),
			(a1*c2) + (c1*d2),
			(b1*c2) + (d1*d2),
			e1 + (a1*e2) + (c1*f2),
			(b1*e2) + f1 + (d1*f2)
		);
	}

	inverse() {
		let a = this.a, b = this.b, c = this.c, d = this.d, e = this.e, f = this.f;
		// https://www.wolframalpha.com/input/?i=inverse+of+%7B%7Ba,c,e%7D,%7Bb,d,f%7D,%7B0,0,1%7D%7D
		return new Matrix(
			d / ((a * d) - (b * c)),
			b / ((b * c) - (a * d)),
			c / ((b * c) - (a * d)),
			a / ((a * d) - (b * c)),
			((d * e) - (c * f)) / ((b * c) - (a * d)),
			((b * e) - (a * f)) / ((a * d) - (b * c)),
		);
	}

	translate(dx = 0, dy) {
		return this.multiply(new Matrix(1, 0, 0, 1, dx, dy));
	}

	rotate(angle, ox = 0, oy = 0) {
		let c = Math.cos(angle);
		let s = Math.sin(angle);
		return this.translate(-ox, -oy).multiply(new Matrix(c, s, -s, c, 0, 0)).translate(ox, oy);
	}

	scale(sx, sy, ox = 0, oy = 0) {
		if(sy == undefined)
			sy = sx;
		return this.translate(-ox, -oy).multiply(new Matrix(sx, 0, 0, sy, 0, 0)).translate(ox, oy);
	}
}

Matrix.identity = new Matrix(1, 0, 0, 1, 0, 0);

module.exports = Matrix;
<commit_msg>fix trailing comma<commit_after>'use strict';
// the only functional programming in the whole project
class Matrix {
	constructor(a, b, c, d, e, f) {
		this.a = a;
		this.b = b;
		this.c = c;
		this.d = d;
		this.e = e;
		this.f = f;
		Object.freeze(this);
	}

	multiply(m2) {
		let a1 = this.a, b1 = this.b, c1 = this.c, d1 = this.d, e1 = this.e, f1 = this.f;
		if(m2 instanceof Array) {
			return [
				(m2[0] * a1) + (m2[1] * c1) + e1,
				(m2[0] * b1) + (m2[1] * d1) + f1
			];
		}
		let a2 = m2.a, b2 = m2.b, c2 = m2.c, d2 = m2.d, e2 = m2.e, f2 = m2.f;
		// https://www.wolframalpha.com/input/?i=%7B%7Ba,c,e%7D,%7Bb,d,f%7D,%7B0,0,1%7D%7D+*+%7B%7BA,C,E%7D,%7BB,D,F%7D,%7B0,0,1%7D%7D
		return new Matrix(
			(a1*a2) + (b2*c1),
			(a2*b1) + (b2*d1),
			(a1*c2) + (c1*d2),
			(b1*c2) + (d1*d2),
			e1 + (a1*e2) + (c1*f2),
			(b1*e2) + f1 + (d1*f2)
		);
	}

	inverse() {
		let a = this.a, b = this.b, c = this.c, d = this.d, e = this.e, f = this.f;
		// https://www.wolframalpha.com/input/?i=inverse+of+%7B%7Ba,c,e%7D,%7Bb,d,f%7D,%7B0,0,1%7D%7D
		return new Matrix(
			d / ((a * d) - (b * c)),
			b / ((b * c) - (a * d)),
			c / ((b * c) - (a * d)),
			a / ((a * d) - (b * c)),
			((d * e) - (c * f)) / ((b * c) - (a * d)),
			((b * e) - (a * f)) / ((a * d) - (b * c))
		);
	}

	translate(dx = 0, dy) {
		return this.multiply(new Matrix(1, 0, 0, 1, dx, dy));
	}

	rotate(angle, ox = 0, oy = 0) {
		let c = Math.cos(angle);
		let s = Math.sin(angle);
		return this.translate(-ox, -oy).multiply(new Matrix(c, s, -s, c, 0, 0)).translate(ox, oy);
	}

	scale(sx, sy, ox = 0, oy = 0) {
		if(sy == undefined)
			sy = sx;
		return this.translate(-ox, -oy).multiply(new Matrix(sx, 0, 0, sy, 0, 0)).translate(ox, oy);
	}
}

Matrix.identity = new Matrix(1, 0, 0, 1, 0, 0);

module.exports = Matrix;
<|endoftext|>


<commit_before>Zoomer = {
  config: {
    maxZoom: 3
  , zoomSpeed: 10
  }
, position: {
    x: 1
  , y: 1
  }
, mousePosition: {
    x: 1
  , y: 1
  }
, currentWidth: 0
, currentHeight: 0
, disabled: false
, zoomLevel: 1
, followMouse: false
, overflower: document.createElement('div')
, zoomWrapper: document.createElement('div')
, overflowPreventer: document.createElement('div')
, init: function (elementSelector) {
    var self = this
    self.element = document.querySelector(elementSelector)
    if(!self.element) return false
    self.setRequiredStyles()
    self.currentHeight = self.element.clientHeight
    self.currentWidth = self.element.clientWidth
    self.setListeners()
  }
, setListeners: function () {
    var self = this
    self.currentScrollTop = self.zoomWrapper.scrollTop
    self.zoomWrapper.addEventListener('scroll', function (e) {
      if(self.disabled) return true
      self.disabled = false
      self.zoom(self.calcDiff(self.zoomWrapper.scrollTop))
    })
    self.zoomWrapper.addEventListener('mousemove', _.throttle(function (e) {
      self.followToMouse(e.clientX, e.clientY)
      self.mousePosition.x = e.clientX
      self.mousePosition.y = e.clientY
    }, 20))
    self.zoomWrapper.addEventListener('mousedown', function () {
      self.followMouse = true
    })
    self.zoomWrapper.addEventListener('mouseout', function () {
      self.followMouse = false
    })
    self.zoomWrapper.addEventListener('mouseup', function () {
      self.followMouse = false
    })
  }
, zoom: function (diff) {
    var self = this
    setTimeout(function () {
      var newHeight = Math.round(self.element.clientHeight * diff)
      , newWidth = Math.round(self.element.clientWidth * diff)
      , goToX
      , goToY

      self.zoomLevel = self.zoomLevel * diff

      goToX = self.mousePosition.x - (self.mousePosition.x - self.position.x) * diff
      goToY = self.mousePosition.y - (self.mousePosition.y - self.position.y) * diff

      self.goTo(goToX, goToY)

      self.currentHeight = newHeight
      self.element.style.height = newHeight + 'px'
      self.currentWidth = newWidth
      self.element.style.width = newWidth + 'px'
    }, 30)
  } // Takes a factor (ex. 2)
, calcDiff: function (newScrollTop) {
    var self = this
  , scrollDiff = self.currentScrollTop - newScrollTop
    self.currentScrollTop = newScrollTop
    return scrollDiff / self.scrollHeight + 1
  }
, setRequiredStyles: function () {
    var self = this
    self.scrollHeight = self.config.maxZoom * 10 * self.element.clientHeight / self.config.maxZoom

    self.overflower.className = 'zoomer__overflower'
    self.zoomWrapper.className = 'zoomer__wrapper'
    self.overflowPreventer.className = 'zoomer__preventer'

    self.overflower.style.height = self.scrollHeight + 'px'

    self.element.parentNode.appendChild(self.zoomWrapper)
    self.element.parentNode.appendChild(self.overflowPreventer)
    self.overflowPreventer.appendChild(self.element)
    self.zoomWrapper.appendChild(self.overflower)

    self.zoomWrapper.scrollTop = self.scrollHeight
  }
, goTo: function (posX, posY) {
    var self = this
    self.position.x = posX
    self.position.y = posY
    self.element.style.transform = 'matrix(1,0,0,1,' + posX + ',' + posY + ')'
  }
, followToMouse: function (newX, newY) {
    var self = this
    , newPosX
    , newPosY

    if(!self.followMouse) return false

    newPosX = self.position.x + newX - self.mousePosition.x
    newPosY = self.position.y + newY - self.mousePosition.y
    self.goTo(newPosX, newPosY)
  }
}<commit_msg>Use _.throttle for the zoomer zoom function<commit_after>Zoomer = {
  config: {
    maxZoom: 3
  , zoomSpeed: 10
  }
, position: {
    x: 1
  , y: 1
  }
, mousePosition: {
    x: 1
  , y: 1
  }
, currentWidth: 0
, currentHeight: 0
, zoomLevel: 1
, followMouse: false
, overflower: document.createElement('div')
, zoomWrapper: document.createElement('div')
, overflowPreventer: document.createElement('div')
, init: function (elementSelector) {
    var self = this
    self.element = document.querySelector(elementSelector)
    if(!self.element) return false
    self.setRequiredStyles()
    self.currentHeight = self.element.clientHeight
    self.currentWidth = self.element.clientWidth
    self.setListeners()
  }
, setListeners: function () {
    var self = this
    self.currentScrollTop = self.zoomWrapper.scrollTop
    self.zoomWrapper.addEventListener('scroll', _.throttle(function () {
      self.zoom(self.calcDiff(self.zoomWrapper.scrollTop))
    }))
    self.zoomWrapper.addEventListener('mousemove', _.throttle(function (e) {
      self.followToMouse(e.clientX, e.clientY)
      self.mousePosition.x = e.clientX
      self.mousePosition.y = e.clientY
    }, 20))
    self.zoomWrapper.addEventListener('mousedown', function () {
      self.followMouse = true
    })
    self.zoomWrapper.addEventListener('mouseout', function () {
      self.followMouse = false
    })
    self.zoomWrapper.addEventListener('mouseup', function () {
      self.followMouse = false
    })
  }
, zoom: function (diff) {
    var self = this
    var newHeight = Math.round(self.element.clientHeight * diff)
    , newWidth = Math.round(self.element.clientWidth * diff)
    , goToX
    , goToY

    self.zoomLevel = self.zoomLevel * diff

    goToX = self.mousePosition.x - (self.mousePosition.x - self.position.x) * diff
    goToY = self.mousePosition.y - (self.mousePosition.y - self.position.y) * diff

    self.goTo(goToX, goToY)

    self.currentHeight = newHeight
    self.element.style.height = newHeight + 'px'
    self.currentWidth = newWidth
    self.element.style.width = newWidth + 'px'
  } // Takes a factor (ex. 2)
, calcDiff: function (newScrollTop) {
    var self = this
  , scrollDiff = self.currentScrollTop - newScrollTop
    self.currentScrollTop = newScrollTop
    return scrollDiff / self.scrollHeight + 1
  }
, setRequiredStyles: function () {
    var self = this
    self.scrollHeight = self.config.maxZoom * 10 * self.element.clientHeight / self.config.maxZoom

    self.overflower.className = 'zoomer__overflower'
    self.zoomWrapper.className = 'zoomer__wrapper'
    self.overflowPreventer.className = 'zoomer__preventer'

    self.overflower.style.height = self.scrollHeight + 'px'

    self.element.parentNode.appendChild(self.zoomWrapper)
    self.element.parentNode.appendChild(self.overflowPreventer)
    self.overflowPreventer.appendChild(self.element)
    self.zoomWrapper.appendChild(self.overflower)

    self.zoomWrapper.scrollTop = self.scrollHeight
  }
, goTo: function (posX, posY) {
    var self = this
    self.position.x = posX
    self.position.y = posY
    self.element.style.transform = 'matrix(1,0,0,1,' + posX + ',' + posY + ')'
  }
, followToMouse: function (newX, newY) {
    var self = this
    , newPosX
    , newPosY

    if(!self.followMouse) return false

    newPosX = self.position.x + newX - self.mousePosition.x
    newPosY = self.position.y + newY - self.mousePosition.y
    self.goTo(newPosX, newPosY)
  }
}<|endoftext|>


<commit_before>/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the Clear BSD
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 * full text of the license. */

/**
 * @requires OpenLayers/Control/ZoomBox.js
 * @requires OpenLayers/Control/DragPan.js
 * @requires OpenLayers/Handler/MouseWheel.js
 *
 * Class: OpenLayers.Control.Navigation
 * The navigation control handles map browsing with mouse events (dragging,
 *     double-clicking, and scrolling the wheel).  Create a new navigation
 *     control with the <OpenLayers.Control.Navigation> control.
 *
 *     Note that this control is added to the map by default (if no controls
 *     array is sent in the options object to the <OpenLayers.Map>
 *     constructor).
 *
 * Inherits:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {

    /**
     * Property: dragPan
     * {<OpenLayers.Control.DragPan>}
     */
    dragPan: null,

    /**
     * Property: zoomBox
     * {<OpenLayers.Control.ZoomBox>}
     */
    zoomBox: null,

    /**
     * Property: wheelHandler
     * {<OpenLayers.Handler.MouseWheel>}
     */
    wheelHandler: null,

    /**
     * Constructor: OpenLayers.Control.Navigation
     * Create a new navigation control
     *
     * Parameters:
     * options - {Object} An optional object whose properties will be set on
     *                    the control
     */
    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, arguments);
    },

    /**
     * Method: activate
     */
    activate: function() {
        this.dragPan.activate();
        this.wheelHandler.activate();
        this.zoomBox.activate();
        return OpenLayers.Control.prototype.activate.apply(this,arguments);
    },

    /**
     * Method: deactivate
     */
    deactivate: function() {
        this.zoomBox.deactivate();
        this.dragPan.deactivate();
        this.wheelHandler.deactivate();
        return OpenLayers.Control.prototype.deactivate.apply(this,arguments);
    },

    /**
     * Method: draw
     */
    draw: function() {
        this.map.events.register( "dblclick", this, this.defaultDblClick );
        this.dragPan = new OpenLayers.Control.DragPan({map: this.map});
        this.zoomBox = new OpenLayers.Control.ZoomBox(
                    {map: this.map, keyMask: OpenLayers.Handler.MOD_SHIFT});
        this.dragPan.draw();
        this.zoomBox.draw();
        this.wheelHandler = new OpenLayers.Handler.MouseWheel(
                                    this, {"up"  : this.wheelUp,
                                           "down": this.wheelDown} );
        this.activate();
    },

    /**
     * Method: defaultDblClick
     *
     * Parameters:
     * evt - {Event}
     */
    defaultDblClick: function (evt) {
        var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
        this.map.setCenter(newCenter, this.map.zoom + 1);
        OpenLayers.Event.stop(evt);
        return false;
    },

    /**
     * Method: wheelChange
     *
     * Parameters:
     * evt - {Event}
     */
    wheelChange: function(evt, deltaZ) {
        var newZoom = this.map.getZoom() + deltaZ;
        if (!this.map.isValidZoomLevel(newZoom)) {
            return;
        }
        var size    = this.map.getSize();
        var deltaX  = size.w/2 - evt.xy.x;
        var deltaY  = evt.xy.y - size.h/2;
        var newRes  = this.map.baseLayer.resolutions[newZoom];
        var zoomPoint = this.map.getLonLatFromPixel(evt.xy);
        var newCenter = new OpenLayers.LonLat(
                            zoomPoint.lon + deltaX * newRes,
                            zoomPoint.lat + deltaY * newRes );
        this.map.setCenter( newCenter, newZoom );
    },

    /**
     * Method: wheelUp
     * User spun scroll wheel up
     *
     * Parameters:
     * evt - {Event}
     */
    wheelUp: function(evt) {
        this.wheelChange(evt, 1);
    },

    /**
     * Method: wheelDown
     * User spun scroll wheel down
     *
     * Parameters:
     * evt - {Event}
     */
    wheelDown: function(evt) {
        this.wheelChange(evt, -1);
    },

    CLASS_NAME: "OpenLayers.Control.Navigation"
});
<commit_msg>Fix for "When Navigation control is inactive, doubleclick zooms in", using the new click handler that Tim and I created over the weekend. (Hooray for handlers!) r=tschaub (Closes #1068)<commit_after>/* Copyright (c) 2006-2007 MetaCarta, Inc., published under the Clear BSD
 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
 * full text of the license. */

/**
 * @requires OpenLayers/Control/ZoomBox.js
 * @requires OpenLayers/Control/DragPan.js
 * @requires OpenLayers/Handler/MouseWheel.js
 *
 * Class: OpenLayers.Control.Navigation
 * The navigation control handles map browsing with mouse events (dragging,
 *     double-clicking, and scrolling the wheel).  Create a new navigation
 *     control with the <OpenLayers.Control.Navigation> control.
 *
 *     Note that this control is added to the map by default (if no controls
 *     array is sent in the options object to the <OpenLayers.Map>
 *     constructor).
 *
 * Inherits:
 *  - <OpenLayers.Control>
 */
OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {

    /**
     * Property: dragPan
     * {<OpenLayers.Control.DragPan>}
     */
    dragPan: null,

    /**
     * Property: zoomBox
     * {<OpenLayers.Control.ZoomBox>}
     */
    zoomBox: null,

    /**
     * Property: wheelHandler
     * {<OpenLayers.Handler.MouseWheel>}
     */
    wheelHandler: null,

    /**
     * Constructor: OpenLayers.Control.Navigation
     * Create a new navigation control
     *
     * Parameters:
     * options - {Object} An optional object whose properties will be set on
     *                    the control
     */
    initialize: function(options) {
        OpenLayers.Control.prototype.initialize.apply(this, arguments);
    },

    /**
     * Method: activate
     */
    activate: function() {
        this.dragPan.activate();
        this.wheelHandler.activate();
        this.clickHandler.activate();
        this.zoomBox.activate();
        return OpenLayers.Control.prototype.activate.apply(this,arguments);
    },

    /**
     * Method: deactivate
     */
    deactivate: function() {
        this.zoomBox.deactivate();
        this.dragPan.deactivate();
        this.clickHandler.deactivate();
        this.wheelHandler.deactivate();
        return OpenLayers.Control.prototype.deactivate.apply(this,arguments);
    },

    /**
     * Method: draw
     */
    draw: function() {
        this.clickHandler = new OpenLayers.Handler.Click(this,
                                        { 'dblclick': this.defaultDblClick },
                                        {
                                          'double': true,
                                          'stopDouble': true
                                        });
        this.dragPan = new OpenLayers.Control.DragPan({map: this.map});
        this.zoomBox = new OpenLayers.Control.ZoomBox(
                    {map: this.map, keyMask: OpenLayers.Handler.MOD_SHIFT});
        this.dragPan.draw();
        this.zoomBox.draw();
        this.wheelHandler = new OpenLayers.Handler.MouseWheel(
                                    this, {"up"  : this.wheelUp,
                                           "down": this.wheelDown} );
        this.activate();
    },

    /**
     * Method: defaultDblClick
     *
     * Parameters:
     * evt - {Event}
     */
    defaultDblClick: function (evt) {
        var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
        this.map.setCenter(newCenter, this.map.zoom + 1);
    },

    /**
     * Method: wheelChange
     *
     * Parameters:
     * evt - {Event}
     */
    wheelChange: function(evt, deltaZ) {
        var newZoom = this.map.getZoom() + deltaZ;
        if (!this.map.isValidZoomLevel(newZoom)) {
            return;
        }
        var size    = this.map.getSize();
        var deltaX  = size.w/2 - evt.xy.x;
        var deltaY  = evt.xy.y - size.h/2;
        var newRes  = this.map.baseLayer.resolutions[newZoom];
        var zoomPoint = this.map.getLonLatFromPixel(evt.xy);
        var newCenter = new OpenLayers.LonLat(
                            zoomPoint.lon + deltaX * newRes,
                            zoomPoint.lat + deltaY * newRes );
        this.map.setCenter( newCenter, newZoom );
    },

    /**
     * Method: wheelUp
     * User spun scroll wheel up
     *
     * Parameters:
     * evt - {Event}
     */
    wheelUp: function(evt) {
        this.wheelChange(evt, 1);
    },

    /**
     * Method: wheelDown
     * User spun scroll wheel down
     *
     * Parameters:
     * evt - {Event}
     */
    wheelDown: function(evt) {
        this.wheelChange(evt, -1);
    },

    CLASS_NAME: "OpenLayers.Control.Navigation"
});
<|endoftext|>


<commit_before>//==============================================================================
function Point(x,y) {
    this.x  = x || 0;
    this.y = y || 0;
}
//==============================================================================

/**
 * storage class for animation data
 */
function Animation(framemap, framenumb, cols, rows, framewidth, frameheight, bordersize, initialFrame ) {
    this._currentframe = initialFrame || 0;
    this._frames = [];
    this._framemap = framemap;
    this._framewidth = framewidth;
    this._frameheight = frameheight;
    this._borderwidth = bordersize;

    /**
     * currently oscillates, can be changed to provide custom frame updating
     * on a per AnimatedSprite basis
     */
    this._frameupdate= function() {

	this._currentframe += 1;
	if( this._currentframe >= this._frames.length ) { this._currentframe = -(this._currentframe-1); }

    }

    this.initFrames = function(framenumb) {
	    var i = 0;
	    var done = false;
	    var top = new Point(0,0);

	    for (var row  = 0; row < rows && !done; row++) {
		for (var col = 0; col < cols && !done; col++) {
		    top = new Point( col * (frameheight+1)+(col+1)*bordersize, row * (framewidth+1) +(row+1)* bordersize);
		    console.log(top);
		    this._frames.push ( top );
		    i+=1;
		    if( i >= framenumb ) { done = true; }
		}
	    }
    }
    this.initFrames( framenumb );

    this.draw = function(texid, dx, dy, dWidth, dHeight) {
	//absolute value of current frame index is used, allowing for negative frame counts
       	var curframe = this._currentframe<0? -1 * this._currentframe : this._currentframe;
	var frametop = this._frames[curframe];
	//console.log( this._frames[curframe], this._framewidth, this._frameheight, dWidth, dHeight);
	Pender.canvas.drawImage(Pender.getImage(texid), frametop.x, frametop.y, this._framewidth, this._frameheight,
			     dx, dy, dWidth, dHeight);

	//Pender.ctx.drawImage( Pender.getImage(0), frametop.x, frametop.y, this._framewidth, this._frameheight, dx, dy, this._framewidth, this._frameheight   );
	this._frameupdate();
    }

}
//==============================================================================
/**
 *
 */
function AnimatedSprite(anim) {
    this.xpos = 0;
    this.ypos = 0;
    this.xvel = Math.random()*5;
    this.yvel = Math.random()*5;
    this.width = 128;
    this.height = 128;
    this._animation = anim;
    var self = this;

   this.draw = function(texid) {
	self.xpos = self.xpos+ self.xvel;
	self.ypos = self.ypos+ self.yvel;
	if( self.xpos < 0 || self.xpos >= 400-self.width/*Pender.canvas.width*/) {
	    self.xvel = self.xvel * -1;
	}
	if(self.ypos < 0 || self.ypos >= 400-self.height/*Pender.canvas.height */) {
	    self.yvel = self.yvel * -1;
	}

	this._animation.draw( texid, self.xpos, self.ypos, self.width, self.height );
    };
}
//==============================================================================
/**
 *
 */
var Bots = new function () {
    this.numb = 12;
    this.bots = [];
    this.texid = 0;
    var self = this;
    this.init = function() {
	console.log("initing");
        texid = Pender.loadImage("client/assets/build_bot_map_med.png");
	for (var i = 0; i < self.numb; i++) {
	    console.log("newbot");
	    var anim = new Animation (texid, 9, 4, 3, 126, 126, 1);
	    self.bots.push (new AnimatedSprite(anim));
	}
    };

    this.testdraw = function() {
	Pender.canvas.clearRect(0,0,Pender.width,Pender.height);
	Pender.canvas.fillStyle = "rgb(0,0,0)";
	Pender.canvas.fillRect (10, 10, Pender.width, Pender.height);
	self.bots[0].draw(self.texid);
    };

    this.draw =  function() {
	Pender.canvas.clearRect(0,0,Pender.width, Pender.height);
      	for(var i = 0; i < self.numb; i++) {
	    self.bots[i].draw(self.texid);
	}
    };

}

function init() {
    Bots.init();
}

<commit_msg>modified path to reflect expected new structure<commit_after>//==============================================================================
function Point(x,y) {
    this.x  = x || 0;
    this.y = y || 0;
}
//==============================================================================

/**
 * storage class for animation data
 */
function Animation(framemap, framenumb, cols, rows, framewidth, frameheight, bordersize, initialFrame ) {
    this._currentframe = initialFrame || 0;
    this._frames = [];
    this._framemap = framemap;
    this._framewidth = framewidth;
    this._frameheight = frameheight;
    this._borderwidth = bordersize;

    /**
     * currently oscillates, can be changed to provide custom frame updating
     * on a per AnimatedSprite basis
     */
    this._frameupdate= function() {

	this._currentframe += 1;
	if( this._currentframe >= this._frames.length ) { this._currentframe = -(this._currentframe-1); }

    }

    this.initFrames = function(framenumb) {
	    var i = 0;
	    var done = false;
	    var top = new Point(0,0);

	    for (var row  = 0; row < rows && !done; row++) {
		for (var col = 0; col < cols && !done; col++) {
		    top = new Point( col * (frameheight+1)+(col+1)*bordersize, row * (framewidth+1) +(row+1)* bordersize);
		    console.log(top);
		    this._frames.push ( top );
		    i+=1;
		    if( i >= framenumb ) { done = true; }
		}
	    }
    }
    this.initFrames( framenumb );

    this.draw = function(texid, dx, dy, dWidth, dHeight) {
	//absolute value of current frame index is used, allowing for negative frame counts
       	var curframe = this._currentframe<0? -1 * this._currentframe : this._currentframe;
	var frametop = this._frames[curframe];
	//console.log( this._frames[curframe], this._framewidth, this._frameheight, dWidth, dHeight);
	Pender.canvas.drawImage(Pender.getImage(texid), frametop.x, frametop.y, this._framewidth, this._frameheight,
			     dx, dy, dWidth, dHeight);

	//Pender.ctx.drawImage( Pender.getImage(0), frametop.x, frametop.y, this._framewidth, this._frameheight, dx, dy, this._framewidth, this._frameheight   );
	this._frameupdate();
    }

}
//==============================================================================
/**
 *
 */
function AnimatedSprite(anim) {
    this.xpos = 0;
    this.ypos = 0;
    this.xvel = Math.random()*5;
    this.yvel = Math.random()*5;
    this.width = 128;
    this.height = 128;
    this._animation = anim;
    var self = this;

   this.draw = function(texid) {
	self.xpos = self.xpos+ self.xvel;
	self.ypos = self.ypos+ self.yvel;
	if( self.xpos < 0 || self.xpos >= 400-self.width/*Pender.canvas.width*/) {
	    self.xvel = self.xvel * -1;
	}
	if(self.ypos < 0 || self.ypos >= 400-self.height/*Pender.canvas.height */) {
	    self.yvel = self.yvel * -1;
	}

	this._animation.draw( texid, self.xpos, self.ypos, self.width, self.height );
    };
}
//==============================================================================
/**
 *
 */
var Bots = new function () {
    this.numb = 12;
    this.bots = [];
    this.texid = 0;
    var self = this;
    this.init = function() {
	console.log("initing");
        texid = Pender.loadImage("demos/client/assets/build_bot_map_med.png");
	for (var i = 0; i < self.numb; i++) {
	    console.log("newbot");
	    var anim = new Animation (texid, 9, 4, 3, 126, 126, 1);
	    self.bots.push (new AnimatedSprite(anim));
	}
    };

    this.testdraw = function() {
	Pender.canvas.clearRect(0,0,Pender.width,Pender.height);
	Pender.canvas.fillStyle = "rgb(0,0,0)";
	Pender.canvas.fillRect (10, 10, Pender.width, Pender.height);
	self.bots[0].draw(self.texid);
    };

    this.draw =  function() {
	Pender.canvas.clearRect(0,0,Pender.width, Pender.height);
      	for(var i = 0; i < self.numb; i++) {
	    self.bots[i].draw(self.texid);
	}
    };

}

function init() {
    Bots.init();
}

<|endoftext|>