define(["ng.cla.core.lmsg","cla_angular","/intranet/projects/js/built/projects.libs.js","jquery","ng.cla.core.breadcrumb","url-parse"], function(__WEBPACK_EXTERNAL_MODULE_0__, __WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_8__) { return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "/intranet/projects/js/built/";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 16);
/******/ })
/************************************************************************/
/******/ ({

/***/ "../../../node_modules/css-loader/index.js!../../../node_modules/sass-loader/lib/loader.js!./assets/css/project_list.scss":
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__("../../../node_modules/css-loader/lib/css-base.js")();
// imports


// module
exports.push([module.i, "/* project list */\n.project-list {\n  margin: 10px 0;\n}\n\n.project-list-item {\n  position: relative;\n  margin-bottom: 10px;\n}\n\n.list-mixed .project-is-bookmarked.project-list-item,\n.list-thumbnail .project-list-item {\n  padding-right: 15px;\n  margin-bottom: 25px;\n}\n\n.list-mixed .project-is-bookmarked .project-list-details,\n.list-thumbnail .project-list-details {\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);\n}\n\n.list-mixed .project-is-bookmarked .project-list-details:hover,\n.list-thumbnail .project-list-details:hover {\n  border-color: hsl(207, 71%, 57%);\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1), 0 0 0 1px #00adef;\n}\n\n.project-list-bookmark,\n.project-list-bookmark:active {\n  font-size: 18px;\n  color: hsl(214, 32%, 91%);\n}\n\n.list-thumbnail .project-list-bookmark,\n.list-thumbnail .project-list-bookmark:active {\n  color: #fff;\n}\n\n.project-list-bookmark:hover {\n  color: hsl(214, 32%, 91%);\n}\n\n.project-progress {\n  background-color: hsl(204, 45%, 98%);\n  padding: 15px;\n}\n\n.project-progress-component {\n  background-color: hsl(204, 45%, 98%);\n  padding: 15px;\n  max-width: 150px;\n}\n\ntable .project-progress-component {\n  padding: 0;\n}\n\n.project-list-details:hover .project-list-body {\n  background-color: hsl(204, 45%, 98%);\n}\n\n.project-list-details:hover .project-progress {\n  background-color: hsl(214, 32%, 91%);\n}\n\n.project-list-img {\n  display: block;\n  position: relative;\n  background-color: hsl(204, 45%, 98%);\n  background: no-repeat;\n  background-size: 100% auto;\n  background-position: center;\n  position: relative;\n  transition: 0.2s ease-in-out background-size;\n}\n\n.list-mixed .project-is-bookmarked .project-list-img,\n.list-thumbnail .project-list-img {\n  overflow: hidden;\n}\n\n.list-mixed .project-is-bookmarked .project-list-details:hover .project-list-img,\n.list-thumbnail .project-list-details:hover .project-list-img {\n  background-size: 120% auto;\n}\n\n.list-thumbnail .project-list-name,\n.list-mixed .project-is-bookmarked .project-list-name {\n  background-color: rgba(0, 0, 0, 0.5);\n}\n\n.project-list-details:hover {\n  text-decoration: none;\n}\n\n.list-mixed .project-is-bookmarked .project-list-body,\n.list-thumbnail .project-list-body {\n  padding: 10px;\n}\n\n.project-list-name {\n  /*color: #FFF;*/\n  line-height: 1.6em;\n  font-weight: normal;\n  padding: 5px;\n  margin: 0;\n}\n\n.list-mixed .project-is-bookmarked .project-list-name,\n.list-thumbnail .project-list-name {\n  color: #fff;\n  position: absolute;\n  bottom: 0;\n  left: 5px;\n  left: 0;\n  right: 0;\n  text-overflow: ellipsis;\n  max-height: 3.4em;\n  overflow: hidden;\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  -webkit-box-orient: vertical;\n}\n\n.project-list .progress {\n  margin: 0;\n  height: 6px;\n  background-color: #fff;\n  border-radius: 0;\n  -webkit-box-shadow: none;\n  -moz-box-shadow: none;\n  box-shadow: none;\n}\n\n.project-list .progress-bar {\n  background-color: hsl(145, 44%, 51%);\n  box-shadow: none;\n}\n\n.form-control-medium {\n  max-width: 120px;\n}\n\n.list-mixed .project-is-bookmarked .project-list-rag,\n.list-thumbnail .project-list-rag {\n  border-radius: 10px;\n}\n\n/* list-thumbnail */\n.list-thumbnail .project-list-bookmark,\n.list-mixed .project-is-bookmarked .project-list-bookmark {\n  position: absolute;\n  top: 5px;\n  right: 20px;\n  z-index: 2;\n}\n\n/* list mixed */\n/* list list */\n.list-mixed .project-not-bookmarked {\n  clear: left;\n}\n\n.list-mixed .project-not-bookmarked .project-list-details,\n.list-list .project-list-details {\n  background-color: hsl(204, 45%, 98%);\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);\n}\n\n.list-mixed .project-not-bookmarked .project-list-details:hover,\n.list-list .project-list-details:hover {\n  background-color: hsl(204, 45%, 98%);\n  box-shadow: 0 0 3px rgba(0, 0, 0, 0.1), 0 0 0 1px #00adef;\n}\n\n.list-list .project-list-bookmark,\n.list-mixed .project-not-bookmarked .project-list-bookmark {\n  float: left;\n  margin-top: 5px;\n  margin-left: 5px;\n}\n\n.list-mixed .project-not-bookmarked .project-list-name,\n.list-list .project-list-name {\n  font-size: 15px;\n}\n\n.list-mixed .project-not-bookmarked .project-progress,\n.list-mixed .project-not-bookmarked .project-list-company,\n.list-mixed .project-not-bookmarked .project-list-img,\n.list-list .project-progress {\n  display: none;\n}\n\n.cards--list .project-list-label {\n  float: right;\n}\n\n.list-mixed .project-not-bookmarked .project-list-img,\n.list-list .project-list-img {\n  background: none !important;\n}\n\n.list-mixed .project-not-bookmarked .project-list-item,\n.list-list .project-list-item {\n  margin-bottom: 10px;\n}\n\n.list-mixed .project-not-bookmarked .project-list-body,\n.list-list .project-list-body {\n  position: absolute;\n  top: 7px;\n  right: 7px;\n}\n\n.list-mixed .project-not-bookmarked .project-list-details,\n.list-list .project-list-details {\n  padding-left: 25px;\n  padding-right: 100px;\n}\n\n.cards--grid .card .card__bookmark {\n  z-index: 3;\n}\n\n.cards--list .card-content {\n  min-height: 80px;\n}\n\n/* Project list component */\n.project-component-list-item {\n  position: relative;\n  border-bottom: 1px solid hsl(210, 38%, 95%);\n  padding-top: 5px;\n  padding-bottom: 5px;\n}\n\n@media only screen and (min-width: 480px) {\n  .list-mixed .project-list-item.project-is-bookmarked,\n  .list-thumbnail .project-list-item {\n    float: left;\n    width: 230px;\n  }\n}", ""]);

// exports


/***/ }),

/***/ "../../../node_modules/css-loader/index.js!../../../node_modules/sass-loader/lib/loader.js!./assets/css/style.scss":
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__("../../../node_modules/css-loader/lib/css-base.js")();
// imports


// module
exports.push([module.i, ".task-section-edit-colour {\n  display: inline-block;\n}\n\n.tasks-board {\n  overflow-x: scroll;\n  overflow-y: hidden;\n}\n\n.tasks-board-scrollable {\n  display: flex;\n  flex-flow: row nowrap;\n  width: fit-content;\n  position: relative;\n}\n\n.task-board-list {\n  padding: 10px 0;\n}\n\n.status-dot {\n  height: 18px;\n  width: 18px;\n  display: block;\n  border-radius: 10rem;\n}\n\n.status-dot-history {\n  height: 10px;\n  width: 10px;\n  display: inline-block;\n  border-radius: 10rem;\n}\n\n.board-status-column.board-status-header {\n  background-color: hsl(204, 45%, 98%);\n  padding: 10px;\n  vertical-align: middle;\n  color: hsl(218, 21%, 23%);\n}\n\n.board-status-column {\n  width: 300px;\n  display: inline-block;\n  height: 100%;\n  background-color: hsl(204, 45%, 98%);\n  margin: 0 5px;\n  min-height: 40px;\n  border-radius: 5px;\n}\n\n.board-status-media {\n  overflow: visible;\n}\n\n/* Custom styling for the board column rename form input */\n.board-status-media .board-status-input {\n  width: 120px;\n  height: 30px;\n}\n\n.btn-board-status {\n  padding-top: 3px;\n  padding-bottom: 3px;\n}\n\n/* Board mode task item styling  */\n.task-item.board-task {\n  margin: 10px;\n}\n\n.task-item.list-task {\n  padding: 0.25rem 0.5rem;\n  margin-bottom: -1px;\n  border: 1px solid hsl(214, 32%, 91%);\n}\n\n.task-item.list-task .task-item-complete {\n  text-decoration: line-through;\n}\n\n.task-item.list-task .task-item-icon {\n  font-size: 1.15rem;\n  vertical-align: middle;\n}\n\n.task-item-icon-gray {\n  color: hsl(219, 10%, 49%);\n}\n\n.task-item-text {\n  color: hsl(219, 15%, 35%);\n}\n\n.board-task {\n  position: relative;\n  margin: 10px;\n}\n\n.board-task .board-task-title a {\n  color: hsl(218, 21%, 23%);\n}\n\n.board-task-drop-container {\n  display: inline-block;\n  height: 100%;\n  width: 100%;\n}\n\n.as-sortable-dragging,\n.as-sortable-dragging .task-item.board-task {\n  background: white;\n  position: relative;\n}\n\n.as-sortable-dragging .task-item.board-task .card {\n  box-shadow: 0px 12px 8px -6px rgba(0, 0, 0, 0.15);\n}\n\n.project-header .avatar {\n  margin-right: 5px;\n  width: 30px;\n  border-radius: 15px;\n}\n\n.menu-wrapper {\n  float: right;\n  margin-left: 5px;\n  margin-top: 5px;\n}\n\n.project-header-options {\n  float: right;\n  margin-top: 8px;\n}\n\n.header-row {\n  margin-bottom: 10px;\n}\n\n.projects.details .btn-rag {\n  border: none;\n  padding: 0;\n  font-size: 15px;\n  color: hsl(219, 15%, 35%);\n  background: hsl(210, 38%, 95%);\n  height: 30px;\n  width: 30px;\n  margin-left: 5px;\n  border-radius: 10rem;\n  font-weight: bold;\n}\n\n/* Changes text colour of active RAG item to #fff */\n.projects.details .btn-rag.active {\n  color: #fff;\n}\n\n.project-description img {\n  max-width: 100%;\n  height: auto !important;\n}\n\n.sub-header {\n  text-align: right;\n}\n\n.rag-status {\n  display: inline-block;\n}\n\n.project-image {\n  border-radius: var(--theme-rounded-corners);\n  max-width: 185px;\n}\n\n@media only screen and (max-width: 768px) {\n  .sub-header {\n    text-align: left;\n  }\n}\n.project-more-info {\n  margin-top: 10px;\n}\n\n.project-update-icon {\n  box-shadow: 0 0 9px 5px rgba(0, 0, 0, 0.07);\n  border-radius: 10rem;\n  padding: 0.6rem;\n  display: block;\n}\n\n.project-summary img {\n  border-radius: 50%;\n}\n\n.project-summary small {\n  display: block;\n}\n\n.tab-content .panel {\n  margin-top: 10px;\n}\n\n.tab-content .panel h3 {\n  margin: 5px 0;\n}\n\n.project-progress {\n  background-color: hsl(210, 38%, 95%);\n  padding: 15px 15px 0;\n}\n\n.project-list-details .project-progress {\n  padding-bottom: 15px;\n}\n\n.progress {\n  margin: 0;\n  height: 6px;\n  background-color: hsl(210, 38%, 95%);\n  border-radius: 0;\n  box-shadow: none;\n}\n\n.progress-bar {\n  box-shadow: none;\n}\n\n.files-show-more {\n  margin-top: 15px;\n  padding: 5px 10px;\n  display: block;\n  border: 1px solid hsl(210, 38%, 95%);\n  text-align: center;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n\n.files-show-more:hover {\n  border-color: hsl(214, 32%, 91%);\n  background-color: hsl(204, 45%, 98%);\n  text-decoration: none;\n}\n\n/* sections */\n.new-section {\n  border-bottom: 1px solid hsl(214, 32%, 91%);\n  background-color: hsl(204, 45%, 98%);\n}\n\n/* task list */\n.task-list-section {\n  margin-bottom: 0;\n}\n\n.task-list-section .panel-heading {\n  position: relative;\n  overflow: visible;\n}\n\n.task-list-section .kolorPicker,\n.task-list-section .kolorPicker-wrapper {\n  display: inline-block;\n}\n\n.task-list-items {\n  min-height: 10px; /* Used to keep a drag+drop placeholder visible when list is empty */\n  margin-bottom: 0;\n}\n\n/* Allows board cards to be dragged between status columns when empty */\n.board-status-column [as-sortable=\"ctrl.dragTaskListeners\"] {\n  min-height: 130px;\n  height: 100%;\n}\n\n/* Aligns text in add task button to the left, overrides standard .btn-block styling */\n.btn.btn-add-task {\n  text-align: left;\n}\n\n.task-list-item .sortable {\n  cursor: move;\n}\n\n@media only screen and (max-width: 767px) {\n  .task-list-section .form-inline > input {\n    margin-bottom: 10px;\n  }\n}\n.task-item .checkbox-inline {\n  margin-top: -22px;\n}\n\n.task-list-item .section {\n  min-width: 40px;\n  min-height: 1px;\n  margin-top: -7px;\n  display: block;\n  float: right;\n}\n\n.team-role-variant-1 {\n  background-color: hsl(0, 74%, 57%);\n}\n\n.team-role-variant-2 {\n  background-color: hsl(237, 45%, 52%);\n}\n\n.team-role-variant-2 ~ .team-role-variant-2 {\n  background-color: hsl(143, 53%, 62%);\n}\n\n.team-role-variant-3 {\n  background-color: hsl(207, 71%, 57%);\n}\n\n.team-role-variant-4 {\n  background-color: hsl(179, 49%, 39%);\n}\n\n.team-role-variant-5 {\n  background-color: hsl(152, 44%, 28%);\n}\n\n.team-role-variant-6 {\n  background-color: hsl(148, 46%, 43%);\n}\n\n.team-role-variant-7 {\n  background-color: hsl(33, 88%, 65%);\n}\n\n.team-role-variant-8 {\n  background-color: hsl(0, 59%, 48%);\n}\n\n.team-role-variant-8 ~ .team-role-variant-8 {\n  background-color: hsl(242, 36%, 41%);\n}\n\n.team-role-variant-9 {\n  background-color: hsl(16, 63%, 37%);\n}\n\n.team-role-variant-10 {\n  background-color: hsl(218, 21%, 23%);\n}\n\n.task-duration-unit {\n  padding-top: 7px;\n}\n\n.task-duration-unit.hide-unit {\n  visibility: hidden;\n}\n\n/* READY FOR CONVERSION TO SCSS */\n@media only screen and (min-width: 768px) {\n  .project-info {\n    display: flex;\n  }\n}\n.project-info {\n  margin-bottom: 10px;\n}\n\n.project-info .project-info-left {\n  position: relative;\n}\n\n.project-info-left::after {\n  content: \"\";\n  width: 1px;\n  top: 0;\n  bottom: 0;\n  right: 0;\n  background: hsl(210, 38%, 95%);\n  position: absolute;\n  margin: 0 7px;\n}\n\n@media only screen and (max-width: 768px) {\n  .project-info .project-info-left {\n    margin-bottom: 15px;\n    padding-bottom: 15px;\n  }\n  .project-info .project-info-left::after {\n    left: 0;\n    top: unset;\n    height: 1px;\n    width: auto;\n    margin: 0 15px;\n  }\n}\n/* Allows media to display overflow so custom border can be displayed on meta data */\n.meta-custom-wrapper {\n  overflow: visible;\n}\n\n.meta-custom {\n  position: relative;\n}\n\n/* Adds left-hand side border to meta blocks */\n.meta-custom::after {\n  content: \"\";\n  top: 0;\n  bottom: 10px;\n  left: 0;\n  border-left: 1px solid hsl(210, 38%, 95%);\n  position: absolute;\n  margin-left: -10px;\n}\n\n/* Hides left hand border on smaller screens */\n@media only screen and (max-width: 768px) {\n  .meta-custom::after {\n    display: none;\n  }\n}\n/* Adds custom margin to the bottom of the 'last modified' text so the 'created on' text aligns with the RAG status */\n.meta-custom-spacing {\n  margin-bottom: 18px;\n}\n\n/* Resets custom margin on smaller screens */\n@media only screen and (max-width: 768px) {\n  .meta-custom-spacing {\n    margin-bottom: 10.5px;\n  }\n}\n.loading-table {\n  opacity: 0.4;\n}\n\n.team-list-spinner {\n  left: 50%;\n  top: 50%;\n}\n\n.tasks-profile-img {\n  width: 25px;\n  height: 25px;\n}\n\n.btn.btn-custom-due-date {\n  padding-left: 0;\n}\n\n/* Custom position of completed toggle switch which aligns it right on desktop and left on smaller screens */\n.custom-toggle-position {\n  text-align: right;\n}\n\n@media only screen and (max-width: 768px) {\n  .custom-toggle-position {\n    text-align: left;\n  }\n}\n/* Adds custom styling to task priotity badge so it is vertically aligned with other items */\n.task-badge {\n  margin-right: 10px;\n  margin-top: 10px;\n  display: inline-block;\n}\n\n.delete-confirm-icon {\n  line-height: 70px;\n  font-size: 50px;\n  color: hsl(219, 10%, 49%);\n}\n\n/* Board mode - 'Saving' dialog box, which appears when a card has been moved */\n.tasks-board-saving {\n  position: fixed;\n  z-index: 99;\n  background: #fff;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  margin: 0 auto 20px;\n  padding: 10px;\n  width: 160px;\n  border-radius: 8px;\n  box-shadow: 0px 0px 18px 3px rgba(0, 0, 0, 0.1);\n}\n\n.overview-page-wrapper .card-overview {\n  box-shadow: none;\n  margin-bottom: 1rem;\n}\n\n.overview-page-wrapper .card-overview .card-header-overview {\n  padding: 0;\n}\n\n.overview-page-wrapper .card-header-overview .card-title {\n  font-weight: bold;\n}\n\n.overview-page-wrapper .card-header-overview .show-all-text {\n  font-size: 14px;\n}\n\n.overview-page-wrapper .card-header-overview .card-title .btn-overview {\n  margin-top: -20px;\n  margin-bottom: -10px;\n}\n\n.dashboard-profile-img {\n  border-radius: 10rem;\n}\n\n.overview-page-wrapper .card-body-overview {\n  max-height: 300px;\n  overflow-y: auto;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n/* Topics Styling */\n/* Topics table styling */\n.topics-table,\n.topics-table > tbody > tr > td,\n.topics-table > thead > tr > th {\n  border: none;\n}\n\n/* Topics table header styling */\n.topics-table thead tr th.sorting,\n.topics-table thead tr th.sorting_asc,\n.topics-table thead tr th.sorting_desc {\n  position: relative;\n  padding-left: 25px;\n}\n\n/* Workaround to show board tasks as like cla-card without actually being one */\n.card .card-status-border {\n  position: absolute;\n  width: 6px;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  border-radius: 8px 0 0 8px;\n  z-index: 1;\n}\n\n/* Sets minimum width of pinnable wrapper to 120px */\n.pinnable {\n  min-width: 120px;\n}\n\n/* Styling for sorting arrows */\n.sorting::after, .sorting_asc::after, .sorting_desc::after,\n.sorting::before, .sorting_asc::before, .sorting_desc::before {\n  content: \"\";\n  position: absolute;\n  left: 9px;\n  border-style: solid;\n  border-width: 2px;\n  border-color: #fff;\n  width: 7px;\n  height: 7px;\n  transform: rotate(-45deg);\n}\n\n/* Positions top arrow to the top */\n.sorting::before, .sorting_asc::before, .sorting_desc::before {\n  top: 50%;\n  margin-top: -6px;\n}\n\n/* Positions bottom arrow to the bottom */\n.sorting::after, .sorting_asc::after, .sorting_desc::after {\n  bottom: 50%;\n  margin-bottom: -6px;\n}\n\n/* Sets inactive top arrow to light grey */\n.sorting::before, .sorting_desc::before {\n  border-top-color: hsl(219, 15%, 35%);\n  border-right-color: hsl(219, 15%, 35%);\n}\n\n/* Sets inactive bottom arrow to light grey */\n.sorting::after, .sorting_asc::after {\n  border-bottom-color: hsl(219, 15%, 35%);\n  border-left-color: hsl(219, 15%, 35%);\n}\n\n/* Sets active top arrow to dark grey */\n.sorting_desc::after {\n  border-bottom-color: hsl(220, 26%, 14%);\n  border-left-color: hsl(220, 26%, 14%);\n}\n\n/* Sets active bottom arrow to dark grey */\n.sorting_asc::before {\n  border-top-color: hsl(220, 26%, 14%);\n  border-right-color: hsl(220, 26%, 14%);\n}\n\n/* Adds margin to bottom of table to fix issue with the table having to scroll */\n.topic-table-info {\n  display: block;\n  margin-top: 30px;\n  margin-bottom: 35px;\n}\n\n/* Puts the topic user images into a wrapper which stops the items inside from breaking line and limits the width of the table */\n.user-images-wrapper {\n  white-space: nowrap;\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n  max-width: 425px;\n}\n\n/* Adds right hand gradient to show when there are more users than can be displayed */\n.user-images-wrapper:after {\n  content: \"\";\n  position: absolute;\n  right: 0;\n  top: 0;\n  bottom: 0;\n  width: 40px;\n  background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgb(255, 255, 255) 100%);\n}\n\n/* Limits the width of the topic user images on tablet sized screens */\n@media only screen and (max-width: 768px) {\n  .user-images-wrapper {\n    max-width: 225px;\n  }\n}\n/* Limits the width of the topic user images on mobile sized screens */\n@media only screen and (max-width: 450px) {\n  .user-images-wrapper {\n    max-width: 85px;\n  }\n}\n/* Individual topic page styling    */\n.topic-details-list td {\n  padding: 0 10px;\n}\n\n.topic-title {\n  display: inline-block;\n}\n\n/* Project overview page */\n/* Comments component */\n.comment-attachments .comment-attachments-icon,\n.comment-count .comment-count-icon {\n  color: hsl(219, 10%, 49%);\n}\n\n/* Added a max-width to images in history so they don't overflow  */\n.history-wrapper img {\n  max-width: 100%;\n  height: auto !important;\n}\n\n/* Code to reverse styling of the files component so it fits the asthetics of the projects tabs */\n.projects-file-component .dms-view {\n  padding: 0;\n}\n\n.projects-file-component .dms-view .panel-body {\n  padding-top: 0;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n.modal-backdrop + .modal-backdrop {\n  opacity: 0;\n}\n\n.add-project-wrapper {\n  position: relative;\n}\n.add-project-wrapper + .add-project-wrapper::after {\n  content: \"\";\n  background: hsl(214, 32%, 91%);\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: -8px;\n  width: 1px;\n}\n\n.tile-my-projects-component .table-responsive {\n  border-top: none;\n}\n\n.table-avatar {\n  width: 22px;\n  position: relative;\n  margin-top: -4px;\n  border-radius: 150%;\n}\n\n.rag-R {\n  background-color: hsl(0, 74%, 57%);\n}\n\n.rag-A {\n  background-color: hsl(27, 82%, 57%);\n}\n\n.rag-G {\n  background-color: hsl(145, 44%, 51%);\n}\n\n.project-bookmark {\n  color: hsl(24, 73%, 50%);\n}\n\n.project-bookmark:hover {\n  color: lignten(hsl(24, 73%, 50%), 10%);\n}\n\n.task-item .checkbox-inline {\n  margin-top: -22px;\n}\n\n/* ng-sortable drag and drop */\n.as-sortable-placeholder {\n  min-height: 20px;\n  border: 2px dashed hsl(214, 18%, 63%);\n  border-radius: 5px;\n}\n\n/* ng-sortable drag and drop specifically for task cards*/\n.tasks-board-scrollable.tasks-board-tasks .as-sortable-placeholder {\n  width: calc(100% - 20px) !important;\n  margin: 6px 10px;\n  border-radius: 8px;\n}\n\n/* ng-sortable drag and drop for Task List*/\n.task-list-items .as-sortable-placeholder {\n  background: hsl(204, 45%, 98%);\n  margin: 5px;\n  width: calc(100% - 10px) !important;\n}\n\n.as-sortable-drag {\n  opacity: 0.8;\n  position: absolute;\n  pointer-events: none;\n  z-index: 9999;\n}\n\n.task-priority-option {\n  display: inline-block;\n  width: 16px;\n  height: 16px;\n  margin-top: 5px;\n  vertical-align: text-bottom;\n}\n\n.task-priority-sidestrip {\n  position: absolute;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  width: 8px;\n  z-index: 2;\n  border-radius: 0.25rem 0 0 0.25rem;\n}\n\n.task-priority-sidestrip .task-drag-area .drag-icon {\n  position: absolute;\n  top: 50%;\n  margin-top: -8px;\n}\n\n.task-priority-1 {\n  background-color: hsl(145, 44%, 51%);\n}\n\n.task-priority-2 {\n  background-color: hsl(27, 82%, 57%);\n}\n\n.task-priority-3 {\n  background-color: hsl(0, 84%, 68%);\n}\n\n.project-component-list-item td {\n  vertical-align: middle !important;\n}\n\n.project-component-rag {\n  border-radius: 50%;\n  padding: 4px 8px;\n}\n\n.projects-component-title-bar {\n  padding: 10px;\n  margin: 0 0 10px 0;\n  overflow: auto;\n  background-color: hsl(214, 32%, 91%);\n}\n\n.projects-component-title {\n  font-size: larger;\n}\n\n.project-component-services img {\n  padding-right: 5px;\n}\n\n.alert-full-width {\n  width: 100%;\n  display: inline-block;\n}\n\n.task-drag-area {\n  height: 100%;\n}\n\n.wysibb-text {\n  overflow: auto;\n}\n\n/* Tasks Component */\n.my-tasks-component .card-header-overview {\n  display: none;\n}\n\n.tile-my-tasks-component[data-gs-width=\"1\"] .task-item .task-project-name,\n.tile-my-tasks-component[data-gs-width=\"1\"] .task-item .task-date {\n  display: block;\n  float: none !important;\n}\n\n.history_type {\n  font-weight: bold;\n}\n\n.history_list_item_title {\n  font-weight: bold;\n}\n\n.history-status {\n  font-style: italic;\n}\n\n.history-list {\n  font-style: italic;\n}\n\n.card-wrapper:nth-child(4n+1) {\n  clear: both;\n}\n\n/* MAKE RIGHTS TABLE SCROLLABLE ON SMALL DEVICES */\n.rights-table-wrapper > div {\n  overflow-y: auto;\n}\n\n/* Spacing on My Tasks component */\n.sub-items .task-project-name {\n  margin-right: 10px;\n}\n\n.collapsable-info-panel .nav-stacked > li.active > a,\n.collapsable-info-panel .nav-stacked > li.active > a:hover {\n  background: hsl(207, 71%, 57%);\n}\n\n.tasks-profile-img {\n  width: 25px;\n  height: 25px;\n}\n\n/* Tasks item styling */\n.task-users {\n  padding: 6px 12px;\n}\n\n.extra-user-count {\n  padding: 2px 5px;\n  border-radius: 10rem;\n  background: hsl(210, 38%, 95%);\n  font-weight: bold;\n}\n\n.extra-user-count:hover {\n  background: hsl(210, 38%, 100%);\n  cursor: pointer;\n}\n\n.tasks-profile-img {\n  width: 25px;\n  height: 25px;\n}\n\n.cursor-default {\n  cursor: default;\n}\n\n/* Styles individual task profile images */\n.tasks-profile-single {\n  margin-left: 3px;\n  margin-bottom: 3px;\n  display: inline-block;\n}\n\n/* Adds a seperator line between the Polls and Surveys in Add modal. */\n.add-tasks-wrapper {\n  position: relative;\n}\n\n.add-tasks-wrapper + .add-tasks-wrapper::after {\n  content: \"\";\n  background: red;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: -8px;\n  width: 1px;\n}\n\n.projects-file-component .document-list .icons-view .document-item {\n  flex: 0 0 25%;\n  max-width: 25%;\n}\n\n.drag-container {\n  height: 100%;\n  position: relative;\n}", ""]);

// exports


/***/ }),

/***/ "../../../node_modules/css-loader/index.js!../../../node_modules/sass-loader/lib/loader.js!./js/ng/modules/widgets/css/user_list.component.scss":
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__("../../../node_modules/css-loader/lib/css-base.js")();
// imports


// module
exports.push([module.i, ".user-list-component .user-list-wrapper {\n  white-space: nowrap;\n}\n.user-list-component .user-list-wrapper::after {\n  content: \"\";\n  clear: both;\n  height: 0;\n  display: block;\n}\n.user-list-component .user-list, .user-list-component .plus-number-wrapper {\n  margin: 0;\n  padding: 0;\n}\n.user-list-component .user-list {\n  margin-right: 3%;\n  display: inline;\n}\n.user-list-component .plus-number-wrapper {\n  width: 18%;\n  position: relative;\n  background: hsl(214, 32%, 91%); /* $gray-300 */\n  border-radius: 350px;\n  display: inline-block;\n  vertical-align: top;\n  cursor: pointer;\n}\n.user-list-component .plus-number-wrapper::after {\n  content: \"\";\n  display: block;\n  padding-bottom: 100%;\n}\n.user-list-component .plus-number-wrapper .plus-number {\n  position: absolute;\n  font-size: 14px;\n  top: 50%;\n  left: 0;\n  right: 0;\n  text-align: center;\n  transform: translate(0, -50%);\n  line-height: 0;\n}\n.user-list-component .plus-number-wrapper .plus-number:hover {\n  text-decoration: none;\n  color: var(--black);\n  opacity: 0.8;\n}\n.user-list-component .plus-number-wrapper .plus-number.plus-number[href=\"javascript:void(0);\"]:hover {\n  opacity: 1;\n  cursor: default;\n}\n.user-list-component .title {\n  font-size: 14px;\n}\n.user-list-component .title, .user-list-component .plus-number {\n  color: var(--black);\n}\n.user-list-component div.user-list-item {\n  float: left;\n  list-style: none;\n  width: 18%;\n  margin-right: 2%;\n}\n.user-list-component div.user-list-item a {\n  overflow: hidden;\n  border-radius: 350px;\n  display: block;\n}\n.user-list-component div.user-list-item a[href=\"javascript:void(0);\"]:hover {\n  opacity: 1;\n  cursor: default;\n}\n.user-list-component div.user-list-item a img {\n  width: 100%;\n}", ""]);

// exports


/***/ }),

/***/ "../../../node_modules/css-loader/lib/css-base.js":
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function() {
	var list = [];

	// return the list of modules as css string
	list.toString = function toString() {
		var result = [];
		for(var i = 0; i < this.length; i++) {
			var item = this[i];
			if(item[2]) {
				result.push("@media " + item[2] + "{" + item[1] + "}");
			} else {
				result.push(item[1]);
			}
		}
		return result.join("");
	};

	// import a list of modules into the list
	list.i = function(modules, mediaQuery) {
		if(typeof modules === "string")
			modules = [[null, modules, ""]];
		var alreadyImportedModules = {};
		for(var i = 0; i < this.length; i++) {
			var id = this[i][0];
			if(typeof id === "number")
				alreadyImportedModules[id] = true;
		}
		for(i = 0; i < modules.length; i++) {
			var item = modules[i];
			// skip already imported module
			// this implementation is not 100% perfect for weird media query combinations
			//  when a module is imported multiple times with different media queries.
			//  I hope this will never occur (Hey this way we have smaller bundles)
			if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
				if(mediaQuery && !item[2]) {
					item[2] = mediaQuery;
				} else if(mediaQuery) {
					item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
				}
				list.push(item);
			}
		}
	};
	return list;
};


/***/ }),

/***/ "../../../node_modules/style-loader/addStyles.js":
/***/ (function(module, exports, __webpack_require__) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var stylesInDom = {},
	memoize = function(fn) {
		var memo;
		return function () {
			if (typeof memo === "undefined") memo = fn.apply(this, arguments);
			return memo;
		};
	},
	isOldIE = memoize(function() {
		// Test for IE <= 9 as proposed by Browserhacks
		// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
		// Tests for existence of standard globals is to allow style-loader 
		// to operate correctly into non-standard environments
		// @see https://github.com/webpack-contrib/style-loader/issues/177
		return window && document && document.all && !window.atob;
	}),
	getElement = (function(fn) {
		var memo = {};
		return function(selector) {
			if (typeof memo[selector] === "undefined") {
				memo[selector] = fn.call(this, selector);
			}
			return memo[selector]
		};
	})(function (styleTarget) {
		return document.querySelector(styleTarget)
	}),
	singletonElement = null,
	singletonCounter = 0,
	styleElementsInsertedAtTop = [],
	fixUrls = __webpack_require__("../../../node_modules/style-loader/fixUrls.js");

module.exports = function(list, options) {
	if(typeof DEBUG !== "undefined" && DEBUG) {
		if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};
	options.attrs = typeof options.attrs === "object" ? options.attrs : {};

	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (typeof options.singleton === "undefined") options.singleton = isOldIE();

	// By default, add <style> tags to the <head> element
	if (typeof options.insertInto === "undefined") options.insertInto = "head";

	// By default, add <style> tags to the bottom of the target
	if (typeof options.insertAt === "undefined") options.insertAt = "bottom";

	var styles = listToStyles(list);
	addStylesToDom(styles, options);

	return function update(newList) {
		var mayRemove = [];
		for(var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];
			domStyle.refs--;
			mayRemove.push(domStyle);
		}
		if(newList) {
			var newStyles = listToStyles(newList);
			addStylesToDom(newStyles, options);
		}
		for(var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];
			if(domStyle.refs === 0) {
				for(var j = 0; j < domStyle.parts.length; j++)
					domStyle.parts[j]();
				delete stylesInDom[domStyle.id];
			}
		}
	};
};

function addStylesToDom(styles, options) {
	for(var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];
		if(domStyle) {
			domStyle.refs++;
			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}
			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];
			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}
			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles(list) {
	var styles = [];
	var newStyles = {};
	for(var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};
		if(!newStyles[id])
			styles.push(newStyles[id] = {id: id, parts: [part]});
		else
			newStyles[id].parts.push(part);
	}
	return styles;
}

function insertStyleElement(options, styleElement) {
	var styleTarget = getElement(options.insertInto)
	if (!styleTarget) {
		throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
	}
	var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
	if (options.insertAt === "top") {
		if(!lastStyleElementInsertedAtTop) {
			styleTarget.insertBefore(styleElement, styleTarget.firstChild);
		} else if(lastStyleElementInsertedAtTop.nextSibling) {
			styleTarget.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
		} else {
			styleTarget.appendChild(styleElement);
		}
		styleElementsInsertedAtTop.push(styleElement);
	} else if (options.insertAt === "bottom") {
		styleTarget.appendChild(styleElement);
	} else {
		throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
	}
}

function removeStyleElement(styleElement) {
	styleElement.parentNode.removeChild(styleElement);
	var idx = styleElementsInsertedAtTop.indexOf(styleElement);
	if(idx >= 0) {
		styleElementsInsertedAtTop.splice(idx, 1);
	}
}

function createStyleElement(options) {
	var styleElement = document.createElement("style");
	options.attrs.type = "text/css";

	attachTagAttrs(styleElement, options.attrs);
	insertStyleElement(options, styleElement);
	return styleElement;
}

function createLinkElement(options) {
	var linkElement = document.createElement("link");
	options.attrs.type = "text/css";
	options.attrs.rel = "stylesheet";

	attachTagAttrs(linkElement, options.attrs);
	insertStyleElement(options, linkElement);
	return linkElement;
}

function attachTagAttrs(element, attrs) {
	Object.keys(attrs).forEach(function (key) {
		element.setAttribute(key, attrs[key]);
	});
}

function addStyle(obj, options) {
	var styleElement, update, remove;

	if (options.singleton) {
		var styleIndex = singletonCounter++;
		styleElement = singletonElement || (singletonElement = createStyleElement(options));
		update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
		remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
	} else if(obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function") {
		styleElement = createLinkElement(options);
		update = updateLink.bind(null, styleElement, options);
		remove = function() {
			removeStyleElement(styleElement);
			if(styleElement.href)
				URL.revokeObjectURL(styleElement.href);
		};
	} else {
		styleElement = createStyleElement(options);
		update = applyToTag.bind(null, styleElement);
		remove = function() {
			removeStyleElement(styleElement);
		};
	}

	update(obj);

	return function updateStyle(newObj) {
		if(newObj) {
			if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
				return;
			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;
		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag(styleElement, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (styleElement.styleSheet) {
		styleElement.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = styleElement.childNodes;
		if (childNodes[index]) styleElement.removeChild(childNodes[index]);
		if (childNodes.length) {
			styleElement.insertBefore(cssNode, childNodes[index]);
		} else {
			styleElement.appendChild(cssNode);
		}
	}
}

function applyToTag(styleElement, obj) {
	var css = obj.css;
	var media = obj.media;

	if(media) {
		styleElement.setAttribute("media", media)
	}

	if(styleElement.styleSheet) {
		styleElement.styleSheet.cssText = css;
	} else {
		while(styleElement.firstChild) {
			styleElement.removeChild(styleElement.firstChild);
		}
		styleElement.appendChild(document.createTextNode(css));
	}
}

function updateLink(linkElement, options, obj) {
	var css = obj.css;
	var sourceMap = obj.sourceMap;

	/* If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
	and there is no publicPath defined then lets turn convertToAbsoluteUrls
	on by default.  Otherwise default to the convertToAbsoluteUrls option
	directly
	*/
	var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;

	if (options.convertToAbsoluteUrls || autoFixUrls){
		css = fixUrls(css);
	}

	if(sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = linkElement.href;

	linkElement.href = URL.createObjectURL(blob);

	if(oldSrc)
		URL.revokeObjectURL(oldSrc);
}


/***/ }),

/***/ "../../../node_modules/style-loader/fixUrls.js":
/***/ (function(module, exports) {


/**
 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
 * embed the css on the page. This breaks all relative urls because now they are relative to a
 * bundle instead of the current page.
 *
 * One solution is to only use full urls, but that may be impossible.
 *
 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
 *
 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
 *
 */

module.exports = function (css) {
  // get current location
  var location = typeof window !== "undefined" && window.location;

  if (!location) {
    throw new Error("fixUrls requires window.location");
  }

	// blank or null?
	if (!css || typeof css !== "string") {
	  return css;
  }

  var baseUrl = location.protocol + "//" + location.host;
  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");

	// convert each url(...)
	/*
	This regular expression is just a way to recursively match brackets within
	a string.

	 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
	   (  = Start a capturing group
	     (?:  = Start a non-capturing group
	         [^)(]  = Match anything that isn't a parentheses
	         |  = OR
	         \(  = Match a start parentheses
	             (?:  = Start another non-capturing groups
	                 [^)(]+  = Match anything that isn't a parentheses
	                 |  = OR
	                 \(  = Match a start parentheses
	                     [^)(]*  = Match anything that isn't a parentheses
	                 \)  = Match a end parentheses
	             )  = End Group
              *\) = Match anything and then a close parens
          )  = Close non-capturing group
          *  = Match anything
       )  = Close capturing group
	 \)  = Match a close parens

	 /gi  = Get all matches, not the first.  Be case insensitive.
	 */
	var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
		// strip quotes (if they exist)
		var unquotedOrigUrl = origUrl
			.trim()
			.replace(/^"(.*)"$/, function(o, $1){ return $1; })
			.replace(/^'(.*)'$/, function(o, $1){ return $1; });

		// already a full url? no change
		if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(unquotedOrigUrl)) {
		  return fullMatch;
		}

		// convert the url to a full url
		var newUrl;

		if (unquotedOrigUrl.indexOf("//") === 0) {
		  	//TODO: should we add protocol?
			newUrl = unquotedOrigUrl;
		} else if (unquotedOrigUrl.indexOf("/") === 0) {
			// path should be relative to the base url
			newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
		} else {
			// path should be relative to current directory
			newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
		}

		// send back the fixed url(...)
		return "url(" + JSON.stringify(newUrl) + ")";
	});

	// send back the fixed css
	return fixedCss;
};


/***/ }),

/***/ "./assets/css/project_list.scss":
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__("../../../node_modules/css-loader/index.js!../../../node_modules/sass-loader/lib/loader.js!./assets/css/project_list.scss");
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__("../../../node_modules/style-loader/addStyles.js")(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../../../node_modules/css-loader/index.js!../../../../../node_modules/sass-loader/lib/loader.js!./project_list.scss", function() {
			var newContent = require("!!../../../../../node_modules/css-loader/index.js!../../../../../node_modules/sass-loader/lib/loader.js!./project_list.scss");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ "./assets/css/style.scss":
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__("../../../node_modules/css-loader/index.js!../../../node_modules/sass-loader/lib/loader.js!./assets/css/style.scss");
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__("../../../node_modules/style-loader/addStyles.js")(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../../../node_modules/css-loader/index.js!../../../../../node_modules/sass-loader/lib/loader.js!./style.scss", function() {
			var newContent = require("!!../../../../../node_modules/css-loader/index.js!../../../../../node_modules/sass-loader/lib/loader.js!./style.scss");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ "./js/controller/projectFilterCtrl.js":
/***/ (function(module, exports) {

// Side panel page controller
(function()
{
	var moduleName = 'projectFilterApp';

    angular.module(moduleName)
        .controller('projectFilterCtrl', ['$scope', 'claProjectListService', projectFilterController]);

	function projectFilterController($scope, service)
	{
	    $scope.currentFilter = 'active';
        $scope.filters = service.getFilters();

        // If a filter is clicked
        $scope.setFilter = function($event, type, count) {
            $event.preventDefault();

            if (count === '')
                return;

            $scope.currentFilter = type;
            service.setFilter(type)

            // Closes side menu when an item is clicked
            var menuToggle = document.getElementById("page_content");
            menuToggle.classList.remove("open-categories-menu");


        };
    }
}());


/***/ }),

/***/ "./js/controller/projectListCtrl.js":
/***/ (function(module, exports) {

// Main page controller to update project list according to filters, search and pagination
(function()
{
	var moduleName = 'projectListApp';

	angular.module(moduleName)
		.controller("projectListCtrl", ['$scope', '$http', '$localStorage', '$timeout', 'breadcrumb.service', 'claProjectListService', 'confirmService', projectListController]);

	function projectListController($scope, $http, $localStorage, $timeout, breadcrumbService, service, confirmService)
	{
        $scope.projects = [];
        var projects = service.getProjects();

        for (var i = 0; i < projects.length; i++)
        {
            $scope.projects.push(projects[i]);
        }

        // Set up pagination vars
        $scope.isIE = /msie\s|trident\/|edge\//i.test(window.navigator.userAgent);
        $scope.currentPage = current_page;
        $scope.searchTerms = searchTerms;
        $scope.companyId = project_company_filter;
        $scope.sortOrder = sort;

        // Set up filter vars and highlight the right one
        $scope.filters = service.getFilters();

        breadcrumbService.setCrumbs(
            [
                {
                    'url': '/projects',
                    'name': lmsg('projects.breadcrumb.projects')
                }
            ]);

        service.registerCallback(function(){
            $scope.projects.length = 0;
            var projects = service.getProjects();

            for (var i = 0; i < projects.length; i++)
            {
                $scope.projects.push(projects[i]);
            }

            $timeout(function(){
                $scope.$digest();
            }, 0);
        });

        // View layout, saved in local storage
        $scope.$storage = $localStorage.$default({
            layoutType: 'list-thumbnail'
        });

        $scope.changeLayout = function(layout){
            $scope.$storage.layoutType = layout;
        };

        // Sorting
        $scope.changeSortOrder = function($event, orderby) {
            $event.preventDefault();

            if (orderby === $scope.sortOrder)
                return;

            service.changeSortOrder(orderby);
            $scope.sortOrder = orderby;
        };

        $scope.statusClasses =
            {
                1: 'warning',  // Draft
                2: 'success',  // Live
                3: 'info',     // On hold
                4: 'secondary' // Archived
            };

        // Bookmarks
        $scope.toggleBookmark = function($event, project_id, bookmark)
        {
            $event.preventDefault();

            service.toggleBookmark(project_id, bookmark);
		};

        // If pagination is clicked
        $scope.pageChanged = function(newPage) {
            $scope.currentPage = newPage;
            service.pageChanged(newPage);
        };

        $scope.search = function($event)
        {
            if ($event !== undefined)
                $event.preventDefault();

            service.search($scope.searchTerms);
        };

        $scope.getTotalCount = function()
        {
            return service.totalCount;
        }

        $scope.getCurrentPage = function()
        {
            return service.currentPage;
        }

        $scope.getProjectsPerPage = function()
        {
            return service.projectsPerPage;
        }

        $scope.confirmDelete = function(event, project_id)
        {
            event.preventDefault();

            confirmService.show({
                title: lmsg('projects.project.delete_project.title'),
                message: lmsg('projects.project.delete_confirm'),
            }).then(function() {
                service.deleteProject(project_id);
            }, function() {});
        }
    }
}());


/***/ }),

/***/ "./js/controller/projectNewCtrl.js":
/***/ (function(module, exports) {

// Controller used on modal dialog for new project to pick a template project
(function()
{
	var moduleName = 'projectListApp';

	angular.module(moduleName)
		.controller("projectNewCtrl", ["$scope", projectNewController])
		.directive("ngFormCommit", formCommitDirective);

	function projectNewController($scope)
	{
		$scope.template_projects_count = new_project.template_projects.length;
		$scope.non_template_projects_count = new_project.non_template_projects.length;
		$scope.project_options =
		{
			template: new_project.template_projects,
			project: new_project.non_template_projects
		};
		$scope.template_type = 'blank';
		$scope.template_selected =
		{
			template: new_project.template_projects[0],
			project: new_project.non_template_projects[0]
		};

		// Angular won't have created the select options yet so delay turning it into a select2 control
		setTimeout(function()
		{
			$('#projectTemplate').select2({ width: '100%' });
			$('#projectNonTemplate').select2({ width: '100%' });
		}, 50);

		$scope.submit = function(event, form)
		{
			// plain add doesn't need a form so just go to the add project page directly
			if ($scope.template_type == 'blank')
			{
				event.preventDefault();
				window.location = '/projects/add';
			} else
			{
				form.commit();
			}
		}
	}

	// Need to commit a form from outside of itself.
	// jQuery would work but not very Angular so this is a way to allow one to be submitted
	function formCommitDirective()
	{
		function link($scope, $el, $attr, $form)
		{
			$form.commit = function() {
				$el[0].submit();
			};
		}

		return {
			require:"form",
			link: link
		};
	}
}());

/***/ }),

/***/ "./js/ng/modules/widgets/component/checkbox.component.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/component/checkbox.component.html';
var html = "<span>\n\t<cla-checkbox large=\"{{$ctrl.large}}\" name=\"{{$ctrl.name}}\" ng-attr-checked=\"{{$ctrl.ngModel?true:undefined}}\" ng-attr-disabled=\"{{$ctrl.disabled?true:undefined}}\" ng-on-selected=\"$ctrl.onChecked($event)\" ng-on-unselected=\"$ctrl.onUnchecked($event)\" ng-transclude></cla-checkbox>\n</span>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/component/checkbox.component.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/component/checkbox.component.html")], __WEBPACK_AMD_DEFINE_RESULT__ = function (template)
{
    var Checkbox = {
        bindings: {
            ngModel: '=',
            large: '@',
            name: '@',
            disabled: '@',
        },
        require: { ngModelCtrl: 'ngModel' },
        templateUrl: template,
        transclude: true,
        controller: function () {
            var ctrl = this;

            ctrl.$onInit = function() {
                if (ctrl.disabled === undefined)
                    ctrl.disabled = false;
            };

            ctrl.onChecked = function($event) {
                $event.preventDefault();

                ctrl.ngModel = true;
                ctrl.ngModelCtrl.$setViewValue(ctrl.ngModel);
            }

            ctrl.onUnchecked = function($event) {
                $event.preventDefault();

                ctrl.ngModel = false;
                ctrl.ngModelCtrl.$setViewValue(ctrl.ngModel);
            }
        }
    };

    return Checkbox;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/component/confirm.component.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/component/confirm.component.html';
var html = "<div class=\"modal fade\" id=\"projects-confirm\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"more-info\">\n\t<div class=\"modal-dialog\" role=\"document\">\n\t\t<div class=\"modal-content\">\n\t\t\t<div class=\"modal-header\">\n\t\t\t\t<h5 class=\"modal-title\" id=\"more-info--label\">{{$ctrl.options.title}}</h5>\n\t\t\t\t<button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n\t\t\t\t\t<span aria-hidden=\"true\">\n\t\t\t\t\t\t<ion-icon name=\"close-outline\"></ion-icon>\n\t\t\t\t\t</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"modal-body\">\n\n\t\t\t\t<div class=\"media\">\n\t\t\t\t\t<div class=\"mr-3 align-self-center\">\n\t\t\t\t\t\t<span class=\"text-muted\">\n\t\t\t\t\t\t\t<ion-icon class=\"icon-xxl align-middle\" name=\"{{$ctrl.options.icon}}\"></ion-icon>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"media-body align-self-center\">\n\t\t\t\t\t\t<p class=\"mb-0\">{{$ctrl.options.message}}</p>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t</div>\n\t\t\t<div class=\"modal-footer\">\n\t\t\t\t<form id=\"task-edit-form\" class=\"form-horizontal\" name=\"taskForm\">\n\t\t\t\t\t<div ng-if=\"$ctrl.options.mode === 'cancel_delete'\">\n\t\t\t\t\t\t<button class=\"btn btn-link\" ng-click=\"$ctrl.cancel($event)\" lmsg=\"projects.task.cancel\">[Cancel]</button>\n\t\t\t\t\t\t<button class=\"btn btn-danger\" rel=\"tooltip\" ng-click=\"$ctrl.confirm($event)\"><lmsg src=\"projects.task.delete\">[Delete]</lmsg></button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div ng-if=\"$ctrl.options.mode === 'ok'\">\n\t\t\t\t\t\t<button class=\"btn btn-primary\" ng-click=\"$ctrl.confirm($event)\" lmsg=\"common.ok\">[Ok]</button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/component/confirm.component.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/component/confirm.component.html")], __WEBPACK_AMD_DEFINE_RESULT__ = function (template)
{
    var Confirm = {
        bindings: {},
        templateUrl: template,
        transclude: true,
        controller: [
            'confirmService',
            function (confirmService) {
                var ctrl = this;

                ctrl.options = {
                    title: '',
                    message: '',
                    icon: '',
                    mode: ''
                };

                ctrl.settings = function(settings) {
                    var values = {
                        title: '',
                        message: '',
                        icon: 'alert-circle-outline',
                        mode: 'cancel_delete'
                    };
                    ctrl.options = angular.extend(values, settings);
                };
                confirmService.registerConfirmDialog(ctrl.settings);

                ctrl.confirm = function() {
                    confirmService.resolve();
                };

                ctrl.cancel = function() {
                    confirmService.reject();
                };
            }
        ]
    };

    return Confirm;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/component/toggle_switch.component.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/component/toggle_switch.component.html';
var html = "<!-- Hack to assign different values to the \"ontext\" property which is interpreted as an event handler due to the name -->\n<span>\n\t<cla-toggle-switch ng-if=\"$ctrl.labels !== 'showhide'\" lmsg=\"ontext:projects.details.grouped\" offtext=\"{{$ctrl.offLabel()}}\" large=\"{{$ctrl.large}}\" ng-attr-checked=\"{{$ctrl.ngModel?true:undefined}}\" name=\"{{$ctrl.name}}\" ng-attr-disabled=\"{{$ctrl.disabled?true:undefined}}\" ng-on-selected=\"$ctrl.onToggledOn($event)\" ng-on-unselected=\"$ctrl.onToggledOff($event)\" ng-transclude></cla-toggle-switch>\n\t<cla-toggle-switch ng-if=\"$ctrl.labels === 'showhide'\" lmsg=\"ontext:projects.details.show\" offtext=\"{{$ctrl.offLabel()}}\" large=\"{{$ctrl.large}}\" ng-attr-checked=\"{{$ctrl.ngModel?true:undefined}}\" name=\"{{$ctrl.name}}\" ng-attr-disabled=\"{{$ctrl.disabled?true:undefined}}\" ng-on-selected=\"$ctrl.onToggledOn($event)\" ng-on-unselected=\"$ctrl.onToggledOff($event)\" ng-transclude></cla-toggle-switch>\n</span>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/component/toggle_switch.component.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/component/toggle_switch.component.html")], __WEBPACK_AMD_DEFINE_RESULT__ = function (template)
{
    var ToggleSwitch = {
        bindings: {
            ngModel: '=',
            labels: '@',
            labelOn: '@',   // Can't be used until the web component property can be renamed away from 'ontext'
            labelOff: '@',  // Also not used due to above limitation
            large: '@',
            name: '@',
            disabled: '@'
        },
        require: { ngModelCtrl: 'ngModel' },
        templateUrl: template,
        transclude: true,
        controller: function () {
            var ctrl = this;

            ctrl.$onInit = function() {
                if (ctrl.disabled === undefined)
                    ctrl.disabled = false;
            };

            ctrl.offLabel = function() {
                if (ctrl.labels !== 'showhide')
                    return lmsg('projects.details.not_grouped');
                else
                    return lmsg('projects.details.hide');
            };

            ctrl.onToggledOn = function($event) {
                $event.preventDefault();

                ctrl.ngModel = true;
                ctrl.ngModelCtrl.$setViewValue(ctrl.ngModel);
            }

            ctrl.onToggledOff = function($event) {
                $event.preventDefault();

                ctrl.ngModel = false;
                ctrl.ngModelCtrl.$setViewValue(ctrl.ngModel);
            }
        }
    };

    return ToggleSwitch;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/component/user_list.component.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/component/user_list.component.html';
var html = "<div class=\"user-list-wrapper user-list-component\">\n\t<div class=\"user-list\">\n\t\t<ng-transclude></ng-transclude>\n\t\t<div class=\"plus-number-wrapper\" ng-if=\"$ctrl.plusnumber > 0\" ng-click=\"$ctrl.plusClicked($event)\">\n\t\t\t<a ng-href=\"javascript:void(0)\" class=\"plus-number\">+{{$ctrl.plusnumber}}</a>\n\t\t</div>\n\t</div>\n</div>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/component/user_list.component.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/component/user_list.component.html")], __WEBPACK_AMD_DEFINE_RESULT__ = function (template)
{
    var UserList = {
        bindings: {
            plusnumber: '@',
            onPlusClicked: '&'
        },
        transclude: true,
        templateUrl: template,
        controller: [
            function () {
                var ctrl = this;

                ctrl.plusClicked = function($event) {
                    $event.preventDefault();

                    ctrl.onPlusClicked();
                }
            }
        ]
    };

    return UserList;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/component/user_list_item.component.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/component/user_list_item.component.html';
var html = "<div class=\"user-list-item square\" data-original-title=\"{{$ctrl.name}}\" rel=\"tooltip\"><a ng-href=\"{{$ctrl.profile}}\" target=\"_parent\"><img ng-src=\"{{$ctrl.img}}\"/></a></div>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/component/user_list_item.component.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/component/user_list_item.component.html")], __WEBPACK_AMD_DEFINE_RESULT__ = function (template)
{
    var UserListItem = {
        bindings: {
            img: '@',
            name: '@',
            profile: '@'
        },
        templateUrl: template,
        controller: [
            function () {
                var ctrl = this;
            }
        ]
    };

    return UserListItem;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/component/users_list_popup.component.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/component/users_list_popup.component.html';
var html = "<div class=\"modal fade js-users_list_modal\" role=\"dialog\">\n\t<div class=\"modal-dialog\" role=\"document\">\n\t\t<div class=\"modal-content\">\n\t\t\t<div class=\"modal-header\">\n\t\t\t\t<h5 class=\"modal-title\" lmsg=\"projects.task.user_list\">[User list]</h5>\n\t\t\t\t<button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Cancel\">\n\t\t\t\t\t<span aria-hidden=\"true\">\n\t\t\t\t\t\t<ion-icon name=\"close-outline\"></ion-icon>\n\t\t\t\t\t</span>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"modal-body\">\n\t\t\t\t<div class=\"d-inline-flex\"\n\t\t\t\t\t dir-paginate=\"user in $ctrl.paginatedUsers | itemsPerPage: $ctrl.usersPerPage\"\n\t\t\t\t\t pagination-id=\"user_list_popup\"\n\t\t\t\t\t total-items=\"$ctrl.totalItems\"\n\t\t\t\t\t current-page=\"$ctrl.currentPage\">\n\t\t\t\t\t<span ng-if=\"user.profile_url === null\" class=\"btn btn-link disabled\">\n\t\t\t\t\t\t<img class=\"tasks-profile-img profile-img mr-2\" ng-src=\"{{user.profile_img}}\">{{user.name}}\n\t\t\t\t\t</span>\n\n\t\t\t\t\t<a ng-if=\"user.profile_url !== null && user.name != ''\" href=\"{{user.profile_url}}\" class=\"btn btn-link\" rel=\"tooltip\" title=\"{{user.name}}\">\n\t\t\t\t\t\t<img class=\"tasks-profile-img profile-img mr-2\" ng-src=\"{{user.profile_img}}\">{{user.name}}\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"text-center clearfix\">\n\t\t\t\t\t<dir-pagination-controls\n\t\t\t\t\t\t\tpagination-id=\"user_list_popup\"\n\t\t\t\t\t\t\ton-page-change=\"$ctrl.pageChanged(newPageNumber)\"\n\t\t\t\t\t\t\ttemplate-url=\"/intranet/projects/html/components/project_list/pagination.html\"\n\t\t\t\t\t></dir-pagination-controls>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/component/users_list_popup.component.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/component/users_list_popup.component.html")], __WEBPACK_AMD_DEFINE_RESULT__ = function (template)
{
    var UsersListPopup = {
        bindings: {},
        templateUrl: template,
        controller: [
            '$element',
            'userListService',
            function ($element, userListService) {
                var ctrl = this;

                ctrl.users = [];
                ctrl.currentPage = 1;
                ctrl.usersPerPage = 10;
                ctrl.totalItems = 0;
                ctrl.paginatedUsers = []

                ctrl.$onInit = function() {
                    $element.find('.js-users_list_modal').on('update', function(event, users) {
                        ctrl.users = users;

                        ctrl.currentPage = 1;
                        ctrl.totalItems = ctrl.users.length;
                        ctrl.pageChanged(ctrl.currentPage);
                    });
                };

                // If pagination is clicked
                ctrl.pageChanged = function(newPage)
                {
                    ctrl.paginatedUsers = paginate(ctrl.users, ctrl.usersPerPage, newPage);
                };

                function paginate(users, usersPerPage, currentPage) {
                    return users.slice((currentPage - 1) * usersPerPage, currentPage * usersPerPage);
                }
            }
        ]
    };

    return UsersListPopup;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/css/user_list.component.scss":
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__("../../../node_modules/css-loader/index.js!../../../node_modules/sass-loader/lib/loader.js!./js/ng/modules/widgets/css/user_list.component.scss");
if(typeof content === 'string') content = [[module.i, content, '']];
// add the styles to the DOM
var update = __webpack_require__("../../../node_modules/style-loader/addStyles.js")(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../../../../../../../node_modules/css-loader/index.js!../../../../../../../../node_modules/sass-loader/lib/loader.js!./user_list.component.scss", function() {
			var newContent = require("!!../../../../../../../../node_modules/css-loader/index.js!../../../../../../../../node_modules/sass-loader/lib/loader.js!./user_list.component.scss");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ "./js/ng/modules/widgets/directive/user_picker.directive.html":
/***/ (function(module, exports) {

var path = '/js/ng/modules/widgets/directive/user_picker.directive.html';
var html = "<div class=\"row\">\n\t<div class=\"col-md-8 mb-2 mb-sm-0\">\n\t\t<select name=\"user_picker_select\" id=\"{{id}}\" class=\"form-control\" size=\"30\" multiple=\"multiple\"></select>\n\t</div>\n\t<div class=\"col-md-4\">\n\t\t<a href=\"#\" id=\"browse_{{id}}\" class=\"btn btn-secondary\" name=\"select_link\" ng-click=\"browse($event)\"><txt name=\"common:user_picker:browse\">Browse</txt></a>\n\t</div>\n</div>\n";
window.angular.module('ng').run(['$templateCache', function(c) { c.put(path, html) }]);
module.exports = path;

/***/ }),

/***/ "./js/ng/modules/widgets/directive/user_picker.directive.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__("./js/ng/modules/widgets/directive/user_picker.directive.html"), __webpack_require__(3)], __WEBPACK_AMD_DEFINE_RESULT__ = function (template, $)
{
    UserPicker.$inject = ['$timeout'];
    function UserPicker($timeout)
    {
        return {
            restrict: 'E',
            require: '^ngModel',
            templateUrl: template,
            scope: {
                ngModel: '=',
                control: '=',
                allowBlocked: '@'
            },
            link: link
        };

        function link(scope, iElement, iAttrs, ctrl)
        {
            scope.id = iAttrs.selectId + '-inner';
            ctrl.user_name = iAttrs.userName;

            var allow_unset = iAttrs.allowUnset == 1;

            // Get project ID if there is one to limit search results
            scope.project_id = iAttrs.projectId || 0;
            scope.project_rights = iAttrs.projectRights || 0;
            scope.project_param = '';

            if ((typeof(scope.project_id) !== 'undefined') &&
                (scope.project_id > 0))
            {
                scope.project_param = '?project_id=' + scope.project_id;
            }

            // Don't use the system user_picker_popup.php because we need to filter results to a projects team members if needed
            ctrl.UserPicker_InitSelect2 = function (element_id, project_id, project_rights, placeholder, allow_unset) {
                var el = jq_$(element_id);
                var page_size = 50;

                var e = el.select2({
                    placeholder: placeholder,
                    minimumInputLength: 3,
                    width: '100%',
                    allowClear: allow_unset,
                    ajax: {
                        url: "/api/projects/v2/projects/" + project_id + "/users",
                        dataType: 'json',
                        delay: 250,
                        data: function (params) {
                            var page = params.page || 1;
                            return {
                                name: params.term, // search term
                                limit: page_size,
                                offset: (page-1) * page_size,
                                fields: "fullname"
                            };
                        },
                        processResults: function (data, params) {
                            params.page = params.page || 1;
                            var list = data.data.map(function(elem){
                                return {
                                    id: elem.id,
                                    text: elem.fullname
                                }
                            });

                            if (!!scope.allowBlocked) {
                                list.push({id: 0, text: lmsg('projects.task.user_blocked')});
                            }

                            return {
                                results: list,
                                pagination: {
                                    more: data.pagination.next != null
                                }
                            };
                        }
                    }
                });
            };

            // Angular won't have populated the control/browse ids yet so wait until the current event is finished
            $timeout(function(id, text, allow_unset, scope){
                scope.initSelect2(id, text, allow_unset)
            }, 0, true, scope.id, lmsg('projects.picker.select_user'), allow_unset, scope);

            if (scope.ngModel !== undefined && scope.ngModel !== null && Array.isArray(scope.ngModel)) {
                scope.ngModel.map(function (user) {
                    $('#' + scope.id).append($('<option>').attr('value', user.id).attr('selected', 'selected').text(user.name));
                });
            }

            ctrl.UserPicker_InitSelect2(scope.id, scope.project_id, scope.project_rights, lmsg('projects.picker.select_user'), allow_unset);

            ctrl.$viewChangeListeners.push(function() {
                scope.$eval(iAttrs.ngChange);
            });

            scope.initSelect2 = function(id, text, allow_unset)
            {
                var select = $('#' + id);
                select.find('option').remove();

                // Add an entry for the current user if needed
                if (scope.ngModel !== undefined && scope.ngModel !== null && Array.isArray(scope.ngModel)) {
                    scope.ngModel.map(function (user) {
                        select.append($('<option>').attr('value', user.id).text(user.name).attr('selected', 'selected'));
                    });
                }

                select.on('change', function() {
                    var $el = angular.element(this);
                    var user_ids = $el.val();

                    // cast variables to int
                    user_ids = user_ids.map(function (user_id) {
                        return parseInt(user_id);
                    });

                    var user_id = user_ids.slice(-1)[0];
                    var name = user_id === '' ? '' : $el.find('option[value=' + user_id + ']').text();

                    scope.change(user_ids, name);
                });

                ctrl.UserPicker_InitSelect2(scope.id, scope.project_id, scope.project_rights, text, allow_unset);
            };

            /**
             * @param user_ids Array
             * @param name string
             */
            scope.change = function(user_ids, name)
            {
                if (!Array.isArray(user_ids))
                    user_ids = [];

                scope.user_name = name;
                ctrl.$setViewValue(user_ids);
                ctrl.$render();

                $timeout(function(user_ids) {
                    ctrl.$setViewValue(user_ids);
                    ctrl.$render();
                }, 0, true, user_ids);
            };

            scope.browse = function(event)
            {
                event.preventDefault();
                var project_params = '';
                if (scope.project_id > 0)
                    project_params = '&project_id=' + scope.project_id;
                var recwnd = window.open('/projects/user_picker_popup?input_dom_id=' + scope.id + project_params + '&multi=1','user_picker_wnd','width=800,height=450,scrollbars=yes,resizable=yes,hotkeys=no,maximize=no');
                recwnd.focus();
            };

            scope.internalControl = scope.control || {};
            scope.internalControl.reset = function(user_name)
            {
                // Rebind the model. This shouldn't be needed but it never gets updated once reset otherwise
                ctrl.$setViewValue(scope.ngModel);

                scope.initSelect2(scope.id, lmsg('projects.picker.select_user'), true);

                var select = $('#' + scope.id);
                select.find('option').remove();
            };
        }
    }

    return UserPicker;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/projects_widgets.module.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
    __webpack_require__("./js/ng/modules/widgets/directive/user_picker.directive.js"),
    __webpack_require__("./js/ng/modules/widgets/component/toggle_switch.component.js"),
    __webpack_require__("./js/ng/modules/widgets/component/confirm.component.js"),
    __webpack_require__("./js/ng/modules/widgets/component/user_list.component.js"),
    __webpack_require__("./js/ng/modules/widgets/component/user_list_item.component.js"),
    __webpack_require__("./js/ng/modules/widgets/component/users_list_popup.component.js"),
    __webpack_require__("./js/ng/modules/widgets/component/checkbox.component.js"),
    __webpack_require__("./js/ng/modules/widgets/service/confirm.service.js"),
    __webpack_require__("./js/ng/modules/widgets/service/user_list.service.js"),
    __webpack_require__("./node_modules/angular-utils-pagination/dirPagination.js"),
    __webpack_require__("./js/ng/modules/widgets/css/user_list.component.scss")

], __WEBPACK_AMD_DEFINE_RESULT__ = function (
    UserPicker,
    ToggleSwitch,
    Confirm,
    UserList,
    UserListItem,
    UsersListPopup,
    Checkbox,
    ConfirmService,
    UserListService
) {
    return angular
        .module('claromentis.projects.widgets', ['angularUtils.directives.dirPagination'])
        .directive('clangProjectsUserPicker', UserPicker)
        .component('clangToggleSwitch', ToggleSwitch)
        .component('clangConfirm', Confirm)
        .component('clangUserList', UserList)
        .component('clangUserListItem', UserListItem)
        .component('clangUsersListPopup', UsersListPopup)
        .component('clangCheckbox', Checkbox)
        .service('confirmService', ConfirmService)
        .service('userListService', UserListService);
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/service/confirm.service.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function ()
{
    var ConfirmService = function($q) {
        var service = this;

        service.promise = null;
        service.confirmDialog = null;

        service.registerConfirmDialog = function(dialog) {
            if (service.confirmDialog !== null)
                console.error('ConfirmService error: Multiple <clang-confirm> instances exist, only one should be defined per page');

            service.confirmDialog = dialog;
        };

        service.show = function(settings) {
            if (service.confirmDialog === null)
            {
                console.error('Confirmation dialog not found');
                return;
            }
            service.confirmDialog(settings);

            angular.element('#projects-confirm').modal('show');
            service.promise = $q.defer();

            return service.promise.promise;
        };

        service.resolve = function() {
            angular.element('#projects-confirm').modal('hide');
            service.promise.resolve();
        };

        service.reject = function() {
            angular.element('#projects-confirm').modal('hide');
            service.promise.reject();
        };
    };
    ConfirmService.$inject = ['$q'];

    return ConfirmService;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/ng/modules/widgets/service/user_list.service.js":
/***/ (function(module, exports, __webpack_require__) {

var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function ()
{
    var template = '<clang-users-list-popup></clang-users-list-popup>';

    var UserListService = function($rootScope, $rootElement, $compile, $timeout) {
        var service = this;

        service.users = [];

        service.showUsersList = function(users) {
            service.users = users;

            var modal = $rootElement.find('.js-users_list_modal');
            if (modal.length === 0)
            {
                // Add the template to the end of this applications root element
                var newScope = $rootScope.$new(true);
                $rootElement.append($compile(template)(newScope));
            }

            $timeout(function() {
                $rootScope.$digest();

                modal = $rootElement.find('.js-users_list_modal');
                modal.trigger('update', [service.users]);
                modal.modal('show');
            }, 0);
        };
    };
    UserListService.$inject = ['$rootScope', '$rootElement', '$compile', '$timeout'];

    return UserListService;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));


/***/ }),

/***/ "./js/projects.index.js":
/***/ (function(module, exports, __webpack_require__) {

var angular = __webpack_require__(1);
window.angular = angular;

__webpack_require__(2);
__webpack_require__(0);
__webpack_require__(4);

angular.module('cla.project_list', []);
__webpack_require__("./js/service/projectList.service.js");

// Other modules
__webpack_require__("./js/ng/modules/widgets/projects_widgets.module.js");

angular.module('projectListApp', ['ui.bootstrap', 'ngResource', 'ngStorage', 'angularUtils.directives.dirPagination', 'cla.core.lmsg', 'cla.core.breadcrumb', 'cla.project_list', 'claromentis.projects.widgets']);
__webpack_require__("./js/controller/projectNewCtrl.js");
__webpack_require__("./js/controller/projectListCtrl.js");

angular.module('projectFilterApp', ['ui.bootstrap', 'ngResource', 'ngStorage', 'cla.core.lmsg', 'cla.project_list']);
__webpack_require__("./js/controller/projectFilterCtrl.js");

module.exports = null;


/***/ }),

/***/ "./js/service/projectList.service.js":
/***/ (function(module, exports, __webpack_require__) {

(function()
{
    var Url = __webpack_require__(8);

    var moduleName = 'cla.project_list';

    // Manual singleton as the .service() appears to return multiple instances across Angular apps
    var instance = new ProjectListService();

    angular.module(moduleName)
        .service('claProjectListService', ['$http', '$q', '$timeout', '$anchorScroll', function($http, $q, $timeout, $anchorScroll)
        {
            instance.setHttp($http);
            instance.setQ($q);
            instance.setTimeout($timeout);
            instance.setAnchorScroll($anchorScroll);
            return instance;
        }]);

    function ProjectListService()
    {
        var service = this;
        service.$http = null;
        service.$q = null;
        service.$timeout = null;
        service.$anchorScroll = null;
        service.apiUrl = '/api/projects/';

        service.callbacks = [];

        // global variables from the project list template - projects/html/index.html
        service.sortOrder = sort;
        service.currentPage = current_page;
        service.searchTerms = searchTerms;
        service.totalCount = project_count;
        service.projectsPerPage = projects_per_page;
        service.projects = projects;
        service.filters = project_filters;
        service.currentFilter = current_filter;

        /**
         * Promise that is used to cancel the previous page fetching request
         * When it is resolved, the request is cancelled.
         * @type {Deferred}
         */
        service.page_fetch_canceler = null;

        /**
         * Handle to timout used to debounce typing in the search bar
         * @type {Promise}
         */
        service.search_debouncer = null;

        service.setHttp = function($http)
        {
            service.$http = $http;
        }

        service.setQ = function($q)
        {
            service.$q = $q;
            service.page_fetch_canceler = service.$q.defer();
        }

        service.setTimeout = function($timeout)
        {
            service.$timeout = $timeout;
            service.search_debouncer = service.$timeout();
            service.showProgressBars();
        }

        service.setAnchorScroll = function($anchorScroll)
        {
            service.$anchorScroll = $anchorScroll;
            // when we scroll to elements, we want to take the height of the navbar into account
            $anchorScroll.yOffset = angular.element('.claro-navbar');
        }

        service.registerCallback = function(callback) {
            service.callbacks.push(callback);
        }

        service.getProjects = function() {
            return service.projects;
        }

        service.setFilter = function(type) {
            service.currentFilter = type;
            service.currentPage = 1;
            service.getResultsPage(1);
        };

        service.getFilters = function() {
            return service.filters;
        }

        service.changeSortOrder = function(orderby) {
            service.sortOrder = orderby;
            service.getResultsPage(service.currentPage);
        };

        service.toggleBookmark = function(project_id, bookmark)
        {
            var url = '/api/projects/' + project_id + '/bookmark';

            if (bookmark == 0)
            {
                service.$http.put(url).then(function(){
                    service.getResultsPage(service.currentPage, false);
                });
            } else
            {
                service.$http.delete(url).then(function(){
                    service.getResultsPage(service.currentPage, false);
                });
            }
        };

        service.pageChanged = function(newPage) {
            service.getResultsPage(newPage);
        };

        service.search = function(searchTerms)
        {
            service.searchTerms = searchTerms;
            service.getResultsPage(service.currentPage);
        };

        service.getResultsPage = function(pageNumber, no_history)
        {
            var withHistory = true;

            if ((typeof no_history === 'boolean') &&
                (no_history))
            {
                withHistory = false;
            }

            var url = new Url('/projects/', {}, true);
            var query_params = {
                filter: service.currentFilter,
                page: pageNumber,
                sort: service.sortOrder
            };

            if (service.searchTerms.length > 0)
                query_params.search = service.searchTerms;

            if (service.companyId > 0)
                query_params.company_id = service.companyId;

            url.set('query', query_params);
            var history_url = history ? url.href : null;
            // add json parameter for REST request only
            query_params.format = 'json';

            // cancel previous timeout
            service.$timeout.cancel(service.search_debouncer);
            // cancel the actual AJAX request
            service.page_fetch_canceler.resolve();

            service.search_debouncer = service.$timeout(function() {
                service.fetchPage(url.pathname, history_url, query_params)
            }, 500)
        }

        service.fetchPage = function (url, history_url, query_params) {
            // cancel previous request to fetch a page
            service.page_fetch_canceler.resolve();
            service.page_fetch_canceler = service.$q.defer();

            service.$http.get(url, {
                params: query_params,
                timeout: service.page_fetch_canceler.promise
            }).then(function(result) {
                service.projects.length = 0;
                angular.extend(service.projects, result.data.projects);

                // Update pagination var in case it needs to show/hide
                service.totalCount = result.data.project_count;

                service.filters.length = 0;
                angular.extend(service.filters, result.data.filter_count);

                service.showProgressBars();

                // Company detail page has no history so don't attempt to set it
                if (history_url)
                    window.history.pushState({}, '', history_url);

                service.$anchorScroll("js-just-before-projects-list")

                for (var i = 0; i < service.callbacks.length; i++)
                {
                    service.callbacks[i]();
                }
            }, function(response) {
                //do nothing when request is cancelled, but have a callback here to prevent angularjs complaining
                if (response.xhrStatus !== "abort") {
                    console.error({
                        message: "Project list page fetch failed",
                        response: response
                    });
                }
            });
        }

        service.showProgressBars = function()
        {
            // Make IE show the right sized progress bars
            for (var i = 0; i < service.projects.length; i++)
            {
                service.$timeout(function(id, progress)
                {
                    angular.element('#progress-bar-' + id).css('width', progress + '%');
                }, 0, true, service.projects[i].id, service.projects[i].progress);
            }
        };

        /**
         * Delete project
         *
         * @param {number} project_id
         */
        service.deleteProject = function (project_id)
        {
            var url = '/api/projects/' + project_id;

            service.$http.delete(url).then(function(result)
            {
                if (result.data.result)
                    window.location.href = '/projects?message=' + encodeURIComponent(lmsg('projects.js.project.project_deleted'));
                else
                    cla.showMessage(lmsg('common.general.error') + ': ' + result.data.message, '', true);
            });
        }
    }
}());


/***/ }),

/***/ "./node_modules/angular-utils-pagination/dirPagination.js":
/***/ (function(module, exports) {

/**
 * dirPagination - AngularJS module for paginating (almost) anything.
 *
 *
 * Credits
 * =======
 *
 * Daniel Tabuenca: https://groups.google.com/d/msg/angular/an9QpzqIYiM/r8v-3W1X5vcJ
 * for the idea on how to dynamically invoke the ng-repeat directive.
 *
 * I borrowed a couple of lines and a few attribute names from the AngularUI Bootstrap project:
 * https://github.com/angular-ui/bootstrap/blob/master/src/pagination/pagination.js
 *
 * Copyright 2014 Michael Bromley <michael@michaelbromley.co.uk>
 */

(function() {

    /**
     * Config
     */
    var moduleName = 'angularUtils.directives.dirPagination';
    var DEFAULT_ID = '__default';

    /**
     * Module
     */
    angular.module(moduleName, [])
        .directive('dirPaginate', ['$compile', '$parse', 'paginationService', dirPaginateDirective])
        .directive('dirPaginateNoCompile', noCompileDirective)
        .directive('dirPaginationControls', ['paginationService', 'paginationTemplate', dirPaginationControlsDirective])
        .filter('itemsPerPage', ['paginationService', itemsPerPageFilter])
        .service('paginationService', paginationService)
        .provider('paginationTemplate', paginationTemplateProvider)
        .run(['$templateCache',dirPaginationControlsTemplateInstaller]);

    function dirPaginateDirective($compile, $parse, paginationService) {

        return  {
            terminal: true,
            multiElement: true,
            priority: 100,
            compile: dirPaginationCompileFn
        };

        function dirPaginationCompileFn(tElement, tAttrs){

            var expression = tAttrs.dirPaginate;
            // regex taken directly from https://github.com/angular/angular.js/blob/v1.4.x/src/ng/directive/ngRepeat.js#L339
            var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);

            var filterPattern = /\|\s*itemsPerPage\s*:\s*(.*\(\s*\w*\)|([^\)]*?(?=\s+as\s+))|[^\)]*)/;
            if (match[2].match(filterPattern) === null) {
                throw 'pagination directive: the \'itemsPerPage\' filter must be set.';
            }
            var itemsPerPageFilterRemoved = match[2].replace(filterPattern, '');
            var collectionGetter = $parse(itemsPerPageFilterRemoved);

            addNoCompileAttributes(tElement);

            // If any value is specified for paginationId, we register the un-evaluated expression at this stage for the benefit of any
            // dir-pagination-controls directives that may be looking for this ID.
            var rawId = tAttrs.paginationId || DEFAULT_ID;
            paginationService.registerInstance(rawId);

            return function dirPaginationLinkFn(scope, element, attrs){

                // Now that we have access to the `scope` we can interpolate any expression given in the paginationId attribute and
                // potentially register a new ID if it evaluates to a different value than the rawId.
                var paginationId = $parse(attrs.paginationId)(scope) || attrs.paginationId || DEFAULT_ID;
                
                // (TODO: this seems sound, but I'm reverting as many bug reports followed it's introduction in 0.11.0.
                // Needs more investigation.)
                // In case rawId != paginationId we deregister using rawId for the sake of general cleanliness
                // before registering using paginationId
                // paginationService.deregisterInstance(rawId);
                paginationService.registerInstance(paginationId);

                var repeatExpression = getRepeatExpression(expression, paginationId);
                addNgRepeatToElement(element, attrs, repeatExpression);

                removeTemporaryAttributes(element);
                var compiled =  $compile(element);

                var currentPageGetter = makeCurrentPageGetterFn(scope, attrs, paginationId);
                paginationService.setCurrentPageParser(paginationId, currentPageGetter, scope);

                if (typeof attrs.totalItems !== 'undefined') {
                    paginationService.setAsyncModeTrue(paginationId);
                    scope.$watch(function() {
                        return $parse(attrs.totalItems)(scope);
                    }, function (result) {
                        if (0 <= result) {
                            paginationService.setCollectionLength(paginationId, result);
                        }
                    });
                } else {
                    paginationService.setAsyncModeFalse(paginationId);
                    scope.$watchCollection(function() {
                        return collectionGetter(scope);
                    }, function(collection) {
                        if (collection) {
                            var collectionLength = (collection instanceof Array) ? collection.length : Object.keys(collection).length;
                            paginationService.setCollectionLength(paginationId, collectionLength);
                        }
                    });
                }

                // Delegate to the link function returned by the new compilation of the ng-repeat
                compiled(scope);
                 
                // (TODO: Reverting this due to many bug reports in v 0.11.0. Needs investigation as the
                // principle is sound)
                // When the scope is destroyed, we make sure to remove the reference to it in paginationService
                // so that it can be properly garbage collected
                // scope.$on('$destroy', function destroyDirPagination() {
                //     paginationService.deregisterInstance(paginationId);
                // });
            };
        }

        /**
         * If a pagination id has been specified, we need to check that it is present as the second argument passed to
         * the itemsPerPage filter. If it is not there, we add it and return the modified expression.
         *
         * @param expression
         * @param paginationId
         * @returns {*}
         */
        function getRepeatExpression(expression, paginationId) {
            var repeatExpression,
                idDefinedInFilter = !!expression.match(/(\|\s*itemsPerPage\s*:[^|]*:[^|]*)/);

            if (paginationId !== DEFAULT_ID && !idDefinedInFilter) {
                repeatExpression = expression.replace(/(\|\s*itemsPerPage\s*:\s*[^|\s]*)/, "$1 : '" + paginationId + "'");
            } else {
                repeatExpression = expression;
            }

            return repeatExpression;
        }

        /**
         * Adds the ng-repeat directive to the element. In the case of multi-element (-start, -end) it adds the
         * appropriate multi-element ng-repeat to the first and last element in the range.
         * @param element
         * @param attrs
         * @param repeatExpression
         */
        function addNgRepeatToElement(element, attrs, repeatExpression) {
            if (element[0].hasAttribute('dir-paginate-start') || element[0].hasAttribute('data-dir-paginate-start')) {
                // using multiElement mode (dir-paginate-start, dir-paginate-end)
                attrs.$set('ngRepeatStart', repeatExpression);
                element.eq(element.length - 1).attr('ng-repeat-end', true);
            } else {
                attrs.$set('ngRepeat', repeatExpression);
            }
        }

        /**
         * Adds the dir-paginate-no-compile directive to each element in the tElement range.
         * @param tElement
         */
        function addNoCompileAttributes(tElement) {
            angular.forEach(tElement, function(el) {
                if (el.nodeType === 1) {
                    angular.element(el).attr('dir-paginate-no-compile', true);
                }
            });
        }

        /**
         * Removes the variations on dir-paginate (data-, -start, -end) and the dir-paginate-no-compile directives.
         * @param element
         */
        function removeTemporaryAttributes(element) {
            angular.forEach(element, function(el) {
                if (el.nodeType === 1) {
                    angular.element(el).removeAttr('dir-paginate-no-compile');
                }
            });
            element.eq(0).removeAttr('dir-paginate-start').removeAttr('dir-paginate').removeAttr('data-dir-paginate-start').removeAttr('data-dir-paginate');
            element.eq(element.length - 1).removeAttr('dir-paginate-end').removeAttr('data-dir-paginate-end');
        }

        /**
         * Creates a getter function for the current-page attribute, using the expression provided or a default value if
         * no current-page expression was specified.
         *
         * @param scope
         * @param attrs
         * @param paginationId
         * @returns {*}
         */
        function makeCurrentPageGetterFn(scope, attrs, paginationId) {
            var currentPageGetter;
            if (attrs.currentPage) {
                currentPageGetter = $parse(attrs.currentPage);
            } else {
                // If the current-page attribute was not set, we'll make our own.
                // Replace any non-alphanumeric characters which might confuse
                // the $parse service and give unexpected results.
                // See https://github.com/michaelbromley/angularUtils/issues/233
                var defaultCurrentPage = (paginationId + '__currentPage').replace(/\W/g, '_');
                scope[defaultCurrentPage] = 1;
                currentPageGetter = $parse(defaultCurrentPage);
            }
            return currentPageGetter;
        }
    }

    /**
     * This is a helper directive that allows correct compilation when in multi-element mode (ie dir-paginate-start, dir-paginate-end).
     * It is dynamically added to all elements in the dir-paginate compile function, and it prevents further compilation of
     * any inner directives. It is then removed in the link function, and all inner directives are then manually compiled.
     */
    function noCompileDirective() {
        return {
            priority: 5000,
            terminal: true
        };
    }

    function dirPaginationControlsTemplateInstaller($templateCache) {
        $templateCache.put('angularUtils.directives.dirPagination.template', '<ul class="pagination" ng-if="1 < pages.length || !autoHide"><li ng-if="boundaryLinks" ng-class="{ disabled : pagination.current == 1 }"><a href="" ng-click="setCurrent(1)">&laquo;</a></li><li ng-if="directionLinks" ng-class="{ disabled : pagination.current == 1 }"><a href="" ng-click="setCurrent(pagination.current - 1)">&lsaquo;</a></li><li ng-repeat="pageNumber in pages track by tracker(pageNumber, $index)" ng-class="{ active : pagination.current == pageNumber, disabled : pageNumber == \'...\' || ( ! autoHide && pages.length === 1 ) }"><a href="" ng-click="setCurrent(pageNumber)">{{ pageNumber }}</a></li><li ng-if="directionLinks" ng-class="{ disabled : pagination.current == pagination.last }"><a href="" ng-click="setCurrent(pagination.current + 1)">&rsaquo;</a></li><li ng-if="boundaryLinks"  ng-class="{ disabled : pagination.current == pagination.last }"><a href="" ng-click="setCurrent(pagination.last)">&raquo;</a></li></ul>');
    }

    function dirPaginationControlsDirective(paginationService, paginationTemplate) {

        var numberRegex = /^\d+$/;

        var DDO = {
            restrict: 'AE',
            scope: {
                maxSize: '=?',
                onPageChange: '&?',
                paginationId: '=?',
                autoHide: '=?'
            },
            link: dirPaginationControlsLinkFn
        };

        // We need to check the paginationTemplate service to see whether a template path or
        // string has been specified, and add the `template` or `templateUrl` property to
        // the DDO as appropriate. The order of priority to decide which template to use is
        // (highest priority first):
        // 1. paginationTemplate.getString()
        // 2. attrs.templateUrl
        // 3. paginationTemplate.getPath()
        var templateString = paginationTemplate.getString();
        if (templateString !== undefined) {
            DDO.template = templateString;
        } else {
            DDO.templateUrl = function(elem, attrs) {
                return attrs.templateUrl || paginationTemplate.getPath();
            };
        }
        return DDO;

        function dirPaginationControlsLinkFn(scope, element, attrs) {

            // rawId is the un-interpolated value of the pagination-id attribute. This is only important when the corresponding dir-paginate directive has
            // not yet been linked (e.g. if it is inside an ng-if block), and in that case it prevents this controls directive from assuming that there is
            // no corresponding dir-paginate directive and wrongly throwing an exception.
            var rawId = attrs.paginationId ||  DEFAULT_ID;
            var paginationId = scope.paginationId || attrs.paginationId ||  DEFAULT_ID;

            if (!paginationService.isRegistered(paginationId) && !paginationService.isRegistered(rawId)) {
                var idMessage = (paginationId !== DEFAULT_ID) ? ' (id: ' + paginationId + ') ' : ' ';
                if (window.console) {
                    console.warn('Pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive, which was not found at link time.');
                }
            }

            if (!scope.maxSize) { scope.maxSize = 9; }
            scope.autoHide = scope.autoHide === undefined ? true : scope.autoHide;
            scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true;
            scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false;

            var paginationRange = Math.max(scope.maxSize, 5);
            scope.pages = [];
            scope.pagination = {
                last: 1,
                current: 1
            };
            scope.range = {
                lower: 1,
                upper: 1,
                total: 1
            };

            scope.$watch('maxSize', function(val) {
                if (val) {
                    paginationRange = Math.max(scope.maxSize, 5);
                    generatePagination();
                }
            });

            scope.$watch(function() {
                if (paginationService.isRegistered(paginationId)) {
                    return (paginationService.getCollectionLength(paginationId) + 1) * paginationService.getItemsPerPage(paginationId);
                }
            }, function(length) {
                if (0 < length) {
                    generatePagination();
                }
            });

            scope.$watch(function() {
                if (paginationService.isRegistered(paginationId)) {
                    return (paginationService.getItemsPerPage(paginationId));
                }
            }, function(current, previous) {
                if (current != previous && typeof previous !== 'undefined') {
                    goToPage(scope.pagination.current);
                }
            });

            scope.$watch(function() {
                if (paginationService.isRegistered(paginationId)) {
                    return paginationService.getCurrentPage(paginationId);
                }
            }, function(currentPage, previousPage) {
                if (currentPage != previousPage) {
                    goToPage(currentPage);
                }
            });

            scope.setCurrent = function(num) {
                if (paginationService.isRegistered(paginationId) && isValidPageNumber(num)) {
                    num = parseInt(num, 10);
                    paginationService.setCurrentPage(paginationId, num);
                }
            };

            /**
             * Custom "track by" function which allows for duplicate "..." entries on long lists,
             * yet fixes the problem of wrongly-highlighted links which happens when using
             * "track by $index" - see https://github.com/michaelbromley/angularUtils/issues/153
             * @param id
             * @param index
             * @returns {string}
             */
            scope.tracker = function(id, index) {
                return id + '_' + index;
            };

            function goToPage(num) {
                if (paginationService.isRegistered(paginationId) && isValidPageNumber(num)) {
                    var oldPageNumber = scope.pagination.current;

                    scope.pages = generatePagesArray(num, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange);
                    scope.pagination.current = num;
                    updateRangeValues();

                    // if a callback has been set, then call it with the page number as the first argument
                    // and the previous page number as a second argument
                    if (scope.onPageChange) {
                        scope.onPageChange({
                            newPageNumber : num,
                            oldPageNumber : oldPageNumber
                        });
                    }
                }
            }

            function generatePagination() {
                if (paginationService.isRegistered(paginationId)) {
                    var page = parseInt(paginationService.getCurrentPage(paginationId)) || 1;
                    scope.pages = generatePagesArray(page, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange);
                    scope.pagination.current = page;
                    scope.pagination.last = scope.pages[scope.pages.length - 1];
                    if (scope.pagination.last < scope.pagination.current) {
                        scope.setCurrent(scope.pagination.last);
                    } else {
                        updateRangeValues();
                    }
                }
            }

            /**
             * This function updates the values (lower, upper, total) of the `scope.range` object, which can be used in the pagination
             * template to display the current page range, e.g. "showing 21 - 40 of 144 results";
             */
            function updateRangeValues() {
                if (paginationService.isRegistered(paginationId)) {
                    var currentPage = paginationService.getCurrentPage(paginationId),
                        itemsPerPage = paginationService.getItemsPerPage(paginationId),
                        totalItems = paginationService.getCollectionLength(paginationId);

                    scope.range.lower = (currentPage - 1) * itemsPerPage + 1;
                    scope.range.upper = Math.min(currentPage * itemsPerPage, totalItems);
                    scope.range.total = totalItems;
                }
            }
            function isValidPageNumber(num) {
                return (numberRegex.test(num) && (0 < num && num <= scope.pagination.last));
            }
        }

        /**
         * Generate an array of page numbers (or the '...' string) which is used in an ng-repeat to generate the
         * links used in pagination
         *
         * @param currentPage
         * @param rowsPerPage
         * @param paginationRange
         * @param collectionLength
         * @returns {Array}
         */
        function generatePagesArray(currentPage, collectionLength, rowsPerPage, paginationRange) {
            var pages = [];
            var totalPages = Math.ceil(collectionLength / rowsPerPage);
            var halfWay = Math.ceil(paginationRange / 2);
            var position;

            if (currentPage <= halfWay) {
                position = 'start';
            } else if (totalPages - halfWay < currentPage) {
                position = 'end';
            } else {
                position = 'middle';
            }

            var ellipsesNeeded = paginationRange < totalPages;
            var i = 1;
            while (i <= totalPages && i <= paginationRange) {
                var pageNumber = calculatePageNumber(i, currentPage, paginationRange, totalPages);

                var openingEllipsesNeeded = (i === 2 && (position === 'middle' || position === 'end'));
                var closingEllipsesNeeded = (i === paginationRange - 1 && (position === 'middle' || position === 'start'));
                if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
                    pages.push('...');
                } else {
                    pages.push(pageNumber);
                }
                i ++;
            }
            return pages;
        }

        /**
         * Given the position in the sequence of pagination links [i], figure out what page number corresponds to that position.
         *
         * @param i
         * @param currentPage
         * @param paginationRange
         * @param totalPages
         * @returns {*}
         */
        function calculatePageNumber(i, currentPage, paginationRange, totalPages) {
            var halfWay = Math.ceil(paginationRange/2);
            if (i === paginationRange) {
                return totalPages;
            } else if (i === 1) {
                return i;
            } else if (paginationRange < totalPages) {
                if (totalPages - halfWay < currentPage) {
                    return totalPages - paginationRange + i;
                } else if (halfWay < currentPage) {
                    return currentPage - halfWay + i;
                } else {
                    return i;
                }
            } else {
                return i;
            }
        }
    }

    /**
     * This filter slices the collection into pages based on the current page number and number of items per page.
     * @param paginationService
     * @returns {Function}
     */
    function itemsPerPageFilter(paginationService) {

        return function(collection, itemsPerPage, paginationId) {
            if (typeof (paginationId) === 'undefined') {
                paginationId = DEFAULT_ID;
            }
            if (!paginationService.isRegistered(paginationId)) {
                throw 'pagination directive: the itemsPerPage id argument (id: ' + paginationId + ') does not match a registered pagination-id.';
            }
            var end;
            var start;
            if (angular.isObject(collection)) {
                itemsPerPage = parseInt(itemsPerPage) || 9999999999;
                if (paginationService.isAsyncMode(paginationId)) {
                    start = 0;
                } else {
                    start = (paginationService.getCurrentPage(paginationId) - 1) * itemsPerPage;
                }
                end = start + itemsPerPage;
                paginationService.setItemsPerPage(paginationId, itemsPerPage);

                if (collection instanceof Array) {
                    // the array just needs to be sliced
                    return collection.slice(start, end);
                } else {
                    // in the case of an object, we need to get an array of keys, slice that, then map back to
                    // the original object.
                    var slicedObject = {};
                    angular.forEach(keys(collection).slice(start, end), function(key) {
                        slicedObject[key] = collection[key];
                    });
                    return slicedObject;
                }
            } else {
                return collection;
            }
        };
    }

    /**
     * Shim for the Object.keys() method which does not exist in IE < 9
     * @param obj
     * @returns {Array}
     */
    function keys(obj) {
        if (!Object.keys) {
            var objKeys = [];
            for (var i in obj) {
                if (obj.hasOwnProperty(i)) {
                    objKeys.push(i);
                }
            }
            return objKeys;
        } else {
            return Object.keys(obj);
        }
    }

    /**
     * This service allows the various parts of the module to communicate and stay in sync.
     */
    function paginationService() {

        var instances = {};
        var lastRegisteredInstance;

        this.registerInstance = function(instanceId) {
            if (typeof instances[instanceId] === 'undefined') {
                instances[instanceId] = {
                    asyncMode: false
                };
                lastRegisteredInstance = instanceId;
            }
        };

        this.deregisterInstance = function(instanceId) {
            delete instances[instanceId];
        };
        
        this.isRegistered = function(instanceId) {
            return (typeof instances[instanceId] !== 'undefined');
        };

        this.getLastInstanceId = function() {
            return lastRegisteredInstance;
        };

        this.setCurrentPageParser = function(instanceId, val, scope) {
            instances[instanceId].currentPageParser = val;
            instances[instanceId].context = scope;
        };
        this.setCurrentPage = function(instanceId, val) {
            instances[instanceId].currentPageParser.assign(instances[instanceId].context, val);
        };
        this.getCurrentPage = function(instanceId) {
            var parser = instances[instanceId].currentPageParser;
            return parser ? parser(instances[instanceId].context) : 1;
        };

        this.setItemsPerPage = function(instanceId, val) {
            instances[instanceId].itemsPerPage = val;
        };
        this.getItemsPerPage = function(instanceId) {
            return instances[instanceId].itemsPerPage;
        };

        this.setCollectionLength = function(instanceId, val) {
            instances[instanceId].collectionLength = val;
        };
        this.getCollectionLength = function(instanceId) {
            return instances[instanceId].collectionLength;
        };

        this.setAsyncModeTrue = function(instanceId) {
            instances[instanceId].asyncMode = true;
        };

        this.setAsyncModeFalse = function(instanceId) {
            instances[instanceId].asyncMode = false;
        };

        this.isAsyncMode = function(instanceId) {
            return instances[instanceId].asyncMode;
        };
    }

    /**
     * This provider allows global configuration of the template path used by the dir-pagination-controls directive.
     */
    function paginationTemplateProvider() {

        var templatePath = 'angularUtils.directives.dirPagination.template';
        var templateString;

        /**
         * Set a templateUrl to be used by all instances of <dir-pagination-controls>
         * @param {String} path
         */
        this.setPath = function(path) {
            templatePath = path;
        };

        /**
         * Set a string of HTML to be used as a template by all instances
         * of <dir-pagination-controls>. If both a path *and* a string have been set,
         * the string takes precedence.
         * @param {String} str
         */
        this.setString = function(str) {
            templateString = str;
        };

        this.$get = function() {
            return {
                getPath: function() {
                    return templatePath;
                },
                getString: function() {
                    return templateString;
                }
            };
        };
    }
})();


/***/ }),

/***/ 0:
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ }),

/***/ 1:
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_1__;

/***/ }),

/***/ 16:
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__("./assets/css/style.scss");
__webpack_require__("./assets/css/project_list.scss");
module.exports = __webpack_require__("./js/projects.index.js");


/***/ }),

/***/ 2:
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_2__;

/***/ }),

/***/ 3:
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_3__;

/***/ }),

/***/ 4:
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_4__;

/***/ }),

/***/ 8:
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_8__;

/***/ })

/******/ })});;