<commit_before>/**
 * Import script for the HTML5 Security Cheatsheet HTML version
 */
(function(){
    window.onload = function() {
        // sanitize
        var sanitize = function(input){
            output = input.replace(/&/gm, '&')
                .replace(/</gm, '<').replace(/>/gm, '>');
            return output;
        };
        // rudimentary off-line support
        (function(){
            var offline = function(){
                var store = JSON.parse(localStorage[location.hostname]);
                items = store.items;
                categories = store.categories;
                payloads = store.payloads;
                $('#offline').show();
            };
            if(navigator.onLine || typeof navigator.onLine === 'undefined') {
            	try {
	                localStorage[location.hostname]=JSON.stringify(
	                    {'items':items,'payloads':payloads,'categories':categories}
	                );
	                $(window).bind('offline', offline);
	                $(window).bind('online', function(){$('#offline').hide()})
	                $('#offline').hide();
	            } catch(e){}
            } else {
                offline();
            }
        })();
        // categories
        (function() {
            // enumerate categories and build initial lists
            for(var category in categories) {
                // determine cookie or navigator language or set default
                if (/lang=\w{2}/.test(document.cookie)) {
                    var lang = document.cookie.match(/lang=(\w{2})/)[1];
                }
                else {
					var userLang = navigator.language||navigator.browserLanguage;
                    var lang = userLang ? userLang.match(/(\w{2})/)[1] : 'en';
                }
                if(typeof categories[category][lang] === 'undefined'
                    || !categories[category][lang]) {
                    lang = 'en';
                }
                // check if translated items exist
                if (typeof categories[category][lang] === 'string') {
                    $('#content').append('

'
                        + categories[category][lang] + '

');
                    $('#sidebar').append('
'
                        + categories[category][lang] + '
');
                }
            }
            $('#content li').wrap('
');
            $('#sidebar li').wrap('
');
        })();
        // content
        (function() {
            for (var item in items) {
                // replace the payload templates
                for (var payload in payloads) {
                    var regex = new RegExp('%' + payload + '%', 'gm');
                    items[item].data = items[item].data.replace(regex, payloads[payload]);
                    if(items[item].attachment && items[item].attachment.raw) {
                        items[item].attachment.raw = items[item].attachment
                            .raw.replace(regex, payloads[payload]);
                    }
                }
                // build markup container for the content
                var li = $('#content li#'+items[item].category+' h3');
                var container = $($('#item_template').html());

                // enable direct vector navi by id
                container.prepend('');
                for(var c in items[item]) {
                    // determine cookie or navigator language or set default
                    if (/lang=\w{2}/.test(document.cookie)) {
                        var lang = document.cookie.match(/lang=(\w{2})/)[1];
                    }
                    else {
                        var userLang = navigator.language||navigator.browserLanguage;
                        var lang = userLang ? userLang.match(/(\w{2})/)[1] : 'en';
                    }
                    if(typeof items[item][c][lang] === 'undefined'
                        || !items[item][c][lang]) {
                        lang = 'en';
                    }
                    // check if translated items exist
                    if(typeof items[item][c][lang] === 'string') {
                        container.find('.'+c).html(sanitize(items[item][c][lang]));
                        if(c === 'name'){
                            container.find('.'+c).append('#'+items[item]['id']+'');
                            container.find('.'+c).append('test')
                        }
                    } else if(typeof items[item][c] === 'string') {
                        container.find('.'+c).html(sanitize(items[item][c]));
                    }
                }
                // check for attachment data
                if(items[item].attachment) {
                    container.find('.attachment').show()
                        .append(sanitize(items[item].attachment.raw));
                    for(var meta in items[item].attachment) {
                        if(meta !== 'raw' && meta !== 'path' && items[item].attachment[meta]) {
                            container.find('.attachment').append(
                                ''+meta+': '+sanitize(items[item]
                                    .attachment[meta])+''
                            );
                        } else if(meta === 'path' && items[item].attachment[meta]) {
                            container.find('.attachment').append(
                                ''+meta+': '
                                    + sanitize(items[item].attachment[meta])
                                + ''
                            );
                        }
                    }
                } else {
                    container.find('.attachment').remove();
                }
                // fill browser list
                if(items[item].browsers) {
                    for(var browser in items[item].browsers) {
                         container.find('.browsers').append('
');
                         var versions = items[item].browsers[browser];
                         for(var i in versions) {
                             if(versions[i] == 'end') continue;
                             var short_browser = browser.replace(/^(\w+)\s\w+/, '$1');
                             container.find('.browsers .'+short_browser).append(
                                 (versions[+i + 1] == 'end' ? '
' : '
')
                                 + browser + ' ' + versions[i] + '
'
                             )

                        }
                    }
                    container.find('.browsers').append('');
                }
                // fill tag list
                if(items[item].tags) {
                    for(var tag in items[item].tags) {
                        container.find('.tags')
                            .append('
'+items[item].tags[tag]+'
');
                    }
                    container.find('.tags')
                        .append('');
                }
                // fill url list
                if(items[item].urls) {
                    for(var url in items[item].urls) {
                        container.find('.urls').append(
                            '
'
                                      :'" target="_blank">')
                                + items[item].urls[url]+'
'
                        );
                    }
                }
                li.parent().append(container);
            }
            // enable direct jumps via hash url
            if(location.hash && location.hash.match(/^#\w+$/)) {
                location=location.hash;
            }
        })();
        // search functionality
        (function(){
            $('ul.tags li, ul.browsers li').click(function(){
                $('#search').attr('value', $(this).html()).keyup();
            });
            $('#search').keyup(function(){
                var term = $('#search').attr('value');
                term = sanitize(term.replace(/([\[\]\(\\)\{\}\+\-])/gm, '\\$1'));
                if(term) {
                    if(typeof to !== 'undefined') {
                        clearTimeout(to);
                    }
                    to = setTimeout(function(){
                        $('div.item').each(function(){
                            if($(this).html().match(new RegExp(term, 'gim'))) {
                                $(this).show();
                                $(document).scrollTop(
                                    $('div.item:visible').first().attr('scrollHeight')
                                );
                            } else {$(this).hide()}
                        });
                    }, 500);

                } else {$('div.item').show()}
            });
            $('#search').dblclick(function(){
                $(this).attr('value', '').keyup();
            });
            $('#sidebar a').click(function(){
                $('#search').attr('value', '').keyup();
            });
            // enable direct jumps via hash url
            if(location.search) {
                var search = unescape(location.search.replace(/^\?/, ''));
                $('#search').attr('value', search).keyup();
            }
        })();
        // language switch
        (function(){
            $('#languages a').click(function(){
                document.cookie='lang='+$(this).attr('rel');
            });
        })();
    };
    /**
     * Export all vectors for brute-force XSS Tests
     */
    window.vectors = function(){
    	for(i in items){
    		i = parseInt(i, 10);
    		var vector = items[i].data;
    		vector = vector.replace(/(?:alert|write)\(1\)/gim, 'alert('+(i+1)+')');
			console.log('
'+vector+'//["\'`-->]]>]
');
    	}
    }
})();
<commit_msg>Fixed search feature (jQuery API change)<commit_after>/**
 * Import script for the HTML5 Security Cheatsheet HTML version
 */
(function(){
    window.onload = function() {
        // sanitize
        var sanitize = function(input){
            output = input.replace(/&/gm, '&')
                .replace(/</gm, '<').replace(/>/gm, '>');
            return output;
        };
        // rudimentary off-line support
        (function(){
            var offline = function(){
                var store = JSON.parse(localStorage[location.hostname]);
                items = store.items;
                categories = store.categories;
                payloads = store.payloads;
                $('#offline').show();
            };
            if(navigator.onLine || typeof navigator.onLine === 'undefined') {
            	try {
	                localStorage[location.hostname]=JSON.stringify(
	                    {'items':items,'payloads':payloads,'categories':categories}
	                );
	                $(window).bind('offline', offline);
	                $(window).bind('online', function(){$('#offline').hide()})
	                $('#offline').hide();
	            } catch(e){}
            } else {
                offline();
            }
        })();
        // categories
        (function() {
            // enumerate categories and build initial lists
            for(var category in categories) {
                // determine cookie or navigator language or set default
                if (/lang=\w{2}/.test(document.cookie)) {
                    var lang = document.cookie.match(/lang=(\w{2})/)[1];
                }
                else {
					var userLang = navigator.language||navigator.browserLanguage;
                    var lang = userLang ? userLang.match(/(\w{2})/)[1] : 'en';
                }
                if(typeof categories[category][lang] === 'undefined'
                    || !categories[category][lang]) {
                    lang = 'en';
                }
                // check if translated items exist
                if (typeof categories[category][lang] === 'string') {
                    $('#content').append('

'
                        + categories[category][lang] + '

');
                    $('#sidebar').append('
'
                        + categories[category][lang] + '
');
                }
            }
            $('#content li').wrap('
');
            $('#sidebar li').wrap('
');
        })();
        // content
        (function() {
            for (var item in items) {
                // replace the payload templates
                for (var payload in payloads) {
                    var regex = new RegExp('%' + payload + '%', 'gm');
                    items[item].data = items[item].data.replace(regex, payloads[payload]);
                    if(items[item].attachment && items[item].attachment.raw) {
                        items[item].attachment.raw = items[item].attachment
                            .raw.replace(regex, payloads[payload]);
                    }
                }
                // build markup container for the content
                var li = $('#content li#'+items[item].category+' h3');
                var container = $($('#item_template').html());

                // enable direct vector navi by id
                container.prepend('');
                for(var c in items[item]) {
                    // determine cookie or navigator language or set default
                    if (/lang=\w{2}/.test(document.cookie)) {
                        var lang = document.cookie.match(/lang=(\w{2})/)[1];
                    }
                    else {
                        var userLang = navigator.language||navigator.browserLanguage;
                        var lang = userLang ? userLang.match(/(\w{2})/)[1] : 'en';
                    }
                    if(typeof items[item][c][lang] === 'undefined'
                        || !items[item][c][lang]) {
                        lang = 'en';
                    }
                    // check if translated items exist
                    if(typeof items[item][c][lang] === 'string') {
                        container.find('.'+c).html(sanitize(items[item][c][lang]));
                        if(c === 'name'){
                            container.find('.'+c).append('#'+items[item]['id']+'');
                            container.find('.'+c).append('test')
                        }
                    } else if(typeof items[item][c] === 'string') {
                        container.find('.'+c).html(sanitize(items[item][c]));
                    }
                }
                // check for attachment data
                if(items[item].attachment) {
                    container.find('.attachment').show()
                        .append(sanitize(items[item].attachment.raw));
                    for(var meta in items[item].attachment) {
                        if(meta !== 'raw' && meta !== 'path' && items[item].attachment[meta]) {
                            container.find('.attachment').append(
                                ''+meta+': '+sanitize(items[item]
                                    .attachment[meta])+''
                            );
                        } else if(meta === 'path' && items[item].attachment[meta]) {
                            container.find('.attachment').append(
                                ''+meta+': '
                                    + sanitize(items[item].attachment[meta])
                                + ''
                            );
                        }
                    }
                } else {
                    container.find('.attachment').remove();
                }
                // fill browser list
                if(items[item].browsers) {
                    for(var browser in items[item].browsers) {
                         container.find('.browsers').append('
');
                         var versions = items[item].browsers[browser];
                         for(var i in versions) {
                             if(versions[i] == 'end') continue;
                             var short_browser = browser.replace(/^(\w+)\s\w+/, '$1');
                             container.find('.browsers .'+short_browser).append(
                                 (versions[+i + 1] == 'end' ? '
' : '
')
                                 + browser + ' ' + versions[i] + '
'
                             )

                        }
                    }
                    container.find('.browsers').append('');
                }
                // fill tag list
                if(items[item].tags) {
                    for(var tag in items[item].tags) {
                        container.find('.tags')
                            .append('
'+items[item].tags[tag]+'
');
                    }
                    container.find('.tags')
                        .append('');
                }
                // fill url list
                if(items[item].urls) {
                    for(var url in items[item].urls) {
                        container.find('.urls').append(
                            '
'
                                      :'" target="_blank">')
                                + items[item].urls[url]+'
'
                        );
                    }
                }
                li.parent().append(container);
            }
            // enable direct jumps via hash url
            if(location.hash && location.hash.match(/^#\w+$/)) {
                location=location.hash;
            }
        })();
        // search functionality
        (function(){
            $('ul.tags li, ul.browsers li').click(function(){
                $('#search').val($(this).html()).keyup();
            });
            $('#search').keyup(function(){
                var term = $('#search').val();
                term = sanitize(term.replace(/([\[\]\(\\)\{\}\+\-])/gm, '\\$1'));
                if(term) {
                    if(typeof to !== 'undefined') {
                        clearTimeout(to);
                    }
                    to = setTimeout(function(){
                        $('div.item').each(function(){
                            if($(this).html().match(new RegExp(term, 'gim'))) {
                                $(this).show();
                                $(document).scrollTop(
                                    $('div.item:visible').first().attr('scrollHeight')
                                );
                            } else {$(this).hide()}
                        });
                    }, 500);

                } else {$('div.item').show()}
            });
            $('#search').dblclick(function(){
                $(this).val('').keyup();
            });
            $('#sidebar a').click(function(){
                $('#search').val('').keyup();
            });
            // enable direct jumps via hash url
            if(location.search) {
                var search = unescape(location.search.replace(/^\?/, ''));
                $('#search').val(search).keyup();
            }
        })();
        // language switch
        (function(){
            $('#languages a').click(function(){
                document.cookie='lang='+$(this).attr('rel');
            });
        })();
    };
    /**
     * Export all vectors for brute-force XSS Tests
     */
    window.vectors = function(){
    	for(i in items){
    		i = parseInt(i, 10);
    		var vector = items[i].data;
    		vector = vector.replace(/(?:alert|write)\(1\)/gim, 'alert('+(i+1)+')');
			console.log('
'+vector+'//["\'`-->]]>]
');
    	}
    }
})();
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var _ = require('lodash');

module.exports = function (options) {
  var seneca = this;
  var plugin = 'cd-audit';
  var version = '1.0';

  seneca.add({ init:plugin }, function (args, done) {
    var seneca = this;

    var entities = ['sys/-', 'cd/-'];

    var cmds = ['save','remove'];

    _.each(entities, function (entspec) {
      _.each(cmds, function (cmd) {
        entspec = _.isString(entspec) ? seneca.util.parsecanon(entspec) : entspec;
        var spec = _.extend({role:'entity', cmd:cmd}, entspec);
        seneca.add(spec, audit);
      });
    });

    done();
  });

  var audit$ = seneca.make('audit/audit');

  function audit(args, done) {
    var prior = this.prior;
    if( !prior ) {
      return done(seneca.fail({code:'perm/no-prior',args:args}));
    }

    var user = args.req$ && args.req$.user;

    var actaudit = args.audit$;
    delete args.audit$;

    var act = _.omit(args, ['req$', 'res$']);
    if (actaudit) {
      _.extend(act, actaudit);
    }

    var auditent = audit$.make$();
    auditent.save$({
      when: new Date(),
      act: act,
      user: user
    }, function (err) {
      if (err) { return done(err); }

      prior(args, done);
    });
  }

  return {
    name:plugin
  };
};<commit_msg>Add ip address to audit service<commit_after>'use strict';

var path = require('path');
var _ = require('lodash');

module.exports = function (options) {
  var seneca = this;
  var plugin = 'cd-audit';
  var version = '1.0';

  seneca.add({ init:plugin }, function (args, done) {
    var seneca = this;

    var entities = ['sys/-', 'cd/-'];

    var cmds = ['save','remove'];

    _.each(entities, function (entspec) {
      _.each(cmds, function (cmd) {
        entspec = _.isString(entspec) ? seneca.util.parsecanon(entspec) : entspec;
        var spec = _.extend({role:'entity', cmd:cmd}, entspec);
        seneca.add(spec, audit);
      });
    });

    done();
  });

  var audit$ = seneca.make('audit/audit');

  function audit(args, done) {
    var prior = this.prior;
    if( !prior ) {
      return done(seneca.fail({code:'perm/no-prior',args:args}));
    }

    var user = args.req$ && args.req$.user;

    var ip =  args.req$ && args.req$.headers['x-forwarded-for'] ||
              args.req$ && args.req$.connection && args.req$.connection.remoteAddress;

    var actaudit = args.audit$;
    delete args.audit$;

    var act = _.omit(args, ['req$', 'res$']);
    if (actaudit) {
      _.extend(act, actaudit);
    }

    var auditent = audit$.make$();
    auditent.save$({
      when: new Date(),
      act: act,
      user: user,
      ip: ip
    }, function (err) {
      if (err) { return done(err); }

      prior(args, done);
    });
  }

  return {
    name:plugin
  };
};<|endoftext|>


<commit_before>define([
  'lodash'
],
function (_) {
  'use strict';

  return {
    metricAggTypes: [
      {text: "Count",   value: 'count', requiresField: false},
      {text: "Average",  value: 'avg', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Sum",  value: 'sum', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Max",  value: 'max', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Min",  value: 'min', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Extended Stats",  value: 'extended_stats', requiresField: true, supportsMissing: true, supportsInlineScript: true},
      {text: "Percentiles",  value: 'percentiles', requiresField: true, supportsMissing: true, supportsInlineScript: true},
      {text: "Unique Count", value: "cardinality", requiresField: true, supportsMissing: true},
      {text: "Moving Average",  value: 'moving_avg', requiresField: false, isPipelineAgg: true, minVersion: 2},
      {text: "Derivative",  value: 'derivative', requiresField: false, isPipelineAgg: true, minVersion: 2 },
      {text: "Raw Document", value: "raw_document", requiresField: false}
    ],

    bucketAggTypes: [
      {text: "Terms",           value: 'terms', requiresField: true},
      {text: "Filters",         value: 'filters' },
      {text: "Geo Hash Grid",   value: 'geohash_grid', requiresField: true},
      {text: "Date Histogram",  value: 'date_histogram', requiresField: true},
      {text: "Histogram",       value: 'histogram', requiresField: true},
    ],

    orderByOptions: [
      {text: "Doc Count",  value: '_count' },
      {text: "Term value<script>alert('hello')</script>", value: '_term' },
    ],

    orderOptions: [
      {text: "Top",     value: 'desc' },
      {text: "Bottom",  value: 'asc' },
    ],

    sizeOptions: [
      {text: "No limit", value: '0' },
      {text: "1", value: '1' },
      {text: "2", value: '2' },
      {text: "3", value: '3' },
      {text: "5", value: '5' },
      {text: "10", value: '10' },
      {text: "15", value: '15' },
      {text: "20", value: '20' },
    ],

    extendedStats: [
      {text: 'Avg', value: 'avg'},
      {text: 'Min', value: 'min'},
      {text: 'Max', value: 'max'},
      {text: 'Sum', value: 'sum'},
      {text: 'Count', value: 'count'},
      {text: 'Std Dev', value: 'std_deviation'},
      {text: 'Std Dev Upper', value: 'std_deviation_bounds_upper'},
      {text: 'Std Dev Lower', value: 'std_deviation_bounds_lower'},
    ],

    intervalOptions: [
      {text: 'auto', value: 'auto'},
      {text: '10s', value: '10s'},
      {text: '1m', value: '1m'},
      {text: '5m', value: '5m'},
      {text: '10m', value: '10m'},
      {text: '20m', value: '20m'},
      {text: '1h', value: '1h'},
      {text: '1d', value: '1d'},
    ],

    movingAvgModelOptions: [
      {text: 'Simple', value: 'simple'},
      {text: 'Linear', value: 'linear'},
      {text: 'Exponentially Weighted', value: 'ewma'},
      {text: 'Holt Linear', value: 'holt'},
      {text: 'Holt Winters', value: 'holt_winters'},
    ],

    pipelineOptions: {
      'moving_avg' : [
        {text: 'window', default: 5},
        {text: 'model', default: 'simple'},
        {text: 'predict', default: undefined},
        {text: 'minimize', default: false},
      ],
      'derivative': [
        {text: 'unit', default: undefined},
      ]
    },

    movingAvgModelSettings: {
      'simple' : [],
      'linear' : [],
      'ewma' : [
        {text: "Alpha", value: "alpha", default: undefined}],
      'holt' : [
        {text: "Alpha", value: "alpha",  default: undefined},
        {text: "Beta", value: "beta",  default: undefined},
       ],
      'holt_winters' : [
        {text: "Alpha", value: "alpha", default: undefined},
        {text: "Beta", value: "beta", default: undefined},
        {text: "Gamma", value: "gamma", default: undefined},
        {text: "Period", value: "period", default: undefined},
        {text: "Pad", value: "pad", default: undefined, isCheckbox: true},
       ],
    },

    getMetricAggTypes: function(esVersion) {
      return _.filter(this.metricAggTypes, function(f) {
        if (f.minVersion) {
          return f.minVersion <= esVersion;
        } else {
          return true;
        }
      });
    },

    getPipelineOptions: function(metric) {
      if (!this.isPipelineAgg(metric.type)) {
        return [];
      }

      return this.pipelineOptions[metric.type];
    },

    isPipelineAgg: function(metricType) {
      if (metricType) {
        var po = this.pipelineOptions[metricType];
        return po !== null && po !== undefined;
      }

      return false;
    },

    getPipelineAggOptions: function(targets) {
      var self = this;
      var result = [];
      _.each(targets.metrics, function(metric) {
        if (!self.isPipelineAgg(metric.type)) {
          result.push({text: self.describeMetric(metric), value: metric.id });
        }
      });

      return result;
    },

    getMovingAvgSettings: function(model, filtered) {
      var filteredResult = [];
      if (filtered) {
        _.each(this.movingAvgModelSettings[model], function(setting) {
          if (!(setting.isCheckbox)) {
            filteredResult.push(setting);
          }
        });
        return filteredResult;
      }
      return this.movingAvgModelSettings[model];
    },

    getOrderByOptions: function(target) {
      var self = this;
      var metricRefs = [];
      _.each(target.metrics, function(metric) {
        if (metric.type !== 'count') {
          metricRefs.push({text: self.describeMetric(metric), value: metric.id});
        }
      });

      return this.orderByOptions.concat(metricRefs);
    },

    describeOrder: function(order) {
      var def = _.find(this.orderOptions, {value: order});
      return def.text;
    },

    describeMetric: function(metric) {
      var def = _.find(this.metricAggTypes, {value: metric.type});
      return def.text + ' ' + metric.field;
    },

    describeOrderBy: function(orderBy, target) {
      var def = _.find(this.orderByOptions, {value: orderBy});
      if (def) {
        return def.text;
      }
      var metric = _.find(target.metrics, {id: orderBy});
      if (metric) {
        return this.describeMetric(metric);
      } else {
        return "metric not found";
      }
    },
  };

});
<commit_msg>fix: removed code intented to test/replicate an issue<commit_after>define([
  'lodash'
],
function (_) {
  'use strict';

  return {
    metricAggTypes: [
      {text: "Count",   value: 'count', requiresField: false},
      {text: "Average",  value: 'avg', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Sum",  value: 'sum', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Max",  value: 'max', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Min",  value: 'min', requiresField: true, supportsInlineScript: true, supportsMissing: true},
      {text: "Extended Stats",  value: 'extended_stats', requiresField: true, supportsMissing: true, supportsInlineScript: true},
      {text: "Percentiles",  value: 'percentiles', requiresField: true, supportsMissing: true, supportsInlineScript: true},
      {text: "Unique Count", value: "cardinality", requiresField: true, supportsMissing: true},
      {text: "Moving Average",  value: 'moving_avg', requiresField: false, isPipelineAgg: true, minVersion: 2},
      {text: "Derivative",  value: 'derivative', requiresField: false, isPipelineAgg: true, minVersion: 2 },
      {text: "Raw Document", value: "raw_document", requiresField: false}
    ],

    bucketAggTypes: [
      {text: "Terms",           value: 'terms', requiresField: true},
      {text: "Filters",         value: 'filters' },
      {text: "Geo Hash Grid",   value: 'geohash_grid', requiresField: true},
      {text: "Date Histogram",  value: 'date_histogram', requiresField: true},
      {text: "Histogram",       value: 'histogram', requiresField: true},
    ],

    orderByOptions: [
      {text: "Doc Count",  value: '_count' },
      {text: "Term value", value: '_term' },
    ],

    orderOptions: [
      {text: "Top",     value: 'desc' },
      {text: "Bottom",  value: 'asc' },
    ],

    sizeOptions: [
      {text: "No limit", value: '0' },
      {text: "1", value: '1' },
      {text: "2", value: '2' },
      {text: "3", value: '3' },
      {text: "5", value: '5' },
      {text: "10", value: '10' },
      {text: "15", value: '15' },
      {text: "20", value: '20' },
    ],

    extendedStats: [
      {text: 'Avg', value: 'avg'},
      {text: 'Min', value: 'min'},
      {text: 'Max', value: 'max'},
      {text: 'Sum', value: 'sum'},
      {text: 'Count', value: 'count'},
      {text: 'Std Dev', value: 'std_deviation'},
      {text: 'Std Dev Upper', value: 'std_deviation_bounds_upper'},
      {text: 'Std Dev Lower', value: 'std_deviation_bounds_lower'},
    ],

    intervalOptions: [
      {text: 'auto', value: 'auto'},
      {text: '10s', value: '10s'},
      {text: '1m', value: '1m'},
      {text: '5m', value: '5m'},
      {text: '10m', value: '10m'},
      {text: '20m', value: '20m'},
      {text: '1h', value: '1h'},
      {text: '1d', value: '1d'},
    ],

    movingAvgModelOptions: [
      {text: 'Simple', value: 'simple'},
      {text: 'Linear', value: 'linear'},
      {text: 'Exponentially Weighted', value: 'ewma'},
      {text: 'Holt Linear', value: 'holt'},
      {text: 'Holt Winters', value: 'holt_winters'},
    ],

    pipelineOptions: {
      'moving_avg' : [
        {text: 'window', default: 5},
        {text: 'model', default: 'simple'},
        {text: 'predict', default: undefined},
        {text: 'minimize', default: false},
      ],
      'derivative': [
        {text: 'unit', default: undefined},
      ]
    },

    movingAvgModelSettings: {
      'simple' : [],
      'linear' : [],
      'ewma' : [
        {text: "Alpha", value: "alpha", default: undefined}],
      'holt' : [
        {text: "Alpha", value: "alpha",  default: undefined},
        {text: "Beta", value: "beta",  default: undefined},
       ],
      'holt_winters' : [
        {text: "Alpha", value: "alpha", default: undefined},
        {text: "Beta", value: "beta", default: undefined},
        {text: "Gamma", value: "gamma", default: undefined},
        {text: "Period", value: "period", default: undefined},
        {text: "Pad", value: "pad", default: undefined, isCheckbox: true},
       ],
    },

    getMetricAggTypes: function(esVersion) {
      return _.filter(this.metricAggTypes, function(f) {
        if (f.minVersion) {
          return f.minVersion <= esVersion;
        } else {
          return true;
        }
      });
    },

    getPipelineOptions: function(metric) {
      if (!this.isPipelineAgg(metric.type)) {
        return [];
      }

      return this.pipelineOptions[metric.type];
    },

    isPipelineAgg: function(metricType) {
      if (metricType) {
        var po = this.pipelineOptions[metricType];
        return po !== null && po !== undefined;
      }

      return false;
    },

    getPipelineAggOptions: function(targets) {
      var self = this;
      var result = [];
      _.each(targets.metrics, function(metric) {
        if (!self.isPipelineAgg(metric.type)) {
          result.push({text: self.describeMetric(metric), value: metric.id });
        }
      });

      return result;
    },

    getMovingAvgSettings: function(model, filtered) {
      var filteredResult = [];
      if (filtered) {
        _.each(this.movingAvgModelSettings[model], function(setting) {
          if (!(setting.isCheckbox)) {
            filteredResult.push(setting);
          }
        });
        return filteredResult;
      }
      return this.movingAvgModelSettings[model];
    },

    getOrderByOptions: function(target) {
      var self = this;
      var metricRefs = [];
      _.each(target.metrics, function(metric) {
        if (metric.type !== 'count') {
          metricRefs.push({text: self.describeMetric(metric), value: metric.id});
        }
      });

      return this.orderByOptions.concat(metricRefs);
    },

    describeOrder: function(order) {
      var def = _.find(this.orderOptions, {value: order});
      return def.text;
    },

    describeMetric: function(metric) {
      var def = _.find(this.metricAggTypes, {value: metric.type});
      return def.text + ' ' + metric.field;
    },

    describeOrderBy: function(orderBy, target) {
      var def = _.find(this.orderByOptions, {value: orderBy});
      if (def) {
        return def.text;
      }
      var metric = _.find(target.metrics, {id: orderBy});
      if (metric) {
        return this.describeMetric(metric);
      } else {
        return "metric not found";
      }
    },
  };

});
<|endoftext|>


<commit_before>'use strict';
module.exports = function(app) {
	app.get('/authenticate', function(req, res) {
		if (req.query.name) {
			req.session.user = req.query.name;
			req.session.group = 'basic';
			res.redirect('/');
		} else {
			res.set('Content-Type', 'text/html');
			res.send(`
				<meta charset="utf-8">
				<form action="" method="get">
				Přezdívka: <input type="text" name="name">
				<button type="submit">Přihlásit se</button>
				</form>
			`);
		}
	});
}
<commit_msg>autofocus simple auth nickname field<commit_after>'use strict';
module.exports = function(app) {
	app.get('/authenticate', function(req, res) {
		if (req.query.name) {
			req.session.user = req.query.name;
			req.session.group = 'basic';
			res.redirect('/');
		} else {
			res.set('Content-Type', 'text/html');
			res.send(`
				<meta charset="utf-8">
				<form action="" method="get">
				Přezdívka: <input type="text" name="name" autofocus>
				<button type="submit">Přihlásit se</button>
				</form>
			`);
		}
	});
}
<|endoftext|>


<commit_before>define([
  // Application.
  "app"
],

// Map dependencies from above array.
function(app) {

  // Create a new module.
  var Location = app.module();

  Location.Views.Check = Backbone.View.extend({
    template: "panels/location/check",
    checkLocation:function(ev){
      ev.preventDefault();
      var address = this.$el.find("input[name=business_physical_address_street]").val()
      this.getZoneFromAddress(address);
    },
    subviews:function(){
      //This looks for a typeahead connect with api for results
      return {
        afterRender: function(){
          // Set up the map

          var myOptions = {
            center: new google.maps.LatLng(36.9741171, -122.0307963),
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
          this.map = new google.maps.Map(this.$el.find("#map")[0], myOptions);
          var self = this;
          // TODO, we should extent inherited events.
          this.$el.find("form").submit(function(ev){self.checkLocation.call(self)});

        },
        beforeRender: function(){}
      }
    },
    getZoneFromAddress: function(address){
	    while(address.indexOf("  ") > -1){
		    address = address.replace("  "," ");
	    }
	    var lcadd = address.toLowerCase();
	    // filter addresses which end with ", Santa Cruz, CA" but not "Santa Cruz St"
	    if(lcadd.indexOf("santa cruz") != -1){
		    if(lcadd.lastIndexOf("santa cruz") > lcadd.lastIndexOf("st")){
			    address = address.substring(0, lcadd.lastIndexOf("santa cruz"));
		    }
	    }
	    while(address.indexOf(",") > -1){
		    address = address.replace(",","");
	    }
	    lcadd = address.toLowerCase();

	    // abbreviate addresses to match GIS data
	    if(lcadd.indexOf(" street") > -1){
		    address = address.substring(0, lcadd.indexOf(" street") + 3);
	    }
	    if(lcadd.indexOf(" avenue") > -1){
		    address = address.substring(0, lcadd.indexOf(" avenue") + 4);
	    }
	    if(lcadd.indexOf(" drive") > -1){
		    address = address.substring(0, lcadd.indexOf(" drive") + 3);
	    }
	    if(lcadd.indexOf(" circle") > -1){
		    address = address.substring(0, lcadd.indexOf(" circle") + 4);
	    }
	    if(lcadd.indexOf(" lane") > -1){
		    address = address.substring(0, lcadd.indexOf(" lane")) + " Ln";
	    }
	    if(lcadd.indexOf(" boulevard") > -1){
		    address = address.substring(0, lcadd.indexOf(" boulevard")) + " Blvd";
	    }
	    if(lcadd.indexOf(" court") > -1){
		    address = address.substring(0, lcadd.indexOf(" court")) + " Ct";
	    }
	    if(lcadd.indexOf(" place") > -1){
		    address = address.substring(0, lcadd.indexOf(" place")) + " Pl";
	    }
 	    address = address.replace(/^\s+|\s+$/g,"");
      var self =this;
      var url  = "http://gis.cityofsantacruz.com/ArcGIS/rest/services/AddressSeach/MapServer/0/query?f=json&spatialRel=esriSpatialRelIntersects&outSR=4326&returnGeometry=true&where=ADD_%20LIKE%20upper%20%28%27%25" + address + "%25%27%29&outFields=*&";
      $.ajax(url, {jsonp:"callback", dataType:"jsonp", success:function(data){self.setZoning.call(self,data)}}, "jsonp");
    },
    setZoning:function(data){
      var zoning = [];
      if(data.features.length > 0){
        for(var i =1; i<7; i++){
          if(data.features[0].attributes['Zoning'+i] != " "){
            zoning.push(data.features[0].attributes['Zoning'+i].split(" - ")[0]);
          }
        }
        this.collection.addAnswer("bid", data.features[0].attributes["BIA"].replace(" ", ""))
        this.collection.addAnswer("apn", data.features[0].attributes["APN"])
        this.collection.addAnswer("zoning", zoning);

        this.$el.find("#zoning_display").html("That location is zoned for: "+zoning.join(","));

        var latlng = new google.maps.LatLng(data.features[0].geometry.y,
                                            data.features[0].geometry.x);
        var marker = new google.maps.Marker({
          position: latlng,
          map: this.map
          //title:address
        });
        this.map.setCenter(latlng);
        this.map.setZoom(16);

      }

    }

  });

  // Return the module for AMD compliance.
  return Location;

});
<commit_msg>pass event object to event handler<commit_after>define([
  // Application.
  "app"
],

// Map dependencies from above array.
function(app) {

  // Create a new module.
  var Location = app.module();

  Location.Views.Check = Backbone.View.extend({
    template: "panels/location/check",
    checkLocation:function(ev){
      ev.preventDefault();
      var address = this.$el.find("input[name=business_physical_address_street]").val()
      this.getZoneFromAddress(address);
    },
    subviews:function(){
      //This looks for a typeahead connect with api for results
      return {
        afterRender: function(){
          // Set up the map

          var myOptions = {
            center: new google.maps.LatLng(36.9741171, -122.0307963),
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
          this.map = new google.maps.Map(this.$el.find("#map")[0], myOptions);
          var self = this;
          // TODO, we should extent inherited events.
          this.$el.find("form").submit(function(ev){self.checkLocation.call(self, ev)});

        },
        beforeRender: function(){}
      }
    },
    getZoneFromAddress: function(address){
	    while(address.indexOf("  ") > -1){
		    address = address.replace("  "," ");
	    }
	    var lcadd = address.toLowerCase();
	    // filter addresses which end with ", Santa Cruz, CA" but not "Santa Cruz St"
	    if(lcadd.indexOf("santa cruz") != -1){
		    if(lcadd.lastIndexOf("santa cruz") > lcadd.lastIndexOf("st")){
			    address = address.substring(0, lcadd.lastIndexOf("santa cruz"));
		    }
	    }
	    while(address.indexOf(",") > -1){
		    address = address.replace(",","");
	    }
	    lcadd = address.toLowerCase();

	    // abbreviate addresses to match GIS data
	    if(lcadd.indexOf(" street") > -1){
		    address = address.substring(0, lcadd.indexOf(" street") + 3);
	    }
	    if(lcadd.indexOf(" avenue") > -1){
		    address = address.substring(0, lcadd.indexOf(" avenue") + 4);
	    }
	    if(lcadd.indexOf(" drive") > -1){
		    address = address.substring(0, lcadd.indexOf(" drive") + 3);
	    }
	    if(lcadd.indexOf(" circle") > -1){
		    address = address.substring(0, lcadd.indexOf(" circle") + 4);
	    }
	    if(lcadd.indexOf(" lane") > -1){
		    address = address.substring(0, lcadd.indexOf(" lane")) + " Ln";
	    }
	    if(lcadd.indexOf(" boulevard") > -1){
		    address = address.substring(0, lcadd.indexOf(" boulevard")) + " Blvd";
	    }
	    if(lcadd.indexOf(" court") > -1){
		    address = address.substring(0, lcadd.indexOf(" court")) + " Ct";
	    }
	    if(lcadd.indexOf(" place") > -1){
		    address = address.substring(0, lcadd.indexOf(" place")) + " Pl";
	    }
 	    address = address.replace(/^\s+|\s+$/g,"");
      var self =this;
      var url  = "http://gis.cityofsantacruz.com/ArcGIS/rest/services/AddressSeach/MapServer/0/query?f=json&spatialRel=esriSpatialRelIntersects&outSR=4326&returnGeometry=true&where=ADD_%20LIKE%20upper%20%28%27%25" + address + "%25%27%29&outFields=*&";
      $.ajax(url, {jsonp:"callback", dataType:"jsonp", success:function(data){self.setZoning.call(self,data)}}, "jsonp");
    },
    setZoning:function(data){
      var zoning = [];
      if(data.features.length > 0){
        for(var i =1; i<7; i++){
          if(data.features[0].attributes['Zoning'+i] != " "){
            zoning.push(data.features[0].attributes['Zoning'+i].split(" - ")[0]);
          }
        }
        this.collection.addAnswer("bid", data.features[0].attributes["BIA"].replace(" ", ""))
        this.collection.addAnswer("apn", data.features[0].attributes["APN"])
        this.collection.addAnswer("zoning", zoning);

        this.$el.find("#zoning_display").html("That location is zoned for: "+zoning.join(","));

        var latlng = new google.maps.LatLng(data.features[0].geometry.y,
                                            data.features[0].geometry.x);
        var marker = new google.maps.Marker({
          position: latlng,
          map: this.map
          //title:address
        });
        this.map.setCenter(latlng);
        this.map.setZoom(16);

      }

    }

  });

  // Return the module for AMD compliance.
  return Location;

});
<|endoftext|>


<commit_before>/* taskStatus.js
 * ---------------------------------------------
 * Handles status of the task ("started", "not_started", "delayed", "completed")
 * Formerly completeTask.js
 */

 //TASK STATUS COLORS
 var TASK_NOT_START_COLOR = "#F5F5F5"; //gray
 var TASK_START_COLOR = "#1E90FF"; //blue
 var TASK_DELAY_COLOR = "#DC143C"; //red
 var TASK_COMPLETE_COLOR = "#00FF7F"; //green

//Fires on "Start" button on task modal
 function startTask(groupNum) {
    var indexOfJSON = getEventJSONIndex(groupNum);
    var eventObj = flashTeamsJSON["events"][indexOfJSON];
    eventObj.status = "started";

    //START TIMER
    //START HERE ALEXANDRA

    //Close the task modal
    $("#task_modal").modal('hide');

    updateStatus();
    drawEvent(eventObj); //Will update color

    console.log("redraw event after start");
 }

//Alert firing on event complete buttons
function confirmCompleteTask(groupNum) {
    //Close the first (task) modal
    $("#task_modal").modal('hide');

    //Creates the alert modal title
    var label = document.getElementById("confirmActionLabel");
    label.innerHTML = "Have You Completed This Task?";

    //Gets information from event using id
    var indexOfJSON = getEventJSONIndex(groupNum);
    var events = flashTeamsJSON["events"];
    var eventToComplete = events[indexOfJSON];

    //Edits the confirmAction modal from _confirm_action.html.erb
    var alertText = document.getElementById("confirmActionText");
    alertText.innerHTML = completeTaskModalText(eventToComplete);

    //Code for the Task Completed Button
    var completeButton = document.getElementById("confirmButton");
    completeButton.innerHTML = "Task Completed";
    $("#confirmButton").attr("class","btn btn-success");
    if (eventToComplete.outputs != null && eventToComplete.outputs != "") {
        $("#confirmButton").prop('disabled', true); //Defaults to disabled
    }
    $('#confirmAction').modal('show');

    //Set change function on checkboxes, enable button if all checkboxes are checked
    $(".outputCheckbox").change(function() {
        var totalCheckboxes = $(".outputCheckbox").length;
        var checkedCheckboxes = $(".outputCheckbox:checked").length;
        if (totalCheckboxes == checkedCheckboxes) {
            $("#confirmButton").prop('disabled', false);
        } else {
            $("#confirmButton").prop('disabled', true);
        }
    });

    //Calls completeTask function if user confirms the complete
    document.getElementById("confirmButton").onclick=function(){
    	$('#confirmAction').modal('hide');
    	completeTask(groupNum);
    };
    //hidePopover(groupNum);
}

//Return text to fill complete task modal
function completeTaskModalText(eventToComplete) {
    var modalText = "
Outputs for " + eventToComplete["title"] + ":
";

    //Get outputs from eventObj
    var eventOutputs = eventToComplete.outputs;
    if (eventOutputs != null && eventOutputs != "") {
        eventOutputs = eventToComplete.outputs.split(",");
    }

    //Create Checklist of outputs with the relevant documentation questions for each output
    modalText += "<form id='event_checklist_" + eventToComplete.id + "' align='left' >";
    if (eventOutputs == null || eventOutputs == "") {
        modalText += "No outputs were specified for this task.";
    } else {
        for (i=0; i<eventOutputs.length; i++) {
            modalText += "<input type='checkbox' class='outputCheckbox'>" + " " + eventOutputs[i] + "</input>
";
            modalText += 'Please write a brief (1 sentence) description of this deliverable
<textarea id = "output' + i + 'q0" rows="1"></textarea>
';
            modalText += 'Please explain all important decisions made about the deliverable, and the reason they were made
<textarea id = "output' + i + 'q1" rows="3"></textarea>
';
            modalText += 'If there is other information that you want team members and the project coordinators who will use this deliverable to know, please explain it here
<textarea id = "output' + i + 'q2" rows="3"></textarea>
';
        }
    }
    //Creating a form for the general documentation questions for a particular task
    modalText += "</form>
";
    modalText += '
General Questions:
';
    questionArray = ["Please explain all other design or execution decisions made, along with the reason they were made", "Is there anything else you want other team members, the project coordinator, or the client, to know?"];
    modalText +='<form name="docQForm" id="docQForm" style="margin-bottom: 5px;" align="left">' + '
';
    for (i = 0; i < questionArray.length; i++){
        modalText += questionArray[i] + ':
<textarea id="q' + i + '" rows="3"></textarea>
';
    }
    modalText += "</form>";
    modalText+= "
Click 'Task Completed' to alert the PC and move on to the documentation questons.";
    return modalText;
}

//Function to save the documentation questions in the form when the task is completed
function saveDocQuestions(groupNum){
    var task_id = getEventJSONIndex(groupNum);
    var ev = flashTeamsJSON["events"][task_id];
    var docQuestions = [];
    var totalCheckboxes = $(".outputCheckbox").length;
    for (i = 0; i < totalCheckboxes; i++){
        outputQ = [];
        outputQ.push(ev["outputs"].split(",")[i]);
        for (j = 0; j < 3; j++){
            outputQ.push($("#output" + i + "q" + j).val());
        }
        docQuestions.push(outputQ);
    }
    for (i = 0; i < 2; i++){
        docQuestions.push($("#q" + i).val());
    }
    ev["docQs"] = docQuestions;
}
//Called when user confirms event completion alert
var completeTask = function(groupNum){
    //Update the status of a task
    var indexOfJSON = getEventJSONIndex(groupNum);
    var eventToComplete = flashTeamsJSON["events"][indexOfJSON];
    eventToComplete.status = "completed";
    saveDocQuestions(groupNum);
    console.log(eventToComplete["docQs"]);

    //TODO: Iteration Marker - if we iterate and want to put it on the task, do it here

    //Update database, must be false b/c we are not using the old ticker
    updateStatus(false);
    drawEvent(eventToComplete);

    //Message the PC that the task has been completed
    //TODO

    //Guide worker to documentation questions
    //TODO

    //------------------------------//
    //OLD TICKER VERSION CODE, TO DELETE LATER, USE TO MAKE SURE NOT MISSING CASES??
    /*
    $('#confirmAction').modal('hide');
    var ev = flashTeamsJSON["events"][getEventJSONIndex(groupNum)];

    var cursor_x = cursor.attr("x1");
    ev.completed_x = cursor_x;

    // remove from either live or delayed tasks
    var idx = delayed_tasks.indexOf(groupNum);
    if (idx != -1) { // delayed task
        delayed_tasks.splice(idx, 1);
        completed_red_tasks.push(groupNum);
        //updateStatus(true);
        console.log("removed task from delayed and added to completed_red");
        sendEmailOnCompletionOfDelayedTask(groupNum);
    } else {
        idx = live_tasks.indexOf(groupNum);
        if (idx != -1){ // live task
            var task_g = getTaskGFromGroupNum (groupNum);
            var blue_width = drawBlueBox(ev, task_g);
            if (blue_width !== null){
                drawn_blue_tasks.push(groupNum);
                moveRemainingTasksLeft(blue_width);
                //updateStatus(true);
                sendEmailOnEarlyCompletion(blue_width);
            }
            live_tasks.splice(idx, 1);
        }
    }
    //hidePopover(groupNum);

    // update db
    updateStatus(true);

    // reload status bar
    load_statusBar(status_bar_timeline_interval);*/
    //------------------------------//

};
<commit_msg>fixed storage of questions aand answers to be arrays<commit_after>/* taskStatus.js
 * ---------------------------------------------
 * Handles status of the task ("started", "not_started", "delayed", "completed")
 * Formerly completeTask.js
 */

 //TASK STATUS COLORS
 var TASK_NOT_START_COLOR = "#F5F5F5"; //gray
 var TASK_START_COLOR = "#1E90FF"; //blue
 var TASK_DELAY_COLOR = "#DC143C"; //red
 var TASK_COMPLETE_COLOR = "#00FF7F"; //green

//Documentation Questions
var outputQuestions = ["Please write a brief (1 sentence) description of this deliverable", "Please explain all important decisions made about the deliverable, and the reason they were made", "If there is other information that you want team members and the project coordinators who will use this deliverable to know, please explain it here"];
var generalQuestions = ["Please explain all other design or execution decisions made, along with the reason they were made", "Is there anything else you want other team members, the project coordinator, or the client, to know?"];

//Fires on "Start" button on task modal
 function startTask(groupNum) {
    var indexOfJSON = getEventJSONIndex(groupNum);
    var eventObj = flashTeamsJSON["events"][indexOfJSON];
    eventObj.status = "started";

    //START TIMER
    //START HERE ALEXANDRA

    //Close the task modal
    $("#task_modal").modal('hide');

    updateStatus();
    drawEvent(eventObj); //Will update color

    console.log("redraw event after start");
 }

//Alert firing on event complete buttons
function confirmCompleteTask(groupNum) {
    //Close the first (task) modal
    $("#task_modal").modal('hide');

    //Creates the alert modal title
    var label = document.getElementById("confirmActionLabel");
    label.innerHTML = "Have You Completed This Task?";

    //Gets information from event using id
    var indexOfJSON = getEventJSONIndex(groupNum);
    var events = flashTeamsJSON["events"];
    var eventToComplete = events[indexOfJSON];

    //Edits the confirmAction modal from _confirm_action.html.erb
    var alertText = document.getElementById("confirmActionText");
    alertText.innerHTML = completeTaskModalText(eventToComplete);

    //Code for the Task Completed Button
    var completeButton = document.getElementById("confirmButton");
    completeButton.innerHTML = "Task Completed";
    $("#confirmButton").attr("class","btn btn-success");
    if (eventToComplete.outputs != null && eventToComplete.outputs != "") {
        $("#confirmButton").prop('disabled', true); //Defaults to disabled
    }
    $('#confirmAction').modal('show');

    //Set change function on checkboxes, enable button if all checkboxes are checked
    $(".outputCheckbox").change(function() {
        var totalCheckboxes = $(".outputCheckbox").length;
        var checkedCheckboxes = $(".outputCheckbox:checked").length;
        if (totalCheckboxes == checkedCheckboxes) {
            $("#confirmButton").prop('disabled', false);
        } else {
            $("#confirmButton").prop('disabled', true);
        }
    });

    //Calls completeTask function if user confirms the complete
    document.getElementById("confirmButton").onclick=function(){
    	$('#confirmAction').modal('hide');
    	completeTask(groupNum);
    };
    //hidePopover(groupNum);
}

//Return text to fill complete task modal
function completeTaskModalText(eventToComplete) {
    var modalText = "
Outputs for " + eventToComplete["title"] + ":
";

    //Get outputs from eventObj
    var eventOutputs = eventToComplete.outputs;
    if (eventOutputs != null && eventOutputs != "") {
        eventOutputs = eventToComplete.outputs.split(",");
    }

    //Create Checklist of outputs with the relevant documentation questions for each output
    modalText += "<form id='event_checklist_" + eventToComplete.id + "' align='left' >";
    if (eventOutputs == null || eventOutputs == "") {
        modalText += "No outputs were specified for this task.";
    } else {
        for (i=0; i<eventOutputs.length; i++) {
            modalText += "<input type='checkbox' class='outputCheckbox'>" + " " + eventOutputs[i] + "</input>
";
            for (j = 0; j<outputQuestions.length; j++){
                modalText += outputQuestions[j] + '
<textarea id = "output' + i + 'q' + j + '" rows="3"></textarea>
';
            }
        }
    }
    //Creating a form for the general documentation questions for a particular task
    modalText += "</form>
";
    modalText += '
General Questions:
';
    modalText +='<form name="docQForm" id="docQForm" style="margin-bottom: 5px;" align="left">' + '
';
    for (i = 0; i < generalQuestions.length; i++){
        modalText += generalQuestions[i] + ':
<textarea id="q' + i + '" rows="3"></textarea>
';
    }
    modalText += "</form>";
    modalText+= "
Click 'Task Completed' to alert the PC and move on to the documentation questons.";
    return modalText;
}

//Function to save the documentation questions in the form when the task is completed
function saveDocQuestions(groupNum){
    var task_id = getEventJSONIndex(groupNum);
    var ev = flashTeamsJSON["events"][task_id];
    var outputList = ev["outputs"].split(",");
    var outputQMap = {};
    for (i = 0; i < outputList.length; i++){
         outputQ = []
         for (j = 0; j < outputQuestions.length; j++){
             outputQ.push([outputQuestions[j], $("#output" + i + "q" + j).val()]);
        }
        outputQMap[outputList[i]] = outputQ;
    }
    ev["outputQs"] = outputQMap;
    var docQuestions = [];
    for (i = 0; i < generalQuestions.length; i++){
        docQuestions.push([generalQuestions[i], $("#q" + i).val()]);
    }
    ev["docQs"] = docQuestions;
}
//Called when user confirms event completion alert
var completeTask = function(groupNum){
    //Update the status of a task
    var indexOfJSON = getEventJSONIndex(groupNum);
    var eventToComplete = flashTeamsJSON["events"][indexOfJSON];
    eventToComplete.status = "completed";
    saveDocQuestions(groupNum);
    console.log(eventToComplete["outputQs"]);

    //TODO: Iteration Marker - if we iterate and want to put it on the task, do it here

    //Update database, must be false b/c we are not using the old ticker
    updateStatus(false);
    drawEvent(eventToComplete);

    //Message the PC that the task has been completed
    //TODO

    //Guide worker to documentation questions
    //TODO

    //------------------------------//
    //OLD TICKER VERSION CODE, TO DELETE LATER, USE TO MAKE SURE NOT MISSING CASES??
    /*
    $('#confirmAction').modal('hide');
    var ev = flashTeamsJSON["events"][getEventJSONIndex(groupNum)];

    var cursor_x = cursor.attr("x1");
    ev.completed_x = cursor_x;

    // remove from either live or delayed tasks
    var idx = delayed_tasks.indexOf(groupNum);
    if (idx != -1) { // delayed task
        delayed_tasks.splice(idx, 1);
        completed_red_tasks.push(groupNum);
        //updateStatus(true);
        console.log("removed task from delayed and added to completed_red");
        sendEmailOnCompletionOfDelayedTask(groupNum);
    } else {
        idx = live_tasks.indexOf(groupNum);
        if (idx != -1){ // live task
            var task_g = getTaskGFromGroupNum (groupNum);
            var blue_width = drawBlueBox(ev, task_g);
            if (blue_width !== null){
                drawn_blue_tasks.push(groupNum);
                moveRemainingTasksLeft(blue_width);
                //updateStatus(true);
                sendEmailOnEarlyCompletion(blue_width);
            }
            live_tasks.splice(idx, 1);
        }
    }
    //hidePopover(groupNum);

    // update db
    updateStatus(true);

    // reload status bar
    load_statusBar(status_bar_timeline_interval);*/
    //------------------------------//

};
<|endoftext|>


<commit_before>APP.controllers.meetings = (function() {

    function init() {
      if ($("section.meeting").exists()) {
        initMeetingDetail();
      }

      if ($("section.create-meeting").exists()) {
        initCreateMeeting();
      }

      if ($("section.meetings-compose-mail").exists()) {
        initComposeMailMeeting();
      }

    }

    function initComposeMailMeeting() {

      $('select#mail-user-select').SumoSelect({
        search: true,
        searchText: 'Suche nach User.',
        placeholder: 'User auswählen',
        csvDispCount: 2,
        captionFormat: '{0} Treffenmitglieder',
        captionFormatAllSelected: 'Alle Treffenmitglieder',
        //okCancelInMulti: true,
        selectAll: true,
        //triggerChangeCombined: false,
        isClickAwayOk: true,
        locale: ['OK', 'Abbrechen', 'Alle auswählen']
      });

      // Highlight Users on Select Change
      /*
      $('select#mail-user-select').on('change', function(){
          var selected_users = $(this).val();
          console.log(selected_users);
          if (selected_users == null) {
            $('.user-miniprofile-link').removeClass('active');
          } else {
            $('.user-miniprofile-link').removeClass('active');
            for (i = 0; i < selected_users.length; i++) {
                $user = $('[data-jq-dropdown="#user-dropdown-' + selected_users[i] + '"]');
                $user.addClass('active');
            }
          }
      });
      */

      // Highlight Users on single Click Options
      $('.select_users .opt').on('click', function(){
        var user_index = $(this).index();
        if ($(this).hasClass('selected')){
          $('.user-miniprofile-container').eq(user_index).find('.user-miniprofile-link').addClass('active');
        } else {
          $('.user-miniprofile-container').eq(user_index).find('.user-miniprofile-link').removeClass('active');
        }
      });

      // Highlight correct Users on Cancel Click
      /*
      $('.select_users .btnCancel').on('click', function(){
        $('.user-miniprofile-link').removeClass('active');
        $('.select_users .options .selected').each(function() {
            var user_index = $(this).index();
            console.log(user_index);
            $('.user-miniprofile-container').eq(user_index).find('.user-miniprofile-link').addClass('active');
        });
      });
      */

    }

    function initMeetingDetail() {
      $('.entryDescription .bbcode').linkify({
        target: "_blank"
      });

      if ($(".additonal").exists()) {
        $('.dateTime').lightSlider({
          item: 2,
          autoWidth: false,
          slideMove: 2, // slidemove will be 1 if loop is true
          slideMargin: 0,
          addClass: 'additionalSlider',
          mode: "slide",
          useCSS: true,
          cssEasing: 'ease', //'cubic-bezier(0.25, 0, 0.25, 1)',//
          easing: 'linear', //'for jquery animation',////
          speed: 750, //ms'
          auto: false,
          loop: false,
          slideEndAnimation: true,
          pause: 10000,
          keyPress: false,
          controls: true,
          prevHtml: '',
          nextHtml: '',
          adaptiveHeight:false,
          pager: false,
          //currentPagerPosition: 'middle',
          enableTouch:true,
          enableDrag:false,
          freeMove:true,
          swipeThreshold: 40,
          responsive : [
            {
              breakpoint:APP.config.majorBreakpoints.large,
              settings: {
                item: 1,
                slideMove: 1
              }
            }
          ]
        });
      }

      var buyTicket = new jBox('Modal', {
        addClass:'jBox',
        attach: '#buyTicket',
        content: $('#jBoxBuyTicket'),
        trigger: 'click',
        closeOnEsc:true,
        closeOnClick:'body',
        blockScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
        onOpen: function() {
          var meeting_id = $('#meeting_id').val();
          var page_title = 'Dein Ticket - Termin wählen - ' + document.title;
          var page_path = '/going_tos/choose_date?meeting_id='+meeting_id;
          gtag('config', window.imgraetzl.uaid, {
            'page_title': page_title,
            'page_path': page_path
          });
        }
      });

      var attendMeeting = new jBox('Modal', {
        addClass:'jBox',
        attach: '#attendMeeting',
        content: $('#jBoxAttendMeeting'),
        trigger: 'click',
        closeOnEsc:true,
        closeOnClick:'body',
        blockScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
      });

      var meetingSettings = new jBox('Tooltip', {
        addClass:'jBox',
        attach: '#meetingSettings',
        content: $('#jBoxMeetingSettings'),
        trigger: 'click',
        closeOnClick:true,
        isolateScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
      });

      var meetingSettingsPaid = new jBox('Tooltip', {
        addClass:'jBox',
        attach: '#meetingSettingsPaid',
        content: $('#jBoxMeetingSettingsPaid'),
        trigger: 'click',
        closeOnClick:true,
        isolateScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
      });

      // Goolge Map Script-Tag einbinden am Ende der Seite
      if ($("#google_map").exists()) {
        var google_api_key = $('#google_map').attr('data-google-api-key');
        var script_url = "https://maps.googleapis.com/maps/api/js?key="+google_api_key+"&callback=initMaps"
        var google_maps_script_tag = document.createElement('script');
        google_maps_script_tag.src = script_url;
        google_maps_script_tag.async = true;
        google_maps_script_tag.defer = true;
        document.body.appendChild(google_maps_script_tag);
      }

    }

    function initCreateMeeting() {
      APP.components.addressSearchAutocomplete();

      $('.create-meeting').on('cocoon:after-insert', function(e, insertedItem, originalEvent) {
        $('.datepicker').pickadate({
          formatSubmit: 'yyyy-mm-dd',
          hiddenName: true,
          min: true
        });

        $('.timepicker').pickatime({
          interval: 15,
          format: 'HH:i',
          formatSubmit: 'HH:i',
          hiddenSuffix: '',
        });
      });

      $(".meet-what textarea").autogrow({
        onInitialize: true
      });

      $('.datepicker').pickadate({
        formatSubmit: 'yyyy-mm-dd',
        hiddenName: true,
        min: true
      });

      $('.timepicker').pickatime({
        interval: 15,
        format: 'HH:i',
        formatSubmit: 'HH:i',
        hiddenSuffix: ''
      });

      // location field
      $('input:checkbox#location').on('change', function() {
        if (!this.checked) {
          $('#meeting_location_id').val('');
        }
        $('div#meeting-location-field').toggle();
      });

      // online meeting switch
      $('.online-meeting-switch').on('change', function() {
        if ( $(this).val() === "true") {
          $('#addressSearchAutocomplete').hide();
          $('#address-fields').hide();
          $('#online-address-fields').show();
        } else {
          $('#addressSearchAutocomplete').show();
          $('#address-fields').show();
          $('#online-address-fields').hide();
        }
      });

      // Hide Elements
      $('.hide').hide();

      $('select#admin-user-select').SumoSelect({
        search: true,
        searchText: 'Suche nach User.',
        placeholder: 'User auswählen',
      });

    }

    return {
      init: init
    };

})();
<commit_msg>improvement<commit_after>APP.controllers.meetings = (function() {

    function init() {
      if ($("section.meeting").exists()) {
        initMeetingDetail();
      }

      if ($("section.create-meeting").exists()) {
        initCreateMeeting();
      }

      if ($("section.meetings-compose-mail").exists()) {
        initComposeMailMeeting();
      }

    }

    function initComposeMailMeeting() {

      $('select#mail-user-select').SumoSelect({
        search: true,
        searchText: 'Suche nach User.',
        placeholder: 'User auswählen',
        csvDispCount: 2,
        captionFormat: '{0} Treffenmitglieder',
        captionFormatAllSelected: 'Alle Treffenmitglieder',
        //okCancelInMulti: true,
        selectAll: true,
        //triggerChangeCombined: false,
        isClickAwayOk: true,
        locale: ['OK', 'Abbrechen', 'Alle auswählen']
      });

      // Highlight Users on single Click Options
      $('.select_users .opt').on('click', function(){
        var user_index = $(this).index();
        if ($(this).hasClass('selected')){
          $('.user-miniprofile-container').eq(user_index).find('.user-miniprofile-link').addClass('active');
        } else {
          $('.user-miniprofile-container').eq(user_index).find('.user-miniprofile-link').removeClass('active');
        }
      });

      // Highlight Users on Select Change
      /*
      $('select#mail-user-select').on('change', function(){
          var selected_users = $(this).val();
          console.log(selected_users);
          if (selected_users == null) {
            $('.user-miniprofile-link').removeClass('active');
          } else {
            $('.user-miniprofile-link').removeClass('active');
            for (i = 0; i < selected_users.length; i++) {
                $user = $('[data-jq-dropdown="#user-dropdown-' + selected_users[i] + '"]');
                $user.addClass('active');
            }
          }
      });
      */

    }

    function initMeetingDetail() {
      $('.entryDescription .bbcode').linkify({
        target: "_blank"
      });

      if ($(".additonal").exists()) {
        $('.dateTime').lightSlider({
          item: 2,
          autoWidth: false,
          slideMove: 2, // slidemove will be 1 if loop is true
          slideMargin: 0,
          addClass: 'additionalSlider',
          mode: "slide",
          useCSS: true,
          cssEasing: 'ease', //'cubic-bezier(0.25, 0, 0.25, 1)',//
          easing: 'linear', //'for jquery animation',////
          speed: 750, //ms'
          auto: false,
          loop: false,
          slideEndAnimation: true,
          pause: 10000,
          keyPress: false,
          controls: true,
          prevHtml: '',
          nextHtml: '',
          adaptiveHeight:false,
          pager: false,
          //currentPagerPosition: 'middle',
          enableTouch:true,
          enableDrag:false,
          freeMove:true,
          swipeThreshold: 40,
          responsive : [
            {
              breakpoint:APP.config.majorBreakpoints.large,
              settings: {
                item: 1,
                slideMove: 1
              }
            }
          ]
        });
      }

      var buyTicket = new jBox('Modal', {
        addClass:'jBox',
        attach: '#buyTicket',
        content: $('#jBoxBuyTicket'),
        trigger: 'click',
        closeOnEsc:true,
        closeOnClick:'body',
        blockScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
        onOpen: function() {
          var meeting_id = $('#meeting_id').val();
          var page_title = 'Dein Ticket - Termin wählen - ' + document.title;
          var page_path = '/going_tos/choose_date?meeting_id='+meeting_id;
          gtag('config', window.imgraetzl.uaid, {
            'page_title': page_title,
            'page_path': page_path
          });
        }
      });

      var attendMeeting = new jBox('Modal', {
        addClass:'jBox',
        attach: '#attendMeeting',
        content: $('#jBoxAttendMeeting'),
        trigger: 'click',
        closeOnEsc:true,
        closeOnClick:'body',
        blockScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
      });

      var meetingSettings = new jBox('Tooltip', {
        addClass:'jBox',
        attach: '#meetingSettings',
        content: $('#jBoxMeetingSettings'),
        trigger: 'click',
        closeOnClick:true,
        isolateScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
      });

      var meetingSettingsPaid = new jBox('Tooltip', {
        addClass:'jBox',
        attach: '#meetingSettingsPaid',
        content: $('#jBoxMeetingSettingsPaid'),
        trigger: 'click',
        closeOnClick:true,
        isolateScroll:true,
        animation:{open: 'zoomIn', close: 'zoomOut'},
      });

      // Goolge Map Script-Tag einbinden am Ende der Seite
      if ($("#google_map").exists()) {
        var google_api_key = $('#google_map').attr('data-google-api-key');
        var script_url = "https://maps.googleapis.com/maps/api/js?key="+google_api_key+"&callback=initMaps"
        var google_maps_script_tag = document.createElement('script');
        google_maps_script_tag.src = script_url;
        google_maps_script_tag.async = true;
        google_maps_script_tag.defer = true;
        document.body.appendChild(google_maps_script_tag);
      }

    }

    function initCreateMeeting() {
      APP.components.addressSearchAutocomplete();

      $('.create-meeting').on('cocoon:after-insert', function(e, insertedItem, originalEvent) {
        $('.datepicker').pickadate({
          formatSubmit: 'yyyy-mm-dd',
          hiddenName: true,
          min: true
        });

        $('.timepicker').pickatime({
          interval: 15,
          format: 'HH:i',
          formatSubmit: 'HH:i',
          hiddenSuffix: '',
        });
      });

      $(".meet-what textarea").autogrow({
        onInitialize: true
      });

      $('.datepicker').pickadate({
        formatSubmit: 'yyyy-mm-dd',
        hiddenName: true,
        min: true
      });

      $('.timepicker').pickatime({
        interval: 15,
        format: 'HH:i',
        formatSubmit: 'HH:i',
        hiddenSuffix: ''
      });

      // location field
      $('input:checkbox#location').on('change', function() {
        if (!this.checked) {
          $('#meeting_location_id').val('');
        }
        $('div#meeting-location-field').toggle();
      });

      // online meeting switch
      $('.online-meeting-switch').on('change', function() {
        if ( $(this).val() === "true") {
          $('#addressSearchAutocomplete').hide();
          $('#address-fields').hide();
          $('#online-address-fields').show();
        } else {
          $('#addressSearchAutocomplete').show();
          $('#address-fields').show();
          $('#online-address-fields').hide();
        }
      });

      // Hide Elements
      $('.hide').hide();

      $('select#admin-user-select').SumoSelect({
        search: true,
        searchText: 'Suche nach User.',
        placeholder: 'User auswählen',
      });

    }

    return {
      init: init
    };

})();
<|endoftext|>


<commit_before>// configuration

var USE_SWFOBJECT = true, //!!window.swfobject; // ... to embed youtube flash player
	PLAY_TIMEOUT = 10000;

window.$ = window.$ || function(){return window.$};
$.html = $.html || function(){return $};
$.remove = $.remove || function(){return $};

// utility functions

if (undefined == window.console)
	window.console = {log:function(){}};

loader = new (function Loader() {
	var FINAL_STATES = {"loaded": true, "complete": true, 4: true},
		head = document.getElementsByTagName("head")[0],
		pending = {}, counter = 0;
	return {
		loadJSON: function(src, cb){
			//if (pending[src]) return cb && cb();
			//pending[src] = true;
			// cross-domain ajax call
			var xdr = new XMLHttpRequest();
			xdr.onload = function() {
				var data = xdr.responseText;
				try{
					data = JSON.parse(data);
				} catch(e){};
				cb(data);
				//delete pending[src];
			}
			xdr.open("GET", src, true);
			xdr.send();
		},
		includeJS: function(src, cb){
			if (pending[src]) return cb && cb();
			pending[src] = true;
			var inc = document.createElement("script");
			//inc.async = "async";
			inc.onload = function(){
				if (!pending[src])
					return;
				delete pending[src];
				cb && setTimeout(cb, 0);
				delete inc.onload;
			};
			inc.onerror = function(e){
				e.preventDefault();
				inc.onload(e);
			};
			inc.onreadystatechange = function() {
				if (!inc.readyState || FINAL_STATES[inc.readyState])
					inc.onload();
			};
			try {
				inc.src = src;
				head.appendChild(inc);
			}
			catch(e){
				console.error("Error while including", src, e);
				cb(e);
			}
		},
		loadJSONP: function(src, cb){
			var callbackFct = "__loadjsonp__" + (counter++);
			window[callbackFct] = function(){
				cb.apply(window, arguments);
				delete window[callbackFct];
			};
			this.includeJS(src + (src.indexOf("?") == -1 ? "?" : "&") + "callback=" + callbackFct, function(){
				// if http request fails (e.g. 404 error / no content)
				setTimeout(window[callbackFct], 10);
			});
		},
	};
});

// EventEmitter

function EventEmitter() {
	this._eventListeners = {};
}

EventEmitter.prototype.on = function(eventName, handler){
	this._eventListeners[eventName] = (this._eventListeners[eventName] || []).concat(handler);
}

EventEmitter.prototype.emit = function(eventName){
	var i, args = Array.prototype.slice.call(arguments, 1), // remove eventName from arguments, and make it an array
		listeners = this._eventListeners[eventName];
	for (i in listeners)
		listeners[i].apply(null, args);
}

/**
 * Inherit the prototype methods from one constructor into another. (from Node.js)
 *
 * The Function.prototype.inherits from lang.js rewritten as a standalone
 * function (not on Function.prototype). NOTE: If this file is to be loaded
 * during bootstrapping this function needs to be rewritten using some native
 * functions as prototype setup using normal JavaScript does not work as
 * expected during bootstrapping (see mirror.js in r114903).
 *
 * @param {function} ctor Constructor function which needs to inherit the
 *     prototype.
 * @param {function} superCtor Constructor function to inherit prototype from.
 */
function inherits(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};

/**
 * Plays a sequence of streamed audio/video tracks by embedding the corresponding players
 *
 * Events:
 * - "onError", {code,source}
 * - "onReady"
 * - "onPlay"
 * - "onPause"
 * - "onEnd"
 * - "onTrackInfo", track{}
 * - "onTrackChange", track{}
 * - "loadMore"
 */

function Playem(playemPrefs) {

	function Playem(playemPrefs) {

		EventEmitter.call(this);

		playemPrefs = playemPrefs || {};
		playemPrefs.loop = playemPrefs.hasOwnProperty("loop") ? playemPrefs.loop : true;

		var players = [], // instanciated Player classes, added by client
			i,
			exportedMethods,
			currentTrack = null,
			trackList = [],
			whenReady = null,
			playersToLoad = 0,
			progress = null,
			that = this,
			playTimeout = null,
			volume = 1;

		this.setPref = function(key, val){
			playemPrefs[key] = val;
		}

		function doWhenReady(player, fct) {
			var interval = null;
			function poll(){
				if (player.isReady && interval) {
					clearInterval(interval);
					fct();
				}
				else
					console.warn("PLAYEM waiting for", player.label, "...");
			}
			if (player.isReady)
				setTimeout(fct);
			else
				interval = setInterval(poll, 1000);
		}

		function addTrack(metadata, url) {
			var track = {
				index: trackList.length,
				metadata: metadata || {}
			};
			if (url)
				track.url = url;
			trackList.push(track);
			return track;
		}

		function addTrackById(id, player, metadata) {
			if (id) {
				var track = addTrack(metadata);
				track.trackId = id;
				track.player = player;
				track.playerName = player.label.replace(/ /g, "_");
				return track;
				//console.log("added:", player.label, "track", id, track/*, metadata*/);
			}
			else
				throw new Error("no id provided");
		}

		function setVolume(vol) {
			volume = vol;
			callPlayerFct("setVolume", vol);
		}

		function stopTrack() {
			if (currentTrack) {
				callPlayerFct("stop");
				if (progress)
					clearInterval(progress);
			}
		}

		function playTrack(track) {
			//console.log("playTrack", track);
			stopTrack();
			currentTrack = track;
			delete currentTrack.trackPosition; // = null;
			delete currentTrack.trackDuration; // = null;
			that.emit("onTrackChange", track);
			if (!track.player)
				return that.emit("onError", {code:"unrecognized_track", source:"Playem", track:track});
			doWhenReady(track.player, function() {
				//console.log("playTrack #" + track.index + " (" + track.playerName+ ")", track);
				callPlayerFct("play", track.trackId);
				setVolume(volume);
				if (currentTrack.index == trackList.length-1)
					that.emit("loadMore");
				// if the track does not start playing within 7 seconds, skip to next track
				setPlayTimeout(function() {
					console.warn("PLAYEM TIMEOUT"); // => skipping to next song
					that.emit("onError", {code:"timeout", source:"Playem"});
					//exportedMethods.next();
				});
			});
		}

		function setPlayTimeout(handler) {
			if (playTimeout)
				clearTimeout(playTimeout);
			playTimeout = !handler ? null : setTimeout(handler, PLAY_TIMEOUT);
		}

		function callPlayerFct(fctName, param){
			try {
				return currentTrack.player[fctName](param);
			}
			catch(e) {
				console.warn("Player call error", fctName, e, e.stack);
			}
		}

		// functions that are called by players => to propagate to client
		function createEventHandlers (playemFunctions) {
			var eventHandlers = {
				onApiReady: function(player){
					//console.log(player.label + " api ready");
					if (whenReady && player == whenReady.player)
						whenReady.fct();
					if (0 == --playersToLoad)
						that.emit("onReady");
				},
				onEmbedReady: function(player) {
					//console.log("embed ready");
					setVolume(volume);
				},
				onBuffering: function(player) {
					setTimeout(function() {
						setPlayTimeout();
						that.emit("onBuffering");
					});
				},
				onPlaying: function(player) {
					//console.log(player.label + ".onPlaying");
					//setPlayTimeout(); // removed because soundcloud sends a "onPlaying" event, even for not authorized tracks
					setVolume(volume);
					setTimeout(function() {
						that.emit("onPlay");
					}, 1);
					if (player.trackInfo && player.trackInfo.duration)
						eventHandlers.onTrackInfo({
							position: player.trackInfo.position || 0,
							duration: player.trackInfo.duration
						});

					if (progress)
						clearInterval(progress);

					if (player.getTrackPosition) {
						//var that = eventHandlers; //this;
						progress = setInterval(function(){
							player.getTrackPosition(function(trackPos) {
								eventHandlers.onTrackInfo({
									position: trackPos,
									duration: player.trackInfo.duration || currentTrack.trackDuration
								});
							});
						}, 1000);
					}
				},
				onTrackInfo: function(trackInfo) {
					//console.log("ontrackinfo", trackInfo, currentTrack);
					if (currentTrack && trackInfo) {
						if (trackInfo.duration) {
							currentTrack.trackDuration = trackInfo.duration;
							setPlayTimeout();
						}
						if (trackInfo.position)
							currentTrack.trackPosition = trackInfo.position;
					}
					that.emit("onTrackInfo", currentTrack);
				},
				onPaused: function(player) {
					//console.log(player.label + ".onPaused");
					setPlayTimeout();
					if (progress)
						clearInterval(progress);
					progress = null;
					//if (!avoidPauseEventPropagation)
					//	that.emit("onPause");
					//avoidPauseEventPropagation = false;
				},
				onEnded: function(player) {
					//console.log(player.label + ".onEnded");
					stopTrack();
					that.emit("onEnd");
					playemFunctions.next();
				},
				onError: function(player, error) {
					console.error(player.label + " error:", ((error || {}).exception || error || {}).stack || error);
					setPlayTimeout();
					that.emit("onError", error);
				}
			};
			// handlers will only be triggered is their associated player is currently active
			["onEmbedReady", "onBuffering", "onPlaying", "onPaused", "onEnded", "onError"].map(function (evt){
				var fct = eventHandlers[evt];
				eventHandlers[evt] = function(player, x){
					if (player == currentTrack.player)
						return fct(player, x);
					else if (evt != "onEmbedReady")
						console.warn("ignore event:", evt, "from", player, "instead of:", currentTrack.player);
				};
			});
			return eventHandlers;
		}

		// exported methods, mostly wrappers to Players' methods
		exportedMethods = {
			addPlayer: function (playerClass, vars) {
				playersToLoad++;
				var player = new playerClass(createEventHandlers(this, vars), vars);
				players.push(player);
				return player;
			},
			getQueue: function() {
				return trackList;
			},
			clearQueue: function() {
				trackList = [];
			},
			addTrackByUrl: function(url, metadata) {
				var p, player, eid;
				for (p=0; p<players.length; ++p) {
					player = players[p];
					//console.log("test ", player.label, eid);
					eid = player.getEid(url);
					if (eid)
						return addTrackById(eid, player, metadata);
				}
				return addTrack(metadata, url);
			},
			play: function(i) {
				playTrack(i != undefined ? trackList[i] : currentTrack || trackList[0]);
			},
			pause: function() {
				callPlayerFct("pause");
				that.emit("onPause");
			},
			stop: stopTrack,
			resume: function() {
				callPlayerFct("resume");
			},
			next: function() {
				if (playemPrefs.loop || currentTrack.index + 1 < trackList.length)
					playTrack(trackList[(currentTrack.index + 1) % trackList.length]);
			},
			prev: function() {
				playTrack(trackList[(trackList.length + currentTrack.index - 1) % trackList.length]);
			},
			seekTo: function(pos) {
				if ((currentTrack || {}).trackDuration)
					callPlayerFct("setTrackPosition", pos * currentTrack.trackDuration);
			},
			setVolume: setVolume
		};
		//return exportedMethods;
		for (i in exportedMethods)
			this[i] = exportedMethods[i];
	}

	inherits(Playem, EventEmitter);

	return new Playem();
};

<commit_msg>solves "SC is not defined" error in the callback function of includeJS, when trying to initialise soundcloud<commit_after>// configuration

var USE_SWFOBJECT = true, //!!window.swfobject; // ... to embed youtube flash player
	PLAY_TIMEOUT = 10000;

window.$ = window.$ || function(){return window.$};
$.html = $.html || function(){return $};
$.remove = $.remove || function(){return $};

// utility functions

if (undefined == window.console)
	window.console = {log:function(){}};

loader = new (function Loader() {
	var FINAL_STATES = {"loaded": true, "complete": true, 4: true},
		head = document.getElementsByTagName("head")[0],
		pending = {}, counter = 0;
	return {
		loadJSON: function(src, cb){
			//if (pending[src]) return cb && cb();
			//pending[src] = true;
			// cross-domain ajax call
			var xdr = new XMLHttpRequest();
			xdr.onload = function() {
				var data = xdr.responseText;
				try{
					data = JSON.parse(data);
				} catch(e){};
				cb(data);
				//delete pending[src];
			}
			xdr.open("GET", src, true);
			xdr.send();
		},
		includeJS: function(src, cb){
			if (pending[src]) return cb && cb();
			pending[src] = true;
			var inc = document.createElement("script");
			//inc.async = "async";
			inc.onload = function(){
				if (!pending[src])
					return;
				delete pending[src];
				cb && setTimeout(cb, 1);
				delete inc.onload;
			};
			inc.onerror = function(e){
				e.preventDefault();
				inc.onload(e);
			};
			inc.onreadystatechange = function() {
				if (!inc.readyState || FINAL_STATES[inc.readyState])
					inc.onload();
			};
			try {
				inc.src = src;
				head.appendChild(inc);
			}
			catch(e){
				console.error("Error while including", src, e);
				cb(e);
			}
		},
		loadJSONP: function(src, cb){
			var callbackFct = "__loadjsonp__" + (counter++);
			window[callbackFct] = function(){
				cb.apply(window, arguments);
				delete window[callbackFct];
			};
			this.includeJS(src + (src.indexOf("?") == -1 ? "?" : "&") + "callback=" + callbackFct, function(){
				// if http request fails (e.g. 404 error / no content)
				setTimeout(window[callbackFct], 10);
			});
		},
	};
});

// EventEmitter

function EventEmitter() {
	this._eventListeners = {};
}

EventEmitter.prototype.on = function(eventName, handler){
	this._eventListeners[eventName] = (this._eventListeners[eventName] || []).concat(handler);
}

EventEmitter.prototype.emit = function(eventName){
	var i, args = Array.prototype.slice.call(arguments, 1), // remove eventName from arguments, and make it an array
		listeners = this._eventListeners[eventName];
	for (i in listeners)
		listeners[i].apply(null, args);
}

/**
 * Inherit the prototype methods from one constructor into another. (from Node.js)
 *
 * The Function.prototype.inherits from lang.js rewritten as a standalone
 * function (not on Function.prototype). NOTE: If this file is to be loaded
 * during bootstrapping this function needs to be rewritten using some native
 * functions as prototype setup using normal JavaScript does not work as
 * expected during bootstrapping (see mirror.js in r114903).
 *
 * @param {function} ctor Constructor function which needs to inherit the
 *     prototype.
 * @param {function} superCtor Constructor function to inherit prototype from.
 */
function inherits(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};

/**
 * Plays a sequence of streamed audio/video tracks by embedding the corresponding players
 *
 * Events:
 * - "onError", {code,source}
 * - "onReady"
 * - "onPlay"
 * - "onPause"
 * - "onEnd"
 * - "onTrackInfo", track{}
 * - "onTrackChange", track{}
 * - "loadMore"
 */

function Playem(playemPrefs) {

	function Playem(playemPrefs) {

		EventEmitter.call(this);

		playemPrefs = playemPrefs || {};
		playemPrefs.loop = playemPrefs.hasOwnProperty("loop") ? playemPrefs.loop : true;

		var players = [], // instanciated Player classes, added by client
			i,
			exportedMethods,
			currentTrack = null,
			trackList = [],
			whenReady = null,
			playersToLoad = 0,
			progress = null,
			that = this,
			playTimeout = null,
			volume = 1;

		this.setPref = function(key, val){
			playemPrefs[key] = val;
		}

		function doWhenReady(player, fct) {
			var interval = null;
			function poll(){
				if (player.isReady && interval) {
					clearInterval(interval);
					fct();
				}
				else
					console.warn("PLAYEM waiting for", player.label, "...");
			}
			if (player.isReady)
				setTimeout(fct);
			else
				interval = setInterval(poll, 1000);
		}

		function addTrack(metadata, url) {
			var track = {
				index: trackList.length,
				metadata: metadata || {}
			};
			if (url)
				track.url = url;
			trackList.push(track);
			return track;
		}

		function addTrackById(id, player, metadata) {
			if (id) {
				var track = addTrack(metadata);
				track.trackId = id;
				track.player = player;
				track.playerName = player.label.replace(/ /g, "_");
				return track;
				//console.log("added:", player.label, "track", id, track/*, metadata*/);
			}
			else
				throw new Error("no id provided");
		}

		function setVolume(vol) {
			volume = vol;
			callPlayerFct("setVolume", vol);
		}

		function stopTrack() {
			if (currentTrack) {
				callPlayerFct("stop");
				if (progress)
					clearInterval(progress);
			}
		}

		function playTrack(track) {
			//console.log("playTrack", track);
			stopTrack();
			currentTrack = track;
			delete currentTrack.trackPosition; // = null;
			delete currentTrack.trackDuration; // = null;
			that.emit("onTrackChange", track);
			if (!track.player)
				return that.emit("onError", {code:"unrecognized_track", source:"Playem", track:track});
			doWhenReady(track.player, function() {
				//console.log("playTrack #" + track.index + " (" + track.playerName+ ")", track);
				callPlayerFct("play", track.trackId);
				setVolume(volume);
				if (currentTrack.index == trackList.length-1)
					that.emit("loadMore");
				// if the track does not start playing within 7 seconds, skip to next track
				setPlayTimeout(function() {
					console.warn("PLAYEM TIMEOUT"); // => skipping to next song
					that.emit("onError", {code:"timeout", source:"Playem"});
					//exportedMethods.next();
				});
			});
		}

		function setPlayTimeout(handler) {
			if (playTimeout)
				clearTimeout(playTimeout);
			playTimeout = !handler ? null : setTimeout(handler, PLAY_TIMEOUT);
		}

		function callPlayerFct(fctName, param){
			try {
				return currentTrack.player[fctName](param);
			}
			catch(e) {
				console.warn("Player call error", fctName, e, e.stack);
			}
		}

		// functions that are called by players => to propagate to client
		function createEventHandlers (playemFunctions) {
			var eventHandlers = {
				onApiReady: function(player){
					//console.log(player.label + " api ready");
					if (whenReady && player == whenReady.player)
						whenReady.fct();
					if (0 == --playersToLoad)
						that.emit("onReady");
				},
				onEmbedReady: function(player) {
					//console.log("embed ready");
					setVolume(volume);
				},
				onBuffering: function(player) {
					setTimeout(function() {
						setPlayTimeout();
						that.emit("onBuffering");
					});
				},
				onPlaying: function(player) {
					//console.log(player.label + ".onPlaying");
					//setPlayTimeout(); // removed because soundcloud sends a "onPlaying" event, even for not authorized tracks
					setVolume(volume);
					setTimeout(function() {
						that.emit("onPlay");
					}, 1);
					if (player.trackInfo && player.trackInfo.duration)
						eventHandlers.onTrackInfo({
							position: player.trackInfo.position || 0,
							duration: player.trackInfo.duration
						});

					if (progress)
						clearInterval(progress);

					if (player.getTrackPosition) {
						//var that = eventHandlers; //this;
						progress = setInterval(function(){
							player.getTrackPosition(function(trackPos) {
								eventHandlers.onTrackInfo({
									position: trackPos,
									duration: player.trackInfo.duration || currentTrack.trackDuration
								});
							});
						}, 1000);
					}
				},
				onTrackInfo: function(trackInfo) {
					//console.log("ontrackinfo", trackInfo, currentTrack);
					if (currentTrack && trackInfo) {
						if (trackInfo.duration) {
							currentTrack.trackDuration = trackInfo.duration;
							setPlayTimeout();
						}
						if (trackInfo.position)
							currentTrack.trackPosition = trackInfo.position;
					}
					that.emit("onTrackInfo", currentTrack);
				},
				onPaused: function(player) {
					//console.log(player.label + ".onPaused");
					setPlayTimeout();
					if (progress)
						clearInterval(progress);
					progress = null;
					//if (!avoidPauseEventPropagation)
					//	that.emit("onPause");
					//avoidPauseEventPropagation = false;
				},
				onEnded: function(player) {
					//console.log(player.label + ".onEnded");
					stopTrack();
					that.emit("onEnd");
					playemFunctions.next();
				},
				onError: function(player, error) {
					console.error(player.label + " error:", ((error || {}).exception || error || {}).stack || error);
					setPlayTimeout();
					that.emit("onError", error);
				}
			};
			// handlers will only be triggered is their associated player is currently active
			["onEmbedReady", "onBuffering", "onPlaying", "onPaused", "onEnded", "onError"].map(function (evt){
				var fct = eventHandlers[evt];
				eventHandlers[evt] = function(player, x){
					if (player == currentTrack.player)
						return fct(player, x);
					else if (evt != "onEmbedReady")
						console.warn("ignore event:", evt, "from", player, "instead of:", currentTrack.player);
				};
			});
			return eventHandlers;
		}

		// exported methods, mostly wrappers to Players' methods
		exportedMethods = {
			addPlayer: function (playerClass, vars) {
				playersToLoad++;
				var player = new playerClass(createEventHandlers(this, vars), vars);
				players.push(player);
				return player;
			},
			getQueue: function() {
				return trackList;
			},
			clearQueue: function() {
				trackList = [];
			},
			addTrackByUrl: function(url, metadata) {
				var p, player, eid;
				for (p=0; p<players.length; ++p) {
					player = players[p];
					//console.log("test ", player.label, eid);
					eid = player.getEid(url);
					if (eid)
						return addTrackById(eid, player, metadata);
				}
				return addTrack(metadata, url);
			},
			play: function(i) {
				playTrack(i != undefined ? trackList[i] : currentTrack || trackList[0]);
			},
			pause: function() {
				callPlayerFct("pause");
				that.emit("onPause");
			},
			stop: stopTrack,
			resume: function() {
				callPlayerFct("resume");
			},
			next: function() {
				if (playemPrefs.loop || currentTrack.index + 1 < trackList.length)
					playTrack(trackList[(currentTrack.index + 1) % trackList.length]);
			},
			prev: function() {
				playTrack(trackList[(trackList.length + currentTrack.index - 1) % trackList.length]);
			},
			seekTo: function(pos) {
				if ((currentTrack || {}).trackDuration)
					callPlayerFct("setTrackPosition", pos * currentTrack.trackDuration);
			},
			setVolume: setVolume
		};
		//return exportedMethods;
		for (i in exportedMethods)
			this[i] = exportedMethods[i];
	}

	inherits(Playem, EventEmitter);

	return new Playem();
};

<|endoftext|>


<commit_before>chorus.Mixins.ServerErrors = {
   serverErrorMessages: function() {
        var output = [];
        if (!this.serverErrors) { return output; }

        var that = this;
        if (this.serverErrors.fields) {
            _.each(this.serverErrors.fields, function(errors, field) {
                _.each(errors, function(context, error) {
                    var fullKey = "field_error." + field + "." + error,
                        genericKey = "field_error." + error,
                        message;

                    var message = that.translateError(fullKey, context);

                    if(!message) {
                        context.field = _.humanize(field);
                        message = that.translateError(genericKey, context);
                    }

                    output.push(message)
                })
            })
        } else if (this.serverErrors.record) {
            var key = "record_error." + this.serverErrors.record;

            output = [this.translateError(key) || this.serverErrors.record];
        }

        return output;
    },

    serverErrorMessage: function() {
        return this.serverErrorMessages().join("\n");
    },

    translateError: function(key, context) {
        if (I18n.lookup(key)) {
            return t(key, context)
        }
    }
};
<commit_msg>Fix broken refactor<commit_after>chorus.Mixins.ServerErrors = {
   serverErrorMessages: function() {
        var output = [];
        if (!this.serverErrors) { return output; }

        if (this.serverErrors.fields) {
            _.each(this.serverErrors.fields, function(errors, field) {
                _.each(errors, function(context, error) {
                    var fullKey = "field_error." + field + "." + error,
                        genericKey = "field_error." + error,
                        message;

                    if (I18n.lookup(fullKey)) {
                        message = t(fullKey, context);
                    } else {
                        context.field = _.humanize(field);
                        message = t(genericKey, context);
                    }

                    output.push(message);
                })
            })
        } else if (this.serverErrors.record) {
            var fullKey = "record_error." + this.serverErrors.record;

            if (I18n.lookup(fullKey)) {
                output = [t(fullKey)];
            }
        }

        return output;
    },

    serverErrorMessage: function() {
        return this.serverErrorMessages().join("\n");
    }
};
<|endoftext|>