summaryrefslogtreecommitdiffstats
path: root/afb-client/bower_components/foundation-apps/js/angular
diff options
context:
space:
mode:
authorStephane Desneux <stephane.desneux@iot.bzh>2016-05-31 18:16:48 +0200
committerStephane Desneux <stephane.desneux@iot.bzh>2016-05-31 18:16:48 +0200
commit5b1e6cc132f44262a873fa8296a2a3e1017b0278 (patch)
tree43b2cd54e2e300b399ff3f2af4458a2c4ed8a144 /afb-client/bower_components/foundation-apps/js/angular
parentf7d2f9ac4168ee5064580c666d508667a73cefc0 (diff)
parent85ace9c1ce9a98e9b8a22f045c7dd752b38d9129 (diff)
Merge afb-client
Diffstat (limited to 'afb-client/bower_components/foundation-apps/js/angular')
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/app.js35
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion-item.html4
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.html2
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.js107
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-button.html6
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-content.html8
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.html3
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.js226
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/common/common.js171
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/iconic/iconic.js186
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/interchange/interchange.js94
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.html9
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.js291
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-set.html9
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-static.html12
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.html12
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.js417
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.html5
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.js102
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.html6
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.js144
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.html2
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.js160
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab-content.html8
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab.html3
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.html8
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.js311
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/foundation.js22
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js129
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js163
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js125
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js156
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js198
-rw-r--r--afb-client/bower_components/foundation-apps/js/angular/vendor/markdown.js10
-rwxr-xr-xafb-client/bower_components/foundation-apps/js/angular/vendor/svgDirs.js101
35 files changed, 3245 insertions, 0 deletions
diff --git a/afb-client/bower_components/foundation-apps/js/angular/app.js b/afb-client/bower_components/foundation-apps/js/angular/app.js
new file mode 100644
index 0000000..7251eb1
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/app.js
@@ -0,0 +1,35 @@
+(function() {
+ 'use strict';
+
+ angular.module('application', [
+ 'ui.router',
+ 'ngAnimate',
+
+ //foundation
+ 'foundation',
+ 'foundation.dynamicRouting',
+ 'foundation.dynamicRouting.animations'
+ ])
+ .config(config)
+ .run(run)
+ ;
+
+ config.$inject = ['$urlRouterProvider', '$locationProvider'];
+
+ function config($urlProvider, $locationProvider) {
+ $urlProvider.otherwise('/');
+
+ $locationProvider.html5Mode({
+ enabled: false,
+ requireBase: false
+ });
+
+ $locationProvider.hashPrefix('!');
+ }
+
+
+ function run() {
+ FastClick.attach(document.body);
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion-item.html b/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion-item.html
new file mode 100644
index 0000000..2bc4892
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion-item.html
@@ -0,0 +1,4 @@
+<div class="accordion-item" ng-class="{'is-active': active}">
+ <div class="accordion-title" ng-click="activate()">{{ title }}</div>
+ <div class="accordion-content" ng-transclude></div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.html b/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.html
new file mode 100644
index 0000000..344586e
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.html
@@ -0,0 +1,2 @@
+<div class="accordion" ng-transclude>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.js b/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.js
new file mode 100644
index 0000000..2b2dac7
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/accordion/accordion.js
@@ -0,0 +1,107 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.accordion', [])
+ .controller('ZfAccordionController', zfAccordionController)
+ .directive('zfAccordion', zfAccordion)
+ .directive('zfAccordionItem', zfAccordionItem)
+ ;
+
+ zfAccordionController.$inject = ['$scope'];
+
+ function zfAccordionController($scope) {
+ var controller = this;
+ var sections = controller.sections = $scope.sections = [];
+ var multiOpen = controller.multiOpen = $scope.multiOpen = $scope.multiOpen || false;
+ var collapsible = controller.collapsible = $scope.collapsible = $scope.multiOpen || $scope.collapsible || true; //multi open infers a collapsible true
+ var autoOpen = controller.autoOpen = $scope.autoOpen = $scope.autoOpen || true; //auto open opens first tab on render
+
+ controller.select = function(selectSection) {
+ sections.forEach(function(section) {
+ //if multi open is allowed, toggle a tab
+ if(controller.multiOpen) {
+ if(section.scope === selectSection) {
+ section.scope.active = !section.scope.active;
+ }
+ } else {
+ //non multi open will close all tabs and open one
+ if(section.scope === selectSection) {
+ //if collapsible is allowed, a tab will toggle
+ section.scope.active = collapsible ? !section.scope.active : true;
+ } else {
+ section.scope.active = false;
+ }
+ }
+
+ });
+ };
+
+ controller.addSection = function addsection(sectionScope) {
+ sections.push({ scope: sectionScope });
+
+ if(sections.length === 1 && autoOpen === true) {
+ sections[0].active = true;
+ sections[0].scope.active = true;
+ }
+ };
+
+ controller.closeAll = function() {
+ sections.forEach(function(section) {
+ section.scope.active = false;
+ });
+ };
+ }
+
+ function zfAccordion() {
+ var directive = {
+ restrict: 'EA',
+ transclude: 'true',
+ replace: true,
+ templateUrl: 'components/accordion/accordion.html',
+ controller: 'ZfAccordionController',
+ scope: {
+ multiOpen: '@?',
+ collapsible: '@?',
+ autoOpen: '@?'
+ },
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller) {
+ scope.multiOpen = controller.multiOpen = scope.multiOpen === "true" ? true : false;
+ scope.collapsible = controller.collapsible = scope.collapsible === "true" ? true : false;
+ scope.autoOpen = controller.autoOpen = scope.autoOpen === "true" ? true : false;
+ }
+ }
+
+ //accordion item
+ function zfAccordionItem() {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/accordion/accordion-item.html',
+ transclude: true,
+ scope: {
+ title: '@'
+ },
+ require: '^zfAccordion',
+ replace: true,
+ controller: function() {},
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller, transclude) {
+ scope.active = false;
+ controller.addSection(scope);
+
+ scope.activate = function() {
+ controller.select(scope);
+ };
+
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-button.html b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-button.html
new file mode 100644
index 0000000..6df405c
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-button.html
@@ -0,0 +1,6 @@
+<div>
+ <a href="#"
+ class="button"
+ ng-if="title.length > 0">{{ title }}</a>
+ <div ng-transclude></div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-content.html b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-content.html
new file mode 100644
index 0000000..cafb733
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet-content.html
@@ -0,0 +1,8 @@
+<div
+ class="action-sheet {{ position }}"
+ ng-class="{'is-active': active}"
+ >
+ <div
+ ng-transclude>
+ </div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.html b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.html
new file mode 100644
index 0000000..0b1006c
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.html
@@ -0,0 +1,3 @@
+<div class="action-sheet-container"
+ ng-transclude>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.js b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.js
new file mode 100644
index 0000000..e38b67a
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/actionsheet/actionsheet.js
@@ -0,0 +1,226 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.actionsheet', ['foundation.core'])
+ .controller('ZfActionSheetController', zfActionSheetController)
+ .directive('zfActionSheet', zfActionSheet)
+ .directive('zfAsContent', zfAsContent)
+ .directive('zfAsButton', zfAsButton)
+ .service('FoundationActionSheet', FoundationActionSheet)
+ ;
+
+ FoundationActionSheet.$inject = ['FoundationApi'];
+
+ function FoundationActionSheet(foundationApi) {
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ //target should be element ID
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+ }
+
+ zfActionSheetController.$inject = ['$scope', 'FoundationApi'];
+
+ function zfActionSheetController($scope, foundationApi) {
+ var controller = this;
+ var content = controller.content = $scope.content;
+ var container = controller.container = $scope.container;
+ var body = angular.element(document.body);
+
+ controller.registerContent = function(scope) {
+ content = scope;
+ content.active = false;
+ };
+
+ controller.registerContainer = function(scope) {
+ container = scope;
+ container.active = false;
+ };
+
+ controller.toggle = toggle;
+ controller.hide = hide;
+
+ controller.registerListener = function() {
+ document.body.addEventListener('click', listenerLogic);
+ };
+
+ controller.deregisterListener = function() {
+ document.body.removeEventListener('click', listenerLogic);
+ }
+
+ function listenerLogic(e) {
+ var el = e.target;
+ var insideActionSheet = false;
+
+ do {
+ if(el.classList && el.classList.contains('action-sheet-container')) {
+ insideActionSheet = true;
+ break;
+ }
+
+ } while ((el = el.parentNode));
+
+ if(!insideActionSheet) {
+ // if the element has a toggle attribute, do nothing
+ if (e.target.attributes['zf-toggle'] || e.target.attributes['zf-hard-toggle']) {
+ return;
+ };
+ // if the element is outside the action sheet and is NOT a toggle element, hide
+ hide();
+ }
+ }
+
+ function hide() {
+ content.hide();
+ container.hide();
+
+ content.$apply();
+ container.$apply();
+ }
+
+ function toggle() {
+ content.toggle();
+ container.toggle();
+
+ content.$apply();
+ container.$apply();
+ }
+ }
+
+ zfActionSheet.$inject = ['FoundationApi'];
+
+ function zfActionSheet(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ transclude: true,
+ replace: true,
+ templateUrl: 'components/actionsheet/actionsheet.html',
+ controller: 'ZfActionSheetController',
+ compile: compile
+ };
+
+ return directive;
+
+ function compile() {
+
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, iElement, iAttrs) {
+ iAttrs.$set('zf-closable', 'actionsheet');
+ }
+
+ function postLink(scope, element, attrs, controller) {
+ var id = attrs.id || foundationApi.generateUuid();
+ attrs.$set('id', id);
+
+ scope.active = false;
+
+ foundationApi.subscribe(id, function(msg) {
+ if (msg === 'toggle') {
+ controller.toggle();
+ }
+
+ if (msg === 'hide' || msg === 'close') {
+ controller.hide();
+ }
+
+ });
+
+ controller.registerContainer(scope);
+
+ scope.toggle = function() {
+ scope.active = !scope.active;
+ return;
+ };
+
+ scope.hide = function() {
+ scope.active = false;
+ return;
+ };
+ }
+ }
+ }
+
+ zfAsContent.$inject = ['FoundationApi'];
+
+ function zfAsContent(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ transclude: true,
+ replace: true,
+ templateUrl: 'components/actionsheet/actionsheet-content.html',
+ require: '^zfActionSheet',
+ scope: {
+ position: '@?'
+ },
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller) {
+ scope.active = false;
+ scope.position = scope.position || 'bottom';
+ controller.registerContent(scope);
+
+ scope.toggle = function() {
+ scope.active = !scope.active;
+ if(scope.active) {
+ controller.registerListener();
+ } else {
+ controller.deregisterListener();
+ }
+
+ return;
+ };
+
+ scope.hide = function() {
+ scope.active = false;
+ controller.deregisterListener();
+ return;
+ };
+ }
+ }
+
+ zfAsButton.$inject = ['FoundationApi'];
+
+ function zfAsButton(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ transclude: true,
+ replace: true,
+ templateUrl: 'components/actionsheet/actionsheet-button.html',
+ require: '^zfActionSheet',
+ scope: {
+ title: '@?'
+ },
+ link: link
+ }
+
+ return directive;
+
+ function link(scope, element, attrs, controller) {
+
+ element.on('click', function(e) {
+ controller.toggle();
+ e.preventDefault();
+ });
+
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/common/common.js b/afb-client/bower_components/foundation-apps/js/angular/components/common/common.js
new file mode 100644
index 0000000..a818a6d
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/common/common.js
@@ -0,0 +1,171 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.common', ['foundation.core'])
+ .directive('zfClose', zfClose)
+ .directive('zfOpen', zfOpen)
+ .directive('zfToggle', zfToggle)
+ .directive('zfEscClose', zfEscClose)
+ .directive('zfSwipeClose', zfSwipeClose)
+ .directive('zfHardToggle', zfHardToggle)
+ ;
+
+ zfClose.$inject = ['FoundationApi'];
+
+ function zfClose(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs) {
+ var targetId = '';
+ if (attrs.zfClose) {
+ targetId = attrs.zfClose;
+ } else {
+ var parentElement= false;
+ var tempElement = element.parent();
+ //find parent modal
+ while(parentElement === false) {
+ if(tempElement[0].nodeName == 'BODY') {
+ parentElement = '';
+ }
+
+ if(typeof tempElement.attr('zf-closable') !== 'undefined' && tempElement.attr('zf-closable') !== false) {
+ parentElement = tempElement;
+ }
+
+ tempElement = tempElement.parent();
+ }
+ targetId = parentElement.attr('id');
+ }
+
+ element.on('click', function(e) {
+ foundationApi.publish(targetId, 'close');
+ e.preventDefault();
+ });
+ }
+ }
+
+ zfOpen.$inject = ['FoundationApi'];
+
+ function zfOpen(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs) {
+ element.on('click', function(e) {
+ foundationApi.publish(attrs.zfOpen, 'open');
+ e.preventDefault();
+ });
+ }
+ }
+
+ zfToggle.$inject = ['FoundationApi'];
+
+ function zfToggle(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ }
+
+ return directive;
+
+ function link(scope, element, attrs) {
+ element.on('click', function(e) {
+ foundationApi.publish(attrs.zfToggle, 'toggle');
+ e.preventDefault();
+ });
+ }
+ }
+
+ zfEscClose.$inject = ['FoundationApi'];
+
+ function zfEscClose(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs) {
+ element.on('keyup', function(e) {
+ if (e.keyCode === 27) {
+ foundationApi.closeActiveElements();
+ }
+ e.preventDefault();
+ });
+ }
+ }
+
+ zfSwipeClose.$inject = ['FoundationApi'];
+
+ function zfSwipeClose(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ };
+ return directive;
+
+ function link($scope, element, attrs) {
+ var swipeDirection;
+ var hammerElem;
+ if (Hammer) {
+ hammerElem = new Hammer(element[0]);
+ // set the options for swipe (to make them a bit more forgiving in detection)
+ hammerElem.get('swipe').set({
+ direction: Hammer.DIRECTION_ALL,
+ threshold: 5, // this is how far the swipe has to travel
+ velocity: 0.5 // and this is how fast the swipe must travel
+ });
+ }
+ // detect what direction the directive is pointing
+ switch (attrs.zfSwipeClose) {
+ case 'right':
+ swipeDirection = 'swiperight';
+ break;
+ case 'left':
+ swipeDirection = 'swipeleft';
+ break;
+ case 'up':
+ swipeDirection = 'swipeup';
+ break;
+ case 'down':
+ swipeDirection = 'swipedown';
+ break;
+ default:
+ swipeDirection = 'swipe';
+ }
+ hammerElem.on(swipeDirection, function() {
+ foundationApi.publish(attrs.id, 'close');
+ });
+ }
+ }
+
+ zfHardToggle.$inject = ['FoundationApi'];
+
+ function zfHardToggle(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs) {
+ element.on('click', function(e) {
+ foundationApi.closeActiveElements({exclude: attrs.zfHardToggle});
+ foundationApi.publish(attrs.zfHardToggle, 'toggle');
+ e.preventDefault();
+ });
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/iconic/iconic.js b/afb-client/bower_components/foundation-apps/js/angular/components/iconic/iconic.js
new file mode 100644
index 0000000..19cf192
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/iconic/iconic.js
@@ -0,0 +1,186 @@
+(function () {
+ 'use strict';
+
+ angular.module('foundation.iconic', [])
+ .provider('Iconic', Iconic)
+ .directive('zfIconic', zfIconic)
+ ;
+
+ // iconic wrapper
+ function Iconic() {
+ // default path
+ var assetPath = 'assets/img/iconic/';
+
+ /**
+ * Sets the path used to locate the iconic SVG files
+ * @param {string} path - the base path used to locate the iconic SVG files
+ */
+ this.setAssetPath = function (path) {
+ assetPath = angular.isString(path) ? path : assetPath;
+ };
+
+ /**
+ * Service implementation
+ * @returns {{}}
+ */
+ this.$get = function () {
+ var iconicObject = new IconicJS();
+
+ var service = {
+ getAccess: getAccess,
+ getAssetPath: getAssetPath
+ };
+
+ return service;
+
+ /**
+ *
+ * @returns {Window.IconicJS}
+ */
+ function getAccess() {
+ return iconicObject;
+ }
+
+ /**
+ *
+ * @returns {string}
+ */
+ function getAssetPath() {
+ return assetPath;
+ }
+ };
+ }
+
+ zfIconic.$inject = ['Iconic', 'FoundationApi', '$compile'];
+
+ function zfIconic(iconic, foundationApi, $compile) {
+ var directive = {
+ restrict: 'A',
+ template: '<img ng-transclude>',
+ transclude: true,
+ replace: true,
+ scope: {
+ dynSrc: '=?',
+ dynIcon: '=?',
+ size: '@?',
+ icon: '@',
+ iconDir: '@?'
+ },
+ compile: compile
+ };
+
+ return directive;
+
+ function compile() {
+ var contents, assetPath;
+
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, element, attrs) {
+
+ if (scope.iconDir) {
+ // path set via attribute
+ assetPath = scope.iconDir;
+ } else {
+ // default path
+ assetPath = iconic.getAssetPath();
+ }
+ // make sure ends with /
+ if (assetPath.charAt(assetPath.length - 1) !== '/') {
+ assetPath += '/';
+ }
+
+ if (scope.dynSrc) {
+ attrs.$set('data-src', scope.dynSrc);
+ } else if (scope.dynIcon) {
+ attrs.$set('data-src', assetPath + scope.dynIcon + '.svg');
+ } else {
+ if (scope.icon) {
+ attrs.$set('data-src', assetPath + scope.icon + '.svg');
+ } else {
+ // To support expressions on data-src
+ attrs.$set('data-src', attrs.src);
+ }
+ }
+
+ // check if size already added as class
+ if (!element.hasClass('iconic-sm') && !element.hasClass('iconic-md') && !element.hasClass('iconic-lg')) {
+ var iconicClass;
+ switch (scope.size) {
+ case 'small':
+ iconicClass = 'iconic-sm';
+ break;
+ case 'medium':
+ iconicClass = 'iconic-md';
+ break;
+ case 'large':
+ iconicClass = 'iconic-lg';
+ break;
+ default:
+ iconicClass = 'iconic-fluid';
+ }
+ element.addClass(iconicClass);
+ }
+
+ // save contents of un-inject html, to use for dynamic re-injection
+ contents = element[0].outerHTML;
+ }
+
+ function postLink(scope, element, attrs) {
+ var svgElement, ico = iconic.getAccess();
+
+ injectSvg(element[0]);
+
+ foundationApi.subscribe('resize', function () {
+ // only run update on current element
+ ico.update(element[0]);
+ });
+
+ // handle dynamic updating of src
+ if (scope.dynSrc) {
+ scope.$watch('dynSrc', function (newVal, oldVal) {
+ if (newVal && newVal !== oldVal) {
+ reinjectSvg(scope.dynSrc);
+ }
+ });
+ }
+ // handle dynamic updating of icon
+ if (scope.dynIcon) {
+ scope.$watch('dynIcon', function (newVal, oldVal) {
+ if (newVal && newVal !== oldVal) {
+ reinjectSvg(assetPath + scope.dynIcon + '.svg');
+ }
+ });
+ }
+
+ function reinjectSvg(newSrc) {
+ if (svgElement) {
+ // set html
+ svgElement.empty();
+ svgElement.append(angular.element(contents));
+
+ // set new source
+ svgElement.attr('data-src', newSrc);
+
+ // reinject
+ injectSvg(svgElement[0]);
+ }
+ }
+
+ function injectSvg(element) {
+ ico.inject(element, {
+ each: function (injectedElem) {
+ // compile injected svg
+ var angElem = angular.element(injectedElem);
+ svgElement = $compile(angElem)(angElem.scope());
+ }
+ });
+ }
+ }
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/interchange/interchange.js b/afb-client/bower_components/foundation-apps/js/angular/components/interchange/interchange.js
new file mode 100644
index 0000000..74ea897
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/interchange/interchange.js
@@ -0,0 +1,94 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.interchange', ['foundation.core', 'foundation.mediaquery'])
+ .directive('zfInterchange', zfInterchange)
+ ;
+
+ zfInterchange.$inject = [ '$compile', '$http', '$templateCache', 'FoundationApi', 'FoundationMQ'];
+
+ function zfInterchange($compile, $http, $templateCache, foundationApi, foundationMQ) {
+
+ var directive = {
+ restrict: 'EA',
+ transclude: 'element',
+ scope: {
+ position: '@'
+ },
+ replace: true,
+ template: '<div></div>',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, ctrl, transclude) {
+ var childScope, current, scenarios, innerTemplates;
+
+ var globalQueries = foundationMQ.getMediaQueries();
+
+ //setup
+ foundationApi.subscribe('resize', function(msg) {
+ transclude(function(clone, newScope) {
+ if(!scenarios || !innerTemplates) {
+ collectInformation(clone);
+ }
+
+ var ruleMatches = foundationMQ.match(scenarios);
+ var scenario = ruleMatches.length === 0 ? null : scenarios[ruleMatches[0].ind];
+
+ //this could use some love
+ if(scenario && checkScenario(scenario)) {
+ var compiled;
+
+ if(childScope) {
+ childScope.$destroy();
+ childScope = null;
+ }
+
+ if(typeof scenario.templ !== 'undefined') {
+ childScope = newScope;
+
+ //temp container
+ var tmp = document.createElement('div');
+ tmp.appendChild(innerTemplates[scenario.templ][0]);
+
+ element.html(tmp.innerHTML);
+ $compile(element.contents())(childScope);
+ current = scenario;
+ } else {
+ var loader = templateLoader(scenario.src);
+ loader.success(function(html) {
+ childScope = newScope;
+ element.html(html);
+ }).then(function(){
+ $compile(element.contents())(childScope);
+ current = scenario;
+ });
+ }
+ }
+ });
+
+ });
+
+ //init
+ foundationApi.publish('resize', 'initial resize');
+
+ function templateLoader(templateUrl) {
+ return $http.get(templateUrl, {cache: $templateCache});
+ }
+
+ function collectInformation(el) {
+ var data = foundationMQ.collectScenariosFromElement(el);
+
+ scenarios = data.scenarios;
+ innerTemplates = data.templates;
+ }
+
+ function checkScenario(scenario) {
+ return !current || current !== scenario;
+ }
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.html b/afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.html
new file mode 100644
index 0000000..83618db
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.html
@@ -0,0 +1,9 @@
+<div
+ class="modal-overlay"
+ ng-click="hideOverlay()">
+ <aside
+ class="modal"
+ ng-click="$event.stopPropagation();"
+ ng-transclude>
+ </aside>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.js b/afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.js
new file mode 100644
index 0000000..415f21b
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/modal/modal.js
@@ -0,0 +1,291 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.modal', ['foundation.core'])
+ .directive('zfModal', modalDirective)
+ .factory('ModalFactory', ModalFactory)
+ ;
+
+ FoundationModal.$inject = ['FoundationApi', 'ModalFactory'];
+
+ function FoundationModal(foundationApi, ModalFactory) {
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+ service.newModal = newModal;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ //target should be element ID
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+
+ //new modal has to be controlled via the new instance
+ function newModal(config) {
+ return new ModalFactory(config);
+ }
+ }
+
+ modalDirective.$inject = ['FoundationApi'];
+
+ function modalDirective(foundationApi) {
+
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/modal/modal.html',
+ transclude: true,
+ scope: true,
+ replace: true,
+ compile: compile
+ };
+
+ return directive;
+
+ function compile(tElement, tAttrs, transclude) {
+ var type = 'modal';
+
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, iElement, iAttrs, controller) {
+ iAttrs.$set('zf-closable', type);
+ }
+
+ function postLink(scope, element, attrs) {
+ var dialog = angular.element(element.children()[0]);
+
+ scope.active = scope.active || false;
+ scope.overlay = attrs.overlay === 'false' ? false : true;
+ scope.overlayClose = attrs.overlayClose === 'false' ? false : true;
+
+ var animationIn = attrs.animationIn || 'fadeIn';
+ var animationOut = attrs.animationOut || 'fadeOut';
+
+ var overlayIn = 'fadeIn';
+ var overlayOut = 'fadeOut';
+
+ scope.hideOverlay = function() {
+ if(scope.overlayClose) {
+ scope.hide();
+ }
+ };
+
+ scope.hide = function() {
+ scope.active = false;
+ animate();
+ return;
+ };
+
+ scope.show = function() {
+ scope.active = true;
+ animate();
+ dialog.tabIndex = -1;
+ dialog[0].focus();
+ return;
+ };
+
+ scope.toggle = function() {
+ scope.active = !scope.active;
+ animate();
+ return;
+ };
+
+ init();
+
+ //setup
+ foundationApi.subscribe(attrs.id, function(msg) {
+ if(msg === 'show' || msg === 'open') {
+ scope.show();
+ } else if (msg === 'close' || msg === 'hide') {
+ scope.hide();
+ } else if (msg === 'toggle') {
+ scope.toggle();
+ }
+
+ if (scope.$root && !scope.$root.$$phase) {
+ scope.$apply();
+ }
+
+ return;
+ });
+
+ function animate() {
+ //animate both overlay and dialog
+ if(!scope.overlay) {
+ element.css('background', 'transparent');
+ }
+
+ foundationApi.animate(element, scope.active, overlayIn, overlayOut);
+ foundationApi.animate(dialog, scope.active, animationIn, animationOut);
+ }
+
+ function init() {
+ if(scope.active) {
+ scope.show();
+ }
+ }
+ }
+ }
+ }
+
+ ModalFactory.$inject = ['$http', '$templateCache', '$rootScope', '$compile', '$timeout', '$q', 'FoundationApi'];
+
+ function ModalFactory($http, $templateCache, $rootScope, $compile, $timeout, $q, foundationApi) {
+ return modalFactory;
+
+ function modalFactory(config) {
+ var self = this, //for prototype functions
+ container = angular.element(config.container || document.body),
+ id = config.id || foundationApi.generateUuid(),
+ attached = false,
+ destroyed = false,
+ html,
+ element,
+ fetched,
+ scope,
+ contentScope
+ ;
+
+ var props = [
+ 'animationIn',
+ 'animationOut',
+ 'overlay',
+ 'overlayClose'
+ ];
+
+ if(config.templateUrl) {
+ //get template
+ fetched = $http.get(config.templateUrl, {
+ cache: $templateCache
+ }).then(function (response) {
+ html = response.data;
+ assembleDirective();
+ });
+
+ } else if(config.template) {
+ //use provided template
+ fetched = true;
+ html = config.template;
+ assembleDirective();
+ }
+
+ self.activate = activate;
+ self.deactivate = deactivate;
+ self.toggle = toggle;
+ self.destroy = destroy;
+
+
+ return {
+ activate: activate,
+ deactivate: deactivate,
+ toggle: toggle,
+ destroy: destroy
+ };
+
+ function checkStatus() {
+ if(destroyed) {
+ throw "Error: Modal was destroyed. Delete the object and create a new ModalFactory instance."
+ }
+ }
+
+ function activate() {
+ checkStatus();
+ $timeout(function() {
+ init(true);
+ foundationApi.publish(id, 'show');
+ }, 0, false);
+ }
+
+ function deactivate() {
+ checkStatus();
+ $timeout(function() {
+ init(false);
+ foundationApi.publish(id, 'hide');
+ }, 0, false);
+ }
+
+ function toggle() {
+ checkStatus();
+ $timeout(function() {
+ init(true);
+ foundationApi.publish(id, 'toggle');
+ }, 0, false);
+ }
+
+ function init(state) {
+ $q.when(fetched).then(function() {
+ if(!attached && html.length > 0) {
+ var modalEl = container.append(element);
+
+ scope.active = state;
+ $compile(element)(scope);
+
+ attached = true;
+ }
+ });
+ }
+
+ function assembleDirective() {
+ // check for duplicate elements to prevent factory from cloning modals
+ if (document.getElementById(id)) {
+ return;
+ }
+
+ html = '<zf-modal id="' + id + '">' + html + '</zf-modal>';
+
+ element = angular.element(html);
+
+ scope = $rootScope.$new();
+
+ // account for directive attributes
+ for(var i = 0; i < props.length; i++) {
+ var prop = props[i];
+
+ if(config[prop]) {
+ switch (prop) {
+ case 'animationIn':
+ element.attr('animation-in', config[prop]);
+ break;
+ case 'animationOut':
+ element.attr('animation-out', config[prop]);
+ break;
+ default:
+ element.attr(prop, config[prop]);
+ }
+ }
+ }
+ // access view scope variables
+ if (config.contentScope) {
+ contentScope = config.contentScope;
+ for (var prop in config.contentScope) {
+ if (config.contentScope.hasOwnProperty(prop)) {
+ scope[prop] = config.contentScope[prop];
+ }
+ }
+ }
+ }
+
+ function destroy() {
+ self.deactivate();
+ setTimeout(function() {
+ scope.$destroy();
+ element.remove();
+ destroyed = true;
+ }, 3000);
+ foundationApi.unsubscribe(id);
+ }
+
+ }
+
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-set.html b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-set.html
new file mode 100644
index 0000000..9193026
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-set.html
@@ -0,0 +1,9 @@
+<div class="notification-container {{position}}">
+ <zf-notification ng-repeat="notification in notifications"
+ title="notification.title"
+ image="notification.image"
+ notif-id = "notification.id"
+ color="notification.color"
+ autoclose="notification.autoclose"
+ >{{ notification.content }}</zf-notification>
+</div> \ No newline at end of file
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-static.html b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-static.html
new file mode 100644
index 0000000..f524eed
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification-static.html
@@ -0,0 +1,12 @@
+<div zf-swipe-close="swipe" class="static-notification {{ color }} {{ position }}">
+ <a href="#"
+ class="close-button"
+ ng-click="hide(); $event.preventDefault(); $event.stopPropagation()">&times;</a>
+ <div class="notification-icon" ng-if="image">
+ <img ng-src="{{ image }}"/>
+ </div>
+ <div class="notification-content">
+ <h1>{{ title }}</h1>
+ <p ng-transclude></p>
+ </div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.html b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.html
new file mode 100644
index 0000000..a311f01
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.html
@@ -0,0 +1,12 @@
+<div zf-swipe-close="swipe" class="notification {{ color }}">
+ <a href="#"
+ class="close-button"
+ ng-click="hide(); $event.preventDefault(); $event.stopPropagation()">&times;</a>
+ <div class="notification-icon" ng-if="image">
+ <img ng-src="{{ image }}"/>
+ </div>
+ <div class="notification-content">
+ <h1>{{ title }}</h1>
+ <p ng-transclude></p>
+ </div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.js b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.js
new file mode 100644
index 0000000..2c0e3bc
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/notification/notification.js
@@ -0,0 +1,417 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.notification', ['foundation.core'])
+ .controller('ZfNotificationController', ZfNotificationController)
+ .directive('zfNotificationSet', zfNotificationSet)
+ .directive('zfNotification', zfNotification)
+ .directive('zfNotificationStatic', zfNotificationStatic)
+ .directive('zfNotify', zfNotify)
+ .factory('NotificationFactory', NotificationFactory)
+ .service('FoundationNotification', FoundationNotification)
+ ;
+
+ FoundationNotification.$inject = ['FoundationApi', 'NotificationFactory'];
+
+ function FoundationNotification(foundationApi, NotificationFactory) {
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ //target should be element ID
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+
+ function toggle(target) {
+ foundationApi.publish(target, 'toggle');
+ }
+
+ function createNotificationSet(config) {
+ return new NotificationFactory(config);
+ }
+ }
+
+
+ ZfNotificationController.$inject = ['$scope', 'FoundationApi'];
+
+ function ZfNotificationController($scope, foundationApi) {
+ var controller = this;
+ controller.notifications = $scope.notifications = $scope.notifications || [];
+
+ controller.addNotification = function(info) {
+ var id = foundationApi.generateUuid();
+ info.id = id;
+ $scope.notifications.push(info);
+ };
+
+ controller.removeNotification = function(id) {
+ $scope.notifications.forEach(function(notification) {
+ if(notification.id === id) {
+ var ind = $scope.notifications.indexOf(notification);
+ $scope.notifications.splice(ind, 1);
+ }
+ });
+ };
+
+ controller.clearAll = function() {
+ while($scope.notifications.length > 0) {
+ $scope.notifications.pop();
+ }
+ };
+ }
+
+ zfNotificationSet.$inject = ['FoundationApi'];
+
+ function zfNotificationSet(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/notification/notification-set.html',
+ controller: 'ZfNotificationController',
+ replace: true,
+ scope: {
+ position: '@'
+ },
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller) {
+ scope.position = scope.position ? scope.position.split(' ').join('-') : 'top-right';
+
+ foundationApi.subscribe(attrs.id, function(msg) {
+ if(msg === 'clearall') {
+ controller.clearAll();
+ }
+ else {
+ controller.addNotification(msg);
+ if (!scope.$root.$$phase) {
+ scope.$apply();
+ }
+ }
+ });
+ }
+ }
+
+ zfNotification.$inject = ['FoundationApi'];
+
+ function zfNotification(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/notification/notification.html',
+ replace: true,
+ transclude: true,
+ require: '^zfNotificationSet',
+ controller: function() { },
+ scope: {
+ title: '=?',
+ content: '=?',
+ image: '=?',
+ notifId: '=',
+ color: '=?',
+ autoclose: '=?'
+ },
+ compile: compile
+ };
+
+ return directive;
+
+ function compile() {
+
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, iElement, iAttrs) {
+ iAttrs.$set('zf-closable', 'notification');
+ }
+
+ function postLink(scope, element, attrs, controller) {
+ scope.active = false;
+ var animationIn = attrs.animationIn || 'fadeIn';
+ var animationOut = attrs.animationOut || 'fadeOut';
+ var hammerElem;
+
+ //due to dynamic insertion of DOM, we need to wait for it to show up and get working!
+ setTimeout(function() {
+ scope.active = true;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ }, 50);
+
+ scope.hide = function() {
+ scope.active = false;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ setTimeout(function() {
+ controller.removeNotification(scope.notifId);
+ }, 50);
+ };
+
+ // close if autoclose
+ if (scope.autoclose) {
+ setTimeout(function() {
+ if (scope.active) {
+ scope.hide();
+ }
+ }, parseInt(scope.autoclose));
+ };
+
+ // close on swipe
+ if (Hammer) {
+ hammerElem = new Hammer(element[0]);
+ // set the options for swipe (to make them a bit more forgiving in detection)
+ hammerElem.get('swipe').set({
+ direction: Hammer.DIRECTION_ALL,
+ threshold: 5, // this is how far the swipe has to travel
+ velocity: 0.5 // and this is how fast the swipe must travel
+ });
+ }
+
+ hammerElem.on('swipe', function() {
+ if (scope.active) {
+ scope.hide();
+ }
+ });
+ }
+ }
+ }
+
+ zfNotificationStatic.$inject = ['FoundationApi'];
+
+ function zfNotificationStatic(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/notification/notification-static.html',
+ replace: true,
+ transclude: true,
+ scope: {
+ title: '@?',
+ content: '@?',
+ image: '@?',
+ color: '@?',
+ autoclose: '@?'
+ },
+ compile: compile
+ };
+
+ return directive;
+
+ function compile() {
+ var type = 'notification';
+
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, iElement, iAttrs, controller) {
+ iAttrs.$set('zf-closable', type);
+ }
+
+ function postLink(scope, element, attrs, controller) {
+ scope.position = attrs.position ? attrs.position.split(' ').join('-') : 'top-right';
+
+ var animationIn = attrs.animationIn || 'fadeIn';
+ var animationOut = attrs.animationOut || 'fadeOut';
+
+ //setup
+ foundationApi.subscribe(attrs.id, function(msg) {
+ if(msg == 'show' || msg == 'open') {
+ scope.show();
+ // close if autoclose
+ if (scope.autoclose) {
+ setTimeout(function() {
+ if (scope.active) {
+ scope.hide();
+ }
+ }, parseInt(scope.autoclose));
+ };
+ } else if (msg == 'close' || msg == 'hide') {
+ scope.hide();
+ } else if (msg == 'toggle') {
+ scope.toggle();
+ // close if autoclose
+ if (scope.autoclose) {
+ setTimeout(function() {
+ if (scope.active) {
+ scope.toggle();
+ }
+ }, parseInt(scope.autoclose));
+ };
+ }
+
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ scope.$apply();
+
+ return;
+ });
+
+ scope.hide = function() {
+ scope.active = false;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ return;
+ };
+
+ scope.show = function() {
+ scope.active = true;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ return;
+ };
+
+ scope.toggle = function() {
+ scope.active = !scope.active;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ return;
+ };
+
+ }
+ }
+ }
+
+ zfNotify.$inject = ['FoundationApi'];
+
+ function zfNotify(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ scope: {
+ title: '@?',
+ content: '@?',
+ color: '@?',
+ image: '@?',
+ autoclose: '@?'
+ },
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller) {
+ element.on('click', function(e) {
+ foundationApi.publish(attrs.zfNotify, {
+ title: scope.title,
+ content: scope.content,
+ color: scope.color,
+ image: scope.image,
+ autoclose: scope.autoclose
+ });
+ e.preventDefault();
+ });
+ }
+ }
+
+ NotificationFactory.$inject = ['$http', '$templateCache', '$rootScope', '$compile', '$timeout', 'FoundationApi'];
+
+ function NotificationFactory($http, $templateCache, $rootScope, $compile, $timeout, foundationApi) {
+ return notificationFactory;
+
+ function notificationFactory(config) {
+ var self = this, //for prototype functions
+ container = angular.element(config.container || document.body),
+ id = config.id || foundationApi.generateUuid(),
+ attached = false,
+ destroyed = false,
+ html,
+ element,
+ scope,
+ contentScope
+ ;
+
+ var props = [
+ 'position'
+ ];
+
+ assembleDirective();
+
+ self.addNotification = addNotification;
+ self.clearAll = clearAll;
+ self.destroy = destroy;
+
+ return {
+ addNotification: addNotification,
+ clearAll: clearAll,
+ destroy: destroy
+ };
+
+ function checkStatus() {
+ if(destroyed) {
+ throw "Error: Notification Set was destroyed. Delete the object and create a new NotificationFactory instance."
+ }
+ }
+
+ function addNotification(notification) {
+ checkStatus();
+ $timeout(function() {
+ foundationApi.publish(id, notification);
+ }, 0, false);
+ }
+
+ function clearAll() {
+ checkStatus();
+ $timeout(function() {
+ foundationApi.publish(id, 'clearall');
+ }, 0, false);
+ }
+
+ function init(state) {
+ if(!attached && html.length > 0) {
+ var modalEl = container.append(element);
+
+ scope.active = state;
+ $compile(element)(scope);
+
+ attached = true;
+ }
+ }
+
+ function assembleDirective() {
+ // check for duplicate element to prevent factory from cloning notification sets
+ if (document.getElementById(id)) {
+ return;
+ }
+ html = '<zf-notification-set id="' + id + '"></zf-notification-set>';
+
+ element = angular.element(html);
+
+ scope = $rootScope.$new();
+
+ for(var i = 0; i < props.length; i++) {
+ if(config[props[i]]) {
+ element.attr(props[i], config[props[i]]);
+ }
+ }
+
+ // access view scope variables
+ if (config.contentScope) {
+ contentScope = config.contentScope;
+ for (var prop in contentScope) {
+ if (contentScope.hasOwnProperty(prop)) {
+ scope[prop] = contentScope[prop];
+ }
+ }
+ }
+ init(true);
+ }
+
+ function destroy() {
+ self.clearAll();
+ setTimeout(function() {
+ scope.$destroy();
+ element.remove();
+ destroyed = true;
+ }, 3000);
+ foundationApi.unsubscribe(id);
+ }
+
+ }
+
+ }
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.html b/afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.html
new file mode 100644
index 0000000..233cb02
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.html
@@ -0,0 +1,5 @@
+<div
+ class="off-canvas {{ position }}"
+ ng-class="{'is-active': active}"
+ ng-transclude>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.js b/afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.js
new file mode 100644
index 0000000..b1d6cff
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/offcanvas/offcanvas.js
@@ -0,0 +1,102 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.offcanvas', ['foundation.core'])
+ .directive('zfOffcanvas', zfOffcanvas)
+ .service('FoundationOffcanvas', FoundationOffcanvas)
+ ;
+
+ FoundationOffcanvas.$inject = ['FoundationApi'];
+
+ function FoundationOffcanvas(foundationApi) {
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ //target should be element ID
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+
+ function toggle(target) {
+ foundationApi.publish(target, 'toggle');
+ }
+ }
+
+ zfOffcanvas.$inject = ['FoundationApi'];
+
+ function zfOffcanvas(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/offcanvas/offcanvas.html',
+ transclude: true,
+ scope: {
+ position: '@'
+ },
+ replace: true,
+ compile: compile
+ };
+
+ return directive;
+
+ function compile(tElement, tAttrs, transclude) {
+ var type = 'offcanvas';
+
+ return {
+ pre: preLink,
+ post: postLink
+ }
+
+ function preLink(scope, iElement, iAttrs, controller) {
+ iAttrs.$set('zf-closable', type);
+ document.body.classList.add('has-off-canvas');
+ }
+
+ function postLink(scope, element, attrs) {
+ scope.position = scope.position || 'left';
+
+ scope.active = false;
+ //setup
+ foundationApi.subscribe(attrs.id, function(msg) {
+ if(msg === 'show' || msg === 'open') {
+ scope.show();
+ } else if (msg === 'close' || msg === 'hide') {
+ scope.hide();
+ } else if (msg === 'toggle') {
+ scope.toggle();
+ }
+
+ if (!scope.$root.$$phase) {
+ scope.$apply();
+ }
+
+ return;
+ });
+
+ scope.hide = function() {
+ scope.active = false;
+ return;
+ };
+
+ scope.show = function() {
+ scope.active = true;
+ return;
+ };
+
+ scope.toggle = function() {
+ scope.active = !scope.active;
+ return;
+ };
+ }
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.html b/afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.html
new file mode 100644
index 0000000..75a5b48
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.html
@@ -0,0 +1,6 @@
+<div
+ class="panel"
+ ng-class="positionClass"
+ ng-transclude
+ >
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.js b/afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.js
new file mode 100644
index 0000000..396ca28
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/panel/panel.js
@@ -0,0 +1,144 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.panel', ['foundation.core'])
+ .directive('zfPanel', zfPanel)
+ .service('FoundationPanel', FoundationPanel)
+ ;
+
+ FoundationPanel.$inject = ['FoundationApi'];
+
+ function FoundationPanel(foundationApi) {
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ //target should be element ID
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+ }
+
+ zfPanel.$inject = ['FoundationApi', '$window'];
+
+ function zfPanel(foundationApi, $window) {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/panel/panel.html',
+ transclude: true,
+ scope: {
+ position: '@?'
+ },
+ replace: true,
+ compile: compile
+ };
+
+ return directive;
+
+ function compile(tElement, tAttrs, transclude) {
+ var type = 'panel';
+
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, iElement, iAttrs, controller) {
+ iAttrs.$set('zf-closable', type);
+ scope.position = scope.position || 'left';
+ scope.positionClass = 'panel-' + scope.position;
+ }
+
+ function postLink(scope, element, attrs) {
+ scope.active = false;
+ var animationIn, animationOut;
+ var globalQueries = foundationApi.getSettings().mediaQueries;
+
+ //urgh, there must be a better way
+ if(scope.position === 'left') {
+ animationIn = attrs.animationIn || 'slideInRight';
+ animationOut = attrs.animationOut || 'slideOutLeft';
+ } else if (scope.position === 'right') {
+ animationIn = attrs.animationIn || 'slideInLeft';
+ animationOut = attrs.animationOut || 'slideOutRight';
+ } else if (scope.position === 'top') {
+ animationIn = attrs.animationIn || 'slideInDown';
+ animationOut = attrs.animationOut || 'slideOutUp';
+ } else if (scope.position === 'bottom') {
+ animationIn = attrs.animationIn || 'slideInUp';
+ animationOut = attrs.animationOut || 'slideOutBottom';
+ }
+
+
+ //setup
+ foundationApi.subscribe(attrs.id, function(msg) {
+ var panelPosition = $window.getComputedStyle(element[0]).getPropertyValue("position");
+
+ // patch to prevent panel animation on larger screen devices
+ if (panelPosition !== 'absolute') {
+ return;
+ }
+
+ if(msg == 'show' || msg == 'open') {
+ scope.show();
+ } else if (msg == 'close' || msg == 'hide') {
+ scope.hide();
+ } else if (msg == 'toggle') {
+ scope.toggle();
+ }
+
+ if (!scope.$root.$$phase) {
+ scope.$apply();
+ }
+
+ return;
+ });
+
+ scope.hide = function() {
+ if(scope.active){
+ scope.active = false;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ }
+
+ return;
+ };
+
+ scope.show = function() {
+ if(!scope.active){
+ scope.active = true;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ }
+
+ return;
+ };
+
+ scope.toggle = function() {
+ scope.active = !scope.active;
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+
+ return;
+ };
+
+ element.on('click', function(e) {
+ //check sizing
+ var srcEl = e.srcElement;
+
+ if(!matchMedia(globalQueries.medium).matches && srcEl.href && srcEl.href.length > 0) {
+ //hide element if it can't match at least medium
+ scope.hide();
+ foundationApi.animate(element, scope.active, animationIn, animationOut);
+ }
+ });
+ }
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.html b/afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.html
new file mode 100644
index 0000000..50abed7
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.html
@@ -0,0 +1,2 @@
+<div class="popup" ng-class="{'is-active': active }" ng-transclude>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.js b/afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.js
new file mode 100644
index 0000000..f51b1c6
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/popup/popup.js
@@ -0,0 +1,160 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.popup', ['foundation.core'])
+ .directive('zfPopup', zfPopup)
+ .directive('zfPopupToggle', zfPopupToggle)
+ .service('FoundationPopup', FoundationPopup)
+ ;
+
+ FoundationPopup.$inject = ['FoundationApi'];
+
+ function FoundationPopup(foundationApi) {
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ //target should be element ID
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+
+ function toggle(target, popupTarget) {
+ foundationApi.publish(target, ['toggle', popupTarget]);
+ }
+ }
+
+ zfPopup.$inject = ['FoundationApi'];
+
+ function zfPopup(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ transclude: true,
+ replace: true,
+ templateUrl: 'components/popup/popup.html',
+ scope: {
+ pinTo: '@?',
+ pinAt: '@?',
+ target: '@?'
+ },
+ compile: compile
+ };
+
+ return directive;
+
+ function compile() {
+ return {
+ pre: preLink,
+ post: postLink
+ };
+
+ function preLink(scope, iElement, iAttrs) {
+ iAttrs.$set('zf-closable', 'popup');
+ }
+
+ function postLink(scope, element, attrs) {
+ scope.active = false;
+ scope.target = scope.target || false;
+
+ var attachment = scope.pinTo || 'top center';
+ var targetAttachment = scope.pinAt || 'bottom center';
+ var tetherInit = false;
+ var tether = {};
+
+ //setup
+ foundationApi.subscribe(attrs.id, function(msg) {
+ if(msg[0] === 'show' || msg[0] === 'open') {
+ scope.show(msg[1]);
+ } else if (msg[0] === 'close' || msg[0] === 'hide') {
+ scope.hide();
+ } else if (msg[0] === 'toggle') {
+ scope.toggle(msg[1]);
+ }
+
+ scope.$apply();
+
+ return;
+ });
+
+
+ scope.hide = function() {
+ scope.active = false;
+ tetherElement();
+ tether.disable();
+ return;
+ };
+
+ scope.show = function(newTarget) {
+ scope.active = true;
+ tetherElement(newTarget);
+ tether.enable();
+
+ return;
+ };
+
+ scope.toggle = function(newTarget) {
+ scope.active = !scope.active;
+ tetherElement(newTarget);
+
+ if(scope.active) {
+ tether.enable();
+ } else {
+ tether.disable();
+ }
+
+ return;
+ };
+
+ function tetherElement(target) {
+ if(tetherInit) {
+ return;
+ }
+
+ scope.target = scope.target ? document.getElementById(scope.target) : document.getElementById(target);
+
+ tether = new Tether({
+ element: element[0],
+ target: scope.target,
+ attachment: attachment,
+ targetAttachment: targetAttachment,
+ enable: false
+ });
+
+ tetherInit = true;
+ }
+
+ }
+ }
+ }
+
+ zfPopupToggle.$inject = ['FoundationApi'];
+
+ function zfPopupToggle(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs) {
+ var target = attrs.zfPopupToggle;
+ var id = attrs.id || foundationApi.generateUuid();
+ attrs.$set('id', id);
+
+ element.on('click', function(e) {
+ foundationApi.publish(target, ['toggle', id]);
+ e.preventDefault();
+ });
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab-content.html b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab-content.html
new file mode 100644
index 0000000..6ae46e7
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab-content.html
@@ -0,0 +1,8 @@
+<div class="tab-contents">
+ <div zf-tab-individual
+ class="tab-content"
+ ng-class="{'is-active': tab.active}"
+ ng-repeat="tab in tabs"
+ tab="tab">
+ </div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab.html b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab.html
new file mode 100644
index 0000000..082bf86
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tab.html
@@ -0,0 +1,3 @@
+<div class="tab-item"
+ ng-class="{'is-active': active}"
+ ng-click="makeActive()">{{ title }}</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.html b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.html
new file mode 100644
index 0000000..b8a66f5
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.html
@@ -0,0 +1,8 @@
+<div>
+ <div class="tabs" ng-transclude>
+ </div>
+ <div zf-tab-content
+ target="{{ id }}"
+ ng-if="showTabContent">
+ </div>
+</div>
diff --git a/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.js b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.js
new file mode 100644
index 0000000..3818a2a
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/components/tabs/tabs.js
@@ -0,0 +1,311 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.tabs', ['foundation.core'])
+ .controller('ZfTabsController', ZfTabsController)
+ .directive('zfTabs', zfTabs)
+ .directive('zfTabContent', zfTabContent)
+ .directive('zfTab', zfTab)
+ .directive('zfTabIndividual', zfTabIndividual)
+ .directive('zfTabHref', zfTabHref)
+ .directive('zfTabCustom', zfTabCustom)
+ .directive('zfTabContentCustom', zfTabContentCustom)
+ .service('FoundationTabs', FoundationTabs)
+ ;
+
+ FoundationTabs.$inject = ['FoundationApi'];
+
+ function FoundationTabs(foundationApi) {
+ var service = {};
+
+ service.activate = activate;
+
+ return service;
+
+ //target should be element ID
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ }
+
+ ZfTabsController.$inject = ['$scope', 'FoundationApi'];
+
+ function ZfTabsController($scope, foundationApi) {
+ var controller = this;
+ var tabs = controller.tabs = $scope.tabs = [];
+ var id = '';
+
+ controller.select = function(selectTab) {
+ tabs.forEach(function(tab) {
+ tab.active = false;
+ tab.scope.active = false;
+
+ if(tab.scope === selectTab) {
+ foundationApi.publish(id, ['activate', tab]);
+
+ tab.active = true;
+ tab.scope.active = true;
+ }
+ });
+
+ };
+
+ controller.addTab = function addTab(tabScope) {
+ tabs.push({ scope: tabScope, active: false, parentContent: controller.id });
+
+ if(tabs.length === 1) {
+ tabs[0].active = true;
+ tabScope.active = true;
+ }
+ };
+
+ controller.getId = function() {
+ return id;
+ };
+
+ controller.setId = function(newId) {
+ id = newId;
+ };
+ }
+
+ zfTabs.$inject = ['FoundationApi'];
+
+ function zfTabs(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ transclude: 'true',
+ replace: true,
+ templateUrl: 'components/tabs/tabs.html',
+ controller: 'ZfTabsController',
+ scope: {
+ displaced: '@?'
+ },
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller) {
+ scope.id = attrs.id || foundationApi.generateUuid();
+ scope.showTabContent = scope.displaced !== 'true';
+ attrs.$set('id', scope.id);
+ controller.setId(scope.id);
+
+ //update tabs in case tab-content doesn't have them
+ var updateTabs = function() {
+ foundationApi.publish(scope.id + '-tabs', scope.tabs);
+ };
+
+ foundationApi.subscribe(scope.id + '-get-tabs', function() {
+ updateTabs();
+ });
+ }
+ }
+
+ zfTabContent.$inject = ['FoundationApi'];
+
+ function zfTabContent(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ transclude: 'true',
+ replace: true,
+ scope: {
+ tabs: '=?',
+ target: '@'
+ },
+ templateUrl: 'components/tabs/tab-content.html',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, ctrl) {
+ scope.tabs = scope.tabs || [];
+ var id = scope.target;
+
+ foundationApi.subscribe(id, function(msg) {
+ if(msg[0] === 'activate') {
+ var tabId = msg[1];
+ scope.tabs.forEach(function (tab) {
+ tab.scope.active = false;
+ tab.active = false;
+
+ if(tab.scope.id === id) {
+ tab.scope.active = true;
+ tab.active = true;
+ }
+ });
+ }
+ });
+
+ //if tabs empty, request tabs
+ if(scope.tabs.length === 0) {
+ foundationApi.subscribe(id + '-tabs', function(tabs) {
+ scope.tabs = tabs;
+ });
+
+ foundationApi.publish(id + '-get-tabs', '');
+ }
+ }
+ }
+
+ zfTab.$inject = ['FoundationApi'];
+
+ function zfTab(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ templateUrl: 'components/tabs/tab.html',
+ transclude: true,
+ scope: {
+ title: '@'
+ },
+ require: '^zfTabs',
+ replace: true,
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, controller, transclude) {
+ scope.id = attrs.id || foundationApi.generateUuid();
+ scope.active = false;
+ scope.transcludeFn = transclude;
+ controller.addTab(scope);
+
+ foundationApi.subscribe(scope.id, function(msg) {
+ if(msg === 'show' || msg === 'open' || msg === 'activate') {
+ scope.makeActive();
+ }
+ });
+
+ scope.makeActive = function() {
+ controller.select(scope);
+ };
+ }
+ }
+
+ zfTabIndividual.$inject = ['FoundationApi'];
+
+ function zfTabIndividual(foundationApi) {
+ var directive = {
+ restrict: 'EA',
+ transclude: 'true',
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, ctrl, transclude) {
+ var tab = scope.$eval(attrs.tab);
+ var id = tab.scope.id;
+
+ tab.scope.transcludeFn(tab.scope, function(tabContent) {
+ element.append(tabContent);
+ });
+
+ foundationApi.subscribe(tab.scope.id, function(msg) {
+ foundationApi.publish(tab.parentContent, ['activate', tab.scope.id]);
+ scope.$apply();
+ });
+
+ }
+ }
+
+ //custom tabs
+
+ zfTabHref.$inject = ['FoundationApi'];
+
+ function zfTabHref(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ replace: false,
+ link: link
+ }
+
+ return directive;
+
+ function link(scope, element, attrs, ctrl) {
+ var target = attrs.zfTabHref;
+
+ foundationApi.subscribe(target, function(msg) {
+ if(msg === 'activate' || msg === 'show' || msg === 'open') {
+ makeActive();
+ }
+ });
+
+
+ element.on('click', function(e) {
+ foundationApi.publish(target, 'activate');
+ makeActive();
+ e.preventDefault();
+ });
+
+ function makeActive() {
+ element.parent().children().removeClass('is-active');
+ element.addClass('is-active');
+ }
+ }
+ }
+
+ zfTabCustom.$inject = ['FoundationApi'];
+
+ function zfTabCustom(foundationApi) {
+ var directive = {
+ restrict: 'A',
+ replace: false,
+ link: link
+ };
+
+ return directive;
+
+ function link(scope, element, attrs, ctrl, transclude) {
+ var children = element.children();
+ angular.element(children[0]).addClass('is-active');
+ }
+ }
+
+ zfTabContentCustom.$inject = ['FoundationApi'];
+
+ function zfTabContentCustom(foundationApi) {
+ return {
+ restrict: 'A',
+ link: link
+ };
+
+ function link(scope, element, attrs) {
+ var tabs = [];
+ var children = element.children();
+
+ angular.forEach(children, function(node) {
+ if(node.id) {
+ var tabId = node.id;
+ tabs.push(tabId);
+ foundationApi.subscribe(tabId, function(msg) {
+ if(msg === 'activate' || msg === 'show' || msg === 'open') {
+ activateTabs(tabId);
+ }
+ });
+
+ if(tabs.length === 1) {
+ var el = angular.element(node);
+ el.addClass('is-active');
+ }
+ }
+ });
+
+ function activateTabs(tabId) {
+ var tabNodes = element.children();
+ angular.forEach(tabNodes, function(node) {
+ var el = angular.element(node);
+ el.removeClass('is-active');
+ if(el.attr('id') === tabId) {
+ el.addClass('is-active');
+ }
+
+ });
+ }
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/foundation.js b/afb-client/bower_components/foundation-apps/js/angular/foundation.js
new file mode 100644
index 0000000..71ac6e3
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/foundation.js
@@ -0,0 +1,22 @@
+(function() {
+ 'use strict';
+
+ // imports all components and dependencies under a single namespace
+
+ angular.module('foundation', [
+ 'foundation.core',
+ 'foundation.mediaquery',
+ 'foundation.accordion',
+ 'foundation.actionsheet',
+ 'foundation.common',
+ 'foundation.iconic',
+ 'foundation.interchange',
+ 'foundation.modal',
+ 'foundation.notification',
+ 'foundation.offcanvas',
+ 'foundation.panel',
+ 'foundation.popup',
+ 'foundation.tabs'
+ ]);
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js
new file mode 100644
index 0000000..535798a
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.animation.js
@@ -0,0 +1,129 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.core.animation', [])
+ .service('FoundationAnimation', FoundationAnimation)
+ ;
+
+ function FoundationAnimation() {
+ var animations = [];
+ var service = {};
+
+ var initClasses = ['ng-enter', 'ng-leave'];
+ var activeClasses = ['ng-enter-active', 'ng-leave-active'];
+ var activeGenericClass = 'is-active';
+ var events = [
+ 'webkitAnimationEnd', 'mozAnimationEnd',
+ 'MSAnimationEnd', 'oanimationend',
+ 'animationend', 'webkitTransitionEnd',
+ 'otransitionend', 'transitionend'
+ ];
+
+ service.animate = animate;
+ service.toggleAnimation = toggleAnimation;
+
+ return service;
+
+ function toggleAnimation(element, futureState) {
+ if(futureState) {
+ element.addClass(activeGenericClass);
+ } else {
+ element.removeClass(activeGenericClass);
+ }
+ }
+
+ function animate(element, futureState, animationIn, animationOut) {
+ var timedOut = true;
+ var self = this;
+ self.cancelAnimation = cancelAnimation;
+
+ var animationClass = futureState ? animationIn: animationOut;
+ var activation = futureState;
+ var initClass = activation ? initClasses[0] : initClasses[1];
+ var activeClass = activation ? activeClasses[0] : activeClasses[1];
+ //stop animation
+ registerElement(element);
+ reset();
+ element.addClass(animationClass);
+ element.addClass(initClass);
+
+ element.addClass(activeGenericClass);
+
+ //force a "tick"
+ reflow();
+
+ //activate
+ element[0].style.transitionDuration = '';
+ element.addClass(activeClass);
+
+ element.one(events.join(' '), function() {
+ finishAnimation();
+ });
+
+ setTimeout(function() {
+ if(timedOut) {
+ finishAnimation();
+ }
+ }, 3000);
+
+ function finishAnimation() {
+ deregisterElement(element);
+ reset(); //reset all classes
+ element[0].style.transitionDuration = '';
+ element.removeClass(!activation ? activeGenericClass : ''); //if not active, remove active class
+ reflow();
+ timedOut = false;
+ }
+
+
+ function cancelAnimation(element) {
+ deregisterElement(element);
+ angular.element(element).off(events.join(' ')); //kill all animation event handlers
+ timedOut = false;
+ }
+
+ function registerElement(el) {
+ var elObj = {
+ el: el,
+ animation: self
+ };
+
+ //kill in progress animations
+ var inProgress = animations.filter(function(obj) {
+ return obj.el === el;
+ });
+ if(inProgress.length > 0) {
+ var target = inProgress[0].el[0];
+
+ inProgress[0].animation.cancelAnimation(target);
+ }
+
+ animations.push(elObj);
+ }
+
+ function deregisterElement(el) {
+ var index;
+ var currentAnimation = animations.filter(function(obj, ind) {
+ if(obj.el === el) {
+ index = ind;
+ }
+ });
+
+ if(index >= 0) {
+ animations.splice(index, 1);
+ }
+
+ }
+
+ function reflow() {
+ return element[0].offsetWidth;
+ }
+
+ function reset() {
+ element[0].style.transitionDuration = 0;
+ element.removeClass(initClasses.join(' ') + ' ' + activeClasses.join(' ') + ' ' + animationIn + ' ' + animationOut);
+ }
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js
new file mode 100644
index 0000000..6aeb9da
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.core.js
@@ -0,0 +1,163 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.core', [
+ 'foundation.core.animation'
+ ])
+ .service('FoundationApi', FoundationApi)
+ .service('FoundationAdapter', FoundationAdapter)
+ .factory('Utils', Utils)
+ ;
+
+ FoundationApi.$inject = ['FoundationAnimation'];
+
+ function FoundationApi(FoundationAnimation) {
+ var listeners = {};
+ var settings = {};
+ var uniqueIds = [];
+ var service = {};
+
+ service.subscribe = subscribe;
+ service.unsubscribe = unsubscribe;
+ service.publish = publish;
+ service.getSettings = getSettings;
+ service.modifySettings = modifySettings;
+ service.generateUuid = generateUuid;
+ service.toggleAnimate = toggleAnimate;
+ service.closeActiveElements = closeActiveElements;
+ service.animate = animate;
+
+ return service;
+
+ function subscribe(name, callback) {
+ if (!listeners[name]) {
+ listeners[name] = [];
+ }
+
+ listeners[name].push(callback);
+ return true;
+ }
+
+ function unsubscribe(name, callback) {
+ if (listeners[name] !== undefined) {
+ delete listeners[name];
+ }
+ if (typeof callback == 'function') {
+ callback.call(this);
+ }
+ }
+
+ function publish(name, msg) {
+ if (!listeners[name]) {
+ listeners[name] = [];
+ }
+
+ listeners[name].forEach(function(cb) {
+ cb(msg);
+ });
+
+ return;
+ }
+
+ function getSettings() {
+ return settings;
+ }
+
+ function modifySettings(tree) {
+ settings = angular.extend(settings, tree);
+ return settings;
+ }
+
+ function generateUuid() {
+ var uuid = '';
+
+ //little trick to produce semi-random IDs
+ do {
+ uuid += 'zf-uuid-';
+ for (var i=0; i<15; i++) {
+ uuid += Math.floor(Math.random()*16).toString(16);
+ }
+ } while(!uniqueIds.indexOf(uuid));
+
+ uniqueIds.push(uuid);
+ return uuid;
+ }
+
+ function toggleAnimate(element, futureState) {
+ FoundationAnimation.toggleAnimate(element, futureState);
+ }
+
+ function closeActiveElements(options) {
+ var self = this;
+ options = options || {};
+ var activeElements = document.querySelectorAll('.is-active[zf-closable]');
+ // action sheets are nested zf-closable elements, so we have to target the parent
+ var nestedActiveElements = document.querySelectorAll('[zf-closable] > .is-active')
+
+ if (activeElements.length) {
+ angular.forEach(activeElements, function(el) {
+ if (options.exclude !== el.id) {
+ self.publish(el.id, 'close');
+ }
+ });
+ }
+ if (nestedActiveElements.length) {
+ angular.forEach(nestedActiveElements, function(el) {
+ var parentId = el.parentNode.id;
+ if (options.exclude !== parentId) {
+ self.publish(parentId, 'close');
+ }
+ })
+ }
+ }
+
+ function animate(element, futureState, animationIn, animationOut) {
+ FoundationAnimation.animate(element, futureState, animationIn, animationOut);
+ }
+ }
+
+ FoundationAdapter.$inject = ['FoundationApi'];
+
+ function FoundationAdapter(foundationApi) {
+
+ var service = {};
+
+ service.activate = activate;
+ service.deactivate = deactivate;
+
+ return service;
+
+ function activate(target) {
+ foundationApi.publish(target, 'show');
+ }
+
+ function deactivate(target) {
+ foundationApi.publish(target, 'hide');
+ }
+ }
+
+
+ function Utils() {
+ var utils = {};
+
+ utils.throttle = throttleUtil;
+
+ return utils;
+
+ function throttleUtil(func, delay) {
+ var timer = null;
+
+ return function () {
+ var context = this, args = arguments;
+
+ if (timer === null) {
+ timer = setTimeout(function () {
+ func.apply(context, args);
+ timer = null;
+ }, delay);
+ }
+ };
+ }
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js
new file mode 100644
index 0000000..ba79c52
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.animations.js
@@ -0,0 +1,125 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.dynamicRouting.animations', ['foundation.dynamicRouting'])
+ .directive('uiView', uiView)
+ ;
+
+ uiView.$inject = ['$rootScope', '$state'];
+
+ function uiView($rootScope, $state) {
+ var directive = {
+ restrict : 'ECA',
+ priority : -400,
+ link : link
+ };
+
+ return directive;
+
+ function link(scope, element) {
+ var animation = {};
+ var animationEnded = false;
+ var presetHeight;
+
+ var cleanup = [
+ $rootScope.$on('$stateChangeStart', onStateChangeStart),
+ $rootScope.$on('$stateChangeError', onStateChangeError),
+ scope.$on('$stateChangeSuccess', onStateChangeSuccess),
+ scope.$on('$viewContentAnimationEnded', onViewContentAnimationEnded)
+ ];
+
+ var destroyed = scope.$on('$destroy', function onDestroy() {
+ angular.forEach(cleanup, function (cb) {
+ if (angular.isFunction(cb)) {
+ cb();
+ }
+ });
+
+ destroyed();
+ });
+
+ function onStateChangeStart(event, toState, toParams, fromState, fromParams) {
+
+ if (fromState.animation) {
+ if (!fromState.animation.leave && !toState.animation.leave) {
+ return;
+ }
+ else {
+ animationRouter(event, toState, fromState);
+ }
+ }
+ }
+
+ function animationRouter(event, toState, fromState) {
+ if (!animationEnded) {
+ resetParent();
+ prepareParent();
+
+ element.removeClass(fromState.animation.leave);
+ }
+ else {
+ prepareParent();
+
+ element.addClass(fromState.animation.leave);
+ }
+
+ }
+
+ function onStateChangeError() {
+ if(animation.leave) {
+ element.removeClass(animation.leave);
+ }
+
+ resetParent(); //reset parent if state change fails
+ }
+
+ function onStateChangeSuccess() {
+ resetParent();
+ if ($state.includes(getState()) && animation.enter) {
+ element.addClass(animation.enter);
+ }
+ }
+
+ function onViewContentAnimationEnded(event) {
+ if (event.targetScope === scope && animation.enter) {
+ element.removeClass(animation.enter);
+ }
+
+ animationEnded = true;
+
+ }
+
+ function getState() {
+ var view = element.data('$uiView');
+ var state = view && view.state && view.state.self;
+
+ if (state) {
+ angular.extend(animation, state.animation);
+ }
+
+ return state;
+ }
+
+ function resetParent() {
+ element.parent().removeClass('position-absolute');
+ if(presetHeight !== true) {
+ element.parent()[0].style.height = null;
+ }
+ }
+
+ function prepareParent() {
+ var parentHeight = parseInt(element.parent()[0].style.height);
+ var elHeight = parseInt(window.getComputedStyle(element[0], null).getPropertyValue('height'));
+ var tempHeight = parentHeight > 0 ? parentHeight : elHeight > 0 ? elHeight : '';
+
+ if(parentHeight > 0) {
+ presetHeight = true;
+ }
+
+ element.parent()[0].style.height = tempHeight + 'px';
+ element.parent().addClass('position-absolute');
+ }
+ }
+ }
+
+})(); \ No newline at end of file
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js
new file mode 100644
index 0000000..27e3767
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.dynamicRouting.js
@@ -0,0 +1,156 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.dynamicRouting', ['ui.router'])
+ .provider('$FoundationState', FoundationState)
+ .controller('DefaultController', DefaultController)
+ .config(DynamicRoutingConfig)
+ .run(DynamicRoutingRun)
+ ;
+
+ FoundationState.$inject = ['$stateProvider'];
+
+ function FoundationState($stateProvider) {
+ var complexViews = {};
+
+ this.registerDynamicRoutes = function(routes) {
+ var dynamicRoutes = routes || foundationRoutes;
+
+ angular.forEach(dynamicRoutes, function(page) {
+ if (page.hasComposed) {
+ if (!angular.isDefined(complexViews[page.parent])) {
+ complexViews[page.parent] = { children: {} };
+ }
+
+ if (page.controller) {
+ page.controller = getController(page);
+ }
+
+ complexViews[page.parent].children[page.name] = page;
+
+ } else if (page.composed) {
+ if(!angular.isDefined(complexViews[page.name])) {
+ complexViews[page.name] = { children: {} };
+ }
+
+ if (page.controller) {
+ page.controller = getController(page);
+ }
+
+ angular.extend(complexViews[page.name], page);
+ } else {
+ var state = {
+ url: page.url,
+ templateUrl: page.path,
+ abstract: page.abstract || false,
+ parent: page.parent || '',
+ controller: getController(page),
+ data: getData(page),
+ animation: buildAnimations(page),
+ };
+
+ $stateProvider.state(page.name, state);
+ }
+ });
+
+ angular.forEach(complexViews, function(page) {
+ var state = {
+ url: page.url,
+ parent: page.parent || '',
+ abstract: page.abstract || false,
+ data: getData(page),
+ animation: buildAnimations(page),
+ views: {
+ '': buildState(page.path, page)
+ }
+ };
+
+ angular.forEach(page.children, function(sub) {
+ state.views[sub.name + '@' + page.name] = buildState(sub.path, page);
+ });
+
+ $stateProvider.state(page.name, state);
+ });
+ };
+
+ this.$get = angular.noop;
+
+ function getData(page) {
+ var data = { vars: {} };
+ if (page.data) {
+ if (typeof page.data.vars === "object") {
+ data.vars = page.data.vars;
+ }
+ delete page.data.vars;
+ angular.extend(data, page.data);
+ }
+ delete page.data;
+ angular.extend(data.vars, page);
+ return data;
+ }
+
+ function buildState(path, state) {
+ return {
+ templateUrl: path,
+ controller: getController(state),
+ };
+ }
+
+ function getController(state) {
+ var ctrl = state.controller || 'DefaultController';
+
+ if (!/\w\s+as\s+\w/.test(ctrl)) {
+ ctrl += ' as PageCtrl';
+ }
+
+ return ctrl;
+ }
+
+ function buildAnimations(state) {
+ var animations = {};
+
+ if (state.animationIn) {
+ animations.enter = state.animationIn;
+ }
+
+ if (state.animationOut) {
+ animations.leave = state.animationOut;
+ }
+
+ return animations;
+ }
+ }
+
+ DefaultController.$inject = ['$scope', '$stateParams', '$state'];
+
+ function DefaultController($scope, $stateParams, $state) {
+ var params = {};
+ angular.forEach($stateParams, function(value, key) {
+ params[key] = value;
+ });
+
+ $scope.params = params;
+ $scope.current = $state.current.name;
+
+ if($state.current.views) {
+ $scope.vars = $state.current.data.vars;
+ $scope.composed = $state.current.data.vars.children;
+ } else {
+ $scope.vars = $state.current.data.vars;
+ }
+ }
+
+ DynamicRoutingConfig.$inject = ['$FoundationStateProvider'];
+
+ function DynamicRoutingConfig(FoundationStateProvider) {
+ FoundationStateProvider.registerDynamicRoutes(foundationRoutes);
+ }
+
+ DynamicRoutingRun.$inject = ['$rootScope', '$state', '$stateParams'];
+
+ function DynamicRoutingRun($rootScope, $state, $stateParams) {
+ $rootScope.$state = $state;
+ $rootScope.$stateParams = $stateParams;
+ }
+
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js
new file mode 100644
index 0000000..12715f6
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/services/foundation.mediaquery.js
@@ -0,0 +1,198 @@
+(function() {
+ 'use strict';
+
+ angular.module('foundation.mediaquery', ['foundation.core'])
+ .run(mqInitRun)
+ .factory('FoundationMQInit', FoundationMQInit)
+ .factory('mqHelpers', mqHelpers)
+ .service('FoundationMQ', FoundationMQ)
+ ;
+
+ mqInitRun.$inject = ['FoundationMQInit'];
+
+ function mqInitRun(mqInit) {
+ mqInit.init();
+ }
+
+ FoundationMQInit.$inject = ['mqHelpers', 'FoundationApi', 'Utils'];
+
+ function FoundationMQInit(helpers, foundationApi, u){
+ var factory = {};
+ var namedQueries = {
+ 'default' : 'only screen',
+ landscape : 'only screen and (orientation: landscape)',
+ portrait : 'only screen and (orientation: portrait)',
+ retina : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
+ 'only screen and (min--moz-device-pixel-ratio: 2),' +
+ 'only screen and (-o-min-device-pixel-ratio: 2/1),' +
+ 'only screen and (min-device-pixel-ratio: 2),' +
+ 'only screen and (min-resolution: 192dpi),' +
+ 'only screen and (min-resolution: 2dppx)'
+ };
+
+ factory.init = init;
+
+ return factory;
+
+ function init() {
+ var mediaQueries;
+ var extractedMedia;
+ var mediaObject;
+
+ helpers.headerHelper(['foundation-mq']);
+ extractedMedia = helpers.getStyle('.foundation-mq', 'font-family');
+
+ mediaQueries = helpers.parseStyleToObject((extractedMedia));
+
+ for(var key in mediaQueries) {
+ mediaQueries[key] = 'only screen and (min-width: ' + mediaQueries[key].replace('rem', 'em') + ')';
+ }
+
+
+ foundationApi.modifySettings({
+ mediaQueries: angular.extend(mediaQueries, namedQueries)
+ });
+
+ window.addEventListener('resize', u.throttle(function() {
+ foundationApi.publish('resize', 'window resized');
+ }, 50));
+
+ }
+ }
+
+
+ function mqHelpers() {
+ var factory = {};
+
+ factory.headerHelper = headerHelper;
+ factory.getStyle = getStyle;
+ factory.parseStyleToObject = parseStyleToObject;
+
+ return factory;
+
+ function headerHelper(classArray) {
+ var i = classArray.length;
+ var head = angular.element(document.querySelectorAll('head'));
+
+ while(i--) {
+ head.append('<meta class="' + classArray[i] + '" />');
+ }
+
+ return;
+ }
+
+ function getStyle(selector, styleName) {
+ var elem = document.querySelectorAll(selector)[0];
+ var style = window.getComputedStyle(elem, null);
+
+ return style.getPropertyValue('font-family');
+ }
+
+ // https://github.com/sindresorhus/query-string
+ function parseStyleToObject(str) {
+ var styleObject = {};
+
+ if (typeof str !== 'string') {
+ return styleObject;
+ }
+
+ str = str.trim().slice(1, -1); // browsers re-quote string style values
+
+ if (!str) {
+ return styleObject;
+ }
+
+ styleObject = str.split('&').reduce(function(ret, param) {
+ var parts = param.replace(/\+/g, ' ').split('=');
+ var key = parts[0];
+ var val = parts[1];
+ key = decodeURIComponent(key);
+
+ // missing `=` should be `null`:
+ // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
+ val = val === undefined ? null : decodeURIComponent(val);
+
+ if (!ret.hasOwnProperty(key)) {
+ ret[key] = val;
+ } else if (Array.isArray(ret[key])) {
+ ret[key].push(val);
+ } else {
+ ret[key] = [ret[key], val];
+ }
+ return ret;
+ }, {});
+
+ return styleObject;
+ }
+ }
+
+ FoundationMQ.$inject = ['FoundationApi'];
+
+ function FoundationMQ(foundationApi) {
+ var service = [];
+
+ service.getMediaQueries = getMediaQueries;
+ service.match = match;
+ service.collectScenariosFromElement = collectScenariosFromElement;
+
+ return service;
+
+ function getMediaQueries() {
+ return foundationApi.getSettings().mediaQueries;
+ }
+
+ function match(scenarios) {
+ var count = scenarios.length;
+ var queries = service.getMediaQueries();
+ var matches = [];
+
+ if (count > 0) {
+ while (count--) {
+ var mq;
+ var rule = scenarios[count].media;
+
+ if (queries[rule]) {
+ mq = matchMedia(queries[rule]);
+ } else {
+ mq = matchMedia(rule);
+ }
+
+ if (mq.matches) {
+ matches.push({ ind: count});
+ }
+ }
+ }
+
+ return matches;
+ }
+
+ // Collects a scenario object and templates from element
+ function collectScenariosFromElement(parentElement) {
+ var scenarios = [];
+ var templates = [];
+
+ var elements = parentElement.children();
+ var i = 0;
+
+ angular.forEach(elements, function(el) {
+ var elem = angular.element(el);
+
+
+ //if no source or no html, capture element itself
+ if (!elem.attr('src') || !elem.attr('src').match(/.html$/)) {
+ templates[i] = elem;
+ scenarios[i] = { media: elem.attr('media'), templ: i };
+ } else {
+ scenarios[i] = { media: elem.attr('media'), src: elem.attr('src') };
+ }
+
+ i++;
+ });
+
+ return {
+ scenarios: scenarios,
+ templates: templates
+ };
+ }
+ }
+})();
diff --git a/afb-client/bower_components/foundation-apps/js/angular/vendor/markdown.js b/afb-client/bower_components/foundation-apps/js/angular/vendor/markdown.js
new file mode 100644
index 0000000..d0dd9d6
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/vendor/markdown.js
@@ -0,0 +1,10 @@
+angular.module('markdown', [])
+ .directive('markdown', function() {
+ return {
+ restrict: 'A',
+ link: function(scope, element, attrs, controller) {
+ element.html(marked(element.html()));
+ }
+ };
+
+});
diff --git a/afb-client/bower_components/foundation-apps/js/angular/vendor/svgDirs.js b/afb-client/bower_components/foundation-apps/js/angular/vendor/svgDirs.js
new file mode 100755
index 0000000..c07c883
--- /dev/null
+++ b/afb-client/bower_components/foundation-apps/js/angular/vendor/svgDirs.js
@@ -0,0 +1,101 @@
+'use strict';
+
+(function(){
+ var svgDirectives = {};
+
+ angular.forEach([
+ 'clipPath',
+ 'colorProfile',
+ 'src',
+ 'cursor',
+ 'fill',
+ 'filter',
+ 'marker',
+ 'markerStart',
+ 'markerMid',
+ 'markerEnd',
+ 'mask',
+ 'stroke'
+ ],
+ function(attr) {
+ svgDirectives[attr] = [
+ '$rootScope',
+ '$location',
+ '$interpolate',
+ '$sniffer',
+ 'urlResolve',
+ 'computeSVGAttrValue',
+ 'svgAttrExpressions',
+ function(
+ $rootScope,
+ $location,
+ $interpolate,
+ $sniffer,
+ urlResolve,
+ computeSVGAttrValue,
+ svgAttrExpressions) {
+ return {
+ restrict: 'A',
+ link: function(scope, element, attrs) {
+ var initialUrl;
+
+ //Only apply to svg elements to avoid unnecessary observing
+ //Check that is in html5Mode and that history is supported
+ if ((!svgAttrExpressions.SVG_ELEMENT.test(element[0] &&
+ element[0].toString())) ||
+ !$location.$$html5 ||
+ !$sniffer.history) return;
+
+ //Assumes no expressions, since svg is unforgiving of xml violations
+ initialUrl = attrs[attr];
+ attrs.$observe(attr, updateValue);
+ $rootScope.$on('$locationChangeSuccess', updateValue);
+
+ function updateValue () {
+ var newVal = computeSVGAttrValue(initialUrl);
+ //Prevent recursive updating
+ if (newVal && attrs[attr] !== newVal) attrs.$set(attr, newVal);
+ }
+ }
+ };
+ }];
+ });
+
+ angular.module('ngSVGAttributes', []).
+ factory('urlResolve', [function() {
+ //Duplicate of urlResolve & urlParsingNode in angular core
+ var urlParsingNode = document.createElement('a');
+ return function urlResolve(url) {
+ urlParsingNode.setAttribute('href', url);
+ return urlParsingNode;
+ };
+ }]).
+ value('svgAttrExpressions', {
+ FUNC_URI: /^url\((.*)\)$/,
+ SVG_ELEMENT: /SVG[a-zA-Z]*Element/,
+ HASH_PART: /#.*/
+ }).
+ factory('computeSVGAttrValue', [
+ '$location', '$sniffer', 'svgAttrExpressions', 'urlResolve',
+ function($location, $sniffer, svgAttrExpressions, urlResolve) {
+ return function computeSVGAttrValue(url) {
+ var match, fullUrl;
+ if (match = svgAttrExpressions.FUNC_URI.exec(url)) {
+ //hash in html5Mode, forces to be relative to current url instead of base
+ if (match[1].indexOf('#') === 0) {
+ fullUrl = $location.absUrl().
+ replace(svgAttrExpressions.HASH_PART, '') +
+ match[1];
+ }
+ //Presumably links to external SVG document
+ else {
+ fullUrl = urlResolve(match[1]);
+ }
+ }
+ return fullUrl ? 'url(' + fullUrl + ')' : null;
+ };
+ }
+ ]
+ ).
+ directive(svgDirectives);
+}());