├── .gitattributes ├── .gitignore ├── README.md ├── README_Linux.md ├── acServerManager.bat ├── frontend ├── advanced.html ├── app │ ├── angular-toggle-switch.js │ ├── app.js │ ├── controllers.js │ └── services.js ├── css │ ├── angular-toggle-switch-bootstrap-3.css │ ├── animate.min.css │ ├── bootstrap.min.css │ ├── light-bootstrap-dashboard.css │ ├── pe-icon-7-stroke.css │ └── style.css ├── entrylist.html ├── fonts │ ├── Pe-icon-7-stroke.eot │ ├── Pe-icon-7-stroke.svg │ ├── Pe-icon-7-stroke.ttf │ ├── Pe-icon-7-stroke.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── help.html ├── img │ ├── ajax-loader.gif │ ├── favicon.ico │ ├── sidebar-1.jpg │ ├── sidebar-2.jpg │ ├── sidebar-3.jpg │ ├── sidebar-4.jpg │ └── sidebar-5.jpg ├── index.html ├── js │ ├── angular │ │ ├── angular-resource.min.js │ │ ├── angular-resource.min.js.map │ │ ├── angular.js │ │ ├── angular.min.js │ │ ├── angular.min.js.map │ │ ├── show-errors.min.js │ │ └── ui-bootstrap-tpls-0.13.0.min.js │ ├── bootstrap-checkbox-radio-switch.js │ ├── bootstrap-notify.js │ ├── bootstrap-select.js │ ├── bootstrap-switch.js │ ├── bootstrap.min.js │ ├── chartist.min.js │ ├── jquery-1.10.2.js │ ├── light-bootstrap-dashboard.js │ └── npm.js ├── rules.html ├── sass │ ├── lbd │ │ ├── _alerts.scss │ │ ├── _buttons.scss │ │ ├── _cards.scss │ │ ├── _chartist.scss │ │ ├── _checkbox-radio-switch.scss │ │ ├── _dropdown.scss │ │ ├── _footers.scss │ │ ├── _inputs.scss │ │ ├── _misc.scss │ │ ├── _mixins.scss │ │ ├── _navbars.scss │ │ ├── _responsive.scss │ │ ├── _sidebar-and-main-panel.scss │ │ ├── _tables.scss │ │ ├── _typography.scss │ │ ├── _variables.scss │ │ └── mixins │ │ │ ├── _buttons.scss │ │ │ ├── _cards.scss │ │ │ ├── _chartist.scss │ │ │ ├── _icons.scss │ │ │ ├── _inputs.scss │ │ │ ├── _labels.scss │ │ │ ├── _morphing-buttons.scss │ │ │ ├── _navbars.scss │ │ │ ├── _social-buttons.scss │ │ │ ├── _tabs.scss │ │ │ ├── _transparency.scss │ │ │ └── _vendor-prefixes.scss │ └── light-bootstrap-dashboard.scss └── server.html ├── logs └── readme.txt ├── package.json ├── server.js ├── settings.js └── start.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Declare files that will always have CRLF line endings on checkout. 5 | *.html text eol=crlf 6 | *.js text eol=crlf 7 | *.css text eol=crlf 8 | 9 | # Denote all files that are truly binary and should not be modified. 10 | *.png binary 11 | *.jpg binary 12 | *.ico binary 13 | *.gif binary 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ACServerManager 2 | Web based server manager for Assetto Corsa directly manipulating the ini files on the server as an alternative to the windows app and having to copy files to your server. 3 | 4 | Start and stop the server, and stracker directly from the application, meaning you can make changes to the server configuration and restart the server directly from your browser or mobile phone. 5 | 6 | ## ACServerManager on Windows 7 | This is the installation guide for a Windows machine, to review the Linux installation guide go [here](https://github.com/jo3stevens/ACServerManager/blob/master/README_Linux.md). 8 | 9 | ## Updates 10 | 27/01/2017: 11 | * Update to UI layout 12 | * Added restart feature for AC & sTracker server 13 | 14 | 17/10/2015: 15 | * Bug fix when switching between two tracks with multiple track configs 16 | * Added Max Ballast and UDP Plugin fields to Advanced page 17 | * Added new setting for contentPath allowing server and content folders to be seperated (this happens when using a manager package from the kunos tool). If this setting it left empty it will assume the content folder is inside the server folder 18 | 19 | 22/08/2015: 20 | * Finished adding all the new settings from 1.2 including tyres and weather 21 | 22 | ## Prep 23 | NOTE: If you've been using the new windows server manager that came with 1.2 then you may not need this step as when you package the server files it does the same thing. 24 | 25 | The application needs some additional files added to the server/content/tracks and server/content/cars folders to be able to choose track configurations and car skins. 26 | 27 | Copy acServerManager.bat to your root aessettocorsa folder and run it to copy the required folders into server/content/*. You'll then need to copy the content folder to your server. 28 | 29 | For tracks it will copy the ui folder which will contain sub folders when there are multiple track configurations. It will also copy the contents of these directories which contains additional track information which is displayed when choosing a track. 30 | 31 | For cars it will copy the skins/* folder structure but not the files; this is just to be able to choose the skin when setting up the entry list. 32 | 33 | ## Install Node.js 34 | To install Node.js, follow the installation guide on its home page [here](https://nodejs.org). 35 | 36 | ## Install ACServerManager 37 | Create a directory called 'acmanager', go into that directory and click [here](https://github.com/jo3stevens/ACServerManager/archive/master.zip) to download the latest version. Extract 38 | the contents of the zip file into the directory. 39 | 40 | ## ACServerManager Configuration 41 | To configure your manager's settings, open the 'settings.js' file. You'll see a number of variables, point the 'serverPath' 42 | to your Assetto Corsa Server directory. You can configure your username, password & port settings for ACServerManager, also 43 | if you use sTracker, point the 'sTrackerPath' variable to your installation. 44 | 45 | * serverPath: The path to your server folder containing acServer.exe 46 | * sTrackerPath: The path to your stracker folder container stracker.exe (If you don't run stracker just leave this as an empty string ('') to disable it 47 | * username/password: Set these values if you want basic authentication on the application 48 | * port: The port that the application will listen on (Be sure to open up this port on firewalls) 49 | 50 | Note: I've currently set the Assetto Corsa Server installation to one directory up in 'server', change if necessary. 51 | 52 | ## Firewall 53 | If your machine has a firewall enabled (i.e) windows firewall, you'll need to open / allow the ACServerManager port defined in your settings.js file. 54 | 55 | ## Running ACServerManager 56 | You first need to make sure you have the necessary Node.js dependencies, run the following command in the command prompt in the same directory as the 'server.js' file: 57 | ``` 58 | npm install 59 | ``` 60 | To run ACServerManager, execute the 'start.bat' file. If you see no errors, ACServerManager should now be running. 61 | 62 | ## Using ACServerManager 63 | * Browse to the application using your servers IP and the chosen port (or any DNS configured) 64 | * Click the 'Start' button under Assetto Corsa Server section 65 | * If using sTracker wait until the AC server has started and then click 'Start' in the sTracker Server section 66 | 67 | The server should now be running. You'll be able to see any server output in the command window and it will be logged to a file in the 'ACServerManager/log' folder. 68 | 69 | You can change any of settings and it will be applied directly to server_cfg.ini and entry_list.ini on the server. After making a change just stop and start the server from the Server Status page to apply the changes to Assetto Corsa Server. 70 | 71 | Note, the server may fail to start in some cases if the Assetto Corsa Server cannot connect to the master server. Make sure you portforward / open 72 | the necessary ports for the server to function correctly. 73 | 74 | ## Screenshots 75 | ### Server Status 76 | ![Server Status](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-1.JPG) 77 | 78 | ### Server Configuration 79 | ![Server Config](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-2.JPG) 80 | 81 | ### Entry List 82 | ![Entry List](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-3.JPG) 83 | 84 | ### Rules 85 | ![Rules](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-4.JPG) 86 | 87 | ### Advanced 88 | ![Advanced](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-5.JPG) 89 | -------------------------------------------------------------------------------- /README_Linux.md: -------------------------------------------------------------------------------- 1 | # ACServerManager 2 | Web based server manager for Assetto Corsa directly manipulating the ini files on the server as an alternative to the windows app and having to copy files to your server. 3 | 4 | Start and stop the server, and stracker directly from the application, meaning you can make changes to the server configuration and restart the server directly from your browser or mobile phone. 5 | 6 | ## ACServerManager on Linux 7 | This is the installation guide for a Linux machine, to review the Windows installation guide go [here](https://github.com/jo3stevens/ACServerManager/blob/master/README.md). 8 | 9 | ## Updates 10 | 27/01/2017: 11 | * Update to UI layout 12 | * Added restart feature for AC & sTracker server 13 | 14 | 17/10/2015: 15 | * Bug fix when switching between two tracks with multiple track configs 16 | * Added Max Ballast and UDP Plugin fields to Advanced page 17 | * Added new setting for contentPath allowing server and content folders to be seperated (this happens when using a manager package from the kunos tool). If this setting it left empty it will assume the content folder is inside the server folder 18 | 19 | 22/08/2015: 20 | * Finished adding all the new settings from 1.2 including tyres and weather 21 | 22 | ## Details 23 | First you'll need to install Node.js on your machine. It's best to use an application 24 | like [NVM](https://github.com/creationix/nvm) to manage the installation of Node.js on Linux based machines. 25 | After installing Node.js, install [PM2](https://github.com/Unitech/pm2) when using this 26 | version of AC Server Manager, it's basically Node.js application management tool with tons of features 27 | for production use. PM2 will make sure your web application stays online and, auto restarts if it crashes. 28 | 29 | ## Install NVM 30 | To install NVM, follow the installation guide on its GitHub page [here](https://github.com/creationix/nvm). Please install NVM on the same account you run your Assetto Corsa Server. 31 | 32 | ## Install Node.js 33 | Using NVM, run the following command to install the latest version: 34 | ``` 35 | nvm install node 36 | ``` 37 | If you would like to install a specific version using NVM then run something like this: 38 | ``` 39 | nvm install 6.9.4 40 | ``` 41 | ## Install PM2 42 | To install PM2, follow the installation guide on its GitHub page [here](https://github.com/Unitech/pm2). Please install PM2 on the same account you run your Assetto Corsa Server. 43 | 44 | ## Install ACServerManager 45 | Create a directory called 'acmanager', cd into that directory and run this command to download the latest version: 46 | ``` 47 | wget https://github.com/jo3stevens/ACServerManager/archive/master.zip 48 | ``` 49 | Unzip the file & clean up, by running: 50 | ``` 51 | unzip master.zip; mv ACServerManager-master/* .; rm -R ACServerManager-master; rm master.zip 52 | ``` 53 | You'll need to first configure your manager's settings before you can run the application. 54 | ## ACServerManager Configuration 55 | To configure your manager's settings, open the 'settings.js' file. You'll see a number of variables, point the 'serverPath' 56 | to your Assetto Corsa Server directory. You can configure your username, password & port settings for ACServerManager, also 57 | if you use sTracker, point the 'sTrackerPath' variable to your installation. 58 | 59 | * serverPath: The path to your server folder containing acServer.exe 60 | * sTrackerPath: The path to your stracker folder container stracker.exe (If you don't run stracker just leave this as an empty string ('') to disable it 61 | * username/password: Set these values if you want basic authentication on the application 62 | * port: The port that the application will listen on (Be sure to open up this port on firewalls) 63 | 64 | Note: I've currently set the Assetto Corsa Server installation to one directory up in 'server', change if necessary. 65 | 66 | ## Firewall 67 | If your machine has a firewall enabled (i.e) iptables, you'll need to open / allow the ACServerManager port defined in your settings.js file. 68 | 69 | ## Running ACServerManager 70 | You first need to make sure you have the necessary Node.js dependencies, run: 71 | ``` 72 | npm install 73 | ``` 74 | To run ACServerManager using PM2 run the following command: 75 | ``` 76 | pm2 start server.js 77 | ``` 78 | To monitor applications running with PM2 run: 79 | ``` 80 | pm2 list 81 | ``` 82 | There many useful commands to manage applications using PM2, reference their GitHub page. 83 | 84 | ## Using ACServerManager 85 | * Browse to the application using your servers IP and the chosen port (or any DNS configured) 86 | * Click the 'Start' button under Assetto Corsa Server section 87 | * If using sTracker wait until the AC server has started and then click 'Start' in the sTracker Server section 88 | 89 | The server should now be running. You'll be able to see any server output in the command window and it will be logged to a file in the 'ACServerManager/log' folder. 90 | 91 | You can change any of settings and it will be applied directly to server_cfg.ini and entry_list.ini on the server. After making a change just stop and start the server from the Server Status page to apply the changes to Assetto Corsa Server. 92 | 93 | Note, the server may fail to start in some cases if the Assetto Corsa Server cannot connect to the master server. Make sure you portforward / open 94 | the necessary ports for the server to function correctly. 95 | 96 | ## Screenshots 97 | ### Server Status 98 | ![Server Status](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-1.JPG) 99 | 100 | ### Server Configuration 101 | ![Server Config](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-2.JPG) 102 | 103 | ### Entry List 104 | ![Entry List](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-3.JPG) 105 | 106 | ### Rules 107 | ![Rules](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-4.JPG) 108 | 109 | ### Advanced 110 | ![Advanced](http://deltahosting.dyndns.org:8080/acmanager/screen-cap-5.JPG) 111 | -------------------------------------------------------------------------------- /acServerManager.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cls 3 | cd content/tracks 4 | FOR /D %%G in (*) DO ( 5 | echo Removing existing ui folder for %%G 6 | rmdir "%~dp0server\content\tracks\%%G\ui\" /s /q 7 | echo Creating ui folder for %%G 8 | mkdir "%~dp0server\content\tracks\%%G\ui" 9 | echo Copying ui folder for %%G 10 | xcopy /s /e /y %%G\ui "%~dp0server\content\tracks\%%G\ui" 11 | ) 12 | cd ../cars 13 | FOR /D %%G in (*) DO ( 14 | echo Removing skins folder for %%G 15 | rmdir "%~dp0server\content\cars\%%G\skins\" /s /q 16 | echo Creating skins folder for %%G 17 | mkdir "%~dp0server\content\cars\%%G\skins" 18 | echo Copying skins directory structure for %%G 19 | xcopy /t /e /y %%G\skins "%~dp0server\content\cars\%%G\skins" 20 | ) -------------------------------------------------------------------------------- /frontend/advanced.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Assetto Corsa Server Manager 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 |
32 | 79 | 80 |
81 | 97 | 98 |
99 |
100 |
101 | {{alert.msg}} 102 |
103 | 104 |
105 | Advanced Rules 106 |
107 |
108 |
109 | 110 | 111 |
112 |
113 | 114 |
115 |
116 | 117 | 118 |
119 |
120 | 121 |
122 |
123 | 124 | 125 |
126 |
127 |
128 | 129 |
130 |
131 |
132 | 133 | 134 |
135 |
136 | 137 |
138 |
139 | 140 | 145 |
146 |
147 | 148 |
149 |
150 | 151 | 152 |
153 |
154 |
155 | 156 |
157 |
158 |
159 | 160 | 161 |
162 |
163 | 164 |
165 |
168 |
169 |
170 | 171 |
172 | 173 |
174 | Plugin 175 |
176 |
177 |
178 | 179 | 180 |
181 |
182 | 183 |
184 |
185 | 186 | 187 |
188 |
189 | 190 |
191 |
192 | 193 | 194 |
195 |
196 |
197 |
198 | 199 |
200 |
201 | 202 |
203 |
204 |
205 |
206 |
207 | 208 | 234 |
235 |
236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /frontend/app/angular-toggle-switch.js: -------------------------------------------------------------------------------- 1 | angular.module('toggle-switch', ['ng']).directive('toggleSwitch', ['$compile', function($compile) { 2 | return { 3 | restrict: 'EA', 4 | replace: true, 5 | require:'ngModel', 6 | scope: { 7 | isDisabled: '=', 8 | onLabel: '@', 9 | offLabel: '@', 10 | knobLabel: '@', 11 | html: '=', 12 | onChange: '&' 13 | }, 14 | template: 15 | '
' + 16 | '
' + 17 | '' + 18 | '' + 19 | '' + 20 | '
' + 21 | '
', 22 | compile: function(element, attrs) { 23 | if (angular.isUndefined(attrs.onLabel)) { 24 | attrs.onLabel = 'Yes'; 25 | } 26 | if (angular.isUndefined(attrs.offLabel)) { 27 | attrs.offLabel = 'No'; 28 | } 29 | if (angular.isUndefined(attrs.knobLabel)) { 30 | attrs.knobLabel = '\u00a0'; 31 | } 32 | if (angular.isUndefined(attrs.isDisabled)) { 33 | attrs.isDisabled = false; 34 | } 35 | if (angular.isUndefined(attrs.html)) { 36 | attrs.html = false; 37 | } 38 | if (angular.isUndefined(attrs.tabindex)) { 39 | attrs.tabindex = 0; 40 | } 41 | 42 | return function postLink(scope, iElement, iAttrs, ngModel) { 43 | iElement.attr('tabindex', attrs.tabindex); 44 | 45 | scope.toggle = function toggle() { 46 | if (!scope.isDisabled) { 47 | scope.model = !scope.model; 48 | ngModel.$setViewValue(scope.model); 49 | scope.onChange(); 50 | } 51 | }; 52 | 53 | var spaceCharCode = 32; 54 | scope.onKeyPress = function onKeyPress($event) { 55 | if ($event.charCode == spaceCharCode && !$event.altKey && !$event.ctrlKey && !$event.metaKey) { 56 | scope.toggle(); 57 | $event.preventDefault(); 58 | } 59 | }; 60 | 61 | ngModel.$formatters.push(function(modelValue) { 62 | return modelValue; 63 | }); 64 | 65 | ngModel.$parsers.push(function(viewValue) { 66 | return viewValue; 67 | }); 68 | 69 | ngModel.$viewChangeListeners.push(function() { 70 | scope.$eval(attrs.ngChange); 71 | }); 72 | 73 | ngModel.$render = function() { 74 | scope.model = ngModel.$viewValue; 75 | }; 76 | 77 | var bindSpan = function(span, html) { 78 | span = angular.element(span); 79 | var bindAttributeName = (html === true) ? 'ng-bind-html' : 'ng-bind'; 80 | 81 | // remove old ng-bind attributes 82 | span.removeAttr('ng-bind-html'); 83 | span.removeAttr('ng-bind'); 84 | 85 | if (angular.element(span).hasClass("switch-left")) 86 | span.attr(bindAttributeName, 'onLabel'); 87 | if (span.hasClass("knob")) 88 | span.attr(bindAttributeName, 'knobLabel'); 89 | if (span.hasClass("switch-right")) 90 | span.attr(bindAttributeName, 'offLabel'); 91 | 92 | $compile(span)(scope, function(cloned, scope) { 93 | span.replaceWith(cloned); 94 | }); 95 | }; 96 | 97 | // add ng-bind attribute to each span element. 98 | // NOTE: you need angular-sanitize to use ng-bind-html 99 | var bindSwitch = function(iElement, html) { 100 | angular.forEach(iElement[0].children[0].children, function(span, index) { 101 | bindSpan(span, html); 102 | }); 103 | }; 104 | 105 | scope.$watch('html', function(newValue) { 106 | bindSwitch(iElement, newValue); 107 | }); 108 | }; 109 | } 110 | }; 111 | }]); 112 | -------------------------------------------------------------------------------- /frontend/app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular 4 | .module('acServerManager', ['acServerManager.services', 'ui.bootstrap', 'ui.bootstrap.showErrors', 'toggle-switch']) 5 | 6 | .directive('stringToNumber', function() { 7 | return { 8 | require: 'ngModel', 9 | link: function(scope, element, attrs, ngModel) { 10 | ngModel.$parsers.push(function(value) { 11 | return '' + value; 12 | }); 13 | ngModel.$formatters.push(function(value) { 14 | return parseFloat(value, 10); 15 | }); 16 | } 17 | }; 18 | }); -------------------------------------------------------------------------------- /frontend/app/services.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('acServerManager.services', ['ngResource']). 4 | factory('CarService', function($resource) { 5 | return { 6 | GetCars: function(callback) { 7 | var resource = $resource('/api/cars'); 8 | var result = resource.query(function() { 9 | callback(result); 10 | }); 11 | }, 12 | GetSkins: function(car, callback) { 13 | var resource = $resource('/api/cars/:car'); 14 | var result = resource.get({car: car}, function() { 15 | callback(result); 16 | }); 17 | } 18 | }; 19 | }). 20 | factory('TrackService', function($resource) { 21 | return { 22 | GetTracks: function(callback) { 23 | var resource = $resource('/api/tracks'); 24 | var result = resource.query(function() { 25 | callback(result); 26 | }); 27 | }, 28 | GetTrackDetails: function(track, config, callback) { 29 | if (config) { 30 | var resource = $resource('/api/tracks/:track/:config'); 31 | var result = resource.get({track: track, config: config}, function() { 32 | callback(result); 33 | }, function() { 34 | callback(null); 35 | }); 36 | } else { 37 | var resource = $resource('/api/tracks/:track'); 38 | var result = resource.get({track: track}, function() { 39 | callback(result); 40 | }, function() { 41 | callback(null); 42 | }); 43 | } 44 | } 45 | }; 46 | }). 47 | factory('ServerService', function($resource) { 48 | return { 49 | GetServerDetails: function(callback) { 50 | var resource = $resource('/api/server'); 51 | var result = resource.get(function() { 52 | callback(result); 53 | }); 54 | }, 55 | GetServerDetail: function(id, callback) { 56 | var resource = $resource('/api/server/:id'); 57 | var result = resource.get({id: id}, function() { 58 | callback(result); 59 | }); 60 | }, 61 | SaveServerDetails: function(data, callback) { 62 | var resource = $resource('/api/server'); 63 | var result = resource.save(data, function () { 64 | callback(result); 65 | }); 66 | }, 67 | GetServerStatus: function(callback) { 68 | var resource = $resource('/api/server/status'); 69 | var result = resource.get(function() { 70 | callback(result); 71 | }); 72 | }, 73 | }; 74 | }). 75 | factory('BookService', function($resource) { 76 | return { 77 | GetBookingDetails: function(callback) { 78 | var resource = $resource('/api/book'); 79 | var result = resource.get(function() { 80 | callback(result); 81 | }); 82 | }, 83 | SaveBookingDetails: function(data, callback) { 84 | var resource = $resource('/api/book'); 85 | var result = resource.save(data, function () { 86 | callback(result); 87 | }); 88 | } 89 | }; 90 | }). 91 | factory('PracticeService', function($resource) { 92 | return { 93 | GetPracticeDetails: function(callback) { 94 | var resource = $resource('/api/practice'); 95 | var result = resource.get(function() { 96 | callback(result); 97 | }); 98 | }, 99 | SavePracticeDetails: function(data, callback) { 100 | var resource = $resource('/api/practice'); 101 | var result = resource.save(data, function () { 102 | callback(result); 103 | }); 104 | } 105 | }; 106 | }). 107 | factory('QualifyService', function($resource) { 108 | return { 109 | GetQualifyDetails: function(callback) { 110 | var resource = $resource('/api/qualify'); 111 | var result = resource.get(function() { 112 | callback(result); 113 | }); 114 | }, 115 | SaveQualifyDetails: function(data, callback) { 116 | var resource = $resource('/api/qualify'); 117 | var result = resource.save(data, function () { 118 | callback(result); 119 | }); 120 | } 121 | }; 122 | }). 123 | factory('RaceService', function($resource) { 124 | return { 125 | GetRaceDetails: function(callback) { 126 | var resource = $resource('/api/race'); 127 | var result = resource.get(function() { 128 | callback(result); 129 | }); 130 | }, 131 | SaveRaceDetails: function(data, callback) { 132 | var resource = $resource('/api/race'); 133 | var result = resource.save(data, function () { 134 | callback(result); 135 | }); 136 | } 137 | }; 138 | }). 139 | factory('DynamicTrackService', function($resource) { 140 | return { 141 | GetDynamicTrackDetails: function(callback) { 142 | var resource = $resource('/api/dynamictrack'); 143 | var result = resource.get(function() { 144 | callback(result); 145 | }); 146 | }, 147 | SaveDynamicTrackDetails: function(data, callback) { 148 | var resource = $resource('/api/dynamictrack'); 149 | var result = resource.save(data, function () { 150 | callback(result); 151 | }); 152 | } 153 | }; 154 | }). 155 | factory('WeatherService', function($resource) { 156 | return { 157 | GetWeather: function(callback) { 158 | var resource = $resource('/api/weather'); 159 | var result = resource.query(function() { 160 | callback(result); 161 | }); 162 | }, 163 | SaveWeather: function(data, callback) { 164 | var resource = $resource('/api/weather'); 165 | var result = resource.save(data, function () { 166 | callback(result); 167 | }); 168 | } 169 | }; 170 | }). 171 | factory('ProcessService', function($resource, $timeout) { 172 | return { 173 | ACServerStatus: function(callback) { 174 | var resource = $resource('/api/acserver/status'); 175 | var result = resource.get(function() { 176 | callback(result); 177 | }); 178 | }, 179 | StartACServer: function (callback) { 180 | var resource = $resource('/api/acserver'); 181 | var result = resource.save(function () { 182 | callback(result); 183 | }); 184 | }, 185 | StopACServer: function (callback) { 186 | var resource = $resource('/api/acserver/stop'); 187 | var result = resource.save(function () { 188 | callback(result); 189 | }); 190 | }, 191 | RestartACServer: function (callback) { 192 | var resource = $resource('/api/acserver/stop'); 193 | var result = resource.save(function () { 194 | $timeout(function() { 195 | var resource = $resource('/api/acserver'); 196 | var result = resource.save(function () { 197 | callback(result); 198 | }); 199 | }, 500); 200 | }); 201 | }, 202 | STrackerServerStatus: function(callback) { 203 | var resource = $resource('/api/strackerserver/status'); 204 | var result = resource.get(function() { 205 | callback(result); 206 | }); 207 | }, 208 | StartSTrackerServer: function (callback) { 209 | var resource = $resource('/api/strackerserver'); 210 | var result = resource.save(function () { 211 | callback(result); 212 | }); 213 | }, 214 | StopSTrackerServer: function (callback) { 215 | var resource = $resource('/api/strackerserver/stop'); 216 | var result = resource.save(function () { 217 | callback(result); 218 | }); 219 | }, 220 | RestartSTrackerServer: function (callback) { 221 | var resource = $resource('/api/strackerserver/stop'); 222 | var result = resource.save(function () { 223 | var resource = $resource('/api/strackerserver'); 224 | var result = resource.save(function () { 225 | callback(result); 226 | }); 227 | }); 228 | } 229 | }; 230 | }). 231 | factory('EntryListService', function($resource) { 232 | return { 233 | GetEntryList: function(callback) { 234 | var resource = $resource('/api/entrylist'); 235 | var result = resource.get(function() { 236 | callback(result); 237 | }); 238 | }, 239 | SaveEntryList: function(data, callback) { 240 | var resource = $resource('/api/entrylist'); 241 | var result = resource.save(data, function() { 242 | callback(result); 243 | }); 244 | } 245 | }; 246 | }). 247 | factory('DriverService', function($resource) { 248 | return { 249 | GetDrivers: function(callback) { 250 | var resource = $resource('/api/drivers'); 251 | var result = resource.query(function() { 252 | callback(result); 253 | }); 254 | }, 255 | SaveDriver: function(data, callback) { 256 | var resource = $resource('/api/drivers'); 257 | var result = resource.save(data, function() { 258 | callback(result); 259 | }); 260 | }, 261 | DeleteDriver: function(guid, callback) { 262 | var resource = $resource('/api/drivers/:guid'); 263 | var result = resource.delete({guid: guid}, function() { 264 | callback(result); 265 | }); 266 | } 267 | }; 268 | }). 269 | factory('TyreService', function($resource) { 270 | return { 271 | GetTyres: function(cars, callback) { 272 | var resource = $resource('/api/tyres'); 273 | var result = resource.get({cars: cars}, function() { 274 | callback(result); 275 | }); 276 | } 277 | }; 278 | }); -------------------------------------------------------------------------------- /frontend/css/angular-toggle-switch-bootstrap-3.css: -------------------------------------------------------------------------------- 1 | .ats-switch { 2 | border: 1px solid; 3 | cursor: pointer; 4 | display: inline-block; 5 | text-align: left; 6 | overflow: hidden; 7 | line-height: 8px; 8 | min-width: 100px; 9 | } 10 | .ats-switch.disabled { 11 | opacity: 0.5; 12 | filter: alpha(opacity=50); 13 | cursor: default !important; 14 | } 15 | .ats-switch.disabled .switch-left, 16 | .ats-switch.disabled .switch-right, 17 | .ats-switch.disabled .knob { 18 | cursor: default !important; 19 | } 20 | .ats-switch span { 21 | cursor: pointer; 22 | display: inline-block; 23 | float: left; 24 | height: 100%; 25 | line-height: 20px; 26 | padding: 4px; 27 | text-align: center; 28 | width: 33%; 29 | white-space: nowrap; 30 | box-sizing: border-box; 31 | -o-box-sizing: border-box; 32 | -moz-box-sizing: border-box; 33 | -webkit-box-sizing: border-box; 34 | } 35 | .ats-switch > div { 36 | position: relative; 37 | width: 150%; 38 | } 39 | .ats-switch .knob { 40 | background: red; 41 | border-left: 1px solid #ccc; 42 | border-right: 1px solid #ccc; 43 | background-color: #f5f5f5; 44 | width: 34%; 45 | z-index: 100; 46 | } 47 | .ats-switch .switch-on { 48 | left: 0%; 49 | } 50 | .ats-switch .switch-off { 51 | left: -50%; 52 | } 53 | .ats-switch .swtich-left, 54 | .ats-switch .switch-right { 55 | z-index: 1; 56 | } 57 | .ats-switch .switch-left { 58 | color: #fff; 59 | background: #005fcc; 60 | } 61 | .ats-switch .switch-right { 62 | color: #333; 63 | background: #f0f0f0; 64 | } 65 | .ats-switch .switch-animate { 66 | transition: left 0.5s; 67 | -o-transition: left 0.5s; 68 | -moz-transition: left 0.5s; 69 | -webkit-transition: left 0.5s; 70 | } 71 | .ats-switch { 72 | display: inline-block; 73 | cursor: pointer; 74 | border-radius: 4px; 75 | border: 1px solid; 76 | border-color: #ccc; 77 | position: relative; 78 | text-align: left; 79 | overflow: hidden; 80 | line-height: 8px; 81 | -webkit-user-select: none; 82 | -moz-user-select: none; 83 | -ms-user-select: none; 84 | -o-user-select: none; 85 | user-select: none; 86 | vertical-align: middle; 87 | min-width: 100px; 88 | -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 89 | transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 90 | } 91 | .ats-switch:hover { 92 | border-color: #66afe9; 93 | outline: 0; 94 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); 95 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); 96 | } 97 | .ats-switch.disabled:hover { 98 | border-color: #ccc; 99 | -webkit-box-shadow: inset 0 0 0 rgba(0,0,0,0), 0 0 0 rgba(0,0,0,0); 100 | box-shadow: inset 0 0 0 rgba(0,0,0,0), 0 0 0 rgba(0,0,0,0); 101 | } 102 | .ats-switch .knob { 103 | border-right: none; 104 | border-left: none; 105 | text-align: center; 106 | margin-top: -1px; 107 | margin-bottom: -1px; 108 | z-index: 100; 109 | background: #fff; 110 | } 111 | .ats-switch .knob i { 112 | color: #000; 113 | text-shadow: 0 1px 0 #fff; 114 | line-height: 18px; 115 | pointer-events: none; 116 | } 117 | .ats-switch .switch-left, 118 | .ats-switch .switch-right, 119 | .ats-switch .knob { 120 | min-height: 28px; 121 | } 122 | .ats-switch.switch-mini { 123 | min-width: 72px; 124 | } 125 | .ats-switch.switch-mini .switch-left, 126 | .ats-switch.switch-mini .switch-right, 127 | .ats-switch.switch-mini .knob { 128 | padding-bottom: 4px; 129 | padding-top: 4px; 130 | font-size: 10px; 131 | line-height: 9px; 132 | min-height: 18px; 133 | } 134 | .ats-switch.switch-mini i.switch-mini-icons { 135 | height: 1.20em; 136 | line-height: 9px; 137 | vertical-align: text-top; 138 | text-align: center; 139 | transform: scale(0.6); 140 | margin-top: -1px; 141 | margin-bottom: -1px; 142 | } 143 | .ats-switch.switch-small { 144 | min-width: 80px; 145 | } 146 | .ats-switch.switch-small .switch-left, 147 | .ats-switch.switch-small .switch-right, 148 | .ats-switch.switch-small .knob { 149 | padding-bottom: 3px; 150 | padding-top: 3px; 151 | font-size: 12px; 152 | line-height: 18px; 153 | min-height: 24px; 154 | } 155 | .ats-switch.switch-large { 156 | min-width: 120px; 157 | } 158 | .ats-switch.switch-large .switch-left, 159 | .ats-switch.switch-large .switch-right, 160 | .ats-switch.switch-large .knob { 161 | padding-bottom: 9px; 162 | padding-top: 9px; 163 | font-size: 16px; 164 | line-height: normal; 165 | min-height: 34px; 166 | } 167 | .ats-switch span.switch-left { 168 | color: #fff; 169 | background: #428bca; 170 | } 171 | .ats-switch span.switch-right { 172 | color: #000; 173 | background: #eeeeee; 174 | } 175 | .ats-switch.switch-primary span.switch-left { 176 | color: #fff; 177 | background: #428bca; 178 | } 179 | .ats-switch.switch-info span.switch-left { 180 | color: #fff; 181 | background: #5bc0de; 182 | } 183 | .ats-switch.switch-success span.switch-left { 184 | color: #fff; 185 | background: #5cb85c; 186 | } 187 | .ats-switch.switch-warning span.switch-left { 188 | background: #f0ad4e; 189 | color: #fff; 190 | } 191 | .ats-switch.switch-danger span.switch-left { 192 | color: #fff; 193 | background: #d9534f; 194 | } 195 | .ats-switch.switch-default span.switch-left { 196 | color: #000; 197 | background: #eeeeee; 198 | } 199 | -------------------------------------------------------------------------------- /frontend/css/pe-icon-7-stroke.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Pe-icon-7-stroke'; 3 | src:url('../fonts/Pe-icon-7-stroke.eot?d7yf1v'); 4 | src:url('../fonts/Pe-icon-7-stroke.eot?#iefixd7yf1v') format('embedded-opentype'), 5 | url('../fonts/Pe-icon-7-stroke.woff?d7yf1v') format('woff'), 6 | url('../fonts/Pe-icon-7-stroke.ttf?d7yf1v') format('truetype'), 7 | url('../fonts/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="pe-7s-"], [class*=" pe-7s-"] { 13 | display: inline-block; 14 | font-family: 'Pe-icon-7-stroke'; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .pe-7s-album:before { 28 | content: "\e6aa"; 29 | } 30 | .pe-7s-arc:before { 31 | content: "\e6ab"; 32 | } 33 | .pe-7s-back-2:before { 34 | content: "\e6ac"; 35 | } 36 | .pe-7s-bandaid:before { 37 | content: "\e6ad"; 38 | } 39 | .pe-7s-car:before { 40 | content: "\e6ae"; 41 | } 42 | .pe-7s-diamond:before { 43 | content: "\e6af"; 44 | } 45 | .pe-7s-door-lock:before { 46 | content: "\e6b0"; 47 | } 48 | .pe-7s-eyedropper:before { 49 | content: "\e6b1"; 50 | } 51 | .pe-7s-female:before { 52 | content: "\e6b2"; 53 | } 54 | .pe-7s-gym:before { 55 | content: "\e6b3"; 56 | } 57 | .pe-7s-hammer:before { 58 | content: "\e6b4"; 59 | } 60 | .pe-7s-headphones:before { 61 | content: "\e6b5"; 62 | } 63 | .pe-7s-helm:before { 64 | content: "\e6b6"; 65 | } 66 | .pe-7s-hourglass:before { 67 | content: "\e6b7"; 68 | } 69 | .pe-7s-leaf:before { 70 | content: "\e6b8"; 71 | } 72 | .pe-7s-magic-wand:before { 73 | content: "\e6b9"; 74 | } 75 | .pe-7s-male:before { 76 | content: "\e6ba"; 77 | } 78 | .pe-7s-map-2:before { 79 | content: "\e6bb"; 80 | } 81 | .pe-7s-next-2:before { 82 | content: "\e6bc"; 83 | } 84 | .pe-7s-paint-bucket:before { 85 | content: "\e6bd"; 86 | } 87 | .pe-7s-pendrive:before { 88 | content: "\e6be"; 89 | } 90 | .pe-7s-photo:before { 91 | content: "\e6bf"; 92 | } 93 | .pe-7s-piggy:before { 94 | content: "\e6c0"; 95 | } 96 | .pe-7s-plugin:before { 97 | content: "\e6c1"; 98 | } 99 | .pe-7s-refresh-2:before { 100 | content: "\e6c2"; 101 | } 102 | .pe-7s-rocket:before { 103 | content: "\e6c3"; 104 | } 105 | .pe-7s-settings:before { 106 | content: "\e6c4"; 107 | } 108 | .pe-7s-shield:before { 109 | content: "\e6c5"; 110 | } 111 | .pe-7s-smile:before { 112 | content: "\e6c6"; 113 | } 114 | .pe-7s-usb:before { 115 | content: "\e6c7"; 116 | } 117 | .pe-7s-vector:before { 118 | content: "\e6c8"; 119 | } 120 | .pe-7s-wine:before { 121 | content: "\e6c9"; 122 | } 123 | .pe-7s-cloud-upload:before { 124 | content: "\e68a"; 125 | } 126 | .pe-7s-cash:before { 127 | content: "\e68c"; 128 | } 129 | .pe-7s-close:before { 130 | content: "\e680"; 131 | } 132 | .pe-7s-bluetooth:before { 133 | content: "\e68d"; 134 | } 135 | .pe-7s-cloud-download:before { 136 | content: "\e68b"; 137 | } 138 | .pe-7s-way:before { 139 | content: "\e68e"; 140 | } 141 | .pe-7s-close-circle:before { 142 | content: "\e681"; 143 | } 144 | .pe-7s-id:before { 145 | content: "\e68f"; 146 | } 147 | .pe-7s-angle-up:before { 148 | content: "\e682"; 149 | } 150 | .pe-7s-wristwatch:before { 151 | content: "\e690"; 152 | } 153 | .pe-7s-angle-up-circle:before { 154 | content: "\e683"; 155 | } 156 | .pe-7s-world:before { 157 | content: "\e691"; 158 | } 159 | .pe-7s-angle-right:before { 160 | content: "\e684"; 161 | } 162 | .pe-7s-volume:before { 163 | content: "\e692"; 164 | } 165 | .pe-7s-angle-right-circle:before { 166 | content: "\e685"; 167 | } 168 | .pe-7s-users:before { 169 | content: "\e693"; 170 | } 171 | .pe-7s-angle-left:before { 172 | content: "\e686"; 173 | } 174 | .pe-7s-user-female:before { 175 | content: "\e694"; 176 | } 177 | .pe-7s-angle-left-circle:before { 178 | content: "\e687"; 179 | } 180 | .pe-7s-up-arrow:before { 181 | content: "\e695"; 182 | } 183 | .pe-7s-angle-down:before { 184 | content: "\e688"; 185 | } 186 | .pe-7s-switch:before { 187 | content: "\e696"; 188 | } 189 | .pe-7s-angle-down-circle:before { 190 | content: "\e689"; 191 | } 192 | .pe-7s-scissors:before { 193 | content: "\e697"; 194 | } 195 | .pe-7s-wallet:before { 196 | content: "\e600"; 197 | } 198 | .pe-7s-safe:before { 199 | content: "\e698"; 200 | } 201 | .pe-7s-volume2:before { 202 | content: "\e601"; 203 | } 204 | .pe-7s-volume1:before { 205 | content: "\e602"; 206 | } 207 | .pe-7s-voicemail:before { 208 | content: "\e603"; 209 | } 210 | .pe-7s-video:before { 211 | content: "\e604"; 212 | } 213 | .pe-7s-user:before { 214 | content: "\e605"; 215 | } 216 | .pe-7s-upload:before { 217 | content: "\e606"; 218 | } 219 | .pe-7s-unlock:before { 220 | content: "\e607"; 221 | } 222 | .pe-7s-umbrella:before { 223 | content: "\e608"; 224 | } 225 | .pe-7s-trash:before { 226 | content: "\e609"; 227 | } 228 | .pe-7s-tools:before { 229 | content: "\e60a"; 230 | } 231 | .pe-7s-timer:before { 232 | content: "\e60b"; 233 | } 234 | .pe-7s-ticket:before { 235 | content: "\e60c"; 236 | } 237 | .pe-7s-target:before { 238 | content: "\e60d"; 239 | } 240 | .pe-7s-sun:before { 241 | content: "\e60e"; 242 | } 243 | .pe-7s-study:before { 244 | content: "\e60f"; 245 | } 246 | .pe-7s-stopwatch:before { 247 | content: "\e610"; 248 | } 249 | .pe-7s-star:before { 250 | content: "\e611"; 251 | } 252 | .pe-7s-speaker:before { 253 | content: "\e612"; 254 | } 255 | .pe-7s-signal:before { 256 | content: "\e613"; 257 | } 258 | .pe-7s-shuffle:before { 259 | content: "\e614"; 260 | } 261 | .pe-7s-shopbag:before { 262 | content: "\e615"; 263 | } 264 | .pe-7s-share:before { 265 | content: "\e616"; 266 | } 267 | .pe-7s-server:before { 268 | content: "\e617"; 269 | } 270 | .pe-7s-search:before { 271 | content: "\e618"; 272 | } 273 | .pe-7s-film:before { 274 | content: "\e6a5"; 275 | } 276 | .pe-7s-science:before { 277 | content: "\e619"; 278 | } 279 | .pe-7s-disk:before { 280 | content: "\e6a6"; 281 | } 282 | .pe-7s-ribbon:before { 283 | content: "\e61a"; 284 | } 285 | .pe-7s-repeat:before { 286 | content: "\e61b"; 287 | } 288 | .pe-7s-refresh:before { 289 | content: "\e61c"; 290 | } 291 | .pe-7s-add-user:before { 292 | content: "\e6a9"; 293 | } 294 | .pe-7s-refresh-cloud:before { 295 | content: "\e61d"; 296 | } 297 | .pe-7s-paperclip:before { 298 | content: "\e69c"; 299 | } 300 | .pe-7s-radio:before { 301 | content: "\e61e"; 302 | } 303 | .pe-7s-note2:before { 304 | content: "\e69d"; 305 | } 306 | .pe-7s-print:before { 307 | content: "\e61f"; 308 | } 309 | .pe-7s-network:before { 310 | content: "\e69e"; 311 | } 312 | .pe-7s-prev:before { 313 | content: "\e620"; 314 | } 315 | .pe-7s-mute:before { 316 | content: "\e69f"; 317 | } 318 | .pe-7s-power:before { 319 | content: "\e621"; 320 | } 321 | .pe-7s-medal:before { 322 | content: "\e6a0"; 323 | } 324 | .pe-7s-portfolio:before { 325 | content: "\e622"; 326 | } 327 | .pe-7s-like2:before { 328 | content: "\e6a1"; 329 | } 330 | .pe-7s-plus:before { 331 | content: "\e623"; 332 | } 333 | .pe-7s-left-arrow:before { 334 | content: "\e6a2"; 335 | } 336 | .pe-7s-play:before { 337 | content: "\e624"; 338 | } 339 | .pe-7s-key:before { 340 | content: "\e6a3"; 341 | } 342 | .pe-7s-plane:before { 343 | content: "\e625"; 344 | } 345 | .pe-7s-joy:before { 346 | content: "\e6a4"; 347 | } 348 | .pe-7s-photo-gallery:before { 349 | content: "\e626"; 350 | } 351 | .pe-7s-pin:before { 352 | content: "\e69b"; 353 | } 354 | .pe-7s-phone:before { 355 | content: "\e627"; 356 | } 357 | .pe-7s-plug:before { 358 | content: "\e69a"; 359 | } 360 | .pe-7s-pen:before { 361 | content: "\e628"; 362 | } 363 | .pe-7s-right-arrow:before { 364 | content: "\e699"; 365 | } 366 | .pe-7s-paper-plane:before { 367 | content: "\e629"; 368 | } 369 | .pe-7s-delete-user:before { 370 | content: "\e6a7"; 371 | } 372 | .pe-7s-paint:before { 373 | content: "\e62a"; 374 | } 375 | .pe-7s-bottom-arrow:before { 376 | content: "\e6a8"; 377 | } 378 | .pe-7s-notebook:before { 379 | content: "\e62b"; 380 | } 381 | .pe-7s-note:before { 382 | content: "\e62c"; 383 | } 384 | .pe-7s-next:before { 385 | content: "\e62d"; 386 | } 387 | .pe-7s-news-paper:before { 388 | content: "\e62e"; 389 | } 390 | .pe-7s-musiclist:before { 391 | content: "\e62f"; 392 | } 393 | .pe-7s-music:before { 394 | content: "\e630"; 395 | } 396 | .pe-7s-mouse:before { 397 | content: "\e631"; 398 | } 399 | .pe-7s-more:before { 400 | content: "\e632"; 401 | } 402 | .pe-7s-moon:before { 403 | content: "\e633"; 404 | } 405 | .pe-7s-monitor:before { 406 | content: "\e634"; 407 | } 408 | .pe-7s-micro:before { 409 | content: "\e635"; 410 | } 411 | .pe-7s-menu:before { 412 | content: "\e636"; 413 | } 414 | .pe-7s-map:before { 415 | content: "\e637"; 416 | } 417 | .pe-7s-map-marker:before { 418 | content: "\e638"; 419 | } 420 | .pe-7s-mail:before { 421 | content: "\e639"; 422 | } 423 | .pe-7s-mail-open:before { 424 | content: "\e63a"; 425 | } 426 | .pe-7s-mail-open-file:before { 427 | content: "\e63b"; 428 | } 429 | .pe-7s-magnet:before { 430 | content: "\e63c"; 431 | } 432 | .pe-7s-loop:before { 433 | content: "\e63d"; 434 | } 435 | .pe-7s-look:before { 436 | content: "\e63e"; 437 | } 438 | .pe-7s-lock:before { 439 | content: "\e63f"; 440 | } 441 | .pe-7s-lintern:before { 442 | content: "\e640"; 443 | } 444 | .pe-7s-link:before { 445 | content: "\e641"; 446 | } 447 | .pe-7s-like:before { 448 | content: "\e642"; 449 | } 450 | .pe-7s-light:before { 451 | content: "\e643"; 452 | } 453 | .pe-7s-less:before { 454 | content: "\e644"; 455 | } 456 | .pe-7s-keypad:before { 457 | content: "\e645"; 458 | } 459 | .pe-7s-junk:before { 460 | content: "\e646"; 461 | } 462 | .pe-7s-info:before { 463 | content: "\e647"; 464 | } 465 | .pe-7s-home:before { 466 | content: "\e648"; 467 | } 468 | .pe-7s-help2:before { 469 | content: "\e649"; 470 | } 471 | .pe-7s-help1:before { 472 | content: "\e64a"; 473 | } 474 | .pe-7s-graph3:before { 475 | content: "\e64b"; 476 | } 477 | .pe-7s-graph2:before { 478 | content: "\e64c"; 479 | } 480 | .pe-7s-graph1:before { 481 | content: "\e64d"; 482 | } 483 | .pe-7s-graph:before { 484 | content: "\e64e"; 485 | } 486 | .pe-7s-global:before { 487 | content: "\e64f"; 488 | } 489 | .pe-7s-gleam:before { 490 | content: "\e650"; 491 | } 492 | .pe-7s-glasses:before { 493 | content: "\e651"; 494 | } 495 | .pe-7s-gift:before { 496 | content: "\e652"; 497 | } 498 | .pe-7s-folder:before { 499 | content: "\e653"; 500 | } 501 | .pe-7s-flag:before { 502 | content: "\e654"; 503 | } 504 | .pe-7s-filter:before { 505 | content: "\e655"; 506 | } 507 | .pe-7s-file:before { 508 | content: "\e656"; 509 | } 510 | .pe-7s-expand1:before { 511 | content: "\e657"; 512 | } 513 | .pe-7s-exapnd2:before { 514 | content: "\e658"; 515 | } 516 | .pe-7s-edit:before { 517 | content: "\e659"; 518 | } 519 | .pe-7s-drop:before { 520 | content: "\e65a"; 521 | } 522 | .pe-7s-drawer:before { 523 | content: "\e65b"; 524 | } 525 | .pe-7s-download:before { 526 | content: "\e65c"; 527 | } 528 | .pe-7s-display2:before { 529 | content: "\e65d"; 530 | } 531 | .pe-7s-display1:before { 532 | content: "\e65e"; 533 | } 534 | .pe-7s-diskette:before { 535 | content: "\e65f"; 536 | } 537 | .pe-7s-date:before { 538 | content: "\e660"; 539 | } 540 | .pe-7s-cup:before { 541 | content: "\e661"; 542 | } 543 | .pe-7s-culture:before { 544 | content: "\e662"; 545 | } 546 | .pe-7s-crop:before { 547 | content: "\e663"; 548 | } 549 | .pe-7s-credit:before { 550 | content: "\e664"; 551 | } 552 | .pe-7s-copy-file:before { 553 | content: "\e665"; 554 | } 555 | .pe-7s-config:before { 556 | content: "\e666"; 557 | } 558 | .pe-7s-compass:before { 559 | content: "\e667"; 560 | } 561 | .pe-7s-comment:before { 562 | content: "\e668"; 563 | } 564 | .pe-7s-coffee:before { 565 | content: "\e669"; 566 | } 567 | .pe-7s-cloud:before { 568 | content: "\e66a"; 569 | } 570 | .pe-7s-clock:before { 571 | content: "\e66b"; 572 | } 573 | .pe-7s-check:before { 574 | content: "\e66c"; 575 | } 576 | .pe-7s-chat:before { 577 | content: "\e66d"; 578 | } 579 | .pe-7s-cart:before { 580 | content: "\e66e"; 581 | } 582 | .pe-7s-camera:before { 583 | content: "\e66f"; 584 | } 585 | .pe-7s-call:before { 586 | content: "\e670"; 587 | } 588 | .pe-7s-calculator:before { 589 | content: "\e671"; 590 | } 591 | .pe-7s-browser:before { 592 | content: "\e672"; 593 | } 594 | .pe-7s-box2:before { 595 | content: "\e673"; 596 | } 597 | .pe-7s-box1:before { 598 | content: "\e674"; 599 | } 600 | .pe-7s-bookmarks:before { 601 | content: "\e675"; 602 | } 603 | .pe-7s-bicycle:before { 604 | content: "\e676"; 605 | } 606 | .pe-7s-bell:before { 607 | content: "\e677"; 608 | } 609 | .pe-7s-battery:before { 610 | content: "\e678"; 611 | } 612 | .pe-7s-ball:before { 613 | content: "\e679"; 614 | } 615 | .pe-7s-back:before { 616 | content: "\e67a"; 617 | } 618 | .pe-7s-attention:before { 619 | content: "\e67b"; 620 | } 621 | .pe-7s-anchor:before { 622 | content: "\e67c"; 623 | } 624 | .pe-7s-albums:before { 625 | content: "\e67d"; 626 | } 627 | .pe-7s-alarm:before { 628 | content: "\e67e"; 629 | } 630 | .pe-7s-airplay:before { 631 | content: "\e67f"; 632 | } 633 | -------------------------------------------------------------------------------- /frontend/css/style.css: -------------------------------------------------------------------------------- 1 | body { padding-top: 0px;} 2 | 3 | .starter-template { padding: 40px 15px; } 4 | 5 | .top5 { margin-top:5px; } 6 | .top7 { margin-top:7px; } 7 | .top10 { margin-top:10px; } 8 | .top15 { margin-top:15px; } 9 | .top17 { margin-top:17px; } 10 | .top30 { margin-top:30px; } 11 | 12 | .bottom5 { margin-bottom:5px; } 13 | .bottom7 { margin-bottom:7px; } 14 | .bottom10 { margin-bottom:10px; } 15 | .bottom15 { margin-bottom:15px; } 16 | .bottom17 { margin-bottom:17px; } 17 | .bottom30 { margin-bottom:30px; } 18 | 19 | .left {float: left;} 20 | .right {float: right;} 21 | 22 | .alerts { 23 | top: 51px; 24 | left: 0px; 25 | position: fixed; 26 | width: 100%; 27 | z-index: 1; 28 | } 29 | 30 | [ng\:cloak], [ng-cloak], .ng-cloak { 31 | display: none !important; 32 | } 33 | 34 | .all-icons [class*="pe-"]{ 35 | font-size: 40px; 36 | } 37 | .all-icons input{ 38 | border: 0; 39 | } 40 | .all-icons .font-icon-detail{ 41 | text-align: center; 42 | padding: 45px 0px 30px; 43 | border: 1px solid #e5e5e5; 44 | border-radius: 6px; 45 | margin: 15px 0; 46 | } 47 | .all-icons .font-icon-detail input{ 48 | margin: 25px auto 0; 49 | width: 100%; 50 | text-align: center; 51 | display: block; 52 | color: #aaa; 53 | font-size: 13px; 54 | } 55 | 56 | @media (min-width: 992px){ 57 | .typo-line{ 58 | padding-left: 140px; 59 | margin-bottom: 40px; 60 | position: relative; 61 | } 62 | 63 | .typo-line .category{ 64 | transform: translateY(-50%); 65 | top: 50%; 66 | left: 0px; 67 | position: absolute; 68 | } 69 | } 70 | 71 | .places-buttons .btn{ 72 | margin-bottom: 30px 73 | } 74 | .sidebar .nav > li.active-pro{ 75 | position: absolute; 76 | width: 100%; 77 | bottom: 10px; 78 | } 79 | .sidebar .nav > li.active-pro a{ 80 | background: rgba(255, 255, 255, 0.14); 81 | opacity: 1; 82 | color: #FFFFFF; 83 | } 84 | 85 | .table-upgrade td:nth-child(2), 86 | .table-upgrade td:nth-child(3){ 87 | text-align: center; 88 | } 89 | 90 | .checkbox, .checkbox label { 91 | padding-left: 0px; !important 92 | } 93 | 94 | .checkbox { 95 | margin-top: 0px; !important 96 | } 97 | 98 | .checkbox input { 99 | display: block; !important 100 | } -------------------------------------------------------------------------------- /frontend/entrylist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Assetto Corsa Server Manager 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 |
32 | 79 | 80 |
81 | 97 | 98 |
99 |
100 |
101 | {{alert.msg}} 102 |
103 | 104 |
105 |
106 | Add Player 107 | 108 |
109 |
110 |
111 | 112 | 113 |
114 |
115 | 116 |
117 |
118 | 119 | 120 |
121 |
122 | 123 |
124 |
125 | 126 | 127 |
128 |
129 | 130 |
131 |
132 | 133 | 134 |
135 |
136 |
137 | 138 |
139 |
140 |
141 | 142 | 143 |
144 |
145 | 146 |
147 |
148 | 149 | 150 |
151 |
152 | 153 |
154 |
155 | 156 | 157 |
158 |
159 | 160 |
161 | 162 |
163 | 166 |
167 |
168 |
169 | 170 |
171 |
172 | 173 |
174 | 177 |
178 |
179 |
180 | 181 |
182 |
183 | 184 |
185 |
186 | 187 |
188 |
189 |
190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 224 | 225 | 226 |
#NameTeamGUIDCarSkinSpectatorBallast
{{$index + 1}}{{entry.DRIVERNAME}}{{entry.TEAM}}{{entry.GUID}}{{entry.MODEL}}{{entry.SKIN}}{{entry.SPECTATOR_MODE ? 'Yes' : 'No'}}{{entry.BALLAST}}
222 | 223 |
227 |
228 |
229 |
230 | 231 |
232 |
233 | 234 |
235 |
236 |
237 |
238 |
239 |
240 | 241 | 242 | 243 | 269 |
270 |
271 | 272 | 273 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | -------------------------------------------------------------------------------- /frontend/fonts/Pe-icon-7-stroke.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/Pe-icon-7-stroke.eot -------------------------------------------------------------------------------- /frontend/fonts/Pe-icon-7-stroke.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/Pe-icon-7-stroke.ttf -------------------------------------------------------------------------------- /frontend/fonts/Pe-icon-7-stroke.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/Pe-icon-7-stroke.woff -------------------------------------------------------------------------------- /frontend/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /frontend/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /frontend/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /frontend/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /frontend/help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Assetto Corsa Server Manager 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 |
31 | 78 | 79 |
80 | 96 | 97 |
98 |
99 |
100 | {{alert.msg}} 101 |
102 |
103 |
104 |     [SERVER]
105 |     NAME=AC #001 Abarth Festival	;name of the server
106 |     CARS=abarth500_s1;ferrari_458	;models of the cars allowed in the server - that's exactly the car folder's name (into the "content/cars" folder)
107 |     TRACK=vallelunga		;track on the server - that's exactly the track folder's name (into the "content/tracks" folder)
108 |     CONFIG_TRACK=extended_circuit	;subversion of the track, this parameter must contains the name of the track's subversion folder that you find in "content\tracks\TRACK\ui"
109 |     SUN_ANGLE=-8			;angle of the position of the sun
110 |     MAX_CLIENTS=15			;max number of clients (must be <= track's number of pits)
111 |     RACE_OVER_TIME=20		;time remaining in seconds to finish the race from the moment the first one passes on the finish line
112 |     ALLOWED_TYRES_OUT=-1		;penalty (-1 disabled)
113 |     UDP_PORT=9600			;UDP port number -> open this port on your server's firewall
114 |     TCP_PORT=9600			;TCP port number -> open this port on your server's firewall
115 |     HTTP_PORT=8081			;Lobby port number -> open this ports (both UDP and TCP) on your server's firewall
116 |     PASSWORD=something		;server password
117 |     LOOP_MODE=1			;the server restarts from the first track, to disable this set it to 0
118 |     REGISTER_TO_LOBBY=1		;this must not be touched
119 |     PICKUP_MODE_ENABLED=1		;if 0 the server start in booking mode (do not use it). Warning: in pickup mode you have to list only a circuit under TRACK and you need to list a least one car in the entry_list
120 |     SLEEP_TIME=1			;this must not be touched
121 |     VOTING_QUORUM=75		;percentage of vote that is required for the SESSION vote to pass
122 |     VOTE_DURATION=20		;time in seconds
123 |     BLACKLIST_MODE=0		;ban player -> 0 = normal kick, rejoin possible, 1 = until server restart WARNING: 2 is not mor valid since kick_id and ban_id are two different commands.
124 |     TC_ALLOWED=1			;0 -> no car can use TC, 1 -> only car provided with TC can use it; 2-> any car can use TC
125 |     ABS_ALLOWED=1			;0 -> no car can use ABS, 1 -> only car provided with ABS can use it; 2-> any car can use ABS
126 |     STABILITY_ALLOWED=0		;Stability assist 0 -> OFF; 1 -> ON
127 |     AUTOCLUTCH_ALLOWED=1		;Autoclutch assist 0 -> OFF; 1 -> ON
128 |     DAMAGE_MULTIPLIER=0		;Damage from 0 (no damage) to 100 (full damage)
129 |     FUEL_RATE=100			;Fuel usage from 0 (no fuel usage) to XXX (100 is the realistic one)
130 |     TYRE_WEAR_RATE=100		;Tyre wear from 0 (no tyre wear) to XXX (100 is the realistic one)
131 |     CLIENT_SEND_INTERVAL_HZ=15	;refresh rate of packet sending by the server. 10Hz = ~100ms. Higher number = higher MP quality = higher bandwidth resources needed. Really high values can create connection issues
132 |     TYRE_BLANKETS_ALLOWED=1		;at the start of the session or after the pitstop the tyre will have the the optimal temperature
133 |     ADMIN_PASSWORD=kunos		;it's the password needed to be recognized as server administrator: you can join the server using it to be recognized automatically. Write on the game's chat /help to see the command list
134 |     QUALIFY_MAX_WAIT_PERC=120	;this is the factor to calculate the remaining time in a qualify session after the session is ended: 120 means that 120% of the session fastest lap remains to end the current lap.
135 |     WELCOME_MESSAGE=		;path of a file who contains the server welome message
136 |     START_RULE=0			;0 is car locked until start;   1 is teleport   ; 2 is drivethru (if race has 3 or less laps then the Teleport penalty is enabled)
137 |     NUM_THREADS=4			;default is 2
138 |     FORCE_VIRTUAL_MIRROR=1		;1 virtual mirror will be enabled for every client, 0 for mirror as optional
139 |     LEGAL_TYRES=V;E;HR;ST		;list of the tyre's shortnames that will be allowed in the server.
140 |     MAX_BALLAST_KG=50		;the max total of ballast that can be added through the admin command
141 |     UDP_PLUGIN_LOCAL_PORT=0		;see plugin example
142 |     UDP_PLUGIN_ADDRESS=		;see plugin example
143 |     AUTH_PLUGIN_ADDRESS=		;see plugin example
144 |     RACE_GAS_PENALTY_DISABLED=0	;0  any cut will be penalized with the gas cut message; 1 no penalization will be forced, but cuts will be saved in the race result json.
145 |     RESULT_SCREEN_TIME=10		;seconds of result screen between racing sessions.
146 |     RACE_EXTRA_LAP=0		;if it's a timed race, with 1 the race will not end when the time is over and the leader crosses the line, but the latter will be forced to drive another extra lap.
147 | 
148 |     ------ UPDATE ------
149 |     LOCKED_ENTRY_LIST=0		;same as in booking mode, only players already included in the entry list can join the server (password not needed).
150 |     RACE_PIT_WINDOW_START=25	;Pit window open at lap/minute (depends on the race mode)
151 |     RACE_PIT_WINDOW_END=35		;Pit window closes at lap/minute (depends on the race mode)
152 |     REVERSED_GRID_RACE_POSITIONS=8	;0 = no additional race, 1toX = only those position will be reversed for the next race, -1 = all the position will be reversed (Retired players will be on the last positions)
153 |     ------------------------
154 | 
155 |     [DYNAMIC_TRACK]
156 |     SESSION_START=90		;% level of grip at session start
157 |     RANDOMNESS=1			;level of randomness added to the start grip
158 |     LAP_GAIN=1			;how many laps are needed to add 1% grip
159 |     SESSION_TRANSFER=90		;how much of the gained grip is to be added to the next session 100 -> all the gained grip. Example: difference between starting (90) and ending (96) grip in the session = 6%, with session_transfer = 50 then the next session is going to start with 93.
160 | 
161 |     [BOOK]				;booking session - add this section only if your server is in booking mode
162 |     NAME=Booking
163 |     TIME=5				;session length in minutes
164 | 
165 |     [PRACTICE]
166 |     NAME=Free Practice
167 |     TIME=0				;session length in minutes
168 |     IS_OPEN=1			;0 = no join, 1 = free join,
169 | 
170 |     [QUALIFY]
171 |     NAME=Qualify
172 |     TIME=15				;session length in minutes
173 |     IS_OPEN=1			;0 = no join, 1 = free join,
174 | 
175 |     [RACE]
176 |     NAME=Race
177 |     LAPS=5				;length of the lap races
178 | 
179 |     ------ UPDATE ------
180 |     TIME=0				;length of the timed races, only if laps = 0
181 |     ------------------------
182 | 
183 |     WAIT_TIME=60			;seconds before the start of the session
184 |     IS_OPEN=2			;0 = no join, 1 = free join, 2 = free join until 20 seconds to the green light
185 | 
186 |     [WEATHER_0]			;mandatory section for weather.
187 |     GRAPHICS=3_clear		;it's exactly one of the folder name that you find into "content\weather" directory
188 |     BASE_TEMPERATURE_AMBIENT=18	;temperature of the Ambient
189 |     VARIATION_AMBIENT=2		;variation of the ambient's temperature. In this example final ambient's temperature can be 16 or 20
190 |     BASE_TEMPERATURE_ROAD=6		;Relative road temperature: this value will be added to the final ambient temp. In this example the road temperature will be between 22 (16 + 6) and 26 (20 + 6). It can be negative.
191 |     VARIATION_ROAD=1		;variation of the road's temperature. Like the ambient one.
192 |             
193 | 
194 |                     
195 |
196 | 197 | 223 |
224 |
225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /frontend/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/ajax-loader.gif -------------------------------------------------------------------------------- /frontend/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/favicon.ico -------------------------------------------------------------------------------- /frontend/img/sidebar-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/sidebar-1.jpg -------------------------------------------------------------------------------- /frontend/img/sidebar-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/sidebar-2.jpg -------------------------------------------------------------------------------- /frontend/img/sidebar-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/sidebar-3.jpg -------------------------------------------------------------------------------- /frontend/img/sidebar-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/sidebar-4.jpg -------------------------------------------------------------------------------- /frontend/img/sidebar-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jo3stevens/ACServerManager/5303e516ebd078e0f39100e05cd46a52aa2d04a7/frontend/img/sidebar-5.jpg -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Assetto Corsa Server Manager 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 |
31 | 78 | 79 |
80 | 96 | 97 |
98 |
99 |
100 | {{alert.msg}} 101 |
102 | 103 |
104 |
105 | Assetto Corsa Server 106 | 107 |
108 |
109 |

{{acServerStatus === 1 ? 'Running' : acServerStatus === 0 ? 'Stopped' : 'Loading...'}}

110 |
111 | 112 |
113 | 116 | 117 |
118 | 121 | 122 | 125 |
126 | Loading 127 |
128 |
129 |
130 | 131 |
132 | sTracker Server 133 | 134 |
135 |
136 |

{{sTrackerServerStatus === 1 ? 'Running' : acServerStatus === 0 ? 'Stopped' : 'Loading...'}}

137 |
138 | 139 |
140 | 143 | 144 |
145 | 148 | 149 | 152 |
153 | Loading 154 |
155 |
156 |
157 | 158 |
159 | Server Status 160 | 161 |
162 |
163 |

Current Session: {{serverStatus.session}}

164 |
165 |
166 |
167 |
168 |
169 |
170 | 171 | 197 |
198 |
199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /frontend/js/angular/angular-resource.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.3.15 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(I,d,B){'use strict';function D(f,q){q=q||{};d.forEach(q,function(d,h){delete q[h]});for(var h in f)!f.hasOwnProperty(h)||"$"===h.charAt(0)&&"$"===h.charAt(1)||(q[h]=f[h]);return q}var w=d.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;d.module("ngResource",["ng"]).provider("$resource",function(){var f=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; 7 | this.$get=["$http","$q",function(q,h){function t(d,g){this.template=d;this.defaults=s({},f.defaults,g);this.urlParams={}}function v(x,g,l,m){function c(b,k){var c={};k=s({},g,k);r(k,function(a,k){u(a)&&(a=a());var d;if(a&&a.charAt&&"@"==a.charAt(0)){d=b;var e=a.substr(1);if(null==e||""===e||"hasOwnProperty"===e||!C.test("."+e))throw w("badmember",e);for(var e=e.split("."),n=0,g=e.length;n').parent().bootstrapSwitch(); 46 | } 47 | 48 | $('.form-control').on("focus", function(){ 49 | $(this).parent('.input-group').addClass("input-group-focus"); 50 | }).on("blur", function(){ 51 | $(this).parent(".input-group").removeClass("input-group-focus"); 52 | }); 53 | 54 | // Fixes sub-nav not working as expected on IOS 55 | $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); }); 56 | }); 57 | 58 | // activate collapse right menu when the windows is resized 59 | $(window).resize(function(){ 60 | if($(window).width() <= 991){ 61 | lbd.initRightMenu(); 62 | } 63 | }); 64 | 65 | lbd = { 66 | misc:{ 67 | navbar_menu_visible: 0 68 | }, 69 | 70 | checkSidebarImage: function(){ 71 | $sidebar = $('.sidebar'); 72 | image_src = $sidebar.data('image'); 73 | 74 | if(image_src !== undefined){ 75 | sidebar_container = '