<commit_before>console.log('Loading function');

var DNS = require('dns');
var merge = require('merge');
var async = require('async');
var fs = require('fs');

exports.handler = function(event, context) {
    // configurable options through event
    var config = {
        aws_access_key: "",
        aws_secret_access_key: "",
        aws_region: "",
        elb_names: [],
        s3_bucket: "",
        s3_dir: "elb",
        test: true
    }
    var cfg = JSON.parse(fs.readFileSync('./etc/detectandwriteelbips.json', 'utf8'));
    config = merge(config, cfg);

    //if (config.elb_names.length == 0) {
    //    throw 'error elbs must be specified';
    //}

    console.log("STARTING IN %s MODE", config.test ? "TEST" : "PROD");

    var AWS = require('aws-sdk');
    AWS.config.update({
        accessKeyId: config.aws_access_key,
        secretAccessKey: config.aws_secret_access_key,
        region: config.aws_region
    });

    var locals = {
        elbs: []
    };

    // ELB data transfer object to store on S3
    var Elb = function() {
        this.type = 'elb';
        this.name = '';
        this.dns = '';
        this.ipv4 = [];
        this.prev_ipv4 = [];
        this.ipv6 = [];
        this.prev_ipv6 = [];
        this.changed = null;
    }

    async.series([
            function(callback) {
                // get the elb descriptions from AWS
                // and create an Elb in locals.elbs
                console.log('Retrieving ELB data');
                var awsElb = new AWS.ELB({
                    apiVersion: '2012-06-01'
                });
                awsElb.describeLoadBalancers({
                        LoadBalancerNames: config.elb_names
                    }, function(err, data) {
                        if (!err) {
                            // store elb dns names in locals
                            for (var elbIndex = 0; elbIndex < data.LoadBalancerDescriptions.length; elbIndex++) {
                                var elb = new Elb();
                                elb.name = data.LoadBalancerDescriptions[elbIndex].LoadBalancerName;
                                elb.dns = data.LoadBalancerDescriptions[elbIndex].DNSName;
                                locals.elbs.push(elb);
                            }
                        }
                        callback(err);
                });

            },
            function(callback) {
                console.log('Looking up IPV4 and IPV6 for ELBs');
                // locals.elbs now contains array of loadbalancer objects
                // foreach local.elbs, append ipv4 and ipv6 adresses
                async.forEach(locals.elbs, function(elb, callback) {
                    // lookup ipv4 and ipv6 adresses
                    async.parallel([
                        function(callback) {
                            DNS.resolve4(elb.dns, function(err,data) {
                                if (!err) {
                                    elb.ipv4 = data.sort();
                                } else {
                                    if (err.code == 'ENODATA') {
                                        err =  null;
                                    }
                                }
                                callback(err);
                            });
                        },
                        function(callback) {
                            DNS.resolve6(elb.dns, function(err,data) {
                                if (!err) {
                                    elb.ipv6 = data.sort();;
                                } else {
                                    if (err.code == 'ENODATA') {
                                        err =  null;
                                    }
                                }
                                callback(err);
                            });
                        }
                    ], function(err) {
                        callback(err);
                    });
                }, function(err) {
                    callback(err);
                });
            },
            function(callback) {
                // loading previous data
                console.log('Loading previous data from S3');
                var S3 = new AWS.S3({});
                async.forEach(locals.elbs, function(elb, callback) {
                    var key = config.s3_dir + "/" + elb.name + ".json";
                    var params = {Bucket: config.s3_bucket, Key: key};
                    S3.getObject(params, function(err,data) {
                        if (!err) {
                            var oldElb = JSON.parse(data.Body);
                            elb.prev_ipv4 = oldElb.ipv4;
                            elb.prev_ipv6 = oldElb.ipv6;
                        } else if (err.code == 'NoSuchKey') {
                            // first instantiation
                            err = null;
                        }
                        callback(err);
                    });
                }, function(err) {
                    callback(err);
                });
            },
            function(callback) {
                // get the existing description and verify if ipv4 or ipv6 is changed.
                // if changed, write data to S3
                console.log('Writing changed ELB datas to S3');
                var S3 = new AWS.S3({});
                async.forEach(locals.elbs, function(elb, callback) {
                        if (elb.ipv4.toString() != elb.prev_ipv4.toString() || elb.ipv6.toString() != elb.prev_ipv6.toString()) {
                            console.log('elb %s ips changed!', elb.name);
                            elb.changed = new Date();
                            if (config.test) {
                                console.log("running in test mode, skipped storing on s3");
                                callback();
                            } else {
                                var key = config.s3_dir + "/" + elb.name + ".json";
                                console.log("writing data to %s %s", config.s3_bucket, key);
                                var params = {Bucket: config.s3_bucket, Key: key, Body: JSON.stringify(elb)};
                                S3.putObject(params, function(err, data) {
                                    callback(err);
                                });
                            }
                        } else {
                            console.log('no change for elb ' + elb.name);
                            callback();
                        }

                    }, function(err) {
                        callback(err);
                });

            },
            function(callback) {
                console.log('all done');
                callback();
            }
        ],
        function(err) {
            if (err) {
                console.log(err);
                context.done(err,'something went wrong');
            } else {
                context.done(null, 'done');
            }
        }
    );

};<commit_msg>more logging<commit_after>console.log('Loading function');

var DNS = require('dns');
var merge = require('merge');
var async = require('async');
var fs = require('fs');

exports.handler = function(event, context) {
    // configurable options through event
    var config = {
        aws_access_key: "",
        aws_secret_access_key: "",
        aws_region: "",
        elb_names: [],
        s3_bucket: "",
        s3_dir: "elb",
        test: true
    }
    var cfg = JSON.parse(fs.readFileSync('./etc/detectandwriteelbips.json', 'utf8'));
    config = merge(config, cfg);

    //if (config.elb_names.length == 0) {
    //    throw 'error elbs must be specified';
    //}

    console.log("STARTING IN %s MODE", config.test ? "TEST" : "PROD");

    var AWS = require('aws-sdk');
    AWS.config.update({
        accessKeyId: config.aws_access_key,
        secretAccessKey: config.aws_secret_access_key,
        region: config.aws_region
    });

    var locals = {
        elbs: []
    };

    // ELB data transfer object to store on S3
    var Elb = function() {
        this.type = 'elb';
        this.name = '';
        this.dns = '';
        this.ipv4 = [];
        this.prev_ipv4 = [];
        this.ipv6 = [];
        this.prev_ipv6 = [];
        this.changed = null;
    }

    async.series([
            function(callback) {
                // get the elb descriptions from AWS
                // and create an Elb in locals.elbs
                console.log('Retrieving ELB data for ELBs %s', config.elb_names.length > 0 ? config.elb_names.join(', ') : 'all ELBS');
                var awsElb = new AWS.ELB({
                    apiVersion: '2012-06-01'
                });
                awsElb.describeLoadBalancers({
                        LoadBalancerNames: config.elb_names
                    }, function(err, data) {
                        if (!err) {
                            // store elb dns names in locals
                            for (var elbIndex = 0; elbIndex < data.LoadBalancerDescriptions.length; elbIndex++) {
                                var elb = new Elb();
                                elb.name = data.LoadBalancerDescriptions[elbIndex].LoadBalancerName;
                                elb.dns = data.LoadBalancerDescriptions[elbIndex].DNSName;
                                locals.elbs.push(elb);
                            }
                        }
                        callback(err);
                });

            },
            function(callback) {
                if (locals.elbs.length == 0) {
                    console.log('No ELBS found.');
                    callback();
                } else {
                    console.log('found elbs %s', locals.elbs.map(function (elb) {
                        return '1';
                    }).join(', '));

                    console.log('Looking up IPV4 and IPV6 for ELBs');
                    // locals.elbs now contains array of loadbalancer objects
                    // foreach local.elbs, append ipv4 and ipv6 adresses
                    async.forEach(locals.elbs, function (elb, callback) {
                        // lookup ipv4 and ipv6 adresses
                        async.parallel([
                            function (callback) {
                                DNS.resolve4(elb.dns, function (err, data) {
                                    if (!err) {
                                        elb.ipv4 = data.sort();
                                    } else {
                                        if (err.code == 'ENODATA') {
                                            err = null;
                                        }
                                    }
                                    callback(err);
                                });
                            },
                            function (callback) {
                                DNS.resolve6(elb.dns, function (err, data) {
                                    if (!err) {
                                        elb.ipv6 = data.sort();
                                        ;
                                    } else {
                                        if (err.code == 'ENODATA') {
                                            err = null;
                                        }
                                    }
                                    callback(err);
                                });
                            }
                        ], function (err) {
                            callback(err);
                        });
                    }, function (err) {
                        callback(err);
                    });
                }
            },
            function(callback) {
                // loading previous data
                console.log('Loading previous data from S3');
                var S3 = new AWS.S3({});
                async.forEach(locals.elbs, function(elb, callback) {
                    var key = config.s3_dir + "/" + elb.name + ".json";
                    var params = {Bucket: config.s3_bucket, Key: key};
                    S3.getObject(params, function(err,data) {
                        if (!err) {
                            var oldElb = JSON.parse(data.Body);
                            elb.prev_ipv4 = oldElb.ipv4;
                            elb.prev_ipv6 = oldElb.ipv6;
                        } else if (err.code == 'NoSuchKey') {
                            // first instantiation
                            err = null;
                        }
                        callback(err);
                    });
                }, function(err) {
                    callback(err);
                });
            },
            function(callback) {
                // get the existing description and verify if ipv4 or ipv6 is changed.
                // if changed, write data to S3
                console.log('Writing changed ELB datas to S3');
                var S3 = new AWS.S3({});
                async.forEach(locals.elbs, function(elb, callback) {
                        if (elb.ipv4.toString() != elb.prev_ipv4.toString() || elb.ipv6.toString() != elb.prev_ipv6.toString()) {
                            console.log('elb %s ips changed!', elb.name);
                            elb.changed = new Date();
                            if (config.test) {
                                console.log("running in test mode, skipped storing on s3");
                                callback();
                            } else {
                                var key = config.s3_dir + "/" + elb.name + ".json";
                                console.log("writing data to %s %s", config.s3_bucket, key);
                                var params = {Bucket: config.s3_bucket, Key: key, Body: JSON.stringify(elb)};
                                S3.putObject(params, function(err, data) {
                                    callback(err);
                                });
                            }
                        } else {
                            console.log('no change for elb ' + elb.name);
                            callback();
                        }

                    }, function(err) {
                        callback(err);
                });

            },
            function(callback) {
                console.log('all done');
                callback();
            }
        ],
        function(err) {
            if (err) {
                console.log(err);
                context.done(err,'something went wrong');
            } else {
                context.done(null, 'done');
            }
        }
    );

};<|endoftext|>


<commit_before>// IIFE - Immediately Invoked Function Expression
  (function(yourcode) {

    // The global jQuery object is passed as a parameter
  	yourcode(window.jQuery, window, document);

  }(function($, window, document) {

    // The $ is now locally scoped

   // Listen for the jQuery ready event on the document
   $(function() {

	// The DOM is ready!

	var node_figs = document.getElementById('slider_content').getElementsByTagName('figure'),
		first_node_figs = node_figs[0];
		fig_wrap = first_node_figs.cloneNode(true);
	document.getElementById('slider_content').appendChild(fig_wrap);

	var total_slides = $('#slider_content').children('figure').length,
		w_slides_wrapper = total_slides * 100,
		w_percentage = 100/total_slides,
		timeVal = 3000,
		counter = 0,
		timeoutId,
		slides = {
	 		w: $('.slider_content_img').width(),
	 		h: $('.slider_content_img').height(),
	 		nav_animation: 'true'
	 	}

	function setDotNav(){

		var slider = document.getElementById('slider');
		slider.innerHTML += '
'
		var slider_nav = document.getElementById('slider_nav');
		slider_nav.innerHTML += '

';
		var ul = document.getElementById('dot-nav');

		var i = 0;
		while(i < total_slides-1){
			var li = document.createElement('li');
			li.innerHTML += ''+i+'';
			ul.appendChild(li);
			i++;
		}
		ul.appendChild(document.createElement('li'));

		slider.innerHTML += '

\n

';
	}

 	function init(){

 		setDotNav();
 		setController();

		$('#slider').css({
			'max-width': slides.w+'px',
			overflow: 'hidden'
		});

 		$('#slider_content').css({
 			width: w_slides_wrapper+'%'
 		});

 		$('.slider_content_img').css({
 			width: w_percentage+'%'
 		});

 	}

	// create timer
	function setTimer() {
		timeoutId = setTimeout(setTimeFunc, timeVal);
		return false;
	}

	function animateSlides(num){
		TweenLite.killTweensOf($('#slider_content'));
		TweenLite.to($('#slider_content'), 0.8, {css:{left:-(num*100)+'%'}, ease:Power2.easeInOut });

		if(counter >= total_slides-1){
			TweenLite.killTweensOf($('.dotstyle-dotmove li:last-child'));
			TweenLite.to($('.dotstyle-dotmove li:last-child'), 0.8, { css:{left:0+'%'}, ease:Power2.easeInOut});
		}else{
			TweenLite.killTweensOf($('.dotstyle-dotmove li:last-child'));
			TweenLite.to($('.dotstyle-dotmove li:last-child'), 0.8, { css:{left:(48*num)}, ease:Power2.easeInOut});
		}
	}

	function checkNextPrevLimit(){

		if (counter < 0){
			counter = total_slides-2;
			animateSlides(counter);
		}

		if (counter >= total_slides) {
			counter = 1;
			$('#slider_content').css({
				left: '0%'
			});
			animateSlides(counter);
		} else {
			animateSlides(counter);
		}

	}

	// slide animation
	function setTimeFunc() {

		counter++;
		checkNextPrevLimit();
		setTimer();
		return false;

	}

	function setController(){

		$('ul#dot-nav li').each(function(index) {
	  		$(this).click(function(){
				animateSlides(index);
				clearInterval(timeoutId);
			})
		});

		$('#prev_btn').click(function(){
			clearInterval(timeoutId);
			counter--;
			checkNextPrevLimit();
			console.log(counter);
		});

		$('#next_btn').click(function(){
			clearInterval(timeoutId);
			counter++;
			checkNextPrevLimit();

		});

		$('#slider').hover(
			function() {
			    $('#prev_next_btn').fadeIn();
			}, function() {
			    $('#prev_next_btn').fadeOut();
			}
		);
	}

	init();
	setTimer();

   });

   // The rest of the code goes here!

  }));<commit_msg>common.js modified<commit_after>// IIFE - Immediately Invoked Function Expression
  (function(yourcode) {

    // The global jQuery object is passed as a parameter
  	yourcode(window.jQuery, window, document);

  }(function($, window, document) {

    // The $ is now locally scoped

   // Listen for the jQuery ready event on the document
   $(function() {

	// The DOM is ready!

	//clone first image
	var node_figs = document.getElementById('slider_content').getElementsByTagName('figure'),
		first_node_figs = node_figs[0],
		fig_wrap = first_node_figs.cloneNode(true);
	document.getElementById('slider_content').appendChild(fig_wrap);

	//clone last image
	var len = $('#slider_content').children('figure').length;
	var last_node_figs = node_figs[len-2],
		fig_last = last_node_figs.cloneNode(true);
	document.getElementById('slider_content').appendChild(fig_last);
	document.getElementById('slider_content').insertBefore(fig_last,first_node_figs);

	var total_slides = $('#slider_content').children('figure').length,
		w_slides_wrapper = total_slides * 100,
		w_percentage = 100/total_slides,
		timeVal = 3000,
		counter = 0,
		timeoutId,
		slides = {
	 		w: $('.slider_content_img').width(),
	 		h: $('.slider_content_img').height(),
	 		nav_animation: 'true'
	 	}

	function setDotNav(){

		var slider = document.getElementById('slider');
		slider.innerHTML += '
'
		var slider_nav = document.getElementById('slider_nav');
		slider_nav.innerHTML += '

';
		var ul = document.getElementById('dot-nav');

		var i = 1;
		while(i < total_slides-1){
			var li = document.createElement('li');
			li.innerHTML += ''+i+'';
			ul.appendChild(li);
			i++;
		}
		ul.appendChild(document.createElement('li'));

		slider.innerHTML += '

\n

';
	}

 	function init(){

 		counter = counter + 1;
 		TweenLite.to($('#slider_content'), 0, {css:{left:-(counter*100)+'%'} });
 		setDotNav();
 		setController();

		$('#slider').css({
			'max-width': slides.w+'px',
			overflow: 'hidden'
		});

 		$('#slider_content').css({
 			width: w_slides_wrapper+'%'
 		});

 		$('.slider_content_img').css({
 			width: w_percentage+'%'
 		});

 	}

	// create timer
	function setTimer() {
		timeoutId = setTimeout(setTimeFunc, timeVal);
		return false;
	}

	function animateSlides(num){

		TweenLite.killTweensOf($('#slider_content'));
		TweenLite.to($('#slider_content'), 0.8, {css:{left:-(num*100)+'%'}, ease:Power2.easeInOut });

		if(counter <= 0){
			TweenLite.killTweensOf($('.dotstyle-dotmove li:last-child'));
			TweenLite.to($('.dotstyle-dotmove li:last-child'), 0.8, { css:{left:(48*(total_slides-3))}, ease:Power2.easeInOut});
		}else if(counter >= total_slides-1){
			TweenLite.killTweensOf($('.dotstyle-dotmove li:last-child'));
			TweenLite.to($('.dotstyle-dotmove li:last-child'), 0.8, { css:{left:0+'%'}, ease:Power2.easeInOut});
		}else{
			TweenLite.killTweensOf($('.dotstyle-dotmove li:last-child'));
			TweenLite.to($('.dotstyle-dotmove li:last-child'), 0.8, { css:{left:(48*(num-1))}, ease:Power2.easeInOut});
		}

	}

	function checkNextPrevLimit(){

		if (counter < 0){
			counter = total_slides-2;
			animateSlides(counter);
			$('#slider_content').css({
				left: -(counter*100)+'%'
			});
			counter = 2;
			animateSlides(counter);

		}else if (counter >= total_slides) {
			counter = 1;
			$('#slider_content').css({
				left: -(counter*100)+'%'
			});
			counter = 2;
			animateSlides(counter);
		}else{
			animateSlides(counter);
		}

	}

	// slide animation
	function setTimeFunc() {

		counter++;
		checkNextPrevLimit();
		setTimer();
		return false;

	}

	function setController(){

		$('ul#dot-nav li').each(function(index) {
	  		$(this).click(function(){
	  			counter = index+1;
				animateSlides(counter);
				clearInterval(timeoutId);
			})
		});

		$('#prev_btn').click(function(){
			clearInterval(timeoutId);
			counter--;
			checkNextPrevLimit();
		});

		$('#next_btn').click(function(){
			clearInterval(timeoutId);
			counter++;
			checkNextPrevLimit();
		});

		$('#slider').hover(
			function() {
			    $('#prev_next_btn').fadeIn();
			}, function() {
			    $('#prev_next_btn').fadeOut();
			}
		);
	}

	init();
	setTimer();

   });

   // The rest of the code goes here!

  }));<|endoftext|>


<commit_before>function showUser(userData){
	var account = $('
').addClass("account").addClass("col-md-2 panel panel-default");
	if(userData.credit < 0){
		account.addClass("debt");
	}
	account.append($('
').addClass("name").text(userData.name));
	account.append($('
').addClass("credit").text(userData.credit + " €"));

	$('#accounts').append(account);
	account.click(function(){
		showDetail(userData);
	})
}

function showDetail(userData){
	var detail = $('
');

	var row = $('
');
	detail.append(row);

	var userinfo = $('
');
	row.append(userinfo);

	userinfo.append($('
').addClass("name").text(userData.name));
	userinfo.append($('
').addClass("credit").text(userData.credit + " €"));

	// Add Credit-Area
	var addCreditArea = $('
').addClass('panel panel-default');
	addCreditArea.append($('
').addClass('panel-heading')
		.append($('
').addClass('panel-title').text('Add Credit'))
	);

	var creditarea = $('
');
	row.append(creditarea);

	creditarea.append(addCreditArea);
	var addCreditAreaBody = $('
').addClass('panel-body');
	addCreditArea.append(addCreditAreaBody);

	var plus50Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 0.50€");
	var plus1Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 1€");
	var plus2Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 2€");
	var plus5Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 5€");
	addCreditAreaBody.append(plus50Button);
	addCreditAreaBody.append(plus1Button);
	addCreditAreaBody.append(plus2Button);
	addCreditAreaBody.append(plus5Button);

	var removeCreditArea = $('
').addClass('panel').addClass('panel-default');
	addCreditArea.append($('
').addClass('panel-heading')
		.append($('
').addClass('panel-title').text('Remove Credit'))
	);
	var removeCreditAreaBody = $('
').addClass('panel-body');

	addCreditArea.append(removeCreditAreaBody);

	var minus50Button  = $('<button>').addClass('btn btn-danger btn-lg').text("- 0,50€");
	var minus100Button = $('<button>').addClass('btn btn-danger btn-lg').text("- 1,00€");
	var minus150Button = $('<button>').addClass('btn btn-danger btn-lg').text("- 1,50€");
	var minus200Button = $('<button>').addClass('btn btn-danger btn-lg').text("- 2,00€");

	removeCreditAreaBody.append(minus50Button);
	removeCreditAreaBody.append(minus100Button);
	removeCreditAreaBody.append(minus150Button);
	removeCreditAreaBody.append(minus200Button);

	var backButton = $('
').addClass('pager').append($('
').addClass('previous').append($('').text('← Back')));
	detail.append(backButton);

	$('#details').empty().append(detail);
	changeView('detail');

	plus50Button.click(function(){
		changeCredit(userData, 0.5);
	});
	plus1Button.click(function(){
		changeCredit(userData, 1);
	});
	plus2Button.click(function(){
		changeCredit(userData, 2);
	});

	plus5Button.click(function(){
		changeCredit(userData, 5);
	});
	minus50Button.click(function(){
		changeCredit(userData, -0.5);
	});
	minus100Button.click(function(){
		changeCredit(userData, -1);
	});
	minus150Button.click(function(){
		changeCredit(userData, -1.5);
	});
	minus200Button.click(function(){
		changeCredit(userData, -2);
	});

	backButton.click(function(){
		changeView('accounts');
	});
}

function getAllUsers(){
	$.getJSON("/users/all", function(data){
		$('#accounts').empty();
		data.forEach(function(user){
			showUser(user);
		});
		var newuser = $('
').addClass('account col-md-2 panel panel-default')
			.append($('
').addClass('newuser').text('+'));
		$('#accounts').append(newuser);

		newuser.click(function(){
			newUser();
		});
	});
	setTimeout(getAllUsers, 500);
}

function newUser(){
	$('#newuser').empty();
	var newUserForm = $('<form role="form" id="newUserForm">');
	var newUserFormGroup = $('
');
	newUserForm.append(newUserFormGroup);
	newUserFormGroup.append($('<input type="username" name="username" required class="form-control">'));
	newUserFormGroup.append($('<input type="submit" value="Add user" class="form-control">'));

	var backButton = $('
').addClass('pager').append($('
').addClass('previous').append($('').text('← Back')));
	$('#newuser').append(backButton);

	$(document).on('submit', '#newUserForm', function(e){
	    e.preventDefault();
	    $.ajax({
            url: '/user/add',
            type: "POST",
            data: $('#newUserForm').serialize(),
            success: function(){
            	changeView('accounts');
            },
            error: function(err){
            	alert(err.responseText);
            }
        });
	});

	backButton.click(function(){
		changeView('accounts');
	});

	$('#newuser').append(newUserForm);

	changeView('new');
}

function changeView(view){
	$('.view').hide();
	switch(view){
		case 'detail':
			$('#details').show();
			break;
		case 'accounts':
			getAllUsers();
			$('#accounts').show();
			break;
		case 'new':
			$('#newuser').show();
			break;

		default:
			throw 'Invalid View: ' + view;
	}
}

function changeCredit(userData, delta){
	$.ajax({
		url: "/user/credit",
		type: "POST",
		dataType: "json",
		data: {
			"username": userData.name,
			"delta": delta
		}
	}).done(function(data){
		showDetail(data);
	});
}

$(function(){
	changeView('accounts');
	getAllUsers();
});<commit_msg>Code cleanup<commit_after>function showUser(userData){
	var account = $('
').addClass("account col-md-2 panel panel-default");
	if(userData.credit < 0){
		account.addClass("debt");
	}
	account.append($('
').addClass("name").text(userData.name));
	account.append($('
').addClass("credit").text(userData.credit + " €"));

	$('#accounts').append(account);
	account.click(function(){
		showDetail(userData);
	})
}

function showDetail(userData){
	var detail = $('
');

	var row = $('
');
	detail.append(row);

	var userinfo = $('
');
	row.append(userinfo);

	userinfo.append($('
').addClass("name").text(userData.name));
	userinfo.append($('
').addClass("credit").text(userData.credit + " €"));

	// Add Credit-Area
	var addCreditArea = $('
').addClass('panel panel-default');
	addCreditArea.append($('
').addClass('panel-heading')
		.append($('
').addClass('panel-title').text('Add Credit'))
	);

	var creditarea = $('
');
	row.append(creditarea);

	creditarea.append(addCreditArea);
	var addCreditAreaBody = $('
').addClass('panel-body');
	addCreditArea.append(addCreditAreaBody);

	var plus50Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 0.50€");
	var plus100Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 1,00€");
	var plus200Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 2,00€");
	var plus500Button = $('<button>').addClass('btn btn-primary btn-lg').text("+ 5,00€");

	var plusbuttons = [plus50Button, plus100Button, plus200Button, plus500Button];
	addCreditAreaBody.append(plusbuttons);

	var removeCreditArea = $('
').addClass('panel panel-default');
	addCreditArea.append($('
').addClass('panel-heading')
		.append($('
').addClass('panel-title').text('Remove Credit'))
	);
	var removeCreditAreaBody = $('
').addClass('panel-body');

	addCreditArea.append(removeCreditAreaBody);

	var minus50Button  = $('<button>').addClass('btn btn-danger btn-lg').text("- 0,50€");
	var minus100Button = $('<button>').addClass('btn btn-danger btn-lg').text("- 1,00€");
	var minus150Button = $('<button>').addClass('btn btn-danger btn-lg').text("- 1,50€");
	var minus200Button = $('<button>').addClass('btn btn-danger btn-lg').text("- 2,00€");

	var minusbuttons = [minus50Button, minus100Button, minus150Button, minus200Button]
	removeCreditAreaBody.append(minusbuttons);

	var backButton = $('
').addClass('pager').append($('
').addClass('previous').append($('').text('← Back')));
	detail.append(backButton);

	$('#details').empty().append(detail);
	changeView('detail');

	// Plus Buttons
	plus50Button.click(function(){
		changeCredit(userData, 0.5);
	});
	plus100Button.click(function(){
		changeCredit(userData, 1);
	});
	plus200Button.click(function(){
		changeCredit(userData, 2);
	});
	plus500Button.click(function(){
		changeCredit(userData, 5);
	});

	// Minus Buttons
	minus50Button.click(function(){
		changeCredit(userData, -0.5);
	});
	minus100Button.click(function(){
		changeCredit(userData, -1);
	});
	minus150Button.click(function(){
		changeCredit(userData, -1.5);
	});
	minus200Button.click(function(){
		changeCredit(userData, -2);
	});

	// Back Button
	backButton.click(function(){
		changeView('accounts');
	});
}

function getAllUsers(){
	$.getJSON("/users/all", function(data){
		$('#accounts').empty();
		data.forEach(function(user){
			showUser(user);
		});
		var newuser = $('
').addClass('account col-md-2 panel panel-default')
			.append($('
').addClass('newuser').text('+'));
		$('#accounts').append(newuser);

		newuser.click(function(){
			newUser();
		});
	});
	setTimeout(getAllUsers, 500);
}

function newUser(){
	$('#newuser').empty();
	var newUserForm = $('<form role="form" id="newUserForm">');
	var newUserFormGroup = $('
');
	newUserForm.append(newUserFormGroup);
	newUserFormGroup.append($('<input type="username" name="username" required class="form-control">'));
	newUserFormGroup.append($('<input type="submit" value="Add user" class="form-control">'));

	var backButton = $('
').addClass('pager').append($('
').addClass('previous').append($('').text('← Back')));
	$('#newuser').append(backButton);

	$(document).on('submit', '#newUserForm', function(e){
	    e.preventDefault();
	    $.ajax({
            url: '/user/add',
            type: "POST",
            data: $('#newUserForm').serialize(),
            success: function(){
            	changeView('accounts');
            },
            error: function(err){
            	alert(err.responseText);
            }
        });
	});

	backButton.click(function(){
		changeView('accounts');
	});

	$('#newuser').append(newUserForm);

	changeView('new');
}

function changeView(view){
	$('.view').hide();
	switch(view){
		case 'detail':
			$('#details').show();
			break;
		case 'accounts':
			getAllUsers();
			$('#accounts').show();
			break;
		case 'new':
			$('#newuser').show();
			break;

		default:
			throw 'Invalid View: ' + view;
	}
}

function changeCredit(userData, delta){
	$.ajax({
		url: "/user/credit",
		type: "POST",
		dataType: "json",
		data: {
			"username": userData.name,
			"delta": delta
		}
	}).done(function(data){
		showDetail(data);
	});
}

$(function(){
	changeView('accounts');
	getAllUsers();
});<|endoftext|>


<commit_before>import MainLayout from './layout/MainLayout'
import ResidentInfoTable from './ResidentInfoTable/ResidentInfoTable';
// 步骤条
import OrderStep from './OrderStep/OrderStep';
// 基本信息
import BaseInfo from './BaseInfo/BaseInfo';
// 确认支付
import PayModal from './PayModal/PayModal'
// 表单项
import CarryMaterial from './formItme/CarryMaterial/CarryMaterial';
//预约居民签约
import ResidentSign from './need/BookingAgent/ResidentSign';
//预约居民体检
import ResidentInspect from './need/BookingAgent/ResidentInspect';
//预约新生儿访视 and 预约产后访视
import Newborn from './need/BookingAgent/Newborn';
//慢病随访通知
import ChronicDisease from './need/NoticeAgent/ChronicDisease';
//最新政策通知
import NewestPolicy from './need/NoticeAgent/NewestPolicy';
//最新活动通知
import NewestActivity from './need/NoticeAgent/NewestActivity';
//孕妇产检通知
import AntenatalCare from './need/NoticeAgent/AntenatalCare';
//儿童健康随访通知
import ChildHealth from './need/NoticeAgent/ChildHealth';
//用药提醒
import Medication from './need/TrackingReminder/Medication';
//高血压随访
import Hypertension from './need/ChronicDisease/Hypertension';
//糖尿病随访
import Diabetes from './need/ChronicDisease/Diabetes';
export {
	MainLayout,
	ResidentInfoTable,
	OrderStep,
	BaseInfo,
	CarryMaterial,
	PayModal,
	ResidentSign,
	ResidentInspect,
	Newborn,
	ChronicDisease,
	NewestPolicy,
	NewestActivity,
	AntenatalCare,
	ChildHealth,
	Medication,
	Hypertension,
	Diabetes,
}<commit_msg>components->update HypertensionA、B、C js<commit_after>import MainLayout from './layout/MainLayout'
import ResidentInfoTable from './ResidentInfoTable/ResidentInfoTable';
// 步骤条
import OrderStep from './OrderStep/OrderStep';
// 基本信息
import BaseInfo from './BaseInfo/BaseInfo';
// 确认支付
import PayModal from './PayModal/PayModal'
// 表单项
import CarryMaterial from './formItme/CarryMaterial/CarryMaterial';
//预约居民签约
import ResidentSign from './need/BookingAgent/ResidentSign';
//预约居民体检
import ResidentInspect from './need/BookingAgent/ResidentInspect';
//预约新生儿访视 and 预约产后访视
import Newborn from './need/BookingAgent/Newborn';
//慢病随访通知
import ChronicDisease from './need/NoticeAgent/ChronicDisease';
//最新政策通知
import NewestPolicy from './need/NoticeAgent/NewestPolicy';
//最新活动通知
import NewestActivity from './need/NoticeAgent/NewestActivity';
//孕妇产检通知
import AntenatalCare from './need/NoticeAgent/AntenatalCare';
//儿童健康随访通知
import ChildHealth from './need/NoticeAgent/ChildHealth';
//用药提醒
import Medication from './need/TrackingReminder/Medication';
//高血压随访
import Hypertension from './need/ChronicDisease/Hypertension';
//糖尿病随访
import Diabetes from './need/ChronicDisease/Diabetes';
// 高血压方案一
import HypertensionA from './Hypertension/HypertensionA';
// 高血压方案二
import HypertensionB from './Hypertension/HypertensionB';
// 高血压方案三
import HypertensionC from './Hypertension/HypertensionC';
// 高血压症状
import HypertensionSymptom from './Hypertension/HypertensionSymptom';

// 糖尿病症状
import DiabetesSymptom from './Diabetes/DiabetesSymptom';

// 糖尿病方案一
import DiabetesA from './Diabetes/DiabetesA';
// 糖尿病方案二
import DiabetesB from './Diabetes/DiabetesB';
// 糖尿病方案三
import DiabetesC from './Diabetes/DiabetesC';

import EditableCell  from './Hypertension/EditableCell';
import MedicationInfo  from './Hypertension/MedicationInfo';

export {
  MainLayout,
  ResidentInfoTable,
  OrderStep,
  BaseInfo,
  CarryMaterial,
  PayModal,
  ResidentSign,
  ResidentInspect,
  Newborn,
  ChronicDisease,
  NewestPolicy,
  NewestActivity,
  AntenatalCare,
  ChildHealth,
  Medication,
  Hypertension,
  Diabetes,
  HypertensionA,
  HypertensionB,
  HypertensionC,
  EditableCell,
  DiabetesA,
  DiabetesB,
  DiabetesC,
  MedicationInfo,

  HypertensionSymptom,
  DiabetesSymptom,

}
<|endoftext|>


<commit_before>(function (Plugin) {
    'use strict';

    var actions    = require('./app/actions'),
        filters    = require('./app/filters'),
        settings   = require('./app/settings'),
        controller = require('./app/controller');

    //NodeBB list of Hooks: https://github.com/NodeBB/NodeBB/wiki/Hooks
    Plugin.hooks = {
        actions: actions,
        filters: filters,
        statics: {
            load: function (params, callback) {
                var router       = params.router,
                    middleware   = params.middleware,
                    controllers  = params.controllers,
                    pluginUri    = '/admin/plugins/points',
                    apiUri       = '/api' + pluginUri,
                    renderAdmin  = function (req, res, next) {
                        res.render(
                            'admin/plugins/points', {}
                        );
                    },
                    renderClient = function (req, res, next) {
                        controller.getTopUsers(function (error, payload) {
                            if (error) {
                                return res.status(500).json(error);
                            }
                            res.render(
                                'client/points', payload
                            );
                        });
                    };

                router.get(pluginUri, middleware.admin.buildHeader, renderAdmin);
                router.get(apiUri, renderAdmin);

                //Client page
                router.get('/points', middleware.buildHeader, renderClient);
                router.get('/api/points', renderClient);

                settings.init(callback);
            }
        }
    };
})(module.exports);<commit_msg>use concrete template endpoint<commit_after>(function (Plugin) {
    'use strict';

    var actions    = require('./app/actions'),
        filters    = require('./app/filters'),
        settings   = require('./app/settings'),
        controller = require('./app/controller');

    //NodeBB list of Hooks: https://github.com/NodeBB/NodeBB/wiki/Hooks
    Plugin.hooks = {
        actions: actions,
        filters: filters,
        statics: {
            load: function (params, callback) {
                var router       = params.router,
                    middleware   = params.middleware,
                    controllers  = params.controllers,
                    pluginUri    = '/admin/plugins/points',
                    apiUri       = '/api' + pluginUri,
                    renderAdmin  = function (req, res, next) {
                        res.render(
                            'admin/plugins/points', {}
                        );
                    },
                    renderClient = function (req, res, next) {
                        controller.getTopUsers(function (error, payload) {
                            if (error) {
                                return res.status(500).json(error);
                            }
                            res.render(
                                'client/points/overview', payload
                            );
                        });
                    };

                router.get(pluginUri, middleware.admin.buildHeader, renderAdmin);
                router.get(apiUri, renderAdmin);

                //Client page
                router.get('/points', middleware.buildHeader, renderClient);
                router.get('/api/points', renderClient);

                settings.init(callback);
            }
        }
    };
})(module.exports);<|endoftext|>


<commit_before>var vm = require('vm'),
    _ = require('underscore'),
    uglifyJs = require('uglify-js-papandreou'),
    bootstrapper = require('../bootstrapper'),
    i18nTools = require('../i18nTools');

module.exports = function (queryObj, environment, removeAfter) {
    if (!environment) {
        throw new Error("transforms.runJavaScriptConditionalBlocks: no 'environment' option provided");
    }
    return function runJavaScriptConditionalBlocks(assetGraph) {
        assetGraph.findAssets(_.extend({type: 'Html'}, queryObj)).forEach(function (htmlAsset) {
            var contextProperties = {console: console};
            contextProperties[environment] = true;
            var context = bootstrapper.createContext(htmlAsset, assetGraph, contextProperties);

            assetGraph.collectAssetsPostOrder(htmlAsset, {type: ['HtmlScript', 'JavaScriptInclude']}).filter(function (asset) {
                return asset.type === 'JavaScript';
            }).forEach(function (javaScript) {
                // Loop through top-level statements:
                var topLevelStatements = javaScript.parseTree[1];
                for (var i = 0 ; i < topLevelStatements.length ; i += 1) {
                    var node = topLevelStatements[i];
                    if (node[0] === 'if' && ((node[1][0] === 'name' && node[1][1] === environment) ||
                                             (node[1][0] === 'dot' && node[1][1][0] === 'name' && node[1][1][1] === 'window' && node[1][2] === environment))) {

                        var fileName = javaScript.url || assetGraph.findRelations({to: javaScript})[0].baseAsset.url;
                        new vm.Script(uglifyJs.uglify.gen_code(node[2]), fileName).runInContext(context);
                        if (removeAfter) {
                            javaScript.parseTree[1].splice(i, 1);
                            i -= 1;
                        }
                    }
                }
            });
        });
    };
};
<commit_msg>runJavaScriptConditionalBlocks: Skip unloaded assets.<commit_after>var vm = require('vm'),
    _ = require('underscore'),
    uglifyJs = require('uglify-js-papandreou'),
    bootstrapper = require('../bootstrapper'),
    i18nTools = require('../i18nTools');

module.exports = function (queryObj, environment, removeAfter) {
    if (!environment) {
        throw new Error("transforms.runJavaScriptConditionalBlocks: no 'environment' option provided");
    }
    return function runJavaScriptConditionalBlocks(assetGraph) {
        assetGraph.findAssets(_.extend({type: 'Html'}, queryObj)).forEach(function (htmlAsset) {
            var contextProperties = {console: console};
            contextProperties[environment] = true;
            var context = bootstrapper.createContext(htmlAsset, assetGraph, contextProperties);

            assetGraph.collectAssetsPostOrder(htmlAsset, {type: ['HtmlScript', 'JavaScriptInclude']}).filter(function (asset) {
                return asset.isLoaded && asset.type === 'JavaScript';
            }).forEach(function (javaScript) {
                // Loop through top-level statements:
                var topLevelStatements = javaScript.parseTree[1];
                for (var i = 0 ; i < topLevelStatements.length ; i += 1) {
                    var node = topLevelStatements[i];
                    if (node[0] === 'if' && ((node[1][0] === 'name' && node[1][1] === environment) ||
                                             (node[1][0] === 'dot' && node[1][1][0] === 'name' && node[1][1][1] === 'window' && node[1][2] === environment))) {

                        var fileName = javaScript.url || assetGraph.findRelations({to: javaScript})[0].baseAsset.url;
                        new vm.Script(uglifyJs.uglify.gen_code(node[2]), fileName).runInContext(context);
                        if (removeAfter) {
                            javaScript.parseTree[1].splice(i, 1);
                            i -= 1;
                        }
                    }
                }
            });
        });
    };
};
<|endoftext|>


<commit_before>import { error } from 'react-notification-system-redux';
import jwtDecode from 'jwt-decode';

import history from '../history';
import getNotificationOptions from '../utils/notifications';
import Auth from '../utils/authentication';

const SET_USER = 'SET_USER';
const SET_AUTHORIZED = 'SET_AUTHORIZED';

const initialState = {
    user: {
        id: null,
        name: 'Unknown',
        avatar: null,
    },
    isAuthorized: false,
};

export default function userReducer(state = initialState, action) {
    switch (action.type) {
        case SET_USER:
            return {
                ...state,
                user: action.user,
            };
        case SET_AUTHORIZED:
            return {
                ...state,
                isAuthorized: action.status,
            };
        default:
            return state;
    }
}

export const setUser = user => ({ type: SET_USER, user });
export const setAuthorized = status => ({ type: SET_AUTHORIZED, status });

const handleAuthentication = (path, values) => async (dispatch) => {
    try {
        let res = await fetch(`${process.env.API_HOST}/auth/${path}`, {
            method: 'POST',
            headers: new Headers({ 'content-type': 'application/json' }),
            mode: 'cors',
            body: JSON.stringify(values),
        });
        res = await res.json();

        if (res.token) {
            const decoded = jwtDecode(res.token);

            // set token to localstorage
            Auth.authenticateUser(res.token);

            dispatch(setAuthorized(true));
            dispatch(setUser({
                id: decoded.sub,
                name: decoded.name,
            }));
            history.push('/');
        } else {
            dispatch(error(getNotificationOptions(res.message)));
        }
    } catch (err) {
        dispatch(error(getNotificationOptions(err.message)));
    }
};

export const createUser = values => handleAuthentication('register', values);
export const logUserIn = values => handleAuthentication('login', values);

export const logUserOut = () => (dispatch) => {
    try {
        Auth.deauthenticateUser();
        dispatch(setAuthorized(false));
    } catch (err) {
        dispatch(error(getNotificationOptions(err.message)));
    }
};

export const facebookLogin = () => (dispatch) => {
    try {
        FB.login((result) => {
            fetch(`${process.env.API_HOST}/auth/facebook/`, {
                method: 'POST',
                headers: new Headers({
                    'content-type': 'application/json',
                    Authorization: `Bearer ${result.authResponse.accessToken}`,
                }),
                mode: 'cors',
            })
                .then(res => res.json())
                .then((res) => {
                    if (res.token) {
                        const decoded = jwtDecode(res.token);

                        Auth.authenticateUser(res.token);
                        dispatch(setAuthorized(true));
                        dispatch(setUser({
                            id: decoded.sub,
                            name: decoded.name,
                            avatar: decoded.avatar,
                        }));
                        history.push('/');
                    } else {
                        dispatch(error(getNotificationOptions(res.message)));
                    }
                });
        });
    } catch (err) {
        dispatch(error(getNotificationOptions(err.message)));
    }
};
<commit_msg>Actually log out the FB session as well<commit_after>import { error } from 'react-notification-system-redux';
import jwtDecode from 'jwt-decode';

import history from '../history';
import getNotificationOptions from '../utils/notifications';
import Auth from '../utils/authentication';

const SET_USER = 'SET_USER';
const SET_AUTHORIZED = 'SET_AUTHORIZED';

const initialState = {
    user: {
        id: null,
        name: 'Unknown',
        avatar: null,
    },
    isAuthorized: false,
};

export default function userReducer(state = initialState, action) {
    switch (action.type) {
        case SET_USER:
            return {
                ...state,
                user: action.user,
            };
        case SET_AUTHORIZED:
            return {
                ...state,
                isAuthorized: action.status,
            };
        default:
            return state;
    }
}

export const setUser = user => ({ type: SET_USER, user });
export const setAuthorized = status => ({ type: SET_AUTHORIZED, status });

const handleAuthentication = (path, values) => async (dispatch) => {
    try {
        let res = await fetch(`${process.env.API_HOST}/auth/${path}`, {
            method: 'POST',
            headers: new Headers({ 'content-type': 'application/json' }),
            mode: 'cors',
            body: JSON.stringify(values),
        });
        res = await res.json();

        if (res.token) {
            const decoded = jwtDecode(res.token);

            // set token to localstorage
            Auth.authenticateUser(res.token);

            dispatch(setAuthorized(true));
            dispatch(setUser({
                id: decoded.sub,
                name: decoded.name,
            }));
            history.push('/');
        } else {
            dispatch(error(getNotificationOptions(res.message)));
        }
    } catch (err) {
        dispatch(error(getNotificationOptions(err.message)));
    }
};

export const createUser = values => handleAuthentication('register', values);
export const logUserIn = values => handleAuthentication('login', values);

export const logUserOut = () => (dispatch) => {
    try {
        FB.getLoginStatus((res) => {
            if (res.status === 'connected') {
                FB.logout();
            }
        });
        Auth.deauthenticateUser();
        dispatch(setAuthorized(false));
    } catch (err) {
        dispatch(error(getNotificationOptions(err.message)));
    }
};

export const facebookLogin = () => (dispatch) => {
    try {
        FB.login((result) => {
            fetch(`${process.env.API_HOST}/auth/facebook/`, {
                method: 'POST',
                headers: new Headers({
                    'content-type': 'application/json',
                    Authorization: `Bearer ${result.authResponse.accessToken}`,
                }),
                mode: 'cors',
            })
                .then(res => res.json())
                .then((res) => {
                    if (res.token) {
                        const decoded = jwtDecode(res.token);

                        Auth.authenticateUser(res.token);
                        dispatch(setAuthorized(true));
                        dispatch(setUser({
                            id: decoded.sub,
                            name: decoded.name,
                            avatar: decoded.avatar,
                        }));
                        history.push('/');
                    } else {
                        dispatch(error(getNotificationOptions(res.message)));
                    }
                });
        });
    } catch (err) {
        dispatch(error(getNotificationOptions(err.message)));
    }
};
<|endoftext|>


<commit_before>// Global Parameters
var global_enterpriseEndpointUri = "http://localhost/api/enterprise";
var global_tokenEndpointUri = "https://hack.softheon.io/api/identity/core/connect/token";
var global_clientId = "hack001";
var global_clientSecret = "hack001";
var global_scope = "enterpriseapi";
var global_drawer = 1;
var global_token;

/**
 * On Document Ready
 */
$(function () {
    requestAccessToken(global_enterpriseEndpointUri,
        global_tokenEndpointUri,
        global_clientId,
        global_clientSecret,
        global_scope,
        function (token) {
            global_token = token;
            $("button").prop("disabled", false);
        });
});

/**
 * Handles Click event for Insert Template button
 */
function onclick_InsertTemplate(params) {
    var type = $("#txtInsertTemplateType").val();
    insertTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            var root = $("#resInsertTemplate");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Get Template button
 */
function onclick_GetTemplate(params) {
    var type = $("#txtGetTemplateType").val();
    getTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            var root = $("#resGetTemplate");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Update Template button
 */
function onclick_UpdateTemplate(params) {
    var type = $("#txtUpdateTemplateType").val();
    var name = $("#txtUpdateTemplateName").val();

    // Get template first
    getTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            if (status === 200) {
                data.Name = name;
                updateTemplate(global_enterpriseEndpointUri, global_token, data,
                    function (status, data) {
                        var root = $("#resUpdateTemplate");
                        setStatus(root, status.toString());
                        displayResult(root, data);
                    });
            }
        });
}

/**
 * Handles Click event for Delete Template button
 */
function onclick_DeleteTemplate(params) {
    var type = $("#txtDeleteTemplateType").val();
    deleteTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            var root = $("#resDeleteTemplate");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Insert Entity button
 */
function onclick_InsertEntity(params) {
    var type = $("#txtInsertEntityType").val();
    insertEntity(global_enterpriseEndpointUri, global_token, global_drawer, type,
        function (status, data) {
            var root = $("#resInsertEntity");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Get Entity button
 */
function onclick_GetEntity(params) {
    var id = $("#txtGetEntityID").val();
    getEntity(global_enterpriseEndpointUri, global_token, global_drawer, id,
        function (status, data) {
            var root = $("#resGetEntity");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Update Entity button
 */
function onclick_UpdateEntity(params) {
    var id = $("#txtUpdateEntityID").val();
    var phrase = $("#txtUpdateEntityPhrase").val();

    // Get Entity first
    getEntity(global_enterpriseEndpointUri, global_token, global_drawer, id,
        function (status, data) {
            if (status === 200) {
                data.Profiles[0].Strings[0] = phrase;
                updateEntity(global_enterpriseEndpointUri, global_token, global_drawer, id, data,
                    function (status, data) {
                        var root = $("#resUpdateEntity");
                        setStatus(root, status.toString());
                        displayResult(root, data);
                    });
            }
        });
}

/**
 * Handles Click event for Delete Entity button
 */
function onclick_DeleteEntity(params) {
    var id = $("#txtDeleteEntityID").val();
    deleteEntity(global_enterpriseEndpointUri, global_token, global_drawer, id,
        function (status, data) {
            var root = $("#resDeleteEntity");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Sets the status label
 */
function setStatus(root, status) {
    var element = root.find(".label");
    element.html(status);

    element.removeClass("label-success");
    element.removeClass("label-danger");
    element.removeClass("label-warning");

    if (status.substring(0, 1) == "2") {
        element.addClass("label-success");
    }
    else if (status.substring(0, 1) == "5") {
        element.addClass("label-danger");
    }
    else {
        element.addClass("label-warning");
    }
}

/**
 * Displays the result object
 */
function displayResult(root, data) {
    if (data) {
        root.find(".response").html(JSON.stringify(data));
    }
    else {
        root.find(".response").html("No Content");
    }

    root.collapse('show');
}<commit_msg>Updated URL to use Hack-thon endpoint<commit_after>// Global Parameters
var global_enterpriseEndpointUri = "https://hack.softheon.io/api/enterprise";
var global_tokenEndpointUri = "https://hack.softheon.io/api/identity/core/connect/token";
var global_clientId = "hack001";
var global_clientSecret = "hack001";
var global_scope = "enterpriseapi";
var global_drawer = 1;
var global_token;

/**
 * On Document Ready
 */
$(function () {
    requestAccessToken(global_enterpriseEndpointUri,
        global_tokenEndpointUri,
        global_clientId,
        global_clientSecret,
        global_scope,
        function (token) {
            global_token = token;
            $("button").prop("disabled", false);
        });
});

/**
 * Handles Click event for Insert Template button
 */
function onclick_InsertTemplate(params) {
    var type = $("#txtInsertTemplateType").val();
    insertTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            var root = $("#resInsertTemplate");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Get Template button
 */
function onclick_GetTemplate(params) {
    var type = $("#txtGetTemplateType").val();
    getTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            var root = $("#resGetTemplate");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Update Template button
 */
function onclick_UpdateTemplate(params) {
    var type = $("#txtUpdateTemplateType").val();
    var name = $("#txtUpdateTemplateName").val();

    // Get template first
    getTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            if (status === 200) {
                data.Name = name;
                updateTemplate(global_enterpriseEndpointUri, global_token, data,
                    function (status, data) {
                        var root = $("#resUpdateTemplate");
                        setStatus(root, status.toString());
                        displayResult(root, data);
                    });
            }
        });
}

/**
 * Handles Click event for Delete Template button
 */
function onclick_DeleteTemplate(params) {
    var type = $("#txtDeleteTemplateType").val();
    deleteTemplate(global_enterpriseEndpointUri, global_token, type,
        function (status, data) {
            var root = $("#resDeleteTemplate");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Insert Entity button
 */
function onclick_InsertEntity(params) {
    var type = $("#txtInsertEntityType").val();
    insertEntity(global_enterpriseEndpointUri, global_token, global_drawer, type,
        function (status, data) {
            var root = $("#resInsertEntity");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Get Entity button
 */
function onclick_GetEntity(params) {
    var id = $("#txtGetEntityID").val();
    getEntity(global_enterpriseEndpointUri, global_token, global_drawer, id,
        function (status, data) {
            var root = $("#resGetEntity");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Handles Click event for Update Entity button
 */
function onclick_UpdateEntity(params) {
    var id = $("#txtUpdateEntityID").val();
    var phrase = $("#txtUpdateEntityPhrase").val();

    // Get Entity first
    getEntity(global_enterpriseEndpointUri, global_token, global_drawer, id,
        function (status, data) {
            if (status === 200) {
                data.Profiles[0].Strings[0] = phrase;
                updateEntity(global_enterpriseEndpointUri, global_token, global_drawer, id, data,
                    function (status, data) {
                        var root = $("#resUpdateEntity");
                        setStatus(root, status.toString());
                        displayResult(root, data);
                    });
            }
        });
}

/**
 * Handles Click event for Delete Entity button
 */
function onclick_DeleteEntity(params) {
    var id = $("#txtDeleteEntityID").val();
    deleteEntity(global_enterpriseEndpointUri, global_token, global_drawer, id,
        function (status, data) {
            var root = $("#resDeleteEntity");
            setStatus(root, status.toString());
            displayResult(root, data);
        });
}

/**
 * Sets the status label
 */
function setStatus(root, status) {
    var element = root.find(".label");
    element.html(status);

    element.removeClass("label-success");
    element.removeClass("label-danger");
    element.removeClass("label-warning");

    if (status.substring(0, 1) == "2") {
        element.addClass("label-success");
    }
    else if (status.substring(0, 1) == "5") {
        element.addClass("label-danger");
    }
    else {
        element.addClass("label-warning");
    }
}

/**
 * Displays the result object
 */
function displayResult(root, data) {
    if (data) {
        root.find(".response").html(JSON.stringify(data));
    }
    else {
        root.find(".response").html("No Content");
    }

    root.collapse('show');
}<|endoftext|>


<commit_before>/**
 * Author: krasu
 * Date: 10/3/13
 * Time: 5:40 PM
 */
var cfg = require('../../config'),
	async = require('async'),
	_ = require('lodash'),
	ejs = require('ejs'),
	fs = require('fs'),
	templates = {}

module.exports.fillTemplates = function (dir, callback) {
	if (!_.isEmpty(templates)) return
	console.log('Reading email templates from', dir)

	fs.readdir(dir, function (err, files) {
		if (err) return callback(err);

		async.each(files, function (file, cb) {
			fs.readFile(dir + file, 'utf-8', function (err, data) {
				templates[file.replace('.ejs', '')] = data
				cb.apply(this, arguments)
			});
		}, callback);
	});
}

module.exports.send = function (templateName, subject, to, data, callback) {
	var template = templates[templateName]
	if (!template) return callback('No such template')

	cfg.emails.transport.sendMail({
		from: cfg.emails.from,
		subject: subject,
		to: to,
		html: ejs.render(template, _.merge(data, {siteUrl: cfg.fullUrl(), _: _}))
	}, function (error) {
		error && console.error(error)
		callback(error ? 'Failed to send email' : null)
	})
}<commit_msg>added lodash to email templates<commit_after>/**
 * Author: krasu
 * Date: 10/3/13
 * Time: 5:40 PM
 */
var cfg = require('../../config'),
	async = require('async'),
	_ = require('lodash'),
	ejs = require('ejs'),
	fs = require('fs'),
	templates = {}

//TODO: add mail queue
module.exports.fillTemplates = function (dir, callback) {
	if (!_.isEmpty(templates)) return
	console.log('Reading email templates from', dir)

	fs.readdir(dir, function (err, files) {
		if (err) return callback(err);

		async.each(files, function (file, cb) {
			fs.readFile(dir + file, 'utf-8', function (err, data) {
				templates[file.replace('.ejs', '')] = data
				cb.apply(this, arguments)
			});
		}, callback);
	});
}

module.exports.send = function (templateName, subject, to, data, callback) {
	var template = templates[templateName]
	if (!template) return callback('No such template')

	cfg.emails.transport.sendMail({
		from: cfg.emails.from,
		subject: subject,
		to: to,
		html: ejs.render(template, _.merge(data, {siteUrl: cfg.fullUrl(), _: _}))
	}, function (error) {
		error && console.error(error)
		callback(error ? 'Failed to send email' : null)
	})
}<|endoftext|>


<commit_before>import Extension from '../extensions/extension';

let EntryPaint;
Entry.Painter = class Painter {
    constructor(view) {
        this.view = view;
        this.cache = [];

        this.file = {
            id: Entry.generateHash(),
            name: '새그림',
            modified: false,
            mode: 'new', // new or edit
        };

        this.dropper = Extension.getExtension('Dropper');
        this.isShow = false;
        this.clipboard = null;
        this._keyboardEvents = [];
        Entry.addEventListener('pictureImport', this.addPicture.bind(this));
        Entry.addEventListener('run', this.detachKeyboardEvents.bind(this));
        Entry.addEventListener('stop', this.attachKeyboardEvents.bind(this));
        this.importEntryPaint();
    }

    async importEntryPaint() {
        EntryPaint = window.EntryPaint.default;
        // EntryPaint = (await import('entry-paint')).default;
        if (this.requestShow) {
            this.initialize();
        }
    }

    get graphicsMode() {
        return this.entryPaint.graphicsMode;
    }

    initialize() {
        if (this.entryPaint || !EntryPaint) {
            this.requestShow = true;
            return;
        }

        this.isShow = true;

        this.entryPaint = EntryPaint.create({ parent: this.view, mode: 'entry' });
        this.entryPaint.setDropper && this.entryPaint.setDropper(this.dropper);

        this.isImport = true;
        this.entryPaint.on('SNAPSHOT_SAVED', (e) => {
            if (!this.isImport && Entry.stage.selectedObject) {
                Entry.do('editPicture', e, this.entryPaint);
                this.file.modified = true;
            }
            this.isImport = false;
        });
        this.entryPaint.on('NEW_PICTURE', this.newPicture.bind(this));
        this.entryPaint.on('IMPORT_IMAGE', () => {
            Entry.dispatchEvent('openPictureImport');
        });
        this.entryPaint.on('SAVE_PICTURE', () => {
            this.fileSave(false);
        });
        this.entryPaint.on('SAVE_NEW_PICTURE', () => {
            this.file.mode = 'new';
            this.fileSave(false);
        });
        this.entryPaint.on('FULL_SCREEN_ON', () => {
            this.toggleFullscreen(true);
        });
        this.entryPaint.on('FULL_SCREEN_OFF', () => {
            this.toggleFullscreen(false);
        });

        Entry.addEventListener('pictureSelected', this.changePicture.bind(this));
    }

    show() {
        if (!this.isShow) {
            this.initialize();
        }
        this.realign && Entry.windowResized.detach(this.realign);
        this.realign = Entry.windowResized.attach(this.view, this.entryPaint.realign);
    }

    hide() {
        this.entryPaint && Entry.windowResized.detach(this.realign);
    }

    newPicture() {
        const newPicture = {
            dimension: {
                height: 1,
                width: 1,
            },
            fileurl: `${Entry.mediaFilePath}_1x1.png`,
            name: Lang.Painter.new_picture,
            imageType: this._getImageType(),
        };

        newPicture.id = Entry.generateHash();
        if (this.file && this.file.objectId) {
            newPicture.objectId = this.file.objectId;
        }
        Entry.playground.addPicture(newPicture, true);
    }

    changePicture(picture = {}) {
        if (this.file && this.file.id === picture.id) {
            if (!this.file.isUpdate) {
                Entry.stage.updateObject();
                this.file.isUpdate = true;
            }
            return;
        } else if (!this.file.modified) {
            this.afterModified(picture);
        } else {
            if (this.isConfirm) {
                return;
            }

            this.isConfirm = true;
            let wasRun = false;
            if (Entry.engine.state === 'run') {
                Entry.engine.toggleStop();
                wasRun = true;
            }

            entrylms.confirm(Lang.Menus.save_modified_shape).then((result) => {
                this.isConfirm = false;
                result ? this.fileSave(true) : (this.file.modified = false);
                wasRun ? Entry.playground.injectPicture() : this.afterModified(picture);
            });
        }
        Entry.stage.updateObject();
        this.file.isUpdate = true;
    }

    afterModified(picture) {
        const file = this.file;
        file.modified = false;
        this.isImport = true;
        this.entryPaint.reset();

        if (picture.id) {
            file.id = picture.id || Entry.generateHash();
            file.name = picture.name;
            file.mode = 'edit';
            file.objectId = picture.objectId;

            this.addPicture(picture, true);
        } else {
            file.id = Entry.generateHash();
        }

        Entry.stateManager.removeAllPictureCommand();
    }

    getImageSrc(picture) {
        const { fileurl } = picture || {};
        if (fileurl) {
            return fileurl;
        }

        const { imageType = 'png', filename } = picture || {};
        return `${Entry.defaultPath}/uploads/${filename.substring(0, 2)}/${filename.substring(
            2,
            4
        )}/image/${filename}.${imageType}`;
    }

    addPicture(picture, isChangeShape) {
        const { imageType = 'png' } = picture || {};
        const imageSrc = this.getImageSrc(picture);

        isChangeShape && (this.isImport = true);

        switch (imageType) {
            case 'png':
                this.entryPaint.addBitmap(imageSrc, {
                    isChangedLayer: this.isImport,
                    graphicsMode: this.isImport ? this.graphicsMode.BITMAP : '',
                });
                break;
            case 'svg':
                this.entryPaint.addSVG(imageSrc, {
                    graphicsMode: this.isImport ? this.graphicsMode.VECTOR : '',
                });
                break;
        }
    }

    _getImageType() {
        if (this.entryPaint.mode === this.graphicsMode.VECTOR) {
            return 'svg';
        } else {
            return 'png';
        }
    }

    fileSave(taskParam) {
        if (!Entry.stage.selectedObject) {
            return;
        }
        const dataURL = this.entryPaint.getDataURL();
        if (this.entryPaint.mode === this.graphicsMode.VECTOR) {
            this.file.svg = this.entryPaint.exportSVG();
        } else {
            delete this.file.svg;
        }
        this.file.ext = this._getImageType();
        const file = JSON.parse(JSON.stringify(this.file));
        Entry.dispatchEvent('saveCanvasImage', {
            file,
            image: dataURL,
            task: taskParam,
        });
        this.file.isUpdate = false;
        this.file.modified = false;
    }

    attachKeyboardEvents() {
        this.detachKeyboardEvents();

        const events = this._keyboardEvents;

        let evt = Entry.keyPressed;
        evt && events.push(evt.attach(this, this._keyboardPressControl));

        evt = Entry.keyUpped;
        evt && events.push(evt.attach(this, this._keyboardUpControl));
    }

    detachKeyboardEvents() {
        const events = this._keyboardEvents;
        if (!events || !events.length) {
            return;
        }

        while (events.length) {
            const evt = events.pop();
            evt.destroy && evt.destroy();
        }
    }

    _keyboardPressControl(e) {}

    toggleFullscreen(isFullscreen) {
        const { pictureView_ } = Entry.playground;
        const $view = $(this.view);
        if ((isFullscreen !== true && $view.hasClass('fullscreen')) || isFullscreen === false) {
            pictureView_.appendChild(this.view);
            $view.removeClass('fullscreen');
            if (this.fullscreenButton) {
                this.fullscreenButton.setAttribute('title', Lang.Painter.fullscreen);
                this.fullscreenButton.setAttribute('alt', Lang.Painter.fullscreen);
            }
        } else {
            document.body.appendChild(this.view);
            $view.addClass('fullscreen');
            if (this.fullscreenButton) {
                this.fullscreenButton.setAttribute('title', Lang.Painter.exit_fullscreen);
                this.fullscreenButton.setAttribute('alt', Lang.Painter.exit_fullscreen);
            }
        }
        this.entryPaint && this.entryPaint.realign();
    }

    clear() {
        this.toggleFullscreen(false);
    }

    undo() {
        this.entryPaint.undo();
    }

    redo() {
        this.entryPaint.redo();
    }
};
<commit_msg>Remove duplicate behavior<commit_after>import Extension from '../extensions/extension';

let EntryPaint;
Entry.Painter = class Painter {
    constructor(view) {
        this.view = view;
        this.cache = [];

        this.file = {
            id: Entry.generateHash(),
            name: '새그림',
            modified: false,
            mode: 'new', // new or edit
        };

        this.dropper = Extension.getExtension('Dropper');
        this.isShow = false;
        this.clipboard = null;
        this._keyboardEvents = [];
        Entry.addEventListener('pictureImport', this.addPicture.bind(this));
        Entry.addEventListener('run', this.detachKeyboardEvents.bind(this));
        Entry.addEventListener('stop', this.attachKeyboardEvents.bind(this));
        this.importEntryPaint();
    }

    async importEntryPaint() {
        EntryPaint = window.EntryPaint.default;
        // EntryPaint = (await import('entry-paint')).default;
        if (this.requestShow) {
            this.initialize();
        }
    }

    get graphicsMode() {
        return this.entryPaint.graphicsMode;
    }

    initialize() {
        if (this.entryPaint || !EntryPaint) {
            this.requestShow = true;
            return;
        }

        this.isShow = true;

        this.entryPaint = EntryPaint.create({ parent: this.view, mode: 'entry' });
        this.entryPaint.setDropper && this.entryPaint.setDropper(this.dropper);

        this.isImport = true;
        this.entryPaint.on('SNAPSHOT_SAVED', (e) => {
            if (!this.isImport && Entry.stage.selectedObject) {
                Entry.do('editPicture', e, this.entryPaint);
                this.file.modified = true;
            }
            this.isImport = false;
        });
        this.entryPaint.on('NEW_PICTURE', this.newPicture.bind(this));
        this.entryPaint.on('IMPORT_IMAGE', () => {
            Entry.dispatchEvent('openPictureImport');
        });
        this.entryPaint.on('SAVE_PICTURE', () => {
            this.fileSave(false);
        });
        this.entryPaint.on('SAVE_NEW_PICTURE', () => {
            this.file.mode = 'new';
            this.fileSave(false);
        });
        this.entryPaint.on('FULL_SCREEN_ON', () => {
            this.toggleFullscreen(true);
        });
        this.entryPaint.on('FULL_SCREEN_OFF', () => {
            this.toggleFullscreen(false);
        });

        Entry.addEventListener('pictureSelected', this.changePicture.bind(this));
    }

    show() {
        if (!this.isShow) {
            this.initialize();
        }
        this.realign && Entry.windowResized.detach(this.realign);
        this.realign = Entry.windowResized.attach(this.view, this.entryPaint.realign);
    }

    hide() {
        this.entryPaint && Entry.windowResized.detach(this.realign);
    }

    newPicture() {
        const newPicture = {
            dimension: {
                height: 1,
                width: 1,
            },
            fileurl: `${Entry.mediaFilePath}_1x1.png`,
            name: Lang.Painter.new_picture,
            imageType: this._getImageType(),
        };

        newPicture.id = Entry.generateHash();
        if (this.file && this.file.objectId) {
            newPicture.objectId = this.file.objectId;
        }
        Entry.playground.addPicture(newPicture, true);
    }

    changePicture(picture = {}) {
        if (this.file && this.file.id === picture.id) {
            if (!this.file.isUpdate) {
                Entry.stage.updateObject();
                this.file.isUpdate = true;
            }
            return;
        } else if (!this.file.modified) {
            this.afterModified(picture);
        } else {
            if (this.isConfirm) {
                return;
            }

            this.isConfirm = true;
            let wasRun = false;
            if (Entry.engine.state === 'run') {
                Entry.engine.toggleStop();
                wasRun = true;
            }

            entrylms.confirm(Lang.Menus.save_modified_shape).then((result) => {
                this.isConfirm = false;
                result ? this.fileSave(true) : (this.file.modified = false);
                wasRun ? Entry.playground.injectPicture() : this.afterModified(picture);
            });
        }
        Entry.stage.updateObject();
        this.file.isUpdate = true;
    }

    afterModified(picture) {
        const file = this.file;
        file.modified = false;
        this.isImport = true;

        if (picture.id) {
            file.id = picture.id || Entry.generateHash();
            file.name = picture.name;
            file.mode = 'edit';
            file.objectId = picture.objectId;

            this.addPicture(picture, true);
        } else {
            file.id = Entry.generateHash();
        }

        Entry.stateManager.removeAllPictureCommand();
    }

    getImageSrc(picture) {
        const { fileurl } = picture || {};
        if (fileurl) {
            return fileurl;
        }

        const { imageType = 'png', filename } = picture || {};
        return `${Entry.defaultPath}/uploads/${filename.substring(0, 2)}/${filename.substring(
            2,
            4
        )}/image/${filename}.${imageType}`;
    }

    addPicture(picture, isChangeShape) {
        const { imageType = 'png' } = picture || {};
        const imageSrc = this.getImageSrc(picture);

        isChangeShape && (this.isImport = true);

        switch (imageType) {
            case 'png':
                this.entryPaint.addBitmap(imageSrc, {
                    graphicsMode: this.isImport ? this.graphicsMode.BITMAP : '',
                });
                break;
            case 'svg':
                this.entryPaint.addSVG(imageSrc, {
                    graphicsMode: this.isImport ? this.graphicsMode.VECTOR : '',
                });
                break;
        }
    }

    _getImageType() {
        if (this.entryPaint.mode === this.graphicsMode.VECTOR) {
            return 'svg';
        } else {
            return 'png';
        }
    }

    fileSave(taskParam) {
        if (!Entry.stage.selectedObject) {
            return;
        }
        const dataURL = this.entryPaint.getDataURL();
        if (this.entryPaint.mode === this.graphicsMode.VECTOR) {
            this.file.svg = this.entryPaint.exportSVG();
        } else {
            delete this.file.svg;
        }
        this.file.ext = this._getImageType();
        const file = JSON.parse(JSON.stringify(this.file));
        Entry.dispatchEvent('saveCanvasImage', {
            file,
            image: dataURL,
            task: taskParam,
        });
        this.file.isUpdate = false;
        this.file.modified = false;
    }

    attachKeyboardEvents() {
        this.detachKeyboardEvents();

        const events = this._keyboardEvents;

        let evt = Entry.keyPressed;
        evt && events.push(evt.attach(this, this._keyboardPressControl));

        evt = Entry.keyUpped;
        evt && events.push(evt.attach(this, this._keyboardUpControl));
    }

    detachKeyboardEvents() {
        const events = this._keyboardEvents;
        if (!events || !events.length) {
            return;
        }

        while (events.length) {
            const evt = events.pop();
            evt.destroy && evt.destroy();
        }
    }

    _keyboardPressControl(e) {}

    toggleFullscreen(isFullscreen) {
        const { pictureView_ } = Entry.playground;
        const $view = $(this.view);
        if ((isFullscreen !== true && $view.hasClass('fullscreen')) || isFullscreen === false) {
            pictureView_.appendChild(this.view);
            $view.removeClass('fullscreen');
            if (this.fullscreenButton) {
                this.fullscreenButton.setAttribute('title', Lang.Painter.fullscreen);
                this.fullscreenButton.setAttribute('alt', Lang.Painter.fullscreen);
            }
        } else {
            document.body.appendChild(this.view);
            $view.addClass('fullscreen');
            if (this.fullscreenButton) {
                this.fullscreenButton.setAttribute('title', Lang.Painter.exit_fullscreen);
                this.fullscreenButton.setAttribute('alt', Lang.Painter.exit_fullscreen);
            }
        }
        this.entryPaint && this.entryPaint.realign();
    }

    clear() {
        this.toggleFullscreen(false);
    }

    undo() {
        this.entryPaint.undo();
    }

    redo() {
        this.entryPaint.redo();
    }
};
<|endoftext|>


<commit_before>const {CFRPageActions} =
  ChromeUtils.import("resource://activity-stream/lib/CFRPageActions.jsm", {});

function trigger_cfr_panel(browser, trigger, cb) {
  return CFRPageActions.addRecommendation(
    browser,
    trigger,
    {
      content: {
        notification_text: "Mochitest",
        heading_text: "Mochitest",
        info_icon: {
          label: {attributes: {tooltiptext: "Why am I seeing this"}},
          sumo_path: "extensionrecommendations",
        },
        addon: {
          title: "Addon name",
          icon: "foo",
          author: "Author name",
          amo_url: "https://example.com",
        },
        text: "Mochitest",
        buttons: {
          primary: {
            label: {
              value: "OK",
              attributes: {accesskey: "O"},
            },
          },
          secondary: {
            label: {
              value: "Cancel",
              attributes: {accesskey: "C"},
            },
          },
        },
      },
    },
    cb
  );
}

add_task(async function test_cfr_notification_show() {
  // addRecommendation checks that scheme starts with http and host matches
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://example.com", false);

  const response = await trigger_cfr_panel(tab.linkedBrowser, "example.com", () => {});
  Assert.ok(response, "Should return true if addRecommendation checks were successful");

  const showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
  // Open the panel
  document.getElementById("contextual-feature-recommendation").click();
  await showPanel;

  Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
    "Panel should be visible");

  // Check there is a primary button and click it. It will trigger the callback.
  Assert.ok(document.getElementById("contextual-feature-recommendation-notification").button);
  let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
  document.getElementById("contextual-feature-recommendation-notification").button.click();
  await hidePanel;

  // Clicking the primary action also removes the notification
  Assert.equal(PopupNotifications._currentNotifications.length, 0,
    "Should have removed the notification");

  BrowserTestUtils.removeTab(tab);
});
<commit_msg>(mochitests): Fix CFR mochitest intermittent (#4433)<commit_after>const {CFRPageActions} =
  ChromeUtils.import("resource://activity-stream/lib/CFRPageActions.jsm", {});

function trigger_cfr_panel(browser, trigger, cb) {
  return CFRPageActions.addRecommendation(
    browser,
    trigger,
    {
      content: {
        notification_text: "Mochitest",
        heading_text: "Mochitest",
        info_icon: {
          label: {attributes: {tooltiptext: "Why am I seeing this"}},
          sumo_path: "extensionrecommendations",
        },
        addon: {
          title: "Addon name",
          icon: "foo",
          author: "Author name",
          amo_url: "https://example.com",
        },
        text: "Mochitest",
        buttons: {
          primary: {
            label: {
              value: "OK",
              attributes: {accesskey: "O"},
            },
          },
          secondary: {
            label: {
              value: "Cancel",
              attributes: {accesskey: "C"},
            },
          },
        },
      },
    },
    cb
  );
}

add_task(async function test_cfr_notification_show() {
  // addRecommendation checks that scheme starts with http and host matches
  let browser = gBrowser.selectedBrowser;
  browser.loadURI("http://example.com");
  await BrowserTestUtils.browserLoaded(browser, false, "http://example.com/");

  const response = await trigger_cfr_panel(browser, "example.com", () => {});
  Assert.ok(response, "Should return true if addRecommendation checks were successful");

  const showPanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
  // Open the panel
  document.getElementById("contextual-feature-recommendation").click();
  await showPanel;

  Assert.ok(document.getElementById("contextual-feature-recommendation-notification").hidden === false,
    "Panel should be visible");

  // Check there is a primary button and click it. It will trigger the callback.
  Assert.ok(document.getElementById("contextual-feature-recommendation-notification").button);
  let hidePanel = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
  document.getElementById("contextual-feature-recommendation-notification").button.click();
  await hidePanel;

  // Clicking the primary action also removes the notification
  Assert.equal(PopupNotifications._currentNotifications.length, 0,
    "Should have removed the notification");
});
<|endoftext|>


<commit_before>require.config({
    paths: {
        jquery: 'libs/jquery-min',
        underscore: 'libs/underscore-min',
        backbone: 'libs/backbone-min',
        mustache: 'libs/mustache',
    },
    shim: {
        jquery: {
            exports: '$'
        },
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        }
    },

    // add dummy params to break caching
    urlArgs: '__nocache__=' +  (new Date()).getTime()
});

require([
    'jquery',
    'underscore',
    'backbone',
    'mustache',
    'text!/static/templates/search_bar.html.mustache',
    'text!/static/templates/ac_suggestion.html.mustache'
],
function ($, _, Backbone, Mustache, tmplSearchBar, tmplAcSuggestion) {

// the search bar
var SearchBar = Backbone.Model.extend({
    defaults: {
        query: '',
        acSuggestionList: null,

        // minimum amount of time between AJAX calls
        minUpdateIntervalMs: 200,
        timeoutId: null // id for the last update timeout
    },

    initialize: function () {
        this.on('change:query', this.updateSuggestions, this);
    },

    updateSuggestions: function () {
        // clear any existing update timeout
        if (this.get('timeoutId') !== null) {
            clearTimeout(this.get('timeoutId'));
        }

        // set a timeout to update once input is done coming for a bit
        var timeoutId = setTimeout(_.bind(function () {
            // update suggestion list and clear the timeout id
            this.get('acSuggestionList').updateSuggestions(this.get('query'));
            this.set({'timeoutId': null});

        }, this), this.get('minUpdateIntervalMs'));

        // store the timeout id for the next update call
        this.set({'timeoutId': timeoutId});
    }
});

var SearchBarView = Backbone.View.extend({
    template: Mustache.compile(tmplSearchBar),

    events: {
        'keyup input': 'updateQuery',
        'keydown input': 'updateQuery'
    },

    defaults: {
        model: null
    },

    initialize: function () {
        // create the element and add it to the document
        this.setElement($(this.template({placeholder: 'search'})));
        this.$el.appendTo($('body'));

        // cache a ref to the input and focus it
        this.$input = this.$el.find('input');
        this.$input.focus();

        // update the input if the query changes
        this.model.on('change:query', this.updateInput, this);
    },

    updateQuery: function () {
        this.model.set({query: this.$input.val()});
    },

    updateInput: function () {
        this.$input.val(this.model.get('query'));
    }
});

// a single suggestion below the search bar
var AutocompleteSuggestion = Backbone.Model.extend({
    defaults: {
        provider: null,
        suggestion: ''
    }
});

// the suggestions collection below the search bar
var AutocompleteSuggestionList = Backbone.Collection.extend({
    model: AutocompleteSuggestion,
    url: '/search/autocomplete',

    updateSuggestions: function (query) {
        var xhr = $.getJSON(this.url, {'query': query});

        // update the collection on reset
        xhr.success(_.bind(function (data) {
            this.reset(data.results);
        }, this));
    }
});

var AutocompleteSuggestionListView = Backbone.View.extend({
    template: Mustache.compile(tmplAcSuggestion),

    events: {
        'click li': 'clickSuggestion'
    },

    defaults: {
        collection: null,
        model: null
    },

    initialize: function (options) {
        this.collection.on('reset', this.render, this);

        // store any passed-in options
        this.options = options || {};

        // set default options
        if (!this.options.maxSuggestionsRendered) {
            this.options.maxSuggestionsRendered = 15;
        }
    },

    render: function () {
        // get the suggestion list from the collection
        var suggestions = this.collection.toJSON();

        // clear out the old suggestions
        this.$el.children().remove();

        // add all the new suggestions
        var renderedCount = 0;
        _.each(suggestions, function (suggestion) {
            // stop rendering once the cutoff has been reached
            if (renderedCount++ >= this.options.maxSuggestionsRendered) {
                return false;
            }

            this.$el.append(this.template(suggestion));
        }, this);

        return this;
    },

    clickSuggestion: function (e) {
        // set the query to the clicked value, then reset the suggestions
        this.model.set({query: $(e.target).text()});
        this.collection.reset();
    }
});

//
// ENTRY POINT
//

$(function () {
    var searchBar = new SearchBar();
    var searchBarView = new SearchBarView({
        model: searchBar
    });

    var acSuggestionList = new AutocompleteSuggestionList();
    var acSuggestionListView = new AutocompleteSuggestionListView({
        collection: acSuggestionList,
        model: searchBar,
        el: $('#search-bar ul')
    }, {maxSuggestionsRendered: 15});

    searchBar.set({acSuggestionList: acSuggestionList});
});

});
<commit_msg>Fix autocomplete running after suggestion click<commit_after>require.config({
    paths: {
        jquery: 'libs/jquery-min',
        underscore: 'libs/underscore-min',
        backbone: 'libs/backbone-min',
        mustache: 'libs/mustache',
    },
    shim: {
        jquery: {
            exports: '$'
        },
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        }
    },

    // add dummy params to break caching
    urlArgs: '__nocache__=' +  (new Date()).getTime()
});

require([
    'jquery',
    'underscore',
    'backbone',
    'mustache',
    'text!/static/templates/search_bar.html.mustache',
    'text!/static/templates/ac_suggestion.html.mustache'
],
function ($, _, Backbone, Mustache, tmplSearchBar, tmplAcSuggestion) {

// the search bar
var SearchBar = Backbone.Model.extend({
    defaults: {
        query: '',
        acSuggestionList: null,

        // minimum amount of time between AJAX calls
        minUpdateIntervalMs: 200,
        timeoutId: null // id for the last update timeout
    },

    initialize: function () {
        this.on('change:query', this.updateSuggestions, this);
    },

    updateSuggestions: function () {
        // clear any existing update timeout
        if (this.get('timeoutId') !== null) {
            clearTimeout(this.get('timeoutId'));
        }

        // set a timeout to update once input is done coming for a bit
        var timeoutId = setTimeout(_.bind(function () {
            // update suggestion list and clear the timeout id
            this.get('acSuggestionList').updateSuggestions(this.get('query'));
            this.set({'timeoutId': null});

        }, this), this.get('minUpdateIntervalMs'));

        // store the timeout id for the next update call
        this.set({'timeoutId': timeoutId});
    }
});

var SearchBarView = Backbone.View.extend({
    template: Mustache.compile(tmplSearchBar),

    events: {
        'keyup input': 'updateQuery',
        'keydown input': 'updateQuery'
    },

    defaults: {
        model: null
    },

    initialize: function () {
        // create the element and add it to the document
        this.setElement($(this.template({placeholder: 'search'})));
        this.$el.appendTo($('body'));

        // cache a ref to the input and focus it
        this.$input = this.$el.find('input');
        this.$input.focus();

        // update the input if the query changes
        this.model.on('change:query', this.updateInput, this);
    },

    updateQuery: function () {
        this.model.set({query: this.$input.val()});
    },

    updateInput: function () {
        this.$input.val(this.model.get('query'));
    }
});

// a single suggestion below the search bar
var AutocompleteSuggestion = Backbone.Model.extend({
    defaults: {
        provider: null,
        suggestion: ''
    }
});

// the suggestions collection below the search bar
var AutocompleteSuggestionList = Backbone.Collection.extend({
    model: AutocompleteSuggestion,
    url: '/search/autocomplete',

    updateSuggestions: function (query) {
        var xhr = $.getJSON(this.url, {'query': query});

        // update the collection on reset
        xhr.success(_.bind(function (data) {
            this.reset(data.results);
        }, this));
    }
});

var AutocompleteSuggestionListView = Backbone.View.extend({
    template: Mustache.compile(tmplAcSuggestion),

    events: {
        'click li': 'clickSuggestion'
    },

    defaults: {
        collection: null,
        model: null
    },

    initialize: function (options) {
        this.collection.on('reset', this.render, this);

        // store any passed-in options
        this.options = options || {};

        // set default options
        if (!this.options.maxSuggestionsRendered) {
            this.options.maxSuggestionsRendered = 15;
        }
    },

    render: function () {
        // get the suggestion list from the collection
        var suggestions = this.collection.toJSON();

        // clear out the old suggestions
        this.$el.children().remove();

        // add all the new suggestions
        var renderedCount = 0;
        _.each(suggestions, function (suggestion) {
            // stop rendering once the cutoff has been reached
            if (renderedCount++ >= this.options.maxSuggestionsRendered) {
                return false;
            }

            this.$el.append(this.template(suggestion));
        }, this);

        return this;
    },

    clickSuggestion: function (e) {
        // silently set the query to the clicked value, then reset suggestions
        this.model.set({query: $(e.target).text()}, {silent: true});
        this.collection.reset();
    }
});

//
// ENTRY POINT
//

$(function () {
    var searchBar = new SearchBar();
    var searchBarView = new SearchBarView({
        model: searchBar
    });

    var acSuggestionList = new AutocompleteSuggestionList();
    var acSuggestionListView = new AutocompleteSuggestionListView({
        collection: acSuggestionList,
        model: searchBar,
        el: $('#search-bar ul')
    }, {maxSuggestionsRendered: 15});

    searchBar.set({acSuggestionList: acSuggestionList});
});

});
<|endoftext|>