├── .bowerrc
├── .buildignore
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .travis.yml
├── .yo-rc.json
├── Gruntfile.js
├── README.md
├── bower.json
├── client
├── common
│ ├── assets
│ │ └── images
│ │ │ └── yeoman.png
│ ├── auto.scss
│ └── scss
│ │ ├── _colours.scss
│ │ ├── _fonts.scss
│ │ ├── _layout.scss
│ │ └── common.scss
├── ionic
│ ├── scss
│ │ ├── _colours.scss
│ │ ├── _fonts.scss
│ │ ├── _layout.scss
│ │ ├── _variable_overrides.scss
│ │ └── ionic.app.scss
│ └── www
│ │ ├── img
│ │ └── ionic.png
│ │ ├── index.html
│ │ ├── js
│ │ ├── app.js
│ │ ├── controllers.js
│ │ └── services.js
│ │ ├── lib
│ │ └── ionic
│ │ │ ├── css
│ │ │ ├── ionic.css
│ │ │ └── ionic.min.css
│ │ │ ├── fonts
│ │ │ ├── ionicons.eot
│ │ │ ├── ionicons.svg
│ │ │ ├── ionicons.ttf
│ │ │ └── ionicons.woff
│ │ │ ├── js
│ │ │ ├── angular-ui
│ │ │ │ ├── angular-ui-router.js
│ │ │ │ └── angular-ui-router.min.js
│ │ │ ├── angular
│ │ │ │ ├── angular-animate.js
│ │ │ │ ├── angular-animate.min.js
│ │ │ │ ├── angular-resource.js
│ │ │ │ ├── angular-resource.min.js
│ │ │ │ ├── angular-sanitize.js
│ │ │ │ ├── angular-sanitize.min.js
│ │ │ │ ├── angular.js
│ │ │ │ └── angular.min.js
│ │ │ ├── ionic-angular.js
│ │ │ ├── ionic-angular.min.js
│ │ │ ├── ionic.bundle.js
│ │ │ ├── ionic.bundle.min.js
│ │ │ ├── ionic.js
│ │ │ └── ionic.min.js
│ │ │ ├── scss
│ │ │ ├── _action-sheet.scss
│ │ │ ├── _animations.scss
│ │ │ ├── _backdrop.scss
│ │ │ ├── _badge.scss
│ │ │ ├── _bar.scss
│ │ │ ├── _button-bar.scss
│ │ │ ├── _button.scss
│ │ │ ├── _checkbox.scss
│ │ │ ├── _form.scss
│ │ │ ├── _grid.scss
│ │ │ ├── _items.scss
│ │ │ ├── _list.scss
│ │ │ ├── _loading.scss
│ │ │ ├── _menu.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _modal.scss
│ │ │ ├── _platform.scss
│ │ │ ├── _popover.scss
│ │ │ ├── _popup.scss
│ │ │ ├── _progress.scss
│ │ │ ├── _radio.scss
│ │ │ ├── _range.scss
│ │ │ ├── _reset.scss
│ │ │ ├── _scaffolding.scss
│ │ │ ├── _select.scss
│ │ │ ├── _slide-box.scss
│ │ │ ├── _tabs.scss
│ │ │ ├── _toggle.scss
│ │ │ ├── _transitions.scss
│ │ │ ├── _type.scss
│ │ │ ├── _util.scss
│ │ │ ├── _variables.scss
│ │ │ ├── ionic.scss
│ │ │ └── ionicons
│ │ │ │ ├── _ionicons-animation.scss
│ │ │ │ ├── _ionicons-font.scss
│ │ │ │ ├── _ionicons-icons.scss
│ │ │ │ ├── _ionicons-variables.scss
│ │ │ │ └── ionicons.scss
│ │ │ └── version.json
│ │ └── templates
│ │ ├── tab-account.html
│ │ ├── tab-dash.html
│ │ ├── tab-things.html
│ │ ├── tabs.html
│ │ └── thing-detail.html
└── webapp
│ ├── .htaccess
│ ├── .jshintrc
│ ├── app
│ ├── account
│ │ ├── account.js
│ │ ├── login
│ │ │ ├── login.controller.js
│ │ │ ├── login.jade
│ │ │ └── login.scss
│ │ ├── settings
│ │ │ ├── settings.controller.js
│ │ │ └── settings.jade
│ │ └── signup
│ │ │ ├── signup.controller.js
│ │ │ └── signup.jade
│ ├── admin
│ │ ├── admin.controller.js
│ │ ├── admin.jade
│ │ ├── admin.js
│ │ └── admin.scss
│ ├── app.js
│ ├── app.scss
│ └── main
│ │ ├── main.controller.js
│ │ ├── main.controller.spec.js
│ │ ├── main.jade
│ │ ├── main.js
│ │ └── main.scss
│ ├── components
│ ├── auth
│ │ ├── auth.service.js
│ │ └── user.service.js
│ ├── modal
│ │ ├── modal.jade
│ │ ├── modal.scss
│ │ └── modal.service.js
│ ├── mongoose-error
│ │ └── mongoose-error.directive.js
│ └── navbar
│ │ ├── navbar.controller.js
│ │ └── navbar.jade
│ ├── favicon.ico
│ ├── index.html
│ ├── robots.txt
│ └── scss
│ ├── _colours.scss
│ ├── _fonts.scss
│ ├── _layout.scss
│ └── webapp.scss
├── dist-ionic
├── .bowerrc
├── .gitignore
├── bower.json
├── config.xml
├── gulpfile.js
├── hooks
│ ├── README.md
│ └── after_prepare
│ │ └── 010_add_platform_class.js
├── ionic.project
└── package.json
├── e2e
└── main
│ ├── main.po.js
│ └── main.spec.js
├── karma.conf.js
├── notes.txt
├── package.json
├── protractor.conf.js
└── server
├── .jshintrc
├── .jshintrc-spec
├── api
├── thing
│ ├── index.js
│ ├── thing.controller.js
│ ├── thing.model.js
│ └── thing.spec.js
└── user
│ ├── index.js
│ ├── user.controller.js
│ ├── user.model.js
│ └── user.model.spec.js
├── app.js
├── auth
├── auth.service.js
├── facebook
│ ├── index.js
│ └── passport.js
├── google
│ ├── index.js
│ └── passport.js
├── index.js
├── local
│ ├── index.js
│ └── passport.js
└── twitter
│ ├── index.js
│ └── passport.js
├── components
└── errors
│ └── index.js
├── config
├── environment
│ ├── development.js
│ ├── index.js
│ ├── production.js
│ └── test.js
├── express.js
├── local.env.sample.js
└── seed.js
├── routes.js
└── views
└── 404.jade
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "client/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.buildignore:
--------------------------------------------------------------------------------
1 | *.coffee
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | public
3 | .tmp
4 | .sass-cache
5 | .idea
6 | client/bower_components
7 | dist
8 | /server/config/local.env.js
9 | /dist-ionic/www
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '0.10'
4 | - '0.11'
5 | before_script:
6 | - npm install -g bower grunt-cli
7 | - gem install sass
8 | - bower install
9 | services: mongodb
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-angular-fullstack-ionic": {
3 | "insertRoutes": true,
4 | "registerRoutesFile": "server/routes.js",
5 | "routesNeedle": "// Insert routes below",
6 | "routesBase": "/api/",
7 | "pluralizeRoutes": true,
8 | "insertSockets": true,
9 | "registerSocketsFile": "server/config/socketio.js",
10 | "socketsNeedle": "// Insert sockets below",
11 | "filters": {
12 | "js": true,
13 | "jade": true,
14 | "sass": true,
15 | "uirouter": true,
16 | "bootstrap": true,
17 | "uibootstrap": true,
18 | "mongoose": true,
19 | "auth": true,
20 | "oauth": true,
21 | "googleAuth": true,
22 | "facebookAuth": true,
23 | "twitterAuth": true
24 | }
25 | },
26 | "generator-ng-component": {
27 | "routeDirectory": "client/app/",
28 | "directiveDirectory": "client/app/",
29 | "filterDirectory": "client/app/",
30 | "serviceDirectory": "client/app/",
31 | "basePath": "client",
32 | "moduleName": "",
33 | "filters": [
34 | "uirouter"
35 | ],
36 | "extensions": [
37 | "js",
38 | "jade",
39 | "scss"
40 | ],
41 | "directiveSimpleTemplates": "",
42 | "directiveComplexTemplates": "",
43 | "filterTemplates": "",
44 | "serviceTemplates": "",
45 | "factoryTemplates": "",
46 | "controllerTemplates": "",
47 | "decoratorTemplates": "",
48 | "providerTemplates": "",
49 | "routeTemplates": ""
50 | }
51 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-fullstack-ionic-starter
2 |
3 | The motivation behind Angular Fullstack Ionic is to streamline the development of projects that include an API, Angular webapp and Ionic app. It’s core design principles include sharing code and assets wherever possible, creating an efficient workflow and making it super easy to start off a project with handy components available out of the box (e.g. user signup/login).
4 |
5 | It is based on the brilliant Yeoman angular-fullstack project.
6 |
7 | ##### Get started
8 | *Note this project in the early stages - so please read the points below before jumping in!*
9 | ```
10 | npm install
11 | bower install
12 | grunt serve
13 | ```
14 | ##### Dependencies
15 | If you don't have it already, you'll need Sass: ```gem install sass```
16 |
17 | You'll also need MongoDB to be up and running: http://docs.mongodb.org/manual/installation/
18 |
19 | ### Implemented so far
20 | * Grunt development workflow to serve webapp and ionic app in two browser tabs
21 | * Frontend (client) directory with
22 | * webapp - Jade, JS, SCSS and assets specific to webapp
23 | * ionic - HTML, JS, SCSS and assets specific to ionic app
24 | * common - SCSS and assets shared between webapp and ionic app
25 |
26 | ### Next steps
27 | * Wire up grunt dist tasks to work with new client folder structure
28 | * Implement user login in Ionic app
29 | * Implement shared components (e.g. angular directives, etc)
30 | * Implement shared fonts
31 | * Support plain HTML as well as Jade for webapp
32 | * Support Jade as well as plain HTML for ionic app
33 |
34 | ### Get involved
35 | The eventual aim of this project is to create an extension to the Yeoman generator-angular-fullstack
36 |
37 | Please contact @richardgsands if you'd like to help out!
38 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tmp",
3 | "version": "0.0.0",
4 | "dependencies": {
5 | "angular": ">=1.2.*",
6 | "json3": "~3.3.1",
7 | "es5-shim": "~3.0.1",
8 | "bootstrap-sass-official": "~3.1.1",
9 | "bootstrap": "~3.1.1",
10 | "angular-resource": ">=1.2.*",
11 | "angular-cookies": ">=1.2.*",
12 | "angular-sanitize": ">=1.2.*",
13 | "angular-bootstrap": "~0.11.0",
14 | "font-awesome": ">=4.1.0",
15 | "lodash": "~2.4.1",
16 | "angular-ui-router": "~0.2.10"
17 | },
18 | "devDependencies": {
19 | "angular-mocks": ">=1.2.*",
20 | "angular-scenario": ">=1.2.*"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/client/common/assets/images/yeoman.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/common/assets/images/yeoman.png
--------------------------------------------------------------------------------
/client/common/auto.scss:
--------------------------------------------------------------------------------
1 | /**
2 | Create common styles in client/common/scss folder
3 | There should be no need to edit this file
4 | */
5 |
6 | // Common component styles are injected through grunt
7 | // injector
8 | // endinjector
9 |
10 | @import 'scss/common.scss';
--------------------------------------------------------------------------------
/client/common/scss/_colours.scss:
--------------------------------------------------------------------------------
1 | .common-class {
2 | background: #FF8AAC !important;
3 | color: #F5F5F2;
4 | }
--------------------------------------------------------------------------------
/client/common/scss/_fonts.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/common/scss/_fonts.scss
--------------------------------------------------------------------------------
/client/common/scss/_layout.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/common/scss/_layout.scss
--------------------------------------------------------------------------------
/client/common/scss/common.scss:
--------------------------------------------------------------------------------
1 | /**
2 | Include all your common styles in the files below
3 | */
4 |
5 | @import 'colours';
6 | @import 'fonts';
7 | @import 'layout';
--------------------------------------------------------------------------------
/client/ionic/scss/_colours.scss:
--------------------------------------------------------------------------------
1 | .ionic-class {
2 | background: #FFC384;
3 | color: #000000;
4 | }
--------------------------------------------------------------------------------
/client/ionic/scss/_fonts.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/ionic/scss/_fonts.scss
--------------------------------------------------------------------------------
/client/ionic/scss/_layout.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/ionic/scss/_layout.scss
--------------------------------------------------------------------------------
/client/ionic/scss/_variable_overrides.scss:
--------------------------------------------------------------------------------
1 | /*
2 | To customize the look and feel of Ionic, you can override variables in this file.
3 | (See all the variables you can override in client/ionic/www/lib/ionic/scss/_variables.scss.)
4 |
5 | NB: Don't include the !default flag here
6 |
7 | For example:
8 |
9 | $stable: #000000;
10 |
11 | */
12 |
--------------------------------------------------------------------------------
/client/ionic/scss/ionic.app.scss:
--------------------------------------------------------------------------------
1 |
2 | // The path for our ionicons font files, relative to the built CSS in www/css
3 | $ionicons-font-path: "../lib/ionic/fonts" !default;
4 |
5 | // Import any app variable overrides
6 | @import 'variable_overrides';
7 |
8 | // Include all of Ionic
9 | @import "../www/lib/ionic/scss/ionic";
10 |
11 | // Include app scss
12 | @import 'colours';
13 | @import 'fonts';
14 | @import 'layout';
--------------------------------------------------------------------------------
/client/ionic/www/img/ionic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/ionic/www/img/ionic.png
--------------------------------------------------------------------------------
/client/ionic/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/client/ionic/www/js/app.js:
--------------------------------------------------------------------------------
1 | // Ionic Starter App
2 |
3 | // angular.module is a global place for creating, registering and retrieving Angular modules
4 | // 'starter' is the name of this angular module example (also set in a attribute in index.html)
5 | // the 2nd parameter is an array of 'requires'
6 | // 'starter.services' is found in services.js
7 | // 'starter.controllers' is found in controllers.js
8 | angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
9 |
10 | .run(function($ionicPlatform) {
11 | $ionicPlatform.ready(function() {
12 | // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
13 | // for form inputs)
14 | if (window.cordova && window.cordova.plugins.Keyboard) {
15 | cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
16 | }
17 | if (window.StatusBar) {
18 | // org.apache.cordova.statusbar required
19 | StatusBar.styleDefault();
20 | }
21 | });
22 | })
23 |
24 | .config(function($stateProvider, $urlRouterProvider) {
25 |
26 | // Ionic uses AngularUI Router which uses the concept of states
27 | // Learn more here: https://github.com/angular-ui/ui-router
28 | // Set up the various states which the app can be in.
29 | // Each state's controller can be found in controllers.js
30 | $stateProvider
31 |
32 | // setup an abstract state for the tabs directive
33 | .state('tab', {
34 | url: "/tab",
35 | abstract: true,
36 | templateUrl: "templates/tabs.html"
37 | })
38 |
39 | // Each tab has its own nav history stack:
40 |
41 | .state('tab.dash', {
42 | url: '/dash',
43 | views: {
44 | 'tab-dash': {
45 | templateUrl: 'templates/tab-dash.html',
46 | controller: 'DashCtrl'
47 | }
48 | }
49 | })
50 |
51 | .state('tab.things', {
52 | url: '/things',
53 | views: {
54 | 'tab-things': {
55 | templateUrl: 'templates/tab-things.html',
56 | controller: 'ThingsCtrl'
57 | }
58 | }
59 | })
60 | .state('tab.thing-detail', {
61 | url: '/thing/:thingId',
62 | views: {
63 | 'tab-things': {
64 | templateUrl: 'templates/thing-detail.html',
65 | controller: 'ThingDetailCtrl'
66 | }
67 | }
68 | })
69 |
70 | .state('tab.account', {
71 | url: '/account',
72 | views: {
73 | 'tab-account': {
74 | templateUrl: 'templates/tab-account.html',
75 | controller: 'AccountCtrl'
76 | }
77 | }
78 | });
79 |
80 | // if none of the above states are matched, use this as the fallback
81 | $urlRouterProvider.otherwise('/tab/dash');
82 |
83 | });
84 |
--------------------------------------------------------------------------------
/client/ionic/www/js/controllers.js:
--------------------------------------------------------------------------------
1 | angular.module('starter.controllers', [])
2 |
3 | .controller('DashCtrl', function($scope) {})
4 |
5 | .controller('ThingsCtrl', function($scope, Things) {
6 | Things.all(function(err, things) {
7 | $scope.things = things
8 | });
9 | })
10 |
11 | .controller('ThingDetailCtrl', function($scope, $stateParams, Things) {
12 | Things.get($stateParams.thingId, function(err, thing) {
13 | $scope.thing = thing
14 | });
15 | })
16 |
17 | .controller('AccountCtrl', function($scope) {
18 | $scope.settings = {
19 | enableSomething: true
20 | };
21 | });
22 |
--------------------------------------------------------------------------------
/client/ionic/www/js/services.js:
--------------------------------------------------------------------------------
1 | angular.module('starter.services', [])
2 |
3 | /**
4 | * A simple example service that returns some data.
5 | */
6 | .factory('Things', function($http) {
7 | // Might use a resource here that returns a JSON array
8 |
9 | return {
10 | all: function(cb) {
11 | $http.get('/api/things')
12 | .success(function(data, status, headers, config) {
13 | console.log(data);
14 | cb(null, data);
15 | });
16 | },
17 | get: function(thingId, cb) {
18 | console.log('GET /api/things/' + thingId);
19 | $http.get('/api/things/' + thingId)
20 | .success(function(data, status, headers, config) {
21 | console.log(thingId, data);
22 | cb(null, data);
23 | });
24 | }
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/ionic/www/lib/ionic/fonts/ionicons.eot
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/ionic/www/lib/ionic/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/richardgsands/angular-fullstack-ionic-starter/d50735b8db0f55a0992a9b373bde5ce78e5d29e4/client/ionic/www/lib/ionic/fonts/ionicons.woff
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/js/angular/angular-resource.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.3.6
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=c;e--)d.end&&d.end(f[e]);f.length=c}}"string"!==typeof a&&(a=null===a||"undefined"===typeof a?"":""+a);var b,k,f=[],m=a,l;for(f.last=function(){return f[f.length-1]};a;){l="";k=!0;if(f.last()&&x[f.last()])a=a.replace(new RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(a,b){b=b.replace(H,"$1").replace(I,"$1");d.chars&&d.chars(r(b));return""}),e("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(d.comment&&d.comment(a.substring(4,
8 | b)),a=a.substring(b+3),k=!1);else if(y.test(a)){if(b=a.match(y))a=a.replace(b[0],""),k=!1}else if(J.test(a)){if(b=a.match(z))a=a.substring(b[0].length),b[0].replace(z,e),k=!1}else K.test(a)&&((b=a.match(A))?(b[4]&&(a=a.substring(b[0].length),b[0].replace(A,c)),k=!1):(l+="<",a=a.substring(1)));k&&(b=a.indexOf("<"),l+=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),d.chars&&d.chars(r(l)))}if(a==m)throw L("badparse",a);m=a}e()}function r(a){if(!a)return"";var d=M.exec(a);a=d[1];var c=d[3];if(d=d[2])q.innerHTML=
9 | d.replace(//g,">")}function s(a,d){var c=!1,e=h.bind(a,a.push);return{start:function(a,k,f){a=h.lowercase(a);!c&&x[a]&&(c=a);c||!0!==C[a]||(e("<"),e(a),h.forEach(k,function(c,f){var k=
10 | h.lowercase(f),g="img"===a&&"src"===k||"background"===k;!0!==P[k]||!0===D[k]&&!d(c,g)||(e(" "),e(f),e('="'),e(B(c)),e('"'))}),e(f?"/>":">"))},end:function(a){a=h.lowercase(a);c||!0!==C[a]||(e(""),e(a),e(">"));a==c&&(c=!1)},chars:function(a){c||e(B(a))}}}var L=h.$$minErr("$sanitize"),A=/^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/,z=/^<\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^,
11 | J=/^<\//,H=/\x3c!--(.*?)--\x3e/g,y=/]*?)>/i,I=/"\u201d\u2019]/,c=/^mailto:/;return function(e,b){function k(a){a&&g.push(E(a))}
15 | function f(a,c){g.push("');k(c);g.push("")}if(!e)return e;for(var m,l=e,g=[],n,p;m=l.match(d);)n=m[0],m[2]||m[4]||(n=(m[3]?"http://":"mailto:")+n),p=m.index,k(l.substr(0,p)),f(n,m[0].replace(c,"")),l=l.substring(p+m[0].length);k(l);return a(g.join(""))}}])})(window,window.angular);
16 | //# sourceMappingURL=angular-sanitize.min.js.map
17 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_action-sheet.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Action Sheets
3 | * --------------------------------------------------
4 | */
5 |
6 | .action-sheet-backdrop {
7 | @include transition(background-color 300ms ease-in-out);
8 | position: fixed;
9 | top: 0;
10 | left: 0;
11 | z-index: $z-index-action-sheet;
12 | width: 100%;
13 | height: 100%;
14 | background-color: rgba(0,0,0,0);
15 |
16 | &.active {
17 | background-color: rgba(0,0,0,0.5);
18 | }
19 | }
20 |
21 | .action-sheet-wrapper {
22 | @include translate3d(0, 100%, 0);
23 | @include transition(all ease-in-out 300ms);
24 | position: absolute;
25 | bottom: 0;
26 | width: 100%;
27 | }
28 |
29 | .action-sheet-up {
30 | @include translate3d(0, 0, 0);
31 | }
32 |
33 | .action-sheet {
34 | margin-left: 15px;
35 | margin-right: 15px;
36 | width: auto;
37 | z-index: $z-index-action-sheet;
38 | overflow: hidden;
39 |
40 | .button {
41 | display: block;
42 | padding: 1px;
43 | width: 100%;
44 | border-radius: 0;
45 |
46 | background-color: transparent;
47 |
48 | color: $positive;
49 | font-size: 18px;
50 |
51 | &.destructive {
52 | color: $assertive;
53 | }
54 | }
55 | }
56 |
57 | .action-sheet-title {
58 | padding: 10px;
59 | color: lighten($base-color, 40%);
60 | text-align: center;
61 | font-size: 12px;
62 | }
63 |
64 | .action-sheet-group {
65 | margin-bottom: 5px;
66 | border-radius: $sheet-border-radius;
67 | background-color: #fff;
68 | .button {
69 | border-width: 1px 0px 0px 0px;
70 | border-radius: 0;
71 |
72 | &.active {
73 | background-color: transparent;
74 | color: inherit;
75 | }
76 | }
77 | .button:first-child:last-child {
78 | border-width: 0;
79 | }
80 | }
81 |
82 | .action-sheet-open {
83 | pointer-events: none;
84 |
85 | &.modal-open .modal {
86 | pointer-events: none;
87 | }
88 |
89 | .action-sheet-backdrop {
90 | pointer-events: auto;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_animations.scss:
--------------------------------------------------------------------------------
1 |
2 | // Slide up from the bottom, used for modals
3 | // -------------------------------
4 |
5 | .slide-in-up {
6 | @include translate3d(0, 100%, 0);
7 | }
8 | .slide-in-up.ng-enter,
9 | .slide-in-up > .ng-enter {
10 | @include transition(all cubic-bezier(.1, .7, .1, 1) 400ms);
11 | }
12 | .slide-in-up.ng-enter-active,
13 | .slide-in-up > .ng-enter-active {
14 | @include translate3d(0, 0, 0);
15 | }
16 |
17 | .slide-in-up.ng-leave,
18 | .slide-in-up > .ng-leave {
19 | @include transition(all ease-in-out 250ms);
20 | }
21 |
22 |
23 | // Scale Out
24 | // Scale from hero (1 in this case) to zero
25 | // -------------------------------
26 |
27 | @-webkit-keyframes scaleOut {
28 | from { -webkit-transform: scale(1); opacity: 1; }
29 | to { -webkit-transform: scale(0.8); opacity: 0; }
30 | }
31 | @keyframes scaleOut {
32 | from { transform: scale(1); opacity: 1; }
33 | to { transform: scale(0.8); opacity: 0; }
34 | }
35 |
36 |
37 | // Super Scale In
38 | // Scale from super (1.x) to duper (1 in this case)
39 | // -------------------------------
40 |
41 | @-webkit-keyframes superScaleIn {
42 | from { -webkit-transform: scale(1.2); opacity: 0; }
43 | to { -webkit-transform: scale(1); opacity: 1 }
44 | }
45 | @keyframes superScaleIn {
46 | from { transform: scale(1.2); opacity: 0; }
47 | to { transform: scale(1); opacity: 1; }
48 | }
49 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_backdrop.scss:
--------------------------------------------------------------------------------
1 |
2 | .backdrop {
3 | position: fixed;
4 | top: 0;
5 | left: 0;
6 | z-index: $z-index-backdrop;
7 |
8 | width: 100%;
9 | height: 100%;
10 |
11 | background-color: $loading-backdrop-bg-color;
12 |
13 | visibility: hidden;
14 | opacity: 0;
15 |
16 | &.visible {
17 | visibility: visible;
18 | }
19 | &.active {
20 | opacity: 1;
21 | }
22 |
23 | @include transition($loading-backdrop-fadein-duration opacity linear);
24 | }
25 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_badge.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Badges
4 | * --------------------------------------------------
5 | */
6 |
7 | .badge {
8 | @include badge-style($badge-default-bg, $badge-default-text);
9 | z-index: $z-index-badge;
10 | display: inline-block;
11 | padding: 3px 8px;
12 | min-width: 10px;
13 | border-radius: $badge-border-radius;
14 | vertical-align: baseline;
15 | text-align: center;
16 | white-space: nowrap;
17 | font-weight: $badge-font-weight;
18 | font-size: $badge-font-size;
19 | line-height: $badge-line-height;
20 |
21 | &:empty {
22 | display: none;
23 | }
24 | }
25 |
26 | //Be sure to override specificity of rule that 'badge color matches tab color by default'
27 | .tabs .tab-item .badge,
28 | .badge {
29 | &.badge-light {
30 | @include badge-style($badge-light-bg, $badge-light-text);
31 | }
32 | &.badge-stable {
33 | @include badge-style($badge-stable-bg, $badge-stable-text);
34 | }
35 | &.badge-positive {
36 | @include badge-style($badge-positive-bg, $badge-positive-text);
37 | }
38 | &.badge-calm {
39 | @include badge-style($badge-calm-bg, $badge-calm-text);
40 | }
41 | &.badge-assertive {
42 | @include badge-style($badge-assertive-bg, $badge-assertive-text);
43 | }
44 | &.badge-balanced {
45 | @include badge-style($badge-balanced-bg, $badge-balanced-text);
46 | }
47 | &.badge-energized {
48 | @include badge-style($badge-energized-bg, $badge-energized-text);
49 | }
50 | &.badge-royal {
51 | @include badge-style($badge-royal-bg, $badge-royal-text);
52 | }
53 | &.badge-dark {
54 | @include badge-style($badge-dark-bg, $badge-dark-text);
55 | }
56 | }
57 |
58 | // Quick fix for labels/badges in buttons
59 | .button .badge {
60 | position: relative;
61 | top: -1px;
62 | }
63 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_button-bar.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Button Bar
4 | * --------------------------------------------------
5 | */
6 |
7 | .button-bar {
8 | @include display-flex();
9 | @include flex(1);
10 | width: 100%;
11 |
12 | &.button-bar-inline {
13 | display: block;
14 | width: auto;
15 |
16 | @include clearfix();
17 |
18 | > .button {
19 | width: auto;
20 | display: inline-block;
21 | float: left;
22 | }
23 | }
24 | }
25 |
26 | .button-bar > .button {
27 | @include flex(1);
28 | display: block;
29 |
30 | overflow: hidden;
31 |
32 | padding: 0 16px;
33 |
34 | width: 0;
35 |
36 | border-width: 1px 0px 1px 1px;
37 | border-radius: 0;
38 | text-align: center;
39 | text-overflow: ellipsis;
40 | white-space: nowrap;
41 |
42 | &:before,
43 | .icon:before {
44 | line-height: 44px;
45 | }
46 |
47 | &:first-child {
48 | border-radius: $button-border-radius 0px 0px $button-border-radius;
49 | }
50 | &:last-child {
51 | border-right-width: 1px;
52 | border-radius: 0px $button-border-radius $button-border-radius 0px;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_button.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Buttons
4 | * --------------------------------------------------
5 | */
6 |
7 | .button {
8 | // set the color defaults
9 | @include button-style($button-default-bg, $button-default-border, $button-default-active-bg, $button-default-active-border, $button-default-text);
10 |
11 | position: relative;
12 | display: inline-block;
13 | margin: 0;
14 | padding: 0 $button-padding;
15 |
16 | min-width: ($button-padding * 3) + $button-font-size;
17 | min-height: $button-height + 5px;
18 |
19 | border-width: $button-border-width;
20 | border-style: solid;
21 | border-radius: $button-border-radius;
22 |
23 | vertical-align: top;
24 | text-align: center;
25 |
26 | text-overflow: ellipsis;
27 | font-size: $button-font-size;
28 | line-height: $button-height - $button-border-width + 1px;
29 |
30 | cursor: pointer;
31 |
32 | &:after {
33 | // used to create a larger button "hit" area
34 | position: absolute;
35 | top: -6px;
36 | right: -6px;
37 | bottom: -6px;
38 | left: -6px;
39 | content: ' ';
40 | }
41 |
42 | .icon {
43 | vertical-align: top;
44 | pointer-events: none;
45 | }
46 |
47 | .icon:before,
48 | &.icon:before,
49 | &.icon-left:before,
50 | &.icon-right:before {
51 | display: inline-block;
52 | padding: 0 0 $button-border-width 0;
53 | vertical-align: inherit;
54 | font-size: $button-icon-size;
55 | line-height: $button-height - $button-border-width;
56 | pointer-events: none;
57 | }
58 | &.icon-left:before {
59 | float: left;
60 | padding-right: .2em;
61 | padding-left: 0;
62 | }
63 | &.icon-right:before {
64 | float: right;
65 | padding-right: 0;
66 | padding-left: .2em;
67 | }
68 |
69 | &.button-block, &.button-full {
70 | margin-top: $button-block-margin;
71 | margin-bottom: $button-block-margin;
72 | }
73 |
74 | &.button-light {
75 | @include button-style($button-light-bg, $button-light-border, $button-light-active-bg, $button-light-active-border, $button-light-text);
76 | @include button-clear($button-light-border);
77 | @include button-outline($button-light-border);
78 | }
79 |
80 | &.button-stable {
81 | @include button-style($button-stable-bg, $button-stable-border, $button-stable-active-bg, $button-stable-active-border, $button-stable-text);
82 | @include button-clear($button-stable-border);
83 | @include button-outline($button-stable-border);
84 | }
85 |
86 | &.button-positive {
87 | @include button-style($button-positive-bg, $button-positive-border, $button-positive-active-bg, $button-positive-active-border, $button-positive-text);
88 | @include button-clear($button-positive-bg);
89 | @include button-outline($button-positive-bg);
90 | }
91 |
92 | &.button-calm {
93 | @include button-style($button-calm-bg, $button-calm-border, $button-calm-active-bg, $button-calm-active-border, $button-calm-text);
94 | @include button-clear($button-calm-bg);
95 | @include button-outline($button-calm-bg);
96 | }
97 |
98 | &.button-assertive {
99 | @include button-style($button-assertive-bg, $button-assertive-border, $button-assertive-active-bg, $button-assertive-active-border, $button-assertive-text);
100 | @include button-clear($button-assertive-bg);
101 | @include button-outline($button-assertive-bg);
102 | }
103 |
104 | &.button-balanced {
105 | @include button-style($button-balanced-bg, $button-balanced-border, $button-balanced-active-bg, $button-balanced-active-border, $button-balanced-text);
106 | @include button-clear($button-balanced-bg);
107 | @include button-outline($button-balanced-bg);
108 | }
109 |
110 | &.button-energized {
111 | @include button-style($button-energized-bg, $button-energized-border, $button-energized-active-bg, $button-energized-active-border, $button-energized-text);
112 | @include button-clear($button-energized-bg);
113 | @include button-outline($button-energized-bg);
114 | }
115 |
116 | &.button-royal {
117 | @include button-style($button-royal-bg, $button-royal-border, $button-royal-active-bg, $button-royal-active-border, $button-royal-text);
118 | @include button-clear($button-royal-bg);
119 | @include button-outline($button-royal-bg);
120 | }
121 |
122 | &.button-dark {
123 | @include button-style($button-dark-bg, $button-dark-border, $button-dark-active-bg, $button-dark-active-border, $button-dark-text);
124 | @include button-clear($button-dark-bg);
125 | @include button-outline($button-dark-bg);
126 | }
127 | }
128 |
129 | .button-small {
130 | padding: 2px $button-small-padding 1px;
131 | min-width: $button-small-height;
132 | min-height: $button-small-height + 2;
133 | font-size: $button-small-font-size;
134 | line-height: $button-small-height - $button-border-width - 1;
135 |
136 | .icon:before,
137 | &.icon:before,
138 | &.icon-left:before,
139 | &.icon-right:before {
140 | font-size: $button-small-icon-size;
141 | line-height: $button-small-icon-size + 3;
142 | margin-top: 3px;
143 | }
144 | }
145 |
146 | .button-large {
147 | padding: 0 $button-large-padding;
148 | min-width: ($button-large-padding * 3) + $button-large-font-size;
149 | min-height: $button-large-height + 5;
150 | font-size: $button-large-font-size;
151 | line-height: $button-large-height - $button-border-width;
152 |
153 | .icon:before,
154 | &.icon:before,
155 | &.icon-left:before,
156 | &.icon-right:before {
157 | padding-bottom: ($button-border-width * 2);
158 | font-size: $button-large-icon-size;
159 | line-height: $button-large-height - ($button-border-width * 2) - 1;
160 | }
161 | }
162 |
163 | .button-icon {
164 | @include transition(opacity .1s);
165 | padding: 0 6px;
166 | min-width: initial;
167 | border-color: transparent;
168 | background: none;
169 |
170 | &.button.active,
171 | &.button.activated {
172 | border-color: transparent;
173 | background: none;
174 | box-shadow: none;
175 | opacity: 0.3;
176 | }
177 |
178 | .icon:before,
179 | &.icon:before {
180 | font-size: $button-large-icon-size;
181 | }
182 | }
183 |
184 | .button-clear {
185 | @include button-clear($button-default-border);
186 | @include transition(opacity .1s);
187 | padding: 0 $button-clear-padding;
188 | max-height: $button-height;
189 | border-color: transparent;
190 | background: none;
191 | box-shadow: none;
192 |
193 | &.active,
194 | &.activated {
195 | opacity: 0.3;
196 | }
197 | }
198 |
199 | .button-outline {
200 | @include button-outline($button-default-border);
201 | @include transition(opacity .1s);
202 | background: none;
203 | box-shadow: none;
204 | }
205 |
206 | .padding > .button.button-block:first-child {
207 | margin-top: 0;
208 | }
209 |
210 | .button-block {
211 | display: block;
212 | clear: both;
213 |
214 | &:after {
215 | clear: both;
216 | }
217 | }
218 |
219 | .button-full,
220 | .button-full > .button {
221 | display: block;
222 | margin-right: 0;
223 | margin-left: 0;
224 | border-right-width: 0;
225 | border-left-width: 0;
226 | border-radius: 0;
227 | }
228 |
229 | button.button-block,
230 | button.button-full,
231 | .button-full > button.button,
232 | input.button.button-block {
233 | width: 100%;
234 | }
235 |
236 | a.button {
237 | text-decoration: none;
238 |
239 | .icon:before,
240 | &.icon:before,
241 | &.icon-left:before,
242 | &.icon-right:before {
243 | margin-top: 2px;
244 | }
245 | }
246 |
247 | .button.disabled,
248 | .button[disabled] {
249 | opacity: .4;
250 | cursor: default !important;
251 | pointer-events: none;
252 | }
253 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_checkbox.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Checkbox
4 | * --------------------------------------------------
5 | */
6 |
7 | .checkbox {
8 | // set the color defaults
9 | @include checkbox-style($checkbox-off-border-default, $checkbox-on-bg-default, $checkbox-on-border-default);
10 |
11 | position: relative;
12 | display: inline-block;
13 | padding: ($checkbox-height / 4) ($checkbox-width / 4);
14 | cursor: pointer;
15 | }
16 | .checkbox-light {
17 | @include checkbox-style($checkbox-off-border-light, $checkbox-on-bg-light, $checkbox-off-border-light);
18 | }
19 | .checkbox-stable {
20 | @include checkbox-style($checkbox-off-border-stable, $checkbox-on-bg-stable, $checkbox-off-border-stable);
21 | }
22 | .checkbox-positive {
23 | @include checkbox-style($checkbox-off-border-positive, $checkbox-on-bg-positive, $checkbox-off-border-positive);
24 | }
25 | .checkbox-calm {
26 | @include checkbox-style($checkbox-off-border-calm, $checkbox-on-bg-calm, $checkbox-off-border-calm);
27 | }
28 | .checkbox-assertive {
29 | @include checkbox-style($checkbox-off-border-assertive, $checkbox-on-bg-assertive, $checkbox-off-border-assertive);
30 | }
31 | .checkbox-balanced {
32 | @include checkbox-style($checkbox-off-border-balanced, $checkbox-on-bg-balanced, $checkbox-off-border-balanced);
33 | }
34 | .checkbox-energized{
35 | @include checkbox-style($checkbox-off-border-energized, $checkbox-on-bg-energized, $checkbox-off-border-energized);
36 | }
37 | .checkbox-royal {
38 | @include checkbox-style($checkbox-off-border-royal, $checkbox-on-bg-royal, $checkbox-off-border-royal);
39 | }
40 | .checkbox-dark {
41 | @include checkbox-style($checkbox-off-border-dark, $checkbox-on-bg-dark, $checkbox-off-border-dark);
42 | }
43 |
44 | .checkbox input:disabled:before,
45 | .checkbox input:disabled + .checkbox-icon:before {
46 | border-color: $checkbox-off-border-light;
47 | }
48 |
49 | .checkbox input:disabled:checked:before,
50 | .checkbox input:disabled:checked + .checkbox-icon:before {
51 | background: $checkbox-on-bg-light;
52 | }
53 |
54 |
55 | .checkbox.checkbox-input-hidden input {
56 | display: none !important;
57 | }
58 |
59 | .checkbox input,
60 | .checkbox-icon {
61 | position: relative;
62 | width: $checkbox-width;
63 | height: $checkbox-height;
64 | display: block;
65 | border: 0;
66 | background: transparent;
67 | cursor: pointer;
68 | -webkit-appearance: none;
69 |
70 | &:before {
71 | // what the checkbox looks like when its not checked
72 | display: table;
73 | width: 100%;
74 | height: 100%;
75 | border-width: $checkbox-border-width;
76 | border-style: solid;
77 | border-radius: $checkbox-border-radius;
78 | background: $checkbox-off-bg-color;
79 | content: ' ';
80 | @include transition(background-color 20ms ease-in-out);
81 | }
82 | }
83 |
84 | .checkbox input:checked:before,
85 | input:checked + .checkbox-icon:before {
86 | border-width: $checkbox-border-width + 1;
87 | }
88 |
89 | // the checkmark within the box
90 | .checkbox input:after,
91 | .checkbox-icon:after {
92 | @include transition(opacity .05s ease-in-out);
93 | @include rotate(-45deg);
94 | position: absolute;
95 | top: 33%;
96 | left: 25%;
97 | display: table;
98 | width: ($checkbox-width / 2);
99 | height: ($checkbox-width / 4) - 1;
100 | border: $checkbox-check-width solid $checkbox-check-color;
101 | border-top: 0;
102 | border-right: 0;
103 | content: ' ';
104 | opacity: 0;
105 | }
106 |
107 | .platform-android .checkbox-platform input:before,
108 | .platform-android .checkbox-platform .checkbox-icon:before,
109 | .checkbox-square input:before,
110 | .checkbox-square .checkbox-icon:before {
111 | border-radius: 2px;
112 | width: 72%;
113 | height: 72%;
114 | margin-top: 14%;
115 | margin-left: 14%;
116 | border-width: 2px;
117 | }
118 |
119 | .platform-android .checkbox-platform input:after,
120 | .platform-android .checkbox-platform .checkbox-icon:after,
121 | .checkbox-square input:after,
122 | .checkbox-square .checkbox-icon:after {
123 | border-width: 2px;
124 | top: 19%;
125 | left: 25%;
126 | width: ($checkbox-width / 2) - 1;
127 | height: 7px;
128 | }
129 |
130 | .grade-c .checkbox input:after,
131 | .grade-c .checkbox-icon:after {
132 | @include rotate(0);
133 | top: 3px;
134 | left: 4px;
135 | border: none;
136 | color: $checkbox-check-color;
137 | content: '\2713';
138 | font-weight: bold;
139 | font-size: 20px;
140 | }
141 |
142 | // what the checkmark looks like when its checked
143 | .checkbox input:checked:after,
144 | input:checked + .checkbox-icon:after {
145 | opacity: 1;
146 | }
147 |
148 | // make sure item content have enough padding on left to fit the checkbox
149 | .item-checkbox {
150 | padding-left: ($item-padding * 2) + $checkbox-width;
151 |
152 | &.active {
153 | box-shadow: none;
154 | }
155 | }
156 |
157 | // position the checkbox to the left within an item
158 | .item-checkbox .checkbox {
159 | position: absolute;
160 | top: 50%;
161 | right: $item-padding / 2;
162 | left: $item-padding / 2;
163 | z-index: $z-index-item-checkbox;
164 | margin-top: (($checkbox-height + ($checkbox-height / 2)) / 2) * -1;
165 | }
166 |
167 |
168 | .item-checkbox.item-checkbox-right {
169 | padding-right: ($item-padding * 2) + $checkbox-width;
170 | padding-left: $item-padding;
171 | }
172 |
173 | .item-checkbox-right .checkbox input,
174 | .item-checkbox-right .checkbox-icon {
175 | float: right;
176 | }
177 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_form.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Forms
3 | * --------------------------------------------------
4 | */
5 |
6 | // Make all forms have space below them
7 | form {
8 | margin: 0 0 $line-height-base;
9 | }
10 |
11 | // Groups of fields with labels on top (legends)
12 | legend {
13 | display: block;
14 | margin-bottom: $line-height-base;
15 | padding: 0;
16 | width: 100%;
17 | border: $input-border-width solid $input-border;
18 | color: $dark;
19 | font-size: $font-size-base * 1.5;
20 | line-height: $line-height-base * 2;
21 |
22 | small {
23 | color: $stable;
24 | font-size: $line-height-base * .75;
25 | }
26 | }
27 |
28 | // Set font for forms
29 | label,
30 | input,
31 | button,
32 | select,
33 | textarea {
34 | @include font-shorthand($font-size-base, normal, $line-height-base); // Set size, weight, line-height here
35 | }
36 | input,
37 | button,
38 | select,
39 | textarea {
40 | font-family: $font-family-base; // And only set font-family here for those that need it (note the missing label element)
41 | }
42 |
43 |
44 | // Input List
45 | // -------------------------------
46 |
47 | .item-input {
48 | @include display-flex();
49 | @include align-items(center);
50 | position: relative;
51 | overflow: hidden;
52 | padding: 6px 0 5px 16px;
53 |
54 | input {
55 | @include border-radius(0);
56 | @include flex(1, 0, 220px);
57 | @include appearance(none);
58 | margin: 0;
59 | padding-right: 24px;
60 | background-color: transparent;
61 | }
62 |
63 | .button .icon {
64 | @include flex(0, 0, 24px);
65 | position: static;
66 | display: inline-block;
67 | height: auto;
68 | text-align: center;
69 | font-size: 16px;
70 | }
71 |
72 | .button-bar {
73 | @include border-radius(0);
74 | @include flex(1, 0, 220px);
75 | @include appearance(none);
76 | }
77 |
78 | .icon {
79 | min-width: 14px;
80 | }
81 | }
82 |
83 | .item-input-inset {
84 | @include display-flex();
85 | @include align-items(center);
86 | position: relative;
87 | overflow: hidden;
88 | padding: ($item-padding / 3) * 2;
89 | }
90 |
91 | .item-input-wrapper {
92 | @include display-flex();
93 | @include flex(1, 0);
94 | @include align-items(center);
95 | @include border-radius(4px);
96 | padding-right: 8px;
97 | padding-left: 8px;
98 | background: #eee;
99 | }
100 |
101 | .item-input-inset .item-input-wrapper input {
102 | padding-left: 4px;
103 | height: 29px;
104 | background: transparent;
105 | line-height: 18px;
106 | }
107 |
108 | .item-input-wrapper ~ .button {
109 | margin-left: ($item-padding / 3) * 2;
110 | }
111 |
112 | .input-label {
113 | @include flex(1, 0, 100px);
114 | display: table;
115 | padding: 7px 10px 7px 0px;
116 | max-width: 200px;
117 | width: 35%;
118 | color: $input-label-color;
119 | font-size: 16px;
120 | }
121 |
122 | .placeholder-icon {
123 | color: #aaa;
124 | &:first-child {
125 | padding-right: 6px;
126 | }
127 | &:last-child {
128 | padding-left: 6px;
129 | }
130 | }
131 |
132 | .item-stacked-label {
133 | display: block;
134 | background-color: transparent;
135 | box-shadow: none;
136 |
137 | .input-label, .icon {
138 | display: inline-block;
139 | padding: 4px 0 0 0px;
140 | vertical-align: middle;
141 | }
142 | }
143 |
144 | .item-stacked-label input,
145 | .item-stacked-label textarea {
146 | @include border-radius(2px);
147 | padding: 4px 8px 3px 0;
148 | border: none;
149 | background-color: $input-bg;
150 | }
151 | .item-stacked-label input {
152 | overflow: hidden;
153 | height: $line-height-computed + $font-size-base + 12px;
154 | }
155 |
156 | .item-floating-label {
157 | display: block;
158 | background-color: transparent;
159 | box-shadow: none;
160 |
161 | .input-label {
162 | position: relative;
163 | padding: 5px 0 0 0;
164 | opacity: 0;
165 | top: 10px;
166 | @include transition(opacity .15s ease-in, top .2s linear);
167 |
168 | &.has-input {
169 | opacity: 1;
170 | top: 0;
171 | @include transition(opacity .15s ease-in, top .2s linear);
172 | }
173 | }
174 | }
175 |
176 |
177 | // Form Controls
178 | // -------------------------------
179 |
180 | // Shared size and type resets
181 | textarea,
182 | input[type="text"],
183 | input[type="password"],
184 | input[type="datetime"],
185 | input[type="datetime-local"],
186 | input[type="date"],
187 | input[type="month"],
188 | input[type="time"],
189 | input[type="week"],
190 | input[type="number"],
191 | input[type="email"],
192 | input[type="url"],
193 | input[type="search"],
194 | input[type="tel"],
195 | input[type="color"] {
196 | display: block;
197 | padding-top: 2px;
198 | padding-left: 0;
199 | height: $line-height-computed + $font-size-base;
200 | color: $input-color;
201 | vertical-align: middle;
202 | font-size: $font-size-base;
203 | line-height: $font-size-base + 2;
204 | }
205 |
206 | .platform-ios,
207 | .platform-android {
208 | input[type="datetime-local"],
209 | input[type="date"],
210 | input[type="month"],
211 | input[type="time"],
212 | input[type="week"] {
213 | padding-top: 8px;
214 | }
215 | }
216 |
217 | input,
218 | textarea {
219 | width: 100%;
220 | }
221 | textarea {
222 | padding-left: 0;
223 | @include placeholder($input-color-placeholder, -3px);
224 | }
225 |
226 | // Reset height since textareas have rows
227 | textarea {
228 | height: auto;
229 | }
230 |
231 | // Everything else
232 | textarea,
233 | input[type="text"],
234 | input[type="password"],
235 | input[type="datetime"],
236 | input[type="datetime-local"],
237 | input[type="date"],
238 | input[type="month"],
239 | input[type="time"],
240 | input[type="week"],
241 | input[type="number"],
242 | input[type="email"],
243 | input[type="url"],
244 | input[type="search"],
245 | input[type="tel"],
246 | input[type="color"] {
247 | border: 0;
248 | }
249 |
250 | // Position radios and checkboxes better
251 | input[type="radio"],
252 | input[type="checkbox"] {
253 | margin: 0;
254 | line-height: normal;
255 | }
256 |
257 | // Reset width of input images, buttons, radios, checkboxes
258 | input[type="file"],
259 | input[type="image"],
260 | input[type="submit"],
261 | input[type="reset"],
262 | input[type="button"],
263 | input[type="radio"],
264 | input[type="checkbox"] {
265 | width: auto; // Override of generic input selector
266 | }
267 |
268 | // Set the height of file to match text inputs
269 | input[type="file"] {
270 | line-height: $input-height-base;
271 | }
272 |
273 | // Text input classes to hide text caret during scroll
274 | .previous-input-focus,
275 | .cloned-text-input + input,
276 | .cloned-text-input + textarea {
277 | position: absolute !important;
278 | left: -9999px;
279 | width: 200px;
280 | }
281 |
282 |
283 | // Placeholder
284 | // -------------------------------
285 | input,
286 | textarea {
287 | @include placeholder();
288 | }
289 |
290 |
291 | // DISABLED STATE
292 | // -------------------------------
293 |
294 | // Disabled and read-only inputs
295 | input[disabled],
296 | select[disabled],
297 | textarea[disabled],
298 | input[readonly]:not(.cloned-text-input),
299 | textarea[readonly]:not(.cloned-text-input),
300 | select[readonly] {
301 | background-color: $input-bg-disabled;
302 | cursor: not-allowed;
303 | }
304 | // Explicitly reset the colors here
305 | input[type="radio"][disabled],
306 | input[type="checkbox"][disabled],
307 | input[type="radio"][readonly],
308 | input[type="checkbox"][readonly] {
309 | background-color: transparent;
310 | }
311 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_grid.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Grid
3 | * --------------------------------------------------
4 | * Using flexbox for the grid, inspired by Philip Walton:
5 | * http://philipwalton.github.io/solved-by-flexbox/demos/grids/
6 | * By default each .col within a .row will evenly take up
7 | * available width, and the height of each .col with take
8 | * up the height of the tallest .col in the same .row.
9 | */
10 |
11 | .row {
12 | @include display-flex();
13 | padding: ($grid-padding-width / 2);
14 | width: 100%;
15 | }
16 |
17 | .row-wrap {
18 | @include flex-wrap(wrap);
19 | }
20 |
21 | .row + .row {
22 | margin-top: ($grid-padding-width / 2) * -1;
23 | padding-top: 0;
24 | }
25 |
26 | .col {
27 | @include flex(1);
28 | display: block;
29 | padding: ($grid-padding-width / 2);
30 | width: 100%;
31 | }
32 |
33 |
34 | /* Vertically Align Columns */
35 | /* .row-* vertically aligns every .col in the .row */
36 | .row-top {
37 | @include align-items(flex-start);
38 | }
39 | .row-bottom {
40 | @include align-items(flex-end);
41 | }
42 | .row-center {
43 | @include align-items(center);
44 | }
45 | .row-stretch {
46 | @include align-items(stretch);
47 | }
48 | .row-baseline {
49 | @include align-items(baseline);
50 | }
51 |
52 | /* .col-* vertically aligns an individual .col */
53 | .col-top {
54 | @include align-self(flex-start);
55 | }
56 | .col-bottom {
57 | @include align-self(flex-end);
58 | }
59 | .col-center {
60 | @include align-self(center);
61 | }
62 |
63 | /* Column Offsets */
64 | .col-offset-10 {
65 | margin-left: 10%;
66 | }
67 | .col-offset-20 {
68 | margin-left: 20%;
69 | }
70 | .col-offset-25 {
71 | margin-left: 25%;
72 | }
73 | .col-offset-33, .col-offset-34 {
74 | margin-left: 33.3333%;
75 | }
76 | .col-offset-50 {
77 | margin-left: 50%;
78 | }
79 | .col-offset-66, .col-offset-67 {
80 | margin-left: 66.6666%;
81 | }
82 | .col-offset-75 {
83 | margin-left: 75%;
84 | }
85 | .col-offset-80 {
86 | margin-left: 80%;
87 | }
88 | .col-offset-90 {
89 | margin-left: 90%;
90 | }
91 |
92 |
93 | /* Explicit Column Percent Sizes */
94 | /* By default each grid column will evenly distribute */
95 | /* across the grid. However, you can specify individual */
96 | /* columns to take up a certain size of the available area */
97 | .col-10 {
98 | @include flex(0, 0, 10%);
99 | max-width: 10%;
100 | }
101 | .col-20 {
102 | @include flex(0, 0, 20%);
103 | max-width: 20%;
104 | }
105 | .col-25 {
106 | @include flex(0, 0, 25%);
107 | max-width: 25%;
108 | }
109 | .col-33, .col-34 {
110 | @include flex(0, 0, 33.3333%);
111 | max-width: 33.3333%;
112 | }
113 | .col-50 {
114 | @include flex(0, 0, 50%);
115 | max-width: 50%;
116 | }
117 | .col-66, .col-67 {
118 | @include flex(0, 0, 66.6666%);
119 | max-width: 66.6666%;
120 | }
121 | .col-75 {
122 | @include flex(0, 0, 75%);
123 | max-width: 75%;
124 | }
125 | .col-80 {
126 | @include flex(0, 0, 80%);
127 | max-width: 80%;
128 | }
129 | .col-90 {
130 | @include flex(0, 0, 90%);
131 | max-width: 90%;
132 | }
133 |
134 |
135 | /* Responsive Grid Classes */
136 | /* Adding a class of responsive-X to a row */
137 | /* will trigger the flex-direction to */
138 | /* change to column and add some margin */
139 | /* to any columns in the row for clearity */
140 |
141 | @include responsive-grid-break('.responsive-sm', $grid-responsive-sm-break);
142 | @include responsive-grid-break('.responsive-md', $grid-responsive-md-break);
143 | @include responsive-grid-break('.responsive-lg', $grid-responsive-lg-break);
144 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_list.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Lists
4 | * --------------------------------------------------
5 | */
6 |
7 | .list {
8 | position: relative;
9 | padding-top: $item-border-width;
10 | padding-bottom: $item-border-width;
11 | padding-left: 0; // reset padding because ul and ol
12 | margin-bottom: 20px;
13 | }
14 | .list:last-child {
15 | margin-bottom: 0px;
16 | &.card{
17 | margin-bottom:40px;
18 | }
19 | }
20 |
21 |
22 | /**
23 | * List Header
24 | * --------------------------------------------------
25 | */
26 |
27 | .list-header {
28 | margin-top: $list-header-margin-top;
29 | padding: $list-header-padding;
30 | background-color: $list-header-bg;
31 | color: $list-header-color;
32 | font-weight: bold;
33 | }
34 |
35 | // when its a card make sure it doesn't duplicate top and bottom borders
36 | .card.list .list-item {
37 | padding-right: 1px;
38 | padding-left: 1px;
39 | }
40 |
41 |
42 | /**
43 | * Cards and Inset Lists
44 | * --------------------------------------------------
45 | * A card and list-inset are close to the same thing, except a card as a box shadow.
46 | */
47 |
48 | .card,
49 | .list-inset {
50 | overflow: hidden;
51 | margin: ($content-padding * 2) $content-padding;
52 | border-radius: $card-border-radius;
53 | background-color: $card-body-bg;
54 | }
55 |
56 | .card {
57 | padding-top: $item-border-width;
58 | padding-bottom: $item-border-width;
59 | box-shadow: $card-box-shadow;
60 |
61 | .item {
62 | border-left: 0;
63 | border-right: 0;
64 | }
65 | .item:first-child {
66 | border-top: 0;
67 | }
68 | .item:last-child {
69 | border-bottom: 0;
70 | }
71 | }
72 |
73 | .padding {
74 | .card, .list-inset {
75 | margin-left: 0;
76 | margin-right: 0;
77 | }
78 | }
79 |
80 | .card .item,
81 | .list-inset .item,
82 | .padding > .list .item
83 | {
84 | &:first-child {
85 | border-top-left-radius: $card-border-radius;
86 | border-top-right-radius: $card-border-radius;
87 |
88 | .item-content {
89 | border-top-left-radius: $card-border-radius;
90 | border-top-right-radius: $card-border-radius;
91 | }
92 | }
93 | &:last-child {
94 | border-bottom-right-radius: $card-border-radius;
95 | border-bottom-left-radius: $card-border-radius;
96 |
97 | .item-content {
98 | border-bottom-right-radius: $card-border-radius;
99 | border-bottom-left-radius: $card-border-radius;
100 | }
101 | }
102 | }
103 |
104 | .card .item:last-child,
105 | .list-inset .item:last-child {
106 | margin-bottom: $item-border-width * -1;
107 | }
108 |
109 | .card .item,
110 | .list-inset .item,
111 | .padding > .list .item,
112 | .padding-horizontal > .list .item {
113 | margin-right: 0;
114 | margin-left: 0;
115 |
116 | &.item-input input {
117 | padding-right: 44px;
118 | }
119 | }
120 | .padding-left > .list .item {
121 | margin-left: 0;
122 | }
123 | .padding-right > .list .item {
124 | margin-right: 0;
125 | }
126 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_loading.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Loading
4 | * --------------------------------------------------
5 | */
6 |
7 | .loading-container {
8 | position: absolute;
9 | left: 0;
10 | top: 0;
11 | right: 0;
12 | bottom: 0;
13 |
14 | z-index: $z-index-loading;
15 |
16 | @include display-flex();
17 | @include justify-content(center);
18 | @include align-items(center);
19 |
20 | @include transition(0.2s opacity linear);
21 | visibility: hidden;
22 | opacity: 0;
23 |
24 | &:not(.visible) .icon {
25 | display: none;
26 | }
27 | &.visible {
28 | visibility: visible;
29 | }
30 | &.active {
31 | opacity: 1;
32 | }
33 |
34 | .loading {
35 | padding: $loading-padding;
36 |
37 | border-radius: $loading-border-radius;
38 | background-color: $loading-bg-color;
39 |
40 | color: $loading-text-color;
41 |
42 | text-align: center;
43 | text-overflow: ellipsis;
44 | font-size: $loading-font-size;
45 |
46 | h1, h2, h3, h4, h5, h6 {
47 | color: $loading-text-color;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_menu.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Menus
4 | * --------------------------------------------------
5 | * Side panel structure
6 | */
7 |
8 | .menu {
9 | position: absolute;
10 | top: 0;
11 | bottom: 0;
12 | z-index: $z-index-menu;
13 | overflow: hidden;
14 |
15 | min-height: 100%;
16 | max-height: 100%;
17 | width: $menu-width;
18 |
19 | background-color: $menu-bg;
20 |
21 | .scroll-content {
22 | z-index: $z-index-menu-scroll-content;
23 | }
24 |
25 | .bar-header {
26 | z-index: $z-index-menu-bar-header;
27 | }
28 | }
29 |
30 | .menu-content {
31 | @include transform(none);
32 | box-shadow: $menu-side-shadow;
33 | }
34 |
35 | .menu-open .menu-content .pane,
36 | .menu-open .menu-content .scroll-content {
37 | pointer-events: none;
38 | }
39 |
40 | .grade-b .menu-content,
41 | .grade-c .menu-content {
42 | @include box-sizing(content-box);
43 | right: -1px;
44 | left: -1px;
45 | border-right: 1px solid #ccc;
46 | border-left: 1px solid #ccc;
47 | box-shadow: none;
48 | }
49 |
50 | .menu-left {
51 | left: 0;
52 | }
53 |
54 | .menu-right {
55 | right: 0;
56 | }
57 |
58 | .aside-open.aside-resizing .menu-right {
59 | display: none;
60 | }
61 |
62 | .menu-animated {
63 | @include transition-transform($menu-animation-speed ease);
64 | }
65 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_modal.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Modals
4 | * --------------------------------------------------
5 | * Modals are independent windows that slide in from off-screen.
6 | */
7 |
8 | .modal-backdrop {
9 | @include transition(background-color 300ms ease-in-out);
10 | position: fixed;
11 | top: 0;
12 | left: 0;
13 | z-index: $z-index-modal;
14 | width: 100%;
15 | height: 100%;
16 | background-color: $modal-backdrop-bg-inactive;
17 |
18 | &.active {
19 | background-color: $modal-backdrop-bg-active;
20 | }
21 | }
22 |
23 | .modal {
24 | display: block;
25 | position: absolute;
26 | top: 0;
27 | z-index: $z-index-modal;
28 | overflow: hidden;
29 | min-height: 100%;
30 | width: 100%;
31 | background-color: $modal-bg-color;
32 | }
33 |
34 | @media (min-width: $modal-inset-mode-break-point) {
35 | // inset mode is when the modal doesn't fill the entire
36 | // display but instead is centered within a large display
37 | .modal {
38 | top: $modal-inset-mode-top;
39 | right: $modal-inset-mode-right;
40 | bottom: $modal-inset-mode-bottom;
41 | left: $modal-inset-mode-left;
42 | overflow: visible;
43 | min-height: $modal-inset-mode-min-height;
44 | width: (100% - $modal-inset-mode-left - $modal-inset-mode-right);
45 | }
46 |
47 | .modal.ng-leave-active {
48 | bottom: 0;
49 | }
50 |
51 | // remove ios header padding from inset header
52 | .platform-ios.platform-cordova .modal-wrapper .modal{
53 | .bar-header:not(.bar-subheader) {
54 | height: $bar-height;
55 | > * {
56 | margin-top: 0;
57 | }
58 | }
59 | .tabs-top > .tabs,
60 | .tabs.tabs-top {
61 | top: $bar-height;
62 | }
63 | .has-header,
64 | .bar-subheader {
65 | top: $bar-height;
66 | }
67 | .has-subheader {
68 | top: $bar-height + $bar-subheader-height;
69 | }
70 | .has-tabs-top {
71 | top: $bar-height + $tabs-height;
72 | }
73 | .has-header.has-subheader.has-tabs-top {
74 | top: $bar-height + $bar-subheader-height + $tabs-height;
75 | }
76 | }
77 | }
78 |
79 | // disable clicks on all but the modal
80 | .modal-open {
81 | pointer-events: none;
82 |
83 | .modal,
84 | .modal-backdrop {
85 | pointer-events: auto;
86 | }
87 | // prevent clicks on modal when loading overlay is active though
88 | &.loading-active {
89 | .modal,
90 | .modal-backdrop {
91 | pointer-events: none;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_platform.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Platform
4 | * --------------------------------------------------
5 | * Platform specific tweaks
6 | */
7 |
8 | .platform-ios.platform-cordova {
9 | // iOS7/8 has a status bar which sits on top of the header.
10 | // Bump down everything to make room for it. However, if
11 | // if its in Cordova, and set to fullscreen, then disregard the bump.
12 | &:not(.fullscreen) {
13 | .bar-header:not(.bar-subheader) {
14 | height: $bar-height + $ios-statusbar-height;
15 |
16 | &.item-input-inset .item-input-wrapper {
17 | margin-top: 19px !important;
18 | }
19 |
20 | > * {
21 | margin-top: $ios-statusbar-height;
22 | }
23 | }
24 | .tabs-top > .tabs,
25 | .tabs.tabs-top {
26 | top: $bar-height + $ios-statusbar-height;
27 | }
28 |
29 | .has-header,
30 | .bar-subheader {
31 | top: $bar-height + $ios-statusbar-height;
32 | }
33 | .has-subheader {
34 | top: $bar-height + $bar-subheader-height + $ios-statusbar-height;
35 | }
36 | .has-tabs-top {
37 | top: $bar-height + $tabs-height + $ios-statusbar-height;
38 | }
39 | .has-header.has-subheader.has-tabs-top {
40 | top: $bar-height + $bar-subheader-height + $tabs-height + $ios-statusbar-height;
41 | }
42 | }
43 | &.status-bar-hide {
44 | // Cordova doesn't adjust the body height correctly, this makes up for it
45 | margin-bottom: 20px;
46 | }
47 | }
48 |
49 | @media (orientation:landscape) {
50 | .platform-ios.platform-browser.platform-ipad {
51 | position: fixed; // required for iPad 7 Safari
52 | }
53 | }
54 |
55 | .platform-c:not(.enable-transitions) * {
56 | // disable transitions on grade-c devices (Android 2)
57 | -webkit-transition: none !important;
58 | transition: none !important;
59 | }
60 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_popover.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Popovers
4 | * --------------------------------------------------
5 | * Popovers are independent views which float over content
6 | */
7 |
8 | .popover-backdrop {
9 | position: fixed;
10 | top: 0;
11 | left: 0;
12 | z-index: $z-index-popover;
13 | width: 100%;
14 | height: 100%;
15 | background-color: $popover-backdrop-bg-inactive;
16 |
17 | &.active {
18 | background-color: $popover-backdrop-bg-active;
19 | }
20 | }
21 |
22 | .popover {
23 | position: absolute;
24 | top: 25%;
25 | left: 50%;
26 | z-index: $z-index-popover;
27 | display: block;
28 | margin-top: 12px;
29 | margin-left: -$popover-width / 2;
30 | height: $popover-height;
31 | width: $popover-width;
32 | background-color: $popover-bg-color;
33 | box-shadow: $popover-box-shadow;
34 | opacity: 0;
35 |
36 | .item:first-child {
37 | border-top: 0;
38 | }
39 |
40 | .item:last-child {
41 | border-bottom: 0;
42 | }
43 |
44 | &.popover-bottom {
45 | margin-top: -12px;
46 | }
47 | }
48 |
49 |
50 | // Set popover border-radius
51 | .popover,
52 | .popover .bar-header {
53 | border-radius: $popover-border-radius;
54 | }
55 | .popover .scroll-content {
56 | z-index: 1;
57 | margin: 2px 0;
58 | }
59 | .popover .bar-header {
60 | border-bottom-right-radius: 0;
61 | border-bottom-left-radius: 0;
62 | }
63 | .popover .has-header {
64 | border-top-right-radius: 0;
65 | border-top-left-radius: 0;
66 | }
67 | .popover-arrow {
68 | display: none;
69 | }
70 |
71 |
72 | // iOS Popover
73 | .platform-ios {
74 |
75 | .popover {
76 | box-shadow: $popover-box-shadow-ios;
77 | }
78 |
79 | .popover,
80 | .popover .bar-header {
81 | border-radius: $popover-border-radius-ios;
82 | }
83 | .popover .scroll-content {
84 | margin: 8px 0;
85 | border-radius: $popover-border-radius-ios;
86 | }
87 | .popover .scroll-content.has-header {
88 | margin-top: 0;
89 | }
90 | .popover-arrow {
91 | position: absolute;
92 | display: block;
93 | top: -17px;
94 | width: 30px;
95 | height: 19px;
96 | overflow: hidden;
97 |
98 | &:after {
99 | position: absolute;
100 | top: 12px;
101 | left: 5px;
102 | width: 20px;
103 | height: 20px;
104 | background-color: $popover-bg-color;
105 | border-radius: 3px;
106 | content: '';
107 | @include rotate(-45deg);
108 | }
109 | }
110 | .popover-bottom .popover-arrow {
111 | top: auto;
112 | bottom: -10px;
113 | &:after {
114 | top: -6px;
115 | }
116 | }
117 | }
118 |
119 |
120 | // Android Popover
121 | .platform-android {
122 |
123 | .popover {
124 | margin-top: -32px;
125 | background-color: $popover-bg-color-android;
126 | box-shadow: $popover-box-shadow-android;
127 |
128 | .item {
129 | border-color: $popover-bg-color-android;
130 | background-color: $popover-bg-color-android;
131 | color: #4d4d4d;
132 | }
133 | &.popover-bottom {
134 | margin-top: 32px;
135 | }
136 | }
137 |
138 | .popover-backdrop,
139 | .popover-backdrop.active {
140 | background-color: transparent;
141 | }
142 | }
143 |
144 |
145 | // disable clicks on all but the popover
146 | .popover-open {
147 | pointer-events: none;
148 |
149 | .popover,
150 | .popover-backdrop {
151 | pointer-events: auto;
152 | }
153 | // prevent clicks on popover when loading overlay is active though
154 | &.loading-active {
155 | .popover,
156 | .popover-backdrop {
157 | pointer-events: none;
158 | }
159 | }
160 | }
161 |
162 |
163 | // wider popover on larger viewports
164 | @media (min-width: $popover-large-break-point) {
165 | .popover {
166 | width: $popover-large-width;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_popup.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Popups
4 | * --------------------------------------------------
5 | */
6 |
7 | .popup-container {
8 | position: absolute;
9 | top: 0;
10 | left: 0;
11 | bottom: 0;
12 | right: 0;
13 | background: rgba(0,0,0,0);
14 |
15 | @include display-flex();
16 | @include justify-content(center);
17 | @include align-items(center);
18 |
19 | z-index: $z-index-popup;
20 |
21 | // Start hidden
22 | visibility: hidden;
23 | &.popup-showing {
24 | visibility: visible;
25 | }
26 |
27 | &.popup-hidden .popup {
28 | @include animation-name(scaleOut);
29 | @include animation-duration($popup-leave-animation-duration);
30 | @include animation-timing-function(ease-in-out);
31 | @include animation-fill-mode(both);
32 | }
33 |
34 | &.active .popup {
35 | @include animation-name(superScaleIn);
36 | @include animation-duration($popup-enter-animation-duration);
37 | @include animation-timing-function(ease-in-out);
38 | @include animation-fill-mode(both);
39 | }
40 |
41 | .popup {
42 | width: $popup-width;
43 | max-width: 100%;
44 | max-height: 90%;
45 |
46 | border-radius: $popup-border-radius;
47 | background-color: $popup-background-color;
48 |
49 | @include display-flex();
50 | @include flex-direction(column);
51 | }
52 | }
53 |
54 | .popup-head {
55 | padding: 15px 10px;
56 | border-bottom: 1px solid #eee;
57 | text-align: center;
58 | }
59 | .popup-title {
60 | margin: 0;
61 | padding: 0;
62 | font-size: 15px;
63 | }
64 | .popup-sub-title {
65 | margin: 5px 0 0 0;
66 | padding: 0;
67 | font-weight: normal;
68 | font-size: 11px;
69 | }
70 | .popup-body {
71 | padding: 10px;
72 | overflow: scroll;
73 | }
74 |
75 | .popup-buttons {
76 | @include display-flex();
77 | @include flex-direction(row);
78 | padding: 10px;
79 | min-height: $popup-button-min-height + 20;
80 |
81 | .button {
82 | @include flex(1);
83 | display: block;
84 | min-height: $popup-button-min-height;
85 | border-radius: $popup-button-border-radius;
86 | line-height: $popup-button-line-height;
87 |
88 | margin-right: 5px;
89 | &:last-child {
90 | margin-right: 0px;
91 | }
92 | }
93 | }
94 |
95 | .popup-open {
96 | pointer-events: none;
97 |
98 | &.modal-open .modal {
99 | pointer-events: none;
100 | }
101 |
102 | .popup-backdrop, .popup {
103 | pointer-events: auto;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_progress.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Progress
4 | * --------------------------------------------------
5 | */
6 |
7 | progress {
8 | display: block;
9 | margin: $progress-margin;
10 | width: $progress-width;
11 | }
12 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_radio.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Radio Button Inputs
4 | * --------------------------------------------------
5 | */
6 |
7 | .item-radio {
8 | padding: 0;
9 |
10 | &:hover {
11 | cursor: pointer;
12 | }
13 | }
14 |
15 | .item-radio .item-content {
16 | /* give some room to the right for the checkmark icon */
17 | padding-right: $item-padding * 4;
18 | }
19 |
20 | .item-radio .radio-icon {
21 | /* checkmark icon will be hidden by default */
22 | position: absolute;
23 | top: 0;
24 | right: 0;
25 | z-index: $z-index-item-radio;
26 | visibility: hidden;
27 | padding: $item-padding - 2;
28 | height: 100%;
29 | font-size: 24px;
30 | }
31 |
32 | .item-radio input {
33 | /* hide any radio button inputs elements (the ugly circles) */
34 | position: absolute;
35 | left: -9999px;
36 |
37 | &:checked ~ .item-content {
38 | /* style the item content when its checked */
39 | background: #f7f7f7;
40 | }
41 |
42 | &:checked ~ .radio-icon {
43 | /* show the checkmark icon when its checked */
44 | visibility: visible;
45 | }
46 | }
47 |
48 | // Hack for Android to correctly display the checked item
49 | // http://timpietrusky.com/advanced-checkbox-hack
50 | .platform-android.grade-b .item-radio,
51 | .platform-android.grade-c .item-radio {
52 | -webkit-animation: androidCheckedbugfix infinite 1s;
53 | }
54 | @-webkit-keyframes androidCheckedbugfix {
55 | from { padding: 0; }
56 | to { padding: 0; }
57 | }
58 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_range.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Range
4 | * --------------------------------------------------
5 | */
6 |
7 | input[type="range"] {
8 | display: inline-block;
9 | overflow: hidden;
10 | margin-top: 5px;
11 | margin-bottom: 5px;
12 | padding-right: 2px;
13 | padding-left: 1px;
14 | width: auto;
15 | height: $range-slider-height + 15;
16 | outline: none;
17 | background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, $range-default-track-bg), color-stop(100%, $range-default-track-bg));
18 | background: linear-gradient(to right, $range-default-track-bg 0%, $range-default-track-bg 100%);
19 | background-position: center;
20 | background-size: 99% $range-track-height;
21 | background-repeat: no-repeat;
22 | -webkit-appearance: none;
23 |
24 | &::-webkit-slider-thumb {
25 | position: relative;
26 | width: $range-slider-width;
27 | height: $range-slider-height;
28 | border-radius: $range-slider-border-radius;
29 | background-color: $toggle-handle-off-bg-color;
30 | box-shadow: $range-slider-box-shadow;
31 | cursor: pointer;
32 | -webkit-appearance: none;
33 | border: 0;
34 | }
35 |
36 | &::-webkit-slider-thumb:before {
37 | /* what creates the colorful line on the left side of the slider */
38 | position: absolute;
39 | top: ($range-slider-height / 2) - ($range-track-height / 2);
40 | left: -2001px;
41 | width: 2000px;
42 | height: $range-track-height;
43 | background: $dark;
44 | content: ' ';
45 | }
46 |
47 | &::-webkit-slider-thumb:after {
48 | /* create a larger (but hidden) hit area */
49 | position: absolute;
50 | top: -15px;
51 | left: -15px;
52 | padding: 30px;
53 | content: ' ';
54 | //background: red;
55 | //opacity: .5;
56 | }
57 |
58 | }
59 |
60 | .range {
61 | @include display-flex();
62 | @include align-items(center);
63 | padding: 2px 11px;
64 |
65 | &.range-light {
66 | input { @include range-style($range-light-track-bg); }
67 | }
68 | &.range-stable {
69 | input { @include range-style($range-stable-track-bg); }
70 | }
71 | &.range-positive {
72 | input { @include range-style($range-positive-track-bg); }
73 | }
74 | &.range-calm {
75 | input { @include range-style($range-calm-track-bg); }
76 | }
77 | &.range-balanced {
78 | input { @include range-style($range-balanced-track-bg); }
79 | }
80 | &.range-assertive {
81 | input { @include range-style($range-assertive-track-bg); }
82 | }
83 | &.range-energized {
84 | input { @include range-style($range-energized-track-bg); }
85 | }
86 | &.range-royal {
87 | input { @include range-style($range-royal-track-bg); }
88 | }
89 | &.range-dark {
90 | input { @include range-style($range-dark-track-bg); }
91 | }
92 | }
93 |
94 | .range .icon {
95 | @include flex(0);
96 | display: block;
97 | min-width: $range-icon-size;
98 | text-align: center;
99 | font-size: $range-icon-size;
100 | }
101 |
102 | .range input {
103 | @include flex(1);
104 | display: block;
105 | margin-right: 10px;
106 | margin-left: 10px;
107 | }
108 |
109 | .range-label {
110 | @include flex(0, 0, auto);
111 | display: block;
112 | white-space: nowrap;
113 | }
114 |
115 | .range-label:first-child {
116 | padding-left: 5px;
117 | }
118 | .range input + .range-label {
119 | padding-right: 5px;
120 | padding-left: 0;
121 | }
122 |
123 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_reset.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Resets
4 | * --------------------------------------------------
5 | * Adapted from normalize.css and some reset.css. We don't care even one
6 | * bit about old IE, so we don't need any hacks for that in here.
7 | *
8 | * There are probably other things we could remove here, as well.
9 | *
10 | * normalize.css v2.1.2 | MIT License | git.io/normalize
11 |
12 | * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
13 | * http://cssreset.com
14 | */
15 |
16 | html, body, div, span, applet, object, iframe,
17 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
18 | a, abbr, acronym, address, big, cite, code,
19 | del, dfn, em, img, ins, kbd, q, s, samp,
20 | small, strike, strong, sub, sup, tt, var,
21 | b, i, u, center,
22 | dl, dt, dd, ol, ul, li,
23 | fieldset, form, label, legend,
24 | table, caption, tbody, tfoot, thead, tr, th, td,
25 | article, aside, canvas, details, embed, fieldset,
26 | figure, figcaption, footer, header, hgroup,
27 | menu, nav, output, ruby, section, summary,
28 | time, mark, audio, video {
29 | margin: 0;
30 | padding: 0;
31 | border: 0;
32 | vertical-align: baseline;
33 | font: inherit;
34 | font-size: 100%;
35 | }
36 |
37 | ol, ul {
38 | list-style: none;
39 | }
40 | blockquote, q {
41 | quotes: none;
42 | }
43 | blockquote:before, blockquote:after,
44 | q:before, q:after {
45 | content: '';
46 | content: none;
47 | }
48 |
49 | /**
50 | * Prevent modern browsers from displaying `audio` without controls.
51 | * Remove excess height in iOS 5 devices.
52 | */
53 |
54 | audio:not([controls]) {
55 | display: none;
56 | height: 0;
57 | }
58 |
59 | /**
60 | * Hide the `template` element in IE, Safari, and Firefox < 22.
61 | */
62 |
63 | [hidden],
64 | template {
65 | display: none;
66 | }
67 |
68 | script {
69 | display: none !important;
70 | }
71 |
72 | /* ==========================================================================
73 | Base
74 | ========================================================================== */
75 |
76 | /**
77 | * 1. Set default font family to sans-serif.
78 | * 2. Prevent iOS text size adjust after orientation change, without disabling
79 | * user zoom.
80 | */
81 |
82 | html {
83 | @include user-select(none);
84 | font-family: sans-serif; /* 1 */
85 | -webkit-text-size-adjust: 100%;
86 | -ms-text-size-adjust: 100%; /* 2 */
87 | -webkit-text-size-adjust: 100%; /* 2 */
88 | }
89 |
90 | /**
91 | * Remove default margin.
92 | */
93 |
94 | body {
95 | margin: 0;
96 | line-height: 1;
97 | }
98 |
99 |
100 | /**
101 | * Remove default outlines.
102 | */
103 | a,
104 | button,
105 | :focus,
106 | a:focus,
107 | button:focus,
108 | a:active,
109 | a:hover {
110 | outline: 0;
111 | }
112 |
113 | /* *
114 | * Remove tap highlight color
115 | */
116 |
117 | a {
118 | -webkit-user-drag: none;
119 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
120 | -webkit-tap-highlight-color: transparent;
121 |
122 | &[href]:hover {
123 | cursor: pointer;
124 | }
125 | }
126 |
127 | /* ==========================================================================
128 | Typography
129 | ========================================================================== */
130 |
131 |
132 | /**
133 | * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
134 | */
135 |
136 | b,
137 | strong {
138 | font-weight: bold;
139 | }
140 |
141 | /**
142 | * Address styling not present in Safari 5 and Chrome.
143 | */
144 |
145 | dfn {
146 | font-style: italic;
147 | }
148 |
149 | /**
150 | * Address differences between Firefox and other browsers.
151 | */
152 |
153 | hr {
154 | -moz-box-sizing: content-box;
155 | box-sizing: content-box;
156 | height: 0;
157 | }
158 |
159 |
160 | /**
161 | * Correct font family set oddly in Safari 5 and Chrome.
162 | */
163 |
164 | code,
165 | kbd,
166 | pre,
167 | samp {
168 | font-size: 1em;
169 | font-family: monospace, serif;
170 | }
171 |
172 | /**
173 | * Improve readability of pre-formatted text in all browsers.
174 | */
175 |
176 | pre {
177 | white-space: pre-wrap;
178 | }
179 |
180 | /**
181 | * Set consistent quote types.
182 | */
183 |
184 | q {
185 | quotes: "\201C" "\201D" "\2018" "\2019";
186 | }
187 |
188 | /**
189 | * Address inconsistent and variable font size in all browsers.
190 | */
191 |
192 | small {
193 | font-size: 80%;
194 | }
195 |
196 | /**
197 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
198 | */
199 |
200 | sub,
201 | sup {
202 | position: relative;
203 | vertical-align: baseline;
204 | font-size: 75%;
205 | line-height: 0;
206 | }
207 |
208 | sup {
209 | top: -0.5em;
210 | }
211 |
212 | sub {
213 | bottom: -0.25em;
214 | }
215 |
216 | /**
217 | * Define consistent border, margin, and padding.
218 | */
219 |
220 | fieldset {
221 | margin: 0 2px;
222 | padding: 0.35em 0.625em 0.75em;
223 | border: 1px solid #c0c0c0;
224 | }
225 |
226 | /**
227 | * 1. Correct `color` not being inherited in IE 8/9.
228 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
229 | */
230 |
231 | legend {
232 | padding: 0; /* 2 */
233 | border: 0; /* 1 */
234 | }
235 |
236 | /**
237 | * 1. Correct font family not being inherited in all browsers.
238 | * 2. Correct font size not being inherited in all browsers.
239 | * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
240 | * 4. Remove any default :focus styles
241 | * 5. Make sure webkit font smoothing is being inherited
242 | * 6. Remove default gradient in Android Firefox / FirefoxOS
243 | */
244 |
245 | button,
246 | input,
247 | select,
248 | textarea {
249 | margin: 0; /* 3 */
250 | font-size: 100%; /* 2 */
251 | font-family: inherit; /* 1 */
252 | outline-offset: 0; /* 4 */
253 | outline-style: none; /* 4 */
254 | outline-width: 0; /* 4 */
255 | -webkit-font-smoothing: inherit; /* 5 */
256 | background-image: none; /* 6 */
257 | }
258 |
259 | /**
260 | * Address Firefox 4+ setting `line-height` on `input` using `importnt` in
261 | * the UA stylesheet.
262 | */
263 |
264 | button,
265 | input {
266 | line-height: normal;
267 | }
268 |
269 | /**
270 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
271 | * All other form control elements do not inherit `text-transform` values.
272 | * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
273 | * Correct `select` style inheritance in Firefox 4+ and Opera.
274 | */
275 |
276 | button,
277 | select {
278 | text-transform: none;
279 | }
280 |
281 | /**
282 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
283 | * and `video` controls.
284 | * 2. Correct inability to style clickable `input` types in iOS.
285 | * 3. Improve usability and consistency of cursor style between image-type
286 | * `input` and others.
287 | */
288 |
289 | button,
290 | html input[type="button"], /* 1 */
291 | input[type="reset"],
292 | input[type="submit"] {
293 | cursor: pointer; /* 3 */
294 | -webkit-appearance: button; /* 2 */
295 | }
296 |
297 | /**
298 | * Re-set default cursor for disabled elements.
299 | */
300 |
301 | button[disabled],
302 | html input[disabled] {
303 | cursor: default;
304 | }
305 |
306 | /**
307 | * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
308 | * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
309 | * (include `-moz` to future-proof).
310 | */
311 |
312 | input[type="search"] {
313 | -webkit-box-sizing: content-box; /* 2 */
314 | -moz-box-sizing: content-box;
315 | box-sizing: content-box;
316 | -webkit-appearance: textfield; /* 1 */
317 | }
318 |
319 | /**
320 | * Remove inner padding and search cancel button in Safari 5 and Chrome
321 | * on OS X.
322 | */
323 |
324 | input[type="search"]::-webkit-search-cancel-button,
325 | input[type="search"]::-webkit-search-decoration {
326 | -webkit-appearance: none;
327 | }
328 |
329 | /**
330 | * Remove inner padding and border in Firefox 4+.
331 | */
332 |
333 | button::-moz-focus-inner,
334 | input::-moz-focus-inner {
335 | padding: 0;
336 | border: 0;
337 | }
338 |
339 | /**
340 | * 1. Remove default vertical scrollbar in IE 8/9.
341 | * 2. Improve readability and alignment in all browsers.
342 | */
343 |
344 | textarea {
345 | overflow: auto; /* 1 */
346 | vertical-align: top; /* 2 */
347 | }
348 |
349 |
350 | img {
351 | -webkit-user-drag: none;
352 | }
353 |
354 | /* ==========================================================================
355 | Tables
356 | ========================================================================== */
357 |
358 | /**
359 | * Remove most spacing between table cells.
360 | */
361 |
362 | table {
363 | border-spacing: 0;
364 | border-collapse: collapse;
365 | }
366 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_select.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Select
4 | * --------------------------------------------------
5 | */
6 |
7 | .item-select {
8 | position: relative;
9 |
10 | select {
11 | @include appearance(none);
12 | position: absolute;
13 | top: 0;
14 | right: 0;
15 | padding: ($item-padding - 2) ($item-padding * 3) ($item-padding) $item-padding;
16 | max-width: 65%;
17 |
18 | border: none;
19 | background: $item-default-bg;
20 | color: #333;
21 |
22 | // hack to hide default dropdown arrow in FF
23 | text-indent: .01px;
24 | text-overflow: '';
25 |
26 | white-space: nowrap;
27 | font-size: $font-size-base;
28 |
29 | cursor: pointer;
30 | direction: rtl; // right align the select text
31 | }
32 |
33 | select::-ms-expand {
34 | // hide default dropdown arrow in IE
35 | display: none;
36 | }
37 |
38 | option {
39 | direction: ltr;
40 | }
41 |
42 | &:after {
43 | position: absolute;
44 | top: 50%;
45 | right: $item-padding;
46 | margin-top: -3px;
47 | width: 0;
48 | height: 0;
49 | border-top: 5px solid;
50 | border-right: 5px solid rgba(0, 0, 0, 0);
51 | border-left: 5px solid rgba(0, 0, 0, 0);
52 | color: #999;
53 | content: "";
54 | pointer-events: none;
55 | }
56 | &.item-light {
57 | select{
58 | background:$item-light-bg;
59 | color:$item-light-text;
60 | }
61 | }
62 | &.item-stable {
63 | select{
64 | background:$item-stable-bg;
65 | color:$item-stable-text;
66 | }
67 | &:after, .input-label{
68 | color:darken($item-stable-border,30%);
69 | }
70 | }
71 | &.item-positive {
72 | select{
73 | background:$item-positive-bg;
74 | color:$item-positive-text;
75 | }
76 | &:after, .input-label{
77 | color:$item-positive-text;
78 | }
79 | }
80 | &.item-calm {
81 | select{
82 | background:$item-calm-bg;
83 | color:$item-calm-text;
84 | }
85 | &:after, .input-label{
86 | color:$item-calm-text;
87 | }
88 | }
89 | &.item-assertive {
90 | select{
91 | background:$item-assertive-bg;
92 | color:$item-assertive-text;
93 | }
94 | &:after, .input-label{
95 | color:$item-assertive-text;
96 | }
97 | }
98 | &.item-balanced {
99 | select{
100 | background:$item-balanced-bg;
101 | color:$item-balanced-text;
102 | }
103 | &:after, .input-label{
104 | color:$item-balanced-text;
105 | }
106 | }
107 | &.item-energized {
108 | select{
109 | background:$item-energized-bg;
110 | color:$item-energized-text;
111 | }
112 | &:after, .input-label{
113 | color:$item-energized-text;
114 | }
115 | }
116 | &.item-royal {
117 | select{
118 | background:$item-royal-bg;
119 | color:$item-royal-text;
120 | }
121 | &:after, .input-label{
122 | color:$item-royal-text;
123 | }
124 | }
125 | &.item-dark {
126 | select{
127 | background:$item-dark-bg;
128 | color:$item-dark-text;
129 | }
130 | &:after, .input-label{
131 | color:$item-dark-text;
132 | }
133 | }
134 | }
135 |
136 | select {
137 | &[multiple],
138 | &[size] {
139 | height: auto;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_slide-box.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Slide Box
4 | * --------------------------------------------------
5 | */
6 |
7 | .slider {
8 | position: relative;
9 | visibility: hidden;
10 | // Make sure items don't scroll over ever
11 | overflow: hidden;
12 | }
13 |
14 | .slider-slides {
15 | position: relative;
16 | height: 100%;
17 | }
18 |
19 | .slider-slide {
20 | position: relative;
21 | display: block;
22 | float: left;
23 | width: 100%;
24 | height: 100%;
25 | vertical-align: top;
26 | }
27 |
28 | .slider-slide-image {
29 | > img {
30 | width: 100%;
31 | }
32 | }
33 |
34 | .slider-pager {
35 | position: absolute;
36 | bottom: 20px;
37 | z-index: $z-index-slider-pager;
38 | width: 100%;
39 | height: 15px;
40 | text-align: center;
41 |
42 | .slider-pager-page {
43 | display: inline-block;
44 | margin: 0px 3px;
45 | width: 15px;
46 | color: #000;
47 | text-decoration: none;
48 |
49 | opacity: 0.3;
50 |
51 | &.active {
52 | @include transition(opacity 0.4s ease-in);
53 | opacity: 1;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_toggle.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Toggle
4 | * --------------------------------------------------
5 | */
6 |
7 | .item-toggle {
8 | pointer-events: none;
9 | }
10 |
11 | .toggle {
12 | // set the color defaults
13 | @include toggle-style($toggle-on-default-border, $toggle-on-default-bg);
14 |
15 | position: relative;
16 | display: inline-block;
17 | pointer-events: auto;
18 | margin: -$toggle-hit-area-expansion;
19 | padding: $toggle-hit-area-expansion;
20 |
21 | &.dragging {
22 | .handle {
23 | background-color: $toggle-handle-dragging-bg-color !important;
24 | }
25 | }
26 |
27 | &.toggle-light {
28 | @include toggle-style($toggle-on-light-border, $toggle-on-light-bg);
29 | }
30 | &.toggle-stable {
31 | @include toggle-style($toggle-on-stable-border, $toggle-on-stable-bg);
32 | }
33 | &.toggle-positive {
34 | @include toggle-style($toggle-on-positive-border, $toggle-on-positive-bg);
35 | }
36 | &.toggle-calm {
37 | @include toggle-style($toggle-on-calm-border, $toggle-on-calm-bg);
38 | }
39 | &.toggle-assertive {
40 | @include toggle-style($toggle-on-assertive-border, $toggle-on-assertive-bg);
41 | }
42 | &.toggle-balanced {
43 | @include toggle-style($toggle-on-balanced-border, $toggle-on-balanced-bg);
44 | }
45 | &.toggle-energized {
46 | @include toggle-style($toggle-on-energized-border, $toggle-on-energized-bg);
47 | }
48 | &.toggle-royal {
49 | @include toggle-style($toggle-on-royal-border, $toggle-on-royal-bg);
50 | }
51 | &.toggle-dark {
52 | @include toggle-style($toggle-on-dark-border, $toggle-on-dark-bg);
53 | }
54 | }
55 |
56 | .toggle input {
57 | // hide the actual input checkbox
58 | display: none;
59 | }
60 |
61 | /* the track appearance when the toggle is "off" */
62 | .toggle .track {
63 | @include transition-timing-function(ease-in-out);
64 | @include transition-duration($toggle-transition-duration);
65 | @include transition-property((background-color, border));
66 |
67 | display: inline-block;
68 | box-sizing: border-box;
69 | width: $toggle-width;
70 | height: $toggle-height;
71 | border: solid $toggle-border-width $toggle-off-border-color;
72 | border-radius: $toggle-border-radius;
73 | background-color: $toggle-off-bg-color;
74 | content: ' ';
75 | cursor: pointer;
76 | pointer-events: none;
77 | }
78 |
79 | /* Fix to avoid background color bleeding */
80 | /* (occured on (at least) Android 4.2, Asus MeMO Pad HD7 ME173X) */
81 | .platform-android4_2 .toggle .track {
82 | -webkit-background-clip: padding-box;
83 | }
84 |
85 | /* the handle (circle) thats inside the toggle's track area */
86 | /* also the handle's appearance when it is "off" */
87 | .toggle .handle {
88 | @include transition($toggle-transition-duration ease-in-out);
89 | position: absolute;
90 | display: block;
91 | width: $toggle-handle-width;
92 | height: $toggle-handle-height;
93 | border-radius: $toggle-handle-radius;
94 | background-color: $toggle-handle-off-bg-color;
95 | top: $toggle-border-width + $toggle-hit-area-expansion;
96 | left: $toggle-border-width + $toggle-hit-area-expansion;
97 |
98 | &:before {
99 | // used to create a larger (but hidden) hit area to slide the handle
100 | position: absolute;
101 | top: -4px;
102 | left: ( ($toggle-handle-width / 2) * -1) - 8;
103 | padding: ($toggle-handle-height / 2) + 5 ($toggle-handle-width + 7);
104 | content: " ";
105 | }
106 | }
107 |
108 | .toggle input:checked + .track .handle {
109 | // the handle when the toggle is "on"
110 | @include translate3d($toggle-width - $toggle-handle-width - ($toggle-border-width * 2), 0, 0);
111 | background-color: $toggle-handle-on-bg-color;
112 | }
113 |
114 | .item-toggle.active {
115 | box-shadow: none;
116 | }
117 |
118 | .item-toggle,
119 | .item-toggle.item-complex .item-content {
120 | // make sure list item content have enough padding on right to fit the toggle
121 | padding-right: ($item-padding * 3) + $toggle-width;
122 | }
123 |
124 | .item-toggle.item-complex {
125 | padding-right: 0;
126 | }
127 |
128 | .item-toggle .toggle {
129 | // position the toggle to the right within a list item
130 | position: absolute;
131 | top: $item-padding / 2;
132 | right: $item-padding;
133 | z-index: $z-index-item-toggle;
134 | }
135 |
136 | .toggle input:disabled + .track {
137 | opacity: .6;
138 | }
139 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_transitions.scss:
--------------------------------------------------------------------------------
1 |
2 | // iOS View Transitions
3 | // -------------------------------
4 |
5 | $ios-transition-duration: 450ms !default;
6 | $ios-transition-timing-function: cubic-bezier(.3, .9, .4, 1) !default;
7 | $ios-transition-container-bg-color: #000 !default;
8 |
9 |
10 | [nav-view-transition="ios"] {
11 |
12 | [nav-view="entering"],
13 | [nav-view="leaving"] {
14 | @include transition-duration( $ios-transition-duration );
15 | @include transition-timing-function( $ios-transition-timing-function );
16 | -webkit-transition-property: opacity, -webkit-transform;
17 | transition-property: opacity, transform;
18 | }
19 |
20 | &[nav-view-direction="forward"],
21 | &[nav-view-direction="back"] {
22 | background-color: $ios-transition-container-bg-color;
23 | }
24 |
25 | [nav-view="active"],
26 | &[nav-view-direction="forward"] [nav-view="entering"],
27 | &[nav-view-direction="back"] [nav-view="leaving"] {
28 | z-index: $z-index-view-above;
29 | }
30 |
31 | &[nav-view-direction="back"] [nav-view="entering"],
32 | &[nav-view-direction="forward"] [nav-view="leaving"] {
33 | z-index: $z-index-view-below;
34 | }
35 |
36 | }
37 |
38 |
39 |
40 | // iOS Nav Bar Transitions
41 | // -------------------------------
42 |
43 | [nav-bar-transition="ios"] {
44 |
45 | .title,
46 | .buttons,
47 | .back-text {
48 | @include transition-duration( $ios-transition-duration );
49 | @include transition-timing-function( $ios-transition-timing-function );
50 | -webkit-transition-property: opacity, -webkit-transform;
51 | transition-property: opacity, transform;
52 | }
53 |
54 | [nav-bar="active"],
55 | [nav-bar="entering"] {
56 | z-index: $z-index-bar-above;
57 |
58 | .bar {
59 | background: transparent;
60 | }
61 | }
62 |
63 | [nav-bar="cached"] {
64 | display: block;
65 |
66 | .header-item {
67 | display: none;
68 | }
69 | }
70 |
71 | }
72 |
73 |
74 |
75 | // Android View Transitions
76 | // -------------------------------
77 |
78 | $android-transition-duration: 200ms !default;
79 | $android-transition-timing-function: cubic-bezier(0.4, 0.6, 0.2, 1) !default;
80 |
81 |
82 | [nav-view-transition="android"] {
83 |
84 | [nav-view="entering"],
85 | [nav-view="leaving"] {
86 | @include transition-duration( $android-transition-duration );
87 | @include transition-timing-function( $android-transition-timing-function );
88 | -webkit-transition-property: -webkit-transform;
89 | transition-property: transform;
90 | }
91 |
92 | [nav-view="active"],
93 | &[nav-view-direction="forward"] [nav-view="entering"],
94 | &[nav-view-direction="back"] [nav-view="leaving"] {
95 | z-index: $z-index-view-above;
96 | }
97 |
98 | &[nav-view-direction="back"] [nav-view="entering"],
99 | &[nav-view-direction="forward"] [nav-view="leaving"] {
100 | z-index: $z-index-view-below;
101 | }
102 |
103 | }
104 |
105 |
106 |
107 | // Android Nav Bar Transitions
108 | // -------------------------------
109 |
110 | [nav-bar-transition="android"] {
111 |
112 | .title,
113 | .buttons {
114 | @include transition-duration( $android-transition-duration );
115 | @include transition-timing-function( $android-transition-timing-function );
116 | -webkit-transition-property: opacity;
117 | transition-property: opacity;
118 | }
119 |
120 | [nav-bar="active"],
121 | [nav-bar="entering"] {
122 | z-index: $z-index-bar-above;
123 |
124 | .bar {
125 | background: transparent;
126 | }
127 | }
128 |
129 | [nav-bar="cached"] {
130 | display: block;
131 |
132 | .header-item {
133 | display: none;
134 | }
135 | }
136 |
137 | }
138 |
139 |
140 |
141 | // Transition Settings
142 | // -------------------------------
143 |
144 | [nav-view="cached"],
145 | [nav-bar="cached"] {
146 | display: none;
147 | }
148 |
149 | [nav-view="stage"] {
150 | opacity: 0;
151 | @include transition-duration( 0 );
152 | }
153 |
154 | [nav-bar="stage"] {
155 | .title,
156 | .buttons,
157 | .back-text {
158 | position: absolute;
159 | opacity: 0;
160 | @include transition-duration(0s);
161 | }
162 | }
163 |
164 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_type.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Typography
4 | * --------------------------------------------------
5 | */
6 |
7 |
8 | // Body text
9 | // -------------------------
10 |
11 | p {
12 | margin: 0 0 ($line-height-computed / 2);
13 | }
14 |
15 |
16 | // Emphasis & misc
17 | // -------------------------
18 |
19 | small { font-size: 85%; }
20 | cite { font-style: normal; }
21 |
22 |
23 | // Alignment
24 | // -------------------------
25 |
26 | .text-left { text-align: left; }
27 | .text-right { text-align: right; }
28 | .text-center { text-align: center; }
29 |
30 |
31 | // Headings
32 | // -------------------------
33 |
34 | h1, h2, h3, h4, h5, h6,
35 | .h1, .h2, .h3, .h4, .h5, .h6 {
36 | color: $base-color;
37 | font-weight: $headings-font-weight;
38 | font-family: $headings-font-family;
39 | line-height: $headings-line-height;
40 |
41 | small {
42 | font-weight: normal;
43 | line-height: 1;
44 | }
45 | }
46 |
47 | h1, .h1,
48 | h2, .h2,
49 | h3, .h3 {
50 | margin-top: $line-height-computed;
51 | margin-bottom: ($line-height-computed / 2);
52 |
53 | &:first-child {
54 | margin-top: 0;
55 | }
56 |
57 | + h1, + .h1,
58 | + h2, + .h2,
59 | + h3, + .h3 {
60 | margin-top: ($line-height-computed / 2);
61 | }
62 | }
63 |
64 | h4, .h4,
65 | h5, .h5,
66 | h6, .h6 {
67 | margin-top: ($line-height-computed / 2);
68 | margin-bottom: ($line-height-computed / 2);
69 | }
70 |
71 | h1, .h1 { font-size: floor($font-size-base * 2.60); } // ~36px
72 | h2, .h2 { font-size: floor($font-size-base * 2.15); } // ~30px
73 | h3, .h3 { font-size: ceil($font-size-base * 1.70); } // ~24px
74 | h4, .h4 { font-size: ceil($font-size-base * 1.25); } // ~18px
75 | h5, .h5 { font-size: $font-size-base; }
76 | h6, .h6 { font-size: ceil($font-size-base * 0.85); } // ~12px
77 |
78 | h1 small, .h1 small { font-size: ceil($font-size-base * 1.70); } // ~24px
79 | h2 small, .h2 small { font-size: ceil($font-size-base * 1.25); } // ~18px
80 | h3 small, .h3 small,
81 | h4 small, .h4 small { font-size: $font-size-base; }
82 |
83 |
84 | // Description Lists
85 | // -------------------------
86 |
87 | dl {
88 | margin-bottom: $line-height-computed;
89 | }
90 | dt,
91 | dd {
92 | line-height: $line-height-base;
93 | }
94 | dt {
95 | font-weight: bold;
96 | }
97 |
98 |
99 | // Blockquotes
100 | // -------------------------
101 |
102 | blockquote {
103 | margin: 0 0 $line-height-computed;
104 | padding: ($line-height-computed / 2) $line-height-computed;
105 | border-left: 5px solid gray;
106 |
107 | p {
108 | font-weight: 300;
109 | font-size: ($font-size-base * 1.25);
110 | line-height: 1.25;
111 | }
112 |
113 | p:last-child {
114 | margin-bottom: 0;
115 | }
116 |
117 | small {
118 | display: block;
119 | line-height: $line-height-base;
120 | &:before {
121 | content: '\2014 \00A0';// EM DASH, NBSP;
122 | }
123 | }
124 | }
125 |
126 |
127 | // Quotes
128 | // -------------------------
129 |
130 | q:before,
131 | q:after,
132 | blockquote:before,
133 | blockquote:after {
134 | content: "";
135 | }
136 |
137 |
138 | // Addresses
139 | // -------------------------
140 |
141 | address {
142 | display: block;
143 | margin-bottom: $line-height-computed;
144 | font-style: normal;
145 | line-height: $line-height-base;
146 | }
147 |
148 |
149 | // Links
150 | // -------------------------
151 |
152 | a.subdued {
153 | padding-right: 10px;
154 | color: #888;
155 | text-decoration: none;
156 |
157 | &:hover {
158 | text-decoration: none;
159 | }
160 | &:last-child {
161 | padding-right: 0;
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/_util.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Utility Classes
4 | * --------------------------------------------------
5 | */
6 |
7 | .hide {
8 | display: none;
9 | }
10 | .opacity-hide {
11 | opacity: 0;
12 | }
13 | .grade-b .opacity-hide,
14 | .grade-c .opacity-hide {
15 | opacity: 1;
16 | display: none;
17 | }
18 | .show {
19 | display: block;
20 | }
21 | .opacity-show {
22 | opacity: 1;
23 | }
24 | .invisible {
25 | visibility: hidden;
26 | }
27 |
28 | .keyboard-open .hide-on-keyboard-open {
29 | display: none;
30 | }
31 |
32 | .keyboard-open .tabs.hide-on-keyboard-open + .pane .has-tabs,
33 | .keyboard-open .bar-footer.hide-on-keyboard-open + .pane .has-footer {
34 | bottom: 0;
35 | }
36 |
37 | .inline {
38 | display: inline-block;
39 | }
40 |
41 | .disable-pointer-events {
42 | pointer-events: none;
43 | }
44 |
45 | .enable-pointer-events {
46 | pointer-events: auto;
47 | }
48 |
49 | .disable-user-behavior {
50 | // used to prevent the browser from doing its native behavior. this doesnt
51 | // prevent the scrolling, but cancels the contextmenu, tap highlighting, etc
52 |
53 | @include user-select(none);
54 | @include touch-callout(none);
55 | @include tap-highlight-transparent();
56 |
57 | -webkit-user-drag: none;
58 |
59 | -ms-touch-action: none;
60 | -ms-content-zooming: none;
61 | }
62 |
63 | // Fill the screen to block clicks (a better pointer-events: none) for the body
64 | // to avoid full-page reflows and paints which can cause flickers
65 | .click-block {
66 | position: absolute;
67 | top: 0;
68 | left: 0;
69 | z-index: $z-index-click-block;
70 | width: 100%;
71 | height: 100%;
72 | opacity: 0;
73 | @include translate3d(0, 0, 0);
74 | }
75 | .click-block-hide {
76 | @include translate3d(-9999px, 0, 0);
77 | }
78 |
79 | .no-resize {
80 | resize: none;
81 | }
82 |
83 | .block {
84 | display: block;
85 | clear: both;
86 | &:after {
87 | display: block;
88 | visibility: hidden;
89 | clear: both;
90 | height: 0;
91 | content: ".";
92 | }
93 | }
94 |
95 | .full-image {
96 | width: 100%;
97 | }
98 |
99 | .clearfix {
100 | *zoom: 1;
101 | &:before,
102 | &:after {
103 | display: table;
104 | content: "";
105 | // Fixes Opera/contenteditable bug:
106 | // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952
107 | line-height: 0;
108 | }
109 | &:after {
110 | clear: both;
111 | }
112 | }
113 |
114 | /**
115 | * Content Padding
116 | * --------------------------------------------------
117 | */
118 |
119 | .padding {
120 | padding: $content-padding;
121 | }
122 |
123 | .padding-top,
124 | .padding-vertical {
125 | padding-top: $content-padding;
126 | }
127 |
128 | .padding-right,
129 | .padding-horizontal {
130 | padding-right: $content-padding;
131 | }
132 |
133 | .padding-bottom,
134 | .padding-vertical {
135 | padding-bottom: $content-padding;
136 | }
137 |
138 | .padding-left,
139 | .padding-horizontal {
140 | padding-left: $content-padding;
141 | }
142 |
143 |
144 | /**
145 | * Rounded
146 | * --------------------------------------------------
147 | */
148 |
149 | .rounded {
150 | border-radius: $border-radius-base;
151 | }
152 |
153 |
154 | /**
155 | * Utility Colors
156 | * --------------------------------------------------
157 | * Utility colors are added to help set a naming convention. You'll
158 | * notice we purposely do not use words like "red" or "blue", but
159 | * instead have colors which represent an emotion or generic theme.
160 | */
161 |
162 | .light, a.light {
163 | color: $light;
164 | }
165 | .light-bg {
166 | background-color: $light;
167 | }
168 | .light-border {
169 | border-color: $button-light-border;
170 | }
171 |
172 | .stable, a.stable {
173 | color: $stable;
174 | }
175 | .stable-bg {
176 | background-color: $stable;
177 | }
178 | .stable-border {
179 | border-color: $button-stable-border;
180 | }
181 |
182 | .positive, a.positive {
183 | color: $positive;
184 | }
185 | .positive-bg {
186 | background-color: $positive;
187 | }
188 | .positive-border {
189 | border-color: $button-positive-border;
190 | }
191 |
192 | .calm, a.calm {
193 | color: $calm;
194 | }
195 | .calm-bg {
196 | background-color: $calm;
197 | }
198 | .calm-border {
199 | border-color: $button-calm-border;
200 | }
201 |
202 | .assertive, a.assertive {
203 | color: $assertive;
204 | }
205 | .assertive-bg {
206 | background-color: $assertive;
207 | }
208 | .assertive-border {
209 | border-color: $button-assertive-border;
210 | }
211 |
212 | .balanced, a.balanced {
213 | color: $balanced;
214 | }
215 | .balanced-bg {
216 | background-color: $balanced;
217 | }
218 | .balanced-border {
219 | border-color: $button-balanced-border;
220 | }
221 |
222 | .energized, a.energized {
223 | color: $energized;
224 | }
225 | .energized-bg {
226 | background-color: $energized;
227 | }
228 | .energized-border {
229 | border-color: $button-energized-border;
230 | }
231 |
232 | .royal, a.royal {
233 | color: $royal;
234 | }
235 | .royal-bg {
236 | background-color: $royal;
237 | }
238 | .royal-border {
239 | border-color: $button-royal-border;
240 | }
241 |
242 | .dark, a.dark {
243 | color: $dark;
244 | }
245 | .dark-bg {
246 | background-color: $dark;
247 | }
248 | .dark-border {
249 | border-color: $button-dark-border;
250 | }
251 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/ionic.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | @import
4 | // Ionicons
5 | "ionicons/ionicons.scss",
6 |
7 | // Variables
8 | "mixins",
9 | "variables",
10 |
11 | // Base
12 | "reset",
13 | "scaffolding",
14 | "type",
15 |
16 | // Components
17 | "action-sheet",
18 | "backdrop",
19 | "bar",
20 | "tabs",
21 | "menu",
22 | "modal",
23 | "popover",
24 | "popup",
25 | "loading",
26 | "items",
27 | "list",
28 | "badge",
29 | "slide-box",
30 |
31 | // Forms
32 | "form",
33 | "checkbox",
34 | "toggle",
35 | "radio",
36 | "range",
37 | "select",
38 | "progress",
39 |
40 | // Buttons
41 | "button",
42 | "button-bar",
43 |
44 | // Util
45 | "grid",
46 | "util",
47 | "platform",
48 |
49 | // Animations
50 | "animations",
51 | "transitions";
52 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/ionicons/_ionicons-animation.scss:
--------------------------------------------------------------------------------
1 | // Animation Icons
2 | // --------------------------
3 |
4 | .#{$ionicons-prefix}spin {
5 | -webkit-animation: spin 1s infinite linear;
6 | -moz-animation: spin 1s infinite linear;
7 | -o-animation: spin 1s infinite linear;
8 | animation: spin 1s infinite linear;
9 | }
10 |
11 | @-moz-keyframes spin {
12 | 0% { -moz-transform: rotate(0deg); }
13 | 100% { -moz-transform: rotate(359deg); }
14 | }
15 | @-webkit-keyframes spin {
16 | 0% { -webkit-transform: rotate(0deg); }
17 | 100% { -webkit-transform: rotate(359deg); }
18 | }
19 | @-o-keyframes spin {
20 | 0% { -o-transform: rotate(0deg); }
21 | 100% { -o-transform: rotate(359deg); }
22 | }
23 | @-ms-keyframes spin {
24 | 0% { -ms-transform: rotate(0deg); }
25 | 100% { -ms-transform: rotate(359deg); }
26 | }
27 | @keyframes spin {
28 | 0% { transform: rotate(0deg); }
29 | 100% { transform: rotate(359deg); }
30 | }
31 |
32 |
33 | .#{$ionicons-prefix}loading-a,
34 | .#{$ionicons-prefix}loading-b,
35 | .#{$ionicons-prefix}loading-c,
36 | .#{$ionicons-prefix}loading-d,
37 | .#{$ionicons-prefix}looping,
38 | .#{$ionicons-prefix}refreshing,
39 | .#{$ionicons-prefix}ios7-reloading {
40 | @extend .ion;
41 | // must spin entire element for android 4.3 and below
42 | @extend .#{$ionicons-prefix}spin;
43 | }
44 |
45 | .#{$ionicons-prefix}loading-a {
46 | -webkit-animation-timing-function: steps(8, start);
47 | -moz-animation-timing-function: steps(8, start);
48 | animation-timing-function: steps(8, start);
49 | }
50 |
51 | .#{$ionicons-prefix}loading-a:before {
52 | @extend .#{$ionicons-prefix}load-a:before;
53 | }
54 |
55 | .#{$ionicons-prefix}loading-b:before {
56 | @extend .#{$ionicons-prefix}load-b:before;
57 | }
58 |
59 | .#{$ionicons-prefix}loading-c:before {
60 | @extend .#{$ionicons-prefix}load-c:before;
61 | }
62 |
63 | .#{$ionicons-prefix}loading-d:before {
64 | @extend .#{$ionicons-prefix}load-d:before;
65 | }
66 |
67 | .#{$ionicons-prefix}looping:before {
68 | @extend .#{$ionicons-prefix}loop:before;
69 | }
70 |
71 | .#{$ionicons-prefix}refreshing:before {
72 | @extend .#{$ionicons-prefix}refresh:before;
73 | }
74 |
75 | .#{$ionicons-prefix}ios7-reloading:before {
76 | @extend .#{$ionicons-prefix}ios7-reload:before;
77 | }
78 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/ionicons/_ionicons-font.scss:
--------------------------------------------------------------------------------
1 | // Ionicons Font Path
2 | // --------------------------
3 |
4 | @font-face {
5 | font-family: $ionicons-font-family;
6 | src:url("#{$ionicons-font-path}/ionicons.eot?v=#{$ionicons-version}");
7 | src:url("#{$ionicons-font-path}/ionicons.eot?v=#{$ionicons-version}#iefix") format("embedded-opentype"),
8 | url("#{$ionicons-font-path}/ionicons.ttf?v=#{$ionicons-version}") format("truetype"),
9 | url("#{$ionicons-font-path}/ionicons.woff?v=#{$ionicons-version}") format("woff"),
10 | url("#{$ionicons-font-path}/ionicons.svg?v=#{$ionicons-version}#Ionicons") format("svg");
11 | font-weight: normal;
12 | font-style: normal;
13 | }
14 |
15 | .ion {
16 | display: inline-block;
17 | font-family: $ionicons-font-family;
18 | speak: none;
19 | font-style: normal;
20 | font-weight: normal;
21 | font-variant: normal;
22 | text-transform: none;
23 | text-rendering: auto;
24 | line-height: 1;
25 | -webkit-font-smoothing: antialiased;
26 | -moz-osx-font-smoothing: grayscale;
27 | }
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/scss/ionicons/ionicons.scss:
--------------------------------------------------------------------------------
1 | @import "ionicons-variables";
2 | /*!
3 | Ionicons, v1.5.2
4 | Created by Ben Sperry for the Ionic Framework, http://ionicons.com/
5 | https://twitter.com/benjsperry https://twitter.com/ionicframework
6 | MIT License: https://github.com/driftyco/ionicons
7 | */
8 |
9 | @import "ionicons-font";
10 | @import "ionicons-animation";
11 | @import "ionicons-icons";
12 |
--------------------------------------------------------------------------------
/client/ionic/www/lib/ionic/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-beta.14",
3 | "codename": "magnesium-mongoose",
4 | "date": "2014-12-15",
5 | "time": "20:15:38"
6 | }
7 |
--------------------------------------------------------------------------------
/client/ionic/www/templates/tab-account.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Enable Something
6 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/client/ionic/www/templates/tab-dash.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
This is your Ionic app
5 |
6 |
7 | It includes ionic styles (client/ionic/scss)
8 |
9 |
10 |
11 |
12 |
Common
13 |
14 |
15 | It also includes common styles (client/common/scss)
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/client/ionic/www/templates/tab-things.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{thing.name}}
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/client/ionic/www/templates/tabs.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/client/ionic/www/templates/thing-detail.html:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 | {{thing.name}}
10 |
11 | {{thing.info}}
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/client/webapp/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": true,
4 | "esnext": true,
5 | "bitwise": true,
6 | "camelcase": true,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "immed": true,
10 | "indent": 2,
11 | "latedef": true,
12 | "newcap": true,
13 | "noarg": true,
14 | "quotmark": "single",
15 | "regexp": true,
16 | "undef": true,
17 | "unused": true,
18 | "strict": true,
19 | "trailing": true,
20 | "smarttabs": true,
21 | "globals": {
22 | "jQuery": true,
23 | "angular": true,
24 | "console": true,
25 | "$": true,
26 | "_": true,
27 | "moment": true,
28 | "describe": true,
29 | "beforeEach": true,
30 | "module": true,
31 | "inject": true,
32 | "it": true,
33 | "expect": true,
34 | "browser": true,
35 | "element": true,
36 | "by": true
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/client/webapp/app/account/account.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .config(function ($stateProvider) {
5 | $stateProvider
6 | .state('login', {
7 | url: '/login',
8 | templateUrl: 'app/account/login/login.html',
9 | controller: 'LoginCtrl'
10 | })
11 | .state('signup', {
12 | url: '/signup',
13 | templateUrl: 'app/account/signup/signup.html',
14 | controller: 'SignupCtrl'
15 | })
16 | .state('settings', {
17 | url: '/settings',
18 | templateUrl: 'app/account/settings/settings.html',
19 | controller: 'SettingsCtrl',
20 | authenticate: true
21 | });
22 | });
--------------------------------------------------------------------------------
/client/webapp/app/account/login/login.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .controller('LoginCtrl', function ($scope, Auth, $location, $window) {
5 | $scope.user = {};
6 | $scope.errors = {};
7 |
8 | $scope.login = function(form) {
9 | $scope.submitted = true;
10 |
11 | if(form.$valid) {
12 | Auth.login({
13 | email: $scope.user.email,
14 | password: $scope.user.password
15 | })
16 | .then( function() {
17 | // Logged in, redirect to home
18 | $location.path('/');
19 | })
20 | .catch( function(err) {
21 | $scope.errors.other = err.message;
22 | });
23 | }
24 | };
25 |
26 | $scope.loginOauth = function(provider) {
27 | $window.location.href = '/auth/' + provider;
28 | };
29 | });
30 |
--------------------------------------------------------------------------------
/client/webapp/app/account/login/login.jade:
--------------------------------------------------------------------------------
1 | div(ng-include='"components/navbar/navbar.html"')
2 | .container
3 | .row
4 | .col-sm-12
5 | h1 Login
6 | p
7 | | Accounts are reset on server restart from
8 | code server/config/seed.js
9 | | . Default account is
10 | code test@test.com
11 | | /
12 | code test
13 | p
14 | | Admin account is
15 | code admin@admin.com
16 | | /
17 | code admin
18 |
19 | .col-sm-12
20 | form.form(name='form', ng-submit='login(form)', novalidate='')
21 | .form-group
22 | label Email
23 | input.form-control(type='text', name='email', ng-model='user.email')
24 | .form-group
25 | label Password
26 | input.form-control(type='password', name='password', ng-model='user.password')
27 |
28 | .form-group.has-error
29 | p.help-block(ng-show='form.email.$error.required && form.password.$error.required && submitted')
30 | | Please enter your email and password.
31 | p.help-block {{ errors.other }}
32 |
33 | div
34 | button.btn.btn-inverse.btn-lg.btn-login(type='submit')
35 | | Login
36 | = ' '
37 | a.btn.btn-default.btn-lg.btn-register(href='/signup')
38 | | Register
39 |
40 | hr
41 |
42 | div
43 | a.btn.btn-facebook(href='', ng-click='loginOauth("facebook")')
44 | i.fa.fa-facebook
45 | | Connect with Facebook
46 | = ' '
47 | a.btn.btn-google-plus(href='', ng-click='loginOauth("google")')
48 | i.fa.fa-google-plus
49 | | Connect with Google+
50 | = ' '
51 | a.btn.btn-twitter(href='', ng-click='loginOauth("twitter")')
52 | i.fa.fa-twitter
53 | | Connect with Twitter
54 | hr
55 |
--------------------------------------------------------------------------------
/client/webapp/app/account/login/login.scss:
--------------------------------------------------------------------------------
1 | // Colors
2 | // --------------------------------------------------
3 |
4 | $btnText: #fff;
5 | $btnTextAlt: #000;
6 |
7 | $btnFacebookBackground: #3B5998;
8 | $btnFacebookBackgroundHighlight: #133783;
9 | $btnTwitterBackground: #2daddc;
10 | $btnTwitterBackgroundHighlight: #0271bf;
11 | $btnGooglePlusBackground: #dd4b39;
12 | $btnGooglePlusBackgroundHighlight: #c53727;
13 | $btnGithubBackground: #fafafa;
14 | $btnGithubBackgroundHighlight: #ccc;
15 |
16 | // Social buttons
17 | // --------------------------------------------------
18 |
19 | .btn-facebook {
20 | @include button-variant($btnText, $btnFacebookBackgroundHighlight, $btnFacebookBackgroundHighlight);
21 | }
22 | .btn-twitter {
23 | @include button-variant($btnText, $btnTwitterBackground, $btnTwitterBackgroundHighlight);
24 | }
25 | .btn-google-plus {
26 | @include button-variant($btnText, $btnGooglePlusBackground, $btnGooglePlusBackgroundHighlight);
27 | }
28 | .btn-github {
29 | @include button-variant($btnTextAlt, $btnGithubBackground, $btnGithubBackgroundHighlight);
30 | }
31 |
--------------------------------------------------------------------------------
/client/webapp/app/account/settings/settings.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .controller('SettingsCtrl', function ($scope, User, Auth) {
5 | $scope.errors = {};
6 |
7 | $scope.changePassword = function(form) {
8 | $scope.submitted = true;
9 | if(form.$valid) {
10 | Auth.changePassword( $scope.user.oldPassword, $scope.user.newPassword )
11 | .then( function() {
12 | $scope.message = 'Password successfully changed.';
13 | })
14 | .catch( function() {
15 | form.password.$setValidity('mongoose', false);
16 | $scope.errors.other = 'Incorrect password';
17 | $scope.message = '';
18 | });
19 | }
20 | };
21 | });
22 |
--------------------------------------------------------------------------------
/client/webapp/app/account/settings/settings.jade:
--------------------------------------------------------------------------------
1 | div(ng-include='"components/navbar/navbar.html"')
2 | .container
3 | .row
4 | .col-sm-12
5 | h1 Change Password
6 | .col-sm-12
7 | form.form(name='form', ng-submit='changePassword(form)', novalidate='')
8 | .form-group
9 | label Current Password
10 | input.form-control(type='password', name='password', ng-model='user.oldPassword', mongoose-error='')
11 | p.help-block(ng-show='form.password.$error.mongoose')
12 | | {{ errors.other }}
13 | .form-group
14 | label New Password
15 | input.form-control(type='password', name='newPassword', ng-model='user.newPassword', ng-minlength='3', required='')
16 | p.help-block(ng-show='(form.newPassword.$error.minlength || form.newPassword.$error.required) && (form.newPassword.$dirty || submitted)')
17 | | Password must be at least 3 characters.
18 |
19 | p.help-block {{ message }}
20 |
21 | button.btn.btn-lg.btn-primary(type='submit') Save changes
22 |
--------------------------------------------------------------------------------
/client/webapp/app/account/signup/signup.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .controller('SignupCtrl', function ($scope, Auth, $location, $window) {
5 | $scope.user = {};
6 | $scope.errors = {};
7 |
8 | $scope.register = function(form) {
9 | $scope.submitted = true;
10 |
11 | if(form.$valid) {
12 | Auth.createUser({
13 | name: $scope.user.name,
14 | email: $scope.user.email,
15 | password: $scope.user.password
16 | })
17 | .then( function() {
18 | // Account created, redirect to home
19 | $location.path('/');
20 | })
21 | .catch( function(err) {
22 | err = err.data;
23 | $scope.errors = {};
24 |
25 | // Update validity of form fields that match the mongoose errors
26 | angular.forEach(err.errors, function(error, field) {
27 | form[field].$setValidity('mongoose', false);
28 | $scope.errors[field] = error.message;
29 | });
30 | });
31 | }
32 | };
33 |
34 | $scope.loginOauth = function(provider) {
35 | $window.location.href = '/auth/' + provider;
36 | };
37 | });
38 |
--------------------------------------------------------------------------------
/client/webapp/app/account/signup/signup.jade:
--------------------------------------------------------------------------------
1 | div(ng-include='"components/navbar/navbar.html"')
2 | .container
3 | .row
4 | .col-sm-12
5 | h1 Sign up
6 | .col-sm-12
7 | form.form(name='form', ng-submit='register(form)', novalidate='')
8 | .form-group(ng-class='{ "has-success": form.name.$valid && submitted,\
9 | "has-error": form.name.$invalid && submitted }')
10 | label Name
11 | input.form-control(type='text', name='name', ng-model='user.name', required='')
12 | p.help-block(ng-show='form.name.$error.required && submitted')
13 | | A name is required
14 |
15 | .form-group(ng-class='{ "has-success": form.email.$valid && submitted,\
16 | "has-error": form.email.$invalid && submitted }')
17 | label Email
18 | input.form-control(type='email', name='email', ng-model='user.email', required='', mongoose-error='')
19 | p.help-block(ng-show='form.email.$error.email && submitted')
20 | | Doesn't look like a valid email.
21 | p.help-block(ng-show='form.email.$error.required && submitted')
22 | | What's your email address?
23 | p.help-block(ng-show='form.email.$error.mongoose')
24 | | {{ errors.email }}
25 |
26 | .form-group(ng-class='{ "has-success": form.password.$valid && submitted,\
27 | "has-error": form.password.$invalid && submitted }')
28 | label Password
29 | input.form-control(type='password', name='password', ng-model='user.password', ng-minlength='3', required='', mongoose-error='')
30 | p.help-block(ng-show='(form.password.$error.minlength || form.password.$error.required) && submitted')
31 | | Password must be at least 3 characters.
32 | p.help-block(ng-show='form.password.$error.mongoose')
33 | | {{ errors.password }}
34 |
35 | div
36 | button.btn.btn-inverse.btn-lg.btn-login(type='submit')
37 | | Sign up
38 | = ' '
39 | a.btn.btn-default.btn-lg.btn-register(href='/login')
40 | | Login
41 |
42 |
43 | hr
44 |
45 | div
46 | a.btn.btn-facebook(href='', ng-click='loginOauth("facebook")')
47 | i.fa.fa-facebook
48 | | Connect with Facebook
49 | = ' '
50 | a.btn.btn-google-plus(href='', ng-click='loginOauth("google")')
51 | i.fa.fa-google-plus
52 | | Connect with Google+
53 | = ' '
54 | a.btn.btn-twitter(href='', ng-click='loginOauth("twitter")')
55 | i.fa.fa-twitter
56 | | Connect with Twitter
57 | hr
58 |
--------------------------------------------------------------------------------
/client/webapp/app/admin/admin.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .controller('AdminCtrl', function ($scope, $http, Auth, User) {
5 |
6 | // Use the User $resource to fetch all users
7 | $scope.users = User.query();
8 |
9 | $scope.delete = function(user) {
10 | User.remove({ id: user._id });
11 | angular.forEach($scope.users, function(u, i) {
12 | if (u === user) {
13 | $scope.users.splice(i, 1);
14 | }
15 | });
16 | };
17 | });
18 |
--------------------------------------------------------------------------------
/client/webapp/app/admin/admin.jade:
--------------------------------------------------------------------------------
1 | div(ng-include='"components/navbar/navbar.html"')
2 | .container
3 | p
4 | | The delete user and user index api routes are restricted to users with the 'admin' role.
5 | ul.list-group
6 | li.list-group-item(ng-repeat='user in users')
7 | strong {{user.name}}
8 | br
9 | span.text-muted {{user.email}}
10 | a.trash(ng-click='delete(user)')
11 | span.glyphicon.glyphicon-trash.pull-right
--------------------------------------------------------------------------------
/client/webapp/app/admin/admin.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .config(function ($stateProvider) {
5 | $stateProvider
6 | .state('admin', {
7 | url: '/admin',
8 | templateUrl: 'app/admin/admin.html',
9 | controller: 'AdminCtrl'
10 | });
11 | });
--------------------------------------------------------------------------------
/client/webapp/app/admin/admin.scss:
--------------------------------------------------------------------------------
1 | .trash { color:rgb(209, 91, 71); }
2 |
--------------------------------------------------------------------------------
/client/webapp/app/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp', [
4 | 'ngCookies',
5 | 'ngResource',
6 | 'ngSanitize',
7 | 'ui.router',
8 | 'ui.bootstrap'
9 | ])
10 | .config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
11 | $urlRouterProvider
12 | .otherwise('/');
13 |
14 | $locationProvider.html5Mode(true);
15 | $httpProvider.interceptors.push('authInterceptor');
16 | })
17 |
18 | .factory('authInterceptor', function ($rootScope, $q, $cookieStore, $location) {
19 | return {
20 | // Add authorization token to headers
21 | request: function (config) {
22 | config.headers = config.headers || {};
23 | if ($cookieStore.get('token')) {
24 | config.headers.Authorization = 'Bearer ' + $cookieStore.get('token');
25 | }
26 | return config;
27 | },
28 |
29 | // Intercept 401s and redirect you to login
30 | responseError: function(response) {
31 | if(response.status === 401) {
32 | $location.path('/login');
33 | // remove any stale tokens
34 | $cookieStore.remove('token');
35 | return $q.reject(response);
36 | }
37 | else {
38 | return $q.reject(response);
39 | }
40 | }
41 | };
42 | })
43 |
44 | .run(function ($rootScope, $location, Auth) {
45 | // Redirect to login if route requires auth and you're not logged in
46 | $rootScope.$on('$stateChangeStart', function (event, next) {
47 | Auth.isLoggedInAsync(function(loggedIn) {
48 | if (next.authenticate && !loggedIn) {
49 | $location.path('/login');
50 | }
51 | });
52 | });
53 | });
--------------------------------------------------------------------------------
/client/webapp/app/app.scss:
--------------------------------------------------------------------------------
1 | /**
2 | Create webapp wide styles in client/webapp/scss folder
3 | There should be no need to edit this file
4 | */
5 |
6 | $icon-font-path: "/bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/";
7 | $fa-font-path: "/bower_components/font-awesome/fonts";
8 |
9 | @import 'bootstrap-sass-official/vendor/assets/stylesheets/bootstrap';
10 | @import 'font-awesome/scss/font-awesome';
11 |
12 | // Webapp component (including folders in app directory) styles are injected through grunt
13 | // injector
14 | @import 'account/login/login.scss';
15 | @import 'admin/admin.scss';
16 | @import 'main/main.scss';
17 | @import 'modal/modal.scss';
18 | // endinjector
19 |
20 | @import '../scss/webapp.scss';
21 |
22 | .browsehappy {
23 | margin: 0.2em 0;
24 | background: #ccc;
25 | color: #000;
26 | padding: 0.2em 0;
27 | }
--------------------------------------------------------------------------------
/client/webapp/app/main/main.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .controller('MainCtrl', function ($scope, $http) {
5 | $scope.awesomeThings = [];
6 |
7 | $http.get('/api/things').success(function(awesomeThings) {
8 | $scope.awesomeThings = awesomeThings;
9 | });
10 |
11 | $scope.addThing = function() {
12 | if($scope.newThing === '') {
13 | return;
14 | }
15 | $http.post('/api/things', { name: $scope.newThing });
16 | $scope.newThing = '';
17 | };
18 |
19 | $scope.deleteThing = function(thing) {
20 | $http.delete('/api/things/' + thing._id);
21 | };
22 | });
23 |
--------------------------------------------------------------------------------
/client/webapp/app/main/main.controller.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('Controller: MainCtrl', function () {
4 |
5 | // load the controller's module
6 | beforeEach(module('starterApp'));
7 |
8 | var MainCtrl,
9 | scope,
10 | $httpBackend;
11 |
12 | // Initialize the controller and a mock scope
13 | beforeEach(inject(function (_$httpBackend_, $controller, $rootScope) {
14 | $httpBackend = _$httpBackend_;
15 | $httpBackend.expectGET('/api/things')
16 | .respond(['HTML5 Boilerplate', 'AngularJS', 'Karma', 'Express']);
17 |
18 | scope = $rootScope.$new();
19 | MainCtrl = $controller('MainCtrl', {
20 | $scope: scope
21 | });
22 | }));
23 |
24 | it('should attach a list of things to the scope', function () {
25 | $httpBackend.flush();
26 | expect(scope.awesomeThings.length).toBe(4);
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/client/webapp/app/main/main.jade:
--------------------------------------------------------------------------------
1 | div(ng-include='"components/navbar/navbar.html"')
2 |
3 | header#banner.hero-unit
4 | .container
5 | h1 'Allo, 'Allo!
6 | p.lead Kick-start your next web and Ionic app with Angular Fullstack Ionic
7 | img(src='common/assets/images/yeoman.png', alt='I\'m Yeoman')
8 |
9 | .container
10 | .row
11 | .col-lg-12
12 | h1.page-header Angular Fullstack Ionic
13 | h2 This is your webapp
14 | .panel.webapp-class
15 | .panel-body Your webapp includes webapp styles (client/webapp/scss)
16 | .panel.common-class
17 | .panel-body It also includes common styles (client/common/scss)
18 | .row
19 | .col-lg-12
20 | h3 Based on Angular Fullstack
21 | ul.nav.nav-tabs.nav-stacked.col-md-4.col-lg-4.col-sm-6(ng-repeat='thing in awesomeThings')
22 | li
23 | a(href='#', tooltip='{{thing.info}}')
24 | | {{thing.name}}
25 |
26 | footer.footer
27 | .container
28 | p
29 | | Angular Fullstack v2.0.13
30 | = ' | '
31 | a(href='https://twitter.com/tyhenkel') @tyhenkel
32 | = ' | '
33 | a(href='https://github.com/DaftMonk/generator-angular-fullstack/issues?state=open') Issues
34 | p
35 | | Angular Fullstack Ionic v0.0.1
36 | = ' | '
37 | a(href='https://twitter.com/richardgsands') @richardgsands
38 | = ' | '
39 | a(href='https://github.com/richardgsands/generator-angular-fullstack-ionic/issues?state=open') Issues
--------------------------------------------------------------------------------
/client/webapp/app/main/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .config(function ($stateProvider) {
5 | $stateProvider
6 | .state('main', {
7 | url: '/',
8 | templateUrl: 'app/main/main.html',
9 | controller: 'MainCtrl'
10 | });
11 | });
--------------------------------------------------------------------------------
/client/webapp/app/main/main.scss:
--------------------------------------------------------------------------------
1 | .thing-form {
2 | margin: 20px 0;
3 | }
4 |
5 | #banner {
6 | border-bottom: none;
7 | margin-top: -20px;
8 | }
9 |
10 | #banner h1 {
11 | font-size: 60px;
12 | line-height: 1;
13 | letter-spacing: -1px;
14 | }
15 |
16 | .hero-unit {
17 | position: relative;
18 | padding: 30px 15px;
19 | color: #F5F5F5;
20 | text-align: center;
21 | text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
22 | background: #4393B9;
23 | }
24 |
25 | .footer {
26 | text-align: center;
27 | padding: 30px 0;
28 | margin-top: 70px;
29 | border-top: 1px solid #E5E5E5;
30 | }
--------------------------------------------------------------------------------
/client/webapp/components/auth/auth.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .factory('Auth', function Auth($location, $rootScope, $http, User, $cookieStore, $q) {
5 | var currentUser = {};
6 | if($cookieStore.get('token')) {
7 | currentUser = User.get();
8 | }
9 |
10 | return {
11 |
12 | /**
13 | * Authenticate user and save token
14 | *
15 | * @param {Object} user - login info
16 | * @param {Function} callback - optional
17 | * @return {Promise}
18 | */
19 | login: function(user, callback) {
20 | var cb = callback || angular.noop;
21 | var deferred = $q.defer();
22 |
23 | $http.post('/auth/local', {
24 | email: user.email,
25 | password: user.password
26 | }).
27 | success(function(data) {
28 | $cookieStore.put('token', data.token);
29 | currentUser = User.get();
30 | deferred.resolve(data);
31 | return cb();
32 | }).
33 | error(function(err) {
34 | this.logout();
35 | deferred.reject(err);
36 | return cb(err);
37 | }.bind(this));
38 |
39 | return deferred.promise;
40 | },
41 |
42 | /**
43 | * Delete access token and user info
44 | *
45 | * @param {Function}
46 | */
47 | logout: function() {
48 | $cookieStore.remove('token');
49 | currentUser = {};
50 | },
51 |
52 | /**
53 | * Create a new user
54 | *
55 | * @param {Object} user - user info
56 | * @param {Function} callback - optional
57 | * @return {Promise}
58 | */
59 | createUser: function(user, callback) {
60 | var cb = callback || angular.noop;
61 |
62 | return User.save(user,
63 | function(data) {
64 | $cookieStore.put('token', data.token);
65 | currentUser = User.get();
66 | return cb(user);
67 | },
68 | function(err) {
69 | this.logout();
70 | return cb(err);
71 | }.bind(this)).$promise;
72 | },
73 |
74 | /**
75 | * Change password
76 | *
77 | * @param {String} oldPassword
78 | * @param {String} newPassword
79 | * @param {Function} callback - optional
80 | * @return {Promise}
81 | */
82 | changePassword: function(oldPassword, newPassword, callback) {
83 | var cb = callback || angular.noop;
84 |
85 | return User.changePassword({ id: currentUser._id }, {
86 | oldPassword: oldPassword,
87 | newPassword: newPassword
88 | }, function(user) {
89 | return cb(user);
90 | }, function(err) {
91 | return cb(err);
92 | }).$promise;
93 | },
94 |
95 | /**
96 | * Gets all available info on authenticated user
97 | *
98 | * @return {Object} user
99 | */
100 | getCurrentUser: function() {
101 | return currentUser;
102 | },
103 |
104 | /**
105 | * Check if a user is logged in
106 | *
107 | * @return {Boolean}
108 | */
109 | isLoggedIn: function() {
110 | return currentUser.hasOwnProperty('role');
111 | },
112 |
113 | /**
114 | * Waits for currentUser to resolve before checking if user is logged in
115 | */
116 | isLoggedInAsync: function(cb) {
117 | if(currentUser.hasOwnProperty('$promise')) {
118 | currentUser.$promise.then(function() {
119 | cb(true);
120 | }).catch(function() {
121 | cb(false);
122 | });
123 | } else if(currentUser.hasOwnProperty('role')) {
124 | cb(true);
125 | } else {
126 | cb(false);
127 | }
128 | },
129 |
130 | /**
131 | * Check if a user is an admin
132 | *
133 | * @return {Boolean}
134 | */
135 | isAdmin: function() {
136 | return currentUser.role === 'admin';
137 | },
138 |
139 | /**
140 | * Get auth token
141 | */
142 | getToken: function() {
143 | return $cookieStore.get('token');
144 | }
145 | };
146 | });
147 |
--------------------------------------------------------------------------------
/client/webapp/components/auth/user.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .factory('User', function ($resource) {
5 | return $resource('/api/users/:id/:controller', {
6 | id: '@_id'
7 | },
8 | {
9 | changePassword: {
10 | method: 'PUT',
11 | params: {
12 | controller:'password'
13 | }
14 | },
15 | get: {
16 | method: 'GET',
17 | params: {
18 | id:'me'
19 | }
20 | }
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/client/webapp/components/modal/modal.jade:
--------------------------------------------------------------------------------
1 | .modal-header
2 | button.close(ng-if='modal.dismissable', type='button', ng-click='$dismiss()') ×
3 | h4.modal-title(ng-if='modal.title', ng-bind='modal.title')
4 | .modal-body
5 | p(ng-if='modal.text', ng-bind='modal.text')
6 | div(ng-if='modal.html', ng-bind-html='modal.html')
7 | .modal-footer
8 | button.btn(ng-repeat='button in modal.buttons', ng-class='button.classes', ng-click='button.click($event)', ng-bind='button.text')
9 |
--------------------------------------------------------------------------------
/client/webapp/components/modal/modal.scss:
--------------------------------------------------------------------------------
1 | .modal-primary,
2 | .modal-info,
3 | .modal-success,
4 | .modal-warning,
5 | .modal-danger {
6 | .modal-header {
7 | color: #fff;
8 | border-radius: 5px 5px 0 0;
9 | }
10 | }
11 | .modal-primary .modal-header {
12 | background: $brand-primary;
13 | }
14 | .modal-info .modal-header {
15 | background: $brand-info;
16 | }
17 | .modal-success .modal-header {
18 | background: $brand-success;
19 | }
20 | .modal-warning .modal-header {
21 | background: $brand-warning;
22 | }
23 | .modal-danger .modal-header {
24 | background: $brand-danger;
25 | }
26 |
--------------------------------------------------------------------------------
/client/webapp/components/modal/modal.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .factory('Modal', function ($rootScope, $modal) {
5 | /**
6 | * Opens a modal
7 | * @param {Object} scope - an object to be merged with modal's scope
8 | * @param {String} modalClass - (optional) class(es) to be applied to the modal
9 | * @return {Object} - the instance $modal.open() returns
10 | */
11 | function openModal(scope, modalClass) {
12 | var modalScope = $rootScope.$new();
13 | scope = scope || {};
14 | modalClass = modalClass || 'modal-default';
15 |
16 | angular.extend(modalScope, scope);
17 |
18 | return $modal.open({
19 | templateUrl: 'components/modal/modal.html',
20 | windowClass: modalClass,
21 | scope: modalScope
22 | });
23 | }
24 |
25 | // Public API here
26 | return {
27 |
28 | /* Confirmation modals */
29 | confirm: {
30 |
31 | /**
32 | * Create a function to open a delete confirmation modal (ex. ng-click='myModalFn(name, arg1, arg2...)')
33 | * @param {Function} del - callback, ran when delete is confirmed
34 | * @return {Function} - the function to open the modal (ex. myModalFn)
35 | */
36 | delete: function(del) {
37 | del = del || angular.noop;
38 |
39 | /**
40 | * Open a delete confirmation modal
41 | * @param {String} name - name or info to show on modal
42 | * @param {All} - any additional args are passed staight to del callback
43 | */
44 | return function() {
45 | var args = Array.prototype.slice.call(arguments),
46 | name = args.shift(),
47 | deleteModal;
48 |
49 | deleteModal = openModal({
50 | modal: {
51 | dismissable: true,
52 | title: 'Confirm Delete',
53 | html: 'Are you sure you want to delete ' + name + ' ?
',
54 | buttons: [{
55 | classes: 'btn-danger',
56 | text: 'Delete',
57 | click: function(e) {
58 | deleteModal.close(e);
59 | }
60 | }, {
61 | classes: 'btn-default',
62 | text: 'Cancel',
63 | click: function(e) {
64 | deleteModal.dismiss(e);
65 | }
66 | }]
67 | }
68 | }, 'modal-danger');
69 |
70 | deleteModal.result.then(function(event) {
71 | del.apply(event, args);
72 | });
73 | };
74 | }
75 | }
76 | };
77 | });
78 |
--------------------------------------------------------------------------------
/client/webapp/components/mongoose-error/mongoose-error.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Removes server error when user updates input
5 | */
6 | angular.module('starterApp')
7 | .directive('mongooseError', function () {
8 | return {
9 | restrict: 'A',
10 | require: 'ngModel',
11 | link: function(scope, element, attrs, ngModel) {
12 | element.on('keydown', function() {
13 | return ngModel.$setValidity('mongoose', true);
14 | });
15 | }
16 | };
17 | });
--------------------------------------------------------------------------------
/client/webapp/components/navbar/navbar.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('starterApp')
4 | .controller('NavbarCtrl', function ($scope, $location, Auth) {
5 | $scope.menu = [{
6 | 'title': 'Home',
7 | 'link': '/'
8 | }];
9 |
10 | $scope.isCollapsed = true;
11 | $scope.isLoggedIn = Auth.isLoggedIn;
12 | $scope.isAdmin = Auth.isAdmin;
13 | $scope.getCurrentUser = Auth.getCurrentUser;
14 |
15 | $scope.logout = function() {
16 | Auth.logout();
17 | $location.path('/login');
18 | };
19 |
20 | $scope.isActive = function(route) {
21 | return route === $location.path();
22 | };
23 | });
--------------------------------------------------------------------------------
/client/webapp/components/navbar/navbar.jade:
--------------------------------------------------------------------------------
1 | div.navbar.navbar-default.navbar-static-top(ng-controller='NavbarCtrl')
2 | div.container
3 | div.navbar-header
4 | button.navbar-toggle(type='button', ng-click='isCollapsed = !isCollapsed')
5 | span.sr-only Toggle navigation
6 | span.icon-bar
7 | span.icon-bar
8 | span.icon-bar
9 | a.navbar-brand(href='/') Starter
10 |
11 | div#navbar-main.navbar-collapse.collapse(collapse='isCollapsed')
12 | ul.nav.navbar-nav
13 | li(ng-repeat='item in menu', ng-class='{active: isActive(item.link)}')
14 | a(ng-href='{{item.link}}') {{item.title}}
15 |
16 | li(ng-show='isAdmin()', ng-class='{active: isActive("/admin")}')
17 | a(href='/admin') Admin
18 |
19 | ul.nav.navbar-nav.navbar-right
20 | li(ng-hide='isLoggedIn()', ng-class='{active: isActive("/signup")}')
21 | a(href='/signup') Sign up
22 |
23 | li(ng-hide='isLoggedIn()', ng-class='{active: isActive("/login")}')
24 | a(href='/login') Login
25 |
26 | li(ng-show='isLoggedIn()')
27 | p.navbar-text Hello {{ getCurrentUser().name }}
28 |
29 | li(ng-show='isLoggedIn()', ng-class='{active: isActive("/settings")}')
30 | a(href='/settings')
31 | span.glyphicon.glyphicon-cog
32 |
33 | li(ng-show='isLoggedIn()', ng-class='{active: isActive("/logout")}')
34 | a(href='', ng-click='logout()') Logout
--------------------------------------------------------------------------------
/client/webapp/favicon.ico:
--------------------------------------------------------------------------------
1 | � ( @ -2Op"=p�Jt��Jt��b���������������������������������������������������b���Jt��Jt��"=p�Op-2 O`O�O�O�O�O�O�O�$\�Jt��������������v���v���������������Jt��$\�O�O�O�O�O�O�O�O` O�O�O�O�O�O�O�O�O�O� ;n�s���>���>���>���>���s��� ;n�O�O�O�O�O�O�O�O�O�O� O`O�O�O�O�O�O�O�O�O�O�$\�]���^n��^n��]���$\�O�O�O�O�O�O�O�O�O�O�O` O�O�O�O�O�O�O�O�O�O�O�n�* ��* ��n�O�O�O�O�O�O�O�O�O�O�O� O�O�O�O�O�O�O�O�O�O�O�5>Y�5>Y�O�O�O�O�O�O�O�O�O�O�O� -2O�O�O�O�O�O�O�O�O�O�&6e�&6e�O�O�O�O�O�O�O�O�O�O�-2 5r�4���E���$\�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�O�$\�E���4���5r� 5r�E���M���M���v���0\��O�O�O�O�O�O�O�$\�$\�O�O�O�O�O�O�O�0\��v���M���M���E���5r� )��p&��p��&��������������b���Jt��Jt��Jt��0\��#i��.r��.r��#i��0\��Jt��Jt��Jt��b���������������&��p��&��)��p 4���&��-���_������������������]���]�������7���p�����������p���7�������]���]�������������������_��-���-���4��� qֈp��p��p����������������������p���7���#i��p�����������p���#i��7���p�����������������������p��&��-���qֈ 8��(p��p��I���v���v���]���7���n���v���p���#i��]���v���v���]���#i��p���v���n���7���]���v���v���I���-���-���8��( ;��`-���M���7���7���7���.r��R��E��R��E��7���7���7���7���E��R��E��R��.r��7���7���7���M���M���;��` ���������������������������z ���������������������������
2 | � ���
3 | �
9�
9�
9�
9�
9�
9�
9�
9�
4 | �n�n�
5 | �
9�
9�
9�
9�
9�
9�
9�
9�
6 | ���� * �x* ��* ��* ��* ��* ��* ��* ��n�&