<commit_before>/**
 * PlaylistController
 *
 * @description :: Server-side logic for managing Playlists
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

var GS  = require('machinepack-grooveshark');
var Zip = require('machinepack-zip');

module.exports = {

  downloadSong: function(req, res){
    var params = req.validator([{name: 'string', artist: 'string'}]);
    if(!params) return null;
    params.path = Globals.path + '/' +  req.session.user;

    GS.downloadSongByNameAndArtist({
      name  : params.name,
      artist: params.artist,
      path  : params.path
    }).exec({

      error: function (err){
        return res.send(400, err);
      },

      notFound: function (){
        return res.notFound();
      },

      downloadLimitExceded: function (){
        return res.forbidden('Download limit exceded');
      },

      success: function (song){
        var fs = require('fs');
        var stat = fs.statSync(song);
        res.writeHead(200, {
          'Content-Type'       : 'audio/mpeg',
          'Content-Length'     : stat.size,
          'Content-disposition': 'attachment; filename=' + params.name + '.mp3'
        });

        var stream = fs.createReadStream(song);
        stream.pipe(res);
        stream.on('end', function(){
          fs.unlink(song, function(err){
            if(err) sails.log.error('Error removing song: ', song);
          });
        });
      }

    });
  },

  downloadPlaylistSafe: function(req, res){
    var params = req.validator([{playlist: 'string'}]);
    if(!params) return null;
    var user = req.session.user;
    params.path = Globals.path + '/' +  user + '/' + params.playlist;

    Playlist.create({groovesharkId: params.playlist, user: user})
    .exec(function(err, playlist){
      if(err) return res.serverError(err);

      GS.downloadPlaylistSave({
        id  : params.playlist,
        path: params.path
      }).exec({

        error: function (err){
          sails.log.error('Playlist Error:', err);
          // TODO: Send email with the error
          Playlist.update(playlist.id, {state: 'unknow error'}).exec(function(){});
        },

        notFound: function (){
          var id = req.session.user;
          sails.sockets.emit(id, 'playlistNotFound', {err: 'Playlist not found'});
          Playlist.update(playlist.id, {state: 'not found'}).exec(function(){});
        },

        downloadLimitExceded: function (){
          sails.log.error('Error: Not found playlist');
          var id  = req.session.user;
          var err = 'Download size exceded, please try again later';
          sails.sockets.emit(id, 'downloadExceded', {err: 'Playlist not found'});
          Playlist.update(playlist.id, {state: 'banned'}).exec(function(){});
        },

        success: function (){
          var destination = params.path + '.zip';
          return _compressAndSendLink(params.path, destination, playlist.id, user);
        }

      });

      return res.ok();

    });

  },

  downloadZip: function(req, res){
    if(!req.param('token')) return res.badRequest();
    Playlist.findOne({token: req.param('token')}).exec(function(err, playlist){
      if(err) return res.serverError();
      if(!playlist) return res.notFound();

      var fs = require('fs');
      if(!fs.existsSync(playlist.zipUrl)) return res.notFound();
      var stat = fs.statSync(playlist.zipUrl);
      res.writeHead(200, {
        'Content-Type'       : 'application/zip, application/octet-stream',
        'Content-Length'     : stat.size,
        'Content-disposition': 'attachment; filename=' + playlist.groovesharkId + '.zip'
      });

      var stream = fs.createReadStream(playlist.zipUrl);
      stream.pipe(res);
      stream.on('end', function(){
        fs.unlink(playlist.zipUrl, function(err){
          if(err) sails.log.error('Error removing zipUrl: ', playlist.zipUrl);
        });
      });
    });
  }

};

var _compressAndSendLink = function(source, destination, playlist, user){
  Zip.zip({
    sources: [source],
    destination: destination,
  }).exec({

    error: function (err){
      sails.sockets.emit(user, 'zipError', {err: 'Error compressing'});
      //TODO: Send email
      sails.log.error('Error Zipping');
    },

    success: function (result){
      //sails.sockets.emit(user, 'playlistDownloaded', {link: destination});
      return _removeSongs(source, destination, playlist, user);
    }

  });
};

var _removeSongs = function(source, destination, playlist, user){
  Playlist.update(playlist, {state: 'completed', zipUrl: destination})
  .exec(function(err, playlist){
    require('fs-extra').remove(source, function(err) {
      if (err) return console.error(err);
    })
  });
};
<commit_msg>Send proper error message via sockets<commit_after>/**
 * PlaylistController
 *
 * @description :: Server-side logic for managing Playlists
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

var GS  = require('machinepack-grooveshark');
var Zip = require('machinepack-zip');

module.exports = {

  downloadSong: function(req, res){
    var params = req.validator([{name: 'string', artist: 'string'}]);
    if(!params) return null;
    params.path = Globals.path + '/' +  req.session.user;

    GS.downloadSongByNameAndArtist({
      name  : params.name,
      artist: params.artist,
      path  : params.path
    }).exec({

      error: function (err){
        return res.send(400, err);
      },

      notFound: function (){
        return res.notFound();
      },

      downloadLimitExceded: function (){
        return res.forbidden('Download limit exceded');
      },

      success: function (song){
        var fs = require('fs');
        var stat = fs.statSync(song);
        res.writeHead(200, {
          'Content-Type'       : 'audio/mpeg',
          'Content-Length'     : stat.size,
          'Content-disposition': 'attachment; filename=' + params.name + '.mp3'
        });

        var stream = fs.createReadStream(song);
        stream.pipe(res);
        stream.on('end', function(){
          fs.unlink(song, function(err){
            if(err) sails.log.error('Error removing song: ', song);
          });
        });
      }

    });
  },

  downloadPlaylistSafe: function(req, res){
    var params = req.validator([{playlist: 'string'}]);
    if(!params) return null;
    var user = req.session.user;
    params.path = Globals.path + '/' +  user + '/' + params.playlist;

    Playlist.create({groovesharkId: params.playlist, user: user})
    .exec(function(err, playlist){
      if(err) return res.serverError(err);

      GS.downloadPlaylistSave({
        id  : params.playlist,
        path: params.path
      }).exec({

        error: function (err){
          sails.log.error('Playlist Error:', err);
          // TODO: Send email with the error
          Playlist.update(playlist.id, {state: 'unknow error'}).exec(function(){});
        },

        notFound: function (){
          var id = req.session.user;
          sails.sockets.emit(id, 'playlistNotFound', {err: 'Playlist not found'});
          Playlist.update(playlist.id, {state: 'not found'}).exec(function(){});
        },

        downloadLimitExceded: function (){
          sails.log.error('Error: Not found playlist');
          var id  = req.session.user;
          var err = 'Download size exceded, please try again later';
          sails.sockets.emit(id, 'downloadExceded', {err: err});
          Playlist.update(playlist.id, {state: 'banned'}).exec(function(){});
        },

        success: function (){
          var destination = params.path + '.zip';
          return _compressAndSendLink(params.path, destination, playlist.id, user);
        }

      });

      return res.ok();

    });

  },

  downloadZip: function(req, res){
    if(!req.param('token')) return res.badRequest();
    Playlist.findOne({token: req.param('token')}).exec(function(err, playlist){
      if(err) return res.serverError();
      if(!playlist) return res.notFound();

      var fs = require('fs');
      if(!fs.existsSync(playlist.zipUrl)) return res.notFound();
      var stat = fs.statSync(playlist.zipUrl);
      res.writeHead(200, {
        'Content-Type'       : 'application/zip, application/octet-stream',
        'Content-Length'     : stat.size,
        'Content-disposition': 'attachment; filename=' + playlist.groovesharkId + '.zip'
      });

      var stream = fs.createReadStream(playlist.zipUrl);
      stream.pipe(res);
      stream.on('end', function(){
        fs.unlink(playlist.zipUrl, function(err){
          if(err) sails.log.error('Error removing zipUrl: ', playlist.zipUrl);
        });
      });
    });
  }

};

var _compressAndSendLink = function(source, destination, playlist, user){
  Zip.zip({
    sources: [source],
    destination: destination,
  }).exec({

    error: function (err){
      sails.sockets.emit(user, 'zipError', {err: 'Error compressing'});
      //TODO: Send email
      sails.log.error('Error Zipping');
    },

    success: function (result){
      //sails.sockets.emit(user, 'playlistDownloaded', {link: destination});
      return _removeSongs(source, destination, playlist, user);
    }

  });
};

var _removeSongs = function(source, destination, playlist, user){
  Playlist.update(playlist, {state: 'completed', zipUrl: destination})
  .exec(function(err, playlist){
    require('fs-extra').remove(source, function(err) {
      if (err) return console.error(err);
    })
  });
};
<|endoftext|>


<commit_before>(function($) {
  $.fn.tweet = function(o){
    var s = {
      username: ["seaofclouds"],              // [string]   required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"]
      avatar_size: null,                      // [integer]  height and width of avatar if displayed (48px max)
      count: 1,                               // [integer]  how many tweets to display?
      intro_text: null,                       // [string]   do you want text BEFORE your your tweets?
      outro_text: null,                       // [string]   do you want text AFTER your tweets?
      join_text:  null,                       // [string]   optional text in between date and tweet, try setting to "auto"
      auto_join_text_default: "i said,",      // [string]   auto text for non verb: "i said" bullocks
      auto_join_text_ed: "i",                 // [string]   auto text for past tense: "i" surfed
      auto_join_text_ing: "i am",             // [string]   auto tense for present tense: "i was" surfing
      auto_join_text_reply: "i replied to",   // [string]   auto tense for replies: "i replied to" @someone "with"
      auto_join_text_url: "i was looking at", // [string]   auto tense for urls: "i was looking at" http:...
      loading_text: null                      // [string]   optional loading text, displayed while tweets load
    };

    function relative_time(time_value) {
      var parsed_date = Date.parse(time_value);
      var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
      var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
      if(delta < 60) {
      return 'less than a minute ago';
      } else if(delta < 120) {
      return 'about a minute ago';
      } else if(delta < (45*60)) {
      return (parseInt(delta / 60)).toString() + ' minutes ago';
      } else if(delta < (90*60)) {
      return 'about an hour ago';
      } else if(delta < (24*60*60)) {
      return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
      } else if(delta < (48*60*60)) {
      return '1 day ago';
      } else {
      return (parseInt(delta / 86400)).toString() + ' days ago';
      }
    }

    if(o) $.extend(s, o);
    return this.each(function(){
      var list = $('
').appendTo(this);
      var intro = '
'+s.intro_text+'
'
      var outro = '
'+s.outro_text+'
'
      var loading = $('
'+s.loading_text+'
');
      if(typeof(s.username) == "string"){
        s.username = [s.username];
      }
      var url = 'http://search.twitter.com/search.json?q=from:'+s.username.join('%20OR%20from:')+'&rpp='+s.count+'&callback=?';
      if (s.loading_text) $(this).append(loading);
      $.getJSON(url,  function(data){
        if (s.loading_text) loading.remove();
        if (s.intro_text) list.before(intro);
        $.each(data.results, function(i,item){
          // audo join text based on verb tense and content
          if (s.join_text == "auto") {
            if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) {
              var join_text = s.auto_join_text_reply;
            } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
              var join_text = s.auto_join_text_url;
            } else if (item.text.match(/^((\w+ed)|just) .*/im)) {
              var join_text = s.auto_join_text_ed;
            } else if (item.text.match(/^(\w*ing) .*/i)) {
              var join_text = s.auto_join_text_ing;
            } else {
              var join_text = s.auto_join_text_default;
            }
          } else {
            var join_text = s.join_text;
          };
          var join = ' '+join_text+' ';

          list.append('
'+(s.avatar_size ? '' : '')+''+relative_time(item.created_at)+''+ ((s.join_text) ? join : ' ') + '' + item.text.replace(/(\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&#\?\/.=]+)/gi, '$1').replace(/[\@]+([A-Za-z0-9-_]+)/gi, '@$1').replace(/ [\#]+([A-Za-z0-9-_]+) /gi, ' #$1 ').replace(/[<]+[3]/gi, "<tt class='heart'>♥</tt>") + '
');
        });
        $('.tweet_list li:odd').addClass('tweet_even');
        $('.tweet_list li:even').addClass('tweet_odd');
        $('.tweet_list li:first').addClass('tweet_first');
        $('.tweet_list li:last').addClass('tweet_last');
        if (s.outro_text) list.after(outro);
      });

    });

  };
})(jQuery);<commit_msg>apply query diff from Luke Redpath<commit_after>(function($) {
  $.fn.tweet = function(o){
    var s = {
      username: ["seaofclouds"],              // [string]   required, unless you want to display our tweets. :) it can be an array, just do ["username1","username2","etc"]
      avatar_size: null,                      // [integer]  height and width of avatar if displayed (48px max)
      count: 1,                               // [integer]  how many tweets to display?
      intro_text: null,                       // [string]   do you want text BEFORE your your tweets?
      outro_text: null,                       // [string]   do you want text AFTER your tweets?
      join_text:  null,                       // [string]   optional text in between date and tweet, try setting to "auto"
      auto_join_text_default: "i said,",      // [string]   auto text for non verb: "i said" bullocks
      auto_join_text_ed: "i",                 // [string]   auto text for past tense: "i" surfed
      auto_join_text_ing: "i am",             // [string]   auto tense for present tense: "i was" surfing
      auto_join_text_reply: "i replied to",   // [string]   auto tense for replies: "i replied to" @someone "with"
      auto_join_text_url: "i was looking at", // [string]   auto tense for urls: "i was looking at" http:...
      loading_text: null,                     // [string]   optional loading text, displayed while tweets load
			query: null															// [string]   optional search query
    };

    function relative_time(time_value) {
      var parsed_date = Date.parse(time_value);
      var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
      var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
      if(delta < 60) {
      return 'less than a minute ago';
      } else if(delta < 120) {
      return 'about a minute ago';
      } else if(delta < (45*60)) {
      return (parseInt(delta / 60)).toString() + ' minutes ago';
      } else if(delta < (90*60)) {
      return 'about an hour ago';
      } else if(delta < (24*60*60)) {
      return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
      } else if(delta < (48*60*60)) {
      return '1 day ago';
      } else {
      return (parseInt(delta / 86400)).toString() + ' days ago';
      }
    }

    if(o) $.extend(s, o);
    return this.each(function(){
      var list = $('
').appendTo(this);
      var intro = '
'+s.intro_text+'
'
      var outro = '
'+s.outro_text+'
'
      var loading = $('
'+s.loading_text+'
');
      if(typeof(s.username) == "string"){
        s.username = [s.username];
      }
			var query = '';
			if(s.query) {
				query += 'q='+s.query;
			}
			query += '&q=from:'+s.username.join('%20OR%20from:');
      var url = 'http://search.twitter.com/search.json?&'+query+'&rpp='+s.count+'&callback=?';
      if (s.loading_text) $(this).append(loading);
			console.log(url);
      $.getJSON(url,  function(data){
        if (s.loading_text) loading.remove();
        if (s.intro_text) list.before(intro);
        $.each(data.results, function(i,item){
          // audo join text based on verb tense and content
          if (s.join_text == "auto") {
            if (item.text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) {
              var join_text = s.auto_join_text_reply;
            } else if (item.text.match(/(^\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+) .*/i)) {
              var join_text = s.auto_join_text_url;
            } else if (item.text.match(/^((\w+ed)|just) .*/im)) {
              var join_text = s.auto_join_text_ed;
            } else if (item.text.match(/^(\w*ing) .*/i)) {
              var join_text = s.auto_join_text_ing;
            } else {
              var join_text = s.auto_join_text_default;
            }
          } else {
            var join_text = s.join_text;
          };
          var join = ' '+join_text+' ';

          list.append('
'+(s.avatar_size ? '' : '')+''+relative_time(item.created_at)+''+ ((s.join_text) ? join : ' ') + '' + item.text.replace(/(\w+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&#\?\/.=]+)/gi, '$1').replace(/[\@]+([A-Za-z0-9-_]+)/gi, '@$1').replace(/ [\#]+([A-Za-z0-9-_]+) /gi, ' #$1 ').replace(/[<]+[3]/gi, "<tt class='heart'>♥</tt>") + '
');
        });
        $('.tweet_list li:odd').addClass('tweet_even');
        $('.tweet_list li:even').addClass('tweet_odd');
        $('.tweet_list li:first').addClass('tweet_first');
        $('.tweet_list li:last').addClass('tweet_last');
        if (s.outro_text) list.after(outro);
      });

    });

  };
})(jQuery);<|endoftext|>


<commit_before>var parseURL = require("./parseURL");
require("../efront/console");
var test = function (url, key, value) {
    var parsed = parseURL(url);
    if (parsed[key] !== value) console.log(parsed), console.fail(`url:${url}, key:${key}, expect:${value}, result:${parsed[key]}`);
    else console.pass(`url:${url}, key:${key}, expect:${value}, result:${parsed[key]}`);
};

test('http://efront.cc/kugou', 'pathname', '/kugou')
test('http://efront.cc/kugou?a', 'path', '/kugou?a')
test('http://yunxu1019@live.cn@github.com/?a', 'username', 'yunxu1019@live.cn')
test('localhost', 'host', 'localhost')
test('localhost:80', 'port', '80')
test('localhost:80/', 'port', '80')
test(':80', 'port', '80')
test('80', 'port', '80')
test('/80', 'pathname', '/80')
test('a80', 'host', 'a80')
test('a:80', 'host', 'a:80')
test('a:b:80', 'host', 'b:80')
test('a:b@a80', 'auth', 'a:b')
test('c:a:b@a80', 'auth', 'a:b')
test('c:d:a:b@a80', 'password', 'a:b')
test('localhost:', 'protocol', 'localhost:')
test('localhost:80', 'hostname', 'localhost')
test('http//:80', 'hostname', 'http')
test('http//:80', 'pathname', '//:80')
test('//h:80', 'host', 'h:80')
test('?80', 'path', '?80')
test('?80', 'search', '?80')
test('?80', 'query', '80')
test('#?80', 'hash', '#?80')
test("http://[fe80::caa:a647:ef1d:b4db]/", "host", "[fe80::caa:a647:ef1d:b4db]")
test("http://[::1]/", "host", "[::1]")
test("http://[::]/", "host", "[::]")
test("http://[::%12]/", "host", "[::%12]")
test("http://[::]:80/", "hostname", "[::]")
test("[::]:80/", "hostname", "[::]")
test("[fd64:f52:f52:f52:f52:f52:f52:97]", "hostname", "[fd64:f52:f52:f52:f52:f52:f52:97]")
test("./cluster-opt.html", "pathname", "./cluster-opt.html")
test(":cluster-opt.html", "pathname", ":cluster-opt.html")
test("d:/cluster-opt.html", "pathname", "d:/cluster-opt.html")
test("d:\\cluster-opt.html", "pathname", "d:\\cluster-opt.html")
test("ftp:\\\\cluster-opt.html", "host", "cluster-opt.html")
test("\\\\cluster-opt.html", "host", "cluster-opt.html")
test("https://a:b@測試?abc#foo", "host", "測試")<commit_msg>增加两条测试用例<commit_after>var parseURL = require("./parseURL");
require("../efront/console");
var test = function (url, key, value) {
    var parsed = parseURL(url);
    if (parsed[key] !== value) console.log(parsed), console.fail(`url:${url}, key:${key}, expect:${value}, result:${parsed[key]}`);
    else console.pass(`url:${url}, key:${key}, expect:${value}, result:${parsed[key]}`);
};

test('http://efront.cc/kugou', 'pathname', '/kugou')
test('http://efront.cc/kugou?a', 'path', '/kugou?a')
test('http://yunxu1019@live.cn@github.com/?a', 'username', 'yunxu1019@live.cn')
test('localhost', 'host', 'localhost')
test('localhost:80', 'port', '80')
test('localhost:80/', 'port', '80')
test('efront.cc', 'host', 'efront.cc')
test('127.0.0.1', 'host', '127.0.0.1')
test(':80', 'port', '80')
test('80', 'port', '80')
test('/80', 'pathname', '/80')
test('a80', 'host', 'a80')
test('a:80', 'host', 'a:80')
test('a:b:80', 'host', 'b:80')
test('a:b@a80', 'auth', 'a:b')
test('c:a:b@a80', 'auth', 'a:b')
test('c:d:a:b@a80', 'password', 'a:b')
test('localhost:', 'protocol', 'localhost:')
test('localhost:80', 'hostname', 'localhost')
test('http//:80', 'hostname', 'http')
test('http//:80', 'pathname', '//:80')
test('//h:80', 'host', 'h:80')
test('?80', 'path', '?80')
test('?80', 'search', '?80')
test('?80', 'query', '80')
test('#?80', 'hash', '#?80')
test("http://[fe80::caa:a647:ef1d:b4db]/", "host", "[fe80::caa:a647:ef1d:b4db]")
test("http://[::1]/", "host", "[::1]")
test("http://[::]/", "host", "[::]")
test("http://[::%12]/", "host", "[::%12]")
test("http://[::]:80/", "hostname", "[::]")
test("[::]:80/", "hostname", "[::]")
test("[fd64:f52:f52:f52:f52:f52:f52:97]", "hostname", "[fd64:f52:f52:f52:f52:f52:f52:97]")
test("./cluster-opt.html", "pathname", "./cluster-opt.html")
test(":cluster-opt.html", "pathname", ":cluster-opt.html")
test("d:/cluster-opt.html", "pathname", "d:/cluster-opt.html")
test("d:\\cluster-opt.html", "pathname", "d:\\cluster-opt.html")
test("ftp:\\\\cluster-opt.html", "host", "cluster-opt.html")
test("\\\\cluster-opt.html", "host", "cluster-opt.html")
test("https://a:b@測試?abc#foo", "host", "測試")<|endoftext|>


<commit_before>(function() {
    // Create the connector object
    var myConnector = tableau.makeConnector();

    // Define the schema
    myConnector.getSchema = function(schemaCallback) {
        var cols = [{
            id: "npc",
            alias: "npc",
            dataType: tableau.dataTypeEnum.string
        }];

        var tableSchema = {
            id: "riversideCrime",
            alias: "Riverside Crime JSON entries",
            columns: cols
        };

        schemaCallback([tableSchema]);
    };

    // Download the data
    myConnector.getData = function(table, doneCallback) {
        $.getJSON("https://riversideca.gov/transparency/data/dataset/json/27", function(resp) {
            var feat = resp.features,
                tableData = [];

            // Iterate over the JSON object
            for (var i = 0, len = feat.length; i < len; i++) {
                tableData.push({

                    "npc": data[i][npc],

                });
            }

            table.appendRows(tableData);
            doneCallback();
        });
    };

    tableau.registerConnector(myConnector);

    // Create event listeners for when the user submits the form
    $(document).ready(function() {
        $("#submitButton").click(function() {
            tableau.connectionName = "Riverside Crime Report"; // This will be the data source name in Tableau
            tableau.submit(); // This sends the connector object to Tableau
        });
    });
})();
<commit_msg>Update RivCrimeReport.js<commit_after>(function() {
    // Create the connector object
    var myConnector = tableau.makeConnector();

    // Define the schema
    myConnector.getSchema = function(schemaCallback) {
        var cols = [{
            id: "npc",
            alias: "npc",
            dataType: tableau.dataTypeEnum.string
        }];

        var tableSchema = {
            id: "riversideCrime",
            alias: "Riverside Crime JSON entries",
            columns: cols
        };

        schemaCallback([tableSchema]);
    };

    // Download the data
    myConnector.getData = function(table, doneCallback) {
        $.getJSON("https://riversideca.gov/transparency/data/dataset/json/27", function(resp) {
            var feat = resp.features,
                tableData = [];

            // Iterate over the JSON object
            for (var i = 0, len = feat.length; i < len; i++) {
                tableData.push({

                    "npc": feat[i].npc,

                });
            }

            table.appendRows(tableData);
            doneCallback();
        });
    };

    tableau.registerConnector(myConnector);

    // Create event listeners for when the user submits the form
    $(document).ready(function() {
        $("#submitButton").click(function() {
            tableau.connectionName = "Riverside Crime Report"; // This will be the data source name in Tableau
            tableau.submit(); // This sends the connector object to Tableau
        });
    });
})();
<|endoftext|>


<commit_before>Package('Karaoke.Views', {
	Catalog : new Class({
		Extends : Sapphire.View,

		initialize : function()
		{
			this.parent();
			this.selected = 0;
			this.songs = [];

//			$('.catalog-container').nanoScroller({ alwaysVisible: true });

			this.listener = KARAOKE.input.listen('inputDown', this.onInputDown.bind(this));
			this.container = $('#catalog-list');
//			this.container.on('scrollstop', this.onScrolled.bind(this));

			this.tvCanvas = $('#tv-canvas')[0];
			this.tvContext = this.tvCanvas.getContext('2d'),

			this.previewCanvas = $('#preview-canvas')[0];
			this.previewContext = this.previewCanvas.getContext('2d'),

			setInterval(this.onTick.bind(this), 10);
			this.setupStatic();
			this.cdgPlaying = false;
			this.lastInput = Date.now();
			this.paused = false;
		},

		renderStatic : function()
		{
			this.tvContext.putImageData(this.samples[Math.floor(this.sampleIndex)], 0, 0);

			this.sampleIndex += 30 / this.FPS; // 1/FPS == 1 second
			if (this.sampleIndex >= this.samples.length) this.sampleIndex = 0;

			var grd = this.tvContext.createLinearGradient(0, this.scanOffsetY, 0, this.scanSize + this.scanOffsetY);

			grd.addColorStop(0, 'rgba(255,255,255,0)');
			grd.addColorStop(0.1, 'rgba(255,255,255,0)');
			grd.addColorStop(0.2, 'rgba(255,255,255,0.2)');
			grd.addColorStop(0.3, 'rgba(255,255,255,0.0)');
			grd.addColorStop(0.45, 'rgba(255,255,255,0.1)');
			grd.addColorStop(0.5, 'rgba(255,255,255,1.0)');
			grd.addColorStop(0.55, 'rgba(255,255,255,0.55)');
			grd.addColorStop(0.6, 'rgba(255,255,255,0.25)');
			//grd.addColorStop(0.8, 'rgba(255,255,255,0.15)');
			grd.addColorStop(1, 'rgba(255,255,255,0)');

			this.tvContext.fillStyle = grd;
			this.tvContext.fillRect(0, this.scanOffsetY, this.tvCanvas.width, this.scanSize + this.scanOffsetY);
			this.tvContext.globalCompositeOperation = "lighter";

			this.scanOffsetY += (this.tvCanvas.height / this.scanSpeed);
			if(this.scanOffsetY > this.tvCanvas.height) this.scanOffsetY = -(this.scanSize / 2);
		},

		setupStatic : function()
		{
			function interpolate(x, x0, y0, x1, y1) {
				return y0 + (y1 - y0)*((x - x0)/(x1 - x0));
			}

			function generateRandomSample(context, w, h) {
				var intensity = [];
				var random = 0;
				var factor = h / 50;

				var intensityCurve = [];
				for(var i = 0; i < Math.floor(h / factor) + factor; i++)
					intensityCurve.push(Math.floor(Math.random() * 15));

				for(var i = 0; i < h; i++) {
					var value = interpolate((i/factor), Math.floor(i / factor), intensityCurve[Math.floor(i / factor)], Math.floor(i / factor) + 1, intensityCurve[Math.floor(i / factor) + 1]);
					intensity.push(value);
				}

				var imageData = context.createImageData(w, h);
				for(var i = 0; i < (w * h); i++) {
					var k = i * 4;
					var color = Math.floor(36 * Math.random());
					// Optional: add an intensity curve to try to simulate scan lines
					color += intensity[Math.floor(i / w)];
					imageData.data[k] = imageData.data[k + 1] = imageData.data[k + 2] = color;
					imageData.data[k + 3] = 255;
				}
				return imageData;
			}

			this.samples = [],
			this.scaleFactor = 2.5; // Noise size
			this.sampleIndex = 0;
			this.scanOffsetY = 0;
			this.scanSize = 0;
			this.FPS = 50;
			this.scanSpeed = this.FPS * 15; // 15 seconds from top to bottom
			this.SAMPLE_COUNT = 10;
			this.showStatic = true;

			this.tvCanvas.width = this.tvCanvas.offsetWidth / this.scaleFactor;
			this.tvCanvas.height = this.tvCanvas.width / (this.tvCanvas.offsetWidth / this.tvCanvas.offsetHeight);
			this.scanSize = (this.tvCanvas.offsetHeight / this.scaleFactor) / 3;
			this.samples = []
			for (var i = 0; i < this.SAMPLE_COUNT; i++)
				this.samples.push(generateRandomSample(this.tvContext, this.tvCanvas.width, this.tvCanvas.height));
		},

		startCdg : function()
		{
			this.cdgStarted = Date.now();
			this.cdgPlaying = true;
			var name = this.songs[this.selected].name;
			var path = this.songs[this.selected].path;
			this.cdg = new Cdg(path, name);
			this.cdgCanvas = new CdgCanvas(this.cdg, this.previewCanvas);
			this.cdgCanvas.start();
			$('#preview-canvas').hide();
			$('#tv-canvas').hide();
		},

		stopCdg : function()
		{
			this.cdgPlaying = false;
			$('#tv-canvas').show();
		},

		renderCdg : function()
		{
			$('#preview-canvas').show();
			var now = Date.now();
			var timeOffset = now - this.cdgStarted;
			timeOffset = timeOffset * 8;
			var drew = this.cdgCanvas.updateSurface(timeOffset);
			if (!drew) this.startCdg();
		},

		pause : function()
		{
			this.paused = true;
			KARAOKE.input.remove('inputDown', this.listener);
		},

		resume : function()
		{
			this.listener = KARAOKE.input.listen('inputDown', this.onInputDown.bind(this));
			this.paused = false;
		},

		onTick : function()
		{
			if (this.paused) return;
			var now = Date.now();
			if (!this.cdgPlaying && now - this.lastInput > 2000) this.startCdg();
			else if (this.cdgPlaying && now - this.lastInput < 2000) this.stopCdg();
			else if (this.cdgPlaying) this.renderCdg();
			else this.renderStatic();
		},

		draw : function(songs)
		{

			songs.sort(function(s1, s2)
			{
				return s1.name.toLowerCase().localeCompare(s2.name.toLowerCase());
			});

			this.container.empty();
			this.songs = songs;
			var template;

			songs.each(function(song, index)
			{
				template = SAPPHIRE.templates.get('song-template');
				template.find('#song-name').text(song.name);
				template.attr('id', 'song-' + index);
				template.click(this.onSongSelect.bind(this, song));

				this.container.append(template);
			}, this);

			setTimeout(function()
			{
				var height = this.container.height();
				this.oneHeight = template.outerHeight();
				this.top = 0;
				this.itemsFit = Math.floor(height / this.oneHeight);
				this.drawSelected();
			}.bind(this), 1);
		},

		drawSelected : function()
		{
			$('.song-item').removeClass('selected');
			$('#song-' + this.selected).addClass('selected');
		},

		doScroll : function()
		{
			if (this.container.scrollTop() !== this.top * this.oneHeight)
			{
				this.container.scrollTop(this.top * this.oneHeight);
			}
		},

		checkScroll : function()
		{
			if (this.selected >= this.top + this.itemsFit)
			{
				this.top = this.selected - this.itemsFit / 2;
				this.top = Math.max(this.top, 0);

				this.doScroll();
			}
			else if (this.selected < this.top)
			{
				this.top = this.selected - this.itemsFit / 2;
				this.top = Math.max(this.top, 0);

				this.doScroll();
			}
		},

		up :function()
		{
			this.selected--;
			this.selected = Math.max(this.selected, 0);
			this.drawSelected();
			this.checkScroll();
		},

		down : function()
		{
			this.selected++;
			this.selected = Math.min(this.songs.length - 1, this.selected);
			this.drawSelected();
			this.checkScroll();
		},

		pageUp : function()
		{
			this.top -= this.itemsFit;
			this.top = Math.max(0, this.top);
			this.selected -= this.itemsFit;
			this.selected = Math.max(0, this.selected);
			this.drawSelected();
			this.doScroll();
		},

		pageDown : function()
		{
			this.top += this.itemsFit;
			this.top = Math.min(this.songs.length - this.itemsFit, this.top);
			this.selected += this.itemsFit;
			this.selected = Math.min(this.songs.length - 1, this.selected);
			this.drawSelected();
			this.doScroll();
		},

		onSongSelect : function(song)
		{
		},

		onScrolled : function()
		{
			var scrollTop = this.container.scrollTop();
			var top = Math.floor(Math.round(scrollTop / this.oneHeight));
			if (this.selected < top) this.selected = top;
			else if (this.selected > top + this.itemsFit) this.selected = top + this.itemsFit / 2;

			if (top === this.top) return;

			this.top = top;
			this.drawSelected();
			this.doScroll();
		},

		onInputDown : function(input)
		{
			this.lastInput = Date.now();
			var action = input.action;
			var data = input.data;
			switch(action)
			{
				case 'up':
					this.up();
					break;
				case 'down':
					this.down();
					break;
				case 'left':
					break;
				case 'right':
					break;
				case 'enter':
					this.fire('songSelect', this.songs[this.selected]);
					break;
				case 'select':
					this.fire('songSelect', this.songs[this.selected]);
					break;
				case 'menu':
					break;
				case 'page-up':
					this.pageUp();
					break;
				case 'page-down':
					this.pageDown();
					break;
				default:
					break;
			}
		}
	})
});
<commit_msg>- timing issue if the song list takes too long to load<commit_after>Package('Karaoke.Views', {
	Catalog : new Class({
		Extends : Sapphire.View,

		initialize : function()
		{
			this.parent();
			this.selected = 0;
			this.songs = [];

//			$('.catalog-container').nanoScroller({ alwaysVisible: true });

			this.listener = KARAOKE.input.listen('inputDown', this.onInputDown.bind(this));
			this.container = $('#catalog-list');
//			this.container.on('scrollstop', this.onScrolled.bind(this));

			this.tvCanvas = $('#tv-canvas')[0];
			this.tvContext = this.tvCanvas.getContext('2d'),

			this.previewCanvas = $('#preview-canvas')[0];
			this.previewContext = this.previewCanvas.getContext('2d'),

			setInterval(this.onTick.bind(this), 10);
			this.setupStatic();
			this.cdgPlaying = false;
			this.lastInput = Date.now();
			this.paused = false;
		},

		renderStatic : function()
		{
			this.tvContext.putImageData(this.samples[Math.floor(this.sampleIndex)], 0, 0);

			this.sampleIndex += 30 / this.FPS; // 1/FPS == 1 second
			if (this.sampleIndex >= this.samples.length) this.sampleIndex = 0;

			var grd = this.tvContext.createLinearGradient(0, this.scanOffsetY, 0, this.scanSize + this.scanOffsetY);

			grd.addColorStop(0, 'rgba(255,255,255,0)');
			grd.addColorStop(0.1, 'rgba(255,255,255,0)');
			grd.addColorStop(0.2, 'rgba(255,255,255,0.2)');
			grd.addColorStop(0.3, 'rgba(255,255,255,0.0)');
			grd.addColorStop(0.45, 'rgba(255,255,255,0.1)');
			grd.addColorStop(0.5, 'rgba(255,255,255,1.0)');
			grd.addColorStop(0.55, 'rgba(255,255,255,0.55)');
			grd.addColorStop(0.6, 'rgba(255,255,255,0.25)');
			//grd.addColorStop(0.8, 'rgba(255,255,255,0.15)');
			grd.addColorStop(1, 'rgba(255,255,255,0)');

			this.tvContext.fillStyle = grd;
			this.tvContext.fillRect(0, this.scanOffsetY, this.tvCanvas.width, this.scanSize + this.scanOffsetY);
			this.tvContext.globalCompositeOperation = "lighter";

			this.scanOffsetY += (this.tvCanvas.height / this.scanSpeed);
			if(this.scanOffsetY > this.tvCanvas.height) this.scanOffsetY = -(this.scanSize / 2);
		},

		setupStatic : function()
		{
			function interpolate(x, x0, y0, x1, y1) {
				return y0 + (y1 - y0)*((x - x0)/(x1 - x0));
			}

			function generateRandomSample(context, w, h) {
				var intensity = [];
				var random = 0;
				var factor = h / 50;

				var intensityCurve = [];
				for(var i = 0; i < Math.floor(h / factor) + factor; i++)
					intensityCurve.push(Math.floor(Math.random() * 15));

				for(var i = 0; i < h; i++) {
					var value = interpolate((i/factor), Math.floor(i / factor), intensityCurve[Math.floor(i / factor)], Math.floor(i / factor) + 1, intensityCurve[Math.floor(i / factor) + 1]);
					intensity.push(value);
				}

				var imageData = context.createImageData(w, h);
				for(var i = 0; i < (w * h); i++) {
					var k = i * 4;
					var color = Math.floor(36 * Math.random());
					// Optional: add an intensity curve to try to simulate scan lines
					color += intensity[Math.floor(i / w)];
					imageData.data[k] = imageData.data[k + 1] = imageData.data[k + 2] = color;
					imageData.data[k + 3] = 255;
				}
				return imageData;
			}

			this.samples = [],
			this.scaleFactor = 2.5; // Noise size
			this.sampleIndex = 0;
			this.scanOffsetY = 0;
			this.scanSize = 0;
			this.FPS = 50;
			this.scanSpeed = this.FPS * 15; // 15 seconds from top to bottom
			this.SAMPLE_COUNT = 10;
			this.showStatic = true;

			this.tvCanvas.width = this.tvCanvas.offsetWidth / this.scaleFactor;
			this.tvCanvas.height = this.tvCanvas.width / (this.tvCanvas.offsetWidth / this.tvCanvas.offsetHeight);
			this.scanSize = (this.tvCanvas.offsetHeight / this.scaleFactor) / 3;
			this.samples = []
			for (var i = 0; i < this.SAMPLE_COUNT; i++)
				this.samples.push(generateRandomSample(this.tvContext, this.tvCanvas.width, this.tvCanvas.height));
		},

		startCdg : function()
		{
			if (!this.songs || this.songs.length <= this.selected) return;
			this.cdgStarted = Date.now();
			this.cdgPlaying = true;
			var name = this.songs[this.selected].name;
			var path = this.songs[this.selected].path;
			this.cdg = new Cdg(path, name);
			this.cdgCanvas = new CdgCanvas(this.cdg, this.previewCanvas);
			this.cdgCanvas.start();
			$('#preview-canvas').hide();
			$('#tv-canvas').hide();
		},

		stopCdg : function()
		{
			this.cdgPlaying = false;
			$('#tv-canvas').show();
		},

		renderCdg : function()
		{
			$('#preview-canvas').show();
			var now = Date.now();
			var timeOffset = now - this.cdgStarted;
			timeOffset = timeOffset * 8;
			var drew = this.cdgCanvas.updateSurface(timeOffset);
			if (!drew) this.startCdg();
		},

		pause : function()
		{
			this.paused = true;
			KARAOKE.input.remove('inputDown', this.listener);
		},

		resume : function()
		{
			this.listener = KARAOKE.input.listen('inputDown', this.onInputDown.bind(this));
			this.paused = false;
		},

		onTick : function()
		{
			if (this.paused) return;
			var now = Date.now();
			if (!this.cdgPlaying && now - this.lastInput > 2000) this.startCdg();
			else if (this.cdgPlaying && now - this.lastInput < 2000) this.stopCdg();
			else if (this.cdgPlaying) this.renderCdg();
			else this.renderStatic();
		},

		draw : function(songs)
		{
			this.paused = false;
			songs.sort(function(s1, s2)
			{
				return s1.name.toLowerCase().localeCompare(s2.name.toLowerCase());
			});

			this.container.empty();
			this.songs = songs;
			var template;

			songs.each(function(song, index)
			{
				template = SAPPHIRE.templates.get('song-template');
				template.find('#song-name').text(song.name);
				template.attr('id', 'song-' + index);
				template.click(this.onSongSelect.bind(this, song));

				this.container.append(template);
			}, this);

			setTimeout(function()
			{
				var height = this.container.height();
				this.oneHeight = template.outerHeight();
				this.top = 0;
				this.itemsFit = Math.floor(height / this.oneHeight);
				this.drawSelected();
			}.bind(this), 1);
		},

		drawSelected : function()
		{
			$('.song-item').removeClass('selected');
			$('#song-' + this.selected).addClass('selected');
		},

		doScroll : function()
		{
			if (this.container.scrollTop() !== this.top * this.oneHeight)
			{
				this.container.scrollTop(this.top * this.oneHeight);
			}
		},

		checkScroll : function()
		{
			if (this.selected >= this.top + this.itemsFit)
			{
				this.top = this.selected - this.itemsFit / 2;
				this.top = Math.max(this.top, 0);

				this.doScroll();
			}
			else if (this.selected < this.top)
			{
				this.top = this.selected - this.itemsFit / 2;
				this.top = Math.max(this.top, 0);

				this.doScroll();
			}
		},

		up :function()
		{
			this.selected--;
			this.selected = Math.max(this.selected, 0);
			this.drawSelected();
			this.checkScroll();
		},

		down : function()
		{
			this.selected++;
			this.selected = Math.min(this.songs.length - 1, this.selected);
			this.drawSelected();
			this.checkScroll();
		},

		pageUp : function()
		{
			this.top -= this.itemsFit;
			this.top = Math.max(0, this.top);
			this.selected -= this.itemsFit;
			this.selected = Math.max(0, this.selected);
			this.drawSelected();
			this.doScroll();
		},

		pageDown : function()
		{
			this.top += this.itemsFit;
			this.top = Math.min(this.songs.length - this.itemsFit, this.top);
			this.selected += this.itemsFit;
			this.selected = Math.min(this.songs.length - 1, this.selected);
			this.drawSelected();
			this.doScroll();
		},

		onSongSelect : function(song)
		{
		},

		onScrolled : function()
		{
			var scrollTop = this.container.scrollTop();
			var top = Math.floor(Math.round(scrollTop / this.oneHeight));
			if (this.selected < top) this.selected = top;
			else if (this.selected > top + this.itemsFit) this.selected = top + this.itemsFit / 2;

			if (top === this.top) return;

			this.top = top;
			this.drawSelected();
			this.doScroll();
		},

		onInputDown : function(input)
		{
			this.lastInput = Date.now();
			var action = input.action;
			var data = input.data;
			switch(action)
			{
				case 'up':
					this.up();
					break;
				case 'down':
					this.down();
					break;
				case 'left':
					break;
				case 'right':
					break;
				case 'enter':
					this.fire('songSelect', this.songs[this.selected]);
					break;
				case 'select':
					this.fire('songSelect', this.songs[this.selected]);
					break;
				case 'menu':
					break;
				case 'page-up':
					this.pageUp();
					break;
				case 'page-down':
					this.pageDown();
					break;
				default:
					break;
			}
		}
	})
});
<|endoftext|>


<commit_before>Template.discussion.onCreated(function() {
	subs.subscribe('discussion', this.data._id);

	this.count = new ReactiveVar(0);
	this.limit = new ReactiveVar(3);
});

Template.discussion.helpers({
	posts: function() {
		var instance = Template.instance();
		var posts = CourseDiscussions.find(
			{
				courseId: this._id,
				parentId: { $exists: false }
			},
			{
				sort: { time_updated: -1 }
			})
			.fetch();

		var count = posts.length;
		instance.count.set(count);

		var limit = instance.limit.get();
		if (limit) posts = posts.slice(0, limit);

		return posts;
	},

	newPost: function() {
		return {
			'new': true,
			courseId: this._id,
			userId: Meteor.userId(),
			text: ''
		};
	},

	limited: function() {
		var instance = Template.instance();
		var limit = instance.limit.get();

		if (limit) return instance.count.get() >= limit;
	},

	count: function() {
		return Template.instance().count.get();
	}
});

Template.discussion.events({
	'click .js-show-all-posts': function(e, instance) {
		 instance.limit.set(0);
	}
});

Template.post.onCreated(function() {
	var post = this.data;

	this.isParent = !post.new && !post.parentId;
	this.count = new ReactiveVar(0);
	this.editing = new ReactiveVar(false);

	this.initialLimit = 1;
	this.limit = new ReactiveVar(this.initialLimit);
});

Template.post.helpers({
	editing: function() {
		return Template.instance().editing.get();
	},

	responses: function() {
		// Note that the 'discussion' subscription from the 'discussion' template
		// covers responses as well
		var instance = Template.instance();
		var responses = false;

		if (instance.isParent) {
			var limit = instance.limit.get();

			// if only one response is shown, show newest
			var sort = limit ? -1 : 1;

			responses = CourseDiscussions.find(
				{ parentId: this._id },
				{ sort: { time_updated: sort } })
				.fetch();

			var count = responses.length;
			instance.count.set(count);

			if (limit) responses = responses.slice(0, limit);
		}

		return responses;
	},

	responsesLimited: function() {
		var instance = Template.instance();
		var limit = instance.limit.get();

		return instance.count.get() > limit;
	},

	allResponsesShown: function() {
		return !Template.instance().limit.get();
	},

	count: function() {
		return Template.instance().count.get();
	},

	allowResponse: function() {
		return Template.instance().isParent;
	},

	newResponse: function() {
		if (this.parentId) return false;
		return {
			new: true,
			parentId: this._id,
			courseId: this.courseId,
			userId: Meteor.userId(),
			text: '',
		};
	}
});

Template.post.events({
	'click .js-toggle-all-responses': function(e, instance) {
		var limit = instance.limit;
		var newLimit = (limit.get() === 0) ? instance.initialLimit : 0;

		limit.set(newLimit);
	}
});

Template.postShow.helpers({
	postClass: function() {
		return this.parentId ? 'discussion-comment' : 'discussion-post';
	},

	mayEdit: function() {
		return mayEditPost(Meteor.user(), this);
	},

	mayDelete: function() {
		var course = Courses.findOne(this.courseId);
		return mayDeletePost(Meteor.user(), course, this);
	},

	hasBeenEdited: function() {
		 return moment(this.time_updated).isAfter(this.time_created);
	}
});

Template.postEdit.onCreated(function() {
	this.anon = new ReactiveVar(!this.data.userId);
	this.validComment = new ReactiveVar(CourseDiscussions.validComment(this.data.text));
});

Template.postEdit.helpers({
	postClass: function() {
		return this.parentId ? 'discussion-comment' : 'discussion-post';
	},

	showUserId: function() {
		return !this.new || !Template.instance().anon.get();
	},

	anonChecked: function() {
		if (Template.instance().anon.get()) {
			return { checked: 1};
		}
		return {};
	},

	anonDisabled: function() {
		if (Meteor.user()) return {};
		return { disabled: 1 };
	},

	enableWhenValid: function() {
		return Template.instance().validComment.get() ? '' : 'disabled';
	},

	hasBeenEdited: function() {
		 return moment(this.time_updated).isAfter(this.time_created);
	}
});

Template.post.events({
	'click .js-discussion-edit': function(event, instance) {
		Tooltips.hide();
		event.stopImmediatePropagation();
		instance.editing.set(true);
	},

	'submit': function (event, instance) {
		event.stopImmediatePropagation();
		var comment = {
			title: instance.$(".js-post-title").val(),
			text: instance.$(".js-post-text").val()
		};

		var method = 'editComment';
		if (instance.data.new) {
			method = 'postComment';

			comment.courseId = instance.data.courseId;

			if (instance.data.parentId)	{
				comment.parentId = instance.data.parentId;
			}

			comment.anon = !!instance.$('.js-anon').prop('checked');
		} else {
			comment._id = instance.data._id;
		}

		Meteor.call(method, comment, function(err, commentId) {
			if (err) {
				showServerError('Posting your comment went wrong', err);
			} else {
				instance.editing.set(false);
			}
		});

		return false;
	},

	'click .js-discussion-cancel': function() {
		Template.instance().editing.set(false);
	},

	'click button.js-delete-comment': function (event, instance) {
		Tooltips.hide();
		event.stopImmediatePropagation();
		Meteor.call('deleteComment', this._id, function(err) {
			if (err) {
				showServerError('Could not delete comment', err);
			} else {
				addMessage("\u2713 " + mf('_message.removed'), 'success');
			}
		});
	},
});

Template.postEdit.rendered = function(){
	 Template.instance().$('.discussion-comment').slideDown();
};

Template.postEdit.events({
	'keyup .js-post-text, change .js-post-text': function(event, instance) {
		var text = instance.$(".js-post-text").val();
		instance.validComment.set(CourseDiscussions.validComment(text));
	},

	'change': function(event, instance) {
		instance.anon.set(instance.$('.js-anon').prop('checked'));
	}
});
<commit_msg>fix logic of limited helper<commit_after>Template.discussion.onCreated(function() {
	subs.subscribe('discussion', this.data._id);

	this.count = new ReactiveVar(0);
	this.limit = new ReactiveVar(3);
});

Template.discussion.helpers({
	posts: function() {
		var instance = Template.instance();
		var posts = CourseDiscussions.find(
			{
				courseId: this._id,
				parentId: { $exists: false }
			},
			{
				sort: { time_updated: -1 }
			})
			.fetch();

		var count = posts.length;
		instance.count.set(count);

		var limit = instance.limit.get();
		if (limit) posts = posts.slice(0, limit);

		return posts;
	},

	newPost: function() {
		return {
			'new': true,
			courseId: this._id,
			userId: Meteor.userId(),
			text: ''
		};
	},

	limited: function() {
		var instance = Template.instance();
		var limit = instance.limit.get();

		if (limit) return instance.count.get() > limit;
	},

	count: function() {
		return Template.instance().count.get();
	}
});

Template.discussion.events({
	'click .js-show-all-posts': function(e, instance) {
		 instance.limit.set(0);
	}
});

Template.post.onCreated(function() {
	var post = this.data;

	this.isParent = !post.new && !post.parentId;
	this.count = new ReactiveVar(0);
	this.editing = new ReactiveVar(false);

	this.initialLimit = 1;
	this.limit = new ReactiveVar(this.initialLimit);
});

Template.post.helpers({
	editing: function() {
		return Template.instance().editing.get();
	},

	responses: function() {
		// Note that the 'discussion' subscription from the 'discussion' template
		// covers responses as well
		var instance = Template.instance();
		var responses = false;

		if (instance.isParent) {
			var limit = instance.limit.get();

			// if only one response is shown, show newest
			var sort = limit ? -1 : 1;

			responses = CourseDiscussions.find(
				{ parentId: this._id },
				{ sort: { time_updated: sort } })
				.fetch();

			var count = responses.length;
			instance.count.set(count);

			if (limit) responses = responses.slice(0, limit);
		}

		return responses;
	},

	responsesLimited: function() {
		var instance = Template.instance();
		var limit = instance.limit.get();

		return instance.count.get() > limit;
	},

	allResponsesShown: function() {
		return !Template.instance().limit.get();
	},

	count: function() {
		return Template.instance().count.get();
	},

	allowResponse: function() {
		return Template.instance().isParent;
	},

	newResponse: function() {
		if (this.parentId) return false;
		return {
			new: true,
			parentId: this._id,
			courseId: this.courseId,
			userId: Meteor.userId(),
			text: '',
		};
	}
});

Template.post.events({
	'click .js-toggle-all-responses': function(e, instance) {
		var limit = instance.limit;
		var newLimit = (limit.get() === 0) ? instance.initialLimit : 0;

		limit.set(newLimit);
	}
});

Template.postShow.helpers({
	postClass: function() {
		return this.parentId ? 'discussion-comment' : 'discussion-post';
	},

	mayEdit: function() {
		return mayEditPost(Meteor.user(), this);
	},

	mayDelete: function() {
		var course = Courses.findOne(this.courseId);
		return mayDeletePost(Meteor.user(), course, this);
	},

	hasBeenEdited: function() {
		 return moment(this.time_updated).isAfter(this.time_created);
	}
});

Template.postEdit.onCreated(function() {
	this.anon = new ReactiveVar(!this.data.userId);
	this.validComment = new ReactiveVar(CourseDiscussions.validComment(this.data.text));
});

Template.postEdit.helpers({
	postClass: function() {
		return this.parentId ? 'discussion-comment' : 'discussion-post';
	},

	showUserId: function() {
		return !this.new || !Template.instance().anon.get();
	},

	anonChecked: function() {
		if (Template.instance().anon.get()) {
			return { checked: 1};
		}
		return {};
	},

	anonDisabled: function() {
		if (Meteor.user()) return {};
		return { disabled: 1 };
	},

	enableWhenValid: function() {
		return Template.instance().validComment.get() ? '' : 'disabled';
	},

	hasBeenEdited: function() {
		 return moment(this.time_updated).isAfter(this.time_created);
	}
});

Template.post.events({
	'click .js-discussion-edit': function(event, instance) {
		Tooltips.hide();
		event.stopImmediatePropagation();
		instance.editing.set(true);
	},

	'submit': function (event, instance) {
		event.stopImmediatePropagation();
		var comment = {
			title: instance.$(".js-post-title").val(),
			text: instance.$(".js-post-text").val()
		};

		var method = 'editComment';
		if (instance.data.new) {
			method = 'postComment';

			comment.courseId = instance.data.courseId;

			if (instance.data.parentId)	{
				comment.parentId = instance.data.parentId;
			}

			comment.anon = !!instance.$('.js-anon').prop('checked');
		} else {
			comment._id = instance.data._id;
		}

		Meteor.call(method, comment, function(err, commentId) {
			if (err) {
				showServerError('Posting your comment went wrong', err);
			} else {
				instance.editing.set(false);
			}
		});

		return false;
	},

	'click .js-discussion-cancel': function() {
		Template.instance().editing.set(false);
	},

	'click button.js-delete-comment': function (event, instance) {
		Tooltips.hide();
		event.stopImmediatePropagation();
		Meteor.call('deleteComment', this._id, function(err) {
			if (err) {
				showServerError('Could not delete comment', err);
			} else {
				addMessage("\u2713 " + mf('_message.removed'), 'success');
			}
		});
	},
});

Template.postEdit.rendered = function(){
	 Template.instance().$('.discussion-comment').slideDown();
};

Template.postEdit.events({
	'keyup .js-post-text, change .js-post-text': function(event, instance) {
		var text = instance.$(".js-post-text").val();
		instance.validComment.set(CourseDiscussions.validComment(text));
	},

	'change': function(event, instance) {
		instance.anon.set(instance.$('.js-anon').prop('checked'));
	}
});
<|endoftext|>


<commit_before>/**
 * ShipmentController
 *
 * @description :: Server-side logic for managing shipments
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

module.exports = {
	new: function (req, res) {
        var params = req.params.all();

        Cogroup.findOne({name: params.id})
        .populate('branches')
        .populate('contacts')
        .exec( function (err, cogroup) {
                res.view({
                    cogroup: cogroup,
            });
        });
    },

	create: function (req, res) {
        console.log('shipments/create/', req.params.all());
        var params = req.params.all();

        if (!(params.PO instanceof Array)) {
            params.PO = [params.PO];
            params.MPN = [params.MPN];
            params.qty = [params.qty];
            params.price = [params.price];
            params.is_supply = [params.is_supply];
        }

        var orderIDs = params.PO,
            qty = params.qty;

        var newShipment = {
            shipmentdate: params['shipmentdate'],
            shipment_no: params['shipment_no'],
            shipmentnote: params['shipmentnote'],
            shipmentdest: params['shipmentdest'],
            group: params.group,
        };

        // Create default order records for non-PO shipments
        defaultOrders = [];
        for (var i=0; i<orderIDs.length; i++) {
            var record = {
                id: orderIDs[i] === 'default' ? undefined : orderIDs[i],
                group: params.group,
                seller: params.is_supply[i] === 'true' ? params.them : params.us,
                buyer: params.is_supply[i] === 'false' ? params.them : params.us,
                qty: params.qty[i],
                MPN: params.MPN[i],
                is_sale: params.is_supply[i] === 'true' ? false : true,
                is_purchase: params.is_supply[i] === 'true' ? true : false,
                applytax: true,
                price: params.price[i],
                orderdate: params.shipmentdate,
                ordernote: '(auto-generated : 自動創造)',
                orderID: '',
                is_open: false,
            }
            defaultOrders.push(record);
        }

        // Update prices in the product records

        // Create shipment
        Shipment.create(newShipment)
        .exec( function (err, shipment) {
            if (err) { res.json(err); return; }

            console.log('SHIPMENT:', shipment);

            defaultOrders.forEach( function (defOrder) {
                console.log('DEF ORDER:', defOrder);
                Order.findOrCreate({id: defOrder.id}, defOrder, function (err, order) {
                    if (err) {
                        res.json({
                            error: err
                        }, 400);
                        return;
                    }
                    console.log('ORDER CREATE or FOUND:', order);

                    var newItem = {
                        order_id: order.id,
                        shipment_id: shipment.id,
                        qty: defOrder.qty,
                    }
                    Shipmentitem.create(newItem)
                    .exec( function (err, shipmentitem) {
                        if (err) res.json({
                            error: err.message
                        }, 400);
                        console.log('SHIP ITEM:', shipmentitem);
                    });
                });
            });
        });
        setTimeout(
            function () { res.redirect('/shipment/showall/'+params.group) },
            200
        );
    },

    showall: function (req, res) {
        var params = req.params.all();

        Cogroup.findOne({name: params.id})
        .populate('branches')
        .exec( function (err, cogroup) {
            if (err) {
                res.json({
                    error: err
                }, 400);
                return;
            }

            res.view({
                cogroup: cogroup,
            });
        });
    },

    get: function (req, res) {
        var params = req.params.all();

        Shipment.findOne({name: params.id}, function (err, cogroup) {
            if (err) {
                res.json({
                    error: err
                }, 400);
                return;
            }

            res.view({
                cogroup: cogroup,
            });
        });
    },

    pdf: function (req, res) {
        var sid = req.param('id');

        // Gets recent shipments for a company. "SHIPMENT/SHOWALL"
        Shipmentitem.query(
            "SELECT shipi.qty, sh.shipmentdate, sh.shipment_no, br.fullname as buyer, po.orderID, po.group, po.seller, prod.inventory_name, prod.product_label, prod.UM, prod.units, prod.SKU, prod.unitcounted"
            + " FROM shipmentitem shipi "
            + " JOIN shipment sh ON sh.id = shipi.shipment_id "
            + " JOIN `order` po ON po.id = shipi.order_id "
            + " JOIN product prod ON prod.MPN = po.MPN "
            + " JOIN branch br ON po.buyer = br.name "
            + " WHERE shipment_id LIKE ?"
            + " ;"
            , [req.param('id')],
        function(err, recs) {
            if (err) {
                res.json(err);
                return;
            }

            Cogroup.findOne(recs[0].group)
            .populate('branches')
            .populate('contacts')
            .exec(function (err, group) {

                res.view({
                    cogroup: group,
                    shipment_no: recs[0].shipment_no,
                    items: recs,
    //                layout: null
                });

            })
        });

    },

    availableNumber: function (req, res) {
        var d = new Date();
        var d_cutoff = new Date(d.getFullYear(), -1, 1);
        Shipment.find({shipmentdate: { '>=': d_cutoff}})
        .exec(function (err, recs) {
            var used_nos = [];
            recs.forEach(function (each) {used_nos.push(each.shipment_no)})
//            console.log(used_nos);
            var new_number = null;
            var counter = 0;
            while (new_number === null) {
                counter += 1;
                var test_no = [
                    d.getYear()-11,
                    ('0000' + counter).slice(-4)
                ].join('');
                if (used_nos.indexOf(test_no) < 0) {
                    new_number = test_no;
                }
            }
            res.send(new_number);
        });
    },

    checkNumber: function (req, res) {
        var no = req.param('id');
        Shipment.find(no)
        .exec(function (err, recs) {
            if (err) {
                res.json(err);
                return;
            }

            if (recs.length === 0) {
                res.send(true);
            } else {
                res.send(false);
            }
        });
    }

};

<commit_msg>Bug fix: Strings of numbers using Chinese input<commit_after>/**
 * ShipmentController
 *
 * @description :: Server-side logic for managing shipments
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

module.exports = {
	new: function (req, res) {
        var params = req.params.all();

        Cogroup.findOne({name: params.id})
        .populate('branches')
        .populate('contacts')
        .exec( function (err, cogroup) {
                res.view({
                    cogroup: cogroup,
            });
        });
    },

	create: function (req, res) {
        console.log('shipments/create/', req.params.all());
        var params = req.params.all();

        if (!(params.PO instanceof Array)) {
            params.PO = [params.PO];
            params.MPN = [params.MPN];
            params.qty = [params.qty];
            params.price = [params.price];
            params.is_supply = [params.is_supply];
        }

        var orderIDs = params.PO,
            qty = params.qty;

        var newShipment = {
            shipmentdate: params['shipmentdate'],
            shipment_no: params['shipment_no'],
            shipmentnote: params['shipmentnote'],
            shipmentdest: params['shipmentdest'],
            group: params.group,
        };

        // Create default order records for non-PO shipments
        defaultOrders = [];
        for (var i=0; i<orderIDs.length; i++) {
            var record = {
                id: orderIDs[i] === 'default' ? undefined : orderIDs[i],
                group: params.group,
                seller: params.is_supply[i] === 'true' ? params.them : params.us,
                buyer: params.is_supply[i] === 'false' ? params.them : params.us,
                qty: params.qty[i],
                MPN: params.MPN[i],
                is_sale: params.is_supply[i] === 'true' ? false : true,
                is_purchase: params.is_supply[i] === 'true' ? true : false,
                applytax: true,
                price: params.price[i],
                orderdate: params.shipmentdate,
                ordernote: '(auto-generated : 自動創造)',
                orderID: '',
                is_open: false,
            }
            defaultOrders.push(record);
        }

        // Update prices in the product records

        // Create shipment
        Shipment.create(newShipment)
        .exec( function (err, shipment) {
            if (err) { res.json(err); return; }

            console.log('SHIPMENT:', shipment);

            defaultOrders.forEach( function (defOrder) {
                console.log('DEF ORDER:', defOrder);
                Order.findOrCreate({id: defOrder.id}, defOrder, function (err, order) {
                    if (err) {
                        res.json({
                            error: err
                        }, 400);
                        return;
                    }
                    console.log('ORDER CREATE or FOUND:', order);

                    var newItem = {
                        order_id: order.id,
                        shipment_id: shipment.id,
                        qty: defOrder.qty,
                    }
                    Shipmentitem.create(newItem)
                    .exec( function (err, shipmentitem) {
                        if (err) res.json({
                            error: err.message
                        }, 400);
                        console.log('SHIP ITEM:', shipmentitem);
                    });
                });
            });
        });
        setTimeout(
            function () { res.redirect('/shipment/showall/'+params.group) },
            200
        );
    },

    showall: function (req, res) {
        var params = req.params.all();

        Cogroup.findOne({name: params.id})
        .populate('branches')
        .exec( function (err, cogroup) {
            if (err) {
                res.json({
                    error: err
                }, 400);
                return;
            }

            res.view({
                cogroup: cogroup,
            });
        });
    },

    get: function (req, res) {
        var params = req.params.all();

        Shipment.findOne({name: params.id}, function (err, cogroup) {
            if (err) {
                res.json({
                    error: err
                }, 400);
                return;
            }

            res.view({
                cogroup: cogroup,
            });
        });
    },

    pdf: function (req, res) {
        var sid = req.param('id');

        // Gets recent shipments for a company. "SHIPMENT/SHOWALL"
        Shipmentitem.query(
            "SELECT shipi.qty, sh.shipmentdate, sh.shipment_no, br.fullname as buyer, po.orderID, po.group, po.seller, prod.inventory_name, prod.product_label, prod.UM, prod.units, prod.SKU, prod.unitcounted"
            + " FROM shipmentitem shipi "
            + " JOIN shipment sh ON sh.id = shipi.shipment_id "
            + " JOIN `order` po ON po.id = shipi.order_id "
            + " JOIN product prod ON prod.MPN = po.MPN "
            + " JOIN branch br ON po.buyer = br.name "
            + " WHERE shipment_id LIKE ?"
            + " ;"
            , [req.param('id')],
        function(err, recs) {
            if (err) {
                res.json(err);
                return;
            }

            Cogroup.findOne(recs[0].group)
            .populate('branches')
            .populate('contacts')
            .exec(function (err, group) {

                res.view({
                    cogroup: group,
                    shipment_no: recs[0].shipment_no,
                    items: recs,
    //                layout: null
                });

            })
        });

    },

    availableNumber: function (req, res) {
        var d = new Date();
        var d_cutoff = new Date(d.getFullYear(), -1, 1);
        Shipment.find({shipmentdate: { '>=': d_cutoff}})
        .exec(function (err, recs) {
            var used_nos = [];
            recs.forEach(function (each) {
                // Only interested in non-lettered shipment IDs
                used_nos.push(parseInt(each.shipment_no));
            });
//            console.log(used_nos);
            var new_number = null;
            var counter = 0;
            while (new_number === null) {
                counter += 1;
                var test_no = parseInt([
                        d.getYear()-11,
                        ('0000' + counter).slice(-4)
                    ].join(''));
                if (used_nos.indexOf(test_no) < 0) {
                    new_number = test_no.toString();
                }
            }
            res.send(new_number);
        });
    },

    checkNumber: function (req, res) {
        var no = req.param('id');
        Shipment.find(no)
        .exec(function (err, recs) {
            if (err) {
                res.json(err);
                return;
            }

            if (recs.length === 0) {
                res.send(true);
            } else {
                res.send(false);
            }
        });
    }

};

<|endoftext|>


<commit_before>$.fn.replicate = function(options) {
  var S = $.extend({
            // These are the defaults.
            total: 100,
            random: true
        }, options );

  for(var i=0;i<S.total;i++){

    $('body').append($(this).clone())

    if(S.random){
      var rw = Math.random() * (window.innerWidth - $(this).width());
      var rh = Math.random() * (window.innerHeight - $(this).height());;

      $(this).css({
        'position':'absolute',
        'top': rh,
        'left':rw
      })

    }
  }; //close for loop

};

$.fn.iterate = function(options) {

  var S = $.extend({
            // These are the defaults.
            speed:500,
            total: 100,
            random: true
        }, options );

    var me = $(this) //store instance of this for later use in the set interval function below.
    var counter = 0;

    var gogogadget = setInterval(function(){

      if( S.total != 0 ){ counter++ };

      if(counter >= S.total && S.total != 0){
        clearInterval(gogogadget);
      }

      $('body').append(me.clone())

      if(S.random){
        var rw = Math.random() * (window.innerWidth - me.width());
        var rh = Math.random() * (window.innerHeight - me.height());
        // console.log(rw + " || " + rh);

        $(me).css({
          'position':'absolute',
          'top': rh,
          'left':rw
        })

      }

    }, S.speed);

};<commit_msg>iterate removes default element, and moved clone to after css, so the first item is set.<commit_after>$.fn.replicate = function(options) {
  var S = $.extend({
            // These are the defaults.
            total: 100,
            random: true
        }, options );

  for(var i=0;i<S.total;i++){

    $('body').append($(this).clone())

    if(S.random){
      var rw = Math.random() * (window.innerWidth - $(this).width());
      var rh = Math.random() * (window.innerHeight - $(this).height());;

      $(this).css({
        'position':'absolute',
        'top': rh,
        'left':rw
      })

    }
  }; //close for loop

};

$.fn.iterate = function(options) {

  var S = $.extend({
            // These are the defaults.
            speed:500,
            total: 100,
            random: true
        }, options );

    var me = $(this) //store instance of this for later use in the set interval function below.
    var counter = 0;

    $('body').find(me).remove();

    var gogogadget = setInterval(function(){

      if( S.total != 0 ){ counter++ };

      if(counter >= S.total && S.total != 0){
        clearInterval(gogogadget);
      }

      if(S.random){
        var rw = Math.random() * (window.innerWidth - me.width());
        var rh = Math.random() * (window.innerHeight - me.height());
        // console.log(rw + " || " + rh);

        $(me).css({
          'position':'absolute',
          'top': rh,
          'left':rw
        })

      }

      $('body').append(me.clone());

    }, S.speed);

};
<|endoftext|>


<commit_before>function IndexController($filter, WordService, GenreService, BandNameService) {
  var ctrl = this;

  ctrl.bandWords = [];
  ctrl.genres = [];

  ctrl.slider = new Slider('#band-name-length', {
      ticks: [1, 2, 3],
      ticks_labels: ['Small', 'Medium', 'Large'],
      tooltip: "hide",
      value: 1,
      formatter: function(value) {
        ctrl.numberOfWords = value;
      }
    });

  ctrl.getGenreNames = function() {
    GenreService.getGenres()
      .then(function(response) {
        ctrl.genres.push(response.data.genres);
      });
  }

  ctrl.getBeginningWords = function() {
    WordService.getWords()
      .then(function(response) {
        var beginningWords = $filter('removeBeginningWordsFilter')(response.data.words, true);
        ctrl.beginningWords = beginningWords;
      });
  }

  ctrl.setBeginningWords = function() {
    if (ctrl.beginsWith != undefined && ctrl.beginsWith != '') {
      ctrl.bandWords.push(ctrl.beginsWith);
    }
  }

  ctrl.getRandomInt = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  ctrl.setBandWords = function(numOfWords) {
    WordService.getWords()
      .then(function(response) {

        var words = $filter('removeBeginningWordsFilter')(response.data.words, false);
        var i = 0

        while (i++ < numOfWords) {
          var randomWordIndex = ctrl.getRandomInt(0, words.length-1);
          ctrl.bandWords.push(words[randomWordIndex].string);
        }

        ctrl.bandName = ctrl.bandWords.join(' ');
        ctrl.saveBandName();
        ctrl.bandWords = [];

      });
  }

  ctrl.saveBandName = function() {
    var data = {
      band_name: {
        name: ctrl.bandName,
        genre_id: parseInt(ctrl.genre)
      },
    };

    BandNameService.postBandName(data);
  }

  ctrl.getBandName = function(numOfWords) {
    ctrl.setBeginningWords();
    ctrl.setBandWords(numOfWords);
  }

  ctrl.getGenreNames();
  ctrl.getBeginningWords();

}

angular
  .module('app')
  .controller('IndexController', IndexController);<commit_msg>remove form logic from IndexController<commit_after>function IndexController() {
  var ctrl = this;

}

angular
  .module('app')
  .controller('IndexController', IndexController);<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

define(['require',
    'backbone',
    'hbs!tmpl/tag/createTagLayoutView_tmpl',
    'utils/Utils'
], function(require, Backbone, CreateTagLayoutViewTmpl, Utils) {

    var CreateTagLayoutView = Backbone.Marionette.LayoutView.extend(
        /** @lends CreateTagLayoutView */
        {
            _viewName: 'CreateTagLayoutView',

            template: CreateTagLayoutViewTmpl,

            templateHelpers: function() {
                return {
                    create: this.create,
                    description: this.description
                };
            },

            /** Layout sub regions */
            regions: {},

            /** ui selector cache */
            ui: {
                tagName: "[data-id='tagName']",
                parentTag: "[data-id='parentTag']",
                description: "[data-id='description']",
                title: "[data-id='title']"
            },
            /** ui events hash */
            events: function() {
                var events = {};
                return events;
            },
            /**
             * intialize a new CreateTagLayoutView Layout
             * @constructs
             */
            initialize: function(options) {
                _.extend(this, _.pick(options, 'tagCollection', 'tag', 'termCollection', 'descriptionData'));
                if (this.tagCollection && this.tagCollection.first().get('traitTypes')) {
                    this.description = this.tagCollection.first().get('traitTypes')[0].typeDescription;
                } else if (this.termCollection) {
                    this.description = this.descriptionData;
                } else {
                    this.create = true;
                }
            },
            bindEvents: function() {},
            onRender: function() {
                if (this.create) {
                    this.tagCollectionList();
                } else {
                    this.ui.title.html('' + this.tag + '');
                }
            },
            tagCollectionList: function() {
                this.ui.parentTag.empty();
                var str = '';
                for (var i = 0; i < this.tagCollection.fullCollection.models.length; i++) {
                    var tags = this.tagCollection.fullCollection.models[i].get("tags");
                    str += '<option>' + tags + '</option>';
                    this.ui.parentTag.html(str);
                }
                this.ui.parentTag.select2({
                    placeholder: "Search Tags",
                    allowClear: true
                });
            },
            fetchCollection: function() {
                $.extend(this.tagCollection.queryParams, { type: 'TRAIT' });
                this.tagCollection.fetch({ reset: true });
            },
        });
    return CreateTagLayoutView;
});
<commit_msg>ATLAS-932: UI: 'create tag' button does not work - when there are no tags in the store<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

define(['require',
    'backbone',
    'hbs!tmpl/tag/createTagLayoutView_tmpl',
    'utils/Utils'
], function(require, Backbone, CreateTagLayoutViewTmpl, Utils) {

    var CreateTagLayoutView = Backbone.Marionette.LayoutView.extend(
        /** @lends CreateTagLayoutView */
        {
            _viewName: 'CreateTagLayoutView',

            template: CreateTagLayoutViewTmpl,

            templateHelpers: function() {
                return {
                    create: this.create,
                    description: this.description
                };
            },

            /** Layout sub regions */
            regions: {},

            /** ui selector cache */
            ui: {
                tagName: "[data-id='tagName']",
                parentTag: "[data-id='parentTag']",
                description: "[data-id='description']",
                title: "[data-id='title']"
            },
            /** ui events hash */
            events: function() {
                var events = {};
                return events;
            },
            /**
             * intialize a new CreateTagLayoutView Layout
             * @constructs
             */
            initialize: function(options) {
                _.extend(this, _.pick(options, 'tagCollection', 'tag', 'termCollection', 'descriptionData'));
                if (this.tagCollection && this.tagCollection.length > 0 && this.tagCollection.first().get('traitTypes')) {
                    this.description = this.tagCollection.first().get('traitTypes')[0].typeDescription;
                } else if (this.termCollection) {
                    this.description = this.descriptionData;
                } else {
                    this.create = true;
                }
            },
            bindEvents: function() {},
            onRender: function() {
                if (this.create) {
                    this.tagCollectionList();
                } else {
                    this.ui.title.html('' + this.tag + '');
                }
            },
            tagCollectionList: function() {
                this.ui.parentTag.empty();
                var str = '';
                for (var i = 0; i < this.tagCollection.fullCollection.models.length; i++) {
                    var tags = this.tagCollection.fullCollection.models[i].get("tags");
                    str += '<option>' + tags + '</option>';
                    this.ui.parentTag.html(str);
                }
                this.ui.parentTag.select2({
                    placeholder: "Search Tags",
                    allowClear: true
                });
            },
            fetchCollection: function() {
                $.extend(this.tagCollection.queryParams, { type: 'TRAIT' });
                this.tagCollection.fetch({ reset: true });
            },
        });
    return CreateTagLayoutView;
});
<|endoftext|>