<commit_before>const fs = require('fs');
const db = require('../../db/db');

const utils = require('../../utils/logging');
const perror = utils.perror;
const info = utils.info;
const log = utils.log;

const watchLectureVideosPage = fs.readFileSync(mustachePath + 'watchLectureVideos.mustache').toString();

router.get('/watchLectureVideos/:courseOfferingId', function (request, response) {
  if(request.isAuthenticated()) {

    response.writeHead(200, {
      'Content-Type': 'text/html'
    });

    var courseOfferingId = request.params.courseOfferingId;

    db.getPlaylistByCourseOfferingId( courseOfferingId ).then(
      values => {

        var playlist = values.map(result => {
          let video = {};
          let des = JSON.parse(JSON.stringify(result.siteSpecificJSON));
          video['name'] = des['title'];
          video['sources'] = [{src: result['videoLocalLocation'], type:'video/mp4'}];
          video['textTracks'] = [{src: result['srtFileLocation'], srclang: 'eng', label: 'English'}];
          video['thumbnail'] = false;
          return video;
        });

        renderWithPartial(watchLectureVideosPage, request, response, { playlist : JSON.stringify(playlist) });
    }).catch(err => { perror(err); }); /* db.getPlaylistByCourseOfferingId() */
  } else {
    response.redirect('../../');
  }
});

/* not used */
router.get('/getVideo', function(request, response) {
  var lectureNumber = "1";
  var file = path.join(__dirname, "../../videos/Lecture_" + lectureNumber + ".mp4");
  console.log(file);

  fs.stat(file, function handle(err, stats) {
    if (err) {
      if (err.code === "ENOENT") {
        response.send("File doesn't exist");
      }
      else {
        response.send("Something unfathomable happened");
      }
    }
    else {
      var range = request.headers.range;
      var positions = range.replace(/bytes=/, "").split("-");
      var start = parseInt(positions[0], 10);

      fs.stat(file, function (err, stats) {
        var total = stats.size;
        var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
        var chunksize = (end - start) + 1;

        response.writeHead(206, {
          "Content-Range": "bytes " + start + "-" + end + "/" + total,
          "Accept-Ranges": "bytes",
          "Content-Length": chunksize,
          "Content-Type": "video/mp4"
        });

        var stream = fs.createReadStream(file, { start: start, end: end })
          .on("open", function () {
            stream.pipe(response);
          }).on("error", function (err) {
            response.end(err);
          });
      });
    }
  });
});

module.exports = router;
<commit_msg>title fix<commit_after>const fs = require('fs');
const db = require('../../db/db');

const utils = require('../../utils/logging');
const perror = utils.perror;
const info = utils.info;
const log = utils.log;

const watchLectureVideosPage = fs.readFileSync(mustachePath + 'watchLectureVideos.mustache').toString();

router.get('/watchLectureVideos/:courseOfferingId', function (request, response) {
  if(request.isAuthenticated()) {

    response.writeHead(200, {
      'Content-Type': 'text/html'
    });

    var courseOfferingId = request.params.courseOfferingId;

    db.getPlaylistByCourseOfferingId( courseOfferingId ).then(
      values => {

        var playlist = values.map(result => {
          let video = {};
            let des = JSON.parse(result.siteSpecificJSON);
            video['name'] = des.title;
          video['sources'] = [{src: result['videoLocalLocation'], type:'video/mp4'}];
          video['textTracks'] = [{src: result['srtFileLocation'], srclang: 'eng', label: 'English'}];
            video['thumbnail'] = false;
          return video;
        });

        renderWithPartial(watchLectureVideosPage, request, response, { playlist : JSON.stringify(playlist) });
    }).catch(err => { perror(err); }); /* db.getPlaylistByCourseOfferingId() */
  } else {
    response.redirect('../../');
  }
});

/* not used */
router.get('/getVideo', function(request, response) {
  var lectureNumber = "1";
  var file = path.join(__dirname, "../../videos/Lecture_" + lectureNumber + ".mp4");
  console.log(file);

  fs.stat(file, function handle(err, stats) {
    if (err) {
      if (err.code === "ENOENT") {
        response.send("File doesn't exist");
      }
      else {
        response.send("Something unfathomable happened");
      }
    }
    else {
      var range = request.headers.range;
      var positions = range.replace(/bytes=/, "").split("-");
      var start = parseInt(positions[0], 10);

      fs.stat(file, function (err, stats) {
        var total = stats.size;
        var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
        var chunksize = (end - start) + 1;

        response.writeHead(206, {
          "Content-Range": "bytes " + start + "-" + end + "/" + total,
          "Accept-Ranges": "bytes",
          "Content-Length": chunksize,
          "Content-Type": "video/mp4"
        });

        var stream = fs.createReadStream(file, { start: start, end: end })
          .on("open", function () {
            stream.pipe(response);
          }).on("error", function (err) {
            response.end(err);
          });
      });
    }
  });
});

module.exports = router;
<|endoftext|>


<commit_before>/**
 * Copyright 2013 IBM Corp.
 *
 * Licensed 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.
 **/

var RED = require(process.env.NODE_RED_HOME+"/red/red");
var util = require("util");
var exec = require('child_process').exec;
var fs =  require('fs');

if (!fs.existsSync("/usr/local/bin/gpio")) {
    exec("cat /proc/cpuinfo | grep BCM27",function(err,stdout,stderr) {
        if (stdout.indexOf('BCM27') > -1) {
            util.log('[36-rpi-gpio.js] Error: Cannot find Wiring-Pi "gpio" command. http://wiringpi.com/download-and-install/');
        }
        // else not on a Pi so don't worry anyone with needless messages.
    });
    return;
}

// Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
var pintable = {
// Physical : WiringPi
         "7":"7",
        "11":"0",
        "12":"1",
        "13":"2",
        "15":"3",
        "16":"4",
        "18":"5",
        "22":"6"
}
var tablepin = {
// WiringPi : Physical
        "7":"7",
        "0":"11",
        "1":"12",
        "2":"13",
        "3":"15",
        "4":"16",
        "5":"18",
        "6":"22"
}

function GPIOInNode(n) {
    RED.nodes.createNode(this,n);
    this.buttonState = -1;
    this.pin = pintable[n.pin];
    this.intype = n.intype;
    var node = this;

    if (this.pin) {
        exec("gpio mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
            if (err) node.error(err);
            else {
                node._interval = setInterval( function() {
                    exec("gpio read "+node.pin, function(err,stdout,stderr) {
                        if (err) node.error(err);
                        else {
                            if (node.buttonState !== Number(stdout)) {
                                var previousState = node.buttonState;
                                node.buttonState = Number(stdout);
                                if (previousState !== -1) {
                                    var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState};
                                    node.send(msg);
                                }
                            }
                        }
                    });
                }, 250);
            }
        });
    }
    else {
        this.error("Invalid GPIO pin: "+this.pin);
    }
}

function GPIOOutNode(n) {
    RED.nodes.createNode(this,n);
    this.pin = pintable[n.pin];
    var node = this;

    if (this.pin) {
        process.nextTick(function() {
            exec("gpio mode "+node.pin+" out", function(err,stdout,stderr) {
                if (err) node.error(err);
                else {
                    node.on("input", function(msg) {
                        if (msg.payload === "true") msg.payload = true;
                        if (msg.payload === "false") msg.payload = false;
                        var out = Number(msg.payload);
                        if ((out == 0)|(out == 1)) {
                            exec("gpio write "+node.pin+" "+out, function(err,stdout,stderr) {
                                if (err) node.error(err);
                            });
                        }
                        else node.warn("Invalid input - not 0 or 1");
                    });
                }
            });
        });
    }
    else {
        this.error("Invalid GPIO pin: "+this.pin);
    }
}

exec("gpio mode 0 in",function(err,stdout,stderr) {
    if (err) {
        util.log('[36-rpi-gpio.js] Error: "gpio" command failed for some reason.');
    }
    exec("gpio mode 1 in");
    exec("gpio mode 2 in");
    exec("gpio mode 3 in");
    exec("gpio mode 4 in");
    exec("gpio mode 5 in");
    exec("gpio mode 6 in");
    exec("gpio mode 7 in",function(err,stdout,stderr) {
        RED.nodes.registerType("rpi-gpio in",GPIOInNode);
        RED.nodes.registerType("rpi-gpio out",GPIOOutNode);

        GPIOInNode.prototype.close = function() {
            clearInterval(this._interval);
        }

        GPIOOutNode.prototype.close = function() {
            exec("gpio mode "+this.pin+" in");
        }

    });
});
<commit_msg>pintable + tablepin maps for all 17 WiringPi pins<commit_after>/**
 * Copyright 2013 IBM Corp.
 *
 * Licensed 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.
 **/

var RED = require(process.env.NODE_RED_HOME+"/red/red");
var util = require("util");
var exec = require('child_process').exec;
var fs =  require('fs');

if (!fs.existsSync("/usr/local/bin/gpio")) {
    exec("cat /proc/cpuinfo | grep BCM27",function(err,stdout,stderr) {
        if (stdout.indexOf('BCM27') > -1) {
            util.log('[36-rpi-gpio.js] Error: Cannot find Wiring-Pi "gpio" command. http://wiringpi.com/download-and-install/');
        }
        // else not on a Pi so don't worry anyone with needless messages.
    });
    return;
}

// Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
var pintable = {
// Physical : WiringPi
        "11":"0",
        "12":"1",
        "13":"2",
        "15":"3",
        "16":"4",
        "18":"5",
        "22":"6",
         "7":"7",
         "3":"8",
         "5":"9",
        "24":"10",
        "26":"11",
        "19":"12",
        "21":"13",
        "23":"14",
         "8":"15",
        "10":"16"
}
var tablepin = {
// WiringPi : Physical
        "0":"11",
        "1":"12",
        "2":"13",
        "3":"15",
        "4":"16",
        "5":"18",
        "6":"22",
        "7":"7",
        "8":"3",
        "9":"5",
       "10":"24",
       "11":"26",
       "12":"19",
       "13":"21",
       "14":"23",
       "15":"8",
       "16":"10"
}

function GPIOInNode(n) {
    RED.nodes.createNode(this,n);
    this.buttonState = -1;
    this.pin = pintable[n.pin];
    this.intype = n.intype;
    var node = this;

    if (this.pin) {
        exec("gpio mode "+node.pin+" "+node.intype, function(err,stdout,stderr) {
            if (err) node.error(err);
            else {
                node._interval = setInterval( function() {
                    exec("gpio read "+node.pin, function(err,stdout,stderr) {
                        if (err) node.error(err);
                        else {
                            if (node.buttonState !== Number(stdout)) {
                                var previousState = node.buttonState;
                                node.buttonState = Number(stdout);
                                if (previousState !== -1) {
                                    var msg = {topic:"pi/"+tablepin[node.pin], payload:node.buttonState};
                                    node.send(msg);
                                }
                            }
                        }
                    });
                }, 250);
            }
        });
    }
    else {
        this.error("Invalid GPIO pin: "+this.pin);
    }
}

function GPIOOutNode(n) {
    RED.nodes.createNode(this,n);
    this.pin = pintable[n.pin];
    var node = this;

    if (this.pin) {
        process.nextTick(function() {
            exec("gpio mode "+node.pin+" out", function(err,stdout,stderr) {
                if (err) node.error(err);
                else {
                    node.on("input", function(msg) {
                        if (msg.payload === "true") msg.payload = true;
                        if (msg.payload === "false") msg.payload = false;
                        var out = Number(msg.payload);
                        if ((out == 0)|(out == 1)) {
                            exec("gpio write "+node.pin+" "+out, function(err,stdout,stderr) {
                                if (err) node.error(err);
                            });
                        }
                        else node.warn("Invalid input - not 0 or 1");
                    });
                }
            });
        });
    }
    else {
        this.error("Invalid GPIO pin: "+this.pin);
    }
}

exec("gpio mode 0 in",function(err,stdout,stderr) {
    if (err) {
        util.log('[36-rpi-gpio.js] Error: "gpio" command failed for some reason.');
    }
    exec("gpio mode 1 in");
    exec("gpio mode 2 in");
    exec("gpio mode 3 in");
    exec("gpio mode 4 in");
    exec("gpio mode 5 in");
    exec("gpio mode 6 in");
    exec("gpio mode 7 in",function(err,stdout,stderr) {
        RED.nodes.registerType("rpi-gpio in",GPIOInNode);
        RED.nodes.registerType("rpi-gpio out",GPIOOutNode);

        GPIOInNode.prototype.close = function() {
            clearInterval(this._interval);
        }

        GPIOOutNode.prototype.close = function() {
            exec("gpio mode "+this.pin+" in");
        }

    });
});
<|endoftext|>


<commit_before>const Discord = require("discord.js");
const SearchCommand = require("../types/SearchCommand");
const Class = require("../models/Class");
const FeatureModel = require("../models/Feature");

module.exports = class Feature extends SearchCommand{
	constructor(client){
		super(client, {
			name: "feature",
			category: "5e",
			help: "Searches for a class feature by name.",
			helpArgs: "<Class Name>/<Feature Name>",
			elevation: 0,
		});
	}

	async execute(msg, args){	// eslint-disable-line no-unused-vars
		let toEdit = await msg.reply("fetching your class. . .");
		let matches = /\s*(\w*.*?)\s*[^\s\w]\s*(\w*(?:\s\w+)*)\s*/.exec(args.join(" "));
		if(!matches || !matches[1] || !matches[2]){
			let prefix;
			if(msg.guild){
				prefix = await this.client.fetchPrefix(msg.guild.id);
			}
			else{
				prefix = "";
			}
			return msg.reply(`invalid command. Proper usage: \`${prefix}${this.name} barbarian/primal rage\``);
		}

		let classes = await Class.find({name: new RegExp(matches[1], "i")});
		if(!classes || classes.length === 0){
			return toEdit.edit("Unable to find that class. Sorry!");
		}

		let resultClass;
		if(classes.length > 1){
			try{
				resultClass = await super.disambiguate(toEdit, msg.author, "class", classes, "name");
			}
			catch(err){
				toEdit.edit(err);
			}
		}
		else{
			resultClass = classes[0];
		}
		let features = await FeatureModel.find({name: new RegExp(matches[2], "i"), class: resultClass.name});

		let result;
		if(features.length > 1){
			try{
				result = await super.disambiguate(toEdit, msg.author, "feature", features, "name");
			}
			catch(err){
				return toEdit.edit(err);
			}
		}
		else{
			result = features[0];
		}
		let description;
		if(result.class.length + result.text.length + result.level.length <= 1995){
			description = `*${result.class} ${result.level}*\n\n${result.text}`;
		}
		else{
			description = `*${result.class} ${result.level}*`;
			let text = result.text;
			let stringBuilder = [];

			while(text.length > 1024){
				let splitIndex = text.lastIndexOf("\n", 1024);
				stringBuilder.push(text.substring(0, splitIndex));
				text = text.substring(splitIndex + 1);
			}

			stringBuilder.forEach(e => {
				embed = embed.addField("\u200b", e);
			});
		}

		let embed = new Discord.RichEmbed().setTitle(`__**${result.name}**__`)
											.setColor(0x97ff43)
											.setDescription(description);

		toEdit.edit("", {embed: embed});
	}
};
<commit_msg>Missed a spot<commit_after>const Discord = require("discord.js");
const SearchCommand = require("../types/SearchCommand");
const Class = require("../models/Class");
const FeatureModel = require("../models/Feature");

module.exports = class Feature extends SearchCommand{
	constructor(client){
		super(client, {
			name: "feature",
			category: "5e",
			help: "Searches for a class feature by name.",
			helpArgs: "<Class Name>/<Feature Name>",
			elevation: 0,
		});
	}

	async execute(msg, args){	// eslint-disable-line no-unused-vars
		let prefix;
		if(msg.guild){
			prefix = await this.client.fetchPrefix(msg.guild.id);
		}
		else{
			prefix = "";
		}
		if(!args){
			msg.reply(`invalid command; please specify a class and feature name.\nProper usage: \`${prefix}${this.name} barbarian/primal rage\``);
		}
		let toEdit = await msg.reply("fetching your class. . .");
		let matches = /\s*(\w*.*?)\s*[^\s\w]\s*(\w*(?:\s\w+)*)\s*/.exec(args.join(" "));
		if(!matches || !matches[1] || !matches[2]){

			return msg.reply(`invalid command; please specify a class and feature name.\nProper usage: \`${prefix}${this.name} barbarian/primal rage\``);
		}

		let classes = await Class.find({name: new RegExp(matches[1], "i")});
		if(!classes || classes.length === 0){
			return toEdit.edit("Unable to find that class. Sorry!");
		}

		let resultClass;
		if(classes.length > 1){
			try{
				resultClass = await super.disambiguate(toEdit, msg.author, "class", classes, "name");
			}
			catch(err){
				toEdit.edit(err);
			}
		}
		else{
			resultClass = classes[0];
		}
		let features = await FeatureModel.find({name: new RegExp(matches[2], "i"), class: resultClass.name});

		let result;
		if(features.length > 1){
			try{
				result = await super.disambiguate(toEdit, msg.author, "feature", features, "name");
			}
			catch(err){
				return toEdit.edit(err);
			}
		}
		else{
			result = features[0];
		}
		let description;
		if(result.class.length + result.text.length + result.level.length <= 1995){
			description = `*${result.class} ${result.level}*\n\n${result.text}`;
		}
		else{
			description = `*${result.class} ${result.level}*`;
			let text = result.text;
			let stringBuilder = [];

			while(text.length > 1024){
				let splitIndex = text.lastIndexOf("\n", 1024);
				stringBuilder.push(text.substring(0, splitIndex));
				text = text.substring(splitIndex + 1);
			}

			stringBuilder.forEach(e => {
				embed = embed.addField("\u200b", e);
			});
		}

		let embed = new Discord.RichEmbed().setTitle(`__**${result.name}**__`)
											.setColor(0x97ff43)
											.setDescription(description);

		toEdit.edit("", {embed: embed});
	}
};
<|endoftext|>


<commit_before>// Copyright 2014 Globo.com Player authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import Browser from 'components/browser'
import $ from 'clappr-zepto'

export function extend(parent, properties) {
  var pluginName = properties.name||""
  class MergedPlugin extends parent {
    constructor(args) {
      super(args)
      if (properties.initialize) {
        properties.initialize.apply(this, [args])
      }
    }
    get name(){
      return pluginName
    }
  }
  delete properties.name
  $.extend(MergedPlugin, properties)
  return MergedPlugin
}

export function formatTime(time) {
    if (!isFinite(time)) {
      return "--:--"
    }
    time = time * 1000
    time = parseInt(time/1000)
    var seconds = time % 60
    time = parseInt(time/60)
    var minutes = time % 60
    time = parseInt(time/60)
    var hours = time % 24
    var days = parseInt(time/24)
    var out = ""
    if (days && days > 0) {
      out += days + ":"
      if (hours < 1) out += "00:"
    }
    if (hours && hours > 0) out += ("0" + hours).slice(-2) + ":"
    out += ("0" + minutes).slice(-2) + ":"
    out += ("0" + seconds).slice(-2)
    return out.trim()
}

export var Fullscreen = {
  isFullscreen: function() {
    return (
      document.webkitFullscreenElement ||
      document.webkitIsFullScreen ||
      document.mozFullScreen ||
      !!document.msFullscreenElement
    )
  },
  requestFullscreen: function(el) {
    if(el.requestFullscreen) {
      el.requestFullscreen()
    } else if(el.webkitRequestFullscreen) {
      el.webkitRequestFullscreen()
    } else if(el.mozRequestFullScreen) {
      el.mozRequestFullScreen()
    } else if(el.msRequestFullscreen) {
      el.msRequestFullscreen()
    } else if (el.querySelector && el.querySelector("video") && el.querySelector("video").webkitEnterFullScreen) {
      el.querySelector("video").webkitEnterFullScreen()
    }
  },
  cancelFullscreen: function() {
    if(document.exitFullscreen) {
      document.exitFullscreen()
    } else if(document.webkitCancelFullScreen) {
      document.webkitCancelFullScreen()
    } else if(document.webkitExitFullscreen) {
      document.webkitExitFullscreen()
    } else if(document.mozCancelFullScreen) {
      document.mozCancelFullScreen()
    } else if(document.msExitFullscreen) {
      document.msExitFullscreen()
    }
  }
}

export class Config {

  static _defaultConfig() {
    return {
      volume: {
        value: 100,
        parse: parseInt
      }
    }
  }

  static _defaultValueFor(key) {
    try {
      return this._defaultConfig()[key]['parse'](this._defaultConfig()[key]['value'])
    } catch(e) {
      return undefined
    }
  }

  static _create_keyspace(key){
    return 'clappr.' + document.domain + '.' + key
  }

  static restore(key) {
    if (Browser.hasLocalstorage && localStorage[this._create_keyspace(key)]){
      return this._defaultConfig()[key]['parse'](localStorage[this._create_keyspace(key)])
    }
    return this._defaultValueFor(key)
  }

  static persist(key, value) {
    if (Browser.hasLocalstorage) {
      try {
        localStorage[this._create_keyspace(key)] = value
        return true
      } catch(e) {
        return false
      }
    }
  }
}

export function seekStringToSeconds(url) {
  var parts = url.match(/t=([0-9]*)(&|\/|$)/);
  if (parts && parts.length > 0) {
    return parseInt(parts[1], 10);
  } else {
    var seconds = 0;
    var factor = {'h': 3600, 'm': 60, 's': 1};
    parts = url.match(/[0-9]+[hms]+/g) || [];
    parts.forEach(function(el) {
      if (el) {
        var suffix = el[el.length - 1];
        var time = parseInt(el.slice(0, el.length - 1), 10);
        seconds += time * (factor[suffix]);
      }
    });
    return seconds;
   }
}

var idsCounter = {}

export function uniqueId(prefix) {
  idsCounter[prefix] || (idsCounter[prefix] = 0)
  var id = ++idsCounter[prefix]
  return prefix + id
}

export function isNumber(value) {
  return value - parseFloat(value) + 1 >= 0
}

export function currentScriptUrl() {
  var scripts = document.getElementsByTagName('script')
  return scripts[scripts.length - 1].src
}

export var requestAnimationFrame = (window.requestAnimationFrame ||
                            window.mozRequestAnimationFrame ||
                            window.webkitRequestAnimationFrame ||
                            function(fn) { window.setTimeout(fn, 1000/60) }).bind(window)

export var cancelAnimationFrame = (window.cancelAnimationFrame ||
                           window.mozCancelAnimationFrame ||
                           window.webkitCancelAnimationFrame ||
                           window.clearTimeout).bind(window)

export default {
  Config,
  Fullscreen,
  extend,
  formatTime,
  seekStringToSeconds,
  uniqueId,
  currentScriptUrl,
  isNumber,
  requestAnimationFrame,
  cancelAnimationFrame
}
<commit_msg>utils.js: add getBrowserLanguage function<commit_after>// Copyright 2014 Globo.com Player authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

import Browser from 'components/browser'
import $ from 'clappr-zepto'

export function extend(parent, properties) {
  var pluginName = properties.name||""
  class MergedPlugin extends parent {
    constructor(args) {
      super(args)
      if (properties.initialize) {
        properties.initialize.apply(this, [args])
      }
    }
    get name(){
      return pluginName
    }
  }
  delete properties.name
  $.extend(MergedPlugin, properties)
  return MergedPlugin
}

export function formatTime(time) {
    if (!isFinite(time)) {
      return "--:--"
    }
    time = time * 1000
    time = parseInt(time/1000)
    var seconds = time % 60
    time = parseInt(time/60)
    var minutes = time % 60
    time = parseInt(time/60)
    var hours = time % 24
    var days = parseInt(time/24)
    var out = ""
    if (days && days > 0) {
      out += days + ":"
      if (hours < 1) out += "00:"
    }
    if (hours && hours > 0) out += ("0" + hours).slice(-2) + ":"
    out += ("0" + minutes).slice(-2) + ":"
    out += ("0" + seconds).slice(-2)
    return out.trim()
}

export var Fullscreen = {
  isFullscreen: function() {
    return (
      document.webkitFullscreenElement ||
      document.webkitIsFullScreen ||
      document.mozFullScreen ||
      !!document.msFullscreenElement
    )
  },
  requestFullscreen: function(el) {
    if(el.requestFullscreen) {
      el.requestFullscreen()
    } else if(el.webkitRequestFullscreen) {
      el.webkitRequestFullscreen()
    } else if(el.mozRequestFullScreen) {
      el.mozRequestFullScreen()
    } else if(el.msRequestFullscreen) {
      el.msRequestFullscreen()
    } else if (el.querySelector && el.querySelector("video") && el.querySelector("video").webkitEnterFullScreen) {
      el.querySelector("video").webkitEnterFullScreen()
    }
  },
  cancelFullscreen: function() {
    if(document.exitFullscreen) {
      document.exitFullscreen()
    } else if(document.webkitCancelFullScreen) {
      document.webkitCancelFullScreen()
    } else if(document.webkitExitFullscreen) {
      document.webkitExitFullscreen()
    } else if(document.mozCancelFullScreen) {
      document.mozCancelFullScreen()
    } else if(document.msExitFullscreen) {
      document.msExitFullscreen()
    }
  }
}

export class Config {

  static _defaultConfig() {
    return {
      volume: {
        value: 100,
        parse: parseInt
      }
    }
  }

  static _defaultValueFor(key) {
    try {
      return this._defaultConfig()[key]['parse'](this._defaultConfig()[key]['value'])
    } catch(e) {
      return undefined
    }
  }

  static _create_keyspace(key){
    return 'clappr.' + document.domain + '.' + key
  }

  static restore(key) {
    if (Browser.hasLocalstorage && localStorage[this._create_keyspace(key)]){
      return this._defaultConfig()[key]['parse'](localStorage[this._create_keyspace(key)])
    }
    return this._defaultValueFor(key)
  }

  static persist(key, value) {
    if (Browser.hasLocalstorage) {
      try {
        localStorage[this._create_keyspace(key)] = value
        return true
      } catch(e) {
        return false
      }
    }
  }
}

export function seekStringToSeconds(url) {
  var parts = url.match(/t=([0-9]*)(&|\/|$)/);
  if (parts && parts.length > 0) {
    return parseInt(parts[1], 10);
  } else {
    var seconds = 0;
    var factor = {'h': 3600, 'm': 60, 's': 1};
    parts = url.match(/[0-9]+[hms]+/g) || [];
    parts.forEach(function(el) {
      if (el) {
        var suffix = el[el.length - 1];
        var time = parseInt(el.slice(0, el.length - 1), 10);
        seconds += time * (factor[suffix]);
      }
    });
    return seconds;
   }
}

var idsCounter = {}

export function uniqueId(prefix) {
  idsCounter[prefix] || (idsCounter[prefix] = 0)
  var id = ++idsCounter[prefix]
  return prefix + id
}

export function isNumber(value) {
  return value - parseFloat(value) + 1 >= 0
}

export function currentScriptUrl() {
  var scripts = document.getElementsByTagName('script')
  return scripts[scripts.length - 1].src
}

export var requestAnimationFrame = (window.requestAnimationFrame ||
                            window.mozRequestAnimationFrame ||
                            window.webkitRequestAnimationFrame ||
                            function(fn) { window.setTimeout(fn, 1000/60) }).bind(window)

export var cancelAnimationFrame = (window.cancelAnimationFrame ||
                           window.mozCancelAnimationFrame ||
                           window.webkitCancelAnimationFrame ||
                           window.clearTimeout).bind(window)

export function getBrowserLanguage() {
  if (window.navigator && window.navigator.language) {
    return window.navigator.language.toLowerCase()
  }
  return null
}

export default {
  Config,
  Fullscreen,
  extend,
  formatTime,
  seekStringToSeconds,
  uniqueId,
  currentScriptUrl,
  isNumber,
  requestAnimationFrame,
  cancelAnimationFrame,
  getBrowserLanguage
}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////
// init.js: Utility functions, Root Object definition      //
//                                                         //
// In this file, utility functions that are used elsewhere //
// in the code are all declared (test, json_post).         //
//                                                         //
// In addition, a root object, AV, is declared, for the    //
// purposes of nice, pleasant namespacing.                 //
/////////////////////////////////////////////////////////////

function test(arg){
	var output = arg || 'fire';
	console.log(output);
}

function json_post(url,data,callback,flag){
	data = data || '';
	callback = callback || '';
	flag = flag || 'default';
	$.ajax({
		url: url,
		type: 'POST',
		data: JSON.stringify(data),
		contentType: 'application/json',
		success: callback,
		error: function(e){test(flag); test(e);}
	});
}

var AV = {};
AV.WORKSPACE = 'public';
<commit_msg>Add global URL generator method<commit_after>/////////////////////////////////////////////////////////////
// init.js: Utility functions, Root Object definition      //
//                                                         //
// In this file, utility functions that are used elsewhere //
// in the code are all declared (test, json_post).         //
//                                                         //
// In addition, a root object, AV, is declared, for the    //
// purposes of nice, pleasant namespacing.                 //
/////////////////////////////////////////////////////////////

function test(arg){
	var output = arg || 'fire';
	console.log(output);
}

function json_post(url,data,callback,flag){
	data = data || '';
	callback = callback || '';
	flag = flag || 'default';
	$.ajax({
		url: url,
		type: 'POST',
		data: JSON.stringify(data),
		contentType: 'application/json',
		success: callback,
		error: function(e){test(flag); test(e);}
	});
}

var AV = {};
AV.WORKSPACE = 'public';
AV.URL = function(path) {
    path = path ? path : '';
    return '/juxta/' + AV.WORKSPACE + '/' + path;
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {

    grunt.initConfig({
        concat: {
            js: {
                src: [
                    'public/bower/angular/angular.min.js',
                    'public/bower/angular-ui-router/release/angular-ui-router.min.js',
                    'public/bower/textAngular/dist/textAngular-rangy.min.js',
                    'public/bower/textAngular/dist/textAngular-sanitize.min.js',
                    'public/bower/textAngular/dist/textAngular.min.js',
                    'app/app.js',
                    'app/factories.js',
                    'app/controllers.js'
                ],
                dest: 'app/scripts.js'
            },
            css: {
                src: [
                    'public/bower/bootstrap/dist/css/bootstrap.min.css',
                    'public/bower/font-awesome/css/font-awesome.min.css',
                    'public/bower/textAngular/dist/textAngular.css',
                    'public/css/admin/admin.css'
                ],
                dest: 'public/css/admin/bundle.css'
            }
        },
        watch: {
            scripts: {
                files: ['app/**/*.js'],
                tasks: ['concat']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default', ['concat', 'watch']);

};<commit_msg>update gruntfile<commit_after>module.exports = function(grunt) {

    grunt.initConfig({
        concat: {
            js: {
                src: [
                    'public/bower/angular/angular.min.js',
                    'public/bower/angular-ui-router/release/angular-ui-router.min.js',
                    'public/bower/textAngular/dist/textAngular-rangy.min.js',
                    'public/bower/textAngular/dist/textAngular-sanitize.min.js',
                    'public/bower/textAngular/dist/textAngular.min.js',
                    'app/app.js',
                    'app/factories.js',
                    'app/controllers.js'
                ],
                dest: 'app/scripts.js'
            },
            css: {
                src: [
                    'public/bower/bootstrap/dist/css/bootstrap.min.css',
                    'public/bower/textAngular/dist/textAngular.css',
                    'public/css/admin/admin.css'
                ],
                dest: 'public/css/admin/bundle.css'
            }
        },
        watch: {
            scripts: {
                files: ['app/**/*.js'],
                tasks: ['concat']
            },
            css: {
                files: ['public/css/admin/**/*.css'],
                tasks: ['concat']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default', ['concat', 'watch']);

};<|endoftext|>


<commit_before>$(function(){
    var report_template = _.template($('#report-template').html());

    removeColumn = function() {
        geoid = $(this).attr('data-val');
        if (document.location.pathname.indexOf('/' + geoid) > 0) {
            document.location.pathname = document.location.pathname.replace(geoid + ',', '');
        } else {
            document.location.pathname = document.location.pathname.replace(',' + geoid, '');
        }
    }

    twistRow = function() {
        var show_child = !$($('tr[parent=' + $(this).attr('id') + ']')[0]).is(":visible");
        twistRowHelper($(this), show_child);
        $(this).toggleClass('closed')
        $(this).toggleClass('open');
    }

    twistRowHelper = function(parent_row, show_me) {
        $.each($('tr[parent=' + $(parent_row).attr('id') + ']'), function(index, value){
            if(show_me){
                $(value).show();
            } else {
                $(value).hide();
            }
            twistRowHelper(value, false);
        });
    }

    addRelatedState = function() {
        this_geoid = $(this).attr('data-val');
        state_geoid = this_geoid.slice(0,2);

        window.location.pathname = window.location.pathname.replace('.html', "," + state_geoid + '.html');
    }

    addRelatedCounty = function() {
        this_geoid = $(this).attr('data-val');
        county_geoid = this_geoid.slice(0,5);

        window.location.pathname = window.location.pathname.replace('.html', "," + county_geoid + '.html');
    }

    window.apiRequest = function(path, callback, handler) {
        $.ajax(API_URL + path, {
            dataType: "jsonp",
            jsonpCallback: callback,
            success: handler
        });
    }

    window.parseGeoids = function() {
        // Get url without hashbang
        var target = _.last(window.location.pathname.split("/"));

        // Ditch the .html
        target = _.first(target.split("."));

        // Split the list
        geoids = target.split(",");

        return geoids;
    }

    window.downloadData = function(format) {
        var url = "/data/" + window.geoids.join(",") + "." + format;

        if (window.location.hash != "") {
             url += "?tables=" + window.location.hash.substring(1);
        }

        window.location = url;
    }

    window.loadLabels = function() {
        apiRequest("/" + window.DATASET + "_labels.jsonp", "labels_" + window.DATASET, function(labels_data) {
            window.labels_data = labels_data;
            window.geoids = parseGeoids();

            window.tables = _.keys(labels_data["tables"])
            window.tables.sort();

            _.each(window.tables, function(table) {
                $('#reports').append($('

'));
            });

            geographies = new Array();

            _.each(geoids, function(geoid) {
                apiRequest("/" + geoid + ".jsonp", "geoid_" + geoid, function(geography_data) {
                    geographies.push(geography_data);

                    // If all geographies have been loaded, make reports
                    if (geographies.length == geoids.length) {
                        // Sort geographies by url order since the return order isn't deterministic
                        window.geographies = _.sortBy(geographies, function(geography) {
                            return _.indexOf(geoids, geography["geoid"]);
                        });

                        // Browser handles displaying reports
                        startBrowser();
                    }
                });
            });
        });
    }

    window.makeReport = function(table, labelset, geoids, geographies) {
        var report = {
            'key': labelset["key"],
            'name': labelset['name'],
            'table': labelset["key"] + ". " + labelset['name'],
            'universe': labelset['universe'],
            'columns': [],
            'rows': []
        };

        var labels = _.sortBy(labelset["labels"], function(label) {
            return label["key"];
        });

        _.each(labels, function(label) {
            row = {
                "key": label["key"],
                "label": label,
                "data": []
            }

            _.each(geographies, function(geography) {
                var d = new Object();

                _.each(["2000", "2010", "delta", "pct_change"], function(year) {
                    try {
                        d[year] = geography["data"][year][table][label["key"]];
                    } catch(err) {
                    }
                });

                row["data"].push(d);
            });

            report["rows"].push(row);
        });

        _.each(geographies, function(geography) {
            var column_meta = {};
            column_name = geography["metadata"]["NAME"];

            // TODO
            if ($.inArray(geography["sumlev"], [SUMLEV_COUNTY, SUMLEV_PLACE, SUMLEV_TRACT]) >= 0) {
                state_fips = geography["metadata"]["STATE"];
                state_name = _.detect(window.query.mappings.states, function(state) {
                    return state[1] == state_fips;
                })[0];
                column_name += ", " + state_name;
            }

            column_meta["name"] = column_name;
            column_meta["geoid"] = geography["geoid"];
            column_meta["sumlev"] = geography["sumlev"];

            report["columns"].push(column_meta);
        });

        report["geoids"] = geoids;
        report["show_remove_button"] = (geoids.length > 1);

        return report;
    }

    window.floatFormat = function(n, decimals) {
        if (_.isString(n)) {
            try {
                n = parseFloat(n);
            } catch(err) {
                return "";
            }
        }

        if (_.isUndefined(n) || _.isNaN(n)) {
            return "";
        }

        if (n % 1 == 0) {
            return Math.round(n);
        }

        if (_.isUndefined(decimals)) {
            decimals = 1;
        }

        pow = Math.pow(10, decimals);

        return Math.round(n * pow) / pow;
    }

    window.toPercent = function(n) {
        if (_.isString(n)) {
            try {
                n = parseFloat(n);
            } catch(err) {
                return "";
            }
        }

        if (_.isUndefined(n) || _.isNaN(n)) {
            return "";
        }

        return n * 100;
    }

    window.intComma = function(n) {
        // Algorithm from Django template tags
        // http://code.djangoproject.com/svn/django/trunk/django/contrib/humanize/templatetags/humanize.py
        if (_.isUndefined(n) || _.isNaN(n)) {
            return "";
        }

        orig = n
        n = n.toString().replace(/^(-?\d+)(\d{3}\.?\d*)/g, "$1,$2");

        if (n == orig) {
            return n;
        } else {
            return intComma(n);
        }
    }

    window.renderReport = function(report) {
        var html = report_template(report);

        $('#report-wrapper-' + report["key"]).append(html);
    }

    // Add event hooks
    $('#report-' + table + ' .button.remove-column').live("click", removeColumn);
    $('#report-' + table + ' tr.row').live("click", this.twistRow);
    $('#report-' + table + ' .button.add-related-state').live("click", this.addRelatedState);
    $('#report-' + table + ' .button.add-related-county').live("click", this.addRelatedCounty);
    $('nav .csv').live("click", function () { downloadData("csv"); });
    $('nav .json').live("click", function () { downloadData("json"); });
    $('nav .kml').live("click", function () { downloadData("kml"); });

    // Table mouseover row highlighting.
    $('#report-' + table + '.report').delegate('td', 'mouseover mouseleave', function(e) {
        if (e.type == 'mouseover') {
            status = ''
            $(this).addClass("selected");
            $(this).parent().addClass("highlight");
            status = $(this).parent().find('.label').text();
            if ($(this).index() > 0) {
                $("colgroup", $(this).parents("table")).eq($(this).index()).addClass("highlight"); //column
                status += ', ' + $($(this).parents("table").find('.locationdef')[Math.ceil($(this).index()/4) - 1]).clone().find('*').remove().end().text().trim();
                status += ', ' + $($(this).parents("table").find('.subhead')[$(this).index() - 1]).text().trim();
            }
            $('#status').show().text(status);
        } else {
            $(this).removeClass("selected");
            $(this).parent().removeClass('highlight');
            if ($(this).index() > 0)
                $("colgroup", $(this).parents("table")).eq($(this).index()).removeClass("highlight");
            $('#status').hide();
        }
    });

    // Kick-off
    loadLabels();
});
<commit_msg>Fix event hooks.<commit_after>$(function(){
    var report_template = _.template($('#report-template').html());

    removeColumn = function() {
        geoid = $(this).attr('data-val');
        if (document.location.pathname.indexOf('/' + geoid) > 0) {
            document.location.pathname = document.location.pathname.replace(geoid + ',', '');
        } else {
            document.location.pathname = document.location.pathname.replace(',' + geoid, '');
        }
    }

    twistRow = function() {
        var show_child = !$($('tr[parent=' + $(this).attr('id') + ']')[0]).is(":visible");
        twistRowHelper($(this), show_child);
        $(this).toggleClass('closed')
        $(this).toggleClass('open');
    }

    twistRowHelper = function(parent_row, show_me) {
        $.each($('tr[parent=' + $(parent_row).attr('id') + ']'), function(index, value){
            if(show_me){
                $(value).show();
            } else {
                $(value).hide();
            }
            twistRowHelper(value, false);
        });
    }

    addRelatedState = function() {
        this_geoid = $(this).attr('data-val');
        state_geoid = this_geoid.slice(0,2);

        window.location.pathname = window.location.pathname.replace('.html', "," + state_geoid + '.html');
    }

    addRelatedCounty = function() {
        this_geoid = $(this).attr('data-val');
        county_geoid = this_geoid.slice(0,5);

        window.location.pathname = window.location.pathname.replace('.html', "," + county_geoid + '.html');
    }

    window.apiRequest = function(path, callback, handler) {
        $.ajax(API_URL + path, {
            dataType: "jsonp",
            jsonpCallback: callback,
            success: handler
        });
    }

    window.parseGeoids = function() {
        // Get url without hashbang
        var target = _.last(window.location.pathname.split("/"));

        // Ditch the .html
        target = _.first(target.split("."));

        // Split the list
        geoids = target.split(",");

        return geoids;
    }

    window.downloadData = function(format) {
        var url = "/data/" + window.geoids.join(",") + "." + format;

        if (window.location.hash != "") {
             url += "?tables=" + window.location.hash.substring(1);
        }

        window.location = url;
    }

    window.loadLabels = function() {
        apiRequest("/" + window.DATASET + "_labels.jsonp", "labels_" + window.DATASET, function(labels_data) {
            window.labels_data = labels_data;
            window.geoids = parseGeoids();

            window.tables = _.keys(labels_data["tables"])
            window.tables.sort();

            _.each(window.tables, function(table) {
                $('#reports').append($('

'));
            });

            geographies = new Array();

            _.each(geoids, function(geoid) {
                apiRequest("/" + geoid + ".jsonp", "geoid_" + geoid, function(geography_data) {
                    geographies.push(geography_data);

                    // If all geographies have been loaded, make reports
                    if (geographies.length == geoids.length) {
                        // Sort geographies by url order since the return order isn't deterministic
                        window.geographies = _.sortBy(geographies, function(geography) {
                            return _.indexOf(geoids, geography["geoid"]);
                        });

                        // Browser handles displaying reports
                        startBrowser();
                    }
                });
            });
        });
    }

    window.makeReport = function(table, labelset, geoids, geographies) {
        var report = {
            'key': labelset["key"],
            'name': labelset['name'],
            'table': labelset["key"] + ". " + labelset['name'],
            'universe': labelset['universe'],
            'columns': [],
            'rows': []
        };

        var labels = _.sortBy(labelset["labels"], function(label) {
            return label["key"];
        });

        _.each(labels, function(label) {
            row = {
                "key": label["key"],
                "label": label,
                "data": []
            }

            _.each(geographies, function(geography) {
                var d = new Object();

                _.each(["2000", "2010", "delta", "pct_change"], function(year) {
                    try {
                        d[year] = geography["data"][year][table][label["key"]];
                    } catch(err) {
                    }
                });

                row["data"].push(d);
            });

            report["rows"].push(row);
        });

        _.each(geographies, function(geography) {
            var column_meta = {};
            column_name = geography["metadata"]["NAME"];

            // TODO
            if ($.inArray(geography["sumlev"], [SUMLEV_COUNTY, SUMLEV_PLACE, SUMLEV_TRACT]) >= 0) {
                state_fips = geography["metadata"]["STATE"];
                state_name = _.detect(window.query.mappings.states, function(state) {
                    return state[1] == state_fips;
                })[0];
                column_name += ", " + state_name;
            }

            column_meta["name"] = column_name;
            column_meta["geoid"] = geography["geoid"];
            column_meta["sumlev"] = geography["sumlev"];

            report["columns"].push(column_meta);
        });

        report["geoids"] = geoids;
        report["show_remove_button"] = (geoids.length > 1);

        return report;
    }

    window.floatFormat = function(n, decimals) {
        if (_.isString(n)) {
            try {
                n = parseFloat(n);
            } catch(err) {
                return "";
            }
        }

        if (_.isUndefined(n) || _.isNaN(n)) {
            return "";
        }

        if (n % 1 == 0) {
            return Math.round(n);
        }

        if (_.isUndefined(decimals)) {
            decimals = 1;
        }

        pow = Math.pow(10, decimals);

        return Math.round(n * pow) / pow;
    }

    window.toPercent = function(n) {
        if (_.isString(n)) {
            try {
                n = parseFloat(n);
            } catch(err) {
                return "";
            }
        }

        if (_.isUndefined(n) || _.isNaN(n)) {
            return "";
        }

        return n * 100;
    }

    window.intComma = function(n) {
        // Algorithm from Django template tags
        // http://code.djangoproject.com/svn/django/trunk/django/contrib/humanize/templatetags/humanize.py
        if (_.isUndefined(n) || _.isNaN(n)) {
            return "";
        }

        orig = n
        n = n.toString().replace(/^(-?\d+)(\d{3}\.?\d*)/g, "$1,$2");

        if (n == orig) {
            return n;
        } else {
            return intComma(n);
        }
    }

    window.renderReport = function(report) {
        var html = report_template(report);

        $('#report-wrapper-' + report["key"]).append(html);
    }

    // Add event hooks
    $('.report .button.remove-column').live("click", removeColumn);
    $('.report tr.row').live("click", this.twistRow);
    $('.report .button.add-related-state').live("click", this.addRelatedState);
    $('.report .button.add-related-county').live("click", this.addRelatedCounty);
    $('nav .csv').live("click", function () { downloadData("csv"); });
    $('nav .json').live("click", function () { downloadData("json"); });
    $('nav .kml').live("click", function () { downloadData("kml"); });

    // Table mouseover row highlighting.
    $('#report-' + table + '.report').delegate('td', 'mouseover mouseleave', function(e) {
        if (e.type == 'mouseover') {
            status = ''
            $(this).addClass("selected");
            $(this).parent().addClass("highlight");
            status = $(this).parent().find('.label').text();
            if ($(this).index() > 0) {
                $("colgroup", $(this).parents("table")).eq($(this).index()).addClass("highlight"); //column
                status += ', ' + $($(this).parents("table").find('.locationdef')[Math.ceil($(this).index()/4) - 1]).clone().find('*').remove().end().text().trim();
                status += ', ' + $($(this).parents("table").find('.subhead')[$(this).index() - 1]).text().trim();
            }
            $('#status').show().text(status);
        } else {
            $(this).removeClass("selected");
            $(this).parent().removeClass('highlight');
            if ($(this).index() > 0)
                $("colgroup", $(this).parents("table")).eq($(this).index()).removeClass("highlight");
            $('#status').hide();
        }
    });

    // Kick-off
    loadLabels();
});
<|endoftext|>


<commit_before><commit_msg>Make string replacements work without passing a magic extra parameter<commit_after><|endoftext|>


<commit_before>/**
 * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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', 'log', 'jquery', 'lodash', 'partitionWith', 'jsonValidator', 'handlebar', 'constants'],
    function (require, log, $, _, PartitionWith, JSONValidator, Handlebars, Constants) {

        /**
         * @class PartitionForm Creates a forms to collect data from a partition
         * @constructor
         * @param {Object} options Rendering options for the view
         */
        var PartitionForm = function (options) {
            if (options !== undefined) {
                this.configurationData = options.configurationData;
                this.application = options.application;
                this.consoleListManager = options.application.outputController;
                this.formUtils = options.formUtils;
                this.jsPlumbInstance = options.jsPlumbInstance;
                var currentTabId = this.application.tabController.activeTab.cid;
                this.designViewContainer = $('#design-container-' + currentTabId);
                this.toggleViewButton = $('#toggle-view-button-' + currentTabId);
            }
        };

        /**
         * Function to check if the connected streams are filled
         * @param {Object} partitionWithList
         * @return {boolean} isFilled
         */
        var ifStreamsAreFilled = function (partitionWithList) {
            var isFilled = false;
            _.forEach(partitionWithList, function (partitionKey) {
                if (partitionKey.getStreamName()) {
                    isFilled = true;
                    return false;
                }
            });
            return isFilled;
        };

        /**
         * @function generate form for Partition
         * @param element selected element(partition)
         * @param formConsole Console which holds the form
         * @param formContainer Container which holds the form
         */
        PartitionForm.prototype.generatePropertiesForm = function (element, formConsole, formContainer) {
            var self = this;
            var id = $(element).parent().attr('id');
            var partitionObject = self.configurationData.getSiddhiAppConfig().getPartition(id);
            var partitionWithList = partitionObject.getPartitionWith();

            if (!partitionWithList || partitionWithList.length === 0) {
                $("#" + id).addClass('incomplete-element');
                $('#' + id).prop('title', 'Connect a stream for partitioning');

                // design view container and toggle view button are enabled
                self.designViewContainer.removeClass('disableContainer');
                self.toggleViewButton.removeClass('disableContainer');
                // close the form window
                self.consoleListManager.removeFormConsole(formConsole);
            } else {
                if (!ifStreamsAreFilled(partitionWithList)) {
                    $("#" + id).addClass('incomplete-element');
                    $('#' + id).prop('title', 'To edit partition configuration, fill the connected stream.');

                    // design view container and toggle view button are enabled
                    self.designViewContainer.removeClass('disableContainer');
                    self.toggleViewButton.removeClass('disableContainer');
                    // close the form window
                    self.consoleListManager.removeFormConsole(formConsole);
                } else {
                    var propertyDiv = $('

 ' +
                        self.formUtils.buildFormButtons() + '
' +
                        '

');

                    formContainer.append(propertyDiv);
                    self.formUtils.popUpSelectedElement(id);
                    // design view container and toggle view button are enabled
                    self.designViewContainer.addClass('disableContainer');
                    self.toggleViewButton.addClass('disableContainer');

                    var annotationListObjects = partitionObject.getAnnotationListObjects();
                    self.formUtils.renderAnnotationTemplate("define-annotation", annotationListObjects);

                    var partitionKeys = [];
                    for (var i = 0; i < partitionWithList.length; i++) {
                        if (partitionWithList[i].getStreamName()) {
                            var partitionKey = {
                                expression: partitionWithList[i].getExpression(),
                                streamName: partitionWithList[i].getStreamName()
                            };
                            partitionKeys.push(partitionKey);
                        }
                    }
                    var partitionFormTemplate = Handlebars.compile($('#partition-by-template').html())(partitionKeys);
                    $('#define-partition-keys').html(partitionFormTemplate);

                    self.formUtils.addEventListenerToRemoveRequiredClass();

                    // 'Submit' button action
                    $(formContainer).on('click', '#btn-submit', function () {

                        self.formUtils.removeErrorClass();
                        var isErrorOccurred = false;

                        var partitionKeys = [];
                        $('#partition-by-content .partition-key').each(function () {
                            var expression = $(this).find('.partition-by-expression').val().trim();
                            if (expression === "") {
                                self.formUtils.addErrorClass($(this).find('.partition-by-expression'));
                                $(this).find('.error-message').text("Expression value is required.")
                                isErrorOccurred = true;
                                return false;
                            } else {
                                var streamName = $(this).find('.partition-by-stream-name').val().trim();
                                var partitionKey = {
                                    expression: expression,
                                    streamName: streamName
                                };
                                partitionKeys.push(partitionKey);
                            }
                        });

                        if (!isErrorOccurred) {
                            partitionObject.clearPartitionWith();
                            _.forEach(partitionKeys, function (partitionKey) {
                                var partitionWithObject = new PartitionWith(partitionKey);
                                partitionObject.addPartitionWith(partitionWithObject);
                            });

                            var isValid = JSONValidator.prototype.validatePartition(partitionObject, self.jsPlumbInstance,
                                false);
                            if (!isValid) {
                                return;
                            }

                            partitionObject.clearAnnotationList();
                            partitionObject.clearAnnotationListObjects();
                            var annotationStringList = [];
                            var annotationObjectList = [];
                            var annotationNodes = $('#annotation-div').jstree(true)._model.data['#'].children;
                            self.formUtils.buildAnnotation(annotationNodes, annotationStringList, annotationObjectList);
                            _.forEach(annotationStringList, function (annotation) {
                                partitionObject.addAnnotation(annotation);
                            });
                            _.forEach(annotationObjectList, function (annotation) {
                                partitionObject.addAnnotationObject(annotation);
                            });

                            $('#' + id).removeClass('incomplete-element');
                            //Send partition element to the backend and generate tooltip
                            var partitionToolTip = self.formUtils.getTooltip(partitionObject, Constants.PARTITION);
                            $('#' + id).prop('title', partitionToolTip);

                            // set the isDesignViewContentChanged to true
                            self.configurationData.setIsDesignViewContentChanged(true);
                            // design view container and toggle view button are enabled
                            self.designViewContainer.removeClass('disableContainer');
                            self.toggleViewButton.removeClass('disableContainer');
                            // close the form window
                            self.consoleListManager.removeFormConsole(formConsole);
                        }
                    });

                    // 'Cancel' button action
                    var cancelButtonElement = $(formContainer).find('#btn-cancel')[0];
                    cancelButtonElement.addEventListener('click', function () {
                        self.designViewContainer.removeClass('disableContainer');
                        self.toggleViewButton.removeClass('disableContainer');
                        // close the form window
                        self.consoleListManager.removeFormConsole(formConsole);
                    });
                }
            }
        };

        return PartitionForm;
    });

<commit_msg>Fix - use select box for partition expression<commit_after>/**
 * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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', 'log', 'jquery', 'lodash', 'partitionWith', 'jsonValidator', 'handlebar', 'constants'],
    function (require, log, $, _, PartitionWith, JSONValidator, Handlebars, Constants) {

        /**
         * @class PartitionForm Creates a forms to collect data from a partition
         * @constructor
         * @param {Object} options Rendering options for the view
         */
        var PartitionForm = function (options) {
            if (options !== undefined) {
                this.configurationData = options.configurationData;
                this.application = options.application;
                this.consoleListManager = options.application.outputController;
                this.formUtils = options.formUtils;
                this.jsPlumbInstance = options.jsPlumbInstance;
                var currentTabId = this.application.tabController.activeTab.cid;
                this.designViewContainer = $('#design-container-' + currentTabId);
                this.toggleViewButton = $('#toggle-view-button-' + currentTabId);
            }
        };

        /**
         * Function to check if the connected streams are filled
         * @param {Object} partitionWithList
         * @return {boolean} isFilled
         */
        var ifStreamsAreFilled = function (partitionWithList) {
            var isFilled = false;
            _.forEach(partitionWithList, function (partitionKey) {
                if (partitionKey.getStreamName()) {
                    isFilled = true;
                    return false;
                }
            });
            return isFilled;
        };

        /**
         * @function to get the attribute names of the connected stream
         */
        var getAttributeNames = function (streamName, self) {
            var connectedElement = self.configurationData.getSiddhiAppConfig().getDefinitionElementByName(streamName);
            var attributes = [];
            _.forEach(connectedElement.element.getAttributeList(), function (attribute) {
                attributes.push(attribute.getName());
            });
            return attributes;
        };

        /**
         * @function generate form for Partition
         * @param element selected element(partition)
         * @param formConsole Console which holds the form
         * @param formContainer Container which holds the form
         */
        PartitionForm.prototype.generatePropertiesForm = function (element, formConsole, formContainer) {
            var self = this;
            var id = $(element).parent().attr('id');
            var partitionObject = self.configurationData.getSiddhiAppConfig().getPartition(id);
            var partitionWithList = partitionObject.getPartitionWith();

            if (!partitionWithList || partitionWithList.length === 0) {
                $("#" + id).addClass('incomplete-element');
                $('#' + id).prop('title', 'Connect a stream for partitioning');

                // design view container and toggle view button are enabled
                self.designViewContainer.removeClass('disableContainer');
                self.toggleViewButton.removeClass('disableContainer');
                // close the form window
                self.consoleListManager.removeFormConsole(formConsole);
            } else {
                if (!ifStreamsAreFilled(partitionWithList)) {
                    $("#" + id).addClass('incomplete-element');
                    $('#' + id).prop('title', 'To edit partition configuration, fill the connected stream.');

                    // design view container and toggle view button are enabled
                    self.designViewContainer.removeClass('disableContainer');
                    self.toggleViewButton.removeClass('disableContainer');
                    // close the form window
                    self.consoleListManager.removeFormConsole(formConsole);
                } else {
                    var propertyDiv = $('

 ' +
                        self.formUtils.buildFormButtons() + '
' +
                        '

');

                    formContainer.append(propertyDiv);
                    self.formUtils.popUpSelectedElement(id);
                    // design view container and toggle view button are enabled
                    self.designViewContainer.addClass('disableContainer');
                    self.toggleViewButton.addClass('disableContainer');

                    var annotationListObjects = partitionObject.getAnnotationListObjects();
                    self.formUtils.renderAnnotationTemplate("define-annotation", annotationListObjects);

                    var partitionKeys = [];
                    for (var i = 0; i < partitionWithList.length; i++) {
                        if (partitionWithList[i].getStreamName()) {
                            var partitionKey = {
                                expression: partitionWithList[i].getExpression(),
                                streamName: partitionWithList[i].getStreamName(),
                                streamAttributes: {
                                    id: "partition-by-expression",
                                    options: getAttributeNames(partitionWithList[i].getStreamName(), self)
                                }
                            };
                            partitionKeys.push(partitionKey);
                        }
                    }
                    self.formUtils.registerDropDownPartial();
                    var partitionFormTemplate = Handlebars.compile($('#partition-by-template').html())(partitionKeys);
                    $('#define-partition-keys').html(partitionFormTemplate);

                    //to map partition expressions
                    var i = 0;
                    $('.partition-key').each(function () {
                        $(this).find('.partition-by-expression-selection option').filter(function () {
                            return ($(this).val() == (partitionKeys[i].expression));
                        }).prop('selected', true);
                        i++;
                    });

                    self.formUtils.addEventListenerToRemoveRequiredClass();

                    // 'Submit' button action
                    $(formContainer).on('click', '#btn-submit', function () {

                        self.formUtils.removeErrorClass();
                        var isErrorOccurred = false;

                        var partitionKeys = [];
                        $('#partition-by-content .partition-key').each(function () {
                            var expression = $(this).find('.partition-by-expression-selection').val();
                            var streamName = $(this).find('.partition-by-stream-name').val().trim();
                            var partitionKey = {
                                expression: expression,
                                streamName: streamName
                            };
                            partitionKeys.push(partitionKey);

                        });

                        if (!isErrorOccurred) {
                            partitionObject.clearPartitionWith();
                            _.forEach(partitionKeys, function (partitionKey) {
                                var partitionWithObject = new PartitionWith(partitionKey);
                                partitionObject.addPartitionWith(partitionWithObject);
                            });

                            var isValid = JSONValidator.prototype.validatePartition(partitionObject, self.jsPlumbInstance,
                                false);
                            if (!isValid) {
                                return;
                            }

                            partitionObject.clearAnnotationList();
                            partitionObject.clearAnnotationListObjects();
                            var annotationStringList = [];
                            var annotationObjectList = [];
                            var annotationNodes = $('#annotation-div').jstree(true)._model.data['#'].children;
                            self.formUtils.buildAnnotation(annotationNodes, annotationStringList, annotationObjectList);
                            _.forEach(annotationStringList, function (annotation) {
                                partitionObject.addAnnotation(annotation);
                            });
                            _.forEach(annotationObjectList, function (annotation) {
                                partitionObject.addAnnotationObject(annotation);
                            });

                            $('#' + id).removeClass('incomplete-element');
                            //Send partition element to the backend and generate tooltip
                            var partitionToolTip = self.formUtils.getTooltip(partitionObject, Constants.PARTITION);
                            $('#' + id).prop('title', partitionToolTip);

                            // set the isDesignViewContentChanged to true
                            self.configurationData.setIsDesignViewContentChanged(true);
                            // design view container and toggle view button are enabled
                            self.designViewContainer.removeClass('disableContainer');
                            self.toggleViewButton.removeClass('disableContainer');
                            // close the form window
                            self.consoleListManager.removeFormConsole(formConsole);
                        }
                    });

                    // 'Cancel' button action
                    var cancelButtonElement = $(formContainer).find('#btn-cancel')[0];
                    cancelButtonElement.addEventListener('click', function () {
                        self.designViewContainer.removeClass('disableContainer');
                        self.toggleViewButton.removeClass('disableContainer');
                        // close the form window
                        self.consoleListManager.removeFormConsole(formConsole);
                    });
                }
            }
        };

        return PartitionForm;
    });

<|endoftext|>


<commit_before>/**
 * Radio modile.
 */

(function(){

    /* Radio */
    function radio_constructor(){

        this.layer_name = 'radio';

        this.row_blocks = ['number', 'name'];

        this.load_params = {
            'type'   : 'radio',
            'action' : 'get_ordered_list'
        };

        this.superclass = Layer.prototype;

        this.hide = function(do_not_reset){
            _debug('radio.hide');

            this.superclass.hide.call(this, do_not_reset);
            stb.player.stop();
            this.update_header_path([{"alias" : "playing", "item" : "*"}]);
        };

        this.bind = function(){
            this.superclass.bind.apply(this);

            this.play.bind(key.OK, this);

            (function(){

                if (stb.player.on){
                    stb.player.stop();
                    this.update_header_path([{"alias" : "playing", "item" : "*"}]);
                    return;
                }

                this.hide();
                main_menu.show();
            }).bind(key.EXIT, this);

            (function(){
                this.hide();
                main_menu.show();
            }).bind(key.LEFT, this).bind(key.MENU, this);
        };

        this.play = function(){
            _debug('radio.play');

            this.update_header_path([{"alias" : "playing", "item" : this.data_items[this.cur_row].name}]);

            stb.player.need_show_info = 1;
            stb.player.play(this.data_items[this.cur_row]);
        };
    }

    radio_constructor.prototype = new Layer();

    var radio = new radio_constructor();

    radio.bind();
    radio.init();

    radio.init_left_ear('ears_back');

    radio.init_header_path('РАДИО');

    radio.hide();

    module.radio = radio;

    /* END RADIO */

    /* Integrate karaoke in main menu */

    main_menu.add('РАДИО', [], function(){
        main_menu.hide();
        module.radio.show();
    });

})();

loader.next();<commit_msg>"Add main_menu image"<commit_after>/**
 * Radio modile.
 */

(function(){

    /* Radio */
    function radio_constructor(){

        this.layer_name = 'radio';

        this.row_blocks = ['number', 'name'];

        this.load_params = {
            'type'   : 'radio',
            'action' : 'get_ordered_list'
        };

        this.superclass = Layer.prototype;

        this.hide = function(do_not_reset){
            _debug('radio.hide');

            this.superclass.hide.call(this, do_not_reset);
            stb.player.stop();
            this.update_header_path([{"alias" : "playing", "item" : "*"}]);
        };

        this.bind = function(){
            this.superclass.bind.apply(this);

            this.play.bind(key.OK, this);

            (function(){

                if (stb.player.on){
                    stb.player.stop();
                    this.update_header_path([{"alias" : "playing", "item" : "*"}]);
                    return;
                }

                this.hide();
                main_menu.show();
            }).bind(key.EXIT, this);

            (function(){
                this.hide();
                main_menu.show();
            }).bind(key.LEFT, this).bind(key.MENU, this);
        };

        this.play = function(){
            _debug('radio.play');

            this.update_header_path([{"alias" : "playing", "item" : this.data_items[this.cur_row].name}]);

            stb.player.need_show_info = 1;
            stb.player.play(this.data_items[this.cur_row]);
        };
    }

    radio_constructor.prototype = new Layer();

    var radio = new radio_constructor();

    radio.bind();
    radio.init();

    radio.init_left_ear('ears_back');

    radio.init_header_path('РАДИО');

    radio.hide();

    module.radio = radio;

    /* END RADIO */

    /* Integrate karaoke in main menu */

    main_menu.add('РАДИО', [], 'i/mm_ico_radio.png', function(){
        main_menu.hide();
        module.radio.show();
    });

})();

loader.next();<|endoftext|>


<commit_before>(function($) {
    jQuery.fn.lake = function(options) {
        var settings = $.extend({
            'speed':    1,
            'scale':    1,
            'waves':    10,
            'image':    true
        }, options);

        var waves = settings['waves'];
        var speed = settings['speed']/4;
        var scale = settings['scale']/2;

        var ca = document.createElement('canvas');
        var c = ca.getContext('2d');

        var img = this.get(0);
        var img_loaded = false;
        var run = true;
        ca.id = img.id + "-lake";

        img.parentNode.insertBefore(ca, img);

        var w, h, dw, dh;

        var offset = 0;
        var frame = 0;
        var max_frames = 0;
        var frames = [];

        img.onload = function() {
            c.save();

            c.canvas.width  = this.width;
            c.canvas.height = this.height*2;

            c.drawImage(this, 0,  0);
            c.scale(1, -1);
            c.drawImage(this, 0,  -this.height*2);

            img_loaded = true;

            c.restore();

            w = c.canvas.width;
            h = c.canvas.height;
            dw = w;
            dh = h/2;

            var id = c.getImageData(0, h/2, w, h).data;
            var end = false;

            // precalc frames
            // image displacement
            c.save();
            while (!end) {
                // var odd = c.createImageData(dw, dh);
                var odd = c.getImageData(0, h/2, w, h);
                var od = odd.data;
                // var pixel = (w*4) * 5;
                var pixel = 0;
                for (var y = 0; y < dh; y++) {
                    for (var x = 0; x < dw; x++) {
                        // var displacement = (scale * dd[pixel]) | 0;
                        var displacement = (scale * 10 * (Math.sin((dh/(y/waves)) + (-offset)))) | 0;
                        var j = ((displacement + y) * w + x + displacement)*4;

                        // horizon flickering fix
                        if (j < 0) {
                            pixel += 4;
                            continue;
                        }

                        // edge wrapping fix
                        var m = j % (w*4);
                        var n = scale * 10 * (y/waves);
                        if (m < n || m > (w*4)-n) {
                            var sign = y < w/2 ? 1 : -1;
                            od[pixel]   = od[pixel + 4 * sign];
                            od[++pixel] = od[pixel + 4 * sign];
                            od[++pixel] = od[pixel + 4 * sign];
                            od[++pixel] = od[pixel + 4 * sign];
                            ++pixel;
                            continue;
                        }

                        if (id[j+3] != 0) {
                            od[pixel]   = id[j];
                            od[++pixel] = id[++j];
                            od[++pixel] = id[++j];
                            od[++pixel] = id[++j];
                            ++pixel;
                        } else {
                            od[pixel]   = od[pixel - w*4];
                            od[++pixel] = od[pixel - w*4];
                            od[++pixel] = od[pixel - w*4];
                            od[++pixel] = od[pixel - w*4];
                            ++pixel;
                            // pixel += 4;
                        }
                    }
                }

                if (offset > speed * (6/speed)) {
                    offset = 0;
                    max_frames = frame - 1;
                    // frames.pop();
                    frame = 0;
                    end = true;
                } else {
                    offset += speed;
                    frame++;
                }
                frames.push(odd);
            }
            c.restore();
            if (!settings.image) {
                c.height = c.height/2;
                c.canvas.height = c.canvas.height/2;
            } else {
            }
        };

        setInterval(function() {
            if (img_loaded && run) {
                if (!settings.image) {
                    c.putImageData(frames[frame], 0, 0);
                } else {
                    c.putImageData(frames[frame], 0, h/2);
                }
                if (frame < max_frames) {
                    frame++;
                } else {
                    frame = 0;
                }
            }
        }, 60);

        var plugin = this;
        plugin.start = function() {
            run = true;
        }

        plugin.stop = function() {
            run = false;
        }
        return this;
    }
})(jQuery);
<commit_msg>Change filetype lake.js with minor update<commit_after>(function($) {
    jQuery.fn.lake = function(options) {
        var settings = $.extend({
            'speed':    1,
            'scale':    1,
            'waves':    10,
            'image':    true
        }, options);

        var waves = settings['waves'];
        var speed = settings['speed']/4;
        var scale = settings['scale']/2;

        var ca = document.createElement('canvas');
        var c = ca.getContext('2d');

        var img = this.get(0);
        var img_loaded = false;
        var run = true;
        ca.id = img.id + "-lake";

        img.parentNode.insertBefore(ca, img);

        var w, h, dw, dh;

        var offset = 0;
        var frame = 0;
        var max_frames = 0;
        var frames = [];

        img.onload = function() {
            c.save();

            c.canvas.width  = this.width;
            c.canvas.height = this.height*2;

            c.drawImage(this, 0,  0);
            c.scale(1, -1);
            c.drawImage(this, 0,  -this.height*2);

            img_loaded = true;

            c.restore();

            w = c.canvas.width;
            h = c.canvas.height;
            dw = w;
            dh = h/2;

            var id = c.getImageData(0, h/2, w, h).data;
            var end = false;

            // precalc frames
            // image displacement
            c.save();
            while (!end) {
                // var odd = c.createImageData(dw, dh);
                var odd = c.getImageData(0, h/2, w, h);
                var od = odd.data;
                // var pixel = (w*4) * 5;
                var pixel = 0;
                for (var y = 0; y < dh; y++) {
                    for (var x = 0; x < dw; x++) {
                        // var displacement = (scale * dd[pixel]) | 0;
                        var displacement = (scale * 10 * (Math.sin((dh/(y/waves)) + (-offset)))) | 0;
                        var j = ((displacement + y) * w + x + displacement)*4;

                        // horizon flickering fix
                        if (j < 0) {
                            pixel += 4;
                            continue;
                        }

                        // edge wrapping fix
                        var m = j % (w*4);
                        var n = scale * 10 * (y/waves);
                        if (m < n || m > (w*4)-n) {
                            var sign = y < w/2 ? 1 : -1;
                            od[pixel]   = od[pixel + 4 * sign];
                            od[++pixel] = od[pixel + 4 * sign];
                            od[++pixel] = od[pixel + 4 * sign];
                            od[++pixel] = od[pixel + 4 * sign];
                            ++pixel;
                            continue;
                        }

                        if (id[j+3] != 0) {
                            od[pixel]   = id[j];
                            od[++pixel] = id[++j];
                            od[++pixel] = id[++j];
                            od[++pixel] = id[++j];
                            ++pixel;
                        } else {
                            od[pixel]   = od[pixel - w*4];
                            od[++pixel] = od[pixel - w*4];
                            od[++pixel] = od[pixel - w*4];
                            od[++pixel] = od[pixel - w*4];
                            ++pixel;
                            // pixel += 4;
                        }
                    }
                }

                if (offset > speed * (6/speed)) {
                    offset = 0;
                    max_frames = frame - 1;
                    // frames.pop();
                    frame = 0;
                    end = true;
                } else {
                    offset += speed;
                    frame++;
                }
                frames.push(odd);
            }
            c.restore();
            if (!settings.image) {
                c.height = c.height/2;
                c.canvas.height = c.canvas.height/2;
                c.putImageData(frames[frame], 0, 0);
            } else {
                c.putImageData(frames[frame], 0, h/2);
            }
        };

        setInterval(function() {
            if (img_loaded && run) {
                if (!settings.image) {
                    c.putImageData(frames[frame], 0, 0);
                } else {
                    c.putImageData(frames[frame], 0, h/2);
                }
                if (frame < max_frames) {
                    frame++;
                } else {
                    frame = 0;
                }
            }
        }, 60);

        var plugin = this;
        plugin.start = function() {
            run = true;
        }

        plugin.stop = function() {
            run = false;
        }
        return this;
    }
})(jQuery);
<|endoftext|>