<commit_before>'use strict';
var config = require('config');
var sleep = require('co-sleep');
var request = require('co-request');
var logger = require('logger');
var co = require('co');
var mongoose = require('mongoose');

var uriMigrate = process.env.MIGRATE_URI || config.get('migrate.uri');
var mongoUri = process.env.MONGO_URI || 'mongodb://' + config.get('mongodb.host') + ':' + config.get('mongodb.port') + '/' + config.get('mongodb.database');

let Subscription = require('models/subscription');

var microserviceClient = require('vizz.microservice-client');

var obtainData = function*(cursor) {
    let url = uriMigrate;
    if (cursor) {
        url += '?cursor=' + cursor;
    }
    logger.debug('Doing request to ', url);
    var response = yield request({
        url: url,
        method: 'GET',
        json: true
    });
    if(response.statusCode !== 200){
        logger.error(response);
        logger.info('Waiting 5 seconds and trying');
        yield sleep(5000);
        response = yield request({
            url: url,
            method: 'GET',
            json: true
        });
    }
    return response.body;
};

let cacheUsers = {};
var obtainNewUserId = function*(userId) {
    try{
        logger.info('Obtaining user with data', userId);
        if(cacheUsers[userId]){
            return cacheUsers[userId];
        }
        let result = yield microserviceClient.requestToMicroservice({
          uri: '/user/oldId/' + userId,
          method: 'GET',
          json: true
        });

        cacheUsers[userId] = result.body.data.id;
        return result.body.data.id;
    }catch(e){
        logger.error(e);
    }
};
logger.info('Setting info', process.env.API_GATEWAY_URL_MIGRATE);
microserviceClient.setDataConnection({
    apiGatewayUrl: process.env.API_GATEWAY_URL_MIGRATE
});

var oldDatasets = {
    'alerts/treeloss': 'umd-loss-gain',
    'alerts/terra': 'terrai-alerts',
    'alerts/glad': 'glad-alerts',
    'alerts/prodes': 'prodes-loss',
    'alerts/viirs': 'viirs-active-fires',
    'alerts/guyra': 'guira-loss',
    'alerts/sad': 'imazon-alerts'
};

var tranformDataset = function(oldDataset){
    if(oldDatasets[oldDataset]){
        return oldDatasets[oldDataset];
    }
    return oldDataset;
}

var transformAndSaveData = function*(data){
    logger.info('Saving data');
    if(data){
         for(let i = 0, length = data.length; i < length; i++){
             if(data[i].confirmed){
                //  logger.debug('Saving data', data[i]);
                 let userId = null;
                 if(data[i].user_id){
                     userId = yield obtainNewUserId(data[i].user_id);
                 }else {
                     logger.info('Subscription without user_id');
                 }
                 let language = data[i].language  || 'en';

                 yield new Subscription({
                     name: data[i].name,
                     confirmed: data[i].confirmed,
                     resource:{
                         type: 'EMAIL',
                         content: data[i].email
                     },
                     userId: userId,
                     createdAt: data[i].created,
                     datasets: [tranformDataset(data[i].topic)],
                     language: language.toLowerCase(),
                     params:{
                         iso:{
                             country: data[i].iso,
                             region: data[i].id1
                         },
                         geostore: data[i].geostore,
                         wdpaid: data[i].wdpaid,
                         use: data[i].use,
                         useId: data[i].useid,
                         ifl: data[i].ifl,
                         fl_id1: data[i].fl_id1
                     }
                 }).save();

             } else {
                 logger.debug('not confirmed');
             }
         }
    } else {
        logger.ingo('Empty list');
    }
};

var migrate = function*() {
    logger.info('Obtaining data');
    var data = yield obtainData();

    while (data) {
        logger.debug('Obtained data');

        let element = null;
        let model, idConn = null;
        yield transformAndSaveData(data.subscriptions);
        if(data.cursor){
            data = yield obtainData(data.cursor);
        } else {
            data = null;
        }
    }

    logger.debug('Finished migration');
};
var onDbReady = function() {
    co(function*() {
        logger.info('Starting migration');

        yield migrate();
        process.exit();
    });
};
mongoose.connect(mongoUri, onDbReady);
<commit_msg>add migrate<commit_after>'use strict';
var config = require('config');
var sleep = require('co-sleep');
var request = require('co-request');
var logger = require('logger');
var co = require('co');
var mongoose = require('mongoose');

var uriMigrate = process.env.MIGRATE_URI || config.get('migrate.uri');
var mongoUri = process.env.MONGO_URI || 'mongodb://' + config.get('mongodb.host') + ':' + config.get('mongodb.port') + '/' + config.get('mongodb.database');

let Subscription = require('models/subscription');

var microserviceClient = require('vizz.microservice-client');

var obtainData = function*(cursor) {
    let url = uriMigrate;
    if (cursor) {
        url += '?cursor=' + cursor;
    }
    logger.debug('Doing request to ', url);
    var response = yield request({
        url: url,
        method: 'GET',
        json: true
    });
    if(response.statusCode !== 200){
        logger.error(response);
        logger.info('Waiting 5 seconds and trying');
        yield sleep(5000);
        response = yield request({
            url: url,
            method: 'GET',
            json: true
        });
    }
    return response.body;
};

let cacheUsers = {};
var obtainNewUserId = function*(userId) {
    try{
        logger.info('Obtaining user with data', userId);
        if(cacheUsers[userId]){
            return cacheUsers[userId];
        }
        let result = yield microserviceClient.requestToMicroservice({
          uri: '/user/oldId/' + userId,
          method: 'GET',
          json: true
        });

        cacheUsers[userId] = result.body.data.id;
        return result.body.data.id;
    }catch(e){
        logger.error(e);
    }
};

var createGeoJSON = function*(geojson) {
    try{
        logger.info('Creating geostore');

        let result = yield microserviceClient.requestToMicroservice({
          uri: '/geostore/' + userId,
          method: 'POST',
          body: {
              geojson: geojson
          }
          json: true
        });

        return result.body.data.id;
    }catch(e){
        logger.error(e);
    }
};
logger.info('Setting info', process.env.API_GATEWAY_URL_MIGRATE);
microserviceClient.setDataConnection({
    apiGatewayUrl: process.env.API_GATEWAY_URL_MIGRATE
});

var oldDatasets = {
    'alerts/treeloss': 'umd-loss-gain',
    'alerts/terra': 'terrai-alerts',
    'alerts/glad': 'glad-alerts',
    'alerts/prodes': 'prodes-loss',
    'alerts/viirs': 'viirs-active-fires',
    'alerts/guyra': 'guira-loss',
    'alerts/sad': 'imazon-alerts'
};

var tranformDataset = function(oldDataset){
    if(oldDatasets[oldDataset]){
        return oldDatasets[oldDataset];
    }
    return oldDataset;
}

var transformAndSaveData = function*(data){
    logger.info('Saving data');
    if(data){
         for(let i = 0, length = data.length; i < length; i++){
             if(data[i].confirmed){
                //  logger.debug('Saving data', data[i]);
                 let userId = null;
                 if(data[i].user_id){
                     userId = yield obtainNewUserId(data[i].user_id);
                 }else {
                     logger.info('Subscription without user_id');
                 }
                 let language = data[i].language  || 'en';

                 if(!data[i].params.iso && !data[i].params.id1 && !data[i].params.wdpaid && !data[i].params.use && !data[i].params.useid && !data[i].params.ifl && data[i].params.fl_id1 && !data[i].params.geostore){
                     let geostore = yield createGeoJSON(data[i].params.geom);
                     data[i].geostore = geostore.id;
                 }

                 yield new Subscription({
                     name: data[i].name,
                     confirmed: data[i].confirmed,
                     resource:{
                         type: 'EMAIL',
                         content: data[i].email
                     },
                     userId: userId,
                     createdAt: data[i].created,
                     datasets: [tranformDataset(data[i].topic)],
                     language: language.toLowerCase(),
                     params:{
                         iso:{
                             country: data[i].iso || data[i].params.iso,
                             region: data[i].id1 || data[i].params.id1
                         },
                         geostore: data[i].geostore || data[i].params.geostore,
                         wdpaid: data[i].wdpaid || data[i].params.wdpaid,
                         use: data[i].use || data[i].params.use,
                         useId: data[i].useid || data[i].params.useid,
                         ifl: data[i].ifl || data[i].params.ifl,
                         fl_id1: data[i].fl_id1 || data[i].params.fl_id1
                     }
                 }).save();

             } else {
                 logger.debug('not confirmed');
             }
         }
    } else {
        logger.ingo('Empty list');
    }
};

var migrate = function*() {
    logger.info('Obtaining data');
    var data = yield obtainData();

    while (data) {
        logger.debug('Obtained data');

        let element = null;
        let model, idConn = null;
        yield transformAndSaveData(data.subscriptions);
        if(data.cursor){
            data = yield obtainData(data.cursor);
        } else {
            data = null;
        }
    }

    logger.debug('Finished migration');
};
var onDbReady = function() {
    co(function*() {
        logger.info('Starting migration');

        yield migrate();
        process.exit();
    });
};
mongoose.connect(mongoUri, onDbReady);
<|endoftext|>


<commit_before>import { StyleSheet, css } from 'aphrodite/no-important';

/* eslint no-underscore-dangle: 0 */

function isValidStyleSheet(styleSheet, key) {
  return !(styleSheet === null ||
    styleSheet === undefined ||
    styleSheet[key] === null ||
    styleSheet[key] === undefined);
}

function isValidStyle(style) {
  return !(style === null ||
    style === undefined ||
    style._definition === null ||
    style._definition === undefined);
}

function mergeStyles(styleA, styleB) {
  if (!isValidStyle(styleA)) {
    return styleB;
  }
  if (!isValidStyle(styleB)) {
    return styleA;
  }
  return Object.assign({}, styleA._definition, styleB._definition);
}

export function getStyleSheet(key, localStyleSheet, injectedStyleSheet) {
  const localStyle = localStyleSheet[key];
  let style = localStyle;
  const result = {};
  if (isValidStyleSheet(injectedStyleSheet, key)) {
    const injectedStyle = injectedStyleSheet[key];
    style = mergeStyles(localStyle, injectedStyle);
    result[key] = style;
    return StyleSheet.create(result);
  }

  result[key] = style;
  return result;
}

export function getStyle(key, localStyleSheet, injectedStyleSheet) {
  const localStyle = localStyleSheet[key];
  if (!isValidStyleSheet(injectedStyleSheet, key)) {
    return localStyle;
  }
  const injectedStyle = injectedStyleSheet[key];
  const mergedStyle = mergeStyles(localStyle, injectedStyle);
  const result = {};
  result[key] = mergedStyle;
  const styleSheet = StyleSheet.create(result);
  return styleSheet[key];
}

export { css, StyleSheet };
<commit_msg>Refactor of Aphrodite utils 🎖<commit_after>import { StyleSheet, css } from 'aphrodite/no-important';

/* eslint no-underscore-dangle: 0 */

function isValidStyleSheet(styleSheet, key) {
  return !(styleSheet === null ||
    styleSheet === undefined ||
    styleSheet[key] === null ||
    styleSheet[key] === undefined);
}

function isValidStyle(style) {
  return !(style === null ||
    style === undefined ||
    style._definition === null ||
    style._definition === undefined);
}

function mergeStyles(styleA, styleB) {
  if (!isValidStyle(styleA)) {
    return styleB;
  }
  if (!isValidStyle(styleB)) {
    return styleA;
  }
  return Object.assign({}, styleA._definition, styleB._definition);
}

function createStyleSheetWithKey(key, definitions) {
  const result = {};
  result[key] = definitions;
  return StyleSheet.create(result);
}

function createStyle(key, definitions) {
  const styleSheet = createStyleSheetWithKey(key, definitions);
  return styleSheet[key];
}

export function getStyleSheet(key, styleSheetA, styleSheetB) {
  if (
    isValidStyleSheet(styleSheetA, key) &&
    isValidStyleSheet(styleSheetB, key)
  ) {
    const mergedStyle = mergeStyles(styleSheetA[key], styleSheetB[key]);
    return createStyleSheetWithKey(key, mergedStyle);
  } else if (isValidStyleSheet(styleSheetA, key)) {
    const result = {};
    result[key] = styleSheetA[key];
    return result;
  }
  return createStyleSheetWithKey(key, {});
}

export function getStyle(key, styleSheetA, styleSheetB) {
  if (
    isValidStyleSheet(styleSheetA, key) &&
    isValidStyleSheet(styleSheetB, key)
  ) {
    const mergedStyle = mergeStyles(styleSheetA[key], styleSheetB[key]);
    return createStyle(key, mergedStyle);
  } else if (isValidStyleSheet(styleSheetA, key)) {
    return styleSheetA[key];
  }
  return createStyle(key, {});
}

export { css, StyleSheet };
<|endoftext|>


<commit_before>/*
 * file:	SR-EELS_ImportCal.js
 * author:	Michael Entrup b. Epping (michael.entrup@wwu.de)
 * version:	20150407
 * info:	This script is used to import calibration images into my "database".
 * 			The "databse" is a folder structure that contains all my calibration images.
 * 			This script trises to gues the acquisition data and all parameters by processing the file path.
 *
 * 			This script is part of the Fiji plugin EFTEMj (https://github.com/EFTEMj/EFTEMj).
 */

importClass(Packages.ij.IJ);
importClass(Packages.java.io.File);
importClass(Packages.ij.io.DirectoryChooser);
importClass(Packages.ij.gui.GenericDialog);

var database = "Q:/Aktuell/SR-EELS Calibration measurements/"

main();

function main() {
	var path;
	if ((path = getDirectory()) == null) return;
	var files;
	if ((files = selectFiles(path)) == null) return;
	var parameters;
	if ((parameters = getParameters(path)) == null) return;
	if (parameters.date != null & parameters.SM != null & parameters.QSinK7 != null) {
		saveFiles(path, files, parameters);
	}
}

function getDirectory() {
	var dc = new DirectoryChooser("Calibration files...");
	return dc.getDirectory();
}

function selectFiles(path) {
	var folder = new File(path);
	var list = folder.list();
	var gd = GenericDialog("Select files");
	for (var i = 0; i < list.length; i++) {
		if (new File(path + list[i]).isFile() & list[i].search("Cal") >= 0) {
			gd.addCheckbox(list[i], true);
		} else {
			gd.addCheckbox(list[i], false);
		}
	}
	gd.showDialog();
	if (gd.wasCanceled()) {
		return null;
	}
	var files = new Array();
	for (var i = 0; i < list.length; i++) {
		if (gd.getNextBoolean()) {
			files.push(list[i]);
		}
	}
	return files;
}

function getParameters(path) {
	var patternDate = /(\d{8})/ig;
	var patternSM = /(?:SM|SpecMag)(\d{2,3})/ig;
	var patternQSinK7 = /(QSinK7[\s|=])(-?\+?\d{1,3})%?/ig;
	var parameters = new Parameters();
	var dateArray;
	while ((dateArray = patternDate.exec(path)) !== null) {
		parameters.date = dateArray[1];
	}
	var smArray;
	while ((smArray = patternSM.exec(path)) !== null) {
		parameters.SM = smArray[1];
	}
	var qsinArray;
	while ((qsinArray = patternQSinK7.exec(path)) !== null) {
		parameters.QSinK7 = qsinArray[2];
	}
	var gd = GenericDialog("Set parameters");
	gd.addStringField("date:", parameters.date);
	gd.addStringField("SpecMag:", parameters.SM);
	gd.addStringField("QSinK7:", parameters.QSinK7);
	gd.addStringField("comment:", parameters.comment);
	gd.showDialog();
	if (gd.wasCanceled()) {
		return null;
	} else {
		parameters.date = gd.getNextString();
		parameters.SM = gd.getNextString();
		parameters.QSinK7 = gd.getNextString();
		parameters.comment = gd.getNextString();
	}
	return parameters;
}

function Parameters() {
	this.date = null;
	this.SM = null;
	this.QSinK7 = null;
	this.comment = null;
}

function saveFiles(path, files, parameters) {
	output = database + parameters.date + " SM" + parameters.SM + " " + parameters.QSinK7 + "%";
	if (parameters.comment != "") {
		output += " " + parameters.comment;
	}
	output += "/";
	folder = new File(output);
	folder.mkdir();
	for (index in files) {
		imp = IJ.openImage(path + files[index]);
		IJ.run(imp, "Rotate 90 Degrees Left", "");
		IJ.save(imp, output + "Cal_" + pad(++index, 2) + ".tif");
		imp.close();
	}
}

function pad(num, size) {
    var s = num+"";
    while (s.length < size) s = "0" + s;
    return s;
}<commit_msg>Adding usage of ij.Prefs to SR-EELS_ImportCal.js:<commit_after>/*
 * file:	SR-EELS_ImportCal.js
 * author:	Michael Entrup b. Epping (michael.entrup@wwu.de)
 * version:	20150407
 * info:	This script is used to import calibration images into my "database".
 * 			The "databse" is a folder structure that contains all my calibration images.
 * 			This script trises to gues the acquisition data and all parameters by processing the file path.
 *
 * 			This script is part of the Fiji plugin EFTEMj (https://github.com/EFTEMj/EFTEMj).
 */

importClass(Packages.ij.IJ);
importClass(Packages.ij.Prefs);
importClass(Packages.java.io.File);
importClass(Packages.ij.io.DirectoryChooser);
importClass(Packages.ij.gui.GenericDialog);

var databaseKey = "EFTEMj.SR-EELS.database.path";
var databasePath;

main();

function main() {
	/*
	 * The path to the databasePath folder is stored in IJ_Prefs.txt.
	 * If the value is not yet defined, the user is asked to set a directory.
	 */
	if ((databasePath = Prefs.get(databaseKey, "")) == "") {
		if ((databasePath = getDirectory("Path to your SR-EELS database...")) != null) Prefs.set(databaseKey, databasePath);
		else return;
	}
	var path;
	/*
	 * Select the files to import.
	 */
	if ((path = getDirectory("Calibration files...")) == null) return;
	var files;
	if ((files = selectFiles(path)) == null) return;
	var parameters;
	if ((parameters = getParameters(path)) == null) return;
	if (parameters.date != null & parameters.SM != null & parameters.QSinK7 != null) {
		saveFiles(path, files, parameters);
	}
}

function getDirectory(title) {
	var dc = new DirectoryChooser(title);
	return dc.getDirectory();
}

function selectFiles(path) {
	var folder = new File(path);
	var list = folder.list();
	var gd = GenericDialog("Select files");
	for (var i = 0; i < list.length; i++) {
		if (new File(path + list[i]).isFile() & list[i].search("Cal") >= 0) {
			gd.addCheckbox(list[i], true);
		} else {
			gd.addCheckbox(list[i], false);
		}
	}
	gd.showDialog();
	if (gd.wasCanceled()) {
		return null;
	}
	var files = new Array();
	for (var i = 0; i < list.length; i++) {
		if (gd.getNextBoolean()) {
			files.push(list[i]);
		}
	}
	return files;
}

function getParameters(path) {
	var patternDate = /(\d{8})/ig;
	var patternSM = /(?:SM|SpecMag)(\d{2,3})/ig;
	var patternQSinK7 = /(QSinK7[\s|=])(-?\+?\d{1,3})%?/ig;
	var parameters = new Parameters();
	var dateArray;
	while ((dateArray = patternDate.exec(path)) !== null) {
		parameters.date = dateArray[1];
	}
	var smArray;
	while ((smArray = patternSM.exec(path)) !== null) {
		parameters.SM = smArray[1];
	}
	var qsinArray;
	while ((qsinArray = patternQSinK7.exec(path)) !== null) {
		parameters.QSinK7 = qsinArray[2];
	}
	var gd = GenericDialog("Set parameters");
	gd.addStringField("date:", parameters.date);
	gd.addStringField("SpecMag:", parameters.SM);
	gd.addStringField("QSinK7:", parameters.QSinK7);
	gd.addStringField("comment:", parameters.comment);
	gd.showDialog();
	if (gd.wasCanceled()) {
		return null;
	} else {
		parameters.date = gd.getNextString();
		parameters.SM = gd.getNextString();
		parameters.QSinK7 = gd.getNextString();
		parameters.comment = gd.getNextString();
	}
	return parameters;
}

function Parameters() {
	this.date = null;
	this.SM = null;
	this.QSinK7 = null;
	this.comment = null;
}

function saveFiles(path, files, parameters) {
	output = databasePath + parameters.date + " SM" + parameters.SM + " " + parameters.QSinK7 + "%";
	if (parameters.comment != "") {
		output += " " + parameters.comment;
	}
	output += "/";
	folder = new File(output);
	folder.mkdir();
	for (index in files) {
		imp = IJ.openImage(path + files[index]);
		IJ.run(imp, "Rotate 90 Degrees Left", "");
		IJ.save(imp, output + "Cal_" + pad(++index, 2) + ".tif");
		imp.close();
	}
}

function pad(num, size) {
    var s = num+"";
    while (s.length < size) s = "0" + s;
    return s;
}<|endoftext|>


<commit_before>/*
	@file: apps/colorwheel/colorwheel.js
*/

function colorwheel() {

	// canvas & context
	this.theCanvas = document.getElementById('canvas');
	this.context = this.theCanvas.getContext('2d');

	//this.mouseX = 0;
	//this.mouseY = 0;

	// pick & complement globals
	this.pickR = 0;
	this.pickG = 0;
	this.pickB = 0;
	this.complementR = 0;
	this.complementG = 0;
	this.complementB = 0;

	this.appStart = appStart;
	this.appQuit = appQuit;

	//this.fillPick = fillPick;
	//this.fillComp = fillComp;
	//this.onMouseMove = onMouseMove;
	//this.onMouseClick = onMouseClick;
	//this.onCompClick = onCompClick;
	//this.onTouchMove = onTouchMove;
	//this.onTouchStart = onTouchStart;

	function appStart() {
		console.log("colorwheel.appStart");
		$("head").append('<link rel="stylesheet" href="colorwheel.css" />');
		setCanvasImage()
	}

	function appQuit() {
		// log the function
		console.log("colorwheel.appQuit");
	}

	function setCanvasImage() {
		console.log("colorwheel.setCanvasImage");
		var canvasImage = new Image();
		canvasImage.onload = function() {
			var x = 0;
			var y = 0;
			var wh = $('.selector').innerWidth();
			$('#canvas').attr('width', wh);
			$('#canvas').attr('height', wh);
			theApp.context.drawImage(canvasImage, x, y, wh, wh);
		};
		canvasImage.src="colorwheel.png";
	}

	$(window).resize(setCanvasImage);

	$('#canvas').mousemove(function(e) {
	  var pos = getPageOffset(this);
	  var x = e.pageX - pos.x;
	  var y = e.pageY - pos.y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $('.radar p').html("X: " + x + " Y: " + y + " Hex: " + hex);
	  $(".hover").css('background-color', hex);
	});

	$('#canvas').mouseup(function(e) {
	  var pos = getPageOffset(this);
	  var x = e.pageX - pos.x;
	  var y = e.pageY - pos.y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $(".pick").css('background-color', hex);
	  var hexy = "#" + ("000000" + rgbToHex(255 - p[0], 255 - p[1], 255 - p[2])).slice(-6);
	  $(".complement").css('background-color', hexy);
	  theApp.pickR = p[0]
		theApp.pickG = p[1]
		theApp.pickB = p[2]
	  theApp.complementR = 255 - p[0]
		theApp.complementG = 255 - p[1]
		theApp.complementB = 255 - p[2]
	  currentLight.setlamp(p[0], p[1], p[2]);
	});

	$('#canvas').touchstart(function(e) {
		e.preventDefault();
	  var pos = getPageOffset(this);
	  var x = e.pageX - pos.x;
	  var y = e.pageY - pos.y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $(".pick").css('background-color', hex);
	  var hexy = "#" + ("000000" + rgbToHex(255 - p[0], 255 - p[1], 255 - p[2])).slice(-6);
	  $(".complement").css('background-color', hexy);
	  theApp.pickR = p[0]
		theApp.pickG = p[1]
		theApp.pickB = p[2]
	  theApp.complementR = 255 - p[0]
		theApp.complementG = 255 - p[1]
		theApp.complementB = 255 - p[2]
	  currentLight.setlamp(p[0], p[1], p[2]);
	});

/*
	function onTouchStart(e) {
		var touch = e.touches[0];
		var pos = getPageOffset(touch);
		var x = touch.pageX - pos.x;
	  var y = touch.pageY - pos.y;
	  var coord = "x = " + x + ", y = " + y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $(".pick").css('background-color', hex);
	  var hexy = "#" + ("000000" + rgbToHex(255 - p[0], 255 - p[1], 255 - p[2])).slice(-6);
	  $(".complement").css('background-color', hexy);
	  theApp.pickR = p[0]
		theApp.pickG = p[1]
		theApp.pickB = p[2]
	  theApp.complementR = 255 - p[0]
		theApp.complementG = 255 - p[1]
		theApp.complementB = 255 - p[2]
	  currentLight.setlamp(p[0], p[1], p[2]);

/* 		theApp.mouseX = touch.clientX - theApp.theCanvas.offsetLeft; */
/* 		theApp.mouseY = touch.clientY - theApp.theCanvas.offsetTop; */
/* 		console.log("mouseX " + theApp.mouseX + " mouseY " + theApp.mouseY);   */
/* 		imageData = theApp.context.getImageData(theApp.mouseX,theApp.mouseY,1,1); */
/* 		var red = imageData.data[0]; */
/* 		var green = imageData.data[1]; */
/* 		var blue = imageData.data[2]; */
/* 		console.log("onTouchStart: rgb(" + red.toString(16) + ", " + green.toString(16) + ", " + blue.toString(16) + ")") */
/* 		fillPick(imageData.data[0], imageData.data[1], imageData.data[2]); */
/* 		fillComp(imageData.data[0], imageData.data[1], imageData.data[2]); */
/* 		currentLight.setlamp(red, green, blue); */

/* 		theApp.lastTouch = new Date().getTime();	 */
/* 	} */
/* */

/*
	function onTouchMove(e) {
		console.log("colorwheel.onTouchMove");
		event.preventDefault();
		curr = new Date().getTime();
		if ((curr - theApp.lastTouch) > 100) {
			console.log("Accepting onTouchMove");
			theApp.onTouchStart(e);
		} else {
			console.log("Declining onTouchMove");
		}
	}
*/

	$(".pick").click(function(){
		console.log("colorwheel.pickClick");
		currentLight.setlamp( theApp.pickR, theApp.pickG, theApp.pickB );
	})

	$(".complement").click(function(){
		console.log("colorwheel.complementClick");
		currentLight.setlamp( theApp.complementR, theApp.complementG, theApp.complementB );
	})

	function getPageOffset(obj) {
	  var cursorX = 0, cursorY = 0;
	  if (obj.offsetParent) {
	    do {
	      cursorX += obj.offsetLeft;
	      cursorY += obj.offsetTop;
	    } while (obj = obj.offsetParent);
	    return { x: cursorX, y: cursorY };
	  }
	  return undefined;
	}

	function rgbToHex(r, g, b) {
		if (r > 255 || g > 255 || b > 255)
	    throw "Invalid";
		return ((r << 16) | (g << 8) | b).toString(16);
	}

	/* 	--- */

/* 	function fillPick(red, green, blue){ */
		/*
		redstr = red.toString(16);
		if (redstr.length < 2) {
			redstr = "0" + redstr;
		}
		greenstr = green.toString(16);
		if (greenstr.length < 2) {
			greenstr = "0" + greenstr;
		}
		bluestr = blue.toString(16);
		if (bluestr.length < 2) {
			bluestr = "0" + bluestr;
		}
		var pick = "#" + redstr + greenstr + bluestr;
		console.log("fillPick: " + pick);
		$(".pick").css('background-color', pick);
		*/
/* 	} */

/* 	function fillComp(red, green, blue){ */
		/*
			theApp.compR = red = 255 - red;
		theApp.compG = green = 255 - green;
		theApp.compB = blue = 255 - blue;
		//console.log(red, green, blue)
		redstr = red.toString(16);
		//console.log(redstr);
		if (redstr.length < 2) {
			redstr = "0" + redstr;
		}
		//console.log(redstr);
		greenstr = green.toString(16);
		if (greenstr.length < 2) {
			greenstr = "0" + greenstr;
		}
		bluestr = blue.toString(16);
		if (bluestr.length < 2) {
			bluestr = "0" + bluestr;
		}
		var complement = "#" + redstr + greenstr + bluestr;
		console.log("fillComp: " + complement);
		$(".complement").css('background-color', complement);
		*/
/* 	}	 */

/* 	function onMouseMove(e) { */

		//theApp.mouseX = e.clientX - (theApp.theCanvas.offsetLeft + $(theApp.theCanvas).parent().parent()[0].offsetLeft);
		//theApp.mouseY = e.clientY - (theApp.theCanvas.offsetTop + $(theApp.theCanvas).parent().parent()[0].offsetTop);

		/*
		theApp.mouseX = e.clientX - theApp.theCanvas.offsetLeft;
		theApp.mouseY = e.clientY - theApp.theCanvas.offsetTop;
		*/

/* 	} */

/* 	function onMouseClick(e) { */

		//theApp.mouseX = e.clientX - (theApp.theCanvas.offsetLeft + $(theApp.theCanvas).parent().parent()[0].offsetLeft);
		//theApp.mouseY = e.clientY - (theApp.theCanvas.offsetTop + $(theApp.theCanvas).parent().parent()[0].offsetTop);

		/*
		theApp.mouseX = e.clientX - theApp.theCanvas.offsetLeft;
		theApp.mouseY = e.clientY - theApp.theCanvas.offsetTop;
		console.log("mouseX: " + theApp.mouseX + ", mouseY: " + theApp.mouseY);
		imageData = theApp.context.getImageData(theApp.mouseX,theApp.mouseY,1,1);
		var red = imageData.data[0];
		var green = imageData.data[1];
		var blue = imageData.data[2];
		console.log("onMouseClick: #" + red.toString(16) + green.toString(16) + blue.toString(16));
		fillPick(imageData.data[0], imageData.data[1], imageData.data[2]);
		fillComp(imageData.data[0], imageData.data[1], imageData.data[2]);
		currentLight.setlamp(red, green, blue);
		*/
/* 	} */

/* 	function onCompClick(e) { */
		/*
		var red = compR;
		var green = compG;
		var blue = compB;
		console.log("onCompClick: rgb(" + red.toString(16) + ", " + green.toString(16) + ", " + blue.toString(16) + ")")
		currentLight.setlamp(red, green, blue);
		*/
/* 	} */

/* 	function onTouchStart(e) { */
		/*
		var touch = e.touches[0];
		console.log("onTouchStart", touch.clientX, touch.clientY);
		//theApp.mouseX = touch.clientX - (theApp.theCanvas.offsetLeft + $(theApp.theCanvas).parent().parent()[0].offsetLeft);
		//theApp.mouseY = touch.clientY - (theApp.theCanvas.offsetTop + $(theApp.theCanvas).parent().parent()[0].offsetTop);
		theApp.mouseX = touch.clientX - theApp.theCanvas.offsetLeft;
		theApp.mouseY = touch.clientY - theApp.theCanvas.offsetTop;
		console.log("mouseX " + theApp.mouseX + " mouseY " + theApp.mouseY);
		imageData = theApp.context.getImageData(theApp.mouseX,theApp.mouseY,1,1);
		//var red = (imageData.data[0] >> 1);
		//var green = (imageData.data[1] >> 1);
		//var blue = (imageData.data[2] >> 1);
		var red = imageData.data[0];
		var green = imageData.data[1];
		var blue = imageData.data[2];
		console.log("onTouchStart: rgb(" + red.toString(16) + ", " + green.toString(16) + ", " + blue.toString(16) + ")")
		fillPick(imageData.data[0], imageData.data[1], imageData.data[2]);
		fillComp(imageData.data[0], imageData.data[1], imageData.data[2]);
		currentLight.setlamp(red, green, blue);
		theApp.lastTouch = new Date().getTime();
		*/
/* 	} */

/* 	function onTouchMove(e) { */
/*
		console.log("colorwheel.onTouchMove");
		event.preventDefault();
		curr = new Date().getTime();
		if ((curr - theApp.lastTouch) > 100) {
			console.log("Accepting onTouchMove");
			theApp.onTouchStart(e);
		} else {
			console.log("Declining onTouchMove");
		}
*/
/* 	} */

	//this.theCanvas.addEventListener("mousemove", this.onMouseMove, false);
	//this.theCanvas.addEventListener("click", this.onMouseClick, false);
	//this.theCanvas.addEventListener("touchstart", this.onTouchStart, false);
	//this.theCanvas.addEventListener("touchmove", this.onTouchMove, false);

}

<commit_msg>Colorwheel more unique variable names, still wibbly screen persists<commit_after>/*
	@file: apps/colorwheel/colorwheel.js
*/

function colorwheel() {

	// canvas & context
	this.theCanvas = document.getElementById('canvas');
	this.context = this.theCanvas.getContext('2d');

	//this.mouseX = 0;
	//this.mouseY = 0;

	// pick & complement globals
	this.pickR = 0;
	this.pickG = 0;
	this.pickB = 0;
	this.complementR = 0;
	this.complementG = 0;
	this.complementB = 0;

	this.appStart = appStart;
	this.appQuit = appQuit;

	//this.fillPick = fillPick;
	//this.fillComp = fillComp;
	//this.onMouseMove = onMouseMove;
	//this.onMouseClick = onMouseClick;
	//this.onCompClick = onCompClick;
	//this.onTouchMove = onTouchMove;
	//this.onTouchStart = onTouchStart;

	function appStart() {
		console.log("colorwheel.appStart");
		$("head").append('<link rel="stylesheet" href="colorwheel.css" />');
		setCanvasImage()
	}

	function appQuit() {
		// log the function
		console.log("colorwheel.appQuit");
	}

	function setCanvasImage() {
		console.log("colorwheel.setCanvasImage");
		var canvasImage = new Image();
		canvasImage.onload = function() {
			var x = 0;
			var y = 0;
			var wh = $('.selector').innerWidth();
			$('#canvas').attr('width', wh);
			$('#canvas').attr('height', wh);
			theApp.context.drawImage(canvasImage, x, y, wh, wh);
		};
		canvasImage.src="colorwheel.png";
	}

	$(window).resize(setCanvasImage);

	$('#canvas').mousemove(function(e) {
	  var pos = getPageOffset(this);
	  var x = e.pageX - pos.x;
	  var y = e.pageY - pos.y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $('.radar p').html("X: " + x + " Y: " + y + " Hex: " + hex);
	  $(".hover").css('background-color', hex);
	});

	$('#canvas').mouseup(function(e) {
	  var pos = getPageOffset(this);
	  var x = e.pageX - pos.x;
	  var y = e.pageY - pos.y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $(".pick").css('background-color', hex);
	  var hexy = "#" + ("000000" + rgbToHex(255 - p[0], 255 - p[1], 255 - p[2])).slice(-6);
	  $(".complement").css('background-color', hexy);
	  theApp.pickR = p[0]
		theApp.pickG = p[1]
		theApp.pickB = p[2]
	  theApp.complementR = 255 - p[0]
		theApp.complementG = 255 - p[1]
		theApp.complementB = 255 - p[2]
	  currentLight.setlamp(p[0], p[1], p[2]);
	});

	function onTouchStart(t) {
		var touch = t.touches[0];
		var pos = getPageOffset(touch);
		var x = touch.pageX - pos.x;
	  var y = touch.pageY - pos.y;
	  var coord = "x = " + x + ", y = " + y;
	  var c = this.getContext('2d');
	  var p = c.getImageData(x, y, 1, 1).data;
	  var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
	  $(".pick").css('background-color', hex);
	  var hexy = "#" + ("000000" + rgbToHex(255 - p[0], 255 - p[1], 255 - p[2])).slice(-6);
	  $(".complement").css('background-color', hexy);
	  theApp.pickR = p[0]
		theApp.pickG = p[1]
		theApp.pickB = p[2]
	  theApp.complementR = 255 - p[0]
		theApp.complementG = 255 - p[1]
		theApp.complementB = 255 - p[2]
	  currentLight.setlamp(p[0], p[1], p[2]);
		theApp.lastTouch = new Date().getTime();
	}

	function onTouchMove(m) {
		console.log("colorwheel.onTouchMove");
		m.preventDefault();
		curr = new Date().getTime();
		if ((curr - theApp.lastTouch) > 100) {
			console.log("Accepting onTouchMove");
			theApp.onTouchStart(m);
		} else {
			console.log("Declining onTouchMove");
		}
	}

	$(".pick").click(function(){
		console.log("colorwheel.pickClick");
		currentLight.setlamp( theApp.pickR, theApp.pickG, theApp.pickB );
	})

	$(".complement").click(function(){
		console.log("colorwheel.complementClick");
		currentLight.setlamp( theApp.complementR, theApp.complementG, theApp.complementB );
	})

	function getPageOffset(obj) {
	  var cursorX = 0, cursorY = 0;
	  if (obj.offsetParent) {
	    do {
	      cursorX += obj.offsetLeft;
	      cursorY += obj.offsetTop;
	    } while (obj = obj.offsetParent);
	    return { x: cursorX, y: cursorY };
	  }
	  return undefined;
	}

	function rgbToHex(r, g, b) {
		if (r > 255 || g > 255 || b > 255)
	    throw "Invalid";
		return ((r << 16) | (g << 8) | b).toString(16);
	}

	/* 	--- */

/* 	function fillPick(red, green, blue){ */
		/*
		redstr = red.toString(16);
		if (redstr.length < 2) {
			redstr = "0" + redstr;
		}
		greenstr = green.toString(16);
		if (greenstr.length < 2) {
			greenstr = "0" + greenstr;
		}
		bluestr = blue.toString(16);
		if (bluestr.length < 2) {
			bluestr = "0" + bluestr;
		}
		var pick = "#" + redstr + greenstr + bluestr;
		console.log("fillPick: " + pick);
		$(".pick").css('background-color', pick);
		*/
/* 	} */

/* 	function fillComp(red, green, blue){ */
		/*
			theApp.compR = red = 255 - red;
		theApp.compG = green = 255 - green;
		theApp.compB = blue = 255 - blue;
		//console.log(red, green, blue)
		redstr = red.toString(16);
		//console.log(redstr);
		if (redstr.length < 2) {
			redstr = "0" + redstr;
		}
		//console.log(redstr);
		greenstr = green.toString(16);
		if (greenstr.length < 2) {
			greenstr = "0" + greenstr;
		}
		bluestr = blue.toString(16);
		if (bluestr.length < 2) {
			bluestr = "0" + bluestr;
		}
		var complement = "#" + redstr + greenstr + bluestr;
		console.log("fillComp: " + complement);
		$(".complement").css('background-color', complement);
		*/
/* 	}	 */

/* 	function onMouseMove(e) { */

		//theApp.mouseX = e.clientX - (theApp.theCanvas.offsetLeft + $(theApp.theCanvas).parent().parent()[0].offsetLeft);
		//theApp.mouseY = e.clientY - (theApp.theCanvas.offsetTop + $(theApp.theCanvas).parent().parent()[0].offsetTop);

		/*
		theApp.mouseX = e.clientX - theApp.theCanvas.offsetLeft;
		theApp.mouseY = e.clientY - theApp.theCanvas.offsetTop;
		*/

/* 	} */

/* 	function onMouseClick(e) { */

		//theApp.mouseX = e.clientX - (theApp.theCanvas.offsetLeft + $(theApp.theCanvas).parent().parent()[0].offsetLeft);
		//theApp.mouseY = e.clientY - (theApp.theCanvas.offsetTop + $(theApp.theCanvas).parent().parent()[0].offsetTop);

		/*
		theApp.mouseX = e.clientX - theApp.theCanvas.offsetLeft;
		theApp.mouseY = e.clientY - theApp.theCanvas.offsetTop;
		console.log("mouseX: " + theApp.mouseX + ", mouseY: " + theApp.mouseY);
		imageData = theApp.context.getImageData(theApp.mouseX,theApp.mouseY,1,1);
		var red = imageData.data[0];
		var green = imageData.data[1];
		var blue = imageData.data[2];
		console.log("onMouseClick: #" + red.toString(16) + green.toString(16) + blue.toString(16));
		fillPick(imageData.data[0], imageData.data[1], imageData.data[2]);
		fillComp(imageData.data[0], imageData.data[1], imageData.data[2]);
		currentLight.setlamp(red, green, blue);
		*/
/* 	} */

/* 	function onCompClick(e) { */
		/*
		var red = compR;
		var green = compG;
		var blue = compB;
		console.log("onCompClick: rgb(" + red.toString(16) + ", " + green.toString(16) + ", " + blue.toString(16) + ")")
		currentLight.setlamp(red, green, blue);
		*/
/* 	} */

/* 	function onTouchStart(e) { */
		/*
		var touch = e.touches[0];
		console.log("onTouchStart", touch.clientX, touch.clientY);
		//theApp.mouseX = touch.clientX - (theApp.theCanvas.offsetLeft + $(theApp.theCanvas).parent().parent()[0].offsetLeft);
		//theApp.mouseY = touch.clientY - (theApp.theCanvas.offsetTop + $(theApp.theCanvas).parent().parent()[0].offsetTop);
		theApp.mouseX = touch.clientX - theApp.theCanvas.offsetLeft;
		theApp.mouseY = touch.clientY - theApp.theCanvas.offsetTop;
		console.log("mouseX " + theApp.mouseX + " mouseY " + theApp.mouseY);
		imageData = theApp.context.getImageData(theApp.mouseX,theApp.mouseY,1,1);
		//var red = (imageData.data[0] >> 1);
		//var green = (imageData.data[1] >> 1);
		//var blue = (imageData.data[2] >> 1);
		var red = imageData.data[0];
		var green = imageData.data[1];
		var blue = imageData.data[2];
		console.log("onTouchStart: rgb(" + red.toString(16) + ", " + green.toString(16) + ", " + blue.toString(16) + ")")
		fillPick(imageData.data[0], imageData.data[1], imageData.data[2]);
		fillComp(imageData.data[0], imageData.data[1], imageData.data[2]);
		currentLight.setlamp(red, green, blue);
		theApp.lastTouch = new Date().getTime();
		*/
/* 	} */

/* 	function onTouchMove(e) { */
/*
		console.log("colorwheel.onTouchMove");
		event.preventDefault();
		curr = new Date().getTime();
		if ((curr - theApp.lastTouch) > 100) {
			console.log("Accepting onTouchMove");
			theApp.onTouchStart(e);
		} else {
			console.log("Declining onTouchMove");
		}
*/
/* 	} */

	//this.theCanvas.addEventListener("mousemove", this.onMouseMove, false);
	//this.theCanvas.addEventListener("click", this.onMouseClick, false);
	//this.theCanvas.addEventListener("touchstart", this.onTouchStart, false);
	//this.theCanvas.addEventListener("touchmove", this.onTouchMove, false);

}

<|endoftext|>


<commit_before>module.exports.drawCallback = function () {
    let pagination = $(this).closest('.dataTables_wrapper').find('.dataTables_paginate'),
        paginationNumbers;

    // Only show pagination when needed
    pagination.toggle(this.api().page.info().pages > 1);

    // Add aria-current to current page number
    pagination.find('.paginate_button.current').attr('aria-current', 'true');

    // Remove disable links
    pagination.find('.paginate_button.disabled').addClass('u-display-none');

    // Add aria-labels to numbered links
    paginationNumbers = pagination.find('.paginate_button:not(.first, .previous, .next, .last)');
    paginationNumbers.each(function () {
        let $numberLink = $(this);
        $numberLink.attr('aria-label', 'Page ' + $numberLink.text());
    });
}
<commit_msg>DT pagination buttons are now read as buttons rather than links in AT<commit_after>module.exports.drawCallback = function () {
    let pagination = $(this).closest('.dataTables_wrapper').find('.dataTables_paginate'),
        paginationNumbers;

    // Only show pagination when needed
    pagination.toggle(this.api().page.info().pages > 1);

    // Make pagination links appear as buttons to AT
    pagination.find('.paginate_button').attr('role', 'button');

    // Add aria-current to current page number
    pagination.find('.paginate_button.current').attr('aria-current', 'true');

    // Remove disable links
    pagination.find('.paginate_button.disabled').addClass('u-display-none');

    // Add aria-labels to numbered links
    paginationNumbers = pagination.find('.paginate_button:not(.first, .previous, .next, .last)');
    paginationNumbers.each(function () {
        let $numberLink = $(this);
        $numberLink.attr('aria-label', 'Page ' + $numberLink.text());
    });
}
<|endoftext|>


<commit_before>define(["react"], function (React) {
    "use strict";

    return React.createClass({
        displayName: "MenuSelectProfile",

        handleSelect: function (evt) {
            var profileId = evt.target.value;
            if (profileId === "__add") {
                return;
            }
            var profile = this.props.profiles.filter(function (profile) {
                return profile.id === profileId;
            })[0];
            this.props.selectProfile(profile);
        },

        render: function () {
            var current = this.props.selectedProfile;
            var options = this.props.profiles.map(function (profile) {
                return React.DOM.option({key: profile.id, value: profile.id, className: "title"}, profile.name);
            });
            options.push(React.DOM.optgroup({key: "__add", label: "───"},
                React.DOM.option({value: "__add", className: "title"}, "Add profile..."))
                );
            return React.DOM.div({ className: this.props.className },
                React.DOM.select({
                    className: "title",
                    value: current.id,
                    onChange: this.handleSelect
                }, options)
                );
        }
    });
});<commit_msg>blur selectbox after updating<commit_after>define(["react"], function (React) {
    "use strict";

    return React.createClass({
        displayName: "MenuSelectProfile",

        componentDidMount: function () {
            this.refs.select.getDOMNode().blur();
        },
        componentDidUpdate: function () {
            this.refs.select.getDOMNode().blur();
        },

        handleSelect: function (evt) {
            var profileId = evt.target.value;
            if (profileId === "__add") {
                return;
            }
            var profile = this.props.profiles.filter(function (profile) {
                return profile.id === profileId;
            })[0];
            this.props.selectProfile(profile);
        },

        render: function () {
            var current = this.props.selectedProfile;
            var options = this.props.profiles.map(function (profile) {
                return React.DOM.option({key: profile.id, value: profile.id, className: "title"}, profile.name);
            });
            options.push(React.DOM.optgroup({key: "__add", label: "───"},
                React.DOM.option({value: "__add", className: "title"}, "Add profile..."))
                );
            return React.DOM.div({ className: this.props.className },
                React.DOM.select({
                    ref: "select",
                    className: "title",
                    value: current.id,
                    onChange: this.handleSelect
                }, options)
                );
        }
    });
});<|endoftext|>


<commit_before>/*
* "checkboxradio" plugin
*/

(function( $, undefined ) {

$.widget( "mobile.checkboxradio", $.mobile.widget, {
	options: {
		theme: null,
		initSelector: "input[type='checkbox'],input[type='radio']"
	},
	_create: function() {
		var self = this,
			input = this.element,
			// NOTE: Windows Phone could not find the label through a selector
			// filter works though.
			label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label[for='" + input[ 0 ].id + "']"),
			inputtype = input.attr( "type" ),
			checkedState = inputtype + "-on",
			uncheckedState = inputtype + "-off",
			icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState,
			activeBtn = icon ? "" : " " + $.mobile.activeBtnClass,
			checkedClass = "ui-" + checkedState + activeBtn,
			uncheckedClass = "ui-" + uncheckedState,
			checkedicon = "ui-icon-" + checkedState,
			uncheckedicon = "ui-icon-" + uncheckedState;

		if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
			return;
		}

		// Expose for other methods
		$.extend( this, {
			label: label,
			inputtype: inputtype,
			checkedClass: checkedClass,
			uncheckedClass: uncheckedClass,
			checkedicon: checkedicon,
			uncheckedicon: uncheckedicon
		});

		// If there's no selected theme...
		if( !this.options.theme ) {
			this.options.theme = this.element.jqmData( "theme" );
		}

		label.buttonMarkup({
			theme: this.options.theme,
			icon: icon,
			shadow: false
		});

		// Wrap the input + label in a div
		input.add( label )
			.wrapAll( "

" );

		label.bind({
			vmouseover: function( event ) {
				if ( $( this ).parent().is( ".ui-disabled" ) ) {
					event.stopPropagation();
				}
			},

			vclick: function( event ) {
				if ( input.is( ":disabled" ) ) {
					event.preventDefault();
					return;
				}

				self._cacheVals();

				input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );

				// trigger click handler's bound directly to the input as a substitute for
				// how label clicks behave normally in the browsers
				// TODO: it would be nice to let the browser's handle the clicks and pass them
				//       through to the associate input. we can swallow that click at the parent
				//       wrapper element level
				input.triggerHandler( 'click' );

				// Input set for common radio buttons will contain all the radio
				// buttons, but will not for checkboxes. clearing the checked status
				// of other radios ensures the active button state is applied properly
				self._getInputSet().not( input ).prop( "checked", false );

				self._updateAll();
				return false;
			}

		});

		input
			.bind({
				vmousedown: function() {
					self._cacheVals();
				},

				vclick: function() {
					var $this = $(this);

					// Adds checked attribute to checked input when keyboard is used
					if ( $this.is( ":checked" ) ) {

						$this.prop( "checked", true);
						self._getInputSet().not($this).prop( "checked", false );
					} else {

						$this.prop( "checked", false );
					}

					self._updateAll();
				},

				focus: function() {
					label.addClass( "ui-focus" );
				},

				blur: function() {
					label.removeClass( "ui-focus" );
				}
			});

		this.refresh();
	},

	_cacheVals: function() {
		this._getInputSet().each(function() {
			var $this = $(this);

			$this.jqmData( "cacheVal", $this.is( ":checked" ) );
		});
	},

	//returns either a set of radios with the same name attribute, or a single checkbox
	_getInputSet: function(){
		if(this.inputtype == "checkbox") {
			return this.element;
		}

		return this.element.closest( "form,fieldset,:jqmData(role='page')" )
			.find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" );
	},

	_updateAll: function() {
		var self = this;

		this._getInputSet().each(function() {
			var $this = $(this);

			if ( $this.is( ":checked" ) || self.inputtype === "checkbox" ) {
				$this.trigger( "change" );
			}
		})
		.checkboxradio( "refresh" );
	},

	refresh: function() {
		var input = this.element,
			label = this.label,
			icon = label.find( ".ui-icon" );

		// input[0].checked expando doesn't always report the proper value
		// for checked='checked'
		if ( $( input[ 0 ] ).prop( "checked" ) ) {

			label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
			icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );

		} else {

			label.removeClass( this.checkedClass ).addClass( this.uncheckedClass );
			icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
		}

		if ( input.is( ":disabled" ) ) {
			this.disable();
		} else {
			this.enable();
		}
	},

	disable: function() {
		this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
	},

	enable: function() {
		this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" );
	}
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ){
	$.mobile.checkboxradio.prototype.enhanceWithin( e.target );
});

})( jQuery );
<commit_msg>Fixes #3086 — Windows Phone 7 seems unable to use find() for an attribute-based selector, in this context.<commit_after>/*
* "checkboxradio" plugin
*/

(function( $, undefined ) {

$.widget( "mobile.checkboxradio", $.mobile.widget, {
	options: {
		theme: null,
		initSelector: "input[type='checkbox'],input[type='radio']"
	},
	_create: function() {
		var self = this,
			input = this.element,
			// NOTE: Windows Phone could not find the label through a selector
			// filter works though.
			label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label" ).filter( "[for='" + input[ 0 ].id + "']" ),
			inputtype = input.attr( "type" ),
			checkedState = inputtype + "-on",
			uncheckedState = inputtype + "-off",
			icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState,
			activeBtn = icon ? "" : " " + $.mobile.activeBtnClass,
			checkedClass = "ui-" + checkedState + activeBtn,
			uncheckedClass = "ui-" + uncheckedState,
			checkedicon = "ui-icon-" + checkedState,
			uncheckedicon = "ui-icon-" + uncheckedState;

		if ( inputtype !== "checkbox" && inputtype !== "radio" ) {
			return;
		}

		// Expose for other methods
		$.extend( this, {
			label: label,
			inputtype: inputtype,
			checkedClass: checkedClass,
			uncheckedClass: uncheckedClass,
			checkedicon: checkedicon,
			uncheckedicon: uncheckedicon
		});

		// If there's no selected theme...
		if( !this.options.theme ) {
			this.options.theme = this.element.jqmData( "theme" );
		}

		label.buttonMarkup({
			theme: this.options.theme,
			icon: icon,
			shadow: false
		});

		// Wrap the input + label in a div
		input.add( label )
			.wrapAll( "

" );

		label.bind({
			vmouseover: function( event ) {
				if ( $( this ).parent().is( ".ui-disabled" ) ) {
					event.stopPropagation();
				}
			},

			vclick: function( event ) {
				if ( input.is( ":disabled" ) ) {
					event.preventDefault();
					return;
				}

				self._cacheVals();

				input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) );

				// trigger click handler's bound directly to the input as a substitute for
				// how label clicks behave normally in the browsers
				// TODO: it would be nice to let the browser's handle the clicks and pass them
				//       through to the associate input. we can swallow that click at the parent
				//       wrapper element level
				input.triggerHandler( 'click' );

				// Input set for common radio buttons will contain all the radio
				// buttons, but will not for checkboxes. clearing the checked status
				// of other radios ensures the active button state is applied properly
				self._getInputSet().not( input ).prop( "checked", false );

				self._updateAll();
				return false;
			}

		});

		input
			.bind({
				vmousedown: function() {
					self._cacheVals();
				},

				vclick: function() {
					var $this = $(this);

					// Adds checked attribute to checked input when keyboard is used
					if ( $this.is( ":checked" ) ) {

						$this.prop( "checked", true);
						self._getInputSet().not($this).prop( "checked", false );
					} else {

						$this.prop( "checked", false );
					}

					self._updateAll();
				},

				focus: function() {
					label.addClass( "ui-focus" );
				},

				blur: function() {
					label.removeClass( "ui-focus" );
				}
			});

		this.refresh();
	},

	_cacheVals: function() {
		this._getInputSet().each(function() {
			var $this = $(this);

			$this.jqmData( "cacheVal", $this.is( ":checked" ) );
		});
	},

	//returns either a set of radios with the same name attribute, or a single checkbox
	_getInputSet: function(){
		if(this.inputtype == "checkbox") {
			return this.element;
		}

		return this.element.closest( "form,fieldset,:jqmData(role='page')" )
			.find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" );
	},

	_updateAll: function() {
		var self = this;

		this._getInputSet().each(function() {
			var $this = $(this);

			if ( $this.is( ":checked" ) || self.inputtype === "checkbox" ) {
				$this.trigger( "change" );
			}
		})
		.checkboxradio( "refresh" );
	},

	refresh: function() {
		var input = this.element,
			label = this.label,
			icon = label.find( ".ui-icon" );

		// input[0].checked expando doesn't always report the proper value
		// for checked='checked'
		if ( $( input[ 0 ] ).prop( "checked" ) ) {

			label.addClass( this.checkedClass ).removeClass( this.uncheckedClass );
			icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon );

		} else {

			label.removeClass( this.checkedClass ).addClass( this.uncheckedClass );
			icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon );
		}

		if ( input.is( ":disabled" ) ) {
			this.disable();
		} else {
			this.enable();
		}
	},

	disable: function() {
		this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" );
	},

	enable: function() {
		this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" );
	}
});

//auto self-init widgets
$( document ).bind( "pagecreate create", function( e ){
	$.mobile.checkboxradio.prototype.enhanceWithin( e.target );
});

})( jQuery );
<|endoftext|>


<commit_before>/*jshint browser: true, jasmine: true */
/*global inject, module */

describe('KeyInfo component', function () {
    'use strict';

    var $compile,
        $rootScope;

    beforeEach(module('ngMock'));
    beforeEach(module('sky.keyinfo'));
    beforeEach(module('sky.templates'));

    beforeEach(inject(function (_$compile_, _$rootScope_) {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

    it('should support vertical and horizontal layouts', function () {
        var el,
            $scope = $rootScope.$new();

        el = $compile('<bb-key-info bb-key-info-layout="horizontal"><bb-key-info-value></bb-key-info-value><bb-key-info-label></bb-key-info-label></bb-key-info>')($scope);

        $scope.$digest();

        expect(el.find('.bb-key-info')).toHaveClass('bb-key-info-horizontal');
    });

    it('should have the appropriate content in expected areas', function () {
        var el,
            $scope = $rootScope.$new(),
            keyvalue = 'foo',
            keylabel = 'bar';

        el = $compile('<bb-key-info><bb-key-info-value>' + keyvalue + '</bb-key-info-value><bb-key-info-label>' + keylabel + '</bb-key-info-label></bb-key-info>')($scope);

        $scope.$digest();

        expect(el.find('.bb-key-info-value')).toHaveText(keyvalue);
        expect(el.find('.bb-key-info-label')).toHaveText(keylabel);
    });
});
<commit_msg>changed keyinfo description<commit_after>/*jshint browser: true, jasmine: true */
/*global inject, module */

describe('Key info component', function () {
    'use strict';

    var $compile,
        $rootScope;

    beforeEach(module('ngMock'));
    beforeEach(module('sky.keyinfo'));
    beforeEach(module('sky.templates'));

    beforeEach(inject(function (_$compile_, _$rootScope_) {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

    it('should support vertical and horizontal layouts', function () {
        var el,
            $scope = $rootScope.$new();

        el = $compile('<bb-key-info bb-key-info-layout="horizontal"><bb-key-info-value></bb-key-info-value><bb-key-info-label></bb-key-info-label></bb-key-info>')($scope);

        $scope.$digest();

        expect(el.find('.bb-key-info')).toHaveClass('bb-key-info-horizontal');
    });

    it('should have the appropriate content in expected areas', function () {
        var el,
            $scope = $rootScope.$new(),
            keyvalue = 'foo',
            keylabel = 'bar';

        el = $compile('<bb-key-info><bb-key-info-value>' + keyvalue + '</bb-key-info-value><bb-key-info-label>' + keylabel + '</bb-key-info-label></bb-key-info>')($scope);

        $scope.$digest();

        expect(el.find('.bb-key-info-value')).toHaveText(keyvalue);
        expect(el.find('.bb-key-info-label')).toHaveText(keylabel);
    });
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         Kiss Statistics
// @description  Adds a stats button to kissanime.com, kissmanga.com, kisscartoon.me and kissasian.com bookmark sites
// @include      http://kissanime.com/BookmarkList
// @include      http://kissanime.com/MyList/*
// @include      http://kissmanga.com/BookmarkList
// @include      http://kisscartoon.me/BookmarkList
// @include      http://kisscartoon.me/MyList/*
// @include      http://kissasian.com/BookmarkList
// @include	     http://kissasian.com/MyList/*
// @author       Playacem
// @updateURL    <TODO>
// @downloadURL  <TODO>
// @require      http://code.jquery.com/jquery-latest.js
// @grant        none
// @version      0.0.50
// ==/UserScript==
/*
	CHANGELOG
	0.0.50:
		First public release.
	0.0.31:
		Changed Unread and Read to Not Completed and Completed
	0.0.30:
		KissAsian.com support.
*/
/* VARS */
// Seperator for the numbers
var sep = '/';

// width in percent
var widthCatName = 37 + 15;
var widthUnread = 12 + 10;
var widthRead = 26;
// Row names
var strCatName = 'Category name';
var strUnread = 'Not Completed';
var strRead = 'Completed';

/* CONSTS*/
/* DO NOT CHANGE UNDER ANY CIRCUMSTANCES! */
const strAllAnimes = ' All Anime';
const strAllCartoons = ' All Cartoons';
const strAllDramas = ' All Drama';
const strNoCategory = ' Uncategorized';
const selectorVisible = ".aUnRead[style!='display: none']";
const classTable = 'listing';
const classTableHead = 'head';
const mainId = 'userscriptVisibleStats';
const userClassTable = 'userStatTable';
const userCompleted = 'userCompleted';
const userOdd = 'odd';
const catArr = getCatArray();
var JQ = jQuery;
/* UTILITY FUNCTIONS */

/* You can't access the sites javascript variables in Firefox, so I wrote this function to replicate lstCats content */
function getCatArray() {
	// after http://stackoverflow.com/questions/9229645/remove-duplicates-from-javascript-array
	type = getSiteType();
	if(type === 'Manga'){return {};}
	function uniq(a) {
		var seen = {};
		return a.filter(function(item) {
			return seen.hasOwnProperty(item) ? false : (seen[item] = true);
		});
	};
	var tmpArray = new Array();
	var selector = 'tr.trAnime';
	if(type === 'Cartoon'){selector = 'tr.trCartoon';}
	if(type === 'Drama'){selector = 'tr.trDrama';}
	$(selector).each(function(index){
		// get Category val
		var tmpCat = $(this).attr('catname');
		// imitate lstCats behaviour
		if(tmpCat === '') {tmpCat = strNoCategory;}
		tmpArray.push(tmpCat);
	});

	var tmpFinalArray = uniq(tmpArray);
	tmpFinalArray.sort();
	return tmpFinalArray;
};

/* Gets all to user visible unread rows by a specific category name and returns their size */
function getVisibleUnreadSizeByCategoryName(type, categoryName) {
	// handle KissManga separately as it does not have categories/folders and no link sharing option
	if (type === 'Manga') {return JQ(selectorVisible).size();}

	// no category given assumes it means all categories combined (All X option in the drop down menu)
	if (categoryName === undefined) {
		if (type === 'Anime') {categoryName = strAllAnimes;}
		if (type === 'Cartoon') {categoryName = strAllCartoons;}
		if (type === 'Drama') {categoryName = strAllDramas;}
	}

	// select indepently from a specific category all visible not completed row size
	if (categoryName === strAllAnimes || categoryName === strAllCartoons || categoryName === strAllDramas) {
		return JQ(selectorVisible).size();
	}

	// handle the special 'Uncategorized' category
	if (categoryName === strNoCategory) {
		if (type === 'Cartoon') {return JQ("tr.trCartoon[catName=''] > td > " + selectorVisible ).size();}
		if (type === 'Drama') {return JQ("tr.trDrama[catName=''] > td > " + selectorVisible ).size();}
		return JQ("tr.trAnime[catName=''] > td > " + selectorVisible ).size();
	}
	// non special categories
	if (type == 'Cartoon') {return JQ("tr.trCartoon[catName='"+ categoryName + "'] > td > " + selectorVisible ).size();}
	if (type == 'Drama') {return JQ("tr.trDrama[catName='"+ categoryName + "'] > td > " + selectorVisible ).size();}
	return JQ("tr.trAnime[catName='" + categoryName + "'] > td > " + selectorVisible).size();
};

/* Gets the total size (completed and not completed) by a specific Category name*/
function getTotalSizeByCategoryName(type, categoryName) {

	// handle KissManga separately as it does not have categories/folders and no link sharing option
	if (type === 'Manga') {return JQ('.aUnRead').size();}

	// no category given assumes it means all categories combined (All X option in the drop down menu)
	if (categoryName == undefined) {
		if (type === 'Anime') {categoryName = strAllAnimes;}
		if (type === 'Cartoon') {categoryName = strAllCartoons;}
		if (type === 'Drama') {categoryName = strAllDramas;}
	}

	// select EVERYTHING (total row count)
	if (categoryName === strAllAnimes || categoryName === strAllCartoons || categoryName === strAllDramas) {
		return JQ('.aUnRead').size();
	}

	// handle the special 'Uncategorized' category
	if (categoryName === strNoCategory) {
		if (type === 'Cartoon') {return JQ("tr.trCartoon[catName='']").size();}
		if (type === 'Drama') {return JQ("tr.trDrama[catName='']").size();}
		return JQ("tr.trAnime[catName='']").size();
	}

	// non special categories
	if (type === 'Cartoon') {return JQ("tr.trCartoon[catName='" + categoryName + "']").size();}
	if (type === 'Drama') {return JQ("tr.trDrama[catName='" + categoryName + "']").size();}
	return JQ("tr.trAnime[catName='" + categoryName + "']").size();
};

/* Adds an 's' if appropriate (basically add it if the Kiss site does so too) */
function getPluralS(type) {
	if(type === 'Anime') {return '';}
	if(type === 'Manga') {return 's';}
	if(type === 'Cartoon') {return 's';}
	if(type === 'Drama') {return '';}
	return '';
};

/* gets the html that represents the data in a table */
function getTableHtml(type) {
	var tableHtml = "
";
	// add header
	tableHtml += "
 " + strCatName + "	 " + strUnread + "	 " + strRead + "
";
	tableHtml += "

";//style row (the bookmark table has it too)

	var allTotal = getTotalSizeByCategoryName(type);
	var allUnread = getVisibleUnreadSizeByCategoryName(type);
	var allRead = allTotal - allUnread;
	var oddEntry = true;
	var additionalClasses = '';

	// add stripes to the rows
	if(oddEntry){
		additionalClasses += userOdd;
		oddEntry = !oddEntry;
	} else {
		oddEntry = !oddEntry;
	}
	// if a category is completed, add this css class. To be used in the future
	if(allUnread == 0){ additionalClasses += (' ' + userCompleted);}
	// All X category
	tableHtml += "
 All " + type + getPluralS(type) +"	 " + allUnread + sep + allTotal + "	 " + allRead + sep + allTotal + "
";

	// do not check for categories if it is KissManga
	if(type != 'Manga') {
		// go over all categories
		for (var index = 0; index < catArr.length; ++index) {
			additionalClasses = '';
			var currCatTotal = getTotalSizeByCategoryName(type, catArr[index]);
			var currCatUnread = getVisibleUnreadSizeByCategoryName(type, catArr[index]);
			var currCatRead = currCatTotal - currCatUnread;
			// move css class stuff in extra function?
			if(oddEntry){
				additionalClasses += userOdd;
				oddEntry = !oddEntry;
			} else {oddEntry = !oddEntry;}
			if(currCatUnread == 0){additionalClasses += (' ' + userCompleted);}
			// add entry for the current category
			tableHtml += "
 " + catArr[index] + "	 " + currCatUnread + sep + currCatTotal + "	 " + currCatRead + sep + currCatTotal + "
";
		}
	}

	tableHtml += '
';

	return tableHtml;
};

/* determine the Site this script is running on */
function getSiteType() {
	var url = window.location.href;
	// Why indexOf? Not every browser supports includes (I am looking at you, Firefox!)
	if (url.indexOf('kissmanga') != -1) {return 'Manga';}
	if (url.indexOf('kisscartoon') != -1) {return 'Cartoon';}
	if (url.indexOf('kissasian') != -1) {return 'Drama';}
	return 'Anime';
};

/* Makes the button actually do stuff */
function addClickFunctionality() {
	var statTableHidden = true;
	JQ('#btnToggleStats').click(function() {
		statTableHidden = !statTableHidden;
		JQ('.' + userClassTable).fadeToggle(400);
		if (statTableHidden) {
			JQ('#btnToggleStats').text('Show Statistics');
		}else {
			JQ('#btnToggleStats').text('Hide Statistics');
		}
	});
};
/* combine everything */
function create() {
	var siteType = getSiteType();
	var tableHtml = getTableHtml(siteType);

	buttonHtml = " Show Statistics ";
	var clear2InTable = "

";
	var divHtml = "
" + buttonHtml + clear2InTable + tableHtml + "
";

	var catSelect = '#divListCategories';
	// KissManga has no Category selector
	if(siteType == 'Manga') {catSelect = '.listing';}

	JQ(divHtml).insertBefore(catSelect);
	JQ('#' + mainId).prev('div.clear2').remove();
	// hide by default
	JQ('.' + userClassTable).hide();

	addClickFunctionality();
};

// load after 2 seconds to capture delayed categories
JQ(window).load(function() {
	setTimeout(function() {
		create();
	}, 2000);
});
<commit_msg>Update kiss-statistics update functionality<commit_after>// ==UserScript==
// @name         Kiss Statistics
// @description  Adds a stats button to kissanime.com, kissmanga.com, kisscartoon.me and kissasian.com bookmark sites
// @include      http://kissanime.com/BookmarkList
// @include      http://kissanime.com/MyList/*
// @include      http://kissmanga.com/BookmarkList
// @include      http://kisscartoon.me/BookmarkList
// @include      http://kisscartoon.me/MyList/*
// @include      http://kissasian.com/BookmarkList
// @include      http://kissasian.com/MyList/*
// @author       Playacem
// @updateURL    https://raw.githubusercontent.com/Playacem/KissScripts/master/kiss-statistics/kiss-statistics.user.js
// @downloadURL  https://raw.githubusercontent.com/Playacem/KissScripts/master/kiss-statistics/kiss-statistics.user.js
// @require      http://code.jquery.com/jquery-latest.js
// @grant        none
// @version      0.0.51
// ==/UserScript==
/*
	CHANGELOG
	0.0.51:
		Added update and download urls
	0.0.50:
		First public release.
	0.0.31:
		Changed Unread and Read to Not Completed and Completed
	0.0.30:
		KissAsian.com support.
*/
/* VARS */
// Seperator for the numbers
var sep = '/';

// width in percent
var widthCatName = 37 + 15;
var widthUnread = 12 + 10;
var widthRead = 26;
// Row names
var strCatName = 'Category name';
var strUnread = 'Not Completed';
var strRead = 'Completed';

/* CONSTS*/
/* DO NOT CHANGE UNDER ANY CIRCUMSTANCES! */
const strAllAnimes = ' All Anime';
const strAllCartoons = ' All Cartoons';
const strAllDramas = ' All Drama';
const strNoCategory = ' Uncategorized';
const selectorVisible = ".aUnRead[style!='display: none']";
const classTable = 'listing';
const classTableHead = 'head';
const mainId = 'userscriptVisibleStats';
const userClassTable = 'userStatTable';
const userCompleted = 'userCompleted';
const userOdd = 'odd';
const catArr = getCatArray();
var JQ = jQuery;
/* UTILITY FUNCTIONS */

/* You can't access the sites javascript variables in Firefox, so I wrote this function to replicate lstCats content */
function getCatArray() {
	// after http://stackoverflow.com/questions/9229645/remove-duplicates-from-javascript-array
	type = getSiteType();
	if(type === 'Manga'){return {};}
	function uniq(a) {
		var seen = {};
		return a.filter(function(item) {
			return seen.hasOwnProperty(item) ? false : (seen[item] = true);
		});
	};
	var tmpArray = new Array();
	var selector = 'tr.trAnime';
	if(type === 'Cartoon'){selector = 'tr.trCartoon';}
	if(type === 'Drama'){selector = 'tr.trDrama';}
	$(selector).each(function(index){
		// get Category val
		var tmpCat = $(this).attr('catname');
		// imitate lstCats behaviour
		if(tmpCat === '') {tmpCat = strNoCategory;}
		tmpArray.push(tmpCat);
	});

	var tmpFinalArray = uniq(tmpArray);
	tmpFinalArray.sort();
	return tmpFinalArray;
};

/* Gets all to user visible unread rows by a specific category name and returns their size */
function getVisibleUnreadSizeByCategoryName(type, categoryName) {
	// handle KissManga separately as it does not have categories/folders and no link sharing option
	if (type === 'Manga') {return JQ(selectorVisible).size();}

	// no category given assumes it means all categories combined (All X option in the drop down menu)
	if (categoryName === undefined) {
		if (type === 'Anime') {categoryName = strAllAnimes;}
		if (type === 'Cartoon') {categoryName = strAllCartoons;}
		if (type === 'Drama') {categoryName = strAllDramas;}
	}

	// select indepently from a specific category all visible not completed row size
	if (categoryName === strAllAnimes || categoryName === strAllCartoons || categoryName === strAllDramas) {
		return JQ(selectorVisible).size();
	}

	// handle the special 'Uncategorized' category
	if (categoryName === strNoCategory) {
		if (type === 'Cartoon') {return JQ("tr.trCartoon[catName=''] > td > " + selectorVisible ).size();}
		if (type === 'Drama') {return JQ("tr.trDrama[catName=''] > td > " + selectorVisible ).size();}
		return JQ("tr.trAnime[catName=''] > td > " + selectorVisible ).size();
	}
	// non special categories
	if (type == 'Cartoon') {return JQ("tr.trCartoon[catName='"+ categoryName + "'] > td > " + selectorVisible ).size();}
	if (type == 'Drama') {return JQ("tr.trDrama[catName='"+ categoryName + "'] > td > " + selectorVisible ).size();}
	return JQ("tr.trAnime[catName='" + categoryName + "'] > td > " + selectorVisible).size();
};

/* Gets the total size (completed and not completed) by a specific Category name*/
function getTotalSizeByCategoryName(type, categoryName) {

	// handle KissManga separately as it does not have categories/folders and no link sharing option
	if (type === 'Manga') {return JQ('.aUnRead').size();}

	// no category given assumes it means all categories combined (All X option in the drop down menu)
	if (categoryName == undefined) {
		if (type === 'Anime') {categoryName = strAllAnimes;}
		if (type === 'Cartoon') {categoryName = strAllCartoons;}
		if (type === 'Drama') {categoryName = strAllDramas;}
	}

	// select EVERYTHING (total row count)
	if (categoryName === strAllAnimes || categoryName === strAllCartoons || categoryName === strAllDramas) {
		return JQ('.aUnRead').size();
	}

	// handle the special 'Uncategorized' category
	if (categoryName === strNoCategory) {
		if (type === 'Cartoon') {return JQ("tr.trCartoon[catName='']").size();}
		if (type === 'Drama') {return JQ("tr.trDrama[catName='']").size();}
		return JQ("tr.trAnime[catName='']").size();
	}

	// non special categories
	if (type === 'Cartoon') {return JQ("tr.trCartoon[catName='" + categoryName + "']").size();}
	if (type === 'Drama') {return JQ("tr.trDrama[catName='" + categoryName + "']").size();}
	return JQ("tr.trAnime[catName='" + categoryName + "']").size();
};

/* Adds an 's' if appropriate (basically add it if the Kiss site does so too) */
function getPluralS(type) {
	if(type === 'Anime') {return '';}
	if(type === 'Manga') {return 's';}
	if(type === 'Cartoon') {return 's';}
	if(type === 'Drama') {return '';}
	return '';
};

/* gets the html that represents the data in a table */
function getTableHtml(type) {
	var tableHtml = "
";
	// add header
	tableHtml += "
 " + strCatName + "	 " + strUnread + "	 " + strRead + "
";
	tableHtml += "

";//style row (the bookmark table has it too)

	var allTotal = getTotalSizeByCategoryName(type);
	var allUnread = getVisibleUnreadSizeByCategoryName(type);
	var allRead = allTotal - allUnread;
	var oddEntry = true;
	var additionalClasses = '';

	// add stripes to the rows
	if(oddEntry){
		additionalClasses += userOdd;
		oddEntry = !oddEntry;
	} else {
		oddEntry = !oddEntry;
	}
	// if a category is completed, add this css class. To be used in the future
	if(allUnread == 0){ additionalClasses += (' ' + userCompleted);}
	// All X category
	tableHtml += "
 All " + type + getPluralS(type) +"	 " + allUnread + sep + allTotal + "	 " + allRead + sep + allTotal + "
";

	// do not check for categories if it is KissManga
	if(type != 'Manga') {
		// go over all categories
		for (var index = 0; index < catArr.length; ++index) {
			additionalClasses = '';
			var currCatTotal = getTotalSizeByCategoryName(type, catArr[index]);
			var currCatUnread = getVisibleUnreadSizeByCategoryName(type, catArr[index]);
			var currCatRead = currCatTotal - currCatUnread;
			// move css class stuff in extra function?
			if(oddEntry){
				additionalClasses += userOdd;
				oddEntry = !oddEntry;
			} else {oddEntry = !oddEntry;}
			if(currCatUnread == 0){additionalClasses += (' ' + userCompleted);}
			// add entry for the current category
			tableHtml += "
 " + catArr[index] + "	 " + currCatUnread + sep + currCatTotal + "	 " + currCatRead + sep + currCatTotal + "
";
		}
	}

	tableHtml += '
';

	return tableHtml;
};

/* determine the Site this script is running on */
function getSiteType() {
	var url = window.location.href;
	// Why indexOf? Not every browser supports includes (I am looking at you, Firefox!)
	if (url.indexOf('kissmanga') != -1) {return 'Manga';}
	if (url.indexOf('kisscartoon') != -1) {return 'Cartoon';}
	if (url.indexOf('kissasian') != -1) {return 'Drama';}
	return 'Anime';
};

/* Makes the button actually do stuff */
function addClickFunctionality() {
	var statTableHidden = true;
	JQ('#btnToggleStats').click(function() {
		statTableHidden = !statTableHidden;
		JQ('.' + userClassTable).fadeToggle(400);
		if (statTableHidden) {
			JQ('#btnToggleStats').text('Show Statistics');
		}else {
			JQ('#btnToggleStats').text('Hide Statistics');
		}
	});
};
/* combine everything */
function create() {
	var siteType = getSiteType();
	var tableHtml = getTableHtml(siteType);

	buttonHtml = " Show Statistics ";
	var clear2InTable = "

";
	var divHtml = "
" + buttonHtml + clear2InTable + tableHtml + "
";

	var catSelect = '#divListCategories';
	// KissManga has no Category drop down selection menu
	if(siteType == 'Manga') {catSelect = '.listing';}

	JQ(divHtml).insertBefore(catSelect);
	JQ('#' + mainId).prev('div.clear2').remove();
	// hide by default
	JQ('.' + userClassTable).hide();

	addClickFunctionality();
};

// load after 2 seconds to capture delayed categories. Categories are loaded from the server asynchronously.
JQ(window).load(function() {
	setTimeout(function() {
		create();
	}, 2000);
});
<|endoftext|>


<commit_before>const KolibriModule = require('kolibri_module');
const coreActions = require('kolibri.coreVue.vuex.actions');
const router = require('kolibri.coreVue.router');

const Vue = require('kolibri.lib.vue');

const RootVue = require('./views');
const actions = require('./state/actions');
const store = require('./state/store');
const PageNames = require('./constants').PageNames;

class LearnModule extends KolibriModule {
  ready() {
    coreActions.getCurrentSession(store).then(() => {
      const routes = [
        {
          name: PageNames.EXPLORE_ROOT,
          path: '/topics',
          handler: (toRoute, fromRoute) => {
            actions.redirectToExploreChannel(store);
          },
        },
        {
          name: PageNames.EXPLORE_CHANNEL,
          path: '/topics/:channel_id',
          handler: (toRoute, fromRoute) => {
            actions.showExploreChannel(store, toRoute.params.channel_id);
          },
        },
        {
          name: PageNames.EXPLORE_TOPIC,
          path: '/topics/:channel_id/topic/:id',
          handler: (toRoute, fromRoute) => {
            actions.showExploreTopic(store, toRoute.params.channel_id, toRoute.params.id);
          },
        },
        {
          name: PageNames.EXPLORE_CONTENT,
          path: '/topics/:channel_id/content/:id',
          handler: (toRoute, fromRoute) => {
            actions.showExploreContent(store, toRoute.params.channel_id, toRoute.params.id);
          },
        },
        {
          name: PageNames.LEARN_ROOT,
          path: '/recommended',
          handler: (toRoute, fromRoute) => {
            actions.redirectToLearnChannel(store);
          },
        },
        {
          name: PageNames.LEARN_CHANNEL,
          path: '/recommended/:channel_id',
          handler: (toRoute, fromRoute) => {
            const page = toRoute.query.page ? Number(toRoute.query.page) : 1;
            actions.showLearnChannel(store, toRoute.params.channel_id, page);
          },
        },
        {
          name: PageNames.LEARN_CONTENT,
          path: '/recommended/:channel_id/content/:id',
          handler: (toRoute, fromRoute) => {
            actions.showLearnContent(store, toRoute.params.channel_id, toRoute.params.id);
          },
        },
        {
          name: PageNames.SCRATCHPAD,
          path: '/scratchpad',
          handler: (toRoute, fromRoute) => {
            actions.showScratchpad(store);
          },
        },
        {
          name: PageNames.CONTENT_UNAVAILABLE,
          path: '/content-unavailable',
          handler: (toRoute, fromRoute) => {
            actions.showContentUnavailable(store);
          },
        },
        {
          name: PageNames.SEARCH_ROOT,
          path: '/search',
          handler: (toRoute, fromRoute) => {
            actions.redirectToChannelSearch(store);
          },
        },
        {
          name: PageNames.SEARCH,
          path: '/search/:channel_id',
          handler: (toRoute, fromRoute) => {
            actions.showSearch(store, toRoute.params.channel_id, toRoute.query.query);
          },
        },
        {
          path: '/',
          redirect: '/recommended',
        },
      ];

      this.rootvue = new Vue({
        el: 'rootvue',
        render: createElement => createElement(RootVue),
        router: router.init(routes),
      });
    });
  }
}

module.exports = new LearnModule();
<commit_msg>update url patterns of learn app<commit_after>const KolibriModule = require('kolibri_module');
const coreActions = require('kolibri.coreVue.vuex.actions');
const router = require('kolibri.coreVue.router');

const Vue = require('kolibri.lib.vue');

const RootVue = require('./views');
const actions = require('./state/actions');
const store = require('./state/store');
const PageNames = require('./constants').PageNames;

class LearnModule extends KolibriModule {
  ready() {
    coreActions.getCurrentSession(store).then(() => {
      const routes = [
        {
          path: '/',
          redirect: '/recommended',
        },
        {
          name: PageNames.EXPLORE_ROOT,
          path: '/topics',
          handler: (toRoute, fromRoute) => {
            actions.redirectToExploreChannel(store);
          },
        },
        {
          name: PageNames.LEARN_ROOT,
          path: '/recommended',
          handler: (toRoute, fromRoute) => {
            actions.redirectToLearnChannel(store);
          },
        },
        {
          name: PageNames.SEARCH_ROOT,
          path: '/search',
          handler: (toRoute, fromRoute) => {
            actions.redirectToChannelSearch(store);
          },
        },
        {
          name: PageNames.SCRATCHPAD,
          path: '/scratchpad',
          handler: (toRoute, fromRoute) => {
            actions.showScratchpad(store);
          },
        },
        {
          name: PageNames.CONTENT_UNAVAILABLE,
          path: '/content-unavailable',
          handler: (toRoute, fromRoute) => {
            actions.showContentUnavailable(store);
          },
        },
        {
          name: PageNames.EXPLORE_CHANNEL,
          path: '/:channel_id/topics',
          handler: (toRoute, fromRoute) => {
            actions.showExploreChannel(store, toRoute.params.channel_id);
          },
        },
        {
          name: PageNames.EXPLORE_TOPIC,
          path: '/:channel_id/topics/t/:id',
          handler: (toRoute, fromRoute) => {
            actions.showExploreTopic(store, toRoute.params.channel_id, toRoute.params.id);
          },
        },
        {
          name: PageNames.EXPLORE_CONTENT,
          path: '/:channel_id/topics/c/:id',
          handler: (toRoute, fromRoute) => {
            actions.showExploreContent(store, toRoute.params.channel_id, toRoute.params.id);
          },
        },
        {
          name: PageNames.LEARN_CHANNEL,
          path: '/:channel_id/recommended',
          handler: (toRoute, fromRoute) => {
            const page = toRoute.query.page ? Number(toRoute.query.page) : 1;
            actions.showLearnChannel(store, toRoute.params.channel_id, page);
          },
        },
        {
          name: PageNames.LEARN_CONTENT,
          path: '/:channel_id/recommended/:id',
          handler: (toRoute, fromRoute) => {
            actions.showLearnContent(store, toRoute.params.channel_id, toRoute.params.id);
          },
        },
        {
          name: PageNames.SEARCH,
          path: '/:channel_id/search',
          handler: (toRoute, fromRoute) => {
            actions.showSearch(store, toRoute.params.channel_id, toRoute.query.query);
          },
        },
        {
          path: '*',
          redirect: '/',
        },
      ];

      this.rootvue = new Vue({
        el: 'rootvue',
        render: createElement => createElement(RootVue),
        router: router.init(routes),
      });
    });
  }
}

module.exports = new LearnModule();
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2014 Microsoft DX TED EMEA

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

var crypto = require('crypto');

// Event Hubs parameters
var namespace = 'YourNameSpaceHere';
var hubname = 'YourHubNameHere';
var deviceName = 'mytessel';
var eventHubAccessKeyName = 'YourEventHubKeyNameHere';
var eventHubAccessKey = 'YourSharedAccessKeyTokenHere';

// Full Event Hub publisher URI
var eventHubUri = 'https://' + namespace + '.servicebus.windows.net' + '/' + hubname + '/publishers/' + deviceName + '/messages';

function createSASToken(uri, keyName, key)
{
    //Token expires in december
    var expiry = '1417774602';

    var signedString = encodeURIComponent(uri) + '\n' + expiry;
    var hmac = crypto.createHmac('sha256', key);
    hmac.update(signedString);
    var signature = hmac.digest('base64');
    var token = 'SharedAccessSignature sr=' + encodeURIComponent(uri) + '&sig=' + encodeURIComponent(signature) + '&se=' + expiry + '&skn=' + keyName;

    return token;
}

var createdSASToken = createSASToken(eventHubUri, eventHubAccessKeyName, eventHubAccessKey)
console.log(createdSASToken);

<commit_msg>Fix expiry date<commit_after>// The MIT License (MIT)

// Copyright (c) 2014 Microsoft DX TED EMEA

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

var crypto = require('crypto');

// Event Hubs parameters
var namespace = 'YourNameSpaceHere';
var hubname = 'YourHubNameHere';
var deviceName = 'mytessel';
var eventHubAccessKeyName = 'YourEventHubKeyNameHere';
var eventHubAccessKey = 'YourSharedAccessKeyTokenHere';

// Full Event Hub publisher URI
var eventHubUri = 'https://' + namespace + '.servicebus.windows.net' + '/' + hubname + '/publishers/' + deviceName + '/messages';

function createSASToken(uri, keyName, key)
{
    //Token expires in december
    var expiry = '1454612852';

    var signedString = encodeURIComponent(uri) + '\n' + expiry;
    var hmac = crypto.createHmac('sha256', key);
    hmac.update(signedString);
    var signature = hmac.digest('base64');
    var token = 'SharedAccessSignature sr=' + encodeURIComponent(uri) + '&sig=' + encodeURIComponent(signature) + '&se=' + expiry + '&skn=' + keyName;

    return token;
}

var createdSASToken = createSASToken(eventHubUri, eventHubAccessKeyName, eventHubAccessKey)
console.log(createdSASToken);

<|endoftext|>