<commit_before>/*global requirejs*/
requirejs(['./paths'], function (paths) {

    requirejs.config(paths);

    requirejs(['fx-c-c/start', 'amplify'], function (ChartCreator) {

/*        amplify.subscribe('fx.component.chart.ready', function () {
            console.log('created!');
        });*/

        // filtering data
        /*
         $.getJSON("tests/resources/AFO_AfricaPITDataLang.json", function (model) {
         var creator = new ChartCreator();
         console.log(model);
         // create serie
         var data = [];
         for(var i in model.data) {
         if (model.data[i][0] === "10210" && (model.data[i][2] === "NIG" || model.data[i][2] === "ETH")) {
         data.push(model.data[i]);
         }
         }
         model.data = data;
         $("body").append(JSON.stringify(model));
         });
         */

        // $.getJSON("tests/resources/afo/AFO_AfricaPITDataLang_nig_eth.json", function (model) {
        //$.getJSON("tests/resources/AFO_AfricaPITDataLang.json", function (model) {
        $.getJSON("tests/resources/afo/AFO_ProductionCapacities.json", function (model) {

            var creator = new ChartCreator();

            creator.init({
                model: model,
                adapter: {
                    filters: {
                        xAxis: 'time',
                        yAxis: 'item',
                        value: 'value',
                        series: []
                    }
                },
                template: {},
                creator: {},
                onReady: renderChart1
            });

            var creator2 = new ChartCreator();

            creator2.init({
                model: model,
                adapter: {
                    lang: 'EN',
                    filters: {
                        xAxis: 'geo',
                        yAxis: 'item',
                        value: 'value',
                        series: []
                    }
                },
                template: {},
                creator: {},
                onReady: renderChart2,
            });

            function renderChart1() {

                creator.render(
                    {
                        container: "#chartTwo"
                    }
                );
            }

            function renderChart2(creator) {
                creator2.render(
                    {
                        container: "#chartOne",
                        creator: {
                            chartObj: {
                                chart:{
                                    type: "column"
                                }
                            }
                        }
                    }

                );

            }
        });

    });
});<commit_msg>update<commit_after>/*global requirejs*/
requirejs(['./paths'], function (paths) {

    requirejs.config(paths);

    requirejs(['fx-c-c/start', 'amplify'], function (ChartCreator) {

/*        amplify.subscribe('fx.component.chart.ready', function () {
            console.log('created!');
        });*/

        // filtering data
        /*
         $.getJSON("tests/resources/AFO_AfricaPITDataLang.json", function (model) {
         var creator = new ChartCreator();
         console.log(model);
         // create serie
         var data = [];
         for(var i in model.data) {
         if (model.data[i][0] === "10210" && (model.data[i][2] === "NIG" || model.data[i][2] === "ETH")) {
         data.push(model.data[i]);
         }
         }
         model.data = data;
         $("body").append(JSON.stringify(model));
         });
         */

        // $.getJSON("tests/resources/afo/AFO_AfricaPITDataLang_nig_eth.json", function (model) {
        //$.getJSON("tests/resources/AFO_AfricaPITDataLang.json", function (model) {
        $.getJSON("tests/resources/afo/AFO_ProductionCapacities.json", function (model) {

            var creator = new ChartCreator();

            creator.init({
                model: model,
                adapter: {
                    filters: {
                        xAxis: 'time',
                        yAxis: 'item',
                        value: 'value',
                        series: []
                    }
                },
                template: {},
                creator: {},
                onReady: renderChart1
            });

            var creator2 = new ChartCreator();

            creator2.init({
                model: model,
                adapter: {
                    lang: 'EN',
                    filters: {
                        xAxis: 'geo',
                        yAxis: 'item',
                        value: 'value',
                        series: []
                    }
                },
                template: {},
                creator: {},
                onReady: renderChart2,
            });

            function renderChart1() {

                creator.render(
                    {
                        container: "#chartTwo"
                    }
                );

            }

            function renderChart2(creator) {

                creator2.render(
                    {
                        container: "#chartOne",
                        creator: {
                            chartObj: {
                                chart:{
                                    type: "column"
                                }
                            }
                        }
                    }

                );

            }
        });

    });
});<|endoftext|>


<commit_before>var models = require('./models');

module.exports = function(bot) {
    this.sendStart = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'Welcome!\nType "buy some socks when i am at some store" or type /help to see the usage.');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '歡迎!\n輸入 "去雜貨店的時候要買肥皂" 或是輸入 /help 來看用法。');
                return;
        }
    };

    this.sendHelp = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'I can understand the following patterns:\n\n1. [do something] when I am [some context]\n2. I am [some context]\n3. done');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '我看得懂以下的模式:\n\n1. 我[情境]的時候要[做事情]\n2. 我[情境]了\n3. 完成');
                return;
        }
    };

    this.sendUnknown = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'What?');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '蛤?');
                return;
        }
    };

    this.sendAddTodo = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'Okay, I will remind you to ' + args.plan + ' when you are ' + args.timing + '.');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '好的，我之後會提醒你' + args.timing + '的時候要' + args.plan + '。');
                return;
        }
    };

    this.sendWhatToDo = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                if (args.plans.length == 0) {
                    bot.sendMessage(msg.chat.id, 'Nothing to do.');
                } else if (args.plans.length == 1) {
                    bot.sendMessage(msg.chat.id, 'Go ' + args.plans[0] + '.');
                } else {
                    bot.sendMessage(msg.chat.id, 'Go do these things:\n' + args.plans.join('\n'));
                }
                return;
            case 'zh-tw':
                if (args.plans.length == 0) {
                    bot.sendMessage(msg.chat.id, '沒事做。');
                } else if (args.plans.length == 1) {
                    bot.sendMessage(msg.chat.id, '去' + args.plans[0] + '。');
                } else {
                    bot.sendMessage(msg.chat.id, '去做這些事:\n' + args.plans.join('\n'));
                }
                return;
        }
    };

    this.sendWhatNow = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                if (args.timings.length == 0) {
                    bot.sendMessage(msg.chat.id, 'Nothing to do.');
                } else if (args.timings.length == 1) {
                    bot.sendMessage(msg.chat.id, 'Are you ' + args.timings[0] + '?');
                } else {
                    bot.sendMessage(msg.chat.id, 'What timing are you at?\n' + args.timings.join('\n'));
                }
                return;
            case 'zh-tw':
                if (args.timings.length == 0) {
                    bot.sendMessage(msg.chat.id, '沒事做。');
                } else if (args.timings.length == 1) {
                    bot.sendMessage(msg.chat.id, '你' + args.timings[0] + '嗎？');
                } else {
                    bot.sendMessage(msg.chat.id, '你現在有任何好時機嗎？\n' + args.timings.join('\n'));
                }
                return;
        }
    };

    this.sendRemoveTodo = function(msg, action, args, profile) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'Great job!');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '太棒了!');
                return;
        }
    };

    this.sendSimpleResponse = function(msg, action) {
        switch (action) {
            case 'START':
                this.sendStart(msg, action);
                return true;
            case 'HELP':
                this.sendHelp(msg, action);
                return true;
            case 'UNKNOWN':
                this.sendUnknown(msg, action);
                return true;
            default:
                return false;
        }
    };

    this.sendBeforeSaveResponse = function(msg, action, args, profile) {
        switch (action) {
            case 'WHAT-NOW':
                this.sendWhatNow(msg, action, args, profile);
                return true;
            default:
                return false;
        }
    };

    this.sendAfterSaveResponse = function(msg, action, args, profile) {
        switch (action) {
            case 'ADD-TODO':
                this.sendAddTodo(msg, action, args, profile);
                return;
            case 'WHAT-TO-DO':
                this.sendWhatToDo(msg, action, args, profile);
                return;
            case 'REMOVE-TODO':
                this.sendRemoveTodo(msg, action, args, profile);
                return;
        }
    };

    this.updateProfileAndArgs = function(msg, action, args, profile) {
        switch (action) {
            case 'ADD-TODO':
                profile.currTiming = null;
                if (profile.todoList.length >= 100) {
                    bot.sendMessage(msg.chat.id, 'Too many things to do!');
                    return false;
                }
                var sameTodo = profile.todoList.filter(function(todo) {
                    return (todo.timing == args.timing && todo.plan == args.plan);
                });
                if (sameTodo.length != 0) {
                    bot.sendMessage(msg.chat.id, 'You already told me that.');
                    return false;
                }
                profile.todoList.push({
                    timing: args.timing,
                    plan: args.plan,
                });
                return true;
            case 'WHAT-TO-DO':
                profile.currTiming = args.timing;
                var targetTodoList = profile.todoList.filter(function(todo) {
                    return (todo.timing == args.timing);
                });
                args.plans = targetTodoList.map(function(todo) {
                    return todo.plan;
                });
                return true;
            case 'WHAT-NOW':
                args.timings = [];
                profile.todoList.forEach(function(todo) {
                    if (args.timings.indexOf(todo.timing) === -1) {
                        args.timings.push(todo.timing);
                    }
                });
                return true;
            case 'REMOVE-TODO':
                if (!profile.currTiming) {
                    bot.sendMessage(msg.chat.id, 'What is your timing now?');
                    return false;
                }
                profile.todoList = profile.todoList.filter(function(todo) {
                    return (todo.timing != profile.currTiming);
                });
                profile.currTiming = null;
                return true;
            default:
                return false;
        }
    };

    this.sendMsg = function(msg, action, args) {
        var me = this;

        args = args || {};

        if (me.sendSimpleResponse(msg, action)) {
            return;
        }

        models.Profile.findOne({userId: msg.from.id})
                .exec(function(err, profile) {
            if (err) {
                bot.sendMessage(msg.chat.id, 'Something went wrong...');
                return;
            }

            if (!profile) {
                var profile = new models.Profile({
                    userId: msg.from.id,
                    currTiming: null,
                    todoList: [],
                });
            }

            if (!me.updateProfileAndArgs(msg, action, args, profile)) {
                return;
            }

            if (me.sendBeforeSaveResponse(msg, action, args, profile)) {
                return;
            }

            profile.save(function(err) {
                if (err) {
                    bot.sendMessage(msg.chat.id, 'Something went wrong...');
                    return;
                }
                me.sendAfterSaveResponse(msg, action, args, profile);
            });
        });
    };
};
<commit_msg>Remove argument "profile" from message senders<commit_after>var models = require('./models');

module.exports = function(bot) {
    this.sendStart = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'Welcome!\nType "buy some socks when i am at some store" or type /help to see the usage.');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '歡迎!\n輸入 "去雜貨店的時候要買肥皂" 或是輸入 /help 來看用法。');
                return;
        }
    };

    this.sendHelp = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'I can understand the following patterns:\n\n1. [do something] when I am [some context]\n2. I am [some context]\n3. done');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '我看得懂以下的模式:\n\n1. 我[情境]的時候要[做事情]\n2. 我[情境]了\n3. 完成');
                return;
        }
    };

    this.sendUnknown = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'What?');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '蛤?');
                return;
        }
    };

    this.sendAddTodo = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'Okay, I will remind you to ' + args.plan + ' when you are ' + args.timing + '.');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '好的，我之後會提醒你' + args.timing + '的時候要' + args.plan + '。');
                return;
        }
    };

    this.sendWhatToDo = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                if (args.plans.length == 0) {
                    bot.sendMessage(msg.chat.id, 'Nothing to do.');
                } else if (args.plans.length == 1) {
                    bot.sendMessage(msg.chat.id, 'Go ' + args.plans[0] + '.');
                } else {
                    bot.sendMessage(msg.chat.id, 'Go do these things:\n' + args.plans.join('\n'));
                }
                return;
            case 'zh-tw':
                if (args.plans.length == 0) {
                    bot.sendMessage(msg.chat.id, '沒事做。');
                } else if (args.plans.length == 1) {
                    bot.sendMessage(msg.chat.id, '去' + args.plans[0] + '。');
                } else {
                    bot.sendMessage(msg.chat.id, '去做這些事:\n' + args.plans.join('\n'));
                }
                return;
        }
    };

    this.sendWhatNow = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                if (args.timings.length == 0) {
                    bot.sendMessage(msg.chat.id, 'Nothing to do.');
                } else if (args.timings.length == 1) {
                    bot.sendMessage(msg.chat.id, 'Are you ' + args.timings[0] + '?');
                } else {
                    bot.sendMessage(msg.chat.id, 'What timing are you at?\n' + args.timings.join('\n'));
                }
                return;
            case 'zh-tw':
                if (args.timings.length == 0) {
                    bot.sendMessage(msg.chat.id, '沒事做。');
                } else if (args.timings.length == 1) {
                    bot.sendMessage(msg.chat.id, '你' + args.timings[0] + '嗎？');
                } else {
                    bot.sendMessage(msg.chat.id, '你現在有任何好時機嗎？\n' + args.timings.join('\n'));
                }
                return;
        }
    };

    this.sendRemoveTodo = function(msg, action, args) {
        switch (process.env.BOT_LANGUAGE) {
            case 'en-us':
                bot.sendMessage(msg.chat.id, 'Great job!');
                return;
            case 'zh-tw':
                bot.sendMessage(msg.chat.id, '太棒了!');
                return;
        }
    };

    this.sendSimpleResponse = function(msg, action) {
        switch (action) {
            case 'START':
                this.sendStart(msg, action);
                return true;
            case 'HELP':
                this.sendHelp(msg, action);
                return true;
            case 'UNKNOWN':
                this.sendUnknown(msg, action);
                return true;
            default:
                return false;
        }
    };

    this.sendBeforeSaveResponse = function(msg, action, args) {
        switch (action) {
            case 'WHAT-NOW':
                this.sendWhatNow(msg, action, args);
                return true;
            default:
                return false;
        }
    };

    this.sendAfterSaveResponse = function(msg, action, args) {
        switch (action) {
            case 'ADD-TODO':
                this.sendAddTodo(msg, action, args);
                return;
            case 'WHAT-TO-DO':
                this.sendWhatToDo(msg, action, args);
                return;
            case 'REMOVE-TODO':
                this.sendRemoveTodo(msg, action, args);
                return;
        }
    };

    this.updateProfileAndArgs = function(msg, action, args, profile) {
        switch (action) {
            case 'ADD-TODO':
                profile.currTiming = null;
                if (profile.todoList.length >= 100) {
                    bot.sendMessage(msg.chat.id, 'Too many things to do!');
                    return false;
                }
                var sameTodo = profile.todoList.filter(function(todo) {
                    return (todo.timing == args.timing && todo.plan == args.plan);
                });
                if (sameTodo.length != 0) {
                    bot.sendMessage(msg.chat.id, 'You already told me that.');
                    return false;
                }
                profile.todoList.push({
                    timing: args.timing,
                    plan: args.plan,
                });
                return true;
            case 'WHAT-TO-DO':
                profile.currTiming = args.timing;
                var targetTodoList = profile.todoList.filter(function(todo) {
                    return (todo.timing == args.timing);
                });
                args.plans = targetTodoList.map(function(todo) {
                    return todo.plan;
                });
                return true;
            case 'WHAT-NOW':
                args.timings = [];
                profile.todoList.forEach(function(todo) {
                    if (args.timings.indexOf(todo.timing) === -1) {
                        args.timings.push(todo.timing);
                    }
                });
                return true;
            case 'REMOVE-TODO':
                if (!profile.currTiming) {
                    bot.sendMessage(msg.chat.id, 'What is your timing now?');
                    return false;
                }
                profile.todoList = profile.todoList.filter(function(todo) {
                    return (todo.timing != profile.currTiming);
                });
                profile.currTiming = null;
                return true;
            default:
                return false;
        }
    };

    this.sendMsg = function(msg, action, args) {
        var me = this;

        args = args || {};

        if (me.sendSimpleResponse(msg, action)) {
            return;
        }

        models.Profile.findOne({userId: msg.from.id})
                .exec(function(err, profile) {
            if (err) {
                bot.sendMessage(msg.chat.id, 'Something went wrong...');
                return;
            }

            if (!profile) {
                var profile = new models.Profile({
                    userId: msg.from.id,
                    currTiming: null,
                    todoList: [],
                });
            }

            if (!me.updateProfileAndArgs(msg, action, args, profile)) {
                return;
            }

            if (me.sendBeforeSaveResponse(msg, action, args)) {
                return;
            }

            profile.save(function(err) {
                if (err) {
                    bot.sendMessage(msg.chat.id, 'Something went wrong...');
                    return;
                }
                me.sendAfterSaveResponse(msg, action, args);
            });
        });
    };
};
<|endoftext|>


<commit_before>app.controller("jobseekerCtrl", ['$scope', '$timeout', '$filter', 'jobFactory',
	function($scope, $timeout, $filter, jobFactory) {
		$scope.job = {};
		$scope.sort = {};
		$scope.filter = {};
		$scope.joblist = [];

		var editedJob = {};

		$scope.init = function() {
			$scope.job.date = new Date();
			$scope.sort.orderBy = '';
			$scope.sort.reverse = false;

			_getJobList();
		};

		$scope.submitForm = function() {
			if ($scope.job._id)
				_editJob();
			else
				_addJob();
		};

		var _getJobList = function() {
			jobFactory.getAllJobs()
			.then(function successCallback(response) {
				$scope.joblist = response.data;
			}, function errorCallback(response) {
				console.log(response.statusText);
			});
		};

		var _addJob = function() {
			jobFactory.addJob($scope.job)
			.then(function successCallback(response) {
				$scope.joblist.push(response.data);
			}, function errorCallback(response) {
				console.log(response.statusText);
			});

			$scope.resetForm();
		};

		var _editJob = function() {
			var id = $scope.job._id;
			var job = {
				date :  $scope.job.date,
				title : $scope.job.title,
				company : $scope.job.company,
				location : $scope.job.location,
				via : $scope.job.via
			};

			jobFactory.editJob(id, job)
			.then(function successCallback(response) {
				return;
			}, function errorCallback(response) {
				console.log(response.statusText);
			});
		};

		$scope.openEditModal = function(job) {

			job.date = new Date(job.date);

			editedJob = {
				_id : job._id,
				date :  job.date,
				title : job.title,
				company : job.company,
				location : job.location,
				via : job.via
			};

			$scope.job = job;
		};

		var _findIndexByID = function(id) {
			for (var i = 0; i < $scope.joblist.length; i++) {
				if ($scope.joblist[i]._id === id)
					return i;
			}

			return -1;
		}

		$scope.deleteJob = function(job) {
			var index = _findIndexByID(job._id);

			jobFactory.deleteJob(job._id)
			.then(function(response) {
				$scope.joblist.splice(index, 1);
			}, function(response) {
				console.log(response.statusText);
			});
		};

		$scope.resetForm = function() {
			if ($scope.job._id)
				_revertForm();
			else
				_clearForm();
		};

		var _clearForm = function() {
			$scope.job = {};
			$scope.job.date = new Date();
		};

		var _revertForm = function() {
			$scope.job._id = editedJob._id;
			$scope.job.date = editedJob.date;
			$scope.job.title = editedJob.title;
			$scope.job.company = editedJob.company;
			$scope.job.location = editedJob.location;
			$scope.job.via = editedJob.via;
		};

		var _isSortedBy = function(colname) {
			return $scope.sort.orderBy === colname;
		};

		$scope.sortBy = function(colname) {
			if (_isSortedBy(colname))
				$scope.sort.reverse = !$scope.sort.reverse;
			else {
				$scope.sort.orderBy = colname;
				$scope.sort.reverse = false;
			}
		};

		$scope.getSortedClass = function(colname) {
			if (_isSortedBy(colname))
				return "text-muted";
			else
				return "";
		};

		$scope.getSortedIcon = function(colname) {
			if ($scope.sort.reverse)
				var direction = "desc";
			else
				var direction = "asc";

			if (_isSortedBy(colname))
				return "fa-sort-" + direction;
			else
				return "fa-sort";
		};

		$("#addJobModal").on("hide.bs.modal", function (e) {
			$timeout(function () {
				_clearForm();
			});
		});

		$scope.dateFilter = function(obj) {
			if ($scope.filter.fromDate && new Date(obj.date) < new Date($scope.filter.fromDate))
				return false;

			if ($scope.filter.toDate && new Date(obj.date) > new Date($scope.filter.toDate))
				return false;

			return true;
		}

		$scope.resetFilters = function() {
			$scope.filter = {};
			$scope.sorted = {};
		};
	}
]);
<commit_msg>fix for #25, setHours(0,0,0,0) needed to compare date only, not including time<commit_after>app.controller("jobseekerCtrl", ['$scope', '$timeout', '$filter', 'jobFactory',
	function($scope, $timeout, $filter, jobFactory) {
		$scope.job = {};
		$scope.sort = {};
		$scope.filter = {};
		$scope.joblist = [];

		var editedJob = {};

		$scope.init = function() {
			$scope.job.date = new Date();
			$scope.job.date.setHours(0,0,0,0);
			$scope.sort.orderBy = '';
			$scope.sort.reverse = false;

			_getJobList();
		};

		$scope.submitForm = function() {
			if ($scope.job._id)
				_editJob();
			else
				_addJob();
		};

		var _getJobList = function() {
			jobFactory.getAllJobs()
			.then(function successCallback(response) {
				$scope.joblist = response.data;
			}, function errorCallback(response) {
				console.log(response.statusText);
			});
		};

		var _addJob = function() {
			$scope.job.date.setHours(0,0,0,0);
			jobFactory.addJob($scope.job)
			.then(function successCallback(response) {
				$scope.joblist.push(response.data);
			}, function errorCallback(response) {
				console.log(response.statusText);
			});

			$scope.resetForm();
		};

		var _editJob = function() {
			var id = $scope.job._id;
			var job = {
				date :  $scope.job.date,
				title : $scope.job.title,
				company : $scope.job.company,
				location : $scope.job.location,
				via : $scope.job.via
			};

			jobFactory.editJob(id, job)
			.then(function successCallback(response) {
				return;
			}, function errorCallback(response) {
				console.log(response.statusText);
			});
		};

		$scope.openEditModal = function(job) {

			job.date = new Date(job.date);

			editedJob = {
				_id : job._id,
				date :  job.date,
				title : job.title,
				company : job.company,
				location : job.location,
				via : job.via
			};

			$scope.job = job;
		};

		var _findIndexByID = function(id) {
			for (var i = 0; i < $scope.joblist.length; i++) {
				if ($scope.joblist[i]._id === id)
					return i;
			}

			return -1;
		}

		$scope.deleteJob = function(job) {
			var index = _findIndexByID(job._id);

			jobFactory.deleteJob(job._id)
			.then(function(response) {
				$scope.joblist.splice(index, 1);
			}, function(response) {
				console.log(response.statusText);
			});
		};

		$scope.resetForm = function() {
			if ($scope.job._id)
				_revertForm();
			else
				_clearForm();
		};

		var _clearForm = function() {
			$scope.job = {};
			$scope.job.date = new Date();
		};

		var _revertForm = function() {
			$scope.job._id = editedJob._id;
			$scope.job.date = editedJob.date;
			$scope.job.title = editedJob.title;
			$scope.job.company = editedJob.company;
			$scope.job.location = editedJob.location;
			$scope.job.via = editedJob.via;
		};

		var _isSortedBy = function(colname) {
			return $scope.sort.orderBy === colname;
		};

		$scope.sortBy = function(colname) {
			if (_isSortedBy(colname))
				$scope.sort.reverse = !$scope.sort.reverse;
			else {
				$scope.sort.orderBy = colname;
				$scope.sort.reverse = false;
			}
		};

		$scope.getSortedClass = function(colname) {
			if (_isSortedBy(colname))
				return "text-muted";
			else
				return "";
		};

		$scope.getSortedIcon = function(colname) {
			if ($scope.sort.reverse)
				var direction = "desc";
			else
				var direction = "asc";

			if (_isSortedBy(colname))
				return "fa-sort-" + direction;
			else
				return "fa-sort";
		};

		$("#addJobModal").on("hide.bs.modal", function (e) {
			$timeout(function () {
				_clearForm();
			});
		});

		$scope.dateFilter = function(obj) {
			var jobDate = new Date(obj.date);
			return (!$scope.filter.fromDate || jobDate >= new Date($scope.filter.fromDate)) && (!$scope.filter.toDate || jobDate <= new Date($scope.filter.toDate))
		}

		$scope.resetFilters = function() {
			$scope.filter = {};
			$scope.sorted = {};
		};
	}
]);
<|endoftext|>


<commit_before>class MCExperimentDatasetsComponentController {
    /*@ngInject*/
    constructor($stateParams, datasetService, toast, $state, $mdDialog) {
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.datasetService = datasetService;
        this.toast = toast;
        this.$state = $state;
        this.$mdDialog = $mdDialog;
        this.datasets = [];
    }

    $onInit() {
        this.datasetService.getDatasetsForExperiment(this.projectId, this.experimentId)
            .then(
                (datasets) => this.datasets = datasets,
                () => this.toast.error('Unable to retrieve datasets for experiment')
            );
    }

    createNewDataset() {
        this.$mdDialog.show({
            templateUrl: 'app/project/experiments/experiment/components/datasets/new-dataset-dialog.html',
            controller: NewExperimentDatasetDialogController,
            controllerAs: '$ctrl',
            bindingToController: true
        }).then(
            (dataset) => {
                this.datasetService.getDatasetsForExperiment(this.projectId, this.experimentId)
                    .then(
                        (datasets) => {
                            this.datasets = datasets;
                            this.$state.go("project.experiment.datasets.dataset", {dataset_id: dataset.id});
                        },
                        () => this.toast.error('Unable to retrieve datasets for experiment')
                    )
            }
        );
    }

    openDataset(datasetId) {
        this.$state.go("project.experiment.datasets.dataset", {dataset_id: datasetId});
    }

    removeDataset(datasetId) {
        this.datasetService.deleteDatasetFromExperiment(this.projectId, this.experimentId, datasetId)
            .then(
                () => this.datasets = this.datasets.filter(d => d.id !== datasetId),
                () => this.toast.error("Unable to delete dataset from experiment")
            );
    }
}

class NewExperimentDatasetDialogController {
    /*@ngInject*/
    constructor($mdDialog, datasetService, $stateParams) {
        this.$mdDialog = $mdDialog;
        this.datasetService = datasetService;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.title = "";
        this.description = "";
    }

    create() {
        if (this.name !== '') {
            this.datasetService.createDatasetForExperiment(this.projectId, this.experimentId, this.title, this.description)
                .then(
                    (dataset) => this.$mdDialog.hide(dataset),
                    () => this.toast.error('Unable to create new dataset')
                );
        }
    }

    cancel() {
        this.$mdDialog.cancel();
    }
}

angular.module('materialscommons').component('mcExperimentDatasets', {
    templateUrl: 'app/project/experiments/experiment/components/datasets/mc-experiment-datasets.html',
    controller: MCExperimentDatasetsComponentController
});<commit_msg>Fixed missing toast injection<commit_after>class MCExperimentDatasetsComponentController {
    /*@ngInject*/
    constructor($stateParams, datasetService, toast, $state, $mdDialog) {
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.datasetService = datasetService;
        this.toast = toast;
        this.$state = $state;
        this.$mdDialog = $mdDialog;
        this.datasets = [];
    }

    $onInit() {
        this.datasetService.getDatasetsForExperiment(this.projectId, this.experimentId)
            .then(
                (datasets) => this.datasets = datasets,
                () => this.toast.error('Unable to retrieve datasets for experiment')
            );
    }

    createNewDataset() {
        this.$mdDialog.show({
            templateUrl: 'app/project/experiments/experiment/components/datasets/new-dataset-dialog.html',
            controller: NewExperimentDatasetDialogController,
            controllerAs: '$ctrl',
            bindingToController: true
        }).then(
            (dataset) => {
                this.datasetService.getDatasetsForExperiment(this.projectId, this.experimentId)
                    .then(
                        (datasets) => {
                            this.datasets = datasets;
                            this.$state.go("project.experiment.datasets.dataset", {dataset_id: dataset.id});
                        },
                        () => this.toast.error('Unable to retrieve datasets for experiment')
                    )
            }
        );
    }

    openDataset(datasetId) {
        this.$state.go("project.experiment.datasets.dataset", {dataset_id: datasetId});
    }

    removeDataset(datasetId) {
        this.datasetService.deleteDatasetFromExperiment(this.projectId, this.experimentId, datasetId)
            .then(
                () => this.datasets = this.datasets.filter(d => d.id !== datasetId),
                () => this.toast.error("Unable to delete dataset from experiment")
            );
    }
}

class NewExperimentDatasetDialogController {
    /*@ngInject*/
    constructor($mdDialog, datasetService, toast, $stateParams) {
        this.$mdDialog = $mdDialog;
        this.datasetService = datasetService;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.toast = toast;
        this.title = "";
        this.description = "";
    }

    create() {
        if (this.name !== '') {
            this.datasetService.createDatasetForExperiment(this.projectId, this.experimentId, this.title, this.description)
                .then(
                    (dataset) => this.$mdDialog.hide(dataset),
                    () => this.toast.error('Unable to create new dataset')
                );
        }
    }

    cancel() {
        this.$mdDialog.cancel();
    }
}

angular.module('materialscommons').component('mcExperimentDatasets', {
    templateUrl: 'app/project/experiments/experiment/components/datasets/mc-experiment-datasets.html',
    controller: MCExperimentDatasetsComponentController
});<|endoftext|>


<commit_before>var webpack = require('webpack');
var path = require('path');

module.exports = {

    entry: './app/scripts/boot',
    output: {
        path: path.resolve(__dirname, 'dist'),
        publicPath: '/dist/',
        filename: 'bundle.js'
    },

    // Turn on source maps
    devtool: 'source-map',

    resolve: {
        extensions: ['', '.ts', '.js']
    },

    plugins: [

        // Minimize output
        // new webpack.optimize.UglifyJsPlugin()
    ],

    module: {
        loaders: [

            // Typescript support
            {test: /\.ts$/, loaders: ['ts-loader'], exclude: /node_modules/},

            // CSS support
            {test: /\.css$/, loader: 'style-loader!css-loader'}
        ]
    }
};<commit_msg>Config<commit_after>var webpack = require('webpack');
var path = require('path');

module.exports = {

    entry: './app/scripts/boot',
    output: {
        path: path.resolve(__dirname, 'app/dist'),
        publicPath: '/dist/',
        filename: 'bundle.js'
    },

    // Turn on source maps
    devtool: 'source-map',

    resolve: {
        extensions: ['', '.ts', '.js']
    },

    plugins: [

        // Minimize output
        // new webpack.optimize.UglifyJsPlugin()
    ],

    module: {
        loaders: [

            // Typescript support
            {test: /\.ts$/, loaders: ['ts-loader'], exclude: /node_modules/},

            // CSS support
            {test: /\.css$/, loader: 'style-loader!css-loader'}
        ]
    }
};<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var ConstDependency = require("./dependencies/ConstDependency");
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");

var NullFactory = require("./NullFactory");

function ConstPlugin() {
}
module.exports = ConstPlugin;

ConstPlugin.prototype.apply = function(compiler) {
	compiler.plugin("compilation", function(compilation, params) {
		compilation.dependencyFactories.set(ConstDependency, new NullFactory());
		compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template());
	});
	compiler.parser.plugin("statement if", function(statement) {
		var param = this.evaluateExpression(statement.test);
		if(param.isBoolean()) {
			this.state.current.addDependency(new ConstDependency(param.bool + "", param.range));
			return param.bool;
		}
	});
	compiler.parser.plugin("evaluate Identifier __resourceQuery", function(expr) {
		if(!this.state.module) return;
		var res = new BasicEvaluatedExpression();
		res.setString(this.state.module.splitQuery(this.state.module.resource)[1]);
		res.setRange(expr.range);
		return res;
	});
	compiler.parser.plugin("expression __resourceQuery", function(expr) {
		if(!this.state.module) return;
		this.state.current.addDependency(new ConstDependency(JSON.stringify(this.state.module.splitQuery(this.state.module.resource)[1]), expr.range));
		return true;
	});
};<commit_msg>use variable for __resourceQuery<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var ConstDependency = require("./dependencies/ConstDependency");
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");

var NullFactory = require("./NullFactory");

function ConstPlugin() {
}
module.exports = ConstPlugin;

ConstPlugin.prototype.apply = function(compiler) {
	compiler.plugin("compilation", function(compilation, params) {
		compilation.dependencyFactories.set(ConstDependency, new NullFactory());
		compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template());
	});
	compiler.parser.plugin("statement if", function(statement) {
		var param = this.evaluateExpression(statement.test);
		if(param.isBoolean()) {
			this.state.current.addDependency(new ConstDependency(param.bool + "", param.range));
			return param.bool;
		}
	});
	compiler.parser.plugin("evaluate Identifier __resourceQuery", function(expr) {
		if(!this.state.module) return;
		var res = new BasicEvaluatedExpression();
		res.setString(this.state.module.splitQuery(this.state.module.resource)[1]);
		res.setRange(expr.range);
		return res;
	});
	compiler.parser.plugin("expression __resourceQuery", function(expr) {
		if(!this.state.module) return;
		this.state.current.addVariable("__resourceQuery", JSON.stringify(this.state.module.splitQuery(this.state.module.resource)[1]));
		return true;
	});
};<|endoftext|>


<commit_before>const Nomad = require('nomad-stream')
const moment = require('moment')
const nomad = new Nomad()
const fetch = require('node-fetch')

let instance = null
const frequency = 60 * 60 * 1000

// parse into url object
let base = 'http://erddap.exploratorium.edu:8080/erddap/tabledap/exploreusgsdata.json?time,temperature,specific_conductance,salinity,turbidity,dissolved_o2,station_id,latitude,longitude&time>='

function buildUrl() {
  const d = new moment()
  const hourAgo = d.subtract(6, 'h')
  const timeString = hourAgo.toISOString()
  const url = `${base}${timeString}`
  const encoded = encodeURI(url)
  return encoded
}

function transform(json) {
  let transformed = {}
  transformed['columnNames'] = json.table.columnNames
  transformed['columnTypes'] = json.table.columnTypes
  transformed['columnUnits'] = json.table.columnUnits
  transformed['data'] = json.table.rows[0]
  return transformed
}

// returns promise
function getMessage() {
  const url = buildUrl()
  return fetch(url).then(res => {
    return res.json();
  }).then(json => {
    const formatted = transform(json)
    return Promise.resolve(JSON.stringify(formatted))
  }).catch(err => {
    console.log(err)
    return Promise.reject(err)
  })
}

nomad.prepareToPublish().then((n) => {
  instance = n
  return instance.publishRoot('hello')
}).then(() => {
  setInterval(() => {
    getMessage().then(m => {
      instance.publish(m)
      .catch(err => {
        console.log(`Error: ${err}`)
      })
    })
    .catch(err => {
      console.log(`Error: ${err}`)
    })
  }, frequency)
})

<commit_msg>added correct URL and fixed time to be 1 hour<commit_after>const Nomad = require('nomad-stream')
const moment = require('moment')
const nomad = new Nomad()
const fetch = require('node-fetch')

let instance = null
const frequency = 60 * 60 * 1000

// parse into url object
let base = 'http://erddap.exploratorium.edu:8080/erddap/tabledap/explorebeaconbay5min.htmlTable?time%2CTemperature_1%2CAir_Pressure%2CTemperature_2%2CRelative_Humidity%2CDew_Point%2CO3_1%2CCO_1%2CNO2_1%2CO3_Working_2%2CO3_Auxiliary_2%2CCO_Working_2%2CCO_Auxiliary_2%2CNO_Working%2CNO_Auxiliary%2CNO_Auxiliary_2%2CNO2_Working_2%2CNO2_Auxiliary_2%2CParticulate_high%2CParticulate_total%2CParticulate_pct%2CCO2%2CTemperature_3%2Cstation_id%2Clatitude%2Clongitudetime>='
//'http://erddap.exploratorium.edu:8080/erddap/tabledap/exploreusgsdata.json?time,temperature,specific_conductance,salinity,turbidity,dissolved_o2,station_id,latitude,longitude&time>='

function buildUrl() {
  const d = new moment()
  const hourAgo = d.subtract(1, 'h')
  const timeString = hourAgo.toISOString()
  const url = `${base}${timeString}`
  const encoded = encodeURI(url)
  return encoded
}

function transform(json) {
  let transformed = {}
  transformed['columnNames'] = json.table.columnNames
  transformed['columnTypes'] = json.table.columnTypes
  transformed['columnUnits'] = json.table.columnUnits
  transformed['data'] = json.table.rows[0]
  return transformed
}

// returns promise
function getMessage() {
  const url = buildUrl()
  return fetch(url).then(res => {
    return res.json();
  }).then(json => {
    const formatted = transform(json)
    return Promise.resolve(JSON.stringify(formatted))
  }).catch(err => {
    console.log(err)
    return Promise.reject(err)
  })
}

nomad.prepareToPublish().then((n) => {
  instance = n
  return instance.publishRoot('hello')
}).then(() => {
  setInterval(() => {
    getMessage().then(m => {
      instance.publish(m)
      .catch(err => {
        console.log(`Error: ${err}`)
      })
    })
    .catch(err => {
      console.log(`Error: ${err}`)
    })
  }, frequency)
})

<|endoftext|>


<commit_before>/**
 * Add and delete 'rows' to any container element.
 *
 * @author      Stephen Lewis (http://github.com/experience/)
 * @copyright   Experience Internet
 * @version     1.1.4
 */

(function($) {

  $.fn.roland = function(options) {
    var opts = $.extend({}, $.fn.roland.defaults, options);

    return this.each(function() {
      var $container = $(this);
      updateIndexes($container, opts);
      updateNav($container, opts);

      // Adds a row.
      $container.find('.' + opts.addRowClass).bind('click', function(e) {
        e.preventDefault();

        var $link       = $(this);
        var $parentRow  = $link.closest('.' + opts.rowClass);
        var $lastRow    = $container.find('.' + opts.rowClass + ':last');
        var $cloneRow   = $lastRow.clone(true);
        var eventData   = {};

        // Reset the field values.
        $cloneRow.find('input').each(function() {
          var type = $(this).attr('type');

          switch (type.toLowerCase()) {
            case 'checkbox':
            case 'radio':
              $(this).attr('checked', false);
              break;

            case 'email':
            case 'password':
            case 'search':
            case 'text':
              $(this).val('');
              break;
          }
        });

        $cloneRow.find('select').val('');

        // Pre-add event. Only checks return value from last listener.
        if ($link.data('events').preAddRow !== undefined) {
          eventData = {container : $container, options : opts, newRow : $cloneRow};
          $cloneRow = $link.triggerHandler('preAddRow', [eventData]);

          // Returning FALSE prevents the row being added.
          if ($cloneRow === false) {
            return;
          }
        }

        // If the 'add row' link lives inside a row, insert the new row after it.
        // Otherwise, just tag it on the end.
        typeof $parentRow === 'object'
          ? $parentRow.after($cloneRow) : $lastRow.append($cloneRow);

        // Update everything.
        updateIndexes($container, opts);
        updateNav($container, opts);

        // Post-add event.
        if ($link.data('events').postAddRow !== undefined) {
          eventData = {container : $container, options : opts, newRow : $cloneRow};
          $link.triggerHandler('postAddRow', [eventData]);
        }
      });

      // Removes a row.
      $container.find('.' + opts.removeRowClass).bind('click', function(e) {
        e.preventDefault();

        var $row = $(this).closest('.' + opts.rowClass);

        // Can't remove the last row.
        if ($row.siblings().length == 0) {
          return false;
        }

        $row.remove();

        // Update everything.
        updateIndexes($container, opts);
        updateNav($container, opts);
      });
    });
  };

  // Defaults.
  $.fn.roland.defaults = {
    rowClass        : 'row',
    addRowClass     : 'add_row',
    removeRowClass  : 'remove_row'
  };

  /* ------------------------------------------
   * PRIVATE METHODS
   * -----------------------------------------*/

  // Updates the indexes of any form elements.
  function updateIndexes($container, opts) {
    $container.find('.' + opts.rowClass).each(function(rowCount) {
      regex = /^([a-z_]+)\[(?:[0-9]+)\]\[([a-z_]+)\]$/;

      $(this).find('input, select, textarea').each(function(fieldCount) {
        $field = $(this);

        if ($field.attr('id')) {
          var fieldId = $field.attr('id')
            .replace(regex, '$1[' + rowCount + ']$2');

          $field.attr('id', fieldId);
        }

        if ($field.attr('name')) {
          var fieldName = $field.attr('name')
            .replace(regex, '$1[' + rowCount + ']$2');

          $field.attr('name', fieldName);
        }
      });
    });
  };

  // Updates the navigation buttons.
  function updateNav($container, opts) {
    var $remove = $container.find('.' + opts.removeRowClass);
    var $rows = $container.find('.' + opts.rowClass);
    $rows.size() == 1 ? $remove.hide() : $remove.show();
  };

})(jQuery);

/* End of file      : jquery.roland.js */
<commit_msg>Fix regular expression bug.<commit_after>/**
 * Add and delete 'rows' to any container element.
 *
 * @author      Stephen Lewis (http://github.com/experience/)
 * @copyright   Experience Internet
 * @version     1.1.4
 */

(function($) {

  $.fn.roland = function(options) {
    var opts = $.extend({}, $.fn.roland.defaults, options);

    return this.each(function() {
      var $container = $(this);
      updateIndexes($container, opts);
      updateNav($container, opts);

      // Adds a row.
      $container.find('.' + opts.addRowClass).bind('click', function(e) {
        e.preventDefault();

        var $link       = $(this);
        var $parentRow  = $link.closest('.' + opts.rowClass);
        var $lastRow    = $container.find('.' + opts.rowClass + ':last');
        var $cloneRow   = $lastRow.clone(true);
        var eventData   = {};

        // Reset the field values.
        $cloneRow.find('input').each(function() {
          var type = $(this).attr('type');

          switch (type.toLowerCase()) {
            case 'checkbox':
            case 'radio':
              $(this).attr('checked', false);
              break;

            case 'email':
            case 'password':
            case 'search':
            case 'text':
              $(this).val('');
              break;
          }
        });

        $cloneRow.find('select').val('');

        // Pre-add event. Only checks return value from last listener.
        if ($link.data('events').preAddRow !== undefined) {
          eventData = {container : $container, options : opts, newRow : $cloneRow};
          $cloneRow = $link.triggerHandler('preAddRow', [eventData]);

          // Returning FALSE prevents the row being added.
          if ($cloneRow === false) {
            return;
          }
        }

        // If the 'add row' link lives inside a row, insert the new row after it.
        // Otherwise, just tag it on the end.
        typeof $parentRow === 'object'
          ? $parentRow.after($cloneRow) : $lastRow.append($cloneRow);

        // Update everything.
        updateIndexes($container, opts);
        updateNav($container, opts);

        // Post-add event.
        if ($link.data('events').postAddRow !== undefined) {
          eventData = {container : $container, options : opts, newRow : $cloneRow};
          $link.triggerHandler('postAddRow', [eventData]);
        }
      });

      // Removes a row.
      $container.find('.' + opts.removeRowClass).bind('click', function(e) {
        e.preventDefault();

        var $row = $(this).closest('.' + opts.rowClass);

        // Can't remove the last row.
        if ($row.siblings().length == 0) {
          return false;
        }

        $row.remove();

        // Update everything.
        updateIndexes($container, opts);
        updateNav($container, opts);
      });
    });
  };

  // Defaults.
  $.fn.roland.defaults = {
    rowClass        : 'row',
    addRowClass     : 'add_row',
    removeRowClass  : 'remove_row'
  };

  /* ------------------------------------------
   * PRIVATE METHODS
   * -----------------------------------------*/

  // Updates the indexes of any form elements.
  function updateIndexes($container, opts) {
    $container.find('.' + opts.rowClass).each(function(rowCount) {
      regex = /^([a-z_]+)\[(?:[0-9]+)\](.*)$/;

      $(this).find('input, select, textarea').each(function(fieldCount) {
        $field = $(this);

        if ($field.attr('id')) {
          var fieldId = $field.attr('id')
            .replace(regex, '$1[' + rowCount + ']$2');

          $field.attr('id', fieldId);
        }

        if ($field.attr('name')) {
          var fieldName = $field.attr('name')
            .replace(regex, '$1[' + rowCount + ']$2');

          $field.attr('name', fieldName);
        }
      });
    });
  };

  // Updates the navigation buttons.
  function updateNav($container, opts) {
    var $remove = $container.find('.' + opts.removeRowClass);
    var $rows = $container.find('.' + opts.rowClass);
    $rows.size() == 1 ? $remove.hide() : $remove.show();
  };

})(jQuery);

/* End of file      : jquery.roland.js */
<|endoftext|>


<commit_before>(function( $ ) {
  $('head').append('\
    ');

  var MAX_SCROLL = 999999999;
  var defaults = {
    backgroundColor: '#333',
    textColor: '#DDD',
    fontFamily: 'monospace',
    height: 300
  };
  var $el, typeDelay = 80;

  var blinkTimer;
  var startBlink = function(next) {
    blinkTimer = setInterval(function() {
      $('.cursor').toggle();
    }, 500);
    next && next();
  };

  var stopBlink = function(next) {
    clearInterval(blinkTimer);
    next && next();
  };

  var addLine = function() {
    $('.cursor').remove();
    var p = $('

');
    $el.append(p);
    $el.scrollTop(MAX_SCROLL);
    return p;
  };

  var methods = {

    init: function(config) {
      config = $.extend(defaults, config);

      $el = this;

      var oldStyle = $el.attr('style') + ';' || '';
      var style = 'background-color: ' + config.backgroundColor;
      style += '; color: ' + config.textColor;
      style += '; font-family: ' + config.fontFamily;

      $el.addClass('typist-container')
        .attr('style', oldStyle + style)
        .height(config.height);

      startBlink();

      return $el;
    },
    prompt: function() {
      return $el.queue(function(next) {
        $('.cursor').remove();
        addLine()
          .addClass('prompt')
          .html('$ |');
        $el.scrollTop(MAX_SCROLL);
        next();
      });
    },
    type: function(text) {
      $el.queue(stopBlink);
      var typeChar = function(index) {
        $el.queue(function(next) {
          $('.cursor').before(text[index]);
          $el.scrollTop(MAX_SCROLL);
          next();
        })
        .delay(typeDelay);
      };
      for (var i = 0; i < text.length; i++) {
        typeChar(i);
      }
      return $el.queue(startBlink);
    },
    echo: function(text) {
      var $p;
      var typeChar = function(index) {
        $el.queue(function(next) {
          if (index === 0) {
            $p = addLine();
          }

          $p.append(text[index]);
          $el.scrollTop(MAX_SCROLL);
          next();
        })
        .delay(typeDelay);
      };
      for (var i = 0; i < text.length; i++) {
        typeChar(i);
      }
      return $el;
    },
    wait: function(millis) {
      return $el.delay(millis);
    },
    speed: function(speed) {
      if (speed === 'fast') {
        typeDelay = 20;
      }
      else if (speed === 'slow') {
        typeDelay = 120;
      }
      return $el;
    }
  };

  $.fn.typist = function(method) {
    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }
  };

})( jQuery );

<commit_msg>Fix scrolling in Firefox<commit_after>(function( $ ) {
  $('head').append('\
    ');

  var MAX_SCROLL = 999999999;
  var defaults = {
    backgroundColor: '#333',
    textColor: '#DDD',
    fontFamily: 'monospace',
    height: 300
  };
  var $el, typeDelay = 80;

  var blinkTimer;
  var startBlink = function(next) {
    blinkTimer = setInterval(function() {
      $('.cursor').toggle();
    }, 500);
    next && next();
  };

  var stopBlink = function(next) {
    clearInterval(blinkTimer);
    next && next();
  };

  var addLine = function() {
    $('.cursor').remove();
    var p = $('

');
    $el.append(p);
    var height = 0;
    $el.children().each(function() {
      height += $(this).height();
    });
    $el.scrollTop(height);
    return p;
  };

  var methods = {

    init: function(config) {
      config = $.extend(defaults, config);

      $el = this;

      var oldStyle = $el.attr('style') + ';' || '';
      var style = 'background-color: ' + config.backgroundColor;
      style += '; color: ' + config.textColor;
      style += '; font-family: ' + config.fontFamily;

      $el.addClass('typist-container')
        .attr('style', oldStyle + style)
        .height(config.height);

      startBlink();

      return $el;
    },
    prompt: function() {
      return $el.queue(function(next) {
        $('.cursor').remove();
        addLine()
          .addClass('prompt')
          .html('$ |');
        next();
      });
    },
    type: function(text) {
      $el.queue(stopBlink);
      var typeChar = function(index) {
        $el.queue(function(next) {
          $('.cursor').before(text[index]);
          next();
        })
        .delay(typeDelay);
      };
      for (var i = 0; i < text.length; i++) {
        typeChar(i);
      }
      return $el.queue(startBlink);
    },
    echo: function(text) {
      var $p;
      var typeChar = function(index) {
        $el.queue(function(next) {
          if (index === 0) {
            $p = addLine();
          }

          $p.append(text[index]);
          next();
        })
        .delay(typeDelay);
      };
      for (var i = 0; i < text.length; i++) {
        typeChar(i);
      }
      return $el;
    },
    wait: function(millis) {
      return $el.delay(millis);
    },
    speed: function(speed) {
      if (speed === 'fast') {
        typeDelay = 20;
      }
      else if (speed === 'slow') {
        typeDelay = 120;
      }
      return $el;
    }
  };

  $.fn.typist = function(method) {
    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }
  };

})( jQuery );

<|endoftext|>


<commit_before>var URL = {
  set(key, value, url) {
    var reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
    var url = url ? url : location.href;
    var result = reg.exec(url);
    if (result) {
      return url.replace(result[0], key + '=' + value);
    } else {
      var reg = /\?(.*)#?(.*)/gi;
      var search = reg.exec(url);
      if (search !== null) {
        return url.replace(search[1], search[1] + '&' + key + '=' + value);;
      } else {
        return '';
      }
    }
  },
  get(key, url) {
    var reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
    var url = url ? url : location.href;
    var result = reg.exec(url);
    if (result) {
      return result[2];
    } else {
      return '';
    }
  }
}
var Is = {
  android() {
    return window.navigator.userAgent.indexOf('Android') > -1 || window.navigator.userAgent.indexOf('Adr') > -1;
  },
  ios() {
    return !!window.navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  },
  mobile() {
    return !!navigator.userAgent.match(/AppleWebKit.*Mobile.*/);
  },
  wechat() {
    return navigator.userAgent.indexOf('MicroMessenger') > -1;
  },
  qq() {
    return navigator.userAgent.match(/\sQQ/i) == " qq";
  }
}

const Cookie = {
  get(key) {
    var arr,
      reg = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg)) {
      return unescape(arr[2]);
    } else {
      return null;
    }
  },
  set(name, value, hour, domain) {
    var domain = domain ? domain : document.location.host;
    if (hour) {
      var expireDate = new Date(new Date().getTime() + hour * 3600 * 1000);
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain + "; expires=" + expireDate.toGMTString();
    } else {
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain;
    }
  },
  delete(name) {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval = this.get(name);
    if (cval != null) {
      document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
    }
  },
  clear() {
    var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
    if (keys) {
      for (var i = keys.length; i--;) {
        document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
      }
    }
  }
};

// 弹窗辅助
var Tools = {
  maskEvent(x, y, rect, callback) {
    if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
      // console.log('in element');
    } else {
      callback && typeof callback === 'function' && callback();
    }
  },
  getStyle(el, name) {
    return window.getComputedStyle(el).getPropertyValue(name);
  },
  /**
   * 将数字千分化
   * 到万的显示'xxxx万'
   * 到亿的显示'xxxx亿'
   * 到万亿的显示'xxxx万亿'
   */
  formatCoin(num, digits = 2) {
    digits = Math.pow(10, digits) // 保留小数位数

    // 千分化
    function toThousands(num) {
      let itg = parseInt(num) // 取整数部分
      let itg_length = itg.toString().length
      let length = num.toString().length
      let dec = num.toString().slice(itg_length, length) // 取小数部分
      // 整数部分千分，小数部分保留2位附加
      return (itg || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + (parseInt(dec * digits) / digits).toString().slice(1);
    }

    num = parseFloat(num)
    if (isNaN(num)) {
      throw new TypeError('parameter must be a number')
    }
    if (num < 1e4) {
      return toThousands(num)
    } else if (num >= 1e4 && num < 1e8) {
      return toThousands(num / 1e4) + '万'
    } else if (num >= 1e8 && num < 1e12) {
      return toThousands(num / 1e8) + '亿'
    } else {
      return toThousands(num / 1e12) + '万亿'
    }
  },
  // 在某个(同步或异步)事件执行后，delay秒后执行。依赖jquery的deferred对象
  wait: function wait(waitFunction, delay, callback) {
    var startTime,
      endTime,
      wait = delay || 0;
    startTime = new Date().getTime();
    // ajax等异步操作 promise|await
    $.when(waitFunction()).done(function(res) {
      endTime = new Date().getTime();
      if (endTime - startTime >= wait) {
        callback(res);
      } else {
        setTimeout(function() {
          callback(res);
        }, wait + startTime - endTime);
      }
    });
  },
  /**
   * 字符编码数值对应的存储长度：
   * UCS-2编码(16进制) UTF-8 字节流(二进制)
   * 0000 - 007F       0xxxxxxx （1字节）
   * 0080 - 07FF       110xxxxx 10xxxxxx （2字节）
   * 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx （3字节）
   */
  getBytesLength: function(string) {
    var totalLength = 0;
    var charCode;
    for (var i = 0; i < string.length; i++) {
      charCode = string.charCodeAt(i);
      if (charCode < 0x007f) {
        totalLength++;
      } else if ((0x0080 <= charCode) && (charCode <= 0x07ff)) {
        totalLength += 2;
      } else if ((0x0800 <= charCode) && (charCode <= 0xffff)) {
        totalLength += 3;
      } else {
        totalLength += 4;
      }
    }
    return totalLength;
  },
  /**
   * Determine the mobile operating system.
   * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'.
   *
   * @returns {String}
   */
  getMobileOperatingSystem: function getMobileOperatingSystem() {
    var userAgent = navigator.userAgent || navigator.vendor || window.opera;

    // Windows Phone must come first because its UA also contains "Android"
    if (/windows phone/i.test(userAgent)) {
      return "Windows Phone";
    }

    if (/android/i.test(userAgent)) {
      return "Android";
    }

    // iOS detection from: http://stackoverflow.com/a/9039885/177710
    if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
      return "iOS";
    }

    return "unknown";
  }
}

// 时间函数
  // 根据秒来获取倒计时的时间[天, 时, 分, 秒]
function countdown(seconds, callback) {
  var timer
  // fix floating seconds
  seconds = Math.round(seconds)

  function prefix(n) {
    return n > 9 ? `${n}` : `0${n}`
  }

  function format(seconds, callback) {
    let day = 0
    let hour = 0
    let min = 0
    let sec = 0
    let Day = 24 * 60 * 60
    let Hour = 60 * 60
    let Min = 60
    if (seconds > Day) {
      day = Math.floor(seconds / Day)
      seconds = seconds % Day
    }
    hour = Math.floor(seconds / Hour)
    seconds = seconds % Hour
    min = Math.floor(seconds / Min)
    sec = seconds % Min
    return callback(prefix(day), prefix(hour), prefix(min), prefix(sec))
  }

  function down() {
    seconds--
    format(seconds, callback)
    if (!seconds) {
      clearInterval(timer)
    }
  }
  if (seconds > 0) {
    timer = setInterval(down, 1000)
    down()
  } else {
    format(0, callback)
  }
}

// unicode转码
var GB2312UnicodeConverter = {
  ToUnicode: function(str) {
    return escape(str).toLocaleLowerCase().replace(/%u/gi, '\\u');
  },
  ToGB2312: function(str) {
    return unescape(str.replace(/\\u/gi, '%u'));
  }
};

// 将对象转换为url的query参数
function formatParam(obj) {
  let str = ''
  for (let i in obj) {
    str += `${i}=${obj[i]}&`
  }
  return str.slice(0, -1)
}

// 替换一个字符串中，前start位，后end位中间的字符串，替换为'*'。常用语手机号转星，身份证号转星
function string2star(string = '', start = 0, end = 0) {
  if (!string) {
    return '';
  }
  if (start + end > string.length) {
    throw new Error('字符串长度小于start和end之和，请检查参数。')
  }
  let matches = string.match(new RegExp('^(.{' + start + '})(.*)(.{' + end + '})$'))
  let middle = matches[2].replace(/./g, s => '*')
  let ret = matches[1] + middle + matches[3]
  return `${matches[1]}${middle}${matches[3]}`
}

/* 格林威治时间修正为本地时间。
 * [Date](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
 */
function getLocaleDate(date) {
  return new Date(new Date(date).getTime() + new Date().getTimezoneOffset() * 60 * 1000)
}

module.exports = {
  countdown,
  string2star,
  getLocaleDate,
  formatParam,
  URL,
  Is,
  Tools,
  Cookie,
  GUC: GB2312UnicodeConverter,
}
<commit_msg>Update utils.js<commit_after>var URL = {
  set(key, value, url) {
    var reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
    var url = url ? url : location.href;
    var result = reg.exec(url);
    if (result) {
      return url.replace(result[0], key + '=' + value);
    } else {
      var reg = /\?(.*)#?(.*)/gi;
      var search = reg.exec(url);
      if (search !== null) {
        return url.replace(search[1], search[1] + '&' + key + '=' + value);;
      } else {
        return '';
      }
    }
  },
  get(key, url) {
    var reg = new RegExp('(' + key + ')=([^&]*)', 'ig');
    var url = url ? url : location.href;
    var result = reg.exec(url);
    if (result) {
      return result[2];
    } else {
      return '';
    }
  }
}
var Is = {
  android() {
    return window.navigator.userAgent.indexOf('Android') > -1 || window.navigator.userAgent.indexOf('Adr') > -1;
  },
  ios() {
    return !!window.navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
  },
  mobile() {
    return !!navigator.userAgent.match(/AppleWebKit.*Mobile.*/);
  },
  wechat() {
    return navigator.userAgent.indexOf('MicroMessenger') > -1;
  },
  qq() {
    return navigator.userAgent.match(/\sQQ/i) == " qq";
  }
}

const Cookie = {
  get(key) {
    var arr,
      reg = new RegExp("(^| )" + key + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg)) {
      return unescape(arr[2]);
    } else {
      return null;
    }
  },
  set(name, value, hour, domain) {
    var domain = domain ? domain : document.location.host;
    if (hour) {
      var expireDate = new Date(new Date().getTime() + hour * 3600 * 1000);
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain + "; expires=" + expireDate.toGMTString();
    } else {
      document.cookie = name + "=" + escape(value) + "; path=/; domain=" + domain;
    }
  },
  delete(name) {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval = this.get(name);
    if (cval != null) {
      document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
    }
  },
  clear() {
    var keys = document.cookie.match(/[^ =;]+(?=\=)/g);
    if (keys) {
      for (var i = keys.length; i--;) {
        document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
      }
    }
  }
};

// 弹窗辅助
var Tools = {
  maskEvent(x, y, rect, callback) {
    if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
      // console.log('in element');
    } else {
      callback && typeof callback === 'function' && callback();
    }
  },
  getStyle(el, name) {
    return window.getComputedStyle(el).getPropertyValue(name);
  },
  /**
   * 将数字千分化
   * 到万的显示'xxxx万'
   * 到亿的显示'xxxx亿'
   * 到万亿的显示'xxxx万亿'
   */
  formatCoin(num, digits = 2) {
    digits = Math.pow(10, digits) // 保留小数位数

    // 千分化
    function toThousands(num) {
      let itg = parseInt(num) // 取整数部分
      let itg_length = itg.toString().length
      let length = num.toString().length
      let dec = num.toString().slice(itg_length, length) // 取小数部分
      // 整数部分千分，小数部分保留2位附加
      return (itg || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') + (parseInt(dec * digits) / digits).toString().slice(1);
    }

    num = parseFloat(num)
    if (isNaN(num)) {
      throw new TypeError('parameter must be a number')
    }
    if (num < 1e4) {
      return toThousands(num)
    } else if (num >= 1e4 && num < 1e8) {
      return toThousands(num / 1e4) + '万'
    } else if (num >= 1e8 && num < 1e12) {
      return toThousands(num / 1e8) + '亿'
    } else {
      return toThousands(num / 1e12) + '万亿'
    }
  },
  // 在某个(同步或异步)事件执行后，delay秒后执行。依赖jquery的deferred对象
  wait: function wait(waitFunction, delay, callback) {
    var startTime,
      endTime,
      wait = delay || 0;
    startTime = new Date().getTime();
    // ajax等异步操作 promise|await
    $.when(waitFunction()).done(function(res) {
      endTime = new Date().getTime();
      if (endTime - startTime >= wait) {
        callback(res);
      } else {
        setTimeout(function() {
          callback(res);
        }, wait + startTime - endTime);
      }
    });
  },
  /**
   * 字符编码数值对应的存储长度：
   * UCS-2编码(16进制) UTF-8 字节流(二进制)
   * 0000 - 007F       0xxxxxxx （1字节）
   * 0080 - 07FF       110xxxxx 10xxxxxx （2字节）
   * 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx （3字节）
   */
  getBytesLength: function(string) {
    var totalLength = 0;
    var charCode;
    for (var i = 0; i < string.length; i++) {
      charCode = string.charCodeAt(i);
      if (charCode < 0x007f) {
        totalLength++;
      } else if ((0x0080 <= charCode) && (charCode <= 0x07ff)) {
        totalLength += 2;
      } else if ((0x0800 <= charCode) && (charCode <= 0xffff)) {
        totalLength += 3;
      } else {
        totalLength += 4;
      }
    }
    return totalLength;
  },
  /**
   * Determine the mobile operating system.
   * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'.
   *
   * @returns {String}
   */
  getMobileOperatingSystem: function getMobileOperatingSystem() {
    var userAgent = navigator.userAgent || navigator.vendor || window.opera;

    // Windows Phone must come first because its UA also contains "Android"
    if (/windows phone/i.test(userAgent)) {
      return "Windows Phone";
    }

    if (/android/i.test(userAgent)) {
      return "Android";
    }

    // iOS detection from: http://stackoverflow.com/a/9039885/177710
    if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
      return "iOS";
    }

    return "unknown";
  }
}

// 时间函数
  // 根据秒来获取倒计时的时间[天, 时, 分, 秒]
function countdown(seconds, callback) {
  var timer
  // fix floating seconds
  seconds = Math.round(seconds)

  function prefix(n) {
    return n > 9 ? `${n}` : `0${n}`
  }

  function format(seconds, callback) {
    let day = 0
    let hour = 0
    let min = 0
    let sec = 0
    let Day = 24 * 60 * 60
    let Hour = 60 * 60
    let Min = 60
    if (seconds > Day) {
      day = Math.floor(seconds / Day)
      seconds = seconds % Day
    }
    hour = Math.floor(seconds / Hour)
    seconds = seconds % Hour
    min = Math.floor(seconds / Min)
    sec = seconds % Min
    return callback(prefix(day), prefix(hour), prefix(min), prefix(sec))
  }

  function down() {
    seconds--
    format(seconds, callback)
    if (!seconds) {
      clearInterval(timer)
    }
  }
  if (seconds > 0) {
    timer = setInterval(down, 1000)
    down()
  } else {
    format(0, callback)
  }
}

// unicode转码
var GB2312UnicodeConverter = {
  ToUnicode: function(str) {
    return escape(str).toLocaleLowerCase().replace(/%u/gi, '\\u');
  },
  ToGB2312: function(str) {
    return unescape(str.replace(/\\u/gi, '%u'));
  }
};

// 将对象转换为url的query参数
function formatParam(obj) {
  let str = ''
  for (let i in obj) {
    str += `${i}=${obj[i]}&`
  }
  return str.slice(0, -1)
}

// 替换一个字符串中，前start位，后end位中间的字符串，替换为'*'。常用语手机号转星，身份证号转星
function string2star(string = '', start = 0, end = 0) {
  if (!string) {
    return '';
  }
  if (start + end > string.length) {
    throw new Error('字符串长度小于start和end之和，请检查参数。')
  }
  let matches = string.match(new RegExp('^(.{' + start + '})(.*)(.{' + end + '})$'))
  let middle = matches[2].replace(/./g, s => '*')
  let ret = matches[1] + middle + matches[3]
  return `${matches[1]}${middle}${matches[3]}`
}

/* 格林威治时间修正为本地时间。
 * [Date](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
 */
function getLocaleDate(date) {
  return new Date(new Date(date).getTime() + new Date().getTimezoneOffset() * 60 * 1000)
}

/**
 * 循环控制
 * @param  {Object} options
 * totalTimes 总共执行次数
 * time 每次执行的时间间隔
 * loop 每次执行的函数
 * end 循环结束后的回调函数
 */
function timerControl(options) {
    var count = 0;
    var timer;
    var CONFIG = {
        totalTimes: 1,
        time: 3000,
        loop: function () {},
        end: function() {}
    }
    options = $.extend({}, CONFIG, options)

    clearInterval(timer);

    timer = setInterval(function() {
        count++
        if (count >= options.totalTimes) {
            clearInterval(timer);
            options.end()
        } else {
            options.loop()
        }
    }, options.time)
}

module.exports = {
  countdown,
  string2star,
  getLocaleDate,
  formatParam,
  URL,
  Is,
  Tools,
  Cookie,
  GUC: GB2312UnicodeConverter,
}
<|endoftext|>


<commit_before>/*global _ */

//
//
// Base NEUE Module that should be extended when creating other modules. It
// provides some common methods and organization so you don't have to a lot
// of busywork. See `_exampleModule.js` for an annotated example implementation.
//

//
// ## Features
//  - Handles initializing modules, including overriding default options if necessary.
//  - Provides a standard location to keep state information, views, templates, and events.
//  - Binds events in the Events object to the root element on initialization.
//  - Prepares any templates in the Templates object.
//
// ---------------------------------------------------------------------------------------------

(function($) {
  "use strict";

  // TODO: Perhaps move this to a general configuration file? Not sure if it makes sense here...
  // We configure Underscore templating to use brackets (Mustache-style) syntax.
  _.templateSettings = {
    evaluate:    /\{\{#([\s\S]+?)\}\}/g,            // {{# console.log("blah") }}
    interpolate: /\{\{[^#\{]([\s\S]+?)[^\}]\}\}/g,  // {{ title }}
    escape:      /\{\{\{([\s\S]+?)\}\}\}/g,         // {{{ title }}}
  };

  // We create the global NEUE namespace if it doesn"t already exist, and attach BaseModule to it.
  window.NEUE = window.NEUE || {};
  window.NEUE.BaseModule = {
    // The `initialized` variable will track if this module has been initialized yet.
    initialized: false,

    // #### Options ####
    //
    // We store options in the `Options` object. This is created by extending the `defaultOptions` object
    // with any options passed to the initialize method.
    Options: {},
    defaultOptions: {},

    // #### State ####
    //
    // `State` is a nice place to keep module state information. It has no special behavior.
    State: {},

    // #### Views ####
    //
    // `Views` is a nice place to keep your module's views. Views should be stored as references to jQuery objects.
    // The root element for your module (given in the constructor) is stored as `$el`.
    Views: {},

    // #### Templates ####
    // `Templates` stores your Underscore templates. Templates will be compiled during initialization so they can
    // be used at any point later. Syntax:
    //
    // ```javascript
    //  Templates: {
    //    templateName: "<selector>",
    //  }
    //
    // ```

    Templates: {},

    // #### Events ####
    // `Events` should be used to bind any DOM events your module needs. Events are bound to the root element (`$el`)
    // so that they don't have to be re-bound as subviews are added and removed from the DOM. Syntax:
    //
    // ```javascript
    // Events: {
    //   "<selector> <event>": "<handler>"
    // }
    // ```
    //
    Events: {},

    // #### Initialize ####
    // The `initialize` function calls Neue's base module initializer and then a custom initializer if there is one.
    // Once both have run, it sets the `initialized` variable to `true`.
    initialize: function(element, opts) {
      this._baseInitialize(element, opts);

      if (typeof this._initialize === "function") {
        this._initialize();
      }

      this.initialized = true;
    },

    // Just like in Backbone, we extend our modules from this base class.
    extend: function(extensions) {
      return _.extend(this, extensions);
    },

    // The base initialization method is run on all modules.
    _baseInitialize: function(element, opts) {
      var _this = this;

      // We take the element given in the constructor and set it as the base view element.
      this.Views.$el = element;
      this.$el = this.Views.$el; // shortcut!

      // We override default options with any settings passed during initialization:
      if ((typeof opts !== "undefined" && opts !== null)) {
        this.Options = $.extend({}, this.defaultOptions, opts);
      } else {
        this.Options = this.defaultOptions;
      }

      // We clear out the contents of the base view element, prepare our templates, and bind events.
      $(document).ready(function() {
        _this.$el.html("");
        _this._prepareTemplates();
        _this._bindEvents();
      });
    },

    // #### Bind Events ####
    // We iterate through the `Events` object and bind any events defined there to the root element.
    _bindEvents: function() {
      var rootElement = this.$el;
      var _this = this;

      _.each(this.Events, function(target, trigger) {
        var elementSelector = trigger.split(" ")[0];
        var eventType = trigger.split(" ")[1];

        rootElement.on(eventType, elementSelector, function(event) {
          event.preventDefault();
          _this[target]();
        });
      });
    },

    // #### Prepare Templates ####
    // We'll compile any templates into Underscore template functions.
    _prepareTemplates: function() {
      var _this = this;

      _.each(this.Templates, function(templateDOM, templateID) {
        _this.Templates[templateID] = _.template( $(templateDOM).html() );
      });
    }
  };

})(jQuery);
<commit_msg>Fixed extend method on BaseModule to properly clone BaseModule.<commit_after>/*global _ */

//
//
// Base NEUE Module that should be extended when creating other modules. It
// provides some common methods and organization so you don't have to a lot
// of busywork. See `_exampleModule.js` for an annotated example implementation.
//

//
// ## Features
//  - Handles initializing modules, including overriding default options if necessary.
//  - Provides a standard location to keep state information, views, templates, and events.
//  - Binds events in the Events object to the root element on initialization.
//  - Prepares any templates in the Templates object.
//
// ---------------------------------------------------------------------------------------------

(function($) {
  "use strict";

  // TODO: Perhaps move this to a general configuration file? Not sure if it makes sense here...
  // We configure Underscore templating to use brackets (Mustache-style) syntax.
  _.templateSettings = {
    evaluate:    /\{\{#([\s\S]+?)\}\}/g,            // {{# console.log("blah") }}
    interpolate: /\{\{[^#\{]([\s\S]+?)[^\}]\}\}/g,  // {{ title }}
    escape:      /\{\{\{([\s\S]+?)\}\}\}/g,         // {{{ title }}}
  };

  // We create the global NEUE namespace if it doesn"t already exist, and attach BaseModule to it.
  window.NEUE = window.NEUE || {};
  window.NEUE.BaseModule = {
    // The `initialized` variable will track if this module has been initialized yet.
    initialized: false,

    // #### Options ####
    //
    // We store options in the `Options` object. This is created by extending the `defaultOptions` object
    // with any options passed to the initialize method.
    Options: {},
    defaultOptions: {},

    // #### State ####
    //
    // `State` is a nice place to keep module state information. It has no special behavior.
    State: {},

    // #### Views ####
    //
    // `Views` is a nice place to keep your module's views. Views should be stored as references to jQuery objects.
    // The root element for your module (given in the constructor) is stored as `$el`.
    Views: {},

    // #### Templates ####
    // `Templates` stores your Underscore templates. Templates will be compiled during initialization so they can
    // be used at any point later. Syntax:
    //
    // ```javascript
    //  Templates: {
    //    templateName: "<selector>",
    //  }
    //
    // ```

    Templates: {},

    // #### Events ####
    // `Events` should be used to bind any DOM events your module needs. Events are bound to the root element (`$el`)
    // so that they don't have to be re-bound as subviews are added and removed from the DOM. Syntax:
    //
    // ```javascript
    // Events: {
    //   "<selector> <event>": "<handler>"
    // }
    // ```
    //
    Events: {},

    // #### Initialize ####
    // The `initialize` function calls Neue's base module initializer and then a custom initializer if there is one.
    // Once both have run, it sets the `initialized` variable to `true`.
    initialize: function(element, opts) {
      this._baseInitialize(element, opts);

      if (typeof this._initialize === "function") {
        this._initialize();
      }

      this.initialized = true;
    },

    // We extend our modules from this base class.
    extend: function(extensions) {
      var parent = this;
      var child = {};

      _.extend(child, parent, extensions);

      return child;
    },

    // The base initialization method is run on all modules.
    _baseInitialize: function(element, opts) {
      var _this = this;

      // We take the element given in the constructor and set it as the base view element.
      this.Views.$el = element;
      this.$el = this.Views.$el; // shortcut!

      // We override default options with any settings passed during initialization:
      if ((typeof opts !== "undefined" && opts !== null)) {
        this.Options = $.extend({}, this.defaultOptions, opts);
      } else {
        this.Options = this.defaultOptions;
      }

      // We clear out the contents of the base view element, prepare our templates, and bind events.
      $(document).ready(function() {
        _this.$el.html("");
        _this._prepareTemplates();
        _this._bindEvents();
      });
    },

    // #### Bind Events ####
    // We iterate through the `Events` object and bind any events defined there to the root element.
    _bindEvents: function() {
      var rootElement = this.$el;
      var _this = this;

      _.each(this.Events, function(target, trigger) {
        var elementSelector = trigger.split(" ")[0];
        var eventType = trigger.split(" ")[1];

        rootElement.on(eventType, elementSelector, function(event) {
          event.preventDefault();
          _this[target]();
        });
      });
    },

    // #### Prepare Templates ####
    // We'll compile any templates into Underscore template functions.
    _prepareTemplates: function() {
      var _this = this;

      _.each(this.Templates, function(templateDOM, templateID) {
        _this.Templates[templateID] = _.template( $(templateDOM).html() );
      });
    }
  };

})(jQuery);
<|endoftext|>


<commit_before>// Copyright 2017-2018, University of Colorado Boulder

/**
 * IO type for Checkbox
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var NodeIO = require( 'SCENERY/nodes/NodeIO' );

  // phet-io modules
  var assertInstanceOf = require( 'ifphetio!PHET_IO/assertInstanceOf' );
  var BooleanIO = require( 'ifphetio!PHET_IO/types/BooleanIO' );
  var FunctionIO = require( 'ifphetio!PHET_IO/types/FunctionIO' );
  var phetioInherit = require( 'ifphetio!PHET_IO/phetioInherit' );
  var sun = require( 'SUN/sun' );
  var VoidIO = require( 'ifphetio!PHET_IO/types/VoidIO' );

  /**
   * @param {Checkbox} checkbox
   * @param {string} phetioID
   * @constructor
   */
  function CheckboxIO( checkbox, phetioID ) {
    assert && assertInstanceOf( checkbox, phet.sun.Checkbox );
    NodeIO.call( this, checkbox, phetioID );
  }

  phetioInherit( NodeIO, 'CheckboxIO', CheckboxIO, {

    link: {
      returnType: VoidIO,
      parameterTypes: [ FunctionIO( VoidIO, [ BooleanIO ] ) ],
      implementation: function( listener ) {
        this.instance.checkboxValueProperty.link( listener );
      },
      documentation: 'Link a listener to the underlying checked PropertyIO.  The listener receives an immediate callback ' +
                     'with the current value (true/false)'
    },

    setChecked: {
      returnType: VoidIO,
      parameterTypes: [ BooleanIO ],
      implementation: function( checked ) {
        this.instance.checkboxValueProperty.set( checked );
      },
      documentation: 'Sets whether the checkbox is checked or not'
    },

    isChecked: {
      returnType: BooleanIO,
      parameterTypes: [],
      implementation: function() {
        return this.instance.checkboxValueProperty.get();
      },
      documentation: 'Returns true if the checkbox is checked, false otherwise'
    }
  }, {
    documentation: 'A traditional checkbox',
    events: [ 'toggled' ]
  } );

  sun.register( 'CheckboxIO', CheckboxIO );

  return CheckboxIO;
} );

<commit_msg>Added docs, see https://github.com/phetsims/faradays-law/issues/85<commit_after>// Copyright 2017-2018, University of Colorado Boulder

/**
 * IO type for Checkbox
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var NodeIO = require( 'SCENERY/nodes/NodeIO' );

  // phet-io modules
  var assertInstanceOf = require( 'ifphetio!PHET_IO/assertInstanceOf' );
  var BooleanIO = require( 'ifphetio!PHET_IO/types/BooleanIO' );
  var FunctionIO = require( 'ifphetio!PHET_IO/types/FunctionIO' );
  var phetioInherit = require( 'ifphetio!PHET_IO/phetioInherit' );
  var sun = require( 'SUN/sun' );
  var VoidIO = require( 'ifphetio!PHET_IO/types/VoidIO' );

  /**
   * @param {Checkbox} checkbox
   * @param {string} phetioID
   * @constructor
   */
  function CheckboxIO( checkbox, phetioID ) {
    assert && assertInstanceOf( checkbox, phet.sun.Checkbox );
    NodeIO.call( this, checkbox, phetioID );
  }

  phetioInherit( NodeIO, 'CheckboxIO', CheckboxIO, {

    link: {
      returnType: VoidIO,
      parameterTypes: [ FunctionIO( VoidIO, [ BooleanIO ] ) ],
      implementation: function( listener ) {
        this.instance.checkboxValueProperty.link( listener );
      },
      documentation: 'Link a listener to the underlying checked PropertyIO.  The listener receives an immediate callback ' +
                     'with the current value (true/false)'
    },

    setChecked: {
      returnType: VoidIO,
      parameterTypes: [ BooleanIO ],
      implementation: function( checked ) {
        this.instance.checkboxValueProperty.set( checked );
      },
      documentation: 'Sets whether the checkbox is checked or not'
    },

    isChecked: {
      returnType: BooleanIO,
      parameterTypes: [],
      implementation: function() {
        return this.instance.checkboxValueProperty.get();
      },
      documentation: 'Returns true if the checkbox is checked, false otherwise'
    }
  }, {
    documentation: 'A user interface component that shows if something is selected (checked) or unselected (unchecked)',
    events: [ 'toggled' ]
  } );

  sun.register( 'CheckboxIO', CheckboxIO );

  return CheckboxIO;
} );
<|endoftext|>