├── data └── img │ └── 1.png ├── public ├── app │ ├── views │ │ ├── partials │ │ │ ├── footer.html │ │ │ ├── top-navbar.html │ │ │ └── sidebar.html │ │ ├── app.html │ │ ├── vulnerability.html │ │ ├── project.html │ │ ├── owasp-uigrid.html │ │ ├── owasp-view.html │ │ ├── project-view.html │ │ ├── owasp-add.html │ │ ├── project-add.html │ │ ├── owasp-edit.html │ │ ├── project-edit.html │ │ ├── dashboard.html │ │ ├── setting.html │ │ ├── vulnerability-view.html │ │ ├── vulnerability-add.html │ │ └── vulnerability-edit.html │ ├── img │ │ ├── logo.png │ │ ├── favicon.png │ │ ├── logo-single.png │ │ └── preloader │ │ │ ├── preloader.full.png │ │ │ └── preloader.empty.png │ ├── json │ │ ├── en.json │ │ └── sidebar-menu.json │ └── js │ │ ├── controllers │ │ ├── dashboard.js │ │ ├── setting.js │ │ ├── owasp-uigrid.js │ │ ├── project.js │ │ └── vulnerability.js │ │ └── appRouter.js ├── vendor │ ├── angular-ui-grid │ │ ├── index.js │ │ ├── fontello.eot │ │ ├── fontello.ttf │ │ ├── fontello.woff │ │ ├── ui-grid.eot │ │ ├── ui-grid.ttf │ │ ├── ui-grid.woff │ │ ├── bower.json │ │ ├── package.json │ │ ├── README.md │ │ ├── fontello.svg │ │ └── ui-grid.svg │ ├── fontawesome │ │ └── fonts │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.ttf │ │ │ ├── fontawesome-webfont.woff │ │ │ └── fontawesome-webfont.woff2 │ ├── simple-line-icons │ │ └── fonts │ │ │ ├── Simple-Line-Icons.eot │ │ │ ├── Simple-Line-Icons.ttf │ │ │ ├── Simple-Line-Icons.woff │ │ │ └── Simple-Line-Icons.woff2 │ ├── weather-icons │ │ └── font │ │ │ ├── weathericons-regular-webfont.eot │ │ │ ├── weathericons-regular-webfont.ttf │ │ │ └── weathericons-regular-webfont.woff │ ├── notify │ │ ├── notificationService.js │ │ ├── notificationDrtv.js │ │ └── notificationJqueryPlugin.js │ ├── downloader │ │ ├── angular-file-saver.min.js │ │ ├── angular-file-saver.js │ │ └── angular-file-saver.bundle.min.js │ ├── flot-spline │ │ └── js │ │ │ └── jquery.flot.spline.min.js │ ├── Flot │ │ ├── jquery.flot.resize.js │ │ ├── jquery.flot.categories.js │ │ └── jquery.flot.time.js │ ├── screenfull │ │ └── dist │ │ │ └── screenfull.js │ ├── jquery.easy-pie-chart │ │ └── dist │ │ │ └── angular.easypiechart.min.js │ ├── slimScroll │ │ └── jquery.slimscroll.min.js │ ├── uploader │ │ └── ng-file-upload-shim.min.js │ ├── flot.tooltip │ │ └── js │ │ │ └── jquery.flot.tooltip.min.js │ ├── animo.js │ │ └── animo.js │ ├── modernizr │ │ └── modernizr.custom.js │ └── angularjs-toaster │ │ └── toaster.css ├── output │ └── index.html ├── proofs │ └── index.html ├── settings │ └── index.html └── index.html ├── package.json ├── README.md └── reporting.sql /data/img/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/data/img/1.png -------------------------------------------------------------------------------- /public/app/views/partials/footer.html: -------------------------------------------------------------------------------- 1 | © {{app.year}} - {{ app.name }} -------------------------------------------------------------------------------- /public/app/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/app/img/logo.png -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/index.js: -------------------------------------------------------------------------------- 1 | require('./ui-grid'); 2 | module.exports = 'ui.grid'; 3 | -------------------------------------------------------------------------------- /public/app/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/app/img/favicon.png -------------------------------------------------------------------------------- /public/output/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

TEST PAGE

4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/proofs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

TEST PAGE

4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/settings/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

TEST PAGE

4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/app/img/logo-single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/app/img/logo-single.png -------------------------------------------------------------------------------- /public/app/img/preloader/preloader.full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/app/img/preloader/preloader.full.png -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/fontello.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/angular-ui-grid/fontello.eot -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/fontello.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/angular-ui-grid/fontello.ttf -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/fontello.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/angular-ui-grid/fontello.woff -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/ui-grid.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/angular-ui-grid/ui-grid.eot -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/ui-grid.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/angular-ui-grid/ui-grid.ttf -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/ui-grid.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/angular-ui-grid/ui-grid.woff -------------------------------------------------------------------------------- /public/app/img/preloader/preloader.empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/app/img/preloader/preloader.empty.png -------------------------------------------------------------------------------- /public/vendor/fontawesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/fontawesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /public/vendor/fontawesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/fontawesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/vendor/fontawesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/fontawesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/vendor/fontawesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/fontawesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/vendor/fontawesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/fontawesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /public/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /public/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /public/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /public/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2 -------------------------------------------------------------------------------- /public/vendor/weather-icons/font/weathericons-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/weather-icons/font/weathericons-regular-webfont.eot -------------------------------------------------------------------------------- /public/vendor/weather-icons/font/weathericons-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/weather-icons/font/weathericons-regular-webfont.ttf -------------------------------------------------------------------------------- /public/vendor/weather-icons/font/weathericons-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vegabird/prithvi/HEAD/public/vendor/weather-icons/font/weathericons-regular-webfont.woff -------------------------------------------------------------------------------- /public/app/json/en.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "sidebar": { 4 | 5 | "nav": { 6 | "DASHBOARD": "Dashboard", 7 | "WIDGETS": "Widgets", 8 | "DOCUMENTATION": "Documentation", 9 | 10 | "table": { 11 | "TABLE": "Table", 12 | "STANDARD": "Standard", 13 | "EXTENDED": "Extended", 14 | "DATATABLE": "Datatable" 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vulnerabilityrepoter", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "impraveensingh", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.16.2", 13 | "multer": "^1.3.0", 14 | "mysql": "^2.15.0", 15 | "officegen": "^0.4.5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/app/js/controllers/dashboard.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | var app = angular.module('app.dashboard'); 4 | app.controller('dashController', ['$scope', '$http', function ($scope, $http) { 5 | $scope.owasp = 0; 6 | $scope.vuln = 0; 7 | $scope.project = 0; 8 | $http.get('/count').then(function (response) { 9 | console.log(response); 10 | $scope.owasp = response.data.data.owasp; 11 | $scope.vuln = response.data.data.vuln; 12 | $scope.project = response.data.data.project; 13 | }); 14 | }]); 15 | })(); -------------------------------------------------------------------------------- /public/app/views/app.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 |
7 | 8 |
9 |
10 | 11 | -------------------------------------------------------------------------------- /public/app/json/sidebar-menu.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "text": "Dashboard", 4 | "sref": "app.dashboard", 5 | "icon": "icon-speedometer" 6 | }, 7 | { 8 | "text": "OWASP", 9 | "sref": "app.owasp", 10 | "icon": "icon-arrow-right-circle" 11 | }, 12 | { 13 | "text": "Projects", 14 | "sref": "app.project", 15 | "icon": "icon-arrow-right-circle" 16 | }, 17 | { 18 | "text": "Setting", 19 | "sref": "app.setting", 20 | "icon": "icon-settings" 21 | } 22 | 23 | ] -------------------------------------------------------------------------------- /public/vendor/notify/notificationService.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 'use strict'; 3 | var app = angular.module('angle'); 4 | app.service('Notify', ['$timeout', function($timeout) { 5 | // .service('Notify', Notify); 6 | 7 | // Notify.$inject = ['$timeout']; 8 | // function Notify($timeout) { 9 | 10 | this.alert = notifyAlert; 11 | 12 | //////////////// 13 | 14 | function notifyAlert(msg, opts) { 15 | if (msg) { 16 | $timeout(function() { 17 | $.notify(msg, opts || {}); 18 | }); 19 | } 20 | } 21 | }]); 22 | })(); -------------------------------------------------------------------------------- /public/app/views/vulnerability.html: -------------------------------------------------------------------------------- 1 |

Vulnerability

2 |
3 |
4 | 5 | 6 |
7 |
8 |
9 |
10 |
-------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-ui-grid", 3 | "description": "A data grid for Angular", 4 | "main": [ 5 | "./ui-grid.css", 6 | "./ui-grid.js" 7 | ], 8 | "ignore": [], 9 | "dependencies": { 10 | "angular": ">=1.4.0 1.5.x" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/angular-ui/ui-grid.git" 15 | }, 16 | "homepage": "http://ui-grid.info", 17 | "bugs": { 18 | "url": "https://github.com/angular-ui/ui-grid/issues" 19 | }, 20 | "keywords": [ 21 | "angular", 22 | "ng-grid", 23 | "nggrid", 24 | "grid", 25 | "angularjs", 26 | "slickgrid", 27 | "kogrid", 28 | "ui-grid", 29 | "ui grid", 30 | "data grid" 31 | ], 32 | "license": "MIT" 33 | } -------------------------------------------------------------------------------- /public/app/views/project.html: -------------------------------------------------------------------------------- 1 |

PROJECT

2 |
3 |
4 |
5 | 6 | 9 | 10 |
11 |
12 |
13 |
14 |
-------------------------------------------------------------------------------- /public/app/views/owasp-uigrid.html: -------------------------------------------------------------------------------- 1 |

OWASP

2 |
3 |
4 |
5 | 6 | 9 | 10 |
11 |
12 |
13 |
14 |
-------------------------------------------------------------------------------- /public/vendor/notify/notificationDrtv.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | 5 | var app = angular.module('angle'); 6 | 7 | 8 | app.directive('notify', ['$window', 'Notify', function($window, Notify) { 9 | // .directive('notify', notify); 10 | 11 | // notify.$inject = ['$window', 'Notify']; 12 | // function notify ($window, Notify) { 13 | 14 | var directive = { 15 | link: link, 16 | restrict: 'A', 17 | scope: { 18 | options: '=', 19 | message: '=' 20 | } 21 | }; 22 | return directive; 23 | 24 | function link(scope, element) { 25 | 26 | element.on('click', function(e) { 27 | e.preventDefault(); 28 | Notify.alert(scope.message, scope.options); 29 | }); 30 | } 31 | 32 | }]); 33 | })(); -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-ui-grid", 3 | "description": "A data grid for Angular", 4 | "main": "index.js", 5 | "ignore": [], 6 | "dependencies": { 7 | "angular": ">=1.4.0 1.5.x" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/angular-ui/ui-grid.git" 12 | }, 13 | "homepage": "http://ui-grid.info", 14 | "bugs": { 15 | "url": "https://github.com/angular-ui/ui-grid/issues" 16 | }, 17 | "keywords": [ 18 | "angular", 19 | "ng-grid", 20 | "nggrid", 21 | "grid", 22 | "angularjs", 23 | "slickgrid", 24 | "kogrid", 25 | "ui-grid", 26 | "ui grid", 27 | "data grid" 28 | ], 29 | "license": "MIT", 30 | "version": "4.0.4", 31 | "files": [ 32 | "less", 33 | "ui-grid.css", 34 | "ui-grid.eot", 35 | "ui-grid.js", 36 | "ui-grid.min.css", 37 | "ui-grid.min.js", 38 | "ui-grid.svg", 39 | "ui-grid.ttf", 40 | "ui-grid.woff" 41 | ] 42 | } -------------------------------------------------------------------------------- /public/app/views/owasp-view.html: -------------------------------------------------------------------------------- 1 |
2 | 5 | 31 | 34 |
-------------------------------------------------------------------------------- /public/app/js/controllers/setting.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | var app = angular.module('app.setting'); 4 | app.controller('settingController', ['$scope', '$http', 'Upload', '$timeout', 'Notify', function ($scope, $http, Upload, $timeout, Notify) { 5 | 6 | $scope.uploadPic = function(file) { 7 | file.upload = Upload.upload({ 8 | url: '/setCon', 9 | data: {companyName: $scope.companyName, companyLogo: file}, 10 | }); 11 | 12 | file.upload.then(function (response) { 13 | $timeout(function () { 14 | file.result = response.data; 15 | 16 | Notify.alert('Configuration Successful', { status: 'success' }); 17 | 18 | }); 19 | }, function (response) { 20 | if (response.status > 0) 21 | $scope.errorMsg = response.status + ': ' + response.data; 22 | }, function (evt) { 23 | // Math.min is to fix IE which reports 200% sometimes 24 | file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total)); 25 | }); 26 | } 27 | 28 | $http.get('/getCon').then(function (response) { 29 | $scope.companyName1 = response.data.data[0].company_name; 30 | $scope.imgpath = response.data.data[0].company_logo; 31 | console.log($scope.imgpath); 32 | }); 33 | 34 | }]); 35 | })(); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prithvi 2 | A Report Generation Tool for Security Assessment 3 | 4 |

Usage

5 |

This project of ours could be used for report generation and its very easy to use.

6 |

It includes following features

7 |
    8 |
  1. We can add Owasp Types and recommendation with details.
  2. 9 |
  3. We can add Multiple Projects and work on it separately.
  4. 10 |
  5. We can add multiple vulnerabilities on different projects with proof of concept.
  6. 11 |
  7. On generating report it provides document file (.docx).
  8. 12 |
  9. Currently we are trying to add more facilities like Chart and will be updated soon.
  10. 13 |
14 | 15 |

Setup

16 |
    17 |
  1. Create Database `reporting` in server (We used XAMPP).
  2. 18 |
  3. Import reporting.sql in your local server.
  4. 19 |
  5. Download complete source and extract node_modules.
  6. 20 |
  7. Run index.js and enjoy.
  8. 21 |
  9. Follow our blog for details
  10. 22 |
23 | 24 |

Technology Used

25 |
    26 |
  1. Angularjs for frontend
  2. 27 |
  3. MySQL as Database
  4. 28 |
  5. NodeJS (ExpressJS) as our back end
  6. 29 |
30 | 31 |

You can view tutorial about how to use our software https://youtu.be/eh7UnuQOYiU .

32 |

You can also view same in our blog and comment your view at https://www.vegabird.com/prithvi .

33 | -------------------------------------------------------------------------------- /public/app/views/partials/top-navbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/app/views/project-view.html: -------------------------------------------------------------------------------- 1 |
2 | 4 | 34 | 37 |
-------------------------------------------------------------------------------- /public/vendor/downloader/angular-file-saver.min.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.ngFileSaver=n():e.ngFileSaver=n()}(this,function(){return function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var t={};return n.m=e,n.c=t,n.p="",n(0)}([function(e,n,t){"use strict";e.exports="ngFileSaver",angular.module("ngFileSaver",[]).factory("FileSaver",["Blob","SaveAs","FileSaverUtils",t(1)]).factory("FileSaverUtils",[t(2)]).factory("Blob",["$window","FileSaverUtils",t(3)]).factory("SaveAs",["$window","FileSaverUtils",t(4)])},function(e,n){"use strict";e.exports=function(e,n,t){function r(e,r,o){try{n(e,r,o)}catch(i){t.handleErrors(i.message)}}return{saveAs:function(e,n,o){return t.isBlobInstance(e)||t.handleErrors("Data argument should be a blob instance"),t.isString(n)||t.handleErrors("Filename argument should be a string"),r(e,n,o)}}}},function(e,n){"use strict";e.exports=function(){return{handleErrors:function(e){throw new Error(e)},isString:function(e){return"string"==typeof e||e instanceof String},isUndefined:function(e){return"undefined"==typeof e},isBlobInstance:function(e){return e instanceof Blob}}}},function(e,n){"use strict";e.exports=function(e,n){var t=e.Blob;return n.isUndefined(t)&&n.handleErrors("Blob is not supported. Please include blob polyfilll"),t}},function(e,n){"use strict";e.exports=function(e,n){var t=e.saveAs;return n.isUndefined(t)&&n.handleErrors("saveAs is not supported. Please include saveAs polyfill"),t}}])}); -------------------------------------------------------------------------------- /public/app/views/owasp-add.html: -------------------------------------------------------------------------------- 1 |
2 | 5 | 33 | 37 |
-------------------------------------------------------------------------------- /public/app/views/project-add.html: -------------------------------------------------------------------------------- 1 |
2 | 4 | 31 | 35 |
-------------------------------------------------------------------------------- /public/app/views/owasp-edit.html: -------------------------------------------------------------------------------- 1 |
2 | 5 | 33 | 38 |
-------------------------------------------------------------------------------- /public/vendor/flot-spline/js/jquery.flot.spline.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"use strict";function b(a,b,c,d,e,f,g){var j,k,l,m,n,o,p,q,h=Math.pow,i=Math.sqrt;return j=i(h(c-a,2)+h(d-b,2)),k=i(h(e-c,2)+h(f-d,2)),l=g*j/(j+k),m=g-l,n=c+l*(a-e),o=d+l*(b-f),p=c-m*(a-e),q=d-m*(b-f),[n,o,p,q]}function d(b,c,d,e,f){var g=a.color.parse(f);g.a="number"==typeof e?e:.3,g.normalize(),g=g.toString(),c.beginPath(),c.moveTo(b[0][0],b[0][1]);for(var h=b.length,i=0;h>i;i++)c[b[i][3]].apply(c,b[i][2]);c.stroke(),c.lineWidth=0,c.lineTo(b[h-1][0],d),c.lineTo(b[0][0],d),c.closePath(),e!==!1&&(c.fillStyle=g,c.fill())}function e(a,b,d,e){(void 0===b||"bezier"!==b&&"quadratic"!==b)&&(b="quadratic"),b+="CurveTo",0==c.length?c.push([d[0],d[1],e.concat(d.slice(2)),b]):"quadraticCurveTo"==b&&2==d.length?(e=e.slice(0,2).concat(d),c.push([d[0],d[1],e,b])):c.push([d[2],d[3],e.concat(d.slice(2)),b])}function f(f,g,h){if(h.splines.show===!0){var k,l,m,i=[],j=h.splines.tension||.5,n=h.datapoints.points,o=h.datapoints.pointsize,p=f.getPlotOffset(),q=n.length,r=[];if(c=[],4>q/o)return a.extend(h.lines,h.splines),void 0;for(k=0;q>k;k+=o)l=n[k],m=n[k+1],null==l||lh.xaxis.max||mh.yaxis.max||r.push(h.xaxis.p2c(l)+p.left,h.yaxis.p2c(m)+p.top);for(q=r.length,k=0;q-2>k;k+=2)i=i.concat(b.apply(this,r.slice(k,k+6).concat([j])));for(g.save(),g.strokeStyle=h.color,g.lineWidth=h.splines.lineWidth,e(g,"quadratic",r.slice(0,4),i.slice(0,2)),k=2;q-3>k;k+=2)e(g,"bezier",r.slice(k,k+4),i.slice(2*k-2,2*k+2));e(g,"quadratic",r.slice(q-2,q),[i[2*q-10],i[2*q-9],r[q-4],r[q-3]]),d(c,g,f.height()+10,h.splines.fill,h.color),g.restore()}}var c=[];a.plot.plugins.push({init:function(a){a.hooks.drawSeries.push(f)},options:{series:{splines:{show:!1,lineWidth:2,tension:.5,fill:!1}}},name:"spline",version:"0.8.2"})}(jQuery); -------------------------------------------------------------------------------- /public/app/views/project-edit.html: -------------------------------------------------------------------------------- 1 |
2 | 4 | 31 | 36 |
-------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Prithvi - A Vulnerabilty Report Generation Tool 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/README.md: -------------------------------------------------------------------------------- 1 | This repo is for distribution on `npm` and `bower`. The source for this module is in the [main UI Grid repo](https://github.com/angular-ui/ui-grid). Please file issues and pull requests against that repo. 2 | 3 | ## Install 4 | 5 | You can install this package either with `npm` or with `bower`. 6 | 7 | ### npm 8 | 9 | ```shell 10 | npm install angular-ui-grid 11 | ``` 12 | 13 | Then add a ` 18 | ``` 19 | 20 | ### bower 21 | 22 | ```shell 23 | bower install angular-ui-grid 24 | ``` 25 | 26 | Then add a ` 31 | ``` 32 | 33 | ## Documentation 34 | 35 | Documentation is available on the [main UI Grid site](http://ui-grid.info). 36 | 37 | ## License 38 | 39 | The MIT License 40 | 41 | Copyright (c) 2013-2015 the Angular-UI team, http://angular-ui.github.com 42 | 43 | Permission is hereby granted, free of charge, to any person obtaining a copy 44 | of this software and associated documentation files (the "Software"), to deal 45 | in the Software without restriction, including without limitation the rights 46 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 47 | copies of the Software, and to permit persons to whom the Software is 48 | furnished to do so, subject to the following conditions: 49 | 50 | The above copyright notice and this permission notice shall be included in 51 | all copies or substantial portions of the Software. 52 | 53 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 54 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 56 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 58 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 59 | THE SOFTWARE. 60 | -------------------------------------------------------------------------------- /public/app/views/partials/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 |
7 | 35 |
36 | -------------------------------------------------------------------------------- /public/app/views/dashboard.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | 8 |
9 |
10 |
{{project}}
11 |
Projects
12 |
13 |
14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
{{vuln}}
25 |
Vulnerabilities
26 |
27 |
28 |
29 |
30 |
31 | 32 |
33 |
34 |
35 | 36 |
37 |
38 |
{{owasp}}
39 |
Owasp
40 |
41 |
42 |
43 |
44 |
45 | 46 |
47 |
48 |
49 | 50 | 51 |
52 | 53 |
54 |
55 | 56 |
57 | 58 | 59 |
60 |
61 |
62 | 63 |
64 |
65 | -------------------------------------------------------------------------------- /public/app/js/appRouter.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | angular.module('app.routes').config(routesConfig); 4 | routesConfig.$inject = ['$stateProvider', '$locationProvider', '$urlRouterProvider', 'RouteHelpersProvider']; 5 | 6 | function routesConfig($stateProvider, $locationProvider, $urlRouterProvider, helper) { 7 | 8 | $locationProvider.html5Mode(false); 9 | 10 | $urlRouterProvider.otherwise('/app/dashboard'); 11 | 12 | 13 | $stateProvider.state('app', { 14 | url: '/app' 15 | , abstract: true 16 | , templateUrl: helper.basepath('app.html') 17 | , resolve: helper.resolveFor('fastclick', 'modernizr', 'icons', 'screenfull', 'animo', 'sparklines', 'slimscroll', 'easypiechart', 'toaster', 'whirl') 18 | }).state('app.dashboard', { 19 | url: '/dashboard' 20 | , title: 'Dashboard' 21 | , templateUrl: helper.basepath('dashboard.html') 22 | , resolve: { 23 | deps: ['$ocLazyLoad', '$$animateJs' 24 | , function ($ocLazyLoad) { 25 | return $ocLazyLoad.load('ui.grid').then(function () { 26 | return $ocLazyLoad.load('app/js/controllers/dashboard.js'); 27 | }) 28 | } 29 | ] 30 | } 31 | 32 | }).state('app.owasp', { 33 | url: '/owasp' 34 | , templateUrl: helper.basepath('owasp-uigrid.html') 35 | , resolve: { 36 | deps: ['$ocLazyLoad', '$$animateJs' 37 | , function ($ocLazyLoad) { 38 | return $ocLazyLoad.load('ui.grid').then(function () { 39 | return $ocLazyLoad.load('app/js/controllers/owasp-uigrid.js'); 40 | }) 41 | } 42 | ] 43 | } 44 | }) 45 | 46 | .state('app.vulnerability', { 47 | url: '/vulnerability/:id/:appType' 48 | , templateUrl: helper.basepath('vulnerability.html') 49 | , resolve: { 50 | deps: ['$ocLazyLoad', '$$animateJs' 51 | , function ($ocLazyLoad) { 52 | return $ocLazyLoad.load(['ui.grid', 'ng-file-upload']).then(function () { 53 | return $ocLazyLoad.load('app/js/controllers/vulnerability.js'); 54 | }) 55 | } 56 | ] 57 | } 58 | }) 59 | 60 | .state('app.project', { 61 | url: '/project' 62 | , templateUrl: helper.basepath('project.html') 63 | , resolve: { 64 | deps: ['$ocLazyLoad', '$$animateJs' 65 | , function ($ocLazyLoad) { 66 | return $ocLazyLoad.load('ui.grid').then(function () { 67 | return $ocLazyLoad.load('app/js/controllers/project.js'); 68 | }) 69 | } 70 | ] 71 | } 72 | }) 73 | 74 | .state('app.setting', { 75 | url: '/setting' 76 | , templateUrl: helper.basepath('setting.html') 77 | , resolve: { 78 | deps: ['$ocLazyLoad', '$$animateJs' 79 | , function ($ocLazyLoad) { 80 | return $ocLazyLoad.load('ng-file-upload').then(function () { 81 | return $ocLazyLoad.load('app/js/controllers/setting.js'); 82 | }) 83 | } 84 | ] 85 | } 86 | }) 87 | 88 | } // routesConfig 89 | })(); -------------------------------------------------------------------------------- /public/vendor/Flot/jquery.flot.resize.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for automatically redrawing plots as the placeholder resizes. 2 | 3 | Copyright (c) 2007-2014 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | It works by listening for changes on the placeholder div (through the jQuery 7 | resize event plugin) - if the size changes, it will redraw the plot. 8 | 9 | There are no options. If you need to disable the plugin for some plots, you 10 | can just fix the size of their placeholders. 11 | 12 | */ 13 | 14 | /* Inline dependency: 15 | * jQuery resize event - v1.1 - 3/14/2010 16 | * http://benalman.com/projects/jquery-resize-plugin/ 17 | * 18 | * Copyright (c) 2010 "Cowboy" Ben Alman 19 | * Dual licensed under the MIT and GPL licenses. 20 | * http://benalman.com/about/license/ 21 | */ 22 | (function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this); 23 | 24 | (function ($) { 25 | var options = { }; // no options 26 | 27 | function init(plot) { 28 | function onResize() { 29 | var placeholder = plot.getPlaceholder(); 30 | 31 | // somebody might have hidden us and we can't plot 32 | // when we don't have the dimensions 33 | if (placeholder.width() == 0 || placeholder.height() == 0) 34 | return; 35 | 36 | plot.resize(); 37 | plot.setupGrid(); 38 | plot.draw(); 39 | } 40 | 41 | function bindEvents(plot, eventHolder) { 42 | plot.getPlaceholder().resize(onResize); 43 | } 44 | 45 | function shutdown(plot, eventHolder) { 46 | plot.getPlaceholder().unbind("resize", onResize); 47 | } 48 | 49 | plot.hooks.bindEvents.push(bindEvents); 50 | plot.hooks.shutdown.push(shutdown); 51 | } 52 | 53 | $.plot.plugins.push({ 54 | init: init, 55 | options: options, 56 | name: 'resize', 57 | version: '1.0' 58 | }); 59 | })(jQuery); 60 | -------------------------------------------------------------------------------- /public/app/views/setting.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Settings
4 |
5 |
6 |
7 |
8 |
9 | 10 |
11 | 12 | *required 13 |
14 |
15 |
16 | 17 |
18 | 21 | *required
22 | File too large 23 | {{errorFile.size / 1000000|number:1}}MB: max 2M 24 |
25 |
26 |
27 |
28 | 30 |
31 |
32 |
33 |
34 | 35 |
37 |
38 | Upload Successful 39 | {{errorMsg}} 40 |
41 |
42 |
43 |
44 | 45 |
46 |
47 |
48 |
49 |
50 |
51 |
Settings
52 |
53 |
54 |
55 |
56 |
57 | 58 |
59 |

{{companyName1}}

60 |
61 |
62 |
63 |
64 |
65 | 66 |
67 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
-------------------------------------------------------------------------------- /public/vendor/screenfull/dist/screenfull.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * screenfull 3 | * v3.0.2 - 2017-03-13 4 | * (c) Sindre Sorhus; MIT License 5 | */ 6 | (function () { 7 | 'use strict'; 8 | 9 | var isCommonjs = typeof module !== 'undefined' && module.exports; 10 | var keyboardAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element; 11 | 12 | var fn = (function () { 13 | var val; 14 | 15 | var fnMap = [ 16 | [ 17 | 'requestFullscreen', 18 | 'exitFullscreen', 19 | 'fullscreenElement', 20 | 'fullscreenEnabled', 21 | 'fullscreenchange', 22 | 'fullscreenerror' 23 | ], 24 | // new WebKit 25 | [ 26 | 'webkitRequestFullscreen', 27 | 'webkitExitFullscreen', 28 | 'webkitFullscreenElement', 29 | 'webkitFullscreenEnabled', 30 | 'webkitfullscreenchange', 31 | 'webkitfullscreenerror' 32 | 33 | ], 34 | // old WebKit (Safari 5.1) 35 | [ 36 | 'webkitRequestFullScreen', 37 | 'webkitCancelFullScreen', 38 | 'webkitCurrentFullScreenElement', 39 | 'webkitCancelFullScreen', 40 | 'webkitfullscreenchange', 41 | 'webkitfullscreenerror' 42 | 43 | ], 44 | [ 45 | 'mozRequestFullScreen', 46 | 'mozCancelFullScreen', 47 | 'mozFullScreenElement', 48 | 'mozFullScreenEnabled', 49 | 'mozfullscreenchange', 50 | 'mozfullscreenerror' 51 | ], 52 | [ 53 | 'msRequestFullscreen', 54 | 'msExitFullscreen', 55 | 'msFullscreenElement', 56 | 'msFullscreenEnabled', 57 | 'MSFullscreenChange', 58 | 'MSFullscreenError' 59 | ] 60 | ]; 61 | 62 | var i = 0; 63 | var l = fnMap.length; 64 | var ret = {}; 65 | 66 | for (; i < l; i++) { 67 | val = fnMap[i]; 68 | if (val && val[1] in document) { 69 | for (i = 0; i < val.length; i++) { 70 | ret[fnMap[0][i]] = val[i]; 71 | } 72 | return ret; 73 | } 74 | } 75 | 76 | return false; 77 | })(); 78 | 79 | var screenfull = { 80 | request: function (elem) { 81 | var request = fn.requestFullscreen; 82 | 83 | elem = elem || document.documentElement; 84 | 85 | // Work around Safari 5.1 bug: reports support for 86 | // keyboard in fullscreen even though it doesn't. 87 | // Browser sniffing, since the alternative with 88 | // setTimeout is even worse. 89 | if (/5\.1[.\d]* Safari/.test(navigator.userAgent)) { 90 | elem[request](); 91 | } else { 92 | elem[request](keyboardAllowed && Element.ALLOW_KEYBOARD_INPUT); 93 | } 94 | }, 95 | exit: function () { 96 | document[fn.exitFullscreen](); 97 | }, 98 | toggle: function (elem) { 99 | if (this.isFullscreen) { 100 | this.exit(); 101 | } else { 102 | this.request(elem); 103 | } 104 | }, 105 | onchange: function (callback) { 106 | document.addEventListener(fn.fullscreenchange, callback, false); 107 | }, 108 | onerror: function (callback) { 109 | document.addEventListener(fn.fullscreenerror, callback, false); 110 | }, 111 | raw: fn 112 | }; 113 | 114 | if (!fn) { 115 | if (isCommonjs) { 116 | module.exports = false; 117 | } else { 118 | window.screenfull = false; 119 | } 120 | 121 | return; 122 | } 123 | 124 | Object.defineProperties(screenfull, { 125 | isFullscreen: { 126 | get: function () { 127 | return Boolean(document[fn.fullscreenElement]); 128 | } 129 | }, 130 | element: { 131 | enumerable: true, 132 | get: function () { 133 | return document[fn.fullscreenElement]; 134 | } 135 | }, 136 | enabled: { 137 | enumerable: true, 138 | get: function () { 139 | // Coerce to boolean in case of old WebKit 140 | return Boolean(document[fn.fullscreenEnabled]); 141 | } 142 | } 143 | }); 144 | 145 | if (isCommonjs) { 146 | module.exports = screenfull; 147 | } else { 148 | window.screenfull = screenfull; 149 | } 150 | })(); 151 | -------------------------------------------------------------------------------- /public/app/views/vulnerability-view.html: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | 106 | 109 |
110 |
-------------------------------------------------------------------------------- /public/vendor/jquery.easy-pie-chart/dist/angular.easypiechart.min.js: -------------------------------------------------------------------------------- 1 | /**! 2 | * easyPieChart 3 | * Lightweight plugin to render simple, animated and retina optimized pie charts 4 | * 5 | * @license 6 | * @author Robert Fleischmann (http://robert-fleischmann.de) 7 | * @version 2.1.6 8 | **/ 9 | !function(a,b){"object"==typeof exports?module.exports=b(require("angular")):"function"==typeof define&&define.amd?define(["angular"],b):b(a.angular)}(this,function(a){!function(a){"use strict";return a.module("easypiechart",[]).directive("easypiechart",[function(){return{restrict:"A",require:"?ngModel",scope:{percent:"=",options:"="},link:function(b,d){b.percent=b.percent||0;var e={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,size:110,rotate:0,animate:{duration:1e3,enabled:!0}};b.options=a.extend(e,b.options);var f=new c(d[0],e);b.$watch("percent",function(a){f.update(a)})}}}])}(a);var b=function(a,b){var c,d=document.createElement("canvas");a.appendChild(d),"undefined"!=typeof G_vmlCanvasManager&&G_vmlCanvasManager.initElement(d);var e=d.getContext("2d");d.width=d.height=b.size;var f=1;window.devicePixelRatio>1&&(f=window.devicePixelRatio,d.style.width=d.style.height=[b.size,"px"].join(""),d.width=d.height=b.size*f,e.scale(f,f)),e.translate(b.size/2,b.size/2),e.rotate((-0.5+b.rotate/180)*Math.PI);var g=(b.size-b.lineWidth)/2;b.scaleColor&&b.scaleLength&&(g-=b.scaleLength+2),Date.now=Date.now||function(){return+new Date};var h=function(a,b,c){c=Math.min(Math.max(-1,c||0),1);var d=0>=c?!0:!1;e.beginPath(),e.arc(0,0,g,0,2*Math.PI*c,d),e.strokeStyle=a,e.lineWidth=b,e.stroke()},i=function(){var a,c;e.lineWidth=1,e.fillStyle=b.scaleColor,e.save();for(var d=24;d>0;--d)d%6===0?(c=b.scaleLength,a=0):(c=.6*b.scaleLength,a=b.scaleLength-c),e.fillRect(-b.size/2+a,0,c,1),e.rotate(Math.PI/12);e.restore()},j=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1e3/60)}}(),k=function(){b.scaleColor&&i(),b.trackColor&&h(b.trackColor,b.trackWidth||b.lineWidth,1)};this.getCanvas=function(){return d},this.getCtx=function(){return e},this.clear=function(){e.clearRect(b.size/-2,b.size/-2,b.size,b.size)},this.draw=function(a){b.scaleColor||b.trackColor?e.getImageData&&e.putImageData?c?e.putImageData(c,0,0):(k(),c=e.getImageData(0,0,b.size*f,b.size*f)):(this.clear(),k()):this.clear(),e.lineCap=b.lineCap;var d;d="function"==typeof b.barColor?b.barColor(a):b.barColor,h(d,b.lineWidth,a/100)}.bind(this),this.animate=function(a,c){var d=Date.now();b.onStart(a,c);var e=function(){var f=Math.min(Date.now()-d,b.animate.duration),g=b.easing(this,f,a,c-a,b.animate.duration);this.draw(g),b.onStep(a,c,g),f>=b.animate.duration?b.onStop(a,c):j(e)}.bind(this);j(e)}.bind(this)},c=function(a,c){var d={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,trackWidth:void 0,size:110,rotate:0,animate:{duration:1e3,enabled:!0},easing:function(a,b,c,d,e){return b/=e/2,1>b?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},onStart:function(){},onStep:function(){},onStop:function(){}};if("undefined"!=typeof b)d.renderer=b;else{if("undefined"==typeof SVGRenderer)throw new Error("Please load either the SVG- or the CanvasRenderer");d.renderer=SVGRenderer}var e={},f=0,g=function(){this.el=a,this.options=e;for(var b in d)d.hasOwnProperty(b)&&(e[b]=c&&"undefined"!=typeof c[b]?c[b]:d[b],"function"==typeof e[b]&&(e[b]=e[b].bind(this)));e.easing="string"==typeof e.easing&&"undefined"!=typeof jQuery&&jQuery.isFunction(jQuery.easing[e.easing])?jQuery.easing[e.easing]:d.easing,"number"==typeof e.animate&&(e.animate={duration:e.animate,enabled:!0}),"boolean"!=typeof e.animate||e.animate||(e.animate={duration:1e3,enabled:e.animate}),this.renderer=new e.renderer(a,e),this.renderer.draw(f),a.dataset&&a.dataset.percent?this.update(parseFloat(a.dataset.percent)):a.getAttribute&&a.getAttribute("data-percent")&&this.update(parseFloat(a.getAttribute("data-percent")))}.bind(this);this.update=function(a){return a=parseFloat(a),e.animate.enabled?this.renderer.animate(f,a):this.renderer.draw(a),f=a,this}.bind(this),this.disableAnimation=function(){return e.animate.enabled=!1,this},this.enableAnimation=function(){return e.animate.enabled=!0,this},g()}}); -------------------------------------------------------------------------------- /reporting.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.5.1 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Host: 127.0.0.1 6 | -- Generation Time: Feb 14, 2018 at 10:21 AM 7 | -- Server version: 10.1.16-MariaDB 8 | -- PHP Version: 5.6.24 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8mb4 */; 18 | 19 | -- 20 | -- Database: `reporting` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- Table structure for table `owasp` 27 | -- 28 | 29 | CREATE TABLE `owasp` ( 30 | `ID` int(11) NOT NULL, 31 | `apptype` text NOT NULL, 32 | `vname` text NOT NULL, 33 | `vowasp` text NOT NULL, 34 | `vdetail` text NOT NULL, 35 | `vrecommend` text NOT NULL 36 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 37 | 38 | -- -------------------------------------------------------- 39 | 40 | -- 41 | -- Table structure for table `projects` 42 | -- 43 | 44 | CREATE TABLE `projects` ( 45 | `pid` int(11) NOT NULL, 46 | `pname` text NOT NULL, 47 | `company_name` text NOT NULL, 48 | `apptype` text NOT NULL, 49 | `startdate` text NOT NULL, 50 | `enddate` text NOT NULL, 51 | `analystname` text NOT NULL 52 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 53 | 54 | -- -------------------------------------------------------- 55 | 56 | -- 57 | -- Table structure for table `proofs` 58 | -- 59 | 60 | CREATE TABLE `proofs` ( 61 | `proofid` int(11) NOT NULL, 62 | `vid` int(11) NOT NULL, 63 | `path` text NOT NULL 64 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 65 | 66 | -- -------------------------------------------------------- 67 | 68 | -- 69 | -- Table structure for table `settings` 70 | -- 71 | 72 | CREATE TABLE `settings` ( 73 | `company_name` text NOT NULL, 74 | `company_logo` text NOT NULL 75 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 76 | 77 | -- -------------------------------------------------------- 78 | 79 | -- 80 | -- Table structure for table `vulnerabilities` 81 | -- 82 | 83 | CREATE TABLE `vulnerabilities` ( 84 | `vid` int(11) NOT NULL, 85 | `pid` int(11) NOT NULL, 86 | `vname` text NOT NULL, 87 | `vowasp` text NOT NULL, 88 | `vdetail` text NOT NULL, 89 | `vrecommend` text NOT NULL, 90 | `risk` text NOT NULL, 91 | `severity` text NOT NULL, 92 | `cvscore` text NOT NULL, 93 | `cvtext` text NOT NULL, 94 | `probability` text NOT NULL, 95 | `remeffort` text NOT NULL, 96 | `vector` text NOT NULL, 97 | `occurrences` text NOT NULL, 98 | `affcomp` text NOT NULL, 99 | `retest` text NOT NULL, 100 | `other` text NOT NULL 101 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 102 | 103 | -- 104 | -- Indexes for dumped tables 105 | -- 106 | 107 | -- 108 | -- Indexes for table `owasp` 109 | -- 110 | ALTER TABLE `owasp` 111 | ADD PRIMARY KEY (`ID`); 112 | 113 | -- 114 | -- Indexes for table `projects` 115 | -- 116 | ALTER TABLE `projects` 117 | ADD PRIMARY KEY (`pid`); 118 | 119 | -- 120 | -- Indexes for table `proofs` 121 | -- 122 | ALTER TABLE `proofs` 123 | ADD PRIMARY KEY (`proofid`); 124 | 125 | -- 126 | -- Indexes for table `vulnerabilities` 127 | -- 128 | ALTER TABLE `vulnerabilities` 129 | ADD PRIMARY KEY (`vid`); 130 | 131 | -- 132 | -- AUTO_INCREMENT for dumped tables 133 | -- 134 | 135 | -- 136 | -- AUTO_INCREMENT for table `owasp` 137 | -- 138 | ALTER TABLE `owasp` 139 | MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT; 140 | -- 141 | -- AUTO_INCREMENT for table `projects` 142 | -- 143 | ALTER TABLE `projects` 144 | MODIFY `pid` int(11) NOT NULL AUTO_INCREMENT; 145 | -- 146 | -- AUTO_INCREMENT for table `proofs` 147 | -- 148 | ALTER TABLE `proofs` 149 | MODIFY `proofid` int(11) NOT NULL AUTO_INCREMENT; 150 | -- 151 | -- AUTO_INCREMENT for table `vulnerabilities` 152 | -- 153 | ALTER TABLE `vulnerabilities` 154 | MODIFY `vid` int(11) NOT NULL AUTO_INCREMENT; 155 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 156 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 157 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 158 | -------------------------------------------------------------------------------- /public/vendor/slimScroll/jquery.slimscroll.min.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) 2 | * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 3 | * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 4 | * 5 | * Version: 1.3.8 6 | * 7 | */ 8 | (function(e){e.fn.extend({slimScroll:function(f){var a=e.extend({width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},f);this.each(function(){function v(d){if(r){d=d||window.event; 9 | var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);e(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&n(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function n(d,g,e){k=!1;var f=b.outerHeight()-c.outerHeight();g&&(g=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),g=Math.min(Math.max(g,0),f),g=0=b.outerHeight()?k=!0:(c.stop(!0, 11 | !0).fadeIn("fast"),a.railVisible&&m.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(B=setTimeout(function(){a.disableFadeOut&&r||y||z||(c.fadeOut("slow"),m.fadeOut("slow"))},1E3))}var r,y,z,B,A,u,l,C,k=!1,b=e(this);if(b.parent().hasClass(a.wrapperClass)){var q=b.scrollTop(),c=b.siblings("."+a.barClass),m=b.siblings("."+a.railClass);x();if(e.isPlainObject(f)){if("height"in f&&"auto"==f.height){b.parent().css("height","auto");b.css("height","auto");var h=b.parent().parent().height();b.parent().css("height", 12 | h);b.css("height",h)}else"height"in f&&(h=f.height,b.parent().css("height",h),b.css("height",h));if("scrollTo"in f)q=parseInt(a.scrollTo);else if("scrollBy"in f)q+=parseInt(a.scrollBy);else if("destroy"in f){c.remove();m.remove();b.unwrap();return}n(q,!1,!0)}}else if(!(e.isPlainObject(f)&&"destroy"in f)){a.height="auto"==a.height?b.parent().height():a.height;q=e("
").addClass(a.wrapperClass).css({position:"relative",overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden", 13 | width:a.width,height:a.height});var m=e("
").addClass(a.railClass).css({width:a.size,height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=e("
").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible?"block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius, 14 | WebkitBorderRadius:a.borderRadius,zIndex:99}),h="right"==a.position?{right:a.distance}:{left:a.distance};m.css(h);c.css(h);b.wrap(q);b.parent().append(c);b.parent().append(m);a.railDraggable&&c.bind("mousedown",function(a){var b=e(document);z=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);n(0,c.position().top,!1)});b.bind("mouseup.slimscroll",function(a){z=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll", 15 | function(a){a.stopPropagation();a.preventDefault();return!1});m.hover(function(){w()},function(){p()});c.hover(function(){y=!0},function(){y=!1});b.hover(function(){r=!0;w();p()},function(){r=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(A=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&&(n((A-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),A=b.originalEvent.touches[0].pageY)}); 16 | x();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}),n(0,!0)):"top"!==a.start&&(n(e(a.start).position().top,null,!0),a.alwaysVisible||c.hide());window.addEventListener?(this.addEventListener("DOMMouseScroll",v,!1),this.addEventListener("mousewheel",v,!1)):document.attachEvent("onmousewheel",v)}});return this}});e.fn.extend({slimscroll:e.fn.slimScroll})})(jQuery); -------------------------------------------------------------------------------- /public/vendor/downloader/angular-file-saver.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["ngFileSaver"] = factory(); 8 | else 9 | root["ngFileSaver"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) 20 | /******/ return installedModules[moduleId].exports; 21 | 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ exports: {}, 25 | /******/ id: moduleId, 26 | /******/ loaded: false 27 | /******/ }; 28 | 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | 32 | /******/ // Flag the module as loaded 33 | /******/ module.loaded = true; 34 | 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | 39 | 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | 46 | /******/ // __webpack_public_path__ 47 | /******/ __webpack_require__.p = ""; 48 | 49 | /******/ // Load entry module and return exports 50 | /******/ return __webpack_require__(0); 51 | /******/ }) 52 | /************************************************************************/ 53 | /******/ ([ 54 | /* 0 */ 55 | /***/ function(module, exports, __webpack_require__) { 56 | 57 | 'use strict'; 58 | 59 | /* 60 | * 61 | * A AngularJS module that implements the HTML5 W3C saveAs() in browsers that 62 | * do not natively support it 63 | * 64 | * (c) 2015 Philipp Alferov 65 | * License: MIT 66 | * 67 | */ 68 | 69 | module.exports = 'ngFileSaver'; 70 | 71 | angular.module('ngFileSaver', []) 72 | .factory('FileSaver', ['Blob', 'SaveAs', 'FileSaverUtils', __webpack_require__(1)]) 73 | .factory('FileSaverUtils', [__webpack_require__(2)]) 74 | .factory('Blob', ['$window', 'FileSaverUtils', __webpack_require__(3)]) 75 | .factory('SaveAs', ['$window', 'FileSaverUtils', __webpack_require__(4)]); 76 | 77 | 78 | /***/ }, 79 | /* 1 */ 80 | /***/ function(module, exports) { 81 | 82 | 'use strict'; 83 | 84 | module.exports = function FileSaver(Blob, SaveAs, FileSaverUtils) { 85 | 86 | function save(blob, filename, disableAutoBOM) { 87 | try { 88 | SaveAs(blob, filename, disableAutoBOM); 89 | } catch(err) { 90 | FileSaverUtils.handleErrors(err.message); 91 | } 92 | } 93 | 94 | return { 95 | 96 | /** 97 | * saveAs 98 | * Immediately starts saving a file, returns undefined. 99 | * 100 | * @name saveAs 101 | * @function 102 | * @param {Blob} data A Blob instance 103 | * @param {Object} filename Custom filename (extension is optional) 104 | * @param {Boolean} disableAutoBOM Disable automatically provided Unicode 105 | * text encoding hints 106 | * 107 | * @return {Undefined} 108 | */ 109 | 110 | saveAs: function(data, filename, disableAutoBOM) { 111 | 112 | if (!FileSaverUtils.isBlobInstance(data)) { 113 | FileSaverUtils.handleErrors('Data argument should be a blob instance'); 114 | } 115 | 116 | if (!FileSaverUtils.isString(filename)) { 117 | FileSaverUtils.handleErrors('Filename argument should be a string'); 118 | } 119 | 120 | return save(data, filename, disableAutoBOM); 121 | } 122 | }; 123 | }; 124 | 125 | 126 | /***/ }, 127 | /* 2 */ 128 | /***/ function(module, exports) { 129 | 130 | 'use strict'; 131 | 132 | module.exports = function FileSaverUtils() { 133 | return { 134 | handleErrors: function(msg) { 135 | throw new Error(msg); 136 | }, 137 | isString: function(obj) { 138 | return typeof obj === 'string' || obj instanceof String; 139 | }, 140 | isUndefined: function(obj) { 141 | return typeof obj === 'undefined'; 142 | }, 143 | isBlobInstance: function(obj) { 144 | return obj instanceof Blob; 145 | } 146 | }; 147 | }; 148 | 149 | 150 | /***/ }, 151 | /* 3 */ 152 | /***/ function(module, exports) { 153 | 154 | 'use strict'; 155 | 156 | module.exports = function Blob($window, FileSaverUtils) { 157 | var blob = $window.Blob; 158 | 159 | if (FileSaverUtils.isUndefined(blob)) { 160 | FileSaverUtils.handleErrors('Blob is not supported. Please include blob polyfilll'); 161 | } 162 | 163 | return blob; 164 | }; 165 | 166 | 167 | /***/ }, 168 | /* 4 */ 169 | /***/ function(module, exports) { 170 | 171 | 'use strict'; 172 | 173 | module.exports = function SaveAs($window, FileSaverUtils) { 174 | var saveAs = $window.saveAs; 175 | 176 | if (FileSaverUtils.isUndefined(saveAs)) { 177 | FileSaverUtils.handleErrors('saveAs is not supported. Please include saveAs polyfill'); 178 | } 179 | 180 | return saveAs; 181 | }; 182 | 183 | 184 | /***/ } 185 | /******/ ]) 186 | }); 187 | ; -------------------------------------------------------------------------------- /public/app/views/vulnerability-add.html: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | 131 | 135 |
136 |
-------------------------------------------------------------------------------- /public/vendor/notify/notificationJqueryPlugin.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | var containers = {}, 4 | messages = {}, 5 | notify = function(options) { 6 | if ($.type(options) === 'string') { 7 | options = { message: options }; 8 | } 9 | if (arguments[1]) { 10 | options = $.extend(options, $.type(arguments[1]) === 'string' ? { status: arguments[1] } : arguments[1]); 11 | } 12 | return (new Message(options)).show(); 13 | }, 14 | closeAll = function(group, instantly) { 15 | var id; 16 | if (group) { 17 | for (id in messages) { if (group === messages[id].group) messages[id].close(instantly); } 18 | } else { 19 | for (id in messages) { messages[id].close(instantly); } 20 | } 21 | }; 22 | var Message = function(options) { 23 | // var $this = this; 24 | this.options = $.extend({}, Message.defaults, options); 25 | this.uuid = 'ID' + (new Date().getTime()) + 'RAND' + (Math.ceil(Math.random() * 100000)); 26 | this.element = $([ 27 | // @geedmo: alert-dismissable enables bs close icon 28 | '
', 29 | '×', 30 | '
' + this.options.message + '
', 31 | '
' 32 | ].join('')).data('notifyMessage', this); 33 | // status 34 | if (this.options.status) { 35 | this.element.addClass('alert alert-' + this.options.status); 36 | this.currentstatus = this.options.status; 37 | } 38 | this.group = this.options.group; 39 | messages[this.uuid] = this; 40 | if (!containers[this.options.pos]) { 41 | containers[this.options.pos] = $('
').appendTo('body').on('click', '.uk-notify-message', function() { 42 | $(this).data('notifyMessage').close(); 43 | }); 44 | } 45 | }; 46 | $.extend(Message.prototype, { 47 | uuid: false, 48 | element: false, 49 | timout: false, 50 | currentstatus: '', 51 | group: false, 52 | show: function() { 53 | if (this.element.is(':visible')) return; 54 | var $this = this; 55 | containers[this.options.pos].show().prepend(this.element); 56 | var marginbottom = parseInt(this.element.css('margin-bottom'), 10); 57 | this.element.css({ 'opacity': 0, 'margin-top': -1 * this.element.outerHeight(), 'margin-bottom': 0 }).animate({ 'opacity': 1, 'margin-top': 0, 'margin-bottom': marginbottom }, function() { 58 | if ($this.options.timeout) { 59 | var closefn = function() { $this.close(); }; 60 | $this.timeout = setTimeout(closefn, $this.options.timeout); 61 | $this.element.hover( 62 | function() { clearTimeout($this.timeout); }, 63 | function() { $this.timeout = setTimeout(closefn, $this.options.timeout); } 64 | ); 65 | } 66 | }); 67 | return this; 68 | }, 69 | close: function(instantly) { 70 | var $this = this, 71 | finalize = function() { 72 | $this.element.remove(); 73 | if (!containers[$this.options.pos].children().length) { 74 | containers[$this.options.pos].hide(); 75 | } 76 | delete messages[$this.uuid]; 77 | }; 78 | if (this.timeout) clearTimeout(this.timeout); 79 | if (instantly) { 80 | finalize(); 81 | } else { 82 | this.element.animate({ 'opacity': 0, 'margin-top': -1 * this.element.outerHeight(), 'margin-bottom': 0 }, function() { 83 | finalize(); 84 | }); 85 | } 86 | }, 87 | content: function(html) { 88 | var container = this.element.find('>div'); 89 | if (!html) { 90 | return container.html(); 91 | } 92 | container.html(html); 93 | return this; 94 | }, 95 | status: function(status) { 96 | if (!status) { 97 | return this.currentstatus; 98 | } 99 | this.element.removeClass('alert alert-' + this.currentstatus).addClass('alert alert-' + status); 100 | this.currentstatus = status; 101 | return this; 102 | } 103 | }); 104 | Message.defaults = { 105 | message: '', 106 | status: 'normal', 107 | timeout: 5000, 108 | group: null, 109 | pos: 'top-center' 110 | }; 111 | 112 | $.notify = notify; 113 | $.notify.message = Message; 114 | $.notify.closeAll = closeAll; 115 | 116 | return notify; 117 | }(jQuery)); -------------------------------------------------------------------------------- /public/app/views/vulnerability-edit.html: -------------------------------------------------------------------------------- 1 |
2 | 5 |
6 | 140 | 145 |
146 |
-------------------------------------------------------------------------------- /public/app/js/controllers/owasp-uigrid.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | var app = angular.module('app.owasp'); 4 | app.service('RowEditor', ['$http', '$rootScope', '$uibModal', function ($http, $rootScope, $uibModal) { 5 | var service = {}; 6 | service.editRow = editRow; 7 | service.addRow = addRow; 8 | service.viewRow = viewRow; 9 | 10 | function editRow(grid, row) { 11 | $uibModal.open({ 12 | templateUrl: 'app/views/owasp-edit.html' 13 | , controller: 'RowEditCtrl' 14 | , controllerAs: 'vm' 15 | , resolve: { 16 | grid: function () { 17 | return grid; 18 | } 19 | , row: function () { 20 | return row; 21 | } 22 | } 23 | }); 24 | } 25 | 26 | function viewRow(grid, row) { 27 | $uibModal.open({ 28 | templateUrl: 'app/views/owasp-view.html' 29 | , controller: 'RowEditCtrl' 30 | , controllerAs: 'vm' 31 | , resolve: { 32 | grid: function () { 33 | return grid; 34 | } 35 | , row: function () { 36 | return row; 37 | } 38 | } 39 | }); 40 | } 41 | 42 | function addRow(grid, row) { 43 | $uibModal.open({ 44 | templateUrl: 'app/views/owasp-add.html' 45 | , controller: 'RowEditCtrl' 46 | , controllerAs: 'vm' 47 | , resolve: { 48 | grid: function () { 49 | return grid; 50 | } 51 | , row: function () { 52 | return row; 53 | } 54 | } 55 | }); 56 | } 57 | return service; 58 | }]); 59 | app.controller('OwaspController', ['$scope', '$http', '$uibModal', 'RowEditor', 'uiGridConstants', '$route', function ($scope, $http, $uibModal, RowEditor, uiGridConstants, $route) { 60 | var vm = this; 61 | vm.applicationType = ["Web", "Mobile"]; 62 | vm.view = function () { 63 | var temp = { 64 | 'appType': vm.appType 65 | } 66 | $http.post('/viewOwasp', temp).then(function (response) { 67 | var temparray = [] 68 | temparray = response.data.data; 69 | vm.serviceGrid.data = temparray; 70 | vm.serviceGrid.seltype = temp.appType 71 | }); 72 | }; 73 | vm.editRow = RowEditor.editRow; 74 | vm.addRow = RowEditor.addRow; 75 | vm.viewRow = RowEditor.viewRow; 76 | vm.serviceGrid = { 77 | enableColumnMenus: false, 78 | enableRowSelection: false 79 | , enableRowHeaderSelection: false 80 | , rowTemplate: "
" 81 | }; 82 | vm.serviceGrid.seltype = 'None'; 83 | vm.serviceGrid.columnDefs = [{ 84 | name: 'Vulnerability Name' 85 | , field: 'vulName' 86 | , enableSorting: false 87 | , enableCellEdit: false 88 | }, { 89 | name: 'Application Name' 90 | , field: 'appType' 91 | , enableSorting: false 92 | , enableCellEdit: false 93 | }, { 94 | name: 'Owasp Name' 95 | , field: 'owaspName' 96 | , enableSorting: false 97 | , enableCellEdit: false 98 | }, 99 | { 100 | field: "View", 101 | width: 100, 102 | displayName: "View", 103 | cellTemplate: '
' 104 | }, 105 | { 106 | field: "Edit", 107 | width: 100, 108 | displayName: "Edit", 109 | cellTemplate: '
' 110 | }]; 111 | vm.addOwasp = function () { 112 | var rowTmp = {}; 113 | var newService = { 114 | "vulName": "" 115 | , "appType": "" 116 | , "owaspName": "" 117 | , "vulDetail": "" 118 | , "vulRecommend": "" 119 | }; 120 | rowTmp.entity = newService; 121 | vm.addRow(vm.serviceGrid, rowTmp); 122 | }; 123 | }]); 124 | app.controller('RowEditCtrl', ['$http', '$uibModalInstance', 'grid', 'row', '$window', '$state','Notify', function ($http, $uibModalInstance, grid, row, $window, $state, Notify) { 125 | var seltype = grid.seltype; 126 | var vm = this; 127 | vm.entity = angular.copy(row.entity); 128 | vm.save = save; 129 | vm.update = update; 130 | vm.remove = remove; 131 | vm.entity.applicationType = ["Web", "Mobile"]; 132 | 133 | function save() { 134 | $http.post('/addOwasp', vm.entity).then(function (response) { 135 | if(response.data.status == 'True'){ 136 | Notify.alert('Owasp Data Added Successful', { status: 'success' }); 137 | } 138 | 139 | 140 | if(seltype == vm.entity.appType){ 141 | vm.entity.id = response.data.id; 142 | grid.data.push(vm.entity); 143 | } 144 | $uibModalInstance.close(row.entity); 145 | }); 146 | $uibModalInstance.close(row.entity); 147 | } 148 | 149 | function update() { 150 | $http.post('/editOwasp', vm.entity).then(function (response) { 151 | if(response.data.status == 'True'){ 152 | Notify.alert('Owasp Data Updated Successful', { status: 'success' }); 153 | } 154 | row.entity.appType = vm.entity.appType; 155 | row.entity.owaspName = vm.entity.owaspName; 156 | row.entity.vulDetail = vm.entity.vulDetail; 157 | row.entity.vulName = vm.entity.vulName; 158 | row.entity.vulRecommend = vm.entity.vulRecommend; 159 | $uibModalInstance.close(row.entity); 160 | }); 161 | } 162 | 163 | function remove() { 164 | $http.post('/deleteOwasp', vm.entity).then(function (response) { 165 | if(response.data.status == 'True'){ 166 | Notify.alert('Owasp Data Deleted Successful', { status: 'success' }); 167 | } 168 | row.entity = angular.extend(row.entity, vm.entity); 169 | var index = grid.appScope.vm.serviceGrid.data.indexOf(row.entity); 170 | grid.appScope.vm.serviceGrid.data.splice(index, 1); 171 | $uibModalInstance.close(row.entity); 172 | }); 173 | } 174 | }]); 175 | })(); -------------------------------------------------------------------------------- /public/app/js/controllers/project.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | var app = angular.module('app.project'); 4 | app.service('RowEditorpro', ['$http', '$rootScope', '$uibModal', function ($http, $rootScope, $uibModal) { 5 | var service = {}; 6 | service.editRow = editRow; 7 | service.addRow = addRow; 8 | service.viewRow = viewRow; 9 | 10 | function editRow(grid, row) { 11 | $uibModal.open({ 12 | templateUrl: 'app/views/project-edit.html' 13 | , controller: 'RowEditCtrl' 14 | , controllerAs: 'vm' 15 | , resolve: { 16 | grid: function () { 17 | return grid; 18 | } 19 | , row: function () { 20 | return row; 21 | } 22 | } 23 | }); 24 | } 25 | 26 | function viewRow(grid, row) { 27 | $uibModal.open({ 28 | templateUrl: 'app/views/project-view.html' 29 | , controller: 'RowEditCtrl' 30 | , controllerAs: 'vm' 31 | , resolve: { 32 | grid: function () { 33 | return grid; 34 | } 35 | , row: function () { 36 | return row; 37 | } 38 | } 39 | }); 40 | } 41 | 42 | function addRow(grid, row) { 43 | $uibModal.open({ 44 | templateUrl: 'app/views/project-add.html' 45 | , controller: 'RowEditCtrl' 46 | , controllerAs: 'vm' 47 | , resolve: { 48 | grid: function () { 49 | return grid; 50 | } 51 | , row: function () { 52 | return row; 53 | } 54 | } 55 | }); 56 | } 57 | return service; 58 | }]); 59 | app.controller('projectController', ['$scope', '$http', '$uibModal', 'RowEditorpro', 'uiGridConstants', '$route', function ($scope, $http, $uibModal, RowEditorpro, uiGridConstants, $route) { 60 | var vm = this; 61 | vm.applicationType = ["Web", "Mobile"]; 62 | vm.view = function () { 63 | var temp = { 64 | 'appType': vm.appType 65 | } 66 | $http.post('/viewProject', temp).then(function (response) { 67 | var temparray = [] 68 | temparray = response.data.data; 69 | vm.serviceGrid.data = temparray; 70 | vm.serviceGrid.seltype = temp.appType 71 | }); 72 | }; 73 | vm.editRow = RowEditorpro.editRow; 74 | vm.addRow = RowEditorpro.addRow; 75 | vm.viewRow = RowEditorpro.viewRow; 76 | vm.serviceGrid = { 77 | enableColumnMenus: false 78 | , enableRowSelection: false 79 | , enableRowHeaderSelection: false 80 | , rowTemplate: "
" 81 | }; 82 | vm.serviceGrid.seltype = 'None'; 83 | vm.serviceGrid.columnDefs = [{ 84 | name: 'Project Name' 85 | , field: 'projectName' 86 | , enableSorting: true 87 | , enableCellEdit: false 88 | }, { 89 | name: 'Company Name' 90 | , field: 'companyName' 91 | , enableSorting: true 92 | , enableCellEdit: false 93 | }, { 94 | name: 'Application Type' 95 | , field: 'appType' 96 | , enableSorting: true 97 | , enableCellEdit: false 98 | }, { 99 | field: "Add_Vulnerability" 100 | , width: 170 101 | , displayName: "Add Vulnerability" 102 | , cellTemplate: '
' 103 | } 104 | , { 105 | field: "View" 106 | , width: 100 107 | , displayName: "View" 108 | , cellTemplate: '
' 109 | } 110 | , { 111 | field: "Edit" 112 | , width: 100 113 | , displayName: "Edit" 114 | , cellTemplate: '
' 115 | }]; 116 | vm.addOwasp = function () { 117 | var rowTmp = {}; 118 | var newService = { 119 | "projectName": "" 120 | , "companyName": "" 121 | , "appType ": "" 122 | , "startDate": "" 123 | , "endDate": "" 124 | , "analystName": "" 125 | }; 126 | rowTmp.entity = newService; 127 | vm.addRow(vm.serviceGrid, rowTmp); 128 | }; 129 | }]); 130 | app.controller('RowEditCtrl', ['$http', '$uibModalInstance', 'grid', 'row', '$window', '$state', 'Notify', function ($http, $uibModalInstance, grid, row, $window, $state, Notify) { 131 | var seltype = grid.seltype; 132 | var vm = this; 133 | vm.entity = angular.copy(row.entity); 134 | vm.save = save; 135 | vm.update = update; 136 | vm.remove = remove; 137 | vm.entity.applicationType = ["Web", "Mobile"]; 138 | 139 | function save() { 140 | $http.post('/addProject', vm.entity).then(function (response) { 141 | if(response.data.status == 'True'){ 142 | Notify.alert('Project Added Successsfully', { status: 'success' }); 143 | } 144 | if (seltype == vm.entity.appType) { 145 | vm.entity.id = response.data.id; 146 | grid.data.push(vm.entity); 147 | } 148 | $uibModalInstance.close(row.entity); 149 | }); 150 | $uibModalInstance.close(row.entity); 151 | } 152 | 153 | function update() { 154 | $http.post('/editProject', vm.entity).then(function (response) { 155 | if(response.data.status == 'True'){ 156 | Notify.alert('Project Updated Successsfully', { status: 'success' }); 157 | } 158 | row.entity.projectName = vm.entity.projectName; 159 | row.entity.companyName = vm.entity.companyName; 160 | row.entity.appType = vm.entity.appType; 161 | row.entity.startDate = vm.entity.startDate; 162 | row.entity.endDate = vm.entity.endDate; 163 | row.entity.analystName = vm.entity.analystName; 164 | $uibModalInstance.close(row.entity); 165 | }); 166 | } 167 | 168 | function remove() { 169 | $http.post('/deleteProject', vm.entity).then(function (response) { 170 | if(response.data.status == 'True'){ 171 | Notify.alert('Project Deleted Successsfully', { status: 'success' }); 172 | } 173 | row.entity = angular.extend(row.entity, vm.entity); 174 | var index = grid.appScope.vm.serviceGrid.data.indexOf(row.entity); 175 | grid.appScope.vm.serviceGrid.data.splice(index, 1); 176 | $uibModalInstance.close(row.entity); 177 | }); 178 | } 179 | }]); 180 | })(); -------------------------------------------------------------------------------- /public/vendor/uploader/ng-file-upload-shim.min.js: -------------------------------------------------------------------------------- 1 | /*! 12.2.13 */ 2 | !function(){function a(a,b){window.XMLHttpRequest.prototype[a]=b(window.XMLHttpRequest.prototype[a])}function b(a,b,c){try{Object.defineProperty(a,b,{get:c})}catch(d){}}if(window.FileAPI||(window.FileAPI={}),!window.XMLHttpRequest)throw"AJAX is not supported. XMLHttpRequest is not defined.";if(FileAPI.shouldLoad=!window.FormData||FileAPI.forceLoad,FileAPI.shouldLoad){var c=function(a){if(!a.__listeners){a.upload||(a.upload={}),a.__listeners=[];var b=a.upload.addEventListener;a.upload.addEventListener=function(c,d){a.__listeners[c]=d,b&&b.apply(this,arguments)}}};a("open",function(a){return function(b,d,e){c(this),this.__url=d;try{a.apply(this,[b,d,e])}catch(f){f.message.indexOf("Access is denied")>-1&&(this.__origError=f,a.apply(this,[b,"_fix_for_ie_crossdomain__",e]))}}}),a("getResponseHeader",function(a){return function(b){return this.__fileApiXHR&&this.__fileApiXHR.getResponseHeader?this.__fileApiXHR.getResponseHeader(b):null==a?null:a.apply(this,[b])}}),a("getAllResponseHeaders",function(a){return function(){return this.__fileApiXHR&&this.__fileApiXHR.getAllResponseHeaders?this.__fileApiXHR.getAllResponseHeaders():null==a?null:a.apply(this)}}),a("abort",function(a){return function(){return this.__fileApiXHR&&this.__fileApiXHR.abort?this.__fileApiXHR.abort():null==a?null:a.apply(this)}}),a("setRequestHeader",function(a){return function(b,d){if("__setXHR_"===b){c(this);var e=d(this);e instanceof Function&&e(this)}else this.__requestHeaders=this.__requestHeaders||{},this.__requestHeaders[b]=d,a.apply(this,arguments)}}),a("send",function(a){return function(){var c=this;if(arguments[0]&&arguments[0].__isFileAPIShim){var d=arguments[0],e={url:c.__url,jsonp:!1,cache:!0,complete:function(a,d){a&&angular.isString(a)&&-1!==a.indexOf("#2174")&&(a=null),c.__completed=!0,!a&&c.__listeners.load&&c.__listeners.load({type:"load",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),!a&&c.__listeners.loadend&&c.__listeners.loadend({type:"loadend",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),"abort"===a&&c.__listeners.abort&&c.__listeners.abort({type:"abort",loaded:c.__loaded,total:c.__total,target:c,lengthComputable:!0}),void 0!==d.status&&b(c,"status",function(){return 0===d.status&&a&&"abort"!==a?500:d.status}),void 0!==d.statusText&&b(c,"statusText",function(){return d.statusText}),b(c,"readyState",function(){return 4}),void 0!==d.response&&b(c,"response",function(){return d.response});var e=d.responseText||(a&&0===d.status&&"abort"!==a?a:void 0);b(c,"responseText",function(){return e}),b(c,"response",function(){return e}),a&&b(c,"err",function(){return a}),c.__fileApiXHR=d,c.onreadystatechange&&c.onreadystatechange(),c.onload&&c.onload()},progress:function(a){if(a.target=c,c.__listeners.progress&&c.__listeners.progress(a),c.__total=a.total,c.__loaded=a.loaded,a.total===a.loaded){var b=this;setTimeout(function(){c.__completed||(c.getAllResponseHeaders=function(){},b.complete(null,{status:204,statusText:"No Content"}))},FileAPI.noContentTimeout||1e4)}},headers:c.__requestHeaders};e.data={},e.files={};for(var f=0;f-1){e=h.substring(0,g+1);break}null==FileAPI.staticPath&&(FileAPI.staticPath=e),i.setAttribute("src",d||e+"FileAPI.min.js"),document.getElementsByTagName("head")[0].appendChild(i)}FileAPI.ngfFixIE=function(d,e,f){if(!b())throw'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';var g=function(){var b=e.parent();d.attr("disabled")?b&&b.removeClass("js-fileapi-wrapper"):(e.attr("__ngf_flash_")||(e.unbind("change"),e.unbind("click"),e.bind("change",function(a){h.apply(this,[a]),f.apply(this,[a])}),e.attr("__ngf_flash_","true")),b.addClass("js-fileapi-wrapper"),a(d)||(b.css("position","absolute").css("top",c(d[0]).top+"px").css("left",c(d[0]).left+"px").css("width",d[0].offsetWidth+"px").css("height",d[0].offsetHeight+"px").css("filter","alpha(opacity=0)").css("display",d.css("display")).css("overflow","hidden").css("z-index","900000").css("visibility","visible"),e.css("width",d[0].offsetWidth+"px").css("height",d[0].offsetHeight+"px").css("position","absolute").css("top","0px").css("left","0px")))};d.bind("mouseenter",g);var h=function(a){for(var b=FileAPI.getFiles(a),c=0;c index) 102 | index = categories[v]; 103 | 104 | return index + 1; 105 | } 106 | 107 | function categoriesTickGenerator(axis) { 108 | var res = []; 109 | for (var label in axis.categories) { 110 | var v = axis.categories[label]; 111 | if (v >= axis.min && v <= axis.max) 112 | res.push([v, label]); 113 | } 114 | 115 | res.sort(function (a, b) { return a[0] - b[0]; }); 116 | 117 | return res; 118 | } 119 | 120 | function setupCategoriesForAxis(series, axis, datapoints) { 121 | if (series[axis].options.mode != "categories") 122 | return; 123 | 124 | if (!series[axis].categories) { 125 | // parse options 126 | var c = {}, o = series[axis].options.categories || {}; 127 | if ($.isArray(o)) { 128 | for (var i = 0; i < o.length; ++i) 129 | c[o[i]] = i; 130 | } 131 | else { 132 | for (var v in o) 133 | c[v] = o[v]; 134 | } 135 | 136 | series[axis].categories = c; 137 | } 138 | 139 | // fix ticks 140 | if (!series[axis].options.ticks) 141 | series[axis].options.ticks = categoriesTickGenerator; 142 | 143 | transformPointsOnAxis(datapoints, axis, series[axis].categories); 144 | } 145 | 146 | function transformPointsOnAxis(datapoints, axis, categories) { 147 | // go through the points, transforming them 148 | var points = datapoints.points, 149 | ps = datapoints.pointsize, 150 | format = datapoints.format, 151 | formatColumn = axis.charAt(0), 152 | index = getNextIndex(categories); 153 | 154 | for (var i = 0; i < points.length; i += ps) { 155 | if (points[i] == null) 156 | continue; 157 | 158 | for (var m = 0; m < ps; ++m) { 159 | var val = points[i + m]; 160 | 161 | if (val == null || !format[m][formatColumn]) 162 | continue; 163 | 164 | if (!(val in categories)) { 165 | categories[val] = index; 166 | ++index; 167 | } 168 | 169 | points[i + m] = categories[val]; 170 | } 171 | } 172 | } 173 | 174 | function processDatapoints(plot, series, datapoints) { 175 | setupCategoriesForAxis(series, "xaxis", datapoints); 176 | setupCategoriesForAxis(series, "yaxis", datapoints); 177 | } 178 | 179 | function init(plot) { 180 | plot.hooks.processRawData.push(processRawData); 181 | plot.hooks.processDatapoints.push(processDatapoints); 182 | } 183 | 184 | $.plot.plugins.push({ 185 | init: init, 186 | options: options, 187 | name: 'categories', 188 | version: '1.0' 189 | }); 190 | })(jQuery); 191 | -------------------------------------------------------------------------------- /public/vendor/downloader/angular-file-saver.bundle.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ngFileSaver=e():t.ngFileSaver=e()}(this,function(){return function(t){function e(o){if(n[o])return n[o].exports;var r=n[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";t.exports="ngFileSaver",angular.module("ngFileSaver",[]).factory("FileSaver",["Blob","SaveAs","FileSaverUtils",n(1)]).factory("FileSaverUtils",[n(2)]).factory("Blob",["$window",n(3)]).factory("SaveAs",[n(5)])},function(t,e){"use strict";t.exports=function(t,e,n){function o(t,o,r){try{e(t,o,r)}catch(i){n.handleErrors(i.message)}}return{saveAs:function(t,e,r){return n.isBlobInstance(t)||n.handleErrors("Data argument should be a blob instance"),n.isString(e)||n.handleErrors("Filename argument should be a string"),o(t,e,r)}}}},function(t,e){"use strict";t.exports=function(){return{handleErrors:function(t){throw new Error(t)},isString:function(t){return"string"==typeof t||t instanceof String},isUndefined:function(t){return"undefined"==typeof t},isBlobInstance:function(t){return t instanceof Blob}}}},function(t,e,n){"use strict";n(4),t.exports=function(t){return t.Blob}},function(t,e){!function(t){"use strict";if(t.URL=t.URL||t.webkitURL,t.Blob&&t.URL)try{return void new Blob}catch(e){}var n=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||function(t){var e=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},n=function(){this.data=[]},o=function(t,e,n){this.data=t,this.size=t.length,this.type=e,this.encoding=n},r=n.prototype,i=o.prototype,a=t.FileReaderSync,c=function(t){this.code=this[this.name=t]},s="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),u=s.length,f=t.URL||t.webkitURL||t,l=f.createObjectURL,d=f.revokeObjectURL,p=f,h=t.btoa,b=t.atob,v=t.ArrayBuffer,w=t.Uint8Array,g=/^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;for(o.fake=i.fake=!0;u--;)c.prototype[s[u]]=u+1;return f.createObjectURL||(p=t.URL=function(t){var e,n=document.createElementNS("http://www.w3.org/1999/xhtml","a");return n.href=t,"origin"in n||("data:"===n.protocol.toLowerCase()?n.origin=null:(e=t.match(g),n.origin=e&&e[1])),n}),p.createObjectURL=function(t){var e,n=t.type;return null===n&&(n="application/octet-stream"),t instanceof o?(e="data:"+n,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):h?e+";base64,"+h(t.data):e+","+encodeURIComponent(t.data)):l?l.call(f,t):void 0},p.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&d&&d.call(f,t)},r.append=function(t){var n=this.data;if(w&&(t instanceof v||t instanceof w)){for(var r="",i=new w(t),s=0,u=i.length;u>s;s++)r+=String.fromCharCode(i[s]);n.push(r)}else if("Blob"===e(t)||"File"===e(t)){if(!a)throw new c("NOT_READABLE_ERR");var f=new a;n.push(f.readAsBinaryString(t))}else t instanceof o?"base64"===t.encoding&&b?n.push(b(t.data)):"URI"===t.encoding?n.push(decodeURIComponent(t.data)):"raw"===t.encoding&&n.push(t.data):("string"!=typeof t&&(t+=""),n.push(unescape(encodeURIComponent(t))))},r.getBlob=function(t){return arguments.length||(t=null),new o(this.data.join(""),t,"raw")},r.toString=function(){return"[object BlobBuilder]"},i.slice=function(t,e,n){var r=arguments.length;return 3>r&&(n=null),new o(this.data.slice(t,r>1?e:this.data.length),n,this.encoding)},i.toString=function(){return"[object Blob]"},i.close=function(){this.size=0,delete this.data},n}(t);t.Blob=function(t,e){var o=e?e.type||"":"",r=new n;if(t)for(var i=0,a=t.length;a>i;i++)Uint8Array&&t[i]instanceof Uint8Array?r.append(t[i].buffer):r.append(t[i]);var c=r.getBlob(o);return!c.slice&&c.webkitSlice&&(c.slice=c.webkitSlice),c};var o=Object.getPrototypeOf||function(t){return t.__proto__};t.Blob.prototype=o(new t.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this)},function(t,e,n){"use strict";t.exports=function(){return n(6).saveAs||function(){}}},function(t,e,n){var o,r,i=i||function(t){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var e=t.document,n=function(){return t.URL||t.webkitURL||t},o=e.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,i=function(t){var e=new MouseEvent("click");t.dispatchEvent(e)},a=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),c=t.webkitRequestFileSystem,s=t.requestFileSystem||c||t.mozRequestFileSystem,u=function(e){(t.setImmediate||t.setTimeout)(function(){throw e},0)},f="application/octet-stream",l=0,d=500,p=function(e){var o=function(){"string"==typeof e?n().revokeObjectURL(e):e.remove()};t.chrome?o():setTimeout(o,d)},h=function(t,e,n){e=[].concat(e);for(var o=e.length;o--;){var r=t["on"+e[o]];if("function"==typeof r)try{r.call(t,n||t)}catch(i){u(i)}}},b=function(t){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob(["\ufeff",t],{type:t.type}):t},v=function(e,u,d){d||(e=b(e));var v,w,g,y=this,R=e.type,S=!1,m=function(){h(y,"writestart progress write writeend".split(" "))},E=function(){if(w&&a&&"undefined"!=typeof FileReader){var o=new FileReader;return o.onloadend=function(){var t=o.result;w.location.href="data:attachment/file"+t.slice(t.search(/[,;]/)),y.readyState=y.DONE,m()},o.readAsDataURL(e),void(y.readyState=y.INIT)}if((S||!v)&&(v=n().createObjectURL(e)),w)w.location.href=v;else{var r=t.open(v,"_blank");void 0==r&&a&&(t.location.href=v)}y.readyState=y.DONE,m(),p(v)},O=function(t){return function(){return y.readyState!==y.DONE?t.apply(this,arguments):void 0}},U={create:!0,exclusive:!1};return y.readyState=y.INIT,u||(u="download"),r?(v=n().createObjectURL(e),o.href=v,o.download=u,void setTimeout(function(){i(o),m(),p(v),y.readyState=y.DONE})):(t.chrome&&R&&R!==f&&(g=e.slice||e.webkitSlice,e=g.call(e,0,e.size,f),S=!0),c&&"download"!==u&&(u+=".download"),(R===f||c)&&(w=t),s?(l+=e.size,void s(t.TEMPORARY,l,O(function(t){t.root.getDirectory("saved",U,O(function(t){var n=function(){t.getFile(u,U,O(function(t){t.createWriter(O(function(n){n.onwriteend=function(e){w.location.href=t.toURL(),y.readyState=y.DONE,h(y,"writeend",e),p(t)},n.onerror=function(){var t=n.error;t.code!==t.ABORT_ERR&&E()},"writestart progress write abort".split(" ").forEach(function(t){n["on"+t]=y["on"+t]}),n.write(e),y.abort=function(){n.abort(),y.readyState=y.DONE},y.readyState=y.WRITING}),E)}),E)};t.getFile(u,{create:!1},O(function(t){t.remove(),n()}),O(function(t){t.code===t.NOT_FOUND_ERR?n():E()}))}),E)}),E)):void E())},w=v.prototype,g=function(t,e,n){return new v(t,e,n)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(t,e,n){return n||(t=b(t)),navigator.msSaveOrOpenBlob(t,e||"download")}:(w.abort=function(){var t=this;t.readyState=t.DONE,h(t,"abort")},w.readyState=w.INIT=0,w.WRITING=1,w.DONE=2,w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null,g)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof t&&t.exports?t.exports.saveAs=i:null!==n(7)&&null!=n(8)&&(o=[],r=function(){return i}.apply(e,o),!(void 0!==r&&(t.exports=r)))},function(t,e){t.exports=function(){throw new Error("define cannot be used indirect")}},function(t,e){(function(e){t.exports=e}).call(e,{})}])}); -------------------------------------------------------------------------------- /public/vendor/flot.tooltip/js/jquery.flot.tooltip.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery.flot.tooltip 3 | * 4 | * description: easy-to-use tooltips for Flot charts 5 | * version: 0.9.0 6 | * authors: Krzysztof Urbas @krzysu [myviews.pl],Evan Steinkerchner @Roundaround 7 | * website: https://github.com/krzysu/flot.tooltip 8 | * 9 | * build on 2016-07-26 10 | * released under MIT License, 2012 11 | */ 12 | !function(a){var b={tooltip:{show:!1,cssClass:"flotTip",content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,monthNames:null,dayNames:null,shifts:{x:10,y:20},defaultTheme:!0,snap:!0,lines:!1,clickTips:!1,onHover:function(a,b){},$compat:!1}};b.tooltipOpts=b.tooltip;var c=function(a){this.tipPosition={x:0,y:0},this.init(a)};c.prototype.init=function(b){function c(a){var c={};c.x=a.pageX,c.y=a.pageY,b.setTooltipPosition(c)}function d(c,d,g){f.clickmode?(a(b.getPlaceholder()).bind("plothover",e),b.hideTooltip(),f.clickmode=!1):(e(c,d,g),f.getDomElement().is(":visible")&&(a(b.getPlaceholder()).unbind("plothover",e),f.clickmode=!0))}function e(c,d,e){var g=function(a,b,c,d){return Math.sqrt((c-a)*(c-a)+(d-b)*(d-b))},h=function(a,b,c,d,e,f,h){if(!h||(h=function(a,b,c,d,e,f){if("undefined"!=typeof c)return{x:c,y:b};if("undefined"!=typeof d)return{x:a,y:d};var g,h=-1/((f-d)/(e-c));return{x:g=(e*(a*h-b+d)+c*(a*-h+b-f))/(h*(e-c)+d-f),y:h*g-h*a+b}}(a,b,c,d,e,f),h.x>=Math.min(c,e)&&h.x<=Math.max(c,e)&&h.y>=Math.min(d,f)&&h.y<=Math.max(d,f))){var i=d-f,j=e-c,k=c*f-d*e;return Math.abs(i*a+j*b+k)/Math.sqrt(i*i+j*j)}var l=g(a,b,c,d),m=g(a,b,e,f);return l>m?m:l};if(e)b.showTooltip(e,f.tooltipOptions.snap?e:d);else if(f.plotOptions.series.lines.show&&f.tooltipOptions.lines===!0){var i=f.plotOptions.grid.mouseActiveRadius,j={distance:i+1},k=d;a.each(b.getData(),function(a,c){for(var e=0,i=-1,l=1;l=d.x&&(e=l-1,i=l);if(-1===i)return void b.hideTooltip();var m={x:c.data[e][0],y:c.data[e][1]},n={x:c.data[i][0],y:c.data[i][1]},o=h(c.xaxis.p2c(d.x),c.yaxis.p2c(d.y),c.xaxis.p2c(m.x),c.yaxis.p2c(m.y),c.xaxis.p2c(n.x),c.yaxis.p2c(n.y),!1);if(oh;h++)this.plotPlugins.push(a.plot.plugins[h].name);b.hooks.bindEvents.push(function(b,g){if(f.plotOptions=b.getOptions(),"boolean"==typeof f.plotOptions.tooltip&&(f.plotOptions.tooltipOpts.show=f.plotOptions.tooltip,f.plotOptions.tooltip=f.plotOptions.tooltipOpts,delete f.plotOptions.tooltipOpts),f.plotOptions.tooltip.show!==!1&&"undefined"!=typeof f.plotOptions.tooltip.show){f.tooltipOptions=f.plotOptions.tooltip,f.tooltipOptions.$compat?(f.wfunc="width",f.hfunc="height"):(f.wfunc="innerWidth",f.hfunc="innerHeight");f.getDomElement();a(b.getPlaceholder()).bind("plothover",e),f.tooltipOptions.clickTips&&a(b.getPlaceholder()).bind("plotclick",d),f.clickmode=!1,a(g).bind("mousemove",c)}}),b.hooks.shutdown.push(function(b,f){a(b.getPlaceholder()).unbind("plothover",e),a(b.getPlaceholder()).unbind("plotclick",d),b.removeTooltip(),a(f).unbind("mousemove",c)}),b.setTooltipPosition=function(b){var c=f.getDomElement(),d=c.outerWidth()+f.tooltipOptions.shifts.x,e=c.outerHeight()+f.tooltipOptions.shifts.y;b.x-a(window).scrollLeft()>a(window)[f.wfunc]()-d&&(b.x-=d,b.x=Math.max(b.x,0)),b.y-a(window).scrollTop()>a(window)[f.hfunc]()-e&&(b.y-=e),isNaN(b.x)?f.tipPosition.x=f.tipPosition.xPrev:(f.tipPosition.x=b.x,f.tipPosition.xPrev=b.x),isNaN(b.y)?f.tipPosition.y=f.tipPosition.yPrev:(f.tipPosition.y=b.y,f.tipPosition.yPrev=b.y)},b.showTooltip=function(a,c,d){var e=f.getDomElement(),g=f.stringFormat(f.tooltipOptions.content,a);""!==g&&(e.html(g),b.setTooltipPosition({x:f.tipPosition.x,y:f.tipPosition.y}),e.css({left:f.tipPosition.x+f.tooltipOptions.shifts.x,top:f.tipPosition.y+f.tooltipOptions.shifts.y}).show(),"function"==typeof f.tooltipOptions.onHover&&f.tooltipOptions.onHover(a,e))},b.hideTooltip=function(){f.getDomElement().hide().html("")},b.removeTooltip=function(){f.getDomElement().remove()}},c.prototype.getDomElement=function(){var b=a("
");return this.tooltipOptions&&this.tooltipOptions.cssClass&&(b=a("."+this.tooltipOptions.cssClass),0===b.length&&(b=a("
").addClass(this.tooltipOptions.cssClass),b.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&b.css({background:"#fff","z-index":"1040",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"}))),b},c.prototype.stringFormat=function(a,b){var c,d,e,f,g,h=/%p\.{0,1}(\d{0,})/,i=/%s/,j=/%c/,k=/%lx/,l=/%ly/,m=/%x\.{0,1}(\d{0,})/,n=/%y\.{0,1}(\d{0,})/,o="%x",p="%y",q="%ct",r="%n";if("undefined"!=typeof b.series.threshold?(c=b.datapoint[0],d=b.datapoint[1],e=b.datapoint[2]):"undefined"!=typeof b.series.curvedLines?(c=b.datapoint[0],d=b.datapoint[1]):"undefined"!=typeof b.series.lines&&b.series.lines.steps?(c=b.series.datapoints.points[2*b.dataIndex],d=b.series.datapoints.points[2*b.dataIndex+1],e=""):(c=b.series.data[b.dataIndex][0],d=b.series.data[b.dataIndex][1],e=b.series.data[b.dataIndex][2]),null===b.series.label&&b.series.originSeries&&(b.series.label=b.series.originSeries.label),"function"==typeof a&&(a=a(b.series.label,c,d,b)),"boolean"==typeof a&&!a)return"";if(e&&(a=a.replace(q,e)),"undefined"!=typeof b.series.percent?f=b.series.percent:"undefined"!=typeof b.series.percents&&(f=b.series.percents[b.dataIndex]),"number"==typeof f&&(a=this.adjustValPrecision(h,a,f)),b.series.hasOwnProperty("pie")&&"undefined"!=typeof b.series.data[0][1]&&(g=b.series.data[0][1]),"number"==typeof g&&(a=a.replace(r,g)),a="undefined"!=typeof b.series.label?a.replace(i,b.series.label):a.replace(i,""),a="undefined"!=typeof b.series.color?a.replace(j,b.series.color):a.replace(j,""),a=this.hasAxisLabel("xaxis",b)?a.replace(k,b.series.xaxis.options.axisLabel):a.replace(k,""),a=this.hasAxisLabel("yaxis",b)?a.replace(l,b.series.yaxis.options.axisLabel):a.replace(l,""),this.isTimeMode("xaxis",b)&&this.isXDateFormat(b)&&(a=a.replace(m,this.timestampToDate(c,this.tooltipOptions.xDateFormat,b.series.xaxis.options))),this.isTimeMode("yaxis",b)&&this.isYDateFormat(b)&&(a=a.replace(n,this.timestampToDate(d,this.tooltipOptions.yDateFormat,b.series.yaxis.options))),"number"==typeof c&&(a=this.adjustValPrecision(m,a,c)),"number"==typeof d&&(a=this.adjustValPrecision(n,a,d)),"undefined"!=typeof b.series.xaxis.ticks){var s;s=this.hasRotatedXAxisTicks(b)?"rotatedTicks":"ticks";var t=b.dataIndex+b.seriesIndex;for(var u in b.series.xaxis[s])if(b.series.xaxis[s].hasOwnProperty(t)&&!this.isTimeMode("xaxis",b)){var v=this.isCategoriesMode("xaxis",b)?b.series.xaxis[s][t].label:b.series.xaxis[s][t].v;v===c&&(a=a.replace(m,b.series.xaxis[s][t].label.replace(/\$/g,"$$$$")))}}if("undefined"!=typeof b.series.yaxis.ticks)for(var w in b.series.yaxis.ticks)if(b.series.yaxis.ticks.hasOwnProperty(w)){var x=this.isCategoriesMode("yaxis",b)?b.series.yaxis.ticks[w].label:b.series.yaxis.ticks[w].v;x===d&&(a=a.replace(n,b.series.yaxis.ticks[w].label.replace(/\$/g,"$$$$")))}return"undefined"!=typeof b.series.xaxis.tickFormatter&&(a=a.replace(o,b.series.xaxis.tickFormatter(c,b.series.xaxis).replace(/\$/g,"$$"))),"undefined"!=typeof b.series.yaxis.tickFormatter&&(a=a.replace(p,b.series.yaxis.tickFormatter(d,b.series.yaxis).replace(/\$/g,"$$"))),a},c.prototype.isTimeMode=function(a,b){return"undefined"!=typeof b.series[a].options.mode&&"time"===b.series[a].options.mode},c.prototype.isXDateFormat=function(a){return"undefined"!=typeof this.tooltipOptions.xDateFormat&&null!==this.tooltipOptions.xDateFormat},c.prototype.isYDateFormat=function(a){return"undefined"!=typeof this.tooltipOptions.yDateFormat&&null!==this.tooltipOptions.yDateFormat},c.prototype.isCategoriesMode=function(a,b){return"undefined"!=typeof b.series[a].options.mode&&"categories"===b.series[a].options.mode},c.prototype.timestampToDate=function(b,c,d){var e=a.plot.dateGenerator(b,d);return a.plot.formatDate(e,c,this.tooltipOptions.monthNames,this.tooltipOptions.dayNames)},c.prototype.adjustValPrecision=function(a,b,c){var d,e=b.match(a);return null!==e&&""!==RegExp.$1&&(d=RegExp.$1,c=c.toFixed(d),b=b.replace(a,c)),b},c.prototype.hasAxisLabel=function(b,c){return-1!==a.inArray("axisLabels",this.plotPlugins)&&"undefined"!=typeof c.series[b].options.axisLabel&&c.series[b].options.axisLabel.length>0},c.prototype.hasRotatedXAxisTicks=function(b){return-1!==a.inArray("tickRotor",this.plotPlugins)&&"undefined"!=typeof b.series.xaxis.rotatedTicks};var d=function(a){new c(a)};a.plot.plugins.push({init:d,options:b,name:"tooltip",version:"0.8.5"})}(jQuery); -------------------------------------------------------------------------------- /public/vendor/animo.js/animo.js: -------------------------------------------------------------------------------- 1 | ;(function ( $, window, document, undefined ) { 2 | 3 | /** 4 | * animo is a powerful little tool that makes managing CSS animations extremely easy. Stack animations, set callbacks, make magic. 5 | * Modern browsers and almost all mobile browsers support CSS animations (http://caniuse.com/css-animation). 6 | * 7 | * @author Daniel Raftery : twitter/ThrivingKings 8 | * @version 1.0.2 9 | */ 10 | function animo( element, options, callback, other_cb ) { 11 | 12 | // Default configuration 13 | var defaults = { 14 | duration: 1, 15 | animation: null, 16 | iterate: 1, 17 | timing: "linear", 18 | keep: false 19 | }; 20 | 21 | // Browser prefixes for CSS 22 | this.prefixes = ["", "-moz-", "-o-animation-", "-webkit-"]; 23 | 24 | // Cache the element 25 | this.element = $(element); 26 | 27 | this.bare = element; 28 | 29 | // For stacking of animations 30 | this.queue = []; 31 | 32 | // Hacky 33 | this.listening = false; 34 | 35 | // Figure out where the callback is 36 | var cb = (typeof callback == "function" ? callback : other_cb); 37 | 38 | // Options can sometimes be a command 39 | switch(options) { 40 | 41 | case "blur": 42 | 43 | defaults = { 44 | amount: 3, 45 | duration: 0.5, 46 | focusAfter: null 47 | }; 48 | 49 | this.options = $.extend( defaults, callback ); 50 | 51 | this._blur(cb); 52 | 53 | break; 54 | 55 | case "focus": 56 | 57 | this._focus(); 58 | 59 | break; 60 | 61 | case "rotate": 62 | 63 | defaults = { 64 | degrees: 15, 65 | duration: 0.5 66 | }; 67 | 68 | this.options = $.extend( defaults, callback ); 69 | 70 | this._rotate(cb); 71 | 72 | break; 73 | 74 | case "cleanse": 75 | 76 | this.cleanse(); 77 | 78 | break; 79 | 80 | default: 81 | 82 | this.options = $.extend( defaults, options ); 83 | 84 | this.init(cb); 85 | 86 | break; 87 | } 88 | } 89 | 90 | animo.prototype = { 91 | 92 | // A standard CSS animation 93 | init: function(callback) { 94 | 95 | var $me = this; 96 | 97 | // Are we stacking animations? 98 | if(Object.prototype.toString.call( $me.options.animation ) === '[object Array]') { 99 | $.merge($me.queue, $me.options.animation); 100 | } else { 101 | $me.queue.push($me.options.animation); 102 | } 103 | 104 | $me.cleanse(); 105 | 106 | $me.animate(callback); 107 | 108 | }, 109 | 110 | // The actual adding of the class and listening for completion 111 | animate: function(callback) { 112 | 113 | this.element.addClass('animated'); 114 | 115 | this.element.addClass(this.queue[0]); 116 | 117 | this.element.data("animo", this.queue[0]); 118 | 119 | var ai = this.prefixes.length; 120 | 121 | // Add the options for each prefix 122 | while(ai--) { 123 | 124 | this.element.css(this.prefixes[ai]+"animation-duration", this.options.duration+"s"); 125 | 126 | this.element.css(this.prefixes[ai]+"animation-iteration-count", this.options.iterate); 127 | 128 | this.element.css(this.prefixes[ai]+"animation-timing-function", this.options.timing); 129 | 130 | } 131 | 132 | var $me = this, _cb = callback; 133 | 134 | if($me.queue.length>1) { 135 | _cb = null; 136 | } 137 | 138 | // Listen for the end of the animation 139 | this._end("AnimationEnd", function() { 140 | 141 | // If there are more, clean it up and move on 142 | if($me.element.hasClass($me.queue[0])) { 143 | 144 | if(!$me.options.keep) { 145 | $me.cleanse(); 146 | } 147 | 148 | $me.queue.shift(); 149 | 150 | if($me.queue.length) { 151 | 152 | $me.animate(callback); 153 | } 154 | } 155 | }, _cb); 156 | }, 157 | 158 | cleanse: function() { 159 | 160 | this.element.removeClass('animated'); 161 | 162 | this.element.removeClass(this.queue[0]); 163 | 164 | this.element.removeClass(this.element.data("animo")); 165 | 166 | var ai = this.prefixes.length; 167 | 168 | while(ai--) { 169 | 170 | this.element.css(this.prefixes[ai]+"animation-duration", ""); 171 | 172 | this.element.css(this.prefixes[ai]+"animation-iteration-count", ""); 173 | 174 | this.element.css(this.prefixes[ai]+"animation-timing-function", ""); 175 | 176 | this.element.css(this.prefixes[ai]+"transition", ""); 177 | 178 | this.element.css(this.prefixes[ai]+"transform", ""); 179 | 180 | this.element.css(this.prefixes[ai]+"filter", ""); 181 | 182 | } 183 | }, 184 | 185 | _blur: function(callback) { 186 | 187 | if(this.element.is("img")) { 188 | 189 | var svg_id = "svg_" + (((1 + Math.random()) * 0x1000000) | 0).toString(16).substring(1); 190 | var filter_id = "filter_" + (((1 + Math.random()) * 0x1000000) | 0).toString(16).substring(1); 191 | 192 | $('body').append(''); 193 | 194 | var ai = this.prefixes.length; 195 | 196 | while(ai--) { 197 | 198 | this.element.css(this.prefixes[ai]+"filter", "blur("+this.options.amount+"px)"); 199 | 200 | this.element.css(this.prefixes[ai]+"transition", this.options.duration+"s all linear"); 201 | 202 | } 203 | 204 | this.element.css("filter", "url(#"+filter_id+")"); 205 | 206 | this.element.data("svgid", svg_id); 207 | 208 | } else { 209 | 210 | var color = this.element.css('color'); 211 | 212 | var ai = this.prefixes.length; 213 | 214 | // Add the options for each prefix 215 | while(ai--) { 216 | 217 | this.element.css(this.prefixes[ai]+"transition", "all "+this.options.duration+"s linear"); 218 | 219 | } 220 | 221 | this.element.css("text-shadow", "0 0 "+this.options.amount+"px "+color); 222 | this.element.css("color", "transparent"); 223 | } 224 | 225 | this._end("TransitionEnd", null, callback); 226 | 227 | var $me = this; 228 | 229 | if(this.options.focusAfter) { 230 | 231 | var focus_wait = window.setTimeout(function() { 232 | 233 | $me._focus(); 234 | 235 | focus_wait = window.clearTimeout(focus_wait); 236 | 237 | }, (this.options.focusAfter*1000)); 238 | } 239 | 240 | }, 241 | 242 | _focus: function() { 243 | 244 | var ai = this.prefixes.length; 245 | 246 | if(this.element.is("img")) { 247 | 248 | while(ai--) { 249 | 250 | this.element.css(this.prefixes[ai]+"filter", ""); 251 | 252 | this.element.css(this.prefixes[ai]+"transition", ""); 253 | 254 | } 255 | 256 | var $svg = $('#'+this.element.data('svgid')); 257 | 258 | $svg.remove(); 259 | } else { 260 | 261 | while(ai--) { 262 | 263 | this.element.css(this.prefixes[ai]+"transition", ""); 264 | 265 | } 266 | 267 | this.element.css("text-shadow", ""); 268 | this.element.css("color", ""); 269 | } 270 | }, 271 | 272 | _rotate: function(callback) { 273 | 274 | var ai = this.prefixes.length; 275 | 276 | // Add the options for each prefix 277 | while(ai--) { 278 | 279 | this.element.css(this.prefixes[ai]+"transition", "all "+this.options.duration+"s linear"); 280 | 281 | this.element.css(this.prefixes[ai]+"transform", "rotate("+this.options.degrees+"deg)"); 282 | 283 | } 284 | 285 | this._end("TransitionEnd", null, callback); 286 | 287 | }, 288 | 289 | _end: function(type, todo, callback) { 290 | 291 | var $me = this; 292 | 293 | var binding = type.toLowerCase()+" webkit"+type+" o"+type+" MS"+type; 294 | 295 | this.element.bind(binding, function() { 296 | 297 | $me.element.unbind(binding); 298 | 299 | if(typeof todo == "function") { 300 | 301 | todo(); 302 | } 303 | 304 | if(typeof callback == "function") { 305 | 306 | callback($me); 307 | } 308 | }); 309 | 310 | } 311 | }; 312 | 313 | $.fn.animo = function ( options, callback, other_cb ) { 314 | 315 | return this.each(function() { 316 | 317 | new animo( this, options, callback, other_cb ); 318 | 319 | }); 320 | 321 | }; 322 | 323 | })( jQuery, window, document ); 324 | -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/fontello.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2017 by original authors @ fontello.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /public/vendor/angular-ui-grid/ui-grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Copyright (C) 2016 by original authors @ fontello.com 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /public/vendor/modernizr/modernizr.custom.js: -------------------------------------------------------------------------------- 1 | /*! modernizr 3.5.0 (Custom Build) | MIT * 2 | * https://modernizr.com/download/?-backgroundsize-bgpositionshorthand-bgpositionxy-bgrepeatspace_bgrepeatround-bgsizecover-borderradius-cssanimations-csscalc-csstransforms-csstransforms3d-csstransitions-flexboxtweener-fontface-inlinesvg-localstorage-multiplebgs-preserve3d-sessionstorage-smil-svgclippaths-svgfilters-svgforeignobject-todataurljpeg_todataurlpng_todataurlwebp-setclasses !*/ 3 | !function(e,t,n){function r(e,t){return typeof e===t}function s(){var e,t,n,s,a,o,i;for(var d in w)if(w.hasOwnProperty(d)){if(e=[],t=w[d],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;nc;c++)if(m=e[c],v=k.style[m],o(m,"-")&&(m=p(m)),k.style[m]!==n){if(a||r(s,"undefined"))return d(),"pfx"==t?m:!0;try{k.style[m]=s}catch(y){}if(k.style[m]!=v)return d(),"pfx"==t?m:!0}return d(),!1}function m(e,t){return function(){return e.apply(t,arguments)}}function v(e,t,n){var s;for(var a in e)if(e[a]in t)return n===!1?e[a]:(s=t[e[a]],r(s,"function")?m(s,n||t):s);return!1}function h(e,t,n,s,a){var o=e.charAt(0).toUpperCase()+e.slice(1),i=(e+" "+E.join(o+" ")+o).split(" ");return r(t,"string")||r(t,"undefined")?g(i,t,s,a):(i=(e+" "+z.join(o+" ")+o).split(" "),v(i,t,n))}function y(e,t,r){return h(e,n,n,t,r)}var w=[],S={_version:"3.5.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){w.push({name:e,fn:t,options:n})},addAsyncTest:function(e){w.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=S,Modernizr=new Modernizr;var b=[],x=t.documentElement,T="svg"===x.nodeName.toLowerCase(),C="Moz O ms Webkit",E=S._config.usePrefixes?C.split(" "):[];S._cssomPrefixes=E;var _={elem:i("modernizr")};Modernizr._q.push(function(){delete _.elem});var k={style:_.elem.style};Modernizr._q.unshift(function(){delete k.style});var z=S._config.usePrefixes?C.toLowerCase().split(" "):[];S._domPrefixes=z,S.testAllProps=h,S.testAllProps=y,Modernizr.addTest("backgroundsize",y("backgroundSize","100%",!0)),Modernizr.addTest("bgpositionshorthand",function(){var e=i("a"),t=e.style,n="right 10px bottom 10px";return t.cssText="background-position: "+n+";",t.backgroundPosition===n}),Modernizr.addTest("bgpositionxy",function(){return y("backgroundPositionX","3px",!0)&&y("backgroundPositionY","5px",!0)}),Modernizr.addTest("bgrepeatround",y("backgroundRepeat","round")),Modernizr.addTest("bgrepeatspace",y("backgroundRepeat","space")),Modernizr.addTest("bgsizecover",y("backgroundSize","cover")),Modernizr.addTest("borderradius",y("borderRadius","0px",!0)),Modernizr.addTest("cssanimations",y("animationName","a",!0));var P=S._config.usePrefixes?" -webkit- -moz- -o- -ms- ".split(" "):["",""];S._prefixes=P,Modernizr.addTest("csscalc",function(){var e="width:",t="calc(10px);",n=i("a");return n.style.cssText=e+P.join(t+e),!!n.style.length}),Modernizr.addTest("csstransforms",function(){return-1===navigator.userAgent.indexOf("Android 2.")&&y("transform","scale(1)",!0)});var R=S.testStyles=l,N="CSS"in e&&"supports"in e.CSS,j="supportsCSS"in e;Modernizr.addTest("supports",N||j),Modernizr.addTest("csstransforms3d",function(){var e=!!y("perspective","1px",!0),t=Modernizr._config.usePrefixes;if(e&&(!t||"webkitPerspective"in x.style)){var n,r="#modernizr{width:0;height:0}";Modernizr.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",R(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),Modernizr.addTest("csstransitions",y("transition","all",!0)),Modernizr.addTest("flexboxtweener",y("flexAlign","end",!0));var A=function(){var e=navigator.userAgent,t=e.match(/w(eb)?osbrowser/gi),n=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9;return t||n}();A?Modernizr.addTest("fontface",!1):R('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),s=r.sheet||r.styleSheet,a=s?s.cssRules&&s.cssRules[0]?s.cssRules[0].cssText:s.cssText||"":"",o=/src/i.test(a)&&0===a.indexOf(n.split(" ")[0]);Modernizr.addTest("fontface",o)}),Modernizr.addTest("inlinesvg",function(){var e=i("div");return e.innerHTML="","http://www.w3.org/2000/svg"==("undefined"!=typeof SVGRect&&e.firstChild&&e.firstChild.namespaceURI)}),Modernizr.addTest("localstorage",function(){var e="modernizr";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(t){return!1}}),Modernizr.addTest("multiplebgs",function(){var e=i("a").style;return e.cssText="background:url(https://),url(https://),red url(https://)",/(url\s*\(.*?){3}/.test(e.background)}),Modernizr.addTest("preserve3d",function(){var t,n,r=e.CSS,s=!1;return r&&r.supports&&r.supports("(transform-style: preserve-3d)")?!0:(t=i("a"),n=i("a"),t.style.cssText="display: block; transform-style: preserve-3d; transform-origin: right; transform: rotateY(40deg);",n.style.cssText="display: block; width: 9px; height: 1px; background: #000; transform-origin: right; transform: rotateY(40deg);",t.appendChild(n),x.appendChild(t),s=n.getBoundingClientRect(),x.removeChild(t),s=s.width&&s.width<4)}),Modernizr.addTest("sessionstorage",function(){var e="modernizr";try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(t){return!1}});var O={}.toString;Modernizr.addTest("smil",function(){return!!t.createElementNS&&/SVGAnimate/.test(O.call(t.createElementNS("http://www.w3.org/2000/svg","animate")))}),Modernizr.addTest("svgclippaths",function(){return!!t.createElementNS&&/SVGClipPath/.test(O.call(t.createElementNS("http://www.w3.org/2000/svg","clipPath")))}),Modernizr.addTest("svgfilters",function(){var t=!1;try{t="SVGFEColorMatrixElement"in e&&2==SVGFEColorMatrixElement.SVG_FECOLORMATRIX_TYPE_SATURATE}catch(n){}return t}),Modernizr.addTest("svgforeignobject",function(){return!!t.createElementNS&&/SVGForeignObject/.test(O.call(t.createElementNS("http://www.w3.org/2000/svg","foreignObject")))}),Modernizr.addTest("canvas",function(){var e=i("canvas");return!(!e.getContext||!e.getContext("2d"))});var V=i("canvas");Modernizr.addTest("todataurljpeg",function(){return!!Modernizr.canvas&&0===V.toDataURL("image/jpeg").indexOf("data:image/jpeg")}),Modernizr.addTest("todataurlpng",function(){return!!Modernizr.canvas&&0===V.toDataURL("image/png").indexOf("data:image/png")}),Modernizr.addTest("todataurlwebp",function(){var e=!1;try{e=!!Modernizr.canvas&&0===V.toDataURL("image/webp").indexOf("data:image/webp")}catch(t){}return e}),s(),a(b),delete S.addTest,delete S.addAsyncTest;for(var L=0;L 0){ 83 | var temp = { 84 | 'id': projectID 85 | } 86 | $http.post('/generate', temp).then(function (response) { 87 | if(response.data.status == 'True'){ 88 | var temp = { 89 | filename: response.data.filename 90 | } 91 | $http.get('/download?filename='+temp.filename+'', {responseType: 'blob'}).then(function (response) { 92 | FileSaver.saveAs(response.data, temp.filename + '.docx'); 93 | }); 94 | } 95 | }); 96 | } 97 | } 98 | 99 | 100 | vm.editRow = vulnRowEditor.editRow; 101 | vm.addRow = vulnRowEditor.addRow; 102 | vm.viewRow = vulnRowEditor.viewRow; 103 | vm.serviceGrid = { 104 | enableColumnMenus: false, 105 | enableRowSelection: false 106 | , enableRowHeaderSelection: false 107 | , rowTemplate: "
" 108 | }; 109 | vm.serviceGrid.seltype = 'None'; 110 | vm.serviceGrid.columnDefs = [{ 111 | name: 'Vulnerability Name' 112 | , field: 'vulName' 113 | , enableSorting: false 114 | , enableCellEdit: false 115 | }, 116 | { 117 | name: 'Owasp Name' 118 | , field: 'owaspName' 119 | , enableSorting: false 120 | , enableCellEdit: false 121 | }, 122 | { 123 | name: 'Risk' 124 | , field: 'risk' 125 | , enableSorting: false 126 | , enableCellEdit: false 127 | }, 128 | { 129 | field: "View", 130 | width: 100, 131 | displayName: "View", 132 | cellTemplate: '
' 133 | }, 134 | { 135 | field: "Edit", 136 | width: 100, 137 | displayName: "Edit", 138 | cellTemplate: '
' 139 | }]; 140 | vm.addVulnerability = function () { 141 | var rowTmp = {}; 142 | var newService = { 143 | "projectID" : "", 144 | "vulName" : "", 145 | "appType" : "", 146 | "owaspName" : "", 147 | "vulDetail" : "", 148 | "vulRecommend" : "", 149 | "risk" : "", 150 | "severity" : "", 151 | "cvscore" : "", 152 | "cvtext" : "", 153 | "probability" : "", 154 | "remeffort" : "", 155 | "vector" : "", 156 | "occurrences" : "", 157 | "affcomp" : "", 158 | "retest" : "", 159 | "other" : "", 160 | "proofExploit": "" 161 | }; 162 | rowTmp.entity = newService; 163 | vm.addRow(vm.serviceGrid, rowTmp); 164 | }; 165 | }]); 166 | app.controller('vulnRowEditCtrl', ['$http', '$uibModalInstance', 'grid', 'row', '$window', '$state', 'Upload', '$scope', '$stateParams', 'Notify', function ($http, $uibModalInstance, grid, row, $window, $state, Upload, $scope,$stateParams, Notify) { 167 | var projectID = $stateParams.id; 168 | var appType = $stateParams.appType; 169 | if(projectID == undefined || projectID == ""){ 170 | $state.go('app.project'); 171 | } 172 | $scope.vul= {}; 173 | $scope.vul = angular.copy(row.entity); 174 | $scope.vul.projectID=projectID; 175 | $scope.vul.appType = appType; 176 | $scope.vul.vulimgpath = []; 177 | 178 | $scope.getimage = function(vulID){ 179 | var tempVulGetImg = { 180 | 'vid': vulID 181 | } 182 | $http.post('/viewVulGetImg', tempVulGetImg).then(function (response) { 183 | for (var i = 0; i < response.data.data.length; i++) { 184 | $scope.vul.vulimgpath.push(response.data.data[i].imgpath); 185 | } 186 | }); 187 | } 188 | if($scope.vul.vulID != undefined){ 189 | $scope.getimage($scope.vul.vulID); 190 | } 191 | 192 | var temp = { 193 | 'appType': $scope.vul.appType 194 | } 195 | $http.post('/viewOwasp', temp).then(function (response) { 196 | $scope.owaspData = response.data.data; 197 | }); 198 | 199 | $scope.owaspSelect = function(data){ 200 | for(var i =0; i<$scope.owaspData.length; i++){ 201 | if($scope.owaspData[i].vulName == data){ 202 | $scope.vul.owaspName = $scope.owaspData[i].owaspName; 203 | $scope.vul.vulDetail = $scope.owaspData[i].vulDetail; 204 | $scope.vul.vulRecommend = $scope.owaspData[i].vulRecommend; 205 | 206 | } 207 | } 208 | } 209 | 210 | var vm = this; 211 | vm.entity = angular.copy(row.entity); 212 | vm.save = save; 213 | vm.update = update; 214 | vm.remove = remove; 215 | 216 | function save(files) { 217 | Upload.upload({ 218 | url: '/addVuln', 219 | arrayKey: '', 220 | data: { 221 | "projectID" : $scope.vul.projectID, 222 | "vulName" : $scope.vul.vulName, 223 | "appType" : $scope.vul.appType, 224 | "owaspName" : $scope.vul.owaspName, 225 | "vulDetail" : $scope.vul.vulDetail, 226 | "vulRecommend" : $scope.vul.vulRecommend, 227 | "risk" : $scope.vul.risk, 228 | "severity" : $scope.vul.severity, 229 | "cvscore" : $scope.vul.cvscore, 230 | "cvtext" : $scope.vul.cvtext, 231 | "probability" : $scope.vul.probability, 232 | "remeffort" : $scope.vul.remeffort, 233 | "vector" : $scope.vul.vector, 234 | "occurrences" : $scope.vul.occurrences, 235 | "affcomp" : $scope.vul.affcomp, 236 | "retest" : $scope.vul.retest, 237 | "other" : $scope.vul.other, 238 | "proofExploit": files 239 | } 240 | }).then(function (response) { 241 | if(response.data.status == 'True'){ 242 | Notify.alert('Vulnerability Added Successful', { status: 'success' }); 243 | } 244 | $scope.vul.vulID = response.data.vid; 245 | grid.data.push($scope.vul); 246 | $uibModalInstance.close(row.entity); 247 | }, function (response) { 248 | 249 | }, function (evt) { 250 | 251 | }); 252 | } 253 | 254 | function update(files) { 255 | Upload.upload({ 256 | url: '/editVuln', 257 | arrayKey: '', 258 | data: { 259 | "id": $scope.vul.vulID, 260 | "projectID" : $scope.vul.projectID, 261 | "vulName" : $scope.vul.vulName, 262 | "appType" : $scope.vul.appType, 263 | "owaspName" : $scope.vul.owaspName, 264 | "vulDetail" : $scope.vul.vulDetail, 265 | "vulRecommend" : $scope.vul.vulRecommend, 266 | "risk" : $scope.vul.risk, 267 | "severity" : $scope.vul.severity, 268 | "cvscore" : $scope.vul.cvscore, 269 | "cvtext" : $scope.vul.cvtext, 270 | "probability" : $scope.vul.probability, 271 | "remeffort" : $scope.vul.remeffort, 272 | "vector" : $scope.vul.vector, 273 | "occurrences" : $scope.vul.occurrences, 274 | "affcomp" : $scope.vul.affcomp, 275 | "retest" : $scope.vul.retest, 276 | "other" : $scope.vul.other, 277 | "proofExploit": files 278 | } 279 | }).then(function (response) { 280 | if(response.data.status == 'True'){ 281 | Notify.alert('Vulnerability Update Successful', { status: 'success' }); 282 | } 283 | 284 | row.entity.vulName = $scope.vul.vulName; 285 | row.entity.owaspName = $scope.vul.owaspName; 286 | row.entity.vulDetail = $scope.vul.vulDetail; 287 | row.entity.vulRecommend = $scope.vul.vulRecommend; 288 | row.entity.risk = $scope.vul.risk; 289 | row.entity.severity = $scope.vul.severity; 290 | row.entity.cvscore = $scope.vul.cvscore; 291 | row.entity.cvtext = $scope.vul.cvtext; 292 | row.entity.probability = $scope.vul.probability; 293 | row.entity.remeffort = $scope.vul.remeffort; 294 | row.entity.vector = $scope.vul.vector; 295 | row.entity.occurrences = $scope.vul.occurrences; 296 | row.entity.affcomp = $scope.vul.affcomp; 297 | row.entity.retest = $scope.vul.retest; 298 | row.entity.other = $scope.vul.other; 299 | $uibModalInstance.close(row.entity); 300 | }, function (response) { 301 | 302 | }, function (evt) { 303 | 304 | }); 305 | } 306 | 307 | function remove() { 308 | var temp = { 309 | "id": vm.entity.vulID 310 | } 311 | $http.post('/deleteVuln', temp).then(function (response) { 312 | if(response.data.status == 'True'){ 313 | Notify.alert('Vulnerability Deleted Successfully', { status: 'success' }); 314 | } 315 | $state.go($state.current, {}, { 316 | reload: true 317 | }); 318 | $uibModalInstance.close(row.entity); 319 | }); 320 | } 321 | $scope.removeImage = function(image, index){ 322 | temp = { 323 | "path": image 324 | } 325 | $http.post('/deleteProof', temp).then(function (response) { 326 | if(response.data.status == 'True'){ 327 | $scope.vul.vulimgpath.splice(index, 1); 328 | 329 | Notify.alert('Image Removed Successful', { status: 'success' }); 330 | 331 | } 332 | 333 | }); 334 | } 335 | }]); 336 | })(); -------------------------------------------------------------------------------- /public/vendor/angularjs-toaster/toaster.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Toastr 3 | * Version 2.0.1 4 | * Copyright 2012 John Papa and Hans Fjallemark. 5 | * All Rights Reserved. 6 | * Use, reproduction, distribution, and modification of this code is subject to the terms and 7 | * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php 8 | * 9 | * Author: John Papa and Hans Fjallemark 10 | * Project: https://github.com/CodeSeven/toastr 11 | */ 12 | .toast-title { 13 | font-weight: bold; 14 | } 15 | .toast-message { 16 | -ms-word-wrap: break-word; 17 | word-wrap: break-word; 18 | } 19 | .toast-message a, 20 | .toast-message label { 21 | color: #ffffff; 22 | } 23 | .toast-message a:hover { 24 | color: #cccccc; 25 | text-decoration: none; 26 | } 27 | 28 | .toast-close-button { 29 | position: relative; 30 | right: -0.3em; 31 | top: -0.3em; 32 | float: right; 33 | font-size: 20px; 34 | font-weight: bold; 35 | color: #ffffff; 36 | -webkit-text-shadow: 0 1px 0 #ffffff; 37 | text-shadow: 0 1px 0 #ffffff; 38 | opacity: 0.8; 39 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); 40 | filter: alpha(opacity=80); 41 | } 42 | .toast-close-button:hover, 43 | .toast-close-button:focus { 44 | color: #000000; 45 | text-decoration: none; 46 | cursor: pointer; 47 | opacity: 0.4; 48 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); 49 | filter: alpha(opacity=40); 50 | } 51 | 52 | /*Additional properties for button version 53 | iOS requires the button element instead of an anchor tag. 54 | If you want the anchor version, it requires `href="#"`.*/ 55 | button.toast-close-button { 56 | padding: 0; 57 | cursor: pointer; 58 | background: transparent; 59 | border: 0; 60 | -webkit-appearance: none; 61 | } 62 | .toast-top-full-width { 63 | top: 0; 64 | right: 0; 65 | width: 100%; 66 | } 67 | .toast-bottom-full-width { 68 | bottom: 0; 69 | right: 0; 70 | width: 100%; 71 | } 72 | .toast-top-left { 73 | top: 12px; 74 | left: 12px; 75 | } 76 | .toast-top-center { 77 | top: 12px; 78 | } 79 | .toast-top-right { 80 | top: 12px; 81 | right: 12px; 82 | } 83 | .toast-bottom-right { 84 | right: 12px; 85 | bottom: 12px; 86 | } 87 | .toast-bottom-center { 88 | bottom: 12px; 89 | } 90 | .toast-bottom-left { 91 | bottom: 12px; 92 | left: 12px; 93 | } 94 | .toast-center { 95 | top: 45%; 96 | } 97 | #toast-container { 98 | position: fixed; 99 | z-index: 999999; 100 | pointer-events: auto; 101 | /*overrides*/ 102 | 103 | } 104 | #toast-container.toast-center, 105 | #toast-container.toast-top-center, 106 | #toast-container.toast-bottom-center{ 107 | width: 100%; 108 | pointer-events: none; 109 | } 110 | #toast-container.toast-center > div, 111 | #toast-container.toast-top-center > div, 112 | #toast-container.toast-bottom-center > div{ 113 | margin: auto; 114 | pointer-events: auto; 115 | } 116 | #toast-container.toast-center > button, 117 | #toast-container.toast-top-center > button, 118 | #toast-container.toast-bottom-center > button{ 119 | pointer-events: auto; 120 | } 121 | #toast-container * { 122 | -moz-box-sizing: border-box; 123 | -webkit-box-sizing: border-box; 124 | box-sizing: border-box; 125 | } 126 | #toast-container > div { 127 | margin: 0 0 6px; 128 | padding: 15px 15px 15px 50px; 129 | width: 300px; 130 | -moz-border-radius: 3px 3px 3px 3px; 131 | -webkit-border-radius: 3px 3px 3px 3px; 132 | border-radius: 3px 3px 3px 3px; 133 | background-position: 15px center; 134 | background-repeat: no-repeat; 135 | -moz-box-shadow: 0 0 12px #999999; 136 | -webkit-box-shadow: 0 0 12px #999999; 137 | box-shadow: 0 0 12px #999999; 138 | color: #ffffff; 139 | opacity: 0.8; 140 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); 141 | filter: alpha(opacity=80); 142 | } 143 | #toast-container > :hover { 144 | -moz-box-shadow: 0 0 12px #000000; 145 | -webkit-box-shadow: 0 0 12px #000000; 146 | box-shadow: 0 0 12px #000000; 147 | opacity: 1; 148 | -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); 149 | filter: alpha(opacity=100); 150 | cursor: pointer; 151 | } 152 | #toast-container > .toast-info { 153 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important; 154 | } 155 | #toast-container > .toast-wait { 156 | background-image: url("data:image/gif;base64,R0lGODlhIAAgAIQAAAQCBISGhMzKzERCROTm5CQiJKyurHx+fPz+/ExOTOzu7Dw+PIyOjCwqLFRWVAwKDIyKjMzOzOzq7CQmJLy6vFRSVPTy9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCQAXACwAAAAAIAAgAAAF3eAljmRpnmh6VRSVqLDpIDTixOdUlFSNUDhSQUAT7ES9GnD0SFQAKWItMqr4bqKHVPDI+WiTkaOFFVlrFe83rDrT0qeIjwrT0iLdU0GOiBxhAA4VeSk6QYeIOAsQEAuJKgw+EI8nA18IA48JBAQvFxCXDI8SNAQikV+iiaQIpheWX5mJmxKeF6g0qpQmA4yOu8C7EwYWCgZswRcTFj4KyMAGlwYxDwcHhCXMXxYxBzQHKNo+3DDeCOAn0V/TddbYJA0K48gAEAFQicMWFsfwNA3JSgAIAAFfwIMIL4QAACH5BAkJABoALAAAAAAgACAAhAQCBIyKjERCRMzOzCQiJPTy9DQyNGRmZMTCxOTm5CwqLHx+fBQWFJyenNTW1Pz6/Dw6PGxubAwKDIyOjNTS1CQmJCwuLPz+/Dw+PHRydAAAAAAAAAAAAAAAAAAAAAAAAAXboCaOZGmeaKoxWcSosMkk15W8cZ7VdZaXkcEgQtrxfD9RhHchima1GwlCGUBSFCaFxMrgRtnLFhWujWHhs2nJc8KoVlWGQnEn7/i8XgOwWAB7JwoONQ4KgSQAZRcOgHgSCwsSIhZMNRZ5CzULIgaWF5h4mhecfIQ8jXmQkiODhYeIiRYGjrG2PxgBARi3IhNMAbcCnwI5BAQpAZ8TIwK6vCQVDwUVKL+WzAANTA210g/VJ8OWxQefByQE4dZMzBoInwh4zrtgn2p725YNthUFTNRuGYB3AYGBHCEAACH5BAkJAB0ALAAAAAAgACAAhAQCBISChFRWVMzKzCQiJOTm5GxqbCwuLJSWlPz6/NTW1AwODJSSlGRmZCwqLOzu7HR2dDQ2NAQGBISGhFxaXNTS1CQmJOzq7GxubDQyNKSmpPz+/Nza3AAAAAAAAAAAAAXfYCeOZGmeaKqurHBdAiuP17Zdc0lMAVHWt9yI8LA9fCPB4xEjARoNSWpis01kBpshFahurqzsZosiGpErScMAUO0maKF8Tq/bTQCIQgFp30cQXhB1BHEcXhx0FgkJFiOHVYlzi42AgoRxeRx8fn+en3UABwedKgsBAwMBCygOCjYKDisLFV4VrCUAtVUKpSZdXl8mB8EbByQWcQPFAyYZxccdB7sV0cvBzbmvvG0LBV4FrFTBYCWuNhyyHRTFFB20trh4BxmdYl4YIqepq0IRxRE+IfDCAFQHARo0NGERAgAh+QQJCQAgACwAAAAAIAAgAIUEAgSEgoRMTkzMyswcHhzk5uR0cnQUFhRcXlwsKiz09vQMCgyMiozU1tQkJiR8fnxkZmT8/vwEBgSEhoRcWlzU0tQkIiT08vR0dnQcGhxkYmQ0MjT8+vwMDgyMjozc2twAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG+UCQcEgsGo/IpHLJXDweC6Z0+IhEHlOjRGIMWLHZoUZx0RQlAajxkFFKFFYFl5m5KNpIySU+X2bIBEoQZBBZGQdMElFhjI2Oj5AgHQEDAw8dQxYeDBaNHRVWVhWYCXsRFwmMXqFWEyAerB6MA6xWA6+xs7URt6VWqIwTu64gDh4eDp6goaORQ5OVAZjO1EgEGhB4RwAYDQ0YAEwIcBEKFEgYrBhLBORxgUYfrB9LELuF8fNDAAaVBuEg7NXCVyRdqHVCGLBiIIQAB1Yc4BXh9uEbwAXuyi2iQI7DuSwHdiFqCEGDtizLRFUDsaGAlQIbVoJYIEDAIiZBAAAh+QQJCQAbACwAAAAAIAAgAIQEAgSMioxcWlz08vQcHhysqqwMDgx8enwsKiykoqRkZmT8+vzEwsQMCgyUlpQkJiS0srQEBgSMjoxcXlz09vQkIiSsrqwUEhQ0MjRsamz8/vwAAAAAAAAAAAAAAAAAAAAF7+AmjmRpnmiqruz2PG0sIssCj4CQJAIgj4/abRNJaI6agu9kCAQaphdJgEQKUIFjgGWsahJYLdf7RTWfLKr3+jsBClVlG5Xb9eb4fImgUBBKDVB4ExRHFGwbGRQLGXMEhUgUfw2QC4IyCmSNDQtHlm2ZXgoiGQsUjW0EnUgLfyKBeYSeiHojfH61uS0GBisVEgEVLRcWRxAXKAgDRwMILMVIECgSVRIrBmS9JtRI1iMVBweuGxerSNolyszOIhjLGs0jEFXSKA8SEkMbcEgWIxfzNBxrw6AKgxIGkM05UOWALhERHJhysOThBgAVWYQAACH5BAkJABkALAAAAAAgACAAhAQGBIyKjERCRMzOzCwuLGRiZPz6/OTm5AwODLSytFRSVNTW1Dw6PHx6fAwKDJSSlERGRNTS1DQyNGxqbPz+/BQSFLy6vFRWVNza3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAXqYCaO5FgFwxBUZeu61ULNFMa+eBvQdJD/owFvFhkBBAwHsBQZUooZyWF2YOQkBNJu6ANMaQeli0AxSEwymi0DcUJeEgPlbEJFAghRe/h+Eeg/Dl9UYks5DF9VhksOAgKFi5GSSwh5kzgVCXIJNxknD5aSCTwJIw8zD5MITpanFKmSCHI8NxUPoJejNKWXLZkznL0vCJ3CxsckDpA/ChYJFzkTBgYTSxc80C4OswbLLhY8Fi/bMwYAJVgl4DTiL9LUJADrFuci1zTZLwD1IwU8BSQuWLCQb1EDHg2QiSDALYvCDAISJLDy8FIIACH5BAkJAB4ALAAAAAAgACAAhAQGBISGhFRSVNTW1CQiJKyqrGRmZOzu7CwuLIyOjGxubPz6/BQSFGRiZOTi5CwqLLy6vDQ2NIyKjFRWVCQmJKyurGxqbPT29DQyNJSSlHRydPz+/BQWFOzq7AAAAAAAAAXhoCeOJElYClGubOs117YtjWuvxCLLi3qbhc6h4FPsdorfiNI5dige43GT9AAkHUcCwCpMNxVP7tgTJY4J1uF7EBl0M8Ooueuo2SOCIkVa11kVX2E2EmgsFH4yBz4uAAkdHVstBAUHQ4xKmZqbnJ2bAhAQAiURGJ4eE0cTIxgzpp0QRxCsrp6xO7MjpaepO6unKxOhv8DFxsfIJBwaChw2DAkZDEocDjIOzi0ZMhlKUjIaLtsb3T8aR+EtDBkJ0yQUBQVQI9XX2ZsDMgMlyxr3mzE2XEgmotCGAARFIHiQ0FMIACH5BAkJABgALAAAAAAgACAAhAQCBISGhDw+POTi5CwuLLS2tPTy9BQSFJyenGRiZDQ2NIyOjLy+vPz6/BweHIyKjFRSVOzq7DQyNLy6vBQWFHRydDw6PPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXICaOZHkcZaquIjVd10SxtFrAcFGrVhBYIwoON9uNAsOA6DCEFTEKBEKxEjQvAtELNxkpGrAGNfW4Plpb2QgxRKjKzfPoVGLj3CnLNUv7hscpSDhKOxJSgDwPP0ZGAACMjAQFDQYFBJA0BAZDBpeYGBQVFUU3TV2YFAMwAzNgTQ2PkBVDFRiuQ7CYszi1pUOnkKmrM5qcnqiiTwQTDQ2Wn9DR0tPUfRKQEBEREDQSFw3XRhEwEd3f4TvjF+XWKgJ8JNnb0QkwCdUlCzAL+CQODAwc9BtIMAQAOw==") !important; 157 | } 158 | #toast-container > .toast-error { 159 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; 160 | } 161 | #toast-container > .toast-success { 162 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important; 163 | } 164 | #toast-container > .toast-warning { 165 | background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important; 166 | } 167 | #toast-container.toast-top-full-width > div, 168 | #toast-container.toast-bottom-full-width > div { 169 | width: 96%; 170 | margin: auto; 171 | } 172 | .toast { 173 | background-color: #030303; 174 | } 175 | .toast-success { 176 | background-color: #51a351; 177 | } 178 | .toast-error { 179 | background-color: #bd362f; 180 | } 181 | .toast-info { 182 | background-color: #2f96b4; 183 | } 184 | .toast-wait { 185 | background-color: #2f96b4; 186 | } 187 | .toast-warning { 188 | background-color: #f89406; 189 | } 190 | /*Responsive Design*/ 191 | @media all and (max-width: 240px) { 192 | #toast-container > div { 193 | padding: 8px 8px 8px 50px; 194 | width: 11em; 195 | } 196 | #toast-container .toast-close-button { 197 | right: -0.2em; 198 | top: -0.2em; 199 | } 200 | } 201 | @media all and (min-width: 241px) and (max-width: 480px) { 202 | #toast-container > div { 203 | padding: 8px 8px 8px 50px; 204 | width: 18em; 205 | } 206 | #toast-container .toast-close-button { 207 | right: -0.2em; 208 | top: -0.2em; 209 | } 210 | } 211 | @media all and (min-width: 481px) and (max-width: 768px) { 212 | #toast-container > div { 213 | padding: 15px 15px 15px 50px; 214 | width: 25em; 215 | } 216 | } 217 | 218 | /* 219 | * AngularJS-Toaster 220 | * Version 0.3 221 | */ 222 | :not(.no-enter)#toast-container > div.ng-enter, 223 | :not(.no-leave)#toast-container > div.ng-leave 224 | { 225 | -webkit-transition: 1000ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all; 226 | -moz-transition: 1000ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all; 227 | -ms-transition: 1000ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all; 228 | -o-transition: 1000ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all; 229 | transition: 1000ms cubic-bezier(0.250, 0.250, 0.750, 0.750) all; 230 | } 231 | 232 | :not(.no-enter)#toast-container > div.ng-enter.ng-enter-active, 233 | :not(.no-leave)#toast-container > div.ng-leave { 234 | opacity: 0.8; 235 | } 236 | 237 | :not(.no-leave)#toast-container > div.ng-leave.ng-leave-active, 238 | :not(.no-enter)#toast-container > div.ng-enter { 239 | opacity: 0; 240 | } -------------------------------------------------------------------------------- /public/vendor/Flot/jquery.flot.time.js: -------------------------------------------------------------------------------- 1 | /* Pretty handling of time axes. 2 | 3 | Copyright (c) 2007-2014 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | Set axis.mode to "time" to enable. See the section "Time series data" in 7 | API.txt for details. 8 | 9 | */ 10 | 11 | (function($) { 12 | 13 | var options = { 14 | xaxis: { 15 | timezone: null, // "browser" for local to the client or timezone for timezone-js 16 | timeformat: null, // format string to use 17 | twelveHourClock: false, // 12 or 24 time in time mode 18 | monthNames: null // list of names of months 19 | } 20 | }; 21 | 22 | // round to nearby lower multiple of base 23 | 24 | function floorInBase(n, base) { 25 | return base * Math.floor(n / base); 26 | } 27 | 28 | // Returns a string with the date d formatted according to fmt. 29 | // A subset of the Open Group's strftime format is supported. 30 | 31 | function formatDate(d, fmt, monthNames, dayNames) { 32 | 33 | if (typeof d.strftime == "function") { 34 | return d.strftime(fmt); 35 | } 36 | 37 | var leftPad = function(n, pad) { 38 | n = "" + n; 39 | pad = "" + (pad == null ? "0" : pad); 40 | return n.length == 1 ? pad + n : n; 41 | }; 42 | 43 | var r = []; 44 | var escape = false; 45 | var hours = d.getHours(); 46 | var isAM = hours < 12; 47 | 48 | if (monthNames == null) { 49 | monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; 50 | } 51 | 52 | if (dayNames == null) { 53 | dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 54 | } 55 | 56 | var hours12; 57 | 58 | if (hours > 12) { 59 | hours12 = hours - 12; 60 | } else if (hours == 0) { 61 | hours12 = 12; 62 | } else { 63 | hours12 = hours; 64 | } 65 | 66 | for (var i = 0; i < fmt.length; ++i) { 67 | 68 | var c = fmt.charAt(i); 69 | 70 | if (escape) { 71 | switch (c) { 72 | case 'a': c = "" + dayNames[d.getDay()]; break; 73 | case 'b': c = "" + monthNames[d.getMonth()]; break; 74 | case 'd': c = leftPad(d.getDate()); break; 75 | case 'e': c = leftPad(d.getDate(), " "); break; 76 | case 'h': // For back-compat with 0.7; remove in 1.0 77 | case 'H': c = leftPad(hours); break; 78 | case 'I': c = leftPad(hours12); break; 79 | case 'l': c = leftPad(hours12, " "); break; 80 | case 'm': c = leftPad(d.getMonth() + 1); break; 81 | case 'M': c = leftPad(d.getMinutes()); break; 82 | // quarters not in Open Group's strftime specification 83 | case 'q': 84 | c = "" + (Math.floor(d.getMonth() / 3) + 1); break; 85 | case 'S': c = leftPad(d.getSeconds()); break; 86 | case 'y': c = leftPad(d.getFullYear() % 100); break; 87 | case 'Y': c = "" + d.getFullYear(); break; 88 | case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; 89 | case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; 90 | case 'w': c = "" + d.getDay(); break; 91 | } 92 | r.push(c); 93 | escape = false; 94 | } else { 95 | if (c == "%") { 96 | escape = true; 97 | } else { 98 | r.push(c); 99 | } 100 | } 101 | } 102 | 103 | return r.join(""); 104 | } 105 | 106 | // To have a consistent view of time-based data independent of which time 107 | // zone the client happens to be in we need a date-like object independent 108 | // of time zones. This is done through a wrapper that only calls the UTC 109 | // versions of the accessor methods. 110 | 111 | function makeUtcWrapper(d) { 112 | 113 | function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { 114 | sourceObj[sourceMethod] = function() { 115 | return targetObj[targetMethod].apply(targetObj, arguments); 116 | }; 117 | }; 118 | 119 | var utc = { 120 | date: d 121 | }; 122 | 123 | // support strftime, if found 124 | 125 | if (d.strftime != undefined) { 126 | addProxyMethod(utc, "strftime", d, "strftime"); 127 | } 128 | 129 | addProxyMethod(utc, "getTime", d, "getTime"); 130 | addProxyMethod(utc, "setTime", d, "setTime"); 131 | 132 | var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; 133 | 134 | for (var p = 0; p < props.length; p++) { 135 | addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); 136 | addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); 137 | } 138 | 139 | return utc; 140 | }; 141 | 142 | // select time zone strategy. This returns a date-like object tied to the 143 | // desired timezone 144 | 145 | function dateGenerator(ts, opts) { 146 | if (opts.timezone == "browser") { 147 | return new Date(ts); 148 | } else if (!opts.timezone || opts.timezone == "utc") { 149 | return makeUtcWrapper(new Date(ts)); 150 | } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { 151 | var d = new timezoneJS.Date(); 152 | // timezone-js is fickle, so be sure to set the time zone before 153 | // setting the time. 154 | d.setTimezone(opts.timezone); 155 | d.setTime(ts); 156 | return d; 157 | } else { 158 | return makeUtcWrapper(new Date(ts)); 159 | } 160 | } 161 | 162 | // map of app. size of time units in milliseconds 163 | 164 | var timeUnitSize = { 165 | "second": 1000, 166 | "minute": 60 * 1000, 167 | "hour": 60 * 60 * 1000, 168 | "day": 24 * 60 * 60 * 1000, 169 | "month": 30 * 24 * 60 * 60 * 1000, 170 | "quarter": 3 * 30 * 24 * 60 * 60 * 1000, 171 | "year": 365.2425 * 24 * 60 * 60 * 1000 172 | }; 173 | 174 | // the allowed tick sizes, after 1 year we use 175 | // an integer algorithm 176 | 177 | var baseSpec = [ 178 | [1, "second"], [2, "second"], [5, "second"], [10, "second"], 179 | [30, "second"], 180 | [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], 181 | [30, "minute"], 182 | [1, "hour"], [2, "hour"], [4, "hour"], 183 | [8, "hour"], [12, "hour"], 184 | [1, "day"], [2, "day"], [3, "day"], 185 | [0.25, "month"], [0.5, "month"], [1, "month"], 186 | [2, "month"] 187 | ]; 188 | 189 | // we don't know which variant(s) we'll need yet, but generating both is 190 | // cheap 191 | 192 | var specMonths = baseSpec.concat([[3, "month"], [6, "month"], 193 | [1, "year"]]); 194 | var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], 195 | [1, "year"]]); 196 | 197 | function init(plot) { 198 | plot.hooks.processOptions.push(function (plot, options) { 199 | $.each(plot.getAxes(), function(axisName, axis) { 200 | 201 | var opts = axis.options; 202 | 203 | if (opts.mode == "time") { 204 | axis.tickGenerator = function(axis) { 205 | 206 | var ticks = []; 207 | var d = dateGenerator(axis.min, opts); 208 | var minSize = 0; 209 | 210 | // make quarter use a possibility if quarters are 211 | // mentioned in either of these options 212 | 213 | var spec = (opts.tickSize && opts.tickSize[1] === 214 | "quarter") || 215 | (opts.minTickSize && opts.minTickSize[1] === 216 | "quarter") ? specQuarters : specMonths; 217 | 218 | if (opts.minTickSize != null) { 219 | if (typeof opts.tickSize == "number") { 220 | minSize = opts.tickSize; 221 | } else { 222 | minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; 223 | } 224 | } 225 | 226 | for (var i = 0; i < spec.length - 1; ++i) { 227 | if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] 228 | + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 229 | && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { 230 | break; 231 | } 232 | } 233 | 234 | var size = spec[i][0]; 235 | var unit = spec[i][1]; 236 | 237 | // special-case the possibility of several years 238 | 239 | if (unit == "year") { 240 | 241 | // if given a minTickSize in years, just use it, 242 | // ensuring that it's an integer 243 | 244 | if (opts.minTickSize != null && opts.minTickSize[1] == "year") { 245 | size = Math.floor(opts.minTickSize[0]); 246 | } else { 247 | 248 | var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); 249 | var norm = (axis.delta / timeUnitSize.year) / magn; 250 | 251 | if (norm < 1.5) { 252 | size = 1; 253 | } else if (norm < 3) { 254 | size = 2; 255 | } else if (norm < 7.5) { 256 | size = 5; 257 | } else { 258 | size = 10; 259 | } 260 | 261 | size *= magn; 262 | } 263 | 264 | // minimum size for years is 1 265 | 266 | if (size < 1) { 267 | size = 1; 268 | } 269 | } 270 | 271 | axis.tickSize = opts.tickSize || [size, unit]; 272 | var tickSize = axis.tickSize[0]; 273 | unit = axis.tickSize[1]; 274 | 275 | var step = tickSize * timeUnitSize[unit]; 276 | 277 | if (unit == "second") { 278 | d.setSeconds(floorInBase(d.getSeconds(), tickSize)); 279 | } else if (unit == "minute") { 280 | d.setMinutes(floorInBase(d.getMinutes(), tickSize)); 281 | } else if (unit == "hour") { 282 | d.setHours(floorInBase(d.getHours(), tickSize)); 283 | } else if (unit == "month") { 284 | d.setMonth(floorInBase(d.getMonth(), tickSize)); 285 | } else if (unit == "quarter") { 286 | d.setMonth(3 * floorInBase(d.getMonth() / 3, 287 | tickSize)); 288 | } else if (unit == "year") { 289 | d.setFullYear(floorInBase(d.getFullYear(), tickSize)); 290 | } 291 | 292 | // reset smaller components 293 | 294 | d.setMilliseconds(0); 295 | 296 | if (step >= timeUnitSize.minute) { 297 | d.setSeconds(0); 298 | } 299 | if (step >= timeUnitSize.hour) { 300 | d.setMinutes(0); 301 | } 302 | if (step >= timeUnitSize.day) { 303 | d.setHours(0); 304 | } 305 | if (step >= timeUnitSize.day * 4) { 306 | d.setDate(1); 307 | } 308 | if (step >= timeUnitSize.month * 2) { 309 | d.setMonth(floorInBase(d.getMonth(), 3)); 310 | } 311 | if (step >= timeUnitSize.quarter * 2) { 312 | d.setMonth(floorInBase(d.getMonth(), 6)); 313 | } 314 | if (step >= timeUnitSize.year) { 315 | d.setMonth(0); 316 | } 317 | 318 | var carry = 0; 319 | var v = Number.NaN; 320 | var prev; 321 | 322 | do { 323 | 324 | prev = v; 325 | v = d.getTime(); 326 | ticks.push(v); 327 | 328 | if (unit == "month" || unit == "quarter") { 329 | if (tickSize < 1) { 330 | 331 | // a bit complicated - we'll divide the 332 | // month/quarter up but we need to take 333 | // care of fractions so we don't end up in 334 | // the middle of a day 335 | 336 | d.setDate(1); 337 | var start = d.getTime(); 338 | d.setMonth(d.getMonth() + 339 | (unit == "quarter" ? 3 : 1)); 340 | var end = d.getTime(); 341 | d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); 342 | carry = d.getHours(); 343 | d.setHours(0); 344 | } else { 345 | d.setMonth(d.getMonth() + 346 | tickSize * (unit == "quarter" ? 3 : 1)); 347 | } 348 | } else if (unit == "year") { 349 | d.setFullYear(d.getFullYear() + tickSize); 350 | } else { 351 | d.setTime(v + step); 352 | } 353 | } while (v < axis.max && v != prev); 354 | 355 | return ticks; 356 | }; 357 | 358 | axis.tickFormatter = function (v, axis) { 359 | 360 | var d = dateGenerator(v, axis.options); 361 | 362 | // first check global format 363 | 364 | if (opts.timeformat != null) { 365 | return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); 366 | } 367 | 368 | // possibly use quarters if quarters are mentioned in 369 | // any of these places 370 | 371 | var useQuarters = (axis.options.tickSize && 372 | axis.options.tickSize[1] == "quarter") || 373 | (axis.options.minTickSize && 374 | axis.options.minTickSize[1] == "quarter"); 375 | 376 | var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; 377 | var span = axis.max - axis.min; 378 | var suffix = (opts.twelveHourClock) ? " %p" : ""; 379 | var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; 380 | var fmt; 381 | 382 | if (t < timeUnitSize.minute) { 383 | fmt = hourCode + ":%M:%S" + suffix; 384 | } else if (t < timeUnitSize.day) { 385 | if (span < 2 * timeUnitSize.day) { 386 | fmt = hourCode + ":%M" + suffix; 387 | } else { 388 | fmt = "%b %d " + hourCode + ":%M" + suffix; 389 | } 390 | } else if (t < timeUnitSize.month) { 391 | fmt = "%b %d"; 392 | } else if ((useQuarters && t < timeUnitSize.quarter) || 393 | (!useQuarters && t < timeUnitSize.year)) { 394 | if (span < timeUnitSize.year) { 395 | fmt = "%b"; 396 | } else { 397 | fmt = "%b %Y"; 398 | } 399 | } else if (useQuarters && t < timeUnitSize.year) { 400 | if (span < timeUnitSize.year) { 401 | fmt = "Q%q"; 402 | } else { 403 | fmt = "Q%q %Y"; 404 | } 405 | } else { 406 | fmt = "%Y"; 407 | } 408 | 409 | var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); 410 | 411 | return rt; 412 | }; 413 | } 414 | }); 415 | }); 416 | } 417 | 418 | $.plot.plugins.push({ 419 | init: init, 420 | options: options, 421 | name: 'time', 422 | version: '1.0' 423 | }); 424 | 425 | // Time-axis support used to be in Flot core, which exposed the 426 | // formatDate function on the plot object. Various plugins depend 427 | // on the function, so we need to re-expose it here. 428 | 429 | $.plot.formatDate = formatDate; 430 | $.plot.dateGenerator = dateGenerator; 431 | 432 | })(jQuery); 433 | --------------------------------------------------------------------------------