From 95318469766c56ace77b062e3cee64d0adb8b580 Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 09:28:58 +0100 Subject: [PATCH 01/13] #5 updated bower dependencies --- app/index.html | 31 ++++++++++++++++--------------- bower.json | 25 ++++++++++++------------- nbproject/customs.json | 22 ++++++++++++++++++++-- nbproject/project.properties | 3 +++ 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/app/index.html b/app/index.html index 3386f2c..f9dcb08 100644 --- a/app/index.html +++ b/app/index.html @@ -6,8 +6,9 @@ - CLARTIY Scenario Analysis + CLARITY Scenario Analysis + @@ -25,7 +26,7 @@ - + diff --git a/bower.json b/bower.json index d53eb33..5b07785 100644 --- a/bower.json +++ b/bower.json @@ -16,17 +16,17 @@ "package.json" ], "dependencies": { - "seamless.js": "1.3.0", - "angular-strap": "2.1.3", - "angular": "1.2.29", - "angular-resource": "1.2.29", + "seamless.js": "1.4.0", + "angular-strap": "2.1.6", + "angular": "1.2.32", + "angular-resource": "1.2.32", "angular-commons": "0.2.0", "json3": "3.2.6", "es5-shim": "2.1.0", "jquery": "2.1.4", "jquery-ui": "1.10.4", "ng-table": "0.3.3", - "bootstrap": "3.3.7", + "bootstrap": "3.4.1", "icmm_js": "1.1.2", "dynatree": "1.2.8", "crisma-worldstate-tree-widget-angular": "1.0.10", @@ -36,21 +36,20 @@ "jquery-knob": "1.2.13", "ngDialog": "0.2.14", "radar-chart-d3": "1.2.1", - "angular-bootstrap": "0.11.2", - "seamless": "seamless.js#1.3.0", - "html2canvas": "https://github.com/niklasvh/html2canvas/releases/download/v1.0.0-alpha.12/html2canvas.js" + "html2canvas": "https://github.com/niklasvh/html2canvas/releases/download/v1.0.0-alpha.12/html2canvas.js", + "angular-bootstrap": "0.11.2" }, "devDependencies": { - "angular-mocks": "1.2.29", - "angular-scenario": "1.2.29" + "angular-mocks": "1.2.32", + "angular-scenario": "1.2.32" }, "resolutions": { - "bootstrap": "3.3.7", + "bootstrap": "3.4.1", "d3": "3.3.13", "icmm_js": "1.1.2", - "angular": "1.2.29", + "angular": "1.2.32", "jquery": "2.1.4", - "angular-resource": "1.2.29", + "angular-resource": "1.2.32", "dynatree": "1.2.8", "html2canvas": "v1.0.0-alpha.12" } diff --git a/nbproject/customs.json b/nbproject/customs.json index acd03d5..70c151f 100644 --- a/nbproject/customs.json +++ b/nbproject/customs.json @@ -1,10 +1,28 @@ { "elements": { + "criteria-function-manager": {}, + "relation-analysis-chart": {}, + "tab-content": {}, "indicator-band": { "attributes": { "criteria-function": {} } - } + }, + "tab": {}, + "worldstate-ranking-table": {}, + "indicator-criteria-table": {}, + "drupal-context-provider": {}, + "indicator-bar-charts": {}, + "tab-heading": {}, + "tabset": {}, + "decision-strategy-manager": {} }, - "attributes": {} + "attributes": { + "dropdown": { + "context": "div" + }, + "collapse": { + "context": "div" + } + } } \ No newline at end of file diff --git a/nbproject/project.properties b/nbproject/project.properties index dc93023..8b1e61c 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -7,7 +7,10 @@ auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css auxiliary.org-netbeans-modules-javascript-grunt.action_2e_build=build auxiliary.org-netbeans-modules-javascript-grunt.action_2e_clean=clean auxiliary.org-netbeans-modules-javascript-grunt.action_2e_rebuild=--force clean dist +auxiliary.org-netbeans-modules-javascript-nodejs.enabled=false +auxiliary.org-netbeans-modules-javascript-nodejs.node_2e_default=true auxiliary.org-netbeans-modules-javascript-nodejs.run_2e_enabled=false +auxiliary.org-netbeans-modules-javascript-nodejs.sync_2e_enabled=true auxiliary.org-netbeans-modules-javascript2-requirejs.enabled=true auxiliary.org-netbeans-modules-web-clientproject-api.js_2e_libs_2e_folder=js/libs browser.autorefresh.Chrome=false From e20403a722caae8a5a3a40d48d83a3712efe8032 Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Wed, 6 Mar 2019 16:50:33 +0100 Subject: [PATCH 02/13] #2 remove workaround --- app/scripts/connectors/nodeConnector.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/scripts/connectors/nodeConnector.js b/app/scripts/connectors/nodeConnector.js index a660472..dd9f7a8 100644 --- a/app/scripts/connectors/nodeConnector.js +++ b/app/scripts/connectors/nodeConnector.js @@ -18,13 +18,8 @@ window.Drupal.behaviors.myBehavior = { // to get node and group id! var groupId = drupalSettings.csisHelpers.entityinfo.study; - // FIXME: this does not work if the iframe is embedded in a separate node that is then referenced - // from the node containg the actual data! var nodeId = drupalSettings.csisHelpers.entityinfo.step; - // ugly workaround parsing the node id from URL study/$1/step/$2 - nodeId = window.location.pathname.split('/')[4]; - console.log('groupId = ' + groupId + ', nodeId = ' + nodeId); var connectCount = 0; // for some unknown the reason angular directive controler of the embedded child iframe From 469f4c42d25ff9f61530dd80549e498eb61c3fe3 Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 18:36:10 +0100 Subject: [PATCH 03/13] #09 basic emikat api communication --- ...rupalContextProviderDirectiveController.js | 17 ++- app/scripts/services/drupalService.js | 118 ++++++++++++++---- 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/app/scripts/controllers/drupalContextProviderDirectiveController.js b/app/scripts/controllers/drupalContextProviderDirectiveController.js index d263f0f..561eaa3 100644 --- a/app/scripts/controllers/drupalContextProviderDirectiveController.js +++ b/app/scripts/controllers/drupalContextProviderDirectiveController.js @@ -13,7 +13,8 @@ angular.module( var showIndicatorFileLoadingError, showFileLoading, loadIndicatorObjects, loadIndicatorObject, onloadCfFile, onloadDsFile, onSeamlessEvent, onloadIccObjects, loadCriteriaFunctions, loadDecisionStrategies; - var restApi = drupalService.restApi; + var drupalRestApi = drupalService.drupalRestApi; + var emikatRestApi = drupalService.emikatRestApi; console.log('window.seamless.connect()'); var parent = window.seamless.connect(); @@ -21,7 +22,7 @@ angular.module( // inside the onConnect() method, otherwise the event is not recieved (race condition?) // strangley, the onConnect callback is called twice. See comment in nodeConncetor.js parent.receive(function (data) { - //console.log(' parent.receive:' + data); + //console.log('parent.receive:' + data); onSeamlessEvent(data); }); @@ -487,7 +488,9 @@ angular.module( onSeamlessEvent = function (eventData) { console.log('load node from node id: ' + eventData.nodeId); - restApi.getNode(eventData.nodeId).then(function (node) { + // FIXME: This is only for testing purposes! We load load the JSON from the + // IA/RA EU-GL step, but ir should come from the Data Package or EMIKAT REST API! + drupalRestApi.getNode(eventData.nodeId).then(function (node) { var indicatorArray = drupalService.nodeHelper.getIndicatorArray(node); var criteriaFunctionArray = drupalService.nodeHelper.getCriteriaFunction(node); var decisionStrategyArray = drupalService.nodeHelper.getDecisionStrategy(node); @@ -498,6 +501,14 @@ angular.module( console.log(error.data.message); showIndicatorFileLoadingError(error.data.message.toString()); }); + + // FIXME: get scenario and view ids from Data Package + emikatRestApi.getImpactScenario(2846, 2812).then(function (impactScenario){ + //TODO: do something useful here! + console.log(impactScenario); + }, function (error) { + console.log(error.data.message); + }); }; /* diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index aaaca7f..0af4944 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -17,20 +17,21 @@ angular.module( ['$http', '$resource', '$q', function ($http, $resource, $q) { 'use strict'; - var $this, nodePath, nodeFields; + var $this, nodePath, emikatPath, nodeFields; $this = this; nodePath = '/node/:nodeId'; + emikatPath = '/scenarios/:scenarioId/feature/view.:viewId/table/data' nodeFields = []; //nodeFields['indicators'] = 'field_mcda_indicators' nodeFields['indicators'] = 'field_mcda_indicators'; nodeFields['criteriaFunction'] = 'field_mcda_criteria_function'; - nodeFields['decisionStrategy'] = 'field_mcda_decision_strategy'; + nodeFields['decisionStrategy'] = 'field_mcda_decision_strategy'; - // + // $this.drupalRestApi = {}; $this.drupalRestApi.host = ''; $this.drupalRestApi.token = undefined; - // + $this.emikatRestApi.emikatCredentials = undefined; $this.drupalRestApi.initToken = function () { return $http({method: 'GET', url: $this.drupalRestApi.host + '/rest/session/token'}) @@ -56,27 +57,57 @@ angular.module( } }; + $this.drupalRestApi.initEmikatCredentials = function () { + return $http({method: 'GET', url: $this.drupalRestApi.host + '/jsonapi/user/user'}) + .then(function tokenSuccessCallback(response) { + if (response !== null && response.data[0] !== null && response.data[0].attributes.field_basic_auth_credentials !== null) { + $this.emikatRestApi.emikatCredentials = response.data[0].attributes.field_basic_auth_credentials; + console.log('EMIKAT Authentication Info API.'); + return $this.emikatRestApi.emikatCredentials; + } else + { + console.log('error retrieving EMIKAT Credentials: ' + response); + $q.reject(response); + } + }, function initEmikatCredentialsErrorCallback(response) { + $this.emikatRestApi.emikatCredentials = undefined; + console.log('error retrieving EMIKAT Credentials: ' + response); + $q.reject(undefined); + }); + }; + + /** + * return a promise! + */ + $this.drupalRestApi.getEmikatCredentials = function () { + if (!$this.drupalRestApi.emikatCredentials || $this.drupalRestApi.emikatCredentials === null || $this.drupalRestApi.emikatCredentials === undefined) { + return $this.drupalRestApi.initEmikatCredentials(); + } else { + $q.when($this.drupalRestApi.emikatCredentials); + } + }; + $this.drupalRestApi.getNode = function (nodeId) { return $this.drupalRestApi.getToken().then(function tokenSuccessCallback(token) { var nodeResource = $resource($this.drupalRestApi.host + nodePath, - { - nodeId: '@nodeId', - _format: 'hal_json' - - }, { - get: { - method: 'GET', - isArray: false, - headers: { - 'Content-Type': 'application/hal+json', - 'X-CSRF-Token': token + { + nodeId: '@nodeId', + _format: 'hal_json' + + }, { + get: { + method: 'GET', + isArray: false, + headers: { + 'Content-Type': 'application/hal+json', + 'X-CSRF-Token': token + } } - } - }); + }); - var nodeInstance = nodeResource.get({nodeId: nodeId}); - return nodeInstance.$promise; + var nodeInstance = nodeResource.get({nodeId: nodeId}); + return nodeInstance.$promise; }, function tokenErrorCallback(response) { return $q.reject(response); @@ -85,29 +116,62 @@ angular.module( // init the token //$this.drupalRestApi.initToken(); + // + + // + $this.emikatRestApi = {}; + $this.emikatRestApi.host = 'https://service.emikat.at/EmiKatTst/api/'; + + $this.emikatRestApi.getImpactScenario = function (scenarioId, viewId) { + + return $this.drupalRestApi.getEmikatCredentials().then(function credentialsSuccessCallback(credentials) { + var impactScenarioResource = $resource($this.drupalRestApi.host + emikatPath, + { + scenarioId: '@scenarioId', + viewId: '@nodeId' + }, { + get: { + method: 'GET', + isArray: false, + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Basic ' + btoa(credentials) + } + } + }); + + var impactScenario = impactScenarioResource.get({scenarioId:scenarioId, viewId:viewId}); + return impactScenario.$promise; + + }, function credentialsErrorCallback(response) { + return $q.reject(response); + }); + }; + // + // $this.drupalNodeHelper = {}; var getObjectFromDrupalField; $this.drupalNodeHelper.getIndicatorArray = function (node) { return getObjectFromDrupalField(node, nodeFields['indicators']); }; - + $this.drupalNodeHelper.getCriteriaFunction = function (node) { return getObjectFromDrupalField(node, nodeFields['criteriaFunction']); }; - + $this.drupalNodeHelper.getDecisionStrategy = function (node) { return getObjectFromDrupalField(node, nodeFields['decisionStrategy']); - }; - - getObjectFromDrupalField = function(node, field) { + }; + + getObjectFromDrupalField = function (node, field) { if (!node || node === null || node === undefined || !node[field] || node[field] === null || node[field] === undefined) { console.log('node object is null or field "' + field + '" is empty!'); return []; } else { var objects = []; - for(var i = 0; i < node[field].length; i++) { + for (var i = 0; i < node[field].length; i++) { // this is madness: parse into object and later stringify again // so that it can be used by the akward ICMM library (won't touch this thing!) var object = JSON.parse(node[field][i].value); @@ -116,9 +180,11 @@ angular.module( return objects; } }; + // return { - restApi: $this.drupalRestApi, + drupalRestApi: $this.drupalRestApi, + emikatApi: $this.emikatApi, nodeHelper: $this.drupalNodeHelper }; } From c69b146bc053caaeeaddbda457a25d3f7fefd91a Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 18:41:10 +0100 Subject: [PATCH 04/13] #9 bugfix --- .../controllers/drupalContextProviderDirectiveController.js | 4 ++-- app/scripts/services/drupalService.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/scripts/controllers/drupalContextProviderDirectiveController.js b/app/scripts/controllers/drupalContextProviderDirectiveController.js index 561eaa3..d4dec35 100644 --- a/app/scripts/controllers/drupalContextProviderDirectiveController.js +++ b/app/scripts/controllers/drupalContextProviderDirectiveController.js @@ -152,13 +152,13 @@ angular.module( $scope.showCfFileLoadingError = function (message) { $scope.cfFileLoadError = true; - $scope.cfFileLoadErrorMsg = 'Criteria functions not loaded. ' + message; + $scope.cfFileLoadErrorMsg = ' Criteria functions not loaded. ' + message; //$scope.$apply(); }; $scope.showDsFileLoadingError = function (message) { $scope.dsFileLoadError = true; - $scope.dsFileLoadErrorMsg = 'Decision strategies not loaded. ' + message; + $scope.dsFileLoadErrorMsg = ' Decision strategies not loaded. ' + message; //$scope.$apply(); }; diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index 0af4944..02e024b 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -31,7 +31,7 @@ angular.module( $this.drupalRestApi = {}; $this.drupalRestApi.host = ''; $this.drupalRestApi.token = undefined; - $this.emikatRestApi.emikatCredentials = undefined; + $this.drupalRestApi.emikatCredentials = undefined; $this.drupalRestApi.initToken = function () { return $http({method: 'GET', url: $this.drupalRestApi.host + '/rest/session/token'}) From b8a70c174d6edc85d147c39b8aacc8911af2cbd5 Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 18:44:24 +0100 Subject: [PATCH 05/13] #9 another bugfix --- app/scripts/services/drupalService.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index 02e024b..d448827 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -20,7 +20,7 @@ angular.module( var $this, nodePath, emikatPath, nodeFields; $this = this; nodePath = '/node/:nodeId'; - emikatPath = '/scenarios/:scenarioId/feature/view.:viewId/table/data' + emikatPath = '/scenarios/:scenarioId/feature/view.:viewId/table/data'; nodeFields = []; //nodeFields['indicators'] = 'field_mcda_indicators' nodeFields['indicators'] = 'field_mcda_indicators'; @@ -184,7 +184,7 @@ angular.module( return { drupalRestApi: $this.drupalRestApi, - emikatApi: $this.emikatApi, + emikatApi: $this.emikatRestApi, nodeHelper: $this.drupalNodeHelper }; } From b972a3fbb4687da35391e241645b432bfbf1746c Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 18:46:59 +0100 Subject: [PATCH 06/13] #9 yet another bugfix --- .../controllers/drupalContextProviderDirectiveController.js | 2 +- app/scripts/services/drupalService.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/scripts/controllers/drupalContextProviderDirectiveController.js b/app/scripts/controllers/drupalContextProviderDirectiveController.js index d4dec35..5d0c1cd 100644 --- a/app/scripts/controllers/drupalContextProviderDirectiveController.js +++ b/app/scripts/controllers/drupalContextProviderDirectiveController.js @@ -477,7 +477,7 @@ angular.module( } $scope.decisionStrategies = decisionStrategyArray; - console.log(decisionStrategyArray.length + 'decision strategies loaded'); + console.log(decisionStrategyArray.length + ' decision strategies loaded'); } else { msg = 'decision strategy object is not an array or empty'; console.log(msg + ': ' + decisionStrategyArray.toString()); diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index d448827..87dffc7 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -184,7 +184,7 @@ angular.module( return { drupalRestApi: $this.drupalRestApi, - emikatApi: $this.emikatRestApi, + emikatRestApi: $this.emikatRestApi, nodeHelper: $this.drupalNodeHelper }; } From 93e650c6aa616d7a1f21e8c678a152bbfc30ff13 Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 19:02:43 +0100 Subject: [PATCH 07/13] #9 more bugfixes --- .../drupalContextProviderDirectiveController.js | 2 +- app/scripts/services/drupalService.js | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/scripts/controllers/drupalContextProviderDirectiveController.js b/app/scripts/controllers/drupalContextProviderDirectiveController.js index 5d0c1cd..cd79279 100644 --- a/app/scripts/controllers/drupalContextProviderDirectiveController.js +++ b/app/scripts/controllers/drupalContextProviderDirectiveController.js @@ -507,7 +507,7 @@ angular.module( //TODO: do something useful here! console.log(impactScenario); }, function (error) { - console.log(error.data.message); + console.log(error.message); }); }; diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index 87dffc7..1c09021 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -59,9 +59,10 @@ angular.module( $this.drupalRestApi.initEmikatCredentials = function () { return $http({method: 'GET', url: $this.drupalRestApi.host + '/jsonapi/user/user'}) - .then(function tokenSuccessCallback(response) { - if (response !== null && response.data[0] !== null && response.data[0].attributes.field_basic_auth_credentials !== null) { - $this.emikatRestApi.emikatCredentials = response.data[0].attributes.field_basic_auth_credentials; + .then(function initEmikatCredentialsSuccessCallback(response) { + // data.data?! fXXXk yeah! :o + if (response !== null && response.data[0] !== null && response.data.data[0].attributes.field_basic_auth_credentials !== null) { + $this.emikatRestApi.emikatCredentials = response.data.data[0].attributes.field_basic_auth_credentials; console.log('EMIKAT Authentication Info API.'); return $this.emikatRestApi.emikatCredentials; } else From 81a6828c7c6cd455fad904547d519f97abda4724 Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 19:04:41 +0100 Subject: [PATCH 08/13] #9 bugfix again! --- app/scripts/services/drupalService.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index 1c09021..9bc7557 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -60,8 +60,8 @@ angular.module( $this.drupalRestApi.initEmikatCredentials = function () { return $http({method: 'GET', url: $this.drupalRestApi.host + '/jsonapi/user/user'}) .then(function initEmikatCredentialsSuccessCallback(response) { - // data.data?! fXXXk yeah! :o - if (response !== null && response.data[0] !== null && response.data.data[0].attributes.field_basic_auth_credentials !== null) { + // data.data?! fXXk yeah! :o + if (response !== null && response.data !== null && response.data.data[0] !== null && response.data.data[0].attributes.field_basic_auth_credentials !== null) { $this.emikatRestApi.emikatCredentials = response.data.data[0].attributes.field_basic_auth_credentials; console.log('EMIKAT Authentication Info API.'); return $this.emikatRestApi.emikatCredentials; @@ -126,7 +126,7 @@ angular.module( $this.emikatRestApi.getImpactScenario = function (scenarioId, viewId) { return $this.drupalRestApi.getEmikatCredentials().then(function credentialsSuccessCallback(credentials) { - var impactScenarioResource = $resource($this.drupalRestApi.host + emikatPath, + var impactScenarioResource = $resource($this.emikatRestApi.host + emikatPath, { scenarioId: '@scenarioId', viewId: '@nodeId' From fe2542b6cb0fa1c7a452c730d07e9cee96b1d23f Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Mon, 4 Mar 2019 19:06:45 +0100 Subject: [PATCH 09/13] #9 bugfix :o --- app/scripts/services/drupalService.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/services/drupalService.js b/app/scripts/services/drupalService.js index 9bc7557..c867d10 100644 --- a/app/scripts/services/drupalService.js +++ b/app/scripts/services/drupalService.js @@ -121,7 +121,7 @@ angular.module( // $this.emikatRestApi = {}; - $this.emikatRestApi.host = 'https://service.emikat.at/EmiKatTst/api/'; + $this.emikatRestApi.host = 'https://service.emikat.at/EmiKatTst/api'; $this.emikatRestApi.getImpactScenario = function (scenarioId, viewId) { From bac4484a4ddf4f8f77db93b0b3664426cbe9dfde Mon Sep 17 00:00:00 2001 From: p-a-s-c-a-l Date: Tue, 5 Mar 2019 09:06:25 +0100 Subject: [PATCH 10/13] #9 support test data --- .gitignore | 3 +- app/index.html | 5 ++- ...rupalContextProviderDirectiveController.js | 38 ++++++++--------- app/scripts/services/drupalService.js | 41 +++++++++++++++---- 4 files changed, 57 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 884b522..c88e3ee 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ app/bower_components target .checkDependencies test-results.xml -private/ \ No newline at end of file +private/ +/app/scripts/.local.js \ No newline at end of file diff --git a/app/index.html b/app/index.html index f9dcb08..e0577a8 100644 --- a/app/index.html +++ b/app/index.html @@ -24,6 +24,9 @@ + + + @@ -515,7 +518,7 @@

- +