<commit_before>var app = angular.module('InventoryApp', [
	'ngRoute',
	'ngAnimate',
	'ngAnimate-animate.css',
	'restangular'
]);

app.constant('djurl', __djurls);

app.config(['djurl', '$routeProvider', '$httpProvider', 'RestangularProvider', function(djurl, $routeProvider, $httpProvider, RestangularProvider) {
	RestangularProvider.setResponseExtractor(function(response, operation, what, url) {
		if (operation === "getList") {
			// Use results as the return type, and save the result metadata
			// in _resultmeta
			if (!response.results) return response;
			var newResponse = response.results;
			newResponse._resultmeta = {
				"count": response.count,
				"next": response.next,
				"previous": response.previous,
			};
			return newResponse;
		}

		return response;
	});
	RestangularProvider.setBaseUrl(djurl.api_root);
	RestangularProvider.setRequestSuffix('/');
	RestangularProvider.setRestangularFields({
		selfLink: 'url'
	});
	$routeProvider.
		when('/', {
			templateUrl: djurl.partial_root + 'index.html',
			controller: 'IndexCtrl'
		}).
		when('/item', {
			templateUrl: djurl.partial_root + 'items.html',
			controller: 'ItemsCtrl'
		}).
    	when('/item/add', {
			templateUrl: djurl.partial_root + 'additem.html',
			controller: 'ItemAddCtrl'
		}).
		when('/item/:id', {
			templateUrl: djurl.partial_root + 'item.html',
			controller: 'ItemCtrl'
		}).
        when('/supplier', {
            templateUrl: djurl.partial_root + 'suppliers.html',
            controller: 'SuppliersCtrl'
        }).
	    otherwise({
			redirectTo: '/'
		});
	$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
	$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
	$httpProvider.defaults.xsrfCookieName = 'csrftoken';
}]);

app.directive('ngConfirmClick', [
  function(){
    return {
      priority: -1,
      restrict: 'A',
      link: function(scope, element, attrs){
        element.bind('click', function(e){
          var message = attrs.ngConfirmClick;
          if(message && !confirm(message)){
            e.stopImmediatePropagation();
            e.preventDefault();
          }
        });
      }
    }
  }
]);
app.directive('tabs', function() {
	return {
		restrict: 'E',
		scope: {},
		transclude: true,
		template: '

{{ pane.tabTitle }}

',
		controller: function($scope) {
			var panes = $scope.panes = [];
			$scope.select = function(pane) {
				angular.forEach(panes, function(pane) {
					pane.active = false;
				});
				pane.active = true;
			};
			this.addPane = function(pane) {
				if (panes.length == 0) {
					$scope.select(pane);
				}
				panes.push(pane);
			};
			$scope.$parent.panes = {
				panes: $scope.panes,
				select: $scope.select
			};
		}
	}
});
app.directive('tab', function() {
	return {
		restrict: 'E',
		scope: {
			tabTitle: '@'
		},
		transclude: true,
		template: '

',
		require: '^tabs',
		link: function(scope, element, attrs, tabsCtrl) {
			tabsCtrl.addPane(scope);
		}
	}
});

app.controller('AppCtrl', function($scope) {
	$scope.hBack = function() {
		window.history.go(-1);
	};
});
app.controller('NavCtrl', function($scope) {
	$scope.navs = [
/*
		{
			'name': 'index',
			'url': '/',
			'text': 'Index'
		},
*/
		{
			'name': 'item',
			'url': '/item',
			'text': 'List Inventory Items'
		},
        {
            'name': 'additem',
            'url': '/item/add',
            'text': 'Add Inventory Item'
        },
        {
            'name': 'supplier',
            'url': '/supplier',
            'text': 'Manage Suppliers'
        },
	];

	$scope.navActive = function(navName) {
		if ($scope.navName == navName) return 'active';
		return '';
	}
});
app.controller('IndexCtrl', function($rootScope) {
	$rootScope.navName = 'index';
});
app.controller('ItemsCtrl', function($rootScope, $scope, $routeParams, $location, Restangular) {
	$rootScope.navName = 'item';

	var thisPage = parseInt($routeParams.page, 10);
	if (thisPage != $routeParams.page) {
		$location.search('page', 1);
		return;
	}

	var perPage = parseInt($routeParams.perPage, 10);
	if (isNaN(perPage) || perPage < 5) {
		perPage = 10;
	}
	var sobj = {
		page: thisPage,
		per_page: perPage
	};

	var items = Restangular.all('item');
	var updateItemData = function() {
        	items.getList(sobj).then(function(res) {
			var startRecord = ((thisPage-1) * perPage) + 1;
			var endRecord = (startRecord + res.length) - 1;
			$scope.data = {
				'startAt': startRecord,
				'endAt': endRecord,
				'results': res,
				'next': (res._resultmeta.next ? thisPage+1 : null),
				'previous': (res._resultmeta.previous ? thisPage-1 : null),
				'count': res._resultmeta.count
			}
		});
	};
	updateItemData();

	$scope.search = function(q) {
		sobj.search = q;
		updateItemData();
	};

	$scope.goTo = function(where) {
		if (!where) return;
		$location.search('page', where);
	};

	$scope.buttonClass = function(pageNum) {
		if (!pageNum) return 'default';
		return 'secondary';
	};

	$scope.itemUrl = function(item) {
		return '#/item/' + item.id;
	};
});
app.controller('ItemCtrl', function($rootScope, $scope, $filter, $routeParams, $location, Restangular, $timeout) {
	$rootScope.navName = 'item';

	$scope.loading = true;
    $scope.editing = false;

	var itemId = parseInt($routeParams.id, 10);

	var item = Restangular.one('item', itemId);
	item.get().then(function(res) {
		$scope.loading = false;
		$scope.data = res;
	});
    var updateNotesData = function() {
        item.getList('notes').then(function(res) {
            $scope.notes = res;
        });
    };
    updateNotesData();
    item.getList('pictures').then(function(res) {
		$scope.pictures = res;
	});
    item.getList('quotes').then(function(res) {
		$scope.quotes = res;
	});

    var suppliers = Restangular.all('supplier');
    suppliers.getList().then(function(res) {
        $scope.suppliers = res;
    });

    var itemCategories = Restangular.all('itemcategory');
    itemCategories.getList().then(function(res) {
        $scope.itemCategories = res;
    });

    var itemStatuses = Restangular.all('itemstatus');
    itemStatuses.getList().then(function(res) {
        $scope.itemStatuses = res;
    });

    var itemOwners = Restangular.all('itemowner');
    itemOwners.getList().then(function(res) {
        $scope.itemOwners = res;
    });

    var itemResponsiblePositions = Restangular.all('itemresponsibleposition');
    itemResponsiblePositions.getList().then(function(res) {
        $scope.itemResponsiblePositions = res;
    });

    var itemHomes = Restangular.all('itemhome');
    itemHomes.getList().then(function(res) {
        $scope.itemHomes = res;
    });

    $scope.edit = function() {
        $scope.edit_data = Restangular.copy($scope.data);
        $scope.edit_data.purchase_date = $filter('date')($scope.edit_data.purchase_date, "dd/MM/yyyy");
        $scope.edit_data.supplier = $scope.edit_data.supplier.url;
        $scope.edit_data.category = $scope.edit_data.category.url;
        $scope.edit_data.status = $scope.edit_data.status.url;
        $scope.edit_data.owner = $scope.edit_data.owner.url;
        $scope.edit_data.responsible_position = $scope.edit_data.responsible_position.url;
        $scope.edit_data.home = $scope.edit_data.home.url;
        $scope.editing = true;
    };

    $scope.cancelEdit = function() {
        $scope.editing = false;
    };

    function retrieveObject(list, url) {
        for (i=0; i < list.length; i++) {
            if (list[i].url == url) {
                return list[i];
            }
        }
    }

    $scope.saveEdit = function() {
        $scope.data = $scope.edit_data;
        $scope.data.purchase_date = moment($scope.data.purchase_date, "DD/MM/YYYY").format("YYYY-MM-DD");
        $scope.data.put();

        $scope.data.supplier = retrieveObject($scope.suppliers, $scope.data.supplier);
        $scope.data.category = retrieveObject($scope.itemCategories, $scope.data.category);
        $scope.data.status = retrieveObject($scope.itemStatuses, $scope.data.status);
        $scope.data.owner = retrieveObject($scope.itemOwners, $scope.data.owner);
        $scope.data.responsible_position = retrieveObject($scope.itemResponsiblePositions, $scope.data.responsible_position);
        $scope.data.home = retrieveObject($scope.itemHomes, $scope.data.home);

        $scope.editing = false;

    };

    $scope.addNote = function(note) {
        console.log("add called.");
        note.item = $scope.data.url;
        note.date_added = moment().format("YYYY-MM-DD");
        Restangular.all('itemnote').post(note).then(function() {
            updateNotesData();
            note.text = "";
        });
    };

});

app.controller('NoteCtrl', function($rootScope, $scope, $filter, $routeParams, $location, Restangular, $timeout) {

    $scope.editing = false;

    $scope.editNote = function (index) {
        $scope.edit_data = Restangular.copy($scope.notes[index]);
        $scope.editing = true;
    };

    $scope.cancelEditNote = function() {
        $scope.editing = false;
    };

    $scope.saveEditNote = function(index) {
        $scope.notes[index] = $scope.edit_data;
        $scope.notes[index].put();
        $scope.editing = false;
    };

});

app.controller('ItemAddCtrl', function($rootScope, $scope, Restangular, $location) {

    $rootScope.navName = 'additem';
    $scope.loading = true;

    var suppliers = Restangular.all('supplier');
    suppliers.getList().then(function(res) {
        $scope.suppliers = res;
    });

    var itemCategories = Restangular.all('itemcategory');
    itemCategories.getList().then(function(res) {
        $scope.itemCategories = res;
    });

    var itemStatuses = Restangular.all('itemstatus');
    itemStatuses.getList().then(function(res) {
        $scope.itemStatuses = res;
    });

    var itemOwners = Restangular.all('itemowner');
    itemOwners.getList().then(function(res) {
        $scope.itemOwners = res;
    });

    var itemResponsiblePositions = Restangular.all('itemresponsibleposition');
    itemResponsiblePositions.getList().then(function(res) {
        $scope.itemResponsiblePositions = res;
    });

    var itemHomes = Restangular.all('itemhome');
    itemHomes.getList().then(function(res) {
        $scope.itemHomes = res;
    });

    $scope.loading = false;

    $scope.add = function(item) {
        item.purchase_date = moment(item.purchase_date, "DD/MM/YYYY").format("YYYY-MM-DD");
        Restangular.all('item').post(item).then(function(response) {
            console.log("Saved Item");
            $location.path("/item/"+response.id);
        });
    };

});

app.controller('SuppliersCtrl', function($rootScope, $scope, $routeParams, $location, Restangular) {

    $rootScope.navName = 'supplier';

	var thisPage = parseInt($routeParams.page, 10);
	if (thisPage != $routeParams.page) {
		$location.search('page', 1);
		return;
	}

	var perPage = parseInt($routeParams.perPage, 10);
	if (isNaN(perPage) || perPage < 5) {
		perPage = 10;
	}
	var sobj = {
		page: thisPage,
		per_page: perPage
	};

	suppliers = Restangular.all('supplier');
	var updateSupplierData = function() {
        suppliers.getList(sobj).then(function(res) {
            var startRecord = ((thisPage-1) * perPage) + 1;
            var endRecord = (startRecord + res.length) - 1;
            $scope.data = {
                'startAt': startRecord,
                'endAt': endRecord,
                'results': res,
                'next': (res._resultmeta.next ? thisPage+1 : null),
                'previous': (res._resultmeta.previous ? thisPage-1 : null),
                'count': res._resultmeta.count
            }
        });
    };
	updateSupplierData();

	$scope.search = function(q) {
		sobj.search = q;
		updateSupplierData();
	};

	$scope.goTo = function(where) {
		if (!where) return;
		$location.search('page', where);
	};

	$scope.buttonClass = function(pageNum) {
		if (!pageNum) return 'default';
		return 'secondary';
	};

    $scope.addSupplier = function(supplier) {
        console.log("add called.");
        Restangular.all('supplier').post(supplier).then(function() {
            updateSupplierData();
            supplier.name = "";
            supplier.url = "";
        });
    };

});

app.controller('SupplierCtrl', function($rootScope, $scope, $filter, $routeParams, $location, Restangular, $timeout) {

    $scope.editing = false;

    $scope.editSupplier = function (index) {
        $scope.edit_data = Restangular.copy($scope.data.results[index]);
        $scope.editing = true;
    };

    $scope.cancelEditSupplier = function() {
        $scope.editing = false;
    };

    $scope.saveEditSupplier = function(index) {
        $scope.data.results[index] = $scope.edit_data;
        $scope.data.results[index].put();
        $scope.editing = false;
    };

});

<commit_msg>Make js cope with null date fields in forms.<commit_after>var app = angular.module('InventoryApp', [
	'ngRoute',
	'ngAnimate',
	'ngAnimate-animate.css',
	'restangular'
]);

app.constant('djurl', __djurls);

app.config(['djurl', '$routeProvider', '$httpProvider', 'RestangularProvider', function(djurl, $routeProvider, $httpProvider, RestangularProvider) {
	RestangularProvider.setResponseExtractor(function(response, operation, what, url) {
		if (operation === "getList") {
			// Use results as the return type, and save the result metadata
			// in _resultmeta
			if (!response.results) return response;
			var newResponse = response.results;
			newResponse._resultmeta = {
				"count": response.count,
				"next": response.next,
				"previous": response.previous,
			};
			return newResponse;
		}

		return response;
	});
	RestangularProvider.setBaseUrl(djurl.api_root);
	RestangularProvider.setRequestSuffix('/');
	RestangularProvider.setRestangularFields({
		selfLink: 'url'
	});
	$routeProvider.
		when('/', {
			templateUrl: djurl.partial_root + 'index.html',
			controller: 'IndexCtrl'
		}).
		when('/item', {
			templateUrl: djurl.partial_root + 'items.html',
			controller: 'ItemsCtrl'
		}).
    	when('/item/add', {
			templateUrl: djurl.partial_root + 'additem.html',
			controller: 'ItemAddCtrl'
		}).
		when('/item/:id', {
			templateUrl: djurl.partial_root + 'item.html',
			controller: 'ItemCtrl'
		}).
        when('/supplier', {
            templateUrl: djurl.partial_root + 'suppliers.html',
            controller: 'SuppliersCtrl'
        }).
	    otherwise({
			redirectTo: '/'
		});
	$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
	$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
	$httpProvider.defaults.xsrfCookieName = 'csrftoken';
}]);

app.directive('ngConfirmClick', [
  function(){
    return {
      priority: -1,
      restrict: 'A',
      link: function(scope, element, attrs){
        element.bind('click', function(e){
          var message = attrs.ngConfirmClick;
          if(message && !confirm(message)){
            e.stopImmediatePropagation();
            e.preventDefault();
          }
        });
      }
    }
  }
]);
app.directive('tabs', function() {
	return {
		restrict: 'E',
		scope: {},
		transclude: true,
		template: '

{{ pane.tabTitle }}

',
		controller: function($scope) {
			var panes = $scope.panes = [];
			$scope.select = function(pane) {
				angular.forEach(panes, function(pane) {
					pane.active = false;
				});
				pane.active = true;
			};
			this.addPane = function(pane) {
				if (panes.length == 0) {
					$scope.select(pane);
				}
				panes.push(pane);
			};
			$scope.$parent.panes = {
				panes: $scope.panes,
				select: $scope.select
			};
		}
	}
});
app.directive('tab', function() {
	return {
		restrict: 'E',
		scope: {
			tabTitle: '@'
		},
		transclude: true,
		template: '

',
		require: '^tabs',
		link: function(scope, element, attrs, tabsCtrl) {
			tabsCtrl.addPane(scope);
		}
	}
});

app.controller('AppCtrl', function($scope) {
	$scope.hBack = function() {
		window.history.go(-1);
	};
});
app.controller('NavCtrl', function($scope) {
	$scope.navs = [
/*
		{
			'name': 'index',
			'url': '/',
			'text': 'Index'
		},
*/
		{
			'name': 'item',
			'url': '/item',
			'text': 'List Inventory Items'
		},
        {
            'name': 'additem',
            'url': '/item/add',
            'text': 'Add Inventory Item'
        },
        {
            'name': 'supplier',
            'url': '/supplier',
            'text': 'Manage Suppliers'
        },
	];

	$scope.navActive = function(navName) {
		if ($scope.navName == navName) return 'active';
		return '';
	}
});
app.controller('IndexCtrl', function($rootScope) {
	$rootScope.navName = 'index';
});
app.controller('ItemsCtrl', function($rootScope, $scope, $routeParams, $location, Restangular) {
	$rootScope.navName = 'item';

	var thisPage = parseInt($routeParams.page, 10);
	if (thisPage != $routeParams.page) {
		$location.search('page', 1);
		return;
	}

	var perPage = parseInt($routeParams.perPage, 10);
	if (isNaN(perPage) || perPage < 5) {
		perPage = 10;
	}
	var sobj = {
		page: thisPage,
		per_page: perPage
	};

	var items = Restangular.all('item');
	var updateItemData = function() {
        	items.getList(sobj).then(function(res) {
			var startRecord = ((thisPage-1) * perPage) + 1;
			var endRecord = (startRecord + res.length) - 1;
			$scope.data = {
				'startAt': startRecord,
				'endAt': endRecord,
				'results': res,
				'next': (res._resultmeta.next ? thisPage+1 : null),
				'previous': (res._resultmeta.previous ? thisPage-1 : null),
				'count': res._resultmeta.count
			}
		});
	};
	updateItemData();

	$scope.search = function(q) {
		sobj.search = q;
		updateItemData();
	};

	$scope.goTo = function(where) {
		if (!where) return;
		$location.search('page', where);
	};

	$scope.buttonClass = function(pageNum) {
		if (!pageNum) return 'default';
		return 'secondary';
	};

	$scope.itemUrl = function(item) {
		return '#/item/' + item.id;
	};
});
app.controller('ItemCtrl', function($rootScope, $scope, $filter, $routeParams, $location, Restangular, $timeout) {
	$rootScope.navName = 'item';

	$scope.loading = true;
    $scope.editing = false;

	var itemId = parseInt($routeParams.id, 10);

	var item = Restangular.one('item', itemId);
	item.get().then(function(res) {
		$scope.loading = false;
		$scope.data = res;
	});
    var updateNotesData = function() {
        item.getList('notes').then(function(res) {
            $scope.notes = res;
        });
    };
    updateNotesData();
    item.getList('pictures').then(function(res) {
		$scope.pictures = res;
	});
    item.getList('quotes').then(function(res) {
		$scope.quotes = res;
	});

    var suppliers = Restangular.all('supplier');
    suppliers.getList().then(function(res) {
        $scope.suppliers = res;
    });

    var itemCategories = Restangular.all('itemcategory');
    itemCategories.getList().then(function(res) {
        $scope.itemCategories = res;
    });

    var itemStatuses = Restangular.all('itemstatus');
    itemStatuses.getList().then(function(res) {
        $scope.itemStatuses = res;
    });

    var itemOwners = Restangular.all('itemowner');
    itemOwners.getList().then(function(res) {
        $scope.itemOwners = res;
    });

    var itemResponsiblePositions = Restangular.all('itemresponsibleposition');
    itemResponsiblePositions.getList().then(function(res) {
        $scope.itemResponsiblePositions = res;
    });

    var itemHomes = Restangular.all('itemhome');
    itemHomes.getList().then(function(res) {
        $scope.itemHomes = res;
    });

    $scope.edit = function() {
        $scope.edit_data = Restangular.copy($scope.data);
        $scope.edit_data.purchase_date = $filter('date')($scope.edit_data.purchase_date, "dd/MM/yyyy");
        $scope.edit_data.supplier = $scope.edit_data.supplier.url;
        $scope.edit_data.category = $scope.edit_data.category.url;
        $scope.edit_data.status = $scope.edit_data.status.url;
        $scope.edit_data.owner = $scope.edit_data.owner.url;
        $scope.edit_data.responsible_position = $scope.edit_data.responsible_position.url;
        $scope.edit_data.home = $scope.edit_data.home.url;
        $scope.editing = true;
    };

    $scope.cancelEdit = function() {
        $scope.editing = false;
    };

    function retrieveObject(list, url) {
        for (i=0; i < list.length; i++) {
            if (list[i].url == url) {
                return list[i];
            }
        }
    }

    $scope.saveEdit = function() {
        $scope.data = $scope.edit_data;
        $scope.data.purchase_date = moment($scope.data.purchase_date, "DD/MM/YYYY").format("YYYY-MM-DD");
        if ($scope.data.purchase_date == "Invalid date") {
            $scope.data.purchase_date = "";
        }
        $scope.data.put();

        $scope.data.supplier = retrieveObject($scope.suppliers, $scope.data.supplier);
        $scope.data.category = retrieveObject($scope.itemCategories, $scope.data.category);
        $scope.data.status = retrieveObject($scope.itemStatuses, $scope.data.status);
        $scope.data.owner = retrieveObject($scope.itemOwners, $scope.data.owner);
        $scope.data.responsible_position = retrieveObject($scope.itemResponsiblePositions, $scope.data.responsible_position);
        $scope.data.home = retrieveObject($scope.itemHomes, $scope.data.home);

        $scope.editing = false;

    };

    $scope.addNote = function(note) {
        console.log("add called.");
        note.item = $scope.data.url;
        note.date_added = moment().format("YYYY-MM-DD");
        Restangular.all('itemnote').post(note).then(function() {
            updateNotesData();
            note.text = "";
        });
    };

});

app.controller('NoteCtrl', function($rootScope, $scope, $filter, $routeParams, $location, Restangular, $timeout) {

    $scope.editing = false;

    $scope.editNote = function (index) {
        $scope.edit_data = Restangular.copy($scope.notes[index]);
        $scope.editing = true;
    };

    $scope.cancelEditNote = function() {
        $scope.editing = false;
    };

    $scope.saveEditNote = function(index) {
        $scope.notes[index] = $scope.edit_data;
        $scope.notes[index].put();
        $scope.editing = false;
    };

});

app.controller('ItemAddCtrl', function($rootScope, $scope, Restangular, $location) {

    $rootScope.navName = 'additem';
    $scope.loading = true;

    var suppliers = Restangular.all('supplier');
    suppliers.getList().then(function(res) {
        $scope.suppliers = res;
    });

    var itemCategories = Restangular.all('itemcategory');
    itemCategories.getList().then(function(res) {
        $scope.itemCategories = res;
    });

    var itemStatuses = Restangular.all('itemstatus');
    itemStatuses.getList().then(function(res) {
        $scope.itemStatuses = res;
    });

    var itemOwners = Restangular.all('itemowner');
    itemOwners.getList().then(function(res) {
        $scope.itemOwners = res;
    });

    var itemResponsiblePositions = Restangular.all('itemresponsibleposition');
    itemResponsiblePositions.getList().then(function(res) {
        $scope.itemResponsiblePositions = res;
    });

    var itemHomes = Restangular.all('itemhome');
    itemHomes.getList().then(function(res) {
        $scope.itemHomes = res;
    });

    $scope.loading = false;

    $scope.add = function(item) {
        item.purchase_date = moment(item.purchase_date, "DD/MM/YYYY").format("YYYY-MM-DD");
        if (item.purchase_date == "Invalid date") {
            console.log("Invalid Date Entered.");
            item.purchase_date = "";
        }
        Restangular.all('item').post(item).then(function(response) {
            console.log("Saved Item");
            $location.path("/item/"+response.id);
        });
    };

});

app.controller('SuppliersCtrl', function($rootScope, $scope, $routeParams, $location, Restangular) {

    $rootScope.navName = 'supplier';

	var thisPage = parseInt($routeParams.page, 10);
	if (thisPage != $routeParams.page) {
		$location.search('page', 1);
		return;
	}

	var perPage = parseInt($routeParams.perPage, 10);
	if (isNaN(perPage) || perPage < 5) {
		perPage = 10;
	}
	var sobj = {
		page: thisPage,
		per_page: perPage
	};

	suppliers = Restangular.all('supplier');
	var updateSupplierData = function() {
        suppliers.getList(sobj).then(function(res) {
            var startRecord = ((thisPage-1) * perPage) + 1;
            var endRecord = (startRecord + res.length) - 1;
            $scope.data = {
                'startAt': startRecord,
                'endAt': endRecord,
                'results': res,
                'next': (res._resultmeta.next ? thisPage+1 : null),
                'previous': (res._resultmeta.previous ? thisPage-1 : null),
                'count': res._resultmeta.count
            }
        });
    };
	updateSupplierData();

	$scope.search = function(q) {
		sobj.search = q;
		updateSupplierData();
	};

	$scope.goTo = function(where) {
		if (!where) return;
		$location.search('page', where);
	};

	$scope.buttonClass = function(pageNum) {
		if (!pageNum) return 'default';
		return 'secondary';
	};

    $scope.addSupplier = function(supplier) {
        console.log("add called.");
        Restangular.all('supplier').post(supplier).then(function() {
            updateSupplierData();
            supplier.name = "";
            supplier.url = "";
        });
    };

});

app.controller('SupplierCtrl', function($rootScope, $scope, $filter, $routeParams, $location, Restangular, $timeout) {

    $scope.editing = false;

    $scope.editSupplier = function (index) {
        $scope.edit_data = Restangular.copy($scope.data.results[index]);
        $scope.editing = true;
    };

    $scope.cancelEditSupplier = function() {
        $scope.editing = false;
    };

    $scope.saveEditSupplier = function(index) {
        $scope.data.results[index] = $scope.edit_data;
        $scope.data.results[index].put();
        $scope.editing = false;
    };

});

<|endoftext|>


<commit_before>YUI.add("passbox", function (Y) {

    // Fires pressed button name (pass, x, xx)
    var PassBox = Y.Base.create("passbox", Y.ButtonGroup, [], {

        renderUI: function () {
            this._renderPassBox();
        },

        _renderPassBox: function () {
            this.add([
                { label: "Pass", name: "pass" },
                { label: "Dbl", name: "x" },
                { label: "Rdbl", name: "xx" }
            ]);
        },

        syncUI: function () {
            this._syncEnabledButtons(this.get("enabledButtons"));
        },

        _syncEnabledButtons: function (enabledButtons) {
            this.each(function (button) {
                button.set("enabled", enabledButtons[button.get("name")]);
            });
        },

        bindUI: function () {
            this.after("button:press", this._afterButtonPress);
            this.after("enabledButtonsChange", this._afterEnabledButtonsChange);
        },

        _afterButtonPress: function (event) {
            this.fire(event.target.get("name"));
        },

        _afterEnabledButtonsChange: function (event) {
            this._syncEnabledButtons(event.newVal);
        }

    }, {

        NAME: "passbox",

        ATTRS: {

            defaultChildType: {
                value: Y.Button
            },

            label: {
                value: ""
            },

            enabledButtons: {
                value: {
                    pass: true,
                    x: false,
                    xx: true
                }
            }

        }

    });

    Y.namespace("Bridge").PassBox = PassBox;

}, "0", { requires: ["gallery-button", "gallery-button-group"] });
<commit_msg>removed NAME property - it's added automatically by Y.Base.create<commit_after>YUI.add("passbox", function (Y) {

    // Fires pressed button name (pass, x, xx)
    var PassBox = Y.Base.create("passbox", Y.ButtonGroup, [], {

        renderUI: function () {
            this._renderPassBox();
        },

        _renderPassBox: function () {
            this.add([
                { label: "Pass", name: "pass" },
                { label: "Dbl", name: "x" },
                { label: "Rdbl", name: "xx" }
            ]);
        },

        syncUI: function () {
            this._syncEnabledButtons(this.get("enabledButtons"));
        },

        _syncEnabledButtons: function (enabledButtons) {
            this.each(function (button) {
                button.set("enabled", enabledButtons[button.get("name")]);
            });
        },

        bindUI: function () {
            this.after("button:press", this._afterButtonPress);
            this.after("enabledButtonsChange", this._afterEnabledButtonsChange);
        },

        _afterButtonPress: function (event) {
            this.fire(event.target.get("name"));
        },

        _afterEnabledButtonsChange: function (event) {
            this._syncEnabledButtons(event.newVal);
        }

    }, {

        ATTRS: {

            defaultChildType: {
                value: Y.Button
            },

            label: {
                value: ""
            },

            enabledButtons: {
                value: {
                    pass: true,
                    x: false,
                    xx: true
                }
            }

        }

    });

    Y.namespace("Bridge").PassBox = PassBox;

}, "0", { requires: ["gallery-button", "gallery-button-group"] });
<|endoftext|>


<commit_before>var simulationMode = false;
var debugMode = false;
var spriteWidth = 400;
var spriteHeight = 300;
var canvasWidth = 1000;
var canvasHeight = 300;
var junior = false;

var repeatTime = 5;
var version2 = true; //even though idon't want  to render content, 2.0 is different from 1.0 (think of dialog that triggers)
var curSessionGlobalVar;

//have EVERYTHING be a scene, don't put any story in v2.0's controller
//every scene can update the narration, or the canvas.
//should there be only one canvas?  Can have player sprites be written to a virtual canvas first, then copied to main one.
//main canvas is either Leader + PesterChumWindow + 1 or more Players (in chat or group chat with leader)
//or Leader + 1 or more Players  (leader doing bullshit side quests with someone)
window.onload = function() {
	//these bitches are SHAREABLE.
	setTimeout(function() {window.scrollTo(0, 0);},1)
	loadNavbar();
	if(getParameterByName("seed")){
		Math.seed = getParameterByName("seed");
		initial_seed = getParameterByName("seed");
	}else{
		var tmp = getRandomSeed();
		Math.seed = tmp;
		initial_seed = tmp;
	}

	shareableURL();

	startSession();

	//intro();  //~~~~~~LOADING SCRIPT WILL CALL THIS~~~~~~~~~

	//debugRelationshipDrama();
	//debugTriggerLevel();
	//debugGrimDark();
	//debugJackScheme();
	//debugLevelTheHellUp();
	//debugGodTierLevelTheHellUp();
	//debugCorpseLevelTheHellUp();
	//debugGodTierRevive();
	//debugCorpseSmooch();
}

function reinit(){
	available_classes = classes.slice(0);
	available_aspects = nonrequired_aspects.slice(0); //required_aspects
	available_aspects = available_aspects.concat(required_aspects.slice(0));

	curSessionGlobalVar.reinit();
}

function startSession(){
	curSessionGlobalVar = new Session(initial_seed)
	reinit();
	createScenesForSession(curSessionGlobalVar);
	//initPlayersRandomness();
	curSessionGlobalVar.makePlayers();
	curSessionGlobalVar.randomizeEntryOrder();
	//authorMessage();
	curSessionGlobalVar.makeGuardians(); //after entry order established
	//easter egg ^_^
	if(getParameterByName("royalRumble")  == "true"){
		debugRoyalRumble();
	}

	if(getParameterByName("COOLK1D")  == "true"){
		cool_kid = true;
		coolK1DMode();
	}

	if(getParameterByName("lollipop")  == "true"){
		tricksterMode();
	}
	//void is in navbar code

	if(getParameterByName("robot")  == "true"){
		roboMode();
	}

	if(getParameterByName("sbajifier")  == "true"){
		sbahjMode();
	}

	if(getParameterByName("babyStuck")  == "true"){
		babyStuckMode();
	}

	checkEasterEgg();
	initializePlayers(curSessionGlobalVar.players); //will take care of overriding players if need be.
	checkEasterEgg();
	checkSGRUB();

	load(curSessionGlobalVar.players, curSessionGlobalVar.guardians); //in loading.js
}

function shareableURL(){
	var params = window.location.href.substr(window.location.href.indexOf("?")+1)
	if (params == window.location.href) params = ""
	var str = '
Shareable URL  &nbsp&nbsp&nbsp&nbsp &nbsp&nbsp&nbsp&nbsp Replay Session (Mildly Fucking Alpha)  &nbsp&nbsp&nbsp&nbsp &nbsp&nbsp&nbsp&nbspRandom Session URL
'
	$("#seedText").html(str);
}

function checkSGRUB(){
	for(var i = 0; i<curSessionGlobalVar.players.length; i++){
		if(curSessionGlobalVar.players[i].isTroll == false){
			return;
		}
	}
	//can only get here if all are trolls.
	$(document).attr("title", "SGRUB Story Generator by jadedResearcher");
	$("#heading").html("SGRUB Story Generator by jadedResearcher (art assistance by karmicRetribution) ");
}

function getSessionType(){
	if(sessionType > .6){
		return "Human"
	}else if(sessionType > .3){
		return "Troll"
	}
	return "Mixed"
}

function renderScratchButton(session){
	var timePlayer = findAspectPlayer(curSessionGlobalVar.players, "Time")
	if(!timePlayer) throw "CAN'T SCRATCH WITHOUT A TIME PLAYER, JACKASS"
	console.log("scratch possible, button");
	//alert("scratch [possible]");
	//can't scratch if it was a a total party wipe. just a regular doomed timeline.
	var living = findLivingPlayers(session.players);
	if(living.length > 0 && (session.makeCombinedSession == false && session.hadCombinedSession == false)){
		console.log("gonna render scratch")
		var timePlayer = findAspectPlayer(session.players, "Time");
		if(!session.scratched){
			//this is apparently spoilery.
			//alert(living.length  + " living players and the " + timePlayer.land + " makes a scratch available!");
			if(session.scratchAvailable){
				var html = '
Click To Scratch Session?';
				$("#story").append(html);
				renderAfterlifeURL();
			}
		}else{
			console.log("no more scratches")
			$("#story").append("
This session is already scratched. No further scratches available.");
			renderAfterlifeURL();
		}
	}else{
		console.log("what went wrong? is makecomo?" +session.makeCombinedSession + "is all dead: " + living.length + " is had combo? " +session.hadCombinedSession )
	}

}

function scratchConfirm(){
	var scratchConfirmed = confirm("This session is doomed. Scratching this session will erase it. A new session will be generated, but you will no longer be able to view this session. Is this okay?");
	if(scratchConfirmed){
		scratch();
	}
}

function restartSession(){
	$("#story").html('<canvas id="loading" width="1000" height="354"> ');
	window.scrollTo(0, 0);
	initializePlayers(curSessionGlobalVar.players); //initializePlayers
	intro();
}

function tick(){
	//console.log("Tick: " + curSessionGlobalVar.timeTillReckoning)
	if(curSessionGlobalVar.timeTillReckoning > 0 && !curSessionGlobalVar.doomedTimeline){
		setTimeout(function(){
			curSessionGlobalVar.timeTillReckoning += -1;
			processScenes2(curSessionGlobalVar.players,curSessionGlobalVar);
			tick();
		},repeatTime); //or availablePlayers.length * *1000?
	}else{

		reckoning();
	}
}

function reckoning(){
	//console.log('reckoning')
	var s = new Reckoning(curSessionGlobalVar);
	s.trigger(curSessionGlobalVar.players)
	s.renderContent(curSessionGlobalVar.newScene());
	if(!curSessionGlobalVar.doomedTimeline){
		reckoningTick();
	}else{
		renderAfterlifeURL();
	}
}

function reckoningTick(){
	//console.log("Reckoning Tick: " + curSessionGlobalVar.timeTillReckoning)
	if(curSessionGlobalVar.timeTillReckoning > -10){
		setTimeout(function(){
			curSessionGlobalVar.timeTillReckoning += -1;
			processReckoning2(curSessionGlobalVar.players,curSessionGlobalVar)
			reckoningTick();
		},repeatTime);
	}else{
		var s = new Aftermath(curSessionGlobalVar);
		s.trigger(curSessionGlobalVar.players)
		s.renderContent(curSessionGlobalVar.newScene());
		if(curSessionGlobalVar.makeCombinedSession == true){
			processCombinedSession();  //make sure everything is done rendering first
		}else{
			renderAfterlifeURL();
		}
	}

}

function processCombinedSession(){
	var tmpcurSessionGlobalVar = curSessionGlobalVar.initializeCombinedSession();
	if(tmpcurSessionGlobalVar){
		curSessionGlobalVar = tmpcurSessionGlobalVar
		$("#story").append("

 But things aren't over, yet. The survivors manage to contact the players in the universe they created. Their sick frog may have screwed them over, but the connection it provides to their child universe will equally prove to be their salvation. Time has no meaning between universes, and they are given ample time to plan an escape from their own Game Over. They will travel to the new universe, and register as players there for session "+curSessionGlobalVar.session_id +". ");
		checkSGRUB();
		load(curSessionGlobalVar.players); //in loading.js
	}else{
		//scratch fuckers.
		curSessionGlobalVar.makeCombinedSession = false;  //can't make a combo session, and skiaia is a frog so no scratch.
		//renderScratchButton(curSessionGlobalVar);
	}

}

function foundRareSession(div, debugMessage){
	console.log(debugMessage)
	var canvasHTML = "
<canvas id='canvasJRAB" + (div.attr("id")) +"' width='" +canvasWidth + "' height="+canvasHeight + "'>  </canvas>";
	div.append(canvasHTML);

	var canvasDiv = document.getElementById("canvasJRAB"+  (div.attr("id")));
	var chat = "";
  chat += "AB: Just thought I'd let you know: " + debugMessage +"\n";
	chat += "JR: *gasp* You found it! Thanks! You are the best!!!\n";
	var quips1 = ["It's why you made me.", "It's not like I have a better use for my flawless mecha-brain.", "Just doing as programmed."];
	chat += "AB: " + getRandomElementFromArrayNoSeed(quips1)+"\n" ;
	chat += "JR: And THAT is why you are the best.\n "
	var quips2 = ["Seriously, isn't it a little narcissistic for you to like me so much?", "I don't get it, you know more than anyone how very little 'I' is in my A.I.", "Why did you go to all the effort to make debugging look like this?"];
	chat += "AB: " + getRandomElementFromArrayNoSeed(quips2)+"\n";
	chat += "JR: Dude, A.I.s are just awesome. Even simple ones. And yeah...being proud of you is a weird roundabout way of being proud of my own achievements.\n";
  var quips3 = ["Won't this be confusing to people who aren't you?", "What if you forget to disable these before deploying to the server?", "Doesn't this risk being visible to people who aren't you?"];
  chat += "AB: " + getRandomElementFromArrayNoSeed(quips3)+"\n";
	chat += "JR: Heh, I'll do my best to turn these debug messages off before deploying, but if I forget, I figure it counts as a highly indulgent author-self insert x2 combo. \n"
  chat += "JR: Oh! And I'm really careful to make sure these little chats don't actually influence the session in any way.\n"
	chat += "JR: Like maybe one day you or I can have a 'yellow yard' type interference scheme. But today is not that day."
	drawChatABJR(canvasDiv, chat);
}

function authorMessage(){
	makeAuthorAvatar();
	introScene = new AuthorMessage(curSessionGlobalVar);
	introScene.trigger(players, players[0])
	introScene.renderContent(newScene(),0); //new scenes take care of displaying on their own.
}

function callNextIntroWithDelay(player_index){
	if(player_index >= curSessionGlobalVar.players.length){
		tick();//NOW start ticking
		return;
	}
	setTimeout(function(){
		var s = new Intro(curSessionGlobalVar);
		var p = curSessionGlobalVar.players[player_index];
		var playersInMedium = curSessionGlobalVar.players.slice(0, player_index+1); //anybody past me isn't in the medium, yet.
		s.trigger(playersInMedium, p)
		s.renderContent(curSessionGlobalVar.newScene(),player_index); //new scenes take care of displaying on their own.
		processScenes2(playersInMedium,curSessionGlobalVar);
		player_index += 1;
		callNextIntroWithDelay(player_index)
	},  repeatTime);  //want all players to be done with their setTimeOuts players.length*1000+2000
}

//in a big pile. draw all the charactesr as they look as they are entereing
function createInitialSprites(){
	for(var i = 0; i<curSessionGlobalVar.players.length; i++){
		var player = curSessionGlobalVar.players[i];
		player.renderSelf();
	}

}

function intro(){
	createInitialSprites();
	callNextIntroWithDelay(0);
}

function makeAuthorAvatar(){
	players[0].grimDark = false;
	players[0].aspect = "Mind"
	players[0].class_name = "Maid"
	players[0].hair = 13;
	players[0].hairColor = "#291200";
	players[0].quirk.punctuation = 3;
	players[0].quirk.capitalization = 1;
	players[0].quirk.favoriteNumber = 3;
	players[0].chatHandle = "jadedResearcher"
	players[0].isTroll = false
	players[0].bloodColor = "#ff0000"
	players[0].mylevels = ["INSTEAD","a CORPSE JUST RENDERS HERE","STILL CAN LEVEL UP.","OH, AND CORPSES.","SAME LEVELS","BUT STILL HAVE","IMAGE","THEY GET A DIFFERENT","BEFORE MAXING OUT","IF THEY GODTIER","AND GO UP THE LADDER","LEVELS NOW","16 PREDETERMINED","HAVE","PLAYERS","I FINISHED ECHELADDERS."];
}
<commit_msg>easter egg scratches working again<commit_after>var simulationMode = false;
var debugMode = false;
var spriteWidth = 400;
var spriteHeight = 300;
var canvasWidth = 1000;
var canvasHeight = 300;
var junior = false;

var repeatTime = 5;
var version2 = true; //even though idon't want  to render content, 2.0 is different from 1.0 (think of dialog that triggers)
var curSessionGlobalVar;

//have EVERYTHING be a scene, don't put any story in v2.0's controller
//every scene can update the narration, or the canvas.
//should there be only one canvas?  Can have player sprites be written to a virtual canvas first, then copied to main one.
//main canvas is either Leader + PesterChumWindow + 1 or more Players (in chat or group chat with leader)
//or Leader + 1 or more Players  (leader doing bullshit side quests with someone)
window.onload = function() {
	//these bitches are SHAREABLE.
	setTimeout(function() {window.scrollTo(0, 0);},1)
	loadNavbar();
	if(getParameterByName("seed")){
		Math.seed = getParameterByName("seed");
		initial_seed = getParameterByName("seed");
	}else{
		var tmp = getRandomSeed();
		Math.seed = tmp;
		initial_seed = tmp;
	}

	shareableURL();

	startSession();

	//intro();  //~~~~~~LOADING SCRIPT WILL CALL THIS~~~~~~~~~

	//debugRelationshipDrama();
	//debugTriggerLevel();
	//debugGrimDark();
	//debugJackScheme();
	//debugLevelTheHellUp();
	//debugGodTierLevelTheHellUp();
	//debugCorpseLevelTheHellUp();
	//debugGodTierRevive();
	//debugCorpseSmooch();
}

function reinit(){
	available_classes = classes.slice(0);
	available_aspects = nonrequired_aspects.slice(0); //required_aspects
	available_aspects = available_aspects.concat(required_aspects.slice(0));

	curSessionGlobalVar.reinit();
}

function startSession(){
	curSessionGlobalVar = new Session(initial_seed)
	reinit();
	createScenesForSession(curSessionGlobalVar);
	//initPlayersRandomness();
	curSessionGlobalVar.makePlayers();
	curSessionGlobalVar.randomizeEntryOrder();
	//authorMessage();
	curSessionGlobalVar.makeGuardians(); //after entry order established
	//easter egg ^_^
	if(getParameterByName("royalRumble")  == "true"){
		debugRoyalRumble();
	}

	if(getParameterByName("COOLK1D")  == "true"){
		cool_kid = true;
		coolK1DMode();
	}

	if(getParameterByName("lollipop")  == "true"){
		tricksterMode();
	}
	//void is in navbar code

	if(getParameterByName("robot")  == "true"){
		roboMode();
	}

	if(getParameterByName("sbajifier")  == "true"){
		sbahjMode();
	}

	if(getParameterByName("babyStuck")  == "true"){
		babyStuckMode();
	}

	checkEasterEgg();
	initializePlayers(curSessionGlobalVar.players); //will take care of overriding players if need be.
	checkEasterEgg();
	checkSGRUB();

	load(curSessionGlobalVar.players, curSessionGlobalVar.guardians); //in loading.js
}

function shareableURL(){
	var params = window.location.href.substr(window.location.href.indexOf("?")+1)
	if (params == window.location.href) params = ""
	var str = '
Shareable URL  &nbsp&nbsp&nbsp&nbsp &nbsp&nbsp&nbsp&nbsp Replay Session (Mildly Fucking Alpha)  &nbsp&nbsp&nbsp&nbsp &nbsp&nbsp&nbsp&nbspRandom Session URL
'
	$("#seedText").html(str);
}

function checkSGRUB(){
	for(var i = 0; i<curSessionGlobalVar.players.length; i++){
		if(curSessionGlobalVar.players[i].isTroll == false){
			return;
		}
	}
	//can only get here if all are trolls.
	$(document).attr("title", "SGRUB Story Generator by jadedResearcher");
	$("#heading").html("SGRUB Story Generator by jadedResearcher (art assistance by karmicRetribution) ");
}

function getSessionType(){
	if(sessionType > .6){
		return "Human"
	}else if(sessionType > .3){
		return "Troll"
	}
	return "Mixed"
}

function renderScratchButton(session){
	var timePlayer = findAspectPlayer(curSessionGlobalVar.players, "Time")
	if(!timePlayer) throw "CAN'T SCRATCH WITHOUT A TIME PLAYER, JACKASS"
	console.log("scratch possible, button");
	//alert("scratch [possible]");
	//can't scratch if it was a a total party wipe. just a regular doomed timeline.
	var living = findLivingPlayers(session.players);
	if(living.length > 0 && (session.makeCombinedSession == false && session.hadCombinedSession == false)){
		console.log("gonna render scratch")
		var timePlayer = findAspectPlayer(session.players, "Time");
		if(!session.scratched){
			//this is apparently spoilery.
			//alert(living.length  + " living players and the " + timePlayer.land + " makes a scratch available!");
			if(session.scratchAvailable){
				var html = '
Click To Scratch Session?';
				$("#story").append(html);
				renderAfterlifeURL();
			}
		}else{
			console.log("no more scratches")
			$("#story").append("
This session is already scratched. No further scratches available.");
			renderAfterlifeURL();
		}
	}else{
		console.log("what went wrong? is makecomo?" +session.makeCombinedSession + "is all dead: " + living.length + " is had combo? " +session.hadCombinedSession )
	}

}

function scratchConfirm(){
	var scratchConfirmed = confirm("This session is doomed. Scratching this session will erase it. A new session will be generated, but you will no longer be able to view this session. Is this okay?");
	if(scratchConfirmed){
		scratch();
	}
}

function restartSession(){
	$("#story").html('<canvas id="loading" width="1000" height="354"> ');
	window.scrollTo(0, 0);
	checkEasterEgg();
	initializePlayers(curSessionGlobalVar.players); //initializePlayers
	checkEasterEgg();
	intro();
}

function tick(){
	//console.log("Tick: " + curSessionGlobalVar.timeTillReckoning)
	if(curSessionGlobalVar.timeTillReckoning > 0 && !curSessionGlobalVar.doomedTimeline){
		setTimeout(function(){
			curSessionGlobalVar.timeTillReckoning += -1;
			processScenes2(curSessionGlobalVar.players,curSessionGlobalVar);
			tick();
		},repeatTime); //or availablePlayers.length * *1000?
	}else{

		reckoning();
	}
}

function reckoning(){
	//console.log('reckoning')
	var s = new Reckoning(curSessionGlobalVar);
	s.trigger(curSessionGlobalVar.players)
	s.renderContent(curSessionGlobalVar.newScene());
	if(!curSessionGlobalVar.doomedTimeline){
		reckoningTick();
	}else{
		renderAfterlifeURL();
	}
}

function reckoningTick(){
	//console.log("Reckoning Tick: " + curSessionGlobalVar.timeTillReckoning)
	if(curSessionGlobalVar.timeTillReckoning > -10){
		setTimeout(function(){
			curSessionGlobalVar.timeTillReckoning += -1;
			processReckoning2(curSessionGlobalVar.players,curSessionGlobalVar)
			reckoningTick();
		},repeatTime);
	}else{
		var s = new Aftermath(curSessionGlobalVar);
		s.trigger(curSessionGlobalVar.players)
		s.renderContent(curSessionGlobalVar.newScene());
		if(curSessionGlobalVar.makeCombinedSession == true){
			processCombinedSession();  //make sure everything is done rendering first
		}else{
			renderAfterlifeURL();
		}
	}

}

function processCombinedSession(){
	var tmpcurSessionGlobalVar = curSessionGlobalVar.initializeCombinedSession();
	if(tmpcurSessionGlobalVar){
		curSessionGlobalVar = tmpcurSessionGlobalVar
		$("#story").append("

 But things aren't over, yet. The survivors manage to contact the players in the universe they created. Their sick frog may have screwed them over, but the connection it provides to their child universe will equally prove to be their salvation. Time has no meaning between universes, and they are given ample time to plan an escape from their own Game Over. They will travel to the new universe, and register as players there for session "+curSessionGlobalVar.session_id +". ");
		checkSGRUB();
		load(curSessionGlobalVar.players); //in loading.js
	}else{
		//scratch fuckers.
		curSessionGlobalVar.makeCombinedSession = false;  //can't make a combo session, and skiaia is a frog so no scratch.
		//renderScratchButton(curSessionGlobalVar);
	}

}

function foundRareSession(div, debugMessage){
	console.log(debugMessage)
	var canvasHTML = "
<canvas id='canvasJRAB" + (div.attr("id")) +"' width='" +canvasWidth + "' height="+canvasHeight + "'>  </canvas>";
	div.append(canvasHTML);

	var canvasDiv = document.getElementById("canvasJRAB"+  (div.attr("id")));
	var chat = "";
  chat += "AB: Just thought I'd let you know: " + debugMessage +"\n";
	chat += "JR: *gasp* You found it! Thanks! You are the best!!!\n";
	var quips1 = ["It's why you made me.", "It's not like I have a better use for my flawless mecha-brain.", "Just doing as programmed."];
	chat += "AB: " + getRandomElementFromArrayNoSeed(quips1)+"\n" ;
	chat += "JR: And THAT is why you are the best.\n "
	var quips2 = ["Seriously, isn't it a little narcissistic for you to like me so much?", "I don't get it, you know more than anyone how very little 'I' is in my A.I.", "Why did you go to all the effort to make debugging look like this?"];
	chat += "AB: " + getRandomElementFromArrayNoSeed(quips2)+"\n";
	chat += "JR: Dude, A.I.s are just awesome. Even simple ones. And yeah...being proud of you is a weird roundabout way of being proud of my own achievements.\n";
  var quips3 = ["Won't this be confusing to people who aren't you?", "What if you forget to disable these before deploying to the server?", "Doesn't this risk being visible to people who aren't you?"];
  chat += "AB: " + getRandomElementFromArrayNoSeed(quips3)+"\n";
	chat += "JR: Heh, I'll do my best to turn these debug messages off before deploying, but if I forget, I figure it counts as a highly indulgent author-self insert x2 combo. \n"
  chat += "JR: Oh! And I'm really careful to make sure these little chats don't actually influence the session in any way.\n"
	chat += "JR: Like maybe one day you or I can have a 'yellow yard' type interference scheme. But today is not that day."
	drawChatABJR(canvasDiv, chat);
}

function authorMessage(){
	makeAuthorAvatar();
	introScene = new AuthorMessage(curSessionGlobalVar);
	introScene.trigger(players, players[0])
	introScene.renderContent(newScene(),0); //new scenes take care of displaying on their own.
}

function callNextIntroWithDelay(player_index){
	if(player_index >= curSessionGlobalVar.players.length){
		tick();//NOW start ticking
		return;
	}
	setTimeout(function(){
		var s = new Intro(curSessionGlobalVar);
		var p = curSessionGlobalVar.players[player_index];
		var playersInMedium = curSessionGlobalVar.players.slice(0, player_index+1); //anybody past me isn't in the medium, yet.
		s.trigger(playersInMedium, p)
		s.renderContent(curSessionGlobalVar.newScene(),player_index); //new scenes take care of displaying on their own.
		processScenes2(playersInMedium,curSessionGlobalVar);
		player_index += 1;
		callNextIntroWithDelay(player_index)
	},  repeatTime);  //want all players to be done with their setTimeOuts players.length*1000+2000
}

//in a big pile. draw all the charactesr as they look as they are entereing
function createInitialSprites(){
	for(var i = 0; i<curSessionGlobalVar.players.length; i++){
		var player = curSessionGlobalVar.players[i];
		player.renderSelf();
	}

}

function intro(){
	createInitialSprites();
	callNextIntroWithDelay(0);
}

function makeAuthorAvatar(){
	players[0].grimDark = false;
	players[0].aspect = "Mind"
	players[0].class_name = "Maid"
	players[0].hair = 13;
	players[0].hairColor = "#291200";
	players[0].quirk.punctuation = 3;
	players[0].quirk.capitalization = 1;
	players[0].quirk.favoriteNumber = 3;
	players[0].chatHandle = "jadedResearcher"
	players[0].isTroll = false
	players[0].bloodColor = "#ff0000"
	players[0].mylevels = ["INSTEAD","a CORPSE JUST RENDERS HERE","STILL CAN LEVEL UP.","OH, AND CORPSES.","SAME LEVELS","BUT STILL HAVE","IMAGE","THEY GET A DIFFERENT","BEFORE MAXING OUT","IF THEY GODTIER","AND GO UP THE LADDER","LEVELS NOW","16 PREDETERMINED","HAVE","PLAYERS","I FINISHED ECHELADDERS."];
}
<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Round shiny button, like for the Reset All button.
 * See https://github.com/phetsims/scenery-phet/issues/23
 *
 * @author John Blanco
 */
define( function( require ) {
  'use strict';

  // Includes
  var Circle = require( 'SCENERY/nodes/Circle' );
  var Color = require( 'SCENERY/util/Color' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var PushButtonDeprecated = require( 'SUN/PushButtonDeprecated' );
  var RadialGradient = require( 'SCENERY/util/RadialGradient' );
  var Shape = require( 'KITE/Shape' );

  // Constants
  var DEFAULT_RADIUS = 32; // Derived from images initially used for reset button.

  // Inner type for creating button nodes used for various button states.
  function ButtonStateNode( radius, fill, icon, iconOffsetX, iconOffsetY, backgroundGradientColorStop0, backgroundGradientColorStop1, innerButtonStroke, innerButtonLineWidth ) {
    Node.call( this, { pickable: false } );
    var backgroundGradient = new RadialGradient( radius * 0.05, radius * 0.05, radius * 0.85, 0, 0, radius * 1.2 );
    backgroundGradient.addColorStop( 0, backgroundGradientColorStop0 );
    backgroundGradient.addColorStop( 1, backgroundGradientColorStop1 );
    this.addChild( new Circle( radius, { fill: backgroundGradient } ) );
    var innerButtonRadius = radius * 0.92; // Multiplier determined by eyeballing it.
    this.addChild( new Circle( innerButtonRadius, { fill: fill, stroke: innerButtonStroke, lineWidth: innerButtonLineWidth } ) );
    this.addChild( icon );
    icon.centerX = iconOffsetX;
    icon.centerY = iconOffsetY;
  }

  inherit( Node, ButtonStateNode );

  /**
   * @param {function} callback
   * @param {Node} icon
   * @param {Object} [options]
   * @constructor
   */
  function RoundShinyButtonDeprecated( callback, icon, options ) {
    options = _.extend( {

      //Colors for the border gradient
      backgroundGradientColorStop0: 'black',
      backgroundGradientColorStop1: 'rgb( 230, 230, 230 )',

      //Drawing a line around the inner circle.  Off by default but maybe should be changed to on by default
      innerButtonStroke: null,
      innerButtonLineWidth: null,

      radius: DEFAULT_RADIUS,
      touchAreaRadius: DEFAULT_RADIUS * 1.3, // convenience for expanding the touchArea, which is a circle

      // By default, icons are centered in the button, but icons with odd
      // shapes (that should not be wrapped in a normalizing parent node), may
      // need to specify offsets to line things up properly
      iconOffsetX: 0,
      iconOffsetY: 0,

      // Default color scheme
      upFill: new Color( 153, 206, 220 ),
      overFill: new Color( 160, 216, 255 ),
      disabledFill: new Color( 180, 180, 180 ),
      downFill: new Color( 145, 190, 250 )
    }, options );
    options.listener = callback;

    // Local functions for creating gradients to use on buttons.
    var createButtonFillGradient = function( baseColor ) {
      var buttonGradient = new RadialGradient( options.radius * 0.05, options.radius * 0.05, options.radius * 0.87, 0, 0, options.radius );
      buttonGradient.addColorStop( 0, baseColor );
      buttonGradient.addColorStop( 0.7, baseColor.colorUtilsBrighter( 0.6 ) );
      buttonGradient.addColorStop( 1, baseColor.colorUtilsBrighter( 0.8 ) );
      return buttonGradient;
    };
    var createPushedButtonGradient = function( baseColor ) {
      var buttonGradient = new RadialGradient( 0, 0, options.radius * 0.5, 0, 0, options.radius );
      buttonGradient.addColorStop( 0, baseColor );
      buttonGradient.addColorStop( 0.3, baseColor );
      buttonGradient.addColorStop( 0.5, baseColor.colorUtilsDarker( 0.1 ) );
      buttonGradient.addColorStop( 0.7, baseColor );
      return buttonGradient;
    };
    var translatedIcon = new Node( {children: [icon]} );

    // Create the nodes for each of the button states. Note: the same icon is
    // used in each of the children (except for the down node, which must be
    // translated), this is to save on memory and CPU but means they all will
    // have the same appearance and offset
    var upNode = new ButtonStateNode( options.radius, createButtonFillGradient( options.upFill ), icon, options.iconOffsetX, options.iconOffsetY,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );
    var overNode = new ButtonStateNode( options.radius, createButtonFillGradient( options.overFill ), icon, options.iconOffsetX, options.iconOffsetY,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );
    var disabledNode = new ButtonStateNode( options.radius, createButtonFillGradient( options.disabledFill ), icon, options.iconOffsetX, options.iconOffsetY,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );
    var downNode = new ButtonStateNode( options.radius, createPushedButtonGradient( options.downFill ), translatedIcon, options.iconOffsetX + options.radius * 0.01, options.iconOffsetY + options.radius * 0.01,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );

    // Create the actual button by invoking the parent type.
    PushButtonDeprecated.call( this, upNode, overNode, downNode, disabledNode, options );

    // Add an explicit mouse area so that the child nodes can all be non-pickable.
    this.mouseArea = Shape.circle( 0, 0, options.radius );

    // Expand the touch area so that the button works better on touch devices.
    this.touchArea = Shape.circle( 0, 0, options.touchAreaRadius );
  }

  return inherit( PushButtonDeprecated, RoundShinyButtonDeprecated, {},

    //Statics
    {
      DEFAULT_RADIUS: DEFAULT_RADIUS
    } );
} );<commit_msg>phetsims/joist#170 replace PushButtonDeprecated with NodesPushButton<commit_after>// Copyright 2002-2013, University of Colorado Boulder

/**
 * Round shiny button, like for the Reset All button.
 * See https://github.com/phetsims/scenery-phet/issues/23
 *
 * @author John Blanco
 */
define( function( require ) {
  'use strict';

  // Includes
  var Circle = require( 'SCENERY/nodes/Circle' );
  var Color = require( 'SCENERY/util/Color' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var NodesPushButton = require( 'SUN/buttons/NodesPushButton' );
  var RadialGradient = require( 'SCENERY/util/RadialGradient' );
  var Shape = require( 'KITE/Shape' );

  // Constants
  var DEFAULT_RADIUS = 32; // Derived from images initially used for reset button.

  // Inner type for creating button nodes used for various button states.
  function ButtonStateNode( radius, fill, icon, iconOffsetX, iconOffsetY, backgroundGradientColorStop0, backgroundGradientColorStop1, innerButtonStroke, innerButtonLineWidth ) {
    Node.call( this, { pickable: false } );
    var backgroundGradient = new RadialGradient( radius * 0.05, radius * 0.05, radius * 0.85, 0, 0, radius * 1.2 );
    backgroundGradient.addColorStop( 0, backgroundGradientColorStop0 );
    backgroundGradient.addColorStop( 1, backgroundGradientColorStop1 );
    this.addChild( new Circle( radius, { fill: backgroundGradient } ) );
    var innerButtonRadius = radius * 0.92; // Multiplier determined by eyeballing it.
    this.addChild( new Circle( innerButtonRadius, { fill: fill, stroke: innerButtonStroke, lineWidth: innerButtonLineWidth } ) );
    this.addChild( icon );
    icon.centerX = iconOffsetX;
    icon.centerY = iconOffsetY;
  }

  inherit( Node, ButtonStateNode );

  /**
   * @param {function} callback
   * @param {Node} icon
   * @param {Object} [options]
   * @constructor
   */
  function RoundShinyButtonDeprecated( callback, icon, options ) {
    options = _.extend( {

      //Colors for the border gradient
      backgroundGradientColorStop0: 'black',
      backgroundGradientColorStop1: 'rgb( 230, 230, 230 )',

      //Drawing a line around the inner circle.  Off by default but maybe should be changed to on by default
      innerButtonStroke: null,
      innerButtonLineWidth: null,

      radius: DEFAULT_RADIUS,
      touchAreaRadius: DEFAULT_RADIUS * 1.3, // convenience for expanding the touchArea, which is a circle

      // By default, icons are centered in the button, but icons with odd
      // shapes (that should not be wrapped in a normalizing parent node), may
      // need to specify offsets to line things up properly
      iconOffsetX: 0,
      iconOffsetY: 0,

      // Default color scheme
      upFill: new Color( 153, 206, 220 ),
      overFill: new Color( 160, 216, 255 ),
      disabledFill: new Color( 180, 180, 180 ),
      downFill: new Color( 145, 190, 250 )
    }, options );
    options.listener = callback;

    // Local functions for creating gradients to use on buttons.
    var createButtonFillGradient = function( baseColor ) {
      var buttonGradient = new RadialGradient( options.radius * 0.05, options.radius * 0.05, options.radius * 0.87, 0, 0, options.radius );
      buttonGradient.addColorStop( 0, baseColor );
      buttonGradient.addColorStop( 0.7, baseColor.colorUtilsBrighter( 0.6 ) );
      buttonGradient.addColorStop( 1, baseColor.colorUtilsBrighter( 0.8 ) );
      return buttonGradient;
    };
    var createPushedButtonGradient = function( baseColor ) {
      var buttonGradient = new RadialGradient( 0, 0, options.radius * 0.5, 0, 0, options.radius );
      buttonGradient.addColorStop( 0, baseColor );
      buttonGradient.addColorStop( 0.3, baseColor );
      buttonGradient.addColorStop( 0.5, baseColor.colorUtilsDarker( 0.1 ) );
      buttonGradient.addColorStop( 0.7, baseColor );
      return buttonGradient;
    };
    var translatedIcon = new Node( {children: [icon]} );

    // Create the nodes for each of the button states. Note: the same icon is
    // used in each of the children (except for the down node, which must be
    // translated), this is to save on memory and CPU but means they all will
    // have the same appearance and offset
    var upNode = new ButtonStateNode( options.radius, createButtonFillGradient( options.upFill ), icon, options.iconOffsetX, options.iconOffsetY,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );
    var overNode = new ButtonStateNode( options.radius, createButtonFillGradient( options.overFill ), icon, options.iconOffsetX, options.iconOffsetY,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );
    var disabledNode = new ButtonStateNode( options.radius, createButtonFillGradient( options.disabledFill ), icon, options.iconOffsetX, options.iconOffsetY,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );
    var downNode = new ButtonStateNode( options.radius, createPushedButtonGradient( options.downFill ), translatedIcon, options.iconOffsetX + options.radius * 0.01, options.iconOffsetY + options.radius * 0.01,
      options.backgroundGradientColorStop0, options.backgroundGradientColorStop1, options.innerButtonStroke, options.innerButtonLineWidth );

    // Create the actual button by invoking the parent type.
    NodesPushButton.call( this, upNode, overNode, downNode, disabledNode, options );

    // Add an explicit mouse area so that the child nodes can all be non-pickable.
    this.mouseArea = Shape.circle( 0, 0, options.radius );

    // Expand the touch area so that the button works better on touch devices.
    this.touchArea = Shape.circle( 0, 0, options.touchAreaRadius );
  }

  return inherit( NodesPushButton, RoundShinyButtonDeprecated, {},

    //Statics
    {
      DEFAULT_RADIUS: DEFAULT_RADIUS
    } );
} );<|endoftext|>


<commit_before>//Nodig voor autoincrement
var selectedcourseid;
var studid;
var worksheets = [];
var worksheetsid = [];

//viewmodel for the assess page
function pageViewModel(gvm) {
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName")}, gvm);
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n. __("AssessTitle2");}, gvm);
    gvm.userId = -1;

    // Page specific i18n bindings
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AssessTitle2");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("HomeRapportManual");}, gvm);
    gvm.foundProjects = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FoundProjects");}, gvm);
    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);

    // Pagination i18n bindings
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    // Table i18n bindings
    gvm.werkficheID = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheID");}, gvm);
    gvm.werkficheName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheName");}, gvm);
    gvm.werkficheDate = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheDate");}, gvm);
    gvm.werkficheAction = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheAction");}, gvm);

    gvm.availableCourses = ko.observableArray([]);
    gvm.availableStudentlists = ko.observableArray([]);
    gvm.availableStudents = ko.observableArray([]);

    gvm.currentCourseId = null;
    gvm.currentStudentlistId = null;
    gvm.currentStudentId = null;

    gvm.updateDropdowns = function() {
        $.getJSON('api/lastdropdownrapporten/' + gvm.userId, function(data) {
            if(!$.isEmptyObject(data)) {
                $.each(data, function(i, item) {
                    $(".btn-courseRapport span:first").text(item.course);
                    $(".btn-studentlist span:first").text(item.studentlist);
                    $('.btn-student span:first').text(item.student);
                    gvm.currentCourseId = item.courseid;
                    selectedcourseid = item.courseid;
                    gvm.updateStudentlists(item.courseid, gvm.userId);
                    gvm.currentStudentlistId = item.studentlistid;
                    gvm.updateStudents(item.studentlistid);
                    gvm.currentStudentId = item.studentid;
                    studid = item.studentid;
                    gvm.updateCourseRapport();
                    loadTablePage(item.courseid, 1);
                });
            } else {
                gvm.updateCourseRapport();
            }
        });
    }

    //Houdt bij wat geselecteerd wordt
    //Wordt opgeroepen bij iedere wijziging (niet ingevulde velden = NULL)
    gvm.saveLastSelectedDropdowns = function() {
        data = {};
        data["user"] = gvm.userId;
        data["course"] = $(".btn-courseRapport span:first").text();
        data["courseid"] = gvm.currentCourseId;
        data["studentlist"] = $('.btn-studentlist span:first').text();
        data["studentlistid"] = gvm.currentStudentlistId;
        data["student"] = $(".btn-student span:first").text();
        data["studentid"] = gvm.currentStudentId;
        studid = gvm.currentStudentId;
        $.ajax({
            type: "POST",
            url: "/api/savedropdownsRapport",
            data: data,
            success: function() {
                console.log("success");
            }
        })
    }

    gvm.updateCourseRapport = function() {
        $.getJSON('/api/coursefromteacher/' + gvm.userId, function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                //  Put item in list
                gvm.availableCourses.push(item);

                // Add listener to listitem
                $("#coursebtn-" + item.id).click(function(){
                    gvm.currentCourseId = item.id;
                    selectedcourseid = item.id;
                    gvm.currentStudentlistId = null;
                    gvm.currentStudentId = null;
                    gvm.updateStudentlists(item.id, gvm.userId);
                    $(".btn-courseRapport span:first").text($(this).text());
                    $(".btn-studentlist span:first").text("Studentlist");
                    $('.btn-student span:first').text("Student");
                    gvm.saveLastSelectedDropdowns();
                });
            });
        });
    };

    /*
     * Update the student data
     */
    gvm.updateStudentlists = function(cid, uid) {
        //get all studentlists
        $.getJSON('api/studentlistdrop/' + cid + '/' + uid, function(data) {
            gvm.availableStudentlists.removeAll();
            $.each(data, function(i,item) {
                // Put item in list
                gvm.availableStudentlists.push(item);

                // Add listener to listitem
                $("#studentlistbtn-" + item.id).click(function(){
                    gvm.currentStudentlistId = item.id;
                    gvm.currentStudentId = null;
                    gvm.updateStudents(item.id);
                    $(".btn-studentlist span:first").text($(this).text());
                    $('.btn-student span:first').text("Student");
                    gvm.saveLastSelectedDropdowns();
                });
            })
        })
    }

    /*
     * Update the student data
     */
    gvm.updateStudents = function(id) {
        //get all students who follow that course
        $.getJSON('api/studentdrop/' + id, function(data) {
            gvm.availableStudents.removeAll();
            $.each(data, function(i,item) {
                // Put item in list
                gvm.availableStudents.push(item);

                // Add listener to listitem
                $("#studentbtn-" + item.id).click(function(){
                    gvm.currentStudentId = item.id;
                    $(".btn-student span:first").text($(this).text());
                    gvm.saveLastSelectedDropdowns();
                });
            })
        })
    }

    // The table data observable array
    gvm.tabledata = ko.observableArray([]);

    // Add data to the table
    gvm.addTableData = function(id, name, lastname, mail, score) {
        // Push data
        var tblOject = {tstudid: id, tname: name, tlname: lastname, tmail: mail, tscore: score};
        gvm.tabledata.push(tblOject);
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function getAllWorksheets() {
    worksheets = [];
    worksheetsid = [];
    $.getJSON('/api/worksheets/' + selectedcourseid, function(data) {
        $.each(data, function(i, item) {
            worksheets.push(item.Name);
            worksheetsid.push(item.id);
        });
    });
    return worksheets;
}

function getWorksheetid() {
    var i = 0;
    var worksheet = 0;
    worksheets.forEach(function(entry) {
        if (new String(entry).valueOf() == new String($('#worksheetComplete').val()).valueOf()) {
            worksheet = worksheetsid[i];
        }
        i+= 1;
    });
    return worksheet;
}

function addWorksheet(worksheetid) {
    console.log("toe te voegenworksheet " + worksheetid + " voor " + studid);
    $.ajax({
        url: "/api/worksheetstudentcouple/" + worksheetid + "/" + studid,
        type: "POST",
        data: {'worksheetid': worksheetid, 'studid': studid},
        success: function(data) {
            //callback(true);
        },
        error: function(data) {
            console.log('Failed to add new student');
            //callback(false);
        }
    });
}

function loadTablePage(pagenr)
{
    $.getJSON('/api/worksheets/page/' + pagenr, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id,  item.firstname, item.lastname, item.mail);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

function initPage() {
    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateDropdowns();
    });

    $('#addGroupForm').hide();

    $('#addWorksheetBtn').click(function() {
        $("#addGroupForm").show();
        $('#worksheetComplete').autocomplete({ source: getAllWorksheets() });
    });

    $('#addNewWorksheetBtn').click(function() {
        //TODO controle of er effectief een lijst / student geselecteerd is.
        console.log("geselecteerd " + $("input:radio[name='studenten']:checked").val())
        //controleren of het voor 1 student is of voor alle studenten
        if ($("input:radio[name='studenten']:checked").val() == "student") { //student
            console.log("Add student");
            addWorksheet(getWorksheetid());
        }
            else if ($("input:radio[name='studenten']:checked")== "studentlist")//studentlist
        {
            console.log("Add studentengroep");
        }
        //table opnieuw laden
        loadTablePage(1);

        //Indien gewenst toevoegformulier weer verbergen.
        $('#worksheetComplete').val("");
        $('#addGroupForm').hide();
    });
}<commit_msg>Keuze geven tussen studentenlijst of enkele student<commit_after>//Nodig voor autoincrement
var selectedcourseid;
var studid;
var worksheets = [];
var worksheetsid = [];

//viewmodel for the assess page
function pageViewModel(gvm) {
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName")}, gvm);
    gvm.title = ko.computed(function(){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n. __("AssessTitle2");}, gvm);
    gvm.userId = -1;

    // Page specific i18n bindings
    gvm.pageHeader = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AssessTitle2");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("HomeRapportManual");}, gvm);
    gvm.foundProjects = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("FoundProjects");}, gvm);
    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);

    // Pagination i18n bindings
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    // Table i18n bindings
    gvm.werkficheID = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheID");}, gvm);
    gvm.werkficheName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheName");}, gvm);
    gvm.werkficheDate = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheDate");}, gvm);
    gvm.werkficheAction = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheAction");}, gvm);

    gvm.availableCourses = ko.observableArray([]);
    gvm.availableStudentlists = ko.observableArray([]);
    gvm.availableStudents = ko.observableArray([]);

    gvm.currentCourseId = null;
    gvm.currentStudentlistId = null;
    gvm.currentStudentId = null;

    gvm.updateDropdowns = function() {
        $.getJSON('api/lastdropdownrapporten/' + gvm.userId, function(data) {
            if(!$.isEmptyObject(data)) {
                $.each(data, function(i, item) {
                    $(".btn-courseRapport span:first").text(item.course);
                    $(".btn-studentlist span:first").text(item.studentlist);
                    $('.btn-student span:first').text(item.student);
                    gvm.currentCourseId = item.courseid;
                    selectedcourseid = item.courseid;
                    gvm.updateStudentlists(item.courseid, gvm.userId);
                    gvm.currentStudentlistId = item.studentlistid;
                    gvm.updateStudents(item.studentlistid);
                    gvm.currentStudentId = item.studentid;
                    studid = item.studentid;
                    gvm.updateCourseRapport();
                    loadTablePage(item.courseid, 1);
                });
            } else {
                gvm.updateCourseRapport();
            }
        });
    }

    //Houdt bij wat geselecteerd wordt
    //Wordt opgeroepen bij iedere wijziging (niet ingevulde velden = NULL)
    gvm.saveLastSelectedDropdowns = function() {
        data = {};
        data["user"] = gvm.userId;
        data["course"] = $(".btn-courseRapport span:first").text();
        data["courseid"] = gvm.currentCourseId;
        data["studentlist"] = $('.btn-studentlist span:first').text();
        data["studentlistid"] = gvm.currentStudentlistId;
        data["student"] = $(".btn-student span:first").text();
        data["studentid"] = gvm.currentStudentId;
        studid = gvm.currentStudentId;
        $.ajax({
            type: "POST",
            url: "/api/savedropdownsRapport",
            data: data,
            success: function() {
                console.log("success");
            }
        })
    }

    gvm.updateCourseRapport = function() {
        $.getJSON('/api/coursefromteacher/' + gvm.userId, function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                //  Put item in list
                gvm.availableCourses.push(item);

                // Add listener to listitem
                $("#coursebtn-" + item.id).click(function(){
                    gvm.currentCourseId = item.id;
                    selectedcourseid = item.id;
                    gvm.currentStudentlistId = null;
                    gvm.currentStudentId = null;
                    gvm.updateStudentlists(item.id, gvm.userId);
                    $(".btn-courseRapport span:first").text($(this).text());
                    $(".btn-studentlist span:first").text("Studentlist");
                    $('.btn-student span:first').text("Student");
                    gvm.saveLastSelectedDropdowns();
                });
            });
        });
    };

    /*
     * Update the student data
     */
    gvm.updateStudentlists = function(cid, uid) {
        //get all studentlists
        $.getJSON('api/studentlistdrop/' + cid + '/' + uid, function(data) {
            gvm.availableStudentlists.removeAll();
            $.each(data, function(i,item) {
                // Put item in list
                gvm.availableStudentlists.push(item);

                // Add listener to listitem
                $("#studentlistbtn-" + item.id).click(function(){
                    gvm.currentStudentlistId = item.id;
                    gvm.currentStudentId = null;
                    gvm.updateStudents(item.id);
                    $(".btn-studentlist span:first").text($(this).text());
                    $('.btn-student span:first').text("Student");
                    gvm.saveLastSelectedDropdowns();
                });
            })
        })
    }

    /*
     * Update the student data
     */
    gvm.updateStudents = function(id) {
        //get all students who follow that course
        $.getJSON('api/studentdrop/' + id, function(data) {
            gvm.availableStudents.removeAll();
            $.each(data, function(i,item) {
                // Put item in list
                gvm.availableStudents.push(item);

                // Add listener to listitem
                $("#studentbtn-" + item.id).click(function(){
                    gvm.currentStudentId = item.id;
                    $(".btn-student span:first").text($(this).text());
                    gvm.saveLastSelectedDropdowns();
                });
            })
        })
    }

    // The table data observable array
    gvm.tabledata = ko.observableArray([]);

    // Add data to the table
    gvm.addTableData = function(id, name, lastname, mail, score) {
        // Push data
        var tblOject = {tstudid: id, tname: name, tlname: lastname, tmail: mail, tscore: score};
        gvm.tabledata.push(tblOject);
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function getAllWorksheets() {
    worksheets = [];
    worksheetsid = [];
    $.getJSON('/api/worksheets/' + selectedcourseid, function(data) {
        $.each(data, function(i, item) {
            worksheets.push(item.Name);
            worksheetsid.push(item.id);
        });
    });
    return worksheets;
}

function getWorksheetid() {
    var i = 0;
    var worksheet = 0;
    worksheets.forEach(function(entry) {
        if (new String(entry).valueOf() == new String($('#worksheetComplete').val()).valueOf()) {
            worksheet = worksheetsid[i];
        }
        i+= 1;
    });
    return worksheet;
}

function addWorksheet(worksheetid) {
    console.log("toe te voegenworksheet " + worksheetid + " voor " + studid);
    $.ajax({
        url: "/api/worksheetstudentcouple/" + worksheetid + "/" + studid,
        type: "POST",
        data: {'worksheetid': worksheetid, 'studid': studid},
        success: function(data) {
            //callback(true);
        },
        error: function(data) {
            console.log('Failed to add new student');
            //callback(false);
        }
    });
}

function loadTablePage(pagenr)
{
    $.getJSON('/api/worksheets/page/' + pagenr, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id,  item.firstname, item.lastname, item.mail);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

function initPage() {
    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateDropdowns();
    });

    $('#addGroupForm').hide();

    $('#addWorksheetBtn').click(function() {
        $("#addGroupForm").show();
        $('#worksheetComplete').autocomplete({ source: getAllWorksheets() });
    });

    $('#addNewWorksheetBtn').click(function() {
        //TODO controle of er effectief een lijst / student geselecteerd is.
        console.log("geselecteerd " + $("input:radio[name='studenten']:checked").val())
        //controleren of het voor 1 student is of voor alle studenten
        if ($("input:radio[name='studenten']:checked").val() == "student") { //student
            console.log("Add student");
            addWorksheet(getWorksheetid());
        }
            else {
            console.log("Add studentengroep");
        }
        //table opnieuw laden
        loadTablePage(1);

        //Indien gewenst toevoegformulier weer verbergen.
        $('#worksheetComplete').val("");
        $('#addGroupForm').hide();
    });
}<|endoftext|>


<commit_before>/*
 *   Copyright 2012 OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/**
 * The delete query confirmation dialog
 */
var DeleteRepositoryObject = Modal.extend({
    type: "delete",

    buttons: [
        { text: "Yes", method: "del" },
        { text: "No", method: "close" }
    ],

    initialize: function(args) {
        this.options.title = "Confirm deletion";
        this.query = args.query;
        this.success = args.success;
        this.message = _.template("Are you sure you want to delete <%= name %>?")
            ({ name: this.query.get('name') });
    },

    del: function() {
        this.query.id = _.uniqueId("query_");
        this.query.url = this.query.url() + "?file=" + this.query.get('file');
        this.query.destroy({
            success: this.success,
            dataType: "text",
            error: this.error
        });
        this.close();
    },

    error: function() {
        $(this.el).find('dialog_body')
            .html("Could not delete repository object");
    }
});
<commit_msg>fix file encode issue for & etc names<commit_after>/*
 *   Copyright 2012 OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

/**
 * The delete query confirmation dialog
 */
var DeleteRepositoryObject = Modal.extend({
    type: "delete",

    buttons: [
        { text: "Yes", method: "del" },
        { text: "No", method: "close" }
    ],

    initialize: function(args) {
        this.options.title = "Confirm deletion";
        this.query = args.query;
        this.success = args.success;
        this.message = _.template("Are you sure you want to delete <%= name %>?")
            ({ name: this.query.get('name') });
    },

    del: function() {
        this.query.id = _.uniqueId("query_");
        this.query.url = this.query.url() + "?file=" + encodeURIComponent(this.query.get('file'));
        this.query.destroy({
            success: this.success,
            dataType: "text",
            error: this.error
        });
        this.close();
    },

    error: function() {
        $(this.el).find('dialog_body')
            .html("Could not delete repository object");
    }
});
<|endoftext|>


<commit_before>var plugin = require('../../processors/tag-parser');
var Config = require('dgeni').Config;

describe("tag-parser doc processor plugin", function() {

  var config;

  beforeEach(function() {
    config = new Config();
    config.set('processing.tagDefinitions', [
      { name: 'ngdoc' },
      { name: 'description' },
      { name: 'param', canHaveName: true, canHaveType: true }
    ]);
  });

  it("should have name 'tag-parser", function() {
    expect(plugin.name).toEqual('tag-parser');
  });

  it("should parse the content of the document and attach a tags property to the doc", function() {
    var doc = {
      content: 'some content\n@ngdoc directive\n@description Some description info\n@param {function(*)|string|Array.<(function(*)|string)>} abc',
      startingLine: 245
    };
    plugin.process([doc], config);
    expect(doc.tags).toBeDefined();
    expect(doc.tags.description).toEqual('some content');
    expect(doc.tags.getTag('ngdoc')).toEqual(jasmine.objectContaining({ tagName: 'ngdoc', description: 'directive' }));
    expect(doc.tags.getTag('description')).toEqual(jasmine.objectContaining({ tagName: 'description', description: 'Some description info' }));
    expect(doc.tags.getTag('param')).toEqual(jasmine.objectContaining({ tagName: 'param', description: ''}));
  });

  it("should parse the typeExpression into an object tree", function() {
    var doc = {
      content: '@param {function(*)|string|Array.<(function(*)|string)>} abc',
      startingLine: 245
    };
    debugger;
    plugin.process([doc], config);
    var tag = doc.tags.getTag('param');
    expect(tag.typeExpression).toEqual('function(*)|string|Array.<(function(*)|string)>');
    expect(tag.type.type).toEqual('TypeUnion');
    expect(tag.type.elements).toEqual([
      { type : 'FunctionType', params : [ { type : 'AllLiteral' } ] },
      { type : 'NameExpression', name : 'string' },
      {
        type : 'TypeApplication',
        expression : { type : 'NameExpression', name : 'Array' },
        applications : [
          {
            type : 'TypeUnion',
            elements : [
              { type : 'FunctionType', params : [ { type : 'AllLiteral' } ] },
              { type : 'NameExpression', name : 'string' }
            ]
          }
        ]
      }
    ]);
  });

  it("should convert a simple type into an object", function() {
    var doc = {
      content: '@param {string} abc',
      startingLine: 1
    };
    plugin.process([doc], config);
    expect(doc.tags.getTag('param').type).toEqual(jasmine.objectContaining(
      { type : 'NameExpression', name : 'string' }));
  });

  it("should convert an optional type into an object", function() {
    var doc = {
      content: '@param {string=} abc',
      startingLine: 1
    };
    plugin.process([doc], config);
    expect(doc.tags.getTag('param').type).toEqual(jasmine.objectContaining({
      type: 'NameExpression', name: 'string', optional: true
    }));
  });

  it("should a simple array of top level types in the typeList property", function() {
    var doc = {
      content: '@param {function(*)|string|Array.<(function(*)|string)>} abc',
      startingLine: 245
    };
    plugin.process([doc], config);
    var tag = doc.tags.getTag('param');
    expect(tag.typeList).toEqual([
      'function(*)',
      'string',
      'Array.<(function(*)|string)>'
    ]);
  });

});<commit_msg>chore(tag-parser spec): remove unused file<commit_after><|endoftext|>


<commit_before>(function($){
  $.fn.textareaAutoExpand = function(){
    return this.each(function(){
      var textarea = $(this);
      var height = textarea.outerHeight();
      var diff = //parseInt(textarea.css('borderBottomWidth')) + parseInt(textarea.css('borderTopWidth')) +
                 parseInt(textarea.css('paddingBottom')) + parseInt(textarea.css('paddingTop'));

      function containsText(value) {
        return (value.replace(/\s/g, '').length > 0);
      }

      //var hasInitialValue = (this.value.replace(/\s/g, '').length > 0);

      //if (textarea.css('box-sizing') === 'border-box' ||
      //    textarea.css('-moz-box-sizing') === 'border-box') {
        //height = textarea.outerHeight();
        //console.log(this.scrollHeight, height, diff);
        if (this.scrollHeight + diff <= height) // special case for Firefox where scrollHeight isn't full height on border-box
          diff = 0;
      //}

      if (containsText(this.value)) {
        textarea.height(this.scrollHeight);
      }

      textarea.on('scroll input keyup', function(event){ // keyup is required for IE to reset height properly when deleting text
        if (event.keyCode == 13 && !event.shiftKey) {
          // just allow default behavior to enter new line
          if (!containsText(this.value)) {
            event.stopImmediatePropagation();
            event.stopPropagation();
          }
        }
        //console.log(this.scrollHeight - diff, diff);
        textarea.height('auto');
        //textarea.height(Math.max(height - diff, this.scrollHeight - diff));
        textarea.height(this.scrollHeight - diff);
        //console.log(this.scrollHeight - diff, diff);
      });
    });
  }
})(jQuery);
<commit_msg>Remove script from examples folder as we'll place it in a src directory and use gulpjs.<commit_after><|endoftext|>