master 558f51695574 cached
171 files
1.2 MB
371.8k tokens
5 symbols
1 requests
Download .txt
Showing preview only (1,331K chars total). Download the full file or copy to clipboard to get everything.
Repository: pbernasconi/ionic-theme-editor
Branch: master
Commit: 558f51695574
Files: 171
Total size: 1.2 MB

Directory structure:
gitextract_mcss25s2/

├── .bowerrc
├── .buildignore
├── .gitignore
├── .travis.yml
├── .yo-rc.json
├── Gruntfile.js
├── LICENSE.md
├── README.md
├── bower.json
├── client/
│   ├── .htaccess
│   ├── .jshintrc
│   ├── app/
│   │   ├── app.css
│   │   ├── app.js
│   │   ├── compiler/
│   │   │   ├── compiler.service.js
│   │   │   └── compiler.service.spec.js
│   │   ├── main/
│   │   │   ├── main.controller.js
│   │   │   ├── main.controller.spec.js
│   │   │   ├── main.css
│   │   │   ├── main.html
│   │   │   └── main.js
│   │   └── theme/
│   │       ├── theme.directive.js
│   │       └── theme.directive.spec.js
│   ├── components/
│   │   └── preview/
│   │       ├── preview-buttons.html
│   │       ├── preview-card.html
│   │       ├── preview-components.html
│   │       ├── preview-form.html
│   │       ├── preview-header.html
│   │       ├── preview-list.html
│   │       └── preview-tabs.html
│   ├── index.html
│   └── robots.txt
├── e2e/
│   └── main/
│       ├── main.po.js
│       └── main.spec.js
├── ionic-tailor.sketch
├── karma.conf.js
├── package.json
├── protractor.conf.js
└── server/
    ├── .jshintrc
    ├── api/
    │   ├── compile/
    │   │   ├── compile.controller.js
    │   │   ├── compile.model.js
    │   │   ├── compile.spec.js
    │   │   └── index.js
    │   └── themes/
    │       ├── index.js
    │       ├── themes.controller.js
    │       ├── themes.model.js
    │       └── themes.spec.js
    ├── app.js
    ├── components/
    │   └── errors/
    │       └── index.js
    ├── config/
    │   ├── environment/
    │   │   ├── development.js
    │   │   ├── index.js
    │   │   ├── production.js
    │   │   └── test.js
    │   └── express.js
    ├── ionic/
    │   ├── scss-live/
    │   │   ├── _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
    │   │   ├── _loaders.scss
    │   │   ├── _loading.scss
    │   │   ├── _menu.scss
    │   │   ├── _mixins.scss
    │   │   ├── _modal.scss
    │   │   ├── _platform.scss
    │   │   ├── _popover.scss
    │   │   ├── _popup.scss
    │   │   ├── _progress.scss
    │   │   ├── _radio.scss
    │   │   ├── _range.scss
    │   │   ├── _refresher.scss
    │   │   ├── _reset.scss
    │   │   ├── _scaffolding.scss
    │   │   ├── _select.scss
    │   │   ├── _slide-box.scss
    │   │   ├── _split-pane.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
    │   ├── scss-prod/
    │   │   ├── _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
    │   │   ├── _loaders.scss
    │   │   ├── _loading.scss
    │   │   ├── _menu.scss
    │   │   ├── _mixins.scss
    │   │   ├── _modal.scss
    │   │   ├── _platform.scss
    │   │   ├── _popover.scss
    │   │   ├── _popup.scss
    │   │   ├── _progress.scss
    │   │   ├── _radio.scss
    │   │   ├── _range.scss
    │   │   ├── _refresher.scss
    │   │   ├── _reset.scss
    │   │   ├── _scaffolding.scss
    │   │   ├── _select.scss
    │   │   ├── _slide-box.scss
    │   │   ├── _split-pane.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
    │   ├── scss_test/
    │   │   ├── _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
    │   │   ├── _type.scss
    │   │   ├── _util.scss
    │   │   ├── _variables.scss
    │   │   └── ionic.scss
    │   └── tmp/
    │       ├── ionic-Zk2IRRDU4.app.css
    │       └── ionic-ZkD6jCwL4.app.css
    ├── routes.js
    └── views/
        └── 404.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .bowerrc
================================================
{
    "directory": "client/bower_components"
}


================================================
FILE: .buildignore
================================================
*.coffee

================================================
FILE: .gitignore
================================================
dist
node_modules
.idea
.tmp
client/bower_components
server/config/local.env.js


================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - '0.10'
  - '0.11'
before_script:
  - npm install -g bower grunt-cli
  - bower install
services: mongodb

================================================
FILE: .yo-rc.json
================================================
{
  "generator-angular-fullstack": {
    "insertRoutes": true,
    "registerRoutesFile": "server/routes.js",
    "routesNeedle": "// Insert routes below",
    "routesBase": "/api/",
    "pluralizeRoutes": true,
    "insertSockets": true,
    "registerSocketsFile": "server/config/socketio.js",
    "socketsNeedle": "// Insert sockets below",
    "filters": {
      "js": true,
      "html": true,
      "css": true,
      "uirouter": true,
      "bootstrap": true,
      "uibootstrap": true,
      "mongoose": true
    }
  },
  "generator-ng-component": {
    "routeDirectory": "client/app/",
    "directiveDirectory": "client/app/",
    "filterDirectory": "client/app/",
    "serviceDirectory": "client/app/",
    "basePath": "client",
    "filters": [
      "uirouter"
    ],
    "extensions": [
      "js",
      "html",
      "css"
    ]
  }
}

================================================
FILE: Gruntfile.js
================================================
'use strict';

module.exports = function (grunt) {
    var localConfig;
    try {
        localConfig = require('./server/config/local.env');
    } catch (e) {
        localConfig = {};
    }

    // Load grunt tasks automatically, when needed
    require('jit-grunt')(grunt, {
        express: 'grunt-express-server',
        useminPrepare: 'grunt-usemin',
        ngtemplates: 'grunt-angular-templates',
        cdnify: 'grunt-google-cdn',
        protractor: 'grunt-protractor-runner',
        injector: 'grunt-asset-injector'
    });

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        yeoman: {
            // configurable paths
            client: require('./bower.json').appPath || 'client',
            dist: 'dist'
        },
        express: {
            options: {
                port: process.env.PORT || 9000
            },
            dev: {
                options: {
                    script: 'server/app.js',
                    debug: true
                }
            },
            prod: {
                options: {
                    script: 'dist/server/app.js'
                }
            }
        },
        open: {
            server: {
                url: 'http://localhost:<%= express.options.port %>'
            }
        },
        watch: {
            injectJS: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.js',
                    '!<%= yeoman.client %>/{app,components}/**/*.spec.js',
                    '!<%= yeoman.client %>/{app,components}/**/*.mock.js',
                    '!<%= yeoman.client %>/app/app.js'],
                tasks: ['injector:scripts']
            },
            injectCss: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.css'
                ],
                tasks: ['injector:css']
            },
            mochaTest: {
                files: ['server/**/*.spec.js'],
                tasks: ['env:test', 'mochaTest']
            },
            jsTest: {
                files: [
                    '<%= yeoman.client %>/{app,components}/**/*.spec.js',
                    '<%= yeoman.client %>/{app,components}/**/*.mock.js'
                ],
                tasks: ['newer:jshint:all', 'karma']
            },
            gruntfile: {
                files: ['Gruntfile.js']
            },
            livereload: {
                files: [
                    '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.css',
                    '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.html',
                    '{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',
                    '!{.tmp,<%= yeoman.client %>}{app,components}/**/*.spec.js',
                    '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js',
                    '<%= yeoman.client %>/assets/images/{,*//*}*.{png,jpg,jpeg,gif,webp,svg}'
                ],
                options: {
                    livereload: true
                }
            },
            express: {
                files: [
                    'server/**/*.{js,json}'
                ],
                tasks: ['express:dev', 'wait'],
                options: {
                    livereload: true,
                    nospawn: true //Without this option specified express won't be reloaded
                }
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '<%= yeoman.client %>/.jshintrc',
                reporter: require('jshint-stylish')
            },
            server: {
                options: {
                    jshintrc: 'server/.jshintrc'
                },
                src: [ 'server/{,*/}*.js']
            },
            all: [
                '<%= yeoman.client %>/{app,components}/**/*.js',
                '!<%= yeoman.client %>/{app,components}/**/*.spec.js',
                '!<%= yeoman.client %>/{app,components}/**/*.mock.js'
            ],
            test: {
                src: [
                    '<%= yeoman.client %>/{app,components}/**/*.spec.js',
                    '<%= yeoman.client %>/{app,components}/**/*.mock.js'
                ]
            }
        },

        // Empties folders to start fresh
        clean: {
            dist: {
                files: [
                    {
                        dot: true,
                        src: [
                            '.tmp',
                            '<%= yeoman.dist %>/*',
                            '!<%= yeoman.dist %>/.git*',
                            '!<%= yeoman.dist %>/.openshift',
                            '!<%= yeoman.dist %>/Procfile'
                        ]
                    }
                ]
            },
            server: '.tmp'
        },

        // Add vendor prefixed styles
        autoprefixer: {
            options: {
                browsers: ['last 1 version']
            },
            dist: {
                files: [
                    {
                        expand: true,
                        cwd: '.tmp/',
                        src: '{,*/}*.css',
                        dest: '.tmp/'
                    }
                ]
            }
        },

        // Debugging with node inspector
        'node-inspector': {
            custom: {
                options: {
                    'web-host': 'localhost'
                }
            }
        },

        // Use nodemon to run server in debug mode with an initial breakpoint
        nodemon: {
            debug: {
                script: 'server/app.js',
                options: {
                    nodeArgs: ['--debug-brk'],
                    env: {
                        PORT: process.env.PORT || 9000
                    },
                    callback: function (nodemon) {
                        nodemon.on('log', function (event) {
                            console.log(event.colour);
                        });

                        // opens browser on initial server start
                        nodemon.on('config:update', function () {
                            setTimeout(function () {
                                require('open')('http://localhost:8080/debug?port=5858');
                            }, 500);
                        });
                    }
                }
            }
        },

        // Automatically inject Bower components into the app
        bowerInstall: {
            target: {
                src: '<%= yeoman.client %>/index.html',
                ignorePath: '<%= yeoman.client %>/',
                exclude: [/bootstrap-sass-official/, /bootstrap.js/, '/json3/', '/es5-shim/']
            }
        },

        // Renames files for browser caching purposes
        rev: {
            dist: {
                files: {
                    src: [
                        '<%= yeoman.dist %>/public/{,*/}*.js',
                        '<%= yeoman.dist %>/public/{,*/}*.css',
                        '<%= yeoman.dist %>/public/assets/fonts/*'
                    ]
                }
            }
        },

        // Reads HTML for usemin blocks to enable smart builds that automatically
        // concat, minify and revision files. Creates configurations in memory so
        // additional tasks can operate on them
        useminPrepare: {
            html: ['<%= yeoman.client %>/index.html'],
            options: {
                dest: '<%= yeoman.dist %>/public'
            }
        },

        // Performs rewrites based on rev and the useminPrepare configuration
        usemin: {
            html: ['<%= yeoman.dist %>/public/{,*/}*.html'],
            css: ['<%= yeoman.dist %>/public/{,*/}*.css'],
            js: ['<%= yeoman.dist %>/public/{,*/}*.js'],
            options: {
                assetsDirs: [
                    '<%= yeoman.dist %>/public',
                    '<%= yeoman.dist %>/public/assets/images'
                ],
                // This is so we update image references in our ng-templates
                patterns: {
                    js: [
                        [/(assets\/images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm, 'Update the JS to reference our revved images']
                    ]
                }
            }
        },

        // The following *-min tasks produce minified files in the dist folder
        imagemin: {
            dist: {
                files: [
                    {
                        expand: true,
                        cwd: '<%= yeoman.client %>/assets/images',
                        src: '{,*/}*.{png,jpg,jpeg,gif}',
                        dest: '<%= yeoman.dist %>/public/assets/images'
                    }
                ]
            }
        },

        svgmin: {
            dist: {
                files: [
                    {
                        expand: true,
                        cwd: '<%= yeoman.client %>/assets/images',
                        src: '{,*/}*.svg',
                        dest: '<%= yeoman.dist %>/public/assets/images'
                    }
                ]
            }
        },

        // Allow the use of non-minsafe AngularJS files. Automatically makes it
        // minsafe compatible so Uglify does not destroy the ng references
        ngAnnotate: {
            dist: {
                files: [
                    {
                        expand: true,
                        cwd: '.tmp/concat',
                        src: '*/**.js',
                        dest: '.tmp/concat'
                    }
                ]
            }
        },

        // Package all the html partials into a single javascript payload
        ngtemplates: {
            options: {
                // This should be the name of your apps angular module
                module: 'projectsApp',
                htmlmin: {
                    collapseBooleanAttributes: true,
                    collapseWhitespace: true,
                    removeAttributeQuotes: true,
                    removeEmptyAttributes: true,
                    removeRedundantAttributes: true,
                    removeScriptTypeAttributes: true,
                    removeStyleLinkTypeAttributes: true
                },
                usemin: 'app/app.js'
            },
            main: {
                cwd: '<%= yeoman.client %>',
                src: ['{app,components}/**/*.html'],
                dest: '.tmp/templates.js'
            },
            tmp: {
                cwd: '.tmp',
                src: ['{app,components}/**/*.html'],
                dest: '.tmp/tmp-templates.js'
            }
        },

        // Replace Google CDN references
        cdnify: {
            dist: {
                html: ['<%= yeoman.dist %>/*.html']
            }
        },

        // Copies remaining files to places other tasks can use
        copy: {
            dist: {
                files: [
                    {
                        expand: true,
                        dot: true,
                        cwd: '<%= yeoman.client %>',
                        dest: '<%= yeoman.dist %>/public',
                        src: [
                            '*.{ico,png,txt}',
                            '.htaccess',
                            'bower_components/**/*',
                            'assets/images/{,*/}*.{webp}',
                            'assets/fonts/**/*',
                            'components/**/*',
                            'index.html'
                        ]
                    },
                    {
                        expand: true,
                        cwd: '.tmp/images',
                        dest: '<%= yeoman.dist %>/public/assets/images',
                        src: ['generated/*']
                    },
                    {
                        expand: true,
                        dest: '<%= yeoman.dist %>',
                        src: [
                            'package.json',
                            'server/**/*'
                        ]
                    }
                ]
            },
            styles: {
                expand: true,
                cwd: '<%= yeoman.client %>',
                dest: '.tmp/',
                src: ['{app,components}/**/*.css']
            }
        },

        // Run some tasks in parallel to speed up the build process
        concurrent: {
            server: [
            ],
            test: [
            ],
            debug: {
                tasks: [
                    'nodemon',
                    'node-inspector'
                ],
                options: {
                    logConcurrentOutput: true
                }
            },
            dist: [
                'imagemin',
                'svgmin'
            ]
        },

        // Test settings
        karma: {
            unit: {
                configFile: 'karma.conf.js',
                singleRun: true
            }
        },

        mochaTest: {
            options: {
                reporter: 'spec'
            },
            src: ['server/**/*.spec.js']
        },

        protractor: {
            options: {
                configFile: 'protractor.conf.js'
            },
            chrome: {
                options: {
                    args: {
                        browser: 'chrome'
                    }
                }
            }
        },

        env: {
            test: {
                NODE_ENV: 'test'
            },
            prod: {
                NODE_ENV: 'production'
            },
            all: localConfig
        },

        injector: {
            options: {

            },
            // Inject application script files into index.html (doesn't include bower)
            scripts: {
                options: {
                    transform: function (filePath) {
                        filePath = filePath.replace('/client/', '');
                        filePath = filePath.replace('/.tmp/', '');
                        return '<script src="' + filePath + '"></script>';
                    },
                    starttag: '<!-- injector:js -->',
                    endtag: '<!-- endinjector -->'
                },
                files: {
                    '<%= yeoman.client %>/index.html': [
                        ['{.tmp,<%= yeoman.client %>}/{app,components}/**/*.js',
                            '!{.tmp,<%= yeoman.client %>}/app/app.js',
                            '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.spec.js',
                            '!{.tmp,<%= yeoman.client %>}/{app,components}/**/*.mock.js']
                    ]
                }
            },

            // Inject component css into index.html
            css: {
                options: {
                    transform: function (filePath) {
                        filePath = filePath.replace('/client/', '');
                        filePath = filePath.replace('/.tmp/', '');
                        return '<link rel="stylesheet" href="' + filePath + '">';
                    },
                    starttag: '<!-- injector:css -->',
                    endtag: '<!-- endinjector -->'
                },
                files: {
                    '<%= yeoman.client %>/index.html': [
                        '<%= yeoman.client %>/{app,components}/**/*.css'
                    ]
                }
            }
        }
    });

    // Used for delaying livereload until after server has restarted
    grunt.registerTask('wait', function () {
        grunt.log.ok('Waiting for server reload...');

        var done = this.async();

        setTimeout(function () {
            grunt.log.writeln('Done waiting!');
            done();
        }, 1500);
    });

    grunt.registerTask('express-keepalive', 'Keep grunt running', function () {
        this.async();
    });

    grunt.registerTask('serve', function (target) {
        if (target === 'dist') {
            return grunt.task.run(['build', 'env:all', 'env:prod', 'express:prod', 'wait', 'open', 'express-keepalive']);
        }

        if (target === 'debug') {
            return grunt.task.run([
                'clean:server',
                'env:all',
                'concurrent:server',
                'injector',
                'bowerInstall',
                'autoprefixer',
                'concurrent:debug'
            ]);
        }

        grunt.task.run([
            'clean:server',
            'env:all',
            'concurrent:server',
            'injector',
            'bowerInstall',
            'autoprefixer',
            'express:dev',
            'wait',
            'open',
            'watch'
        ]);
    });

    grunt.registerTask('server', function () {
        grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
        grunt.task.run(['serve']);
    });

    grunt.registerTask('test', function (target) {
        if (target === 'server') {
            return grunt.task.run([
                'env:all',
                'env:test',
                'mochaTest'
            ]);
        }

        else if (target === 'client') {
            return grunt.task.run([
                'clean:server',
                'env:all',
                'concurrent:test',
                'injector',
                'autoprefixer',
                'karma'
            ]);
        }

        else if (target === 'e2e') {
            return grunt.task.run([
                'clean:server',
                'env:all',
                'env:test',
                'concurrent:test',
                'injector',
                'bowerInstall',
                'autoprefixer',
                'express:dev',
                'protractor'
            ]);
        }

        else grunt.task.run([
                'test:server',
                'test:client'
            ]);
    });

    grunt.registerTask('build', [
        'clean:dist',
        'concurrent:dist',
        'injector',
        'bowerInstall',
        'useminPrepare',
        'autoprefixer',
        'ngtemplates',
        'concat',
        'ngAnnotate',
        'copy:dist',
        'cdnify',
        'cssmin',
        'uglify',
        'rev',
        'usemin'
    ]);

    grunt.registerTask('default', [
        'newer:jshint',
        'test',
        'build'
    ]);
};


================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)

Copyright (c) 2014 Paolo Bernasconi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
[Ionic Theme Editor](http://ionic-theme-editor.herokuapp.com/)
==================

[![preview](https://github.com/pbernasconi/ionic-theme-editor/blob/master/Ionic-Theme-Editor.png)](http://ionic-theme-editor.herokuapp.com/)


## Website

[http://ionic-theme-editor.herokuapp.com/](http://ionic-theme-editor.herokuapp.com/)

## About

The Ionic Theme Editor is a simple live-editor for the [Ionic Framework](ionicframework.com). You can visually customize the primary Ionic variables, view your live changes immediately in several previews, and download a compiled css file with your edits.

## Contributing

Currently the Ionic Theme Editor is hosted in a heroku app. All changes inbetween each release are made to the github repo. I use grunt to build the files. To get setup:

```
git clone https://github.com/pbernasconi/ionic-theme-editor.git
cd ionic-theme-editor
npm install
bower install
grunt build
grunt serve
```

Make a new Pull Request for any changes you think are necessary!


## Authors

#### Paolo Bernasconi

- https://twitter.com/paolobernasconi
- https://github.com/pbernasconi


## LICENSE

Ionic Theme Editor is licensed under the MIT Open Source license. For more information, see the LICENSE file in this repository.


================================================
FILE: bower.json
================================================
{
    "name": "projects",
    "version": "0.0.1",
    "dependencies": {
        "angular": ">=1.2.*",
        "json3": "~3.3.1",
        "es5-shim": "~3.0.1",
        "jquery": "~1.11.0",
        "bootstrap": "~3.1.1",
        "angular-resource": ">=1.2.*",
        "angular-cookies": ">=1.2.*",
        "angular-sanitize": ">=1.2.*",
        "angular-bootstrap": "~0.11.0",
        "font-awesome": ">=4.1.0",
        "lodash": "~2.4.1",
        "angular-ui-router": "~0.2.10",
        "angular-spectrum-colorpicker": "~1.2.0",
        "ionicons": "~1.5.2",
        "ngDialog": "~0.3.0"
    },
    "devDependencies": {
        "angular-mocks": ">=1.2.*",
        "angular-scenario": ">=1.2.*",
        "angular-spectrum-colorpicker": "~1.2.0"
    }
}


================================================
FILE: client/.htaccess
================================================
# Apache Configuration File

# (!) Using `.htaccess` files slows down Apache, therefore, if you have access
# to the main server config file (usually called `httpd.conf`), you should add
# this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html.

# ##############################################################################
# # CROSS-ORIGIN RESOURCE SHARING (CORS)                                       #
# ##############################################################################

# ------------------------------------------------------------------------------
# | Cross-domain AJAX requests                                                 |
# ------------------------------------------------------------------------------

# Enable cross-origin AJAX requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/

# <IfModule mod_headers.c>
#    Header set Access-Control-Allow-Origin "*"
# </IfModule>

# ------------------------------------------------------------------------------
# | CORS-enabled images                                                        |
# ------------------------------------------------------------------------------

# Send the CORS header for images when browsers request it.
# https://developer.mozilla.org/en/CORS_Enabled_Image
# http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
# http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(gif|ico|jpe?g|png|svg|svgz|webp)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
    </IfModule>
</IfModule>

# ------------------------------------------------------------------------------
# | Web fonts access                                                           |
# ------------------------------------------------------------------------------

# Allow access from all domains for web fonts

<IfModule mod_headers.c>
    <FilesMatch "\.(eot|font.css|otf|ttc|ttf|woff)$">
        Header set Access-Control-Allow-Origin "*"
    </FilesMatch>
</IfModule>


# ##############################################################################
# # ERRORS                                                                     #
# ##############################################################################

# ------------------------------------------------------------------------------
# | 404 error prevention for non-existing redirected folders                   |
# ------------------------------------------------------------------------------

# Prevent Apache from returning a 404 error for a rewrite if a directory
# with the same name does not exist.
# http://httpd.apache.org/docs/current/content-negotiation.html#multiviews
# http://www.webmasterworld.com/apache/3808792.htm

Options -MultiViews

# ------------------------------------------------------------------------------
# | Custom error messages / pages                                              |
# ------------------------------------------------------------------------------

# You can customize what Apache returns to the client in case of an error (see
# http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.:

ErrorDocument 404 /404.html


# ##############################################################################
# # INTERNET EXPLORER                                                          #
# ##############################################################################

# ------------------------------------------------------------------------------
# | Better website experience                                                  |
# ------------------------------------------------------------------------------

# Force IE to render pages in the highest available mode in the various
# cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf.

<IfModule mod_headers.c>
    Header set X-UA-Compatible "IE=edge"
    # `mod_headers` can't match based on the content-type, however, we only
    # want to send this header for HTML pages and not for the other resources
    <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
        Header unset X-UA-Compatible
    </FilesMatch>
</IfModule>

# ------------------------------------------------------------------------------
# | Cookie setting from iframes                                                |
# ------------------------------------------------------------------------------

# Allow cookies to be set from iframes in IE.

# <IfModule mod_headers.c>
#   Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
# </IfModule>

# ------------------------------------------------------------------------------
# | Screen flicker                                                             |
# ------------------------------------------------------------------------------

# Stop screen flicker in IE on CSS rollovers (this only works in
# combination with the `ExpiresByType` directives for images from below).

# BrowserMatch "MSIE" brokenvary=1
# BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
# BrowserMatch "Opera" !brokenvary
# SetEnvIf brokenvary 1 force-no-vary


# ##############################################################################
# # MIME TYPES AND ENCODING                                                    #
# ##############################################################################

# ------------------------------------------------------------------------------
# | Proper MIME types for all files                                            |
# ------------------------------------------------------------------------------

<IfModule mod_mime.c>

  # Audio
    AddType audio/mp4                                   m4a f4a f4b
    AddType audio/ogg                                   oga ogg

  # JavaScript
    # Normalize to standard type (it's sniffed in IE anyways):
    # http://tools.ietf.org/html/rfc4329#section-7.2
    AddType application/javascript                      js jsonp
    AddType application/json                            json

  # Video
    AddType video/mp4                                   mp4 m4v f4v f4p
    AddType video/ogg                                   ogv
    AddType video/webm                                  webm
    AddType video/x-flv                                 flv

  # Web fonts
    AddType application/font-woff                       woff
    AddType application/vnd.ms-fontobject               eot

    # Browsers usually ignore the font MIME types and sniff the content,
    # however, Chrome shows a warning if other MIME types are used for the
    # following fonts.
    AddType application/x-font-ttf                      ttc ttf
    AddType font/opentype                               otf

    # Make SVGZ fonts work on iPad:
    # https://twitter.com/FontSquirrel/status/14855840545
    AddType     image/svg+xml                           svg svgz
    AddEncoding gzip                                    svgz

  # Other
    AddType application/octet-stream                    safariextz
    AddType application/x-chrome-extension              crx
    AddType application/x-opera-extension               oex
    AddType application/x-shockwave-flash               swf
    AddType application/x-web-app-manifest+json         webapp
    AddType application/x-xpinstall                     xpi
    AddType application/xml                             atom rdf rss xml
    AddType image/webp                                  webp
    AddType image/x-icon                                ico
    AddType text/cache-manifest                         appcache manifest
    AddType text/vtt                                    vtt
    AddType text/x-component                            htc
    AddType text/x-vcard                                vcf

</IfModule>

# ------------------------------------------------------------------------------
# | UTF-8 encoding                                                             |
# ------------------------------------------------------------------------------

# Use UTF-8 encoding for anything served as `text/html` or `text/plain`.
AddDefaultCharset utf-8

# Force UTF-8 for certain file formats.
<IfModule mod_mime.c>
    AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml
</IfModule>


# ##############################################################################
# # URL REWRITES                                                               #
# ##############################################################################

# ------------------------------------------------------------------------------
# | Rewrite engine                                                             |
# ------------------------------------------------------------------------------

# Turning on the rewrite engine and enabling the `FollowSymLinks` option is
# necessary for the following directives to work.

# If your web host doesn't allow the `FollowSymlinks` option, you may need to
# comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the
# performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks

# Also, some cloud hosting services require `RewriteBase` to be set:
# http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
  # Options +SymLinksIfOwnerMatch
    RewriteEngine On
  # RewriteBase /
</IfModule>

# ------------------------------------------------------------------------------
# | Suppressing / Forcing the "www." at the beginning of URLs                  |
# ------------------------------------------------------------------------------

# The same content should never be available under two different URLs especially
# not with and without "www." at the beginning. This can cause SEO problems
# (duplicate content), therefore, you should choose one of the alternatives and
# redirect the other one.

# By default option 1 (no "www.") is activated:
# http://no-www.org/faq.php?q=class_b

# If you'd prefer to use option 2, just comment out all the lines from option 1
# and uncomment the ones from option 2.

# IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME!

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Option 1: rewrite www.example.com → example.com

<IfModule mod_rewrite.c>
    RewriteCond %{HTTPS} !=on
    RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
    RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
</IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Option 2: rewrite example.com → www.example.com

# Be aware that the following might not be a good idea if you use "real"
# subdomains for certain parts of your website.

# <IfModule mod_rewrite.c>
#    RewriteCond %{HTTPS} !=on
#    RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
#    RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# </IfModule>


# ##############################################################################
# # SECURITY                                                                   #
# ##############################################################################

# ------------------------------------------------------------------------------
# | Content Security Policy (CSP)                                              |
# ------------------------------------------------------------------------------

# You can mitigate the risk of cross-site scripting and other content-injection
# attacks by setting a Content Security Policy which whitelists trusted sources
# of content for your site.

# The example header below allows ONLY scripts that are loaded from the current
# site's origin (no inline scripts, no CDN, etc). This almost certainly won't
# work as-is for your site!

# To get all the details you'll need to craft a reasonable policy for your site,
# read: http://html5rocks.com/en/tutorials/security/content-security-policy (or
# see the specification: http://w3.org/TR/CSP).

# <IfModule mod_headers.c>
#    Header set Content-Security-Policy "script-src 'self'; object-src 'self'"
#    <FilesMatch "\.(appcache|crx|css|eot|gif|htc|ico|jpe?g|js|m4a|m4v|manifest|mp4|oex|oga|ogg|ogv|otf|pdf|png|safariextz|svg|svgz|ttf|vcf|webapp|webm|webp|woff|xml|xpi)$">
#        Header unset Content-Security-Policy
#    </FilesMatch>
# </IfModule>

# ------------------------------------------------------------------------------
# | File access                                                                |
# ------------------------------------------------------------------------------

# Block access to directories without a default document.
# Usually you should leave this uncommented because you shouldn't allow anyone
# to surf through every directory on your server (which may includes rather
# private places like the CMS's directories).

<IfModule mod_autoindex.c>
    Options -Indexes
</IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Block access to hidden files and directories.
# This includes directories used by version control systems such as Git and SVN.

<IfModule mod_rewrite.c>
    RewriteCond %{SCRIPT_FILENAME} -d [OR]
    RewriteCond %{SCRIPT_FILENAME} -f
    RewriteRule "(^|/)\." - [F]
</IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Block access to backup and source files.
# These files may be left by some text editors and can pose a great security
# danger when anyone has access to them.

<FilesMatch "(^#.*#|\.(bak|config|dist|fla|inc|ini|log|psd|sh|sql|sw[op])|~)$">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

# ------------------------------------------------------------------------------
# | Secure Sockets Layer (SSL)                                                 |
# ------------------------------------------------------------------------------

# Rewrite secure requests properly to prevent SSL certificate warnings, e.g.:
# prevent `https://www.example.com` when your certificate only allows
# `https://secure.example.com`.

# <IfModule mod_rewrite.c>
#    RewriteCond %{SERVER_PORT} !^443
#    RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L]
# </IfModule>

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

# Force client-side SSL redirection.

# If a user types "example.com" in his browser, the above rule will redirect him
# to the secure version of the site. That still leaves a window of opportunity
# (the initial HTTP connection) for an attacker to downgrade or redirect the
# request. The following header ensures that browser will ONLY connect to your
# server via HTTPS, regardless of what the users type in the address bar.
# http://www.html5rocks.com/en/tutorials/security/transport-layer-security/

# <IfModule mod_headers.c>
#    Header set Strict-Transport-Security max-age=16070400;
# </IfModule>

# ------------------------------------------------------------------------------
# | Server software information                                                |
# ------------------------------------------------------------------------------

# Avoid displaying the exact Apache version number, the description of the
# generic OS-type and the information about Apache's compiled-in modules.

# ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`!

# ServerTokens Prod


# ##############################################################################
# # WEB PERFORMANCE                                                            #
# ##############################################################################

# ------------------------------------------------------------------------------
# | Compression                                                                |
# ------------------------------------------------------------------------------

<IfModule mod_deflate.c>

    # Force compression for mangled headers.
    # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping
    <IfModule mod_setenvif.c>
        <IfModule mod_headers.c>
            SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
            RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
        </IfModule>
    </IfModule>

    # Compress all output labeled with one of the following MIME-types
    # (for Apache versions below 2.3.7, you don't need to enable `mod_filter`
    #  and can remove the `<IfModule mod_filter.c>` and `</IfModule>` lines
    #  as `AddOutputFilterByType` is still in the core directives).
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE application/atom+xml \
                                      application/javascript \
                                      application/json \
                                      application/rss+xml \
                                      application/vnd.ms-fontobject \
                                      application/x-font-ttf \
                                      application/x-web-app-manifest+json \
                                      application/xhtml+xml \
                                      application/xml \
                                      font/opentype \
                                      image/svg+xml \
                                      image/x-icon \
                                      text/css \
                                      text/html \
                                      text/plain \
                                      text/x-component \
                                      text/xml
    </IfModule>

</IfModule>

# ------------------------------------------------------------------------------
# | Content transformations                                                    |
# ------------------------------------------------------------------------------

# Prevent some of the mobile network providers from modifying the content of
# your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5.

# <IfModule mod_headers.c>
#    Header set Cache-Control "no-transform"
# </IfModule>

# ------------------------------------------------------------------------------
# | ETag removal                                                               |
# ------------------------------------------------------------------------------

# Since we're sending far-future expires headers (see below), ETags can
# be removed: http://developer.yahoo.com/performance/rules.html#etags.

# `FileETag None` is not enough for every server.
<IfModule mod_headers.c>
    Header unset ETag
</IfModule>

FileETag None

# ------------------------------------------------------------------------------
# | Expires headers (for better cache control)                                 |
# ------------------------------------------------------------------------------

# The following expires headers are set pretty far in the future. If you don't
# control versioning with filename-based cache busting, consider lowering the
# cache time for resources like CSS and JS to something like 1 week.

<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

  # CSS
    ExpiresByType text/css                              "access plus 1 year"

  # Data interchange
    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"

  # Favicon (cannot be renamed!)
    ExpiresByType image/x-icon                          "access plus 1 week"

  # HTML components (HTCs)
    ExpiresByType text/x-component                      "access plus 1 month"

  # HTML
    ExpiresByType text/html                             "access plus 0 seconds"

  # JavaScript
    ExpiresByType application/javascript                "access plus 1 year"

  # Manifest files
    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"

  # Media
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"

  # Web feeds
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"

  # Web fonts
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType application/x-font-ttf                "access plus 1 month"
    ExpiresByType font/opentype                         "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"

</IfModule>

# ------------------------------------------------------------------------------
# | Filename-based cache busting                                               |
# ------------------------------------------------------------------------------

# If you're not using a build process to manage your filename version revving,
# you might want to consider enabling the following directives to route all
# requests such as `/css/style.12345.css` to `/css/style.css`.

# To understand why this is important and a better idea than `*.css?v231`, read:
# http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring

# <IfModule mod_rewrite.c>
#    RewriteCond %{REQUEST_FILENAME} !-f
#    RewriteCond %{REQUEST_FILENAME} !-d
#    RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L]
# </IfModule>

# ------------------------------------------------------------------------------
# | File concatenation                                                         |
# ------------------------------------------------------------------------------

# Allow concatenation from within specific CSS and JS files, e.g.:
# Inside of `script.combined.js` you could have
#   <!--#include file="libs/jquery.js" -->
#   <!--#include file="plugins/jquery.idletimer.js" -->
# and they would be included into this single file.

# <IfModule mod_include.c>
#    <FilesMatch "\.combined\.js$">
#        Options +Includes
#        AddOutputFilterByType INCLUDES application/javascript application/json
#        SetOutputFilter INCLUDES
#    </FilesMatch>
#    <FilesMatch "\.combined\.css$">
#        Options +Includes
#        AddOutputFilterByType INCLUDES text/css
#        SetOutputFilter INCLUDES
#    </FilesMatch>
# </IfModule>

# ------------------------------------------------------------------------------
# | Persistent connections                                                     |
# ------------------------------------------------------------------------------

# Allow multiple requests to be sent over the same TCP connection:
# http://httpd.apache.org/docs/current/en/mod/core.html#keepalive.

# Enable if you serve a lot of static content but, be aware of the
# possible disadvantages!

# <IfModule mod_headers.c>
#    Header set Connection Keep-Alive
# </IfModule>


================================================
FILE: client/.jshintrc
================================================
{
  "node": true,
  "browser": true,
  "esnext": true,
  "bitwise": true,
  "camelcase": true,
  "curly": true,
  "eqeqeq": true,
  "immed": true,
  "indent": 2,
  "latedef": true,
  "newcap": true,
  "noarg": true,
  "quotmark": "single",
  "regexp": true,
  "undef": true,
  "unused": true,
  "strict": true,
  "trailing": true,
  "smarttabs": true,
  "globals": {
    "jQuery": true,
    "angular": true,
    "console": true,
    "$": true,
    "_": true,
    "moment": true,
    "describe": true,
    "beforeEach": true,
    "module": true,
    "inject": true,
    "it": true,
    "expect": true,
    "browser": true,
    "element": true,
    "by": true
  }
}


================================================
FILE: client/app/app.css
================================================
/**************************************************
 * Bootstrap Fonts
 */

@font-face {
    font-family: 'Glyphicons Halflings';
    src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot');
    src: url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
    url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff') format('woff'),
    url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf') format('truetype'),
    url('../bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}

/**************************************************
 *Font Awesome Fonts
 */

@font-face {
    font-family: 'FontAwesome';
    src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?v=4.1.0');
    src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),
    url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),
    url('../bower_components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),
    url('../bower_components/font-awesome/fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
    font-weight: 200;
    font-style: normal;
}

/**************************************************
 * App-wide Styles
 */

.browsehappy {
    margin: 0.2em 0;
    background: #ccc;
    color: #000;
    padding: 0.2em 0;
}

html, body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    height: 100%;
    overflow: hidden;
    color: #575859;
}

ul {
    list-style: none;
}

.row {
    margin: 0 0 30px;
}

/***************************************************
 * SIDE PANEL
 */

.side-panel {
    position: absolute;
    left: 0;
    width: 325px;
    height: 100%;
}

.side-panel section::-webkit-scrollbar {
    display: none;
}

/**
 * HEADER
 */

.side-panel > header {
    display: inline-block;
    width: 100%;
    height: 55px;
    line-height: 55px;
    color: white;
    background-color: #6795F5;
    z-index: 10;
}

.side-panel > header .logo {
    float: left;
    padding-left: 10px;
    height: 45px;
    padding-top: 8px;
    vertical-align: middle;
}

.side-panel > header .logo-title {
    float: left;
    margin-left: 15px;
    font-weight: 200;
    font-size: 15px;
    letter-spacing: 2px;
    border-top: 2px solid transparent;
    text-transform: uppercase;
}

/**
 * BUTTON ROW
 */

.side-panel .sub-header {
    background: #ffFFFF;
    height: 50px;
    line-height: 50px;
    text-align: center;
    border-right: solid #ECF0F6 1px;
    margin-top: -5px;
    width: 100%;
    border-bottom: 1px solid #ECF0F6;
    z-index: 10;
    box-shadow: -2px 4px 8px rgba(250, 250, 250, 0.7);
    -webkit-box-shadow: -2px 4px 8px rgba(250, 250, 250, 0.7);
    -moz-box-shadow: -2px 4px 8px rgba(250, 250, 250, 0.7);
}

.sub-header .button-row {
    display: inline-block;
    margin: 0;
}

.sub-header .button-row a {
    color: #575859;
    display: inline-block;
    border: 1px solid #575859;
    text-decoration: none;
    height: 30px;
    line-height: 30px;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-weight: 200;
    width: 130px;
    font-size: 12px;
    cursor: pointer;
    -webkit-transition: 200ms;
    -moz-transition: 200ms;
    -ms-transition: 200ms;
    -o-transition: 200ms;
    transition: 200ms;
}

.sub-header .button-row a:first-child {
    border-radius: 5px 0 0 5px;
    border-right: none;
}

.sub-header .button-row a:last-child {
    margin-left: -5px;
    border-radius: 0 5px 5px 0;
}

.sub-header .button-row a.selected {
    background-color: #575859;
    color: #ffFFFF;
    -webkit-transition: 200ms;
    -moz-transition: 200ms;
    -ms-transition: 200ms;
    -o-transition: 200ms;
    transition: 200ms;
}

/**
 * SECTION
 */

.side-panel section {
    position: absolute;
    height: 93%;
    width: 100%;
    overflow: auto;
    border-right: solid #ECF0F6 1px;
}

.side-panel .side-section-download {
    padding: 20px;
}

.side-panel .btn-download {
    width: 100%;
    background-color: #6795F5;
    color: #fFF;
    font-size: 15px;
    letter-spacing: 1px;
    font-weight: 200;
    text-transform: uppercase;
    border: 1px solid #6795F5;
    -webkit-transition: all 0.20s ease-in-out;
    -moz-transition: all 0.20s ease-in-out;
    -ms-transition: all 0.20s ease-in-out;
    -o-transition: all 0.20s ease-in-out;
}

.side-panel .btn-download:hover, .side-panel .btn-download:focus {
    outline: none;
    border: 1px solid #6795F5;
    color: #6795F5;
    background-color: #FFFFFF;
    -webkit-transition: all 0.20s ease-in-out;
    -moz-transition: all 0.20s ease-in-out;
    -ms-transition: all 0.20s ease-in-out;
    -o-transition: all 0.20s ease-in-out;
}

/* side-section - headers */

.side-section .side-section-header {
    display: inline-block;
    background-color: #F3F5F7;
    width: 100%;
    height: 40px;
    line-height: 40px;
    letter-spacing: 2px;
    font-size: 13px;
    padding: 0 10px;
    text-transform: uppercase;
}

.side-section .btn-revert {
    font-size: 1.1em;
    position: relative;
    float: right;
    margin-right: 8px;
    display: inline-block;
    background-color: transparent;
    padding-top: 5px;
    border: none;
    outline: none;
}

.side-section .btn-revert:hover, .side-section .btn-revert:active {
    color: #ff4f5a;
}

/* side-section - colors */

.side-section ul {
    list-style: none;
    padding-left: 20px;
}

.side-section li {
    padding: 10px 0;
    border-bottom: 1px solid #ECF0F6;
}

.side-section li:last-child {
    border-bottom: none;
    margin-bottom: 15px;
}

.side-section .section-color-preview {
    float: right;
    color: #93969F;
    margin-right: 10px;
}

.side-section-input {
    float: right;
    text-align: right;
    width: 70px;
    margin-right: 20px;
    border: 1px solid #ECF0F6;
    border-radius: 2px;
    padding-right: 5px;
    padding-top: 2px;
    padding-bottom: 2px;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.side-section-input:focus, .side-section-input:hover {
    border: 1px solid #6795F5;
    outline: none;
}

.side-section-select {
    float: right;
    text-align: right;
    width: 120px;
    margin-right: 20px;
    border: 1px solid #ECF0F6;
    border-radius: 2px;
    padding-right: 5px;
    padding-top: 3px;
    padding-bottom: 2px;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.side-section-select:focus, .side-section-select:hover {
    border: 1px solid #6795F5;
    outline: none;
}

/* side-section - footer */

.side-section-footer {
    position: absolute;
    background-color: #2B3442;
    padding-top: 4px;
    text-align: center;
    width: 100%;
    color: white;
    height: 50px;
}

.side-section-footer h4 {
    font-weight: lighter !important;
    font-size: 14px;
    letter-spacing: 1px;
}

/****************************************************
 * COLOR PICKER
 */

.sp-container {
    background-color: #EFF1F5;
    border: 1px solid #eceef0;
    border-radius: 2px;
}

.sp-picker-container {
    border: none;
}

.sp-color {
    border: none;
    border-radius: 2px;
}

.sp-hue {
    border: none;
    border-radius: 2px;
}

.sp-alpha-inner {
    border: none;
}

.sp-slider {
    border-color: #575859;
    border-radius: 1px;
    opacity: 1;
}

.sp-alpha-handle {
    border-color: #575859;
    border-radius: 1px;
    opacity: 1;
}

.sp-replacer {
    float: right;
    margin-right: 20px;
    background-color: transparent;
    padding: 0;
    border: none;
    width: 23px;
    height: 23px;
}

.sp-replacer .sp-preview {
    margin: 0;
    border: 1px solid #ECF0F6;
    width: 23px;
    height: 23px;
}

.sp-dd {
    display: none;
}

input.sp-input {
    background-color: #ffFFFF;
    border: 1px solid #6795F5;
    border-radius: 2px;
    padding: 5px;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

input.sp-input:focus, input.sp-input:hover {
    outline: none;
    border: 1px solid #6795F5;
}

.sp-cancel {
    background: #ff4843;
    text-shadow: none;
    color: #fFF !important;
    border-radius: 3px;
    padding: 4px;
    letter-spacing: 1px;
    font-size: 11px;
    font-weight: 200;
    text-transform: uppercase;
    border: 1px solid #ff4843;
}

.sp-cancel:hover {
    background: #FFF;
    text-decoration: none;
    color: #ff4843 !important;
    border: 1px solid #ff4843;

}

.sp-button-container > button {
    background: #6795F5;
    text-shadow: none;
    color: #fFF;
    letter-spacing: 1px;
    font-size: 11px;
    font-weight: 200;
    text-transform: uppercase;
    border: 1px solid #6795F5;
}

.sp-button-container > button:hover {
    border: 1px solid #6795F5;
    background: #FFF !important;
    color: #6795F5;
    text-shadow: none;
}

/****************************************************
 * MAIN PANEL
 */

.main-panel {
    position: absolute;
    top: 0;
    left: 325px;
    bottom: 0;
    right: 0;
    height: 100%;
}

/* Main - tabs */

.main-panel-tabs {
    list-style: none;
    height: 55px;
    line-height: 55px;
    color: white;
    background-color: #6795F5;
    font-weight: lighter;
    letter-spacing: 1px;
    z-index: 10;
}

.main-panel-tabs > li {
    font-size: 18px;
    list-style: none;
    box-sizing: border-box;
    margin-right: 20px;
    display: inline-block;
    border-top: 2px solid transparent;
    cursor: pointer;
}

.main-panel-tabs > li:hover {
    border-top: 2px solid white;
    cursor: pointer;
}

.main-panel-tabs > li.active {
    border-top: 2px solid white;
    cursor: pointer;
}

.main-panel-tabs .tabs-left {
    float: right;
}

.main-panel-tabs .tabs-left > .btn-login {
    background-color: transparent;
    border: none;
    color: white;
    text-decoration: none;
}

.main-panel-tabs .tabs-left > .btn-login:hover,
.main-panel-tabs .tabs-left > .btn-login:focus {
    border: none;
    outline: none;
}

.main-panel .main-panel-view {
    position: absolute;
    top: 55px;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: auto;
    width: 100%;
    overflow-x: hidden;
}

.main-panel-view .preview-card {
    height: 150px;
    border-top: 3px solid #93969F;
    box-shadow: 0 1px 3px #e0e4ea;
    margin: 0 8px 34px 8px;
    list-style: none;
    display: inline-block;
    width: 300px;
}

.preview-card .card-header {
    background-color: #ECF0F6;
    padding: 5px;
    font-size: 15px;
    font-weight: bold;
}

.preview-card .card-content {
    padding: 5px;
}

/****************************************************
 * DEVICE PREVIEW
 */

.device-header {
    text-align: center;
}

.device-bg {
    background-image: url("../assets/images/device.png");
    background-size: 243px 528px;
    height: 528px;
    width: 243px;
    margin-left: auto;
    margin-right: auto;
}

.device-screen {
    position: relative;
    top: 69px;
    left: 8px;
    z-index: 0;
    width: 341px;
    height: 576px;
    border: 2px solid #22272d;
    background-color: white;
    -ms-zoom: 0.665;
    -moz-transform: scale(0.665);
    -moz-transform-origin: 0 0;
    -o-transform: scale(0.665);
    -o-transform-origin: 0 0;
    -webkit-transform: scale(0.665);
    -webkit-transform-origin: 0 0;
}

/****************************************************
 * SPINNER
 */

.spinner-background {
    width: 100%;
    height: 100%;
    position: absolute;
    background: rgba(255, 255, 255, 0.33);
    background: -moz-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 0.33) 0%, rgba(255, 255, 255, 0.32) 6%, rgba(75, 140, 244, 0.17) 100%);
    background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, rgba(255, 255, 255, 0.33)), color-stop(6%, rgba(255, 255, 255, 0.32)), color-stop(100%, rgba(75, 140, 244, 0.17)));
    background: -webkit-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 0.33) 0%, rgba(255, 255, 255, 0.32) 6%, rgba(75, 140, 244, 0.17) 100%);
    background: -o-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 0.33) 0%, rgba(255, 255, 255, 0.32) 6%, rgba(75, 140, 244, 0.17) 100%);
    background: -ms-radial-gradient(center, ellipse cover, rgba(255, 255, 255, 0.33) 0%, rgba(255, 255, 255, 0.32) 6%, rgba(75, 140, 244, 0.17) 100%);
    background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.33) 0%, rgba(255, 255, 255, 0.32) 6%, rgba(75, 140, 244, 0.17) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#4b8cf4', GradientType=1);
}

.spinner {
    width: 40px;
    height: 40px;
    position: relative;
    padding: 10px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 300px;
}

.double-bounce1, .double-bounce2 {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-color: #6795F5;
    opacity: 0.6;
    position: absolute;
    top: 0;
    left: 0;
    -webkit-animation: bounce 2.0s infinite ease-in-out;
    animation: bounce 2.0s infinite ease-in-out;
}

.double-bounce2 {
    -webkit-animation-delay: -1.0s;
    animation-delay: -1.0s;
}

@-webkit-keyframes bounce {
    0%, 100% {
        -webkit-transform: scale(0.0)
    }
    50% {
        -webkit-transform: scale(1.0)
    }
}

@keyframes bounce {
    0%, 100% {
        transform: scale(0.0);
        -webkit-transform: scale(0.0);
    }
    50% {
        transform: scale(1.0);
        -webkit-transform: scale(1.0);
    }
}

/****************************************************
 * DOWNLOAD MODAL
 */

.ngdialog-content {
    background: #ffffff !important;
    border-radius: 1px !important;
    border: 3px solid #6795F5;
    color: #575859 !important;
    margin: 0 auto;
    max-width: 100%;
    padding: 1em;
    position: relative;
    width: 550px !important;
}

.imodal {
    width: 100%;
}

.imodal-title {
    text-align: center;
    padding-bottom: 20px;
    border-bottom: 1px solid #ECF0F6;
    margin-bottom: 20px;
}

.imodal-content {
    padding: 20px;
    width: 70%;
    margin-right: auto;
    margin-left: auto;
    margin-bottom: 30px;
}

.imodal-content .input-group {
    padding: 10px;
}

.imodal-content .input-group:first-child {
    border-bottom: 1px solid #ECF0F6;
}

.imodal-content label {
    margin-right: 15px;
}

.imodal-content input {
    border: 1px solid #ECF0F6;
    border-radius: 2px;
    padding: 2px 8px;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.imodal-content input:focus, .imodal-content input:hover {
    border: 1px solid #6795F5;
    outline: none;
}

.imodal-buttons {
    width: 100%;
    margin: 0 auto;
    display: inline-block;
}

.imodal .btn-modal {
    width: 49%;
    margin-right: auto;
    margin-left: auto;
}

.imodal .btn-modal-cancel {
    margin-left: 3px;
    background: white;
    border: 1px solid #ff4843;
    color: #ff4843;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.imodal .btn-modal-cancel:hover, .imodal .btn-modal-cancel:focus {
    outline: none;
    border: 1px solid #ff4843;
    color: white;
    background-color: #ff4843;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.imodal .btn-modal-download {
    background: #6795F5;
    color: #fFF;
    border: 1px solid #6795F5;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.imodal .btn-modal-download:hover, .imodal .btn-modal-download:focus {
    outline: none;
    border: 1px solid #6795F5;
    color: #6795F5;
    background-color: #FFFFFF;
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
}

.ngdialog.ngdialog-theme-default .ngdialog-close:before {
    background: #6795F5;
    border-radius: 0 !important;
    color: white;
    content: '\00D7';
    right: 0;
    top: -1px;
}

.ngdialog-close:hover:before {
    color: #575859 !important;
}

.icon-lg {
    font-size: 1.75em;
    line-height: 1;
}


================================================
FILE: client/app/app.js
================================================
'use strict';

angular.module('projectsApp', [
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ui.router',
    'ui.bootstrap',
    'angularSpectrumColorpicker',
    'ngDialog'
])
    .config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
        $urlRouterProvider
            .otherwise('/');

        $locationProvider.html5Mode(true);
    });


================================================
FILE: client/app/compiler/compiler.service.js
================================================
'use strict';

angular.module('projectsApp')
    .service('Compiler', function ($http) {

        return {
            get: function (data) {
                return $http.get('/api/compile/');
            },
            post: function (data, cssType) {
                return $http.post('/api/compile/' + cssType, data);
            }
        }

    });


================================================
FILE: client/app/compiler/compiler.service.spec.js
================================================
'use strict';

describe('Service: compiler', function () {

  // load the service's module
  beforeEach(module('projectsApp'));

  // instantiate service
  var compiler;
  beforeEach(inject(function (_compiler_) {
    compiler = _compiler_;
  }));

  it('should do something', function () {
    expect(!!compiler).toBe(true);
  });

});


================================================
FILE: client/app/main/main.controller.js
================================================
"use strict";

angular.module("projectsApp")

    .controller("MainCtrl", function ($scope, $timeout, ngDialog) {

        // initial variables
        $scope.activeTab = 1;
        $scope.selectedButtonBar = 0;
        $scope.iframeLoaded = false;

        // Global variables
        $scope.globals = [
            {name: "Background Color", variable: "$base-background-color", value: "#fff", type: "color"},
            {name: "Text Color", variable: "$base-color", value: "#000", type: "color"},
            {name: "Link Color", variable: "$link-color", value: "#4a87ee", type: "color"}
        ];

        // Color variables
        $scope.colors = [
            {name: "light", variable: "$light", value: "#fff", type: "color"},
            {name: "stable", variable: "$stable", value: "#f8f8f8", type: "color"},
            {name: "positive", variable: "$positive", value: "#4a87ee", type: "color"},
            {name: "calm", variable: "$calm", value: "#43cee6", type: "color"},
            {name: "balanced", variable: "$balanced", value: "#66cc33", type: "color"},
            {name: "energized", variable: "$energized", value: "#f0b840", type: "color"},
            {name: "assertive", variable: "$assertive", value: "#ef4e3a", type: "color"},
            {name: "royal", variable: "$royal", value: "#8a6de9", type: "color"},
            {name: "dark", variable: "$dark", value: "#444", type: "color"}
        ];

        // Font variables
        $scope.fonts = [
            {name: "Font Family", variable: "$font-family-base", value: "$font-family-sans-serif", type: "select"},
            {name: "Base - font size", variable: "$font-size-base", value: "14px", type: "pixel"},
            {name: "Large - font size", variable: "$font-size-large", value: "18px", type: "pixel"},
            {name: "Small - font size", variable: "$font-size-small", value: "11px", type: "pixel"}
        ];

        // Padding variables
        $scope.padding = [
            {name: "Content Padding", variable: "$content-padding", value: "10px", type: "pixel"},
            {name: "Base - Vertical", variable: "$padding-base-vertical", value: "6px", type: "pixel"},
            {name: "Base - Horizontal", variable: "$padding-base-horizontal", value: "12px", type: "pixel"},
            {name: "Small - Vertical", variable: "$padding-small-vertical", value: "5px", type: "pixel"},
            {name: "Small - Horizontal", variable: "$padding-small-horizontal", value: "10px", type: "pixel"},
            {name: "Large - Vertical", variable: "$padding-large-vertical", value: "10px", type: "pixel"},
            {name: "Large - Horizontal", variable: "$padding-large-horizontal", value: "16px", type: "pixel"}
        ];

        // collect all data together
        $scope.groupedVars = _.union($scope.globals, $scope.colors, $scope.fonts, $scope.padding);

        // make copies for revert case
        var globalsCopy = angular.copy($scope.globals);
        var colorsCopy = angular.copy($scope.colors);
        var fontsCopy = angular.copy($scope.fonts);
        var paddingCopy = angular.copy($scope.padding);

        // setting the button-bar radio like
        $scope.setButtonBar = function (index) {
            $scope.selectedButtonBar = index;
        };

        // return index of selected button bar
        $scope.isButtonBar = function (index) {
            return index === $scope.selectedButtonBar;
        };


        // revert to original data with switch - case
        $scope.revert = function (list) {
            switch (list) {
                case "globals" :
                    var _gCopy = angular.copy(globalsCopy);
                    _.each($scope.globals, function (item, index) {
                        item.value = _gCopy[index].value;
                    });
                    break;
                case "colors" :
                    var _cCopy = angular.copy(colorsCopy);
                    _.each($scope.colors, function (item, index) {
                        item.value = _cCopy[index].value;
                    });
                    break;
                case "fonts" :
                    var _fCopy = angular.copy(fontsCopy);
                    _.each($scope.fonts, function (item, index) {
                        item.value = _fCopy[index].value;
                    });
                    break;

                case "padding" :
                    var _pCopy = angular.copy(paddingCopy);
                    _.each($scope.padding, function (item, index) {
                        item.value = _pCopy[index].value;
                    });
                    break;
                default :
                    break;
            }
        };

        // set the active tab
        $scope.setActiveTab = function (index) {
            if (index == 1) {
                $scope.iframeLoaded = false;
                $scope.iframeCallback();
            }
            return $scope.activeTab = index;
        };


        // iframe loaded
        $scope.iframeCallback = function () {
            $timeout(function () {
                $scope.iframeLoaded = true;
            }, 1000);
        };

        // open modal with download button
        $scope.prepDownload = function () {
            ngDialog.open({
                template: 'downloadModal',
                data: {sassData: $scope.groupedVars},
                controller: 'DownloadModal',
                scope: $scope
            })
        };
    })


    // Download Controller for modal
    .controller("DownloadModal", function ($scope, ngDialog, Compiler) {

        $scope.filename = "ionic.app.css";
        $scope.cssType = "compressed";

        var data = $scope.groupedVars;
        $scope.modalDownload = function () {
            Compiler.post(data, $scope.cssType)
                .success(function (response) {
                    if (response.success == true) {
                        var id = response.id;
                        console.log(id);

                        var hiddenElement = document.createElement('a'); // create new A element and self click to download
                        hiddenElement.href = '/api/compile/download/' + id + '/' + $scope.filename;
                        hiddenElement.target = '_blank';
                        hiddenElement.download = 'ionic.app.css';
                        hiddenElement.click();
                    }
                })
                .error(function (error) {
                    console.log(error);
                    alert("An error occurred : ", error);
                })
        };

        $scope.modalClose = function () {
            ngDialog.close();
        };
    });


================================================
FILE: client/app/main/main.controller.spec.js
================================================
'use strict';

describe('Controller: MainCtrl', function () {

  // load the controller's module
  beforeEach(module('projectsApp'));

  var MainCtrl,
      scope,
      $httpBackend;

  // Initialize the controller and a mock scope
  beforeEach(inject(function (_$httpBackend_, $controller, $rootScope) {
    $httpBackend = _$httpBackend_;
    $httpBackend.expectGET('/api/things')
      .respond(['HTML5 Boilerplate', 'AngularJS', 'Karma', 'Express']);

    scope = $rootScope.$new();
    MainCtrl = $controller('MainCtrl', {
      $scope: scope
    });
  }));

  it('should attach a list of things to the scope', function () {
    $httpBackend.flush();
    expect(scope.awesomeThings.length).toBe(4);
  });
});


================================================
FILE: client/app/main/main.css
================================================


================================================
FILE: client/app/main/main.html
================================================
<div class="content">

    <div class="side-panel">
        <header>
            <img class="logo" src="../assets/images/tailor-icon-white.png">

            <div class="logo-title">Ionic Tailor</div>
        </header>

        <header class="sub-header" headroom>
            <div class="button-row">
                <a ng-click="setButtonBar(0)" ng-class="{'selected' : isButtonBar(0)}">Customize</a>
                <a ng-class="{'selected' : isButtonBar(1)}">Preset themes</a> <!--  ng-click="setButtonBar(1)" -->
            </div>
        </header>


        <section ng-if="isButtonBar(0)">
            <div class="side-section-download">
                <button class="btn btn-download" ng-click="prepDownload()">Download Theme</button>
            </div>
            <div class="side-section">
                <div class="side-section-header">
                    Globals
                    <button class="btn-revert" ng-click="revert('globals')">
                        <i class="icon icon-lg ion-ios7-refresh-empty"></i>
                    </button>
                </div>
                <ul>
                    <li ng-repeat="item in globals" ng-mouseover="show = true" ng-mouseleave="show = false">
                        {{item.name}}
                        <spectrum-colorpicker ng-if="item.type == 'color'"
                                              ng-model="item.value"
                                              options="{showInput: true, showAlpha: true, clickoutFiresChange: true, showInitial: true}"
                                              format="'hex'"
                                              ng-style="{'background-color': item.value };">
                        </spectrum-colorpicker>
                        <span ng-if="show == true && item.type == 'color'" class="section-color-preview" ng-bind="item.value"></span>
                    </li>
                </ul>
            </div>

            <div class="side-section">
                <div class="side-section-header">
                    Colors
                    <button class="btn-revert" ng-click="revert('colors')">
                        <i class="icon icon-lg ion-ios7-refresh-empty"></i>
                    </button>
                </div>
                <ul>
                    <li ng-repeat="item in colors" ng-mouseover="show = true" ng-mouseleave="show = false">
                        {{item.name}}
                        <spectrum-colorpicker ng-model="item.value"
                                              options="{showInput: true, showAlpha: true, clickoutFiresChange: true, showInitial: true}"
                                              format="'hex'"
                                              ng-style="{'background-color': item.value };">
                        </spectrum-colorpicker>
                        <span ng-if="show == true" class="section-color-preview" ng-bind="item.value"></span>
                    </li>
                </ul>
            </div>

            <div class="side-section">
                <div class="side-section-header">
                    Fonts
                    <button class="btn-revert" ng-click="revert('fonts')">
                        <i class="icon icon-lg ion-ios7-refresh-empty"></i>
                    </button>
                </div>
                <ul>
                    <li ng-repeat="item in fonts">
                        {{item.name}}
                        <input type="text" class="side-section-input" ng-if="item.type == 'pixel'" ng-model="item.value">
                        <select class="side-section-select" ng-if="item.type == 'select'" ng-model="item.value">
                            <option value="$font-family-sans-serif" selected>Sans serif</option>
                            <option value="$font-family-light-sans-serif">light sans-serif</option>
                            <option value="$font-family-serif">serif</option>
                            <option value="$font-family-monospace">monospace</option>
                        </select>
                    </li>
                </ul>
            </div>

            <div class="side-section">
                <div class="side-section-header">
                    Padding
                    <button class="btn-revert" ng-click="revert('padding')">
                        <i class="icon icon-lg ion-ios7-refresh-empty"></i>
                    </button>
                </div>
                <ul>
                    <li ng-repeat="item in padding" ng-mouseover="show = true" ng-mouseleave="show = false">
                        {{item.name}}
                        <input type="text" class="side-section-input" ng-if="item.type == 'pixel'" ng-model="item.value">
                    </li>
                </ul>
            </div>

            <div class="side-section-footer">
                <h4>Made with <i class="icon ion-heart"></i> by <a href="https://github.com/pbernasconi/">Paolo Bernasconi</a></h4>
            </div>
        </section>


        <section ng-if="isButtonBar(1)">
            <div class="side-section-download">
                <button class="btn btn-download" ng-click="prepDownload()">Download Theme</button>
            </div>

            <div class="side-card" ng-repeat="">

            </div>

            <div class="side-section-footer">
                <h4>Made with <i class="icon ion-heart"></i> by <a href="https://github.com/pbernasconi/">Paolo Bernasconi</a></h4>
            </div>
        </section>

    </div>

    <div class="main-panel">
        <ul class="main-panel-tabs">
            <li ng-click="setActiveTab(1)" ng-class="{'active': activeTab == 1}">Phone View</li>
            <li ng-class="{'active': activeTab == 2}">Components</li>
            <li class="tabs-left">
                <a class="btn-login" ng-click="loginGithub()" href="https://github.com/pbernasconi/ionic-theme-editor">Github <i class="icon ion-social-github fa-lg"></i></a>
            </li>
        </ul>
        <div class="main-panel-view">
            <div ng-if="activeTab == 0">
                <ul>
                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>

                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>
                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>
                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>
                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>
                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>
                    <li class="preview-card">
                        <div class="card-header">Header</div>

                        <div class="card-content">
                            <div class="bar bar-header bar-positive">
                                <h1 class="title">bar-positive</h1>
                            </div>
                        </div>
                    </li>
                </ul>
            </div>
            <div ng-if="activeTab == 1">
                <div ng-show="iframeLoaded == false" ng-cloak>
                    <div class="spinner-background">
                        <div class="spinner">
                            <div class="double-bounce1"></div>
                            <div class="double-bounce2"></div>
                        </div>
                    </div>
                </div>
                <div ng-show="iframeLoaded == true" ng-cloak style="padding: 40px;">
                    <div class="row">
                        <div class="col-md-4">
                            <h4 class="device-header">Header Bar</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" on-load="iframeCallback()" theme="groupedVars" src="../components/preview/preview-header.html"></iframe>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <h4 class="device-header">Button</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" theme="groupedVars" src="../components/preview/preview-buttons.html"></iframe>
                            </div>
                        </div>
                        <div class="col-md-4">
                            <h4 class="device-header">List</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" theme="groupedVars" src="../components/preview/preview-list.html"></iframe>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-sm-4">
                            <h4 class="device-header">Form</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" theme="groupedVars" src="../components/preview/preview-form.html"></iframe>
                            </div>
                        </div>
                        <div class="col-sm-4">
                            <h4 class="device-header">Tabs</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" theme="groupedVars" src="../components/preview/preview-tabs.html"></iframe>
                            </div>
                        </div>
                        <div class="col-sm-4">
                            <h4 class="device-header">Card</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" theme="groupedVars" src="../components/preview/preview-card.html"></iframe>
                            </div>
                        </div>
                    </div>

                    <div class="row">
                        <div class="col-sm-4">
                            <h4 class="device-header">Components</h4>

                            <div class="device-bg">
                                <iframe class="device-screen ionic" theme="groupedVars" src="../components/preview/preview-components.html"></iframe>
                            </div>
                        </div>
                    </div>
                </div>

            </div>

            <div ng-if="activeTab == 2">
                Examples tab
            </div>

        </div>
    </div>
</div>


<script type="text/ng-template" id="downloadModal">
    <div class="imodal">
        <h1 class="imodal-title">Download CSS File</h1>

        <div class="imodal-content">
            <div class="input-group">
                <label>File name</label>
                <input type="text" ng-model="filename" autoFocus>
            </div>

            <div class="input-group">
                <label style="margin-left: 30px;">Minimized</label>
                <input type="radio" name="css-type" value="compressed" ng-model="cssType">

                <label style="margin-left: 20px;">Nested</label>
                <input type="radio" name="css-type" value="nested" ng-model="cssType">
            </div>
        </div>


        <div class="imodal-buttons">
            <button class="btn btn-modal btn-modal-cancel" ng-click="modalClose()">Cancel</button>
            <button class="btn btn-modal btn-modal-download" ng-click="modalDownload()">Download</button>
        </div>
    </div>
</script>


================================================
FILE: client/app/main/main.js
================================================
'use strict';

angular.module('projectsApp')
  .config(function ($stateProvider) {
    $stateProvider
      .state('main', {
        url: '/',
        templateUrl: 'app/main/main.html',
        controller: 'MainCtrl'
      });
  });

================================================
FILE: client/app/theme/theme.directive.js
================================================
'use strict';

angular.module('projectsApp')
    .directive('theme', function () {
        return {
            restrict: 'EA',
            scope: {
                theme: '=',
                callBack: '&onLoad'
            },
            link: function ($scope, $element, $attr) {
                var cw;
                $element.ready(function () {
                    cw = $element[0].contentWindow;
                });

                $element.on('load', function () {
                    return $scope.callBack();
                });

                var updatePreview = function (colors) {
                    if (!cw) {
                        return;
                    }
                    cw.IonicThemer && cw.IonicThemer.update(colors);
                };

                $scope.$watch('theme', function (nv, ov) {
                    updatePreview(nv);
                }, true);
            }
        }
    })

    .directive('autoFocus', function ($timeout) {
        return {
            restrict: 'AC',
            link: function (_scope, _element) {
                $timeout(function () {
                    _element[0].focus();
                }, 0);
            }
        };
    });


================================================
FILE: client/app/theme/theme.directive.spec.js
================================================
'use strict';

describe('Directive: theme', function () {

  // load the directive's module
  beforeEach(module('projectsApp'));

  var element,
    scope;

  beforeEach(inject(function ($rootScope) {
    scope = $rootScope.$new();
  }));

  it('should make hidden element visible', inject(function ($compile) {
    element = angular.element('<theme></theme>');
    element = $compile(element)(scope);
    expect(element.text()).toBe('this is the theme directive');
  }));
});

================================================
FILE: client/components/preview/preview-buttons.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
    <link id="ionic-css" rel="stylesheet" href="/">

    <script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
    <ion-header-bar class="bar-brand">
        <h1 class="title">BUTTONS</h1>
    </ion-header-bar>
    <ion-content class="has-header padding-horizontal" >

        <button class="button  button-light button-block">Light</button>
        <button class="button  button-stable button-block">Stable</button>
        <button class="button  button-positive button-block">Positive</button>
        <button class="button  button-calm button-block">Calm</button>
        <button class="button  button-balanced button-block">Balanced</button>
        <button class="button  button-energized button-block">Energized</button>
        <button class="button  button-assertive button-block">Assertive</button>
        <button class="button  button-royal button-block">Royal</button>
        <button class="button  button-dark button-block">Dark</button>

    </ion-content>
</ion-pane>
<script>
    angular.module('starter', ['ionic']);

    var css = document.getElementById('ionic-css');
    window.IonicThemer = {
        update: function (colors) {
            var args = [];
            for (var i = 0; i < colors.length; i++) {
                args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
            }
            var path = args.join('&');
            var newUrl = '/api/compile/live/ionic.css?' + path;
            css.setAttribute('href', newUrl);
        }
    }
</script>
</body>
</html>


================================================
FILE: client/components/preview/preview-card.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
    <link id="ionic-css" rel="stylesheet" href="/">

    <script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
    <ion-header-bar class="bar-brand">
        <h1 class="title">Title</h1>
    </ion-header-bar>
    <ion-content class="has-header">

        <div class="list card">

            <div class="item item-avatar">
                <img src="avatar.jpg">

                <h2>Pretty Hate Machine</h2>

                <p>Nine Inch Nails</p>
            </div>

            <div class="item item-image">
                <img src="cover.jpg">
            </div>

            <a class="item item-icon-left assertive" href="#">
                <i class="icon ion-music-note"></i>
                Start listening
            </a>

        </div>

    </ion-content>
</ion-pane>
<script>
    angular.module('starter', ['ionic']);

    var css = document.getElementById('ionic-css');
    window.IonicThemer = {
        update: function (colors) {
            var args = [];
            for (var i = 0; i < colors.length; i++) {
                args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
            }
            var path = args.join('&');
            var newUrl = '/api/compile/live/ionic.css?' + path;
            css.setAttribute('href', newUrl);
        }
    }
</script>
</body>
</html>


================================================
FILE: client/components/preview/preview-components.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
    <link id="ionic-css" rel="stylesheet" href="/">

    <script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
    <ion-header-bar class="bar-brand">
        <h1 class="title">Title</h1>
    </ion-header-bar>
    <ion-content class="has-header">

        <ul class="list">
            <div class="item item-divider">
                Toggle
            </div>
            <li class="item item-toggle">
                HTML5
                <label class="toggle toggle-assertive">
                    <input type="checkbox">

                    <div class="track">
                        <div class="handle"></div>
                    </div>
                </label>
            </li>


            <div class="item item-divider">
                Checkbox
            </div>
            <li class="item item-checkbox">
                <label class="checkbox">
                    <input type="checkbox" ng-model="isChecked">
                </label>
                Flux Capacitor
            </li>
            <li class="item item-checkbox">
                <label class="checkbox">
                    <input type="checkbox">
                </label>
                Flux Capacitor
            </li>

            <div class="item item-divider">
                Radio
            </div>
            <label class="item item-radio">
                <input type="radio" name="group">

                <div class="item-content">
                    Go
                </div>
                <i class="radio-icon ion-checkmark"></i>
            </label>
            <label class="item item-radio">
                <input type="radio" name="group">

                <div class="item-content">
                    Go
                </div>
                <i class="radio-icon ion-checkmark"></i>
            </label>

            <div class="item item-divider">
                Range
            </div>
            <div class="item range range-positive">
                <i class="icon ion-ios-sunny-outline"></i>
                <input type="range" name="volume" min="0" max="100" value="33">
                <i class="icon ion-ios-sunny"></i>
            </div>

            <div class="item item-divider">
                Select
            </div>
            <label class="item item-input item-select">
                <div class="input-label">
                    Lightsaber
                </div>
                <select>
                    <option>Blue</option>
                    <option selected>Green</option>
                    <option>Red</option>
                </select>
            </label>
        </ul>
    </ion-content>
</ion-pane>
<script>
    angular.module('starter', ['ionic']);

    var css = document.getElementById('ionic-css');
    window.IonicThemer = {
        update: function (colors) {
            var args = [];
            for (var i = 0; i < colors.length; i++) {
                args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
            }
            var path = args.join('&');
            var newUrl = '/api/compile/live/ionic.css?' + path;
            css.setAttribute('href', newUrl);
        }
    }
</script>
</body>
</html>


================================================
FILE: client/components/preview/preview-form.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
    <link id="ionic-css" rel="stylesheet" href="/">

    <script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
    <ion-header-bar class="bar-brand">
        <h1 class="title">Title</h1>
    </ion-header-bar>
    <ion-content class="has-header">

        <div class="list">
            <div class="item item-divider">
                Inline
            </div>
            <label class="item item-input">
                <span class="input-label">Username</span>
                <input type="text">
            </label>
            <label class="item item-input">
                <span class="input-label">Password</span>
                <input type="password">
            </label>
        </div>

        <div class="list">
            <div class="item item-divider">
                Placeholder labels
            </div>
            <label class="item item-input">
                <input type="text" placeholder="First Name">
            </label>
            <label class="item item-input">
                <input type="text" placeholder="Last Name">
            </label>
        </div>


        <div class="list">
            <div class="item item-divider">
                Stacked Labels
            </div>
            <label class="item item-input item-stacked-label">
                <span class="input-label">First Name</span>
                <input type="text" placeholder="John">
            </label>
            <label class="item item-input item-stacked-label">
                <span class="input-label">Email</span>
                <input type="text" placeholder="john@suhr.com">
            </label>
        </div>


        <div class="list">
            <div class="item item-divider">
                Floating Labels
            </div>
            <label class="item item-input item-floating-label">
                <span class="input-label">First Name</span>
                <input type="text" placeholder="First Name">
            </label>
            <label class="item item-input item-floating-label">
                <span class="input-label">Email</span>
                <input type="text" placeholder="Email">
            </label>
        </div>
    </ion-content>
</ion-pane>
<script>
    angular.module('starter', ['ionic']);

    var css = document.getElementById('ionic-css');
    window.IonicThemer = {
        update: function (colors) {
            var args = [];
            for (var i = 0; i < colors.length; i++) {
                args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
            }
            var path = args.join('&');
            var newUrl = '/api/compile/live/ionic.css?' + path;
            css.setAttribute('href', newUrl);
        }
    }
</script>
</body>
</html>


================================================
FILE: client/components/preview/preview-header.html
================================================
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
    <link id="ionic-css" rel="stylesheet" href="/">

    <script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
    <ion-header-bar class="bar-brand bar-light">
        <h1 class="title">bar-light</h1>
    </ion-header-bar>
    <ion-content class="has-header">

        <div class="bar bar-header bar-stable" style="position: relative; top: 20px">
            <h1 class="title">bar-stable</h1>
        </div>

        <div class="bar bar-header bar-positive" style="position: relative; top: 40px">
            <h1 class="title">bar-positive</h1>
        </div>

        <div class="bar bar-header bar-calm" style="position: relative; top: 60px">
            <h1 class="title">bar-calm</h1>
        </div>

        <div class="bar bar-header bar-balanced" style="position: relative; top: 80px">
            <h1 class="title">bar-balanced</h1>
        </div>

        <div class="bar bar-header bar-energized" style="position: relative; top: 100px">
            <h1 class="title">bar-energized</h1>
        </div>

        <div class="bar bar-header bar-assertive" style="position: relative; top: 120px">
            <h1 class="title">bar-assertive</h1>
        </div>

        <div class="bar bar-header bar-royal" style="position: relative; top: 140px">
            <h1 class="title">bar-royal</h1>
        </div>

        <div class="bar bar-header bar-dark" style="position: relative; top: 160px">
            <h1 class="title">bar-dark</h1>
        </div>

    </ion-content>
</ion-pane>
<script>
    angular.module('starter', ['ionic']);

    var css = document.getElementById('ionic-css');
    window.IonicThemer = {
        update: function (colors) {
            var args = [];
            for (var i = 0; i < colors.length; i++) {
                args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
            }
            var path = args.join('&');
            var newUrl = '/api/compile/live/ionic.css?' + path;
            css.setAttribute('href', newUrl);
        }
    }
</script>
</body>
</html>


================================================
FILE: client/components/preview/preview-list.html
================================================
<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
	<link id="ionic-css" rel="stylesheet" href="/">

	<script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
	<ion-header-bar class="bar-brand">
		<h1 class="title">Title</h1>
	</ion-header-bar>
	<ion-content class="has-header">

		<div class="list">

			<div class="item item-divider">
				Candy Bars
			</div>

			<a class="item item-icon-left" href="#">
				<i class="icon ion-email"></i>
				Check mail
			</a>

			<a class="item item-icon-left item-icon-right" href="#">
				<i class="icon ion-chatbubble-working"></i>
				Call Ma
				<i class="icon ion-ios-telephone-outline"></i>
			</a>


			<a class="item item-icon-left" href="#">
				<i class="icon ion-mic-a"></i>
				Record album
				<span class="item-note">Grammy</span>
			</a>

			<a class="item item-icon-left" href="#">
				<i class="icon ion-person-stalker"></i>
				Friends
				<span class="badge badge-assertive">0</span>
			</a>

			<div class="item item-divider">
				Avatars
			</div>

			<a class="item" href="#">
				Butterfinger
			</a>

			<a class="item" href="#">
				Butterfinger
			</a>

			<div class="item item-button-right">
				Call Ma
				<button class="button button-positive">
					<i class="icon ion-ios-telephone"></i>
				</button>
			</div>


			<a class="item" href="#">
				Butterfinger
			</a>


		</div>

	</ion-content>
</ion-pane>
<script>
	angular.module('starter', ['ionic']);

	var css = document.getElementById('ionic-css');
	window.IonicThemer = {
		update: function (colors) {
			var args = [];
			for (var i = 0; i < colors.length; i++) {
				args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
			}
			var path = args.join('&');
			var newUrl = '/api/compile/live/ionic.css?' + path;
			css.setAttribute('href', newUrl);
		}
	}
</script>
</body>
</html>


================================================
FILE: client/components/preview/preview-tabs.html
================================================
<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="http://code.ionicframework.com/nightly/css/ionic.min.css">
	<link id="ionic-css" rel="stylesheet" href="/">

	<script src="http://code.ionicframework.com/nightly/js/ionic.bundle.min.js"></script>
</head>
<body ng-app="starter">

<ion-pane>
	<ion-header-bar class="bar-brand">
		<h1 class="title">Title</h1>
	</ion-header-bar>
	<ion-content class="has-header has-tabs">

	</ion-content>
	<ion-tabs class="tabs-positive tabs-icon-only">

		<ion-tab title="Home" icon-on="ion-ios-filing" icon-off="ion-ios-filing-outline">
			<!-- Tab 1 content -->
		</ion-tab>

		<ion-tab title="About" icon-on="ion-ios-clock" icon-off="ion-ios-clock-outline">
			<!-- Tab 2 content -->
		</ion-tab>

		<ion-tab title="Settings" icon-on="ion-ios-gear" icon-off="ion-ios-gear-outline">
			<!-- Tab 3 content -->
		</ion-tab>

	</ion-tabs>
</ion-pane>
<script>
	angular.module('starter', ['ionic']);

	var css = document.getElementById('ionic-css');
	window.IonicThemer = {
		update: function (colors) {
			var args = [];
			for (var i = 0; i < colors.length; i++) {
				args.push(encodeURIComponent(colors[i].variable) + "=" + encodeURIComponent(colors[i].value));
			}
			var path = args.join('&');
			var newUrl = '/api/compile/live/ionic.css?' + path;
			css.setAttribute('href', newUrl);
		}
	}
</script>
</body>
</html>


================================================
FILE: client/index.html
================================================
<!doctype html>
<!--[if lt IE 7]>
<html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>
<html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>
<html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js"> <!--<![endif]-->
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <base href="/">
    <title>Ionic Tailor</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link rel="icon" type="image/x-icon" href="icon.ico"/>

    <!-- build:css(client) app/vendor.css -->
    <!-- bower:css -->
    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.css" />
    <link rel="stylesheet" href="bower_components/spectrum/spectrum.css" />
    <link rel="stylesheet" href="bower_components/ionicons/css/ionicons.css" />
    <link rel="stylesheet" href="bower_components/ngDialog/css/ngDialog.css" />
    <link rel="stylesheet" href="bower_components/ngDialog/css/ngDialog-theme-default.css" />
    <!-- endbower -->
    <!-- endbuild -->
    <!-- build:css({.tmp,client}) app/app.css -->
    <link rel="stylesheet" href="app/app.css">
    <!-- injector:css -->
    <link rel="stylesheet" href="app/app.css">
    <link rel="stylesheet" href="app/main/main.css">
    <!-- endinjector -->
    <!-- endbuild -->
</head>
<body ng-app="projectsApp">
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->

<div ui-view=""></div>

<script>
    (function (i, s, o, g, r, a, m) {
        i['GoogleAnalyticsObject'] = r;
        i[r] = i[r] || function () {
            (i[r].q = i[r].q || []).push(arguments)
        }, i[r].l = 1 * new Date();
        a = s.createElement(o),
            m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        m.parentNode.insertBefore(a, m)
    })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

    ga('create', 'UA-47300658-4');
    ga('send', 'pageview');
</script>

<!--[if lt IE 9]>
<script src="bower_components/es5-shim/es5-shim.js"></script>
<script src="bower_components/json3/lib/json3.min.js"></script>
<![endif]-->

<!-- build:js(client) app/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<script src="bower_components/lodash/dist/lodash.compat.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="bower_components/spectrum/spectrum.js"></script>
<script src="bower_components/angular-spectrum-colorpicker/dist/angular-spectrum-colorpicker.js"></script>
<script src="bower_components/ngDialog/js/ngDialog.js"></script>
<!-- endbower -->
<!-- endbuild -->

<!-- build:js({.tmp,client}) app/app.js -->
<script src="app/app.js"></script>
<!-- injector:js -->
<script src="app/compiler/compiler.service.js"></script>
<script src="app/main/main.controller.js"></script>
<script src="app/main/main.js"></script>
<script src="app/theme/theme.directive.js"></script>
<!-- endinjector -->
<!-- endbuild -->
</body>
</html>


================================================
FILE: client/robots.txt
================================================
# robotstxt.org

User-agent: *


================================================
FILE: e2e/main/main.po.js
================================================
/**
 * This file uses the Page Object pattern to define the main page for tests
 * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
 */

'use strict';

var MainPage = function() {
  this.heroEl = element(by.css('.hero-unit'));
  this.h1El = this.heroEl.element(by.css('h1'));
  this.imgEl = this.heroEl.element(by.css('img'));
};

module.exports = new MainPage();



================================================
FILE: e2e/main/main.spec.js
================================================
'use strict';

describe('Main View', function() {
  var page;

  beforeEach(function() {
    browser.get('/');
    page = require('./main.po');
  });

  it('should include jumbotron with correct data', function() {
    expect(page.h1El.getText()).toBe('\'Allo, \'Allo!');
    expect(page.imgEl.getAttribute('src')).toMatch(/assets\/images\/yeoman.png$/);
    expect(page.imgEl.getAttribute('alt')).toBe('I\'m Yeoman');
  });
});


================================================
FILE: karma.conf.js
================================================
// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html

module.exports = function(config) {
  config.set({
    // base path, that will be used to resolve files and exclude
    basePath: '',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'client/bower_components/jquery/dist/jquery.js',
      'client/bower_components/angular/angular.js',
      'client/bower_components/angular-mocks/angular-mocks.js',
      'client/bower_components/angular-resource/angular-resource.js',
      'client/bower_components/angular-cookies/angular-cookies.js',
      'client/bower_components/angular-sanitize/angular-sanitize.js',
      'client/bower_components/angular-route/angular-route.js',
      'client/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
      'client/bower_components/lodash/dist/lodash.compat.js',
      'client/bower_components/angular-ui-router/release/angular-ui-router.js',
      'client/app/app.js',
      'client/app/app.coffee',
      'client/app/**/*.js',
      'client/app/**/*.coffee',
      'client/components/**/*.js',
      'client/components/**/*.coffee',
      'client/app/**/*.jade',
      'client/components/**/*.jade',
      'client/app/**/*.html',
      'client/components/**/*.html'
    ],

    preprocessors: {
      '**/*.jade': 'ng-jade2js',
      '**/*.html': 'html2js',
      '**/*.coffee': 'coffee',
    },

    ngHtml2JsPreprocessor: {
      stripPrefix: 'client/'
    },

    ngJade2JsPreprocessor: {
      stripPrefix: 'client/'
    },

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,


    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['PhantomJS'],


    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};


================================================
FILE: package.json
================================================
{
  "name": "projects",
  "version": "0.0.0",
  "main": "server/app.js",
  "dependencies": {
    "body-parser": "~1.0.0",
    "composable-middleware": "^0.3.0",
    "compression": "~1.0.1",
    "connect-mongo": "^0.4.1",
    "cookie-parser": "~1.0.1",
    "ejs": "~0.8.4",
    "errorhandler": "~1.0.0",
    "express": "~4.8.0",
    "express-session": "~1.0.2",
    "lodash": "~2.4.1",
    "method-override": "~1.0.0",
    "mkdirp": "^0.5.0",
    "mongoose": "~3.8.8",
    "morgan": "~1.0.0",
    "node-sass": "^0.9.3",
    "request": "^2.42.0",
    "semver": "^3.0.1",
    "shortid": "^2.0.1",
    "static-favicon": "~1.0.1"
  },
  "devDependencies": {
    "grunt": "~0.4.4",
    "grunt-autoprefixer": "~0.7.2",
    "grunt-bower-install": "~1.4.0",
    "grunt-concurrent": "~0.5.0",
    "grunt-contrib-clean": "~0.5.0",
    "grunt-contrib-concat": "~0.4.0",
    "grunt-contrib-copy": "~0.5.0",
    "grunt-contrib-cssmin": "~0.9.0",
    "grunt-contrib-htmlmin": "~0.2.0",
    "grunt-contrib-imagemin": "~0.7.1",
    "grunt-contrib-jshint": "~0.10.0",
    "grunt-contrib-uglify": "~0.4.0",
    "grunt-contrib-watch": "~0.6.1",
    "grunt-google-cdn": "~0.4.0",
    "grunt-newer": "~0.7.0",
    "grunt-ng-annotate": "^0.2.3",
    "grunt-rev": "~0.1.0",
    "grunt-svgmin": "~0.4.0",
    "grunt-usemin": "~2.1.1",
    "grunt-env": "~0.4.1",
    "grunt-node-inspector": "~0.1.5",
    "grunt-nodemon": "~0.2.0",
    "grunt-angular-templates": "^0.5.4",
    "grunt-dom-munger": "^3.4.0",
    "grunt-protractor-runner": "^1.1.0",
    "grunt-asset-injector": "^0.1.0",
    "grunt-karma": "~0.8.2",
    "grunt-mocha-test": "~0.10.2",
    "jit-grunt": "^0.5.0",
    "time-grunt": "~0.3.1",
    "grunt-express-server": "~0.4.17",
    "grunt-open": "~0.2.3",
    "open": "~0.0.4",
    "jshint-stylish": "~0.1.5",
    "connect-livereload": "~0.4.0",
    "karma-ng-scenario": "~0.1.0",
    "karma-firefox-launcher": "~0.1.3",
    "karma-script-launcher": "~0.1.0",
    "karma-html2js-preprocessor": "~0.1.0",
    "karma-ng-jade2js-preprocessor": "^0.1.2",
    "karma-jasmine": "~0.1.5",
    "karma-chrome-launcher": "~0.1.3",
    "requirejs": "~2.1.11",
    "karma-requirejs": "~0.2.1",
    "karma-coffee-preprocessor": "~0.2.1",
    "karma-jade-preprocessor": "0.0.11",
    "karma-phantomjs-launcher": "~0.1.4",
    "karma": "~0.12.9",
    "karma-ng-html2js-preprocessor": "~0.1.0",
    "supertest": "~0.11.0",
    "should": "~3.3.1"
  },
  "engines": {
    "node": ">=0.10.0"
  },
  "scripts": {
    "start": "node server/app.js",
    "test": "grunt test",
    "update-webdriver": "node node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager update"
  },
  "private": true
}


================================================
FILE: protractor.conf.js
================================================
// Protractor configuration
// https://github.com/angular/protractor/blob/master/referenceConf.js

'use strict';

exports.config = {
  // The timeout for each script run on the browser. This should be longer
  // than the maximum time your application needs to stabilize between tasks.
  allScriptsTimeout: 110000,

  // A base URL for your application under test. Calls to protractor.get()
  // with relative paths will be prepended with this.
  baseUrl: 'http://localhost:' + (process.env.PORT || '9000'),

  // If true, only chromedriver will be started, not a standalone selenium.
  // Tests for browsers other than chrome will not run.
  chromeOnly: true,

  // list of files / patterns to load in the browser
  specs: [
    'e2e/**/*.spec.js'
  ],

  // Patterns to exclude.
  exclude: [],

  // ----- Capabilities to be passed to the webdriver instance ----
  //
  // For a full list of available capabilities, see
  // https://code.google.com/p/selenium/wiki/DesiredCapabilities
  // and
  // https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
  capabilities: {
    'browserName': 'chrome'
  },

  // ----- The test framework -----
  //
  // Jasmine and Cucumber are fully supported as a test and assertion framework.
  // Mocha has limited beta support. You will need to include your own
  // assertion framework if working with mocha.
  framework: 'jasmine',

  // ----- Options to be passed to minijasminenode -----
  //
  // See the full list at https://github.com/juliemr/minijasminenode
  jasmineNodeOpts: {
    defaultTimeoutInterval: 30000
  }
};


================================================
FILE: server/.jshintrc
================================================
{
  "node": true,
  "esnext": true,
  "bitwise": true,
  "eqeqeq": true,
  "immed": true,
  "latedef": true,
  "newcap": true,
  "noarg": true,
  "regexp": true,
  "undef": true,
  "smarttabs": true,
  "asi": true,
  "debug": true
}

================================================
FILE: server/api/compile/compile.controller.js
================================================
'use strict';

var _ = require('lodash');
var Compile = require('./compile.model');
var http = require('http');
var https = require('https');
var fs = require('fs');
var request = require('request');
var mkdirp = require('mkdirp');
var path = require('path');
var sass = require('node-sass');
var shortId = require('shortid');


// GET : download file, remove after success
exports.download = function (req, res) {
    var id = req.params.id;
    var filename = req.params.filename || "ionic.app.css";
    console.log(req.params.filename);
    var file = "./server/ionic/tmp/ionic-" + id + ".app.css";

    res.download(path.resolve(file), filename, function (err) {  // send file for download
        if (err) {
            console.log(err);
            throw err;
        } else {
            fs.unlink(path.resolve(file), function (err) { // delete file when done
                if (err) {
                    console.log(err);
                    throw err;
                }
                res.status(200);
            });
        }
    });
};


// POST : Creates a new compile in the DB.
exports.compile = function (req, res) {
    var postData = req.body;
    var cssType = req.params.cssType;
    var uniqueID = shortId.generate(); // generate a unique ID for tmp file
    var stats = {};
    var sassString = "";

    mkdirp('./server/ionic/tmp', function (err) { // create temporary folder
        if (err) {
            console.log(err);
            throw err;
        }
    });

    console.log(cssType);

    if (cssType != "nested" && cssType != "compressed") {
        res.status(400).json({success: false, id: null, error: "Wrong CSS type"}).end();
    }

    sassString += "$ionicons-font-path: '../../../ionic/scss/fonts' !default;";
    sassString += "$font-family-sans-serif: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif !default;";
    sassString += "$font-family-light-sans-serif:'Helvetica Neue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif !default;"
    sassString += "$font-family-serif: Georgia, 'Times New Roman', Times, serif !default;";
    sassString += "$font-family-monospace:  Monaco, Menlo, Consolas, 'Courier New', monospace !default;";

    _.each(postData, function (each) { // create variables SASS compiler string
        sassString += each.variable + ":  " + each.value + " !default;\n";
    });

    sassString += "@import './server/ionic/scss-prod/ionic';"; // import ionic into SASS compiler string

    sass.renderFile({
        data: sassString,
        success: function (css) {
            res.status(200).json({success: true, id: uniqueID});
        },
        error: function (error) {
            console.log(error);
            res.status(400).json({success: false, id: null, error: error});
        },
        outFile: "./server/ionic/tmp/ionic-" + uniqueID + ".app.css",
        outputStyle: cssType,
        stats: stats
    });
};


// GET : compile for live preview
exports.live = function (req, res) {

    var reqData = req.query;
    var sassString = "";
    res.set('Content-Type', 'text/css');

    sassString += "$font-family-sans-serif: 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif !default;";
    sassString += "$font-family-light-sans-serif:'Helvetica Neue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif !default;"
    sassString += "$font-family-serif: Georgia, 'Times New Roman', Times, serif !default;";
    sassString += "$font-family-monospace:  Monaco, Menlo, Consolas, 'Courier New', monospace !default;";

    _.each(reqData, function (value, key) {
        sassString += key + ":  " + value + " !default;\n";
    });

    sassString += "@import './server/ionic/scss-live/ionic';";
    //sassString += "@function best-text-color($color) { @if (lightness( $color ) > 70) {@return #000000;} @else { @return #FFFFFF;}}";
    //sassString += ".bar {&.bar-brand { @include bar-style($brand, lighten($brand, 50%), best-text-color($brand));} }";


    var stats = {};
    sass.render({
        data: sassString,
        success: function (css) {
            res.send(css);
        },
        error: function (error) {
            console.log(error);
            res.status(400).json({success: false, id: null});
        },
        includePaths: ['ionic/scss/ionic'],
        outputStyle: 'compressed',
        stats: stats
    });
};


// ??? : Update ionic sass files depending on latest version
exports.update = function (req, res) {

    mkdirp('./server/ionic/scss_test', function (err) { // create new scss test folder
        if (!err == null) console.log(err);
    });
};


function getNightly(postData) {
    var outputString = "";
    var ionicVersion = "";
    var githubStr = "https://github.com/driftyco/ionic/blob/master/";
    var rawgitStr = "https://cdn.rawgit.com/driftyco/ionic/master/";

    request('https://cdn.rawgit.com/driftyco/ionic/master/package.json', function (error, response, body) {
        if (!error && response.statusCode == 200) {
            ionicVersion = JSON.parse(body).version;

            console.log(ionicVersion);

            var gitOptions = {
                url: 'https://api.github.com/repos/driftyco/ionic/contents/scss?', //ref=v' + ionicVersion,
                headers: {'User-Agent': 'request'}
            };

            request(gitOptions, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    var scss = JSON.parse(body);
                    _.each(scss, function (each) {
                        if (each.name != "ionicons") {
                            var fileIn = each.html_url.replace(githubStr, rawgitStr);
                            var fileOut = path.resolve("./server/ionic/scss/" + each.name);

                            var options = {
                                url: fileIn,
                                headers: {'User-Agent': 'request'}
                            };

                            request(options, function (error, res, bod) {
                                fs.writeFile(path.resolve(fileOut), (bod), function (error) {
                                    if (error) console.log("error : " + error);
                                    else {
                                        _.each(postData, function (each) {
                                            outputString += each.variable + ":  " + each.value + " !default;\n";
                                        });

                                        outputString += "@import './server/ionic/scss/ionic';";

                                        var dateID = new Date().getTime();

                                        CompileSass(outputString, dateID);
                                    }
                                });
                            });
                        }
                    });
                }
            });


        }
    });
}

function CompileSass(outputString, dateID) {
    var stats = {};
    sass.renderFile({
        data: outputString,
        success: function (css) {
            //res.status(200).json({success: true, id: dateID});
        },
        error: function (error) {
            console.log(error);
            //res.status(400).json({success: false, id: null});
        },
        includePaths: ['ionic/scss/ionic'],
        outFile: "./server/ionic/tmp/ionic.app.css", // + dateID + ".css",
        outputStyle: 'nested',
        stats: stats
    });
}

function handleError(res, err) {
    return res.send(500, err);
}


================================================
FILE: server/api/compile/compile.model.js
================================================
'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var CompileSchema = new Schema({
  name: String,
  info: String,
  active: Boolean
});

module.exports = mongoose.model('Compile', CompileSchema);

================================================
FILE: server/api/compile/compile.spec.js
================================================
'use strict';

var should = require('should');
var app = require('../../app');
var request = require('supertest');

describe('GET /api/compile', function() {

  it('should respond with JSON array', function(done) {
    request(app)
      .get('/api/compile')
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function(err, res) {
        if (err) return done(err);
        res.body.should.be.instanceof(Array);
        done();
      });
  });
});

================================================
FILE: server/api/compile/index.js
================================================
'use strict';

var express = require('express');
var controller = require('./compile.controller');

var router = express.Router();

router.get('/download/:id/:filename', controller.download); // download ionic.css
router.get('/live/ionic.css:data', controller.live); // post a live
router.post('/:cssType', controller.compile); // post a new compile script
router.get('/live/:body', controller.live); // post a live
router.put('/:id', controller.update);

module.exports = router;


================================================
FILE: server/api/themes/index.js
================================================
'use strict';

var express = require('express');
var controller = require('./themes.controller');

var router = express.Router();

router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);

module.exports = router;

================================================
FILE: server/api/themes/themes.controller.js
================================================
'use strict';

var _ = require('lodash');
var Themes = require('./themes.model');

// Get list of themess
exports.index = function(req, res) {
  Themes.find(function (err, themess) {
    if(err) { return handleError(res, err); }
    return res.json(200, themess);
  });
};

// Get a single themes
exports.show = function(req, res) {
  Themes.findById(req.params.id, function (err, themes) {
    if(err) { return handleError(res, err); }
    if(!themes) { return res.send(404); }
    return res.json(themes);
  });
};

// Creates a new themes in the DB.
exports.create = function(req, res) {
  Themes.create(req.body, function(err, themes) {
    if(err) { return handleError(res, err); }
    return res.json(201, themes);
  });
};

// Updates an existing themes in the DB.
exports.update = function(req, res) {
  if(req.body._id) { delete req.body._id; }
  Themes.findById(req.params.id, function (err, themes) {
    if (err) { return handleError(res, err); }
    if(!themes) { return res.send(404); }
    var updated = _.merge(themes, req.body);
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, themes);
    });
  });
};

// Deletes a themes from the DB.
exports.destroy = function(req, res) {
  Themes.findById(req.params.id, function (err, themes) {
    if(err) { return handleError(res, err); }
    if(!themes) { return res.send(404); }
    themes.remove(function(err) {
      if(err) { return handleError(res, err); }
      return res.send(204);
    });
  });
};

function handleError(res, err) {
  return res.send(500, err);
}

================================================
FILE: server/api/themes/themes.model.js
================================================
'use strict';

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var ThemesSchema = new Schema({
  name: String,
  info: String,
  active: Boolean
});

module.exports = mongoose.model('Themes', ThemesSchema);

================================================
FILE: server/api/themes/themes.spec.js
================================================
'use strict';

var should = require('should');
var app = require('../../app');
var request = require('supertest');

describe('GET /api/themes', function() {

  it('should respond with JSON array', function(done) {
    request(app)
      .get('/api/themes')
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function(err, res) {
        if (err) return done(err);
        res.body.should.be.instanceof(Array);
        done();
      });
  });
});

================================================
FILE: server/app.js
================================================
/**
 * Main application file
 */

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var express = require('express');
var mongoose = require('mongoose');
var config = require('./config/environment');

// Connect to database
mongoose.connect(config.mongo.uri, config.mongo.options);

// Populate DB with sample dat
// Setup server
var app = express();
var server = require('http').createServer(app);
require('./config/express')(app);
require('./routes')(app);

// Start server
server.listen(config.port, config.ip, function () {
  console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

// Expose app
exports = module.exports = app;


================================================
FILE: server/components/errors/index.js
================================================
/**
 * Error responses
 */

'use strict';

module.exports[404] = function pageNotFound(req, res) {
  var viewFilePath = '404';
  var statusCode = 404;
  var result = {
    status: statusCode
  };

  res.status(result.status);
  res.render(viewFilePath, function (err) {
    if (err) { return res.json(result, result.status); }

    res.render(viewFilePath);
  });
};


================================================
FILE: server/config/environment/development.js
================================================
'use strict';

// Development specific configuration
// ==================================
module.exports = {
  // MongoDB connection options
  mongo: {
    uri: 'mongodb://localhost/projects-dev'
  },

  seedDB: true
};


================================================
FILE: server/config/environment/index.js
================================================
'use strict';

var path = require('path');
var _ = require('lodash');

function requiredProcessEnv(name) {
  if(!process.env[name]) {
    throw new Error('You must set the ' + name + ' environment variable');
  }
  return process.env[name];
}

// All configurations will extend these options
// ============================================
var all = {
  env: process.env.NODE_ENV,

  // Root path of server
  root: path.normalize(__dirname + '/../../..'),

  // Server port
  port: process.env.PORT || 9000,

  // Should we populate the DB with sample data?
  seedDB: false,

  // Secret for session, you will want to change this and make it an environment variable
  secrets: {
    session: 'projects-secret'
  },

  // List of user roles
  userRoles: ['guest', 'user', 'admin'],

  // MongoDB connection options
  mongo: {
    options: {
      db: {
        safe: true
      }
    }
  },

};

// Export the config object based on the NODE_ENV
// ==============================================
module.exports = _.merge(
  all,
  require('./' + process.env.NODE_ENV + '.js') || {});

================================================
FILE: server/config/environment/production.js
================================================
'use strict';

// Production specific configuration
// =================================
module.exports = {
  // Server IP
  ip:       process.env.OPENSHIFT_NODEJS_IP ||
            process.env.IP ||
            undefined,

  // Server port
  port:     process.env.OPENSHIFT_NODEJS_PORT ||
            process.env.PORT ||
            8080,

  // MongoDB connection options
  mongo: {
    uri:    process.env.MONGOLAB_URI ||
            process.env.MONGOHQ_URL ||
            process.env.OPENSHIFT_MONGODB_DB_URL+process.env.OPENSHIFT_APP_NAME ||
            'mongodb://localhost/projects'
  }
};

================================================
FILE: server/config/environment/test.js
================================================
'use strict';

// Test specific configuration
// ===========================
module.exports = {
  // MongoDB connection options
  mongo: {
    uri: 'mongodb://localhost/projects-test'
  }
};

================================================
FILE: server/config/express.js
================================================
/**
 * Express configuration
 */

'use strict';

var express = require('express');
var favicon = require('static-favicon');
var morgan = require('morgan');
var compression = require('compression');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var cookieParser = require('cookie-parser');
var errorHandler = require('errorhandler');
var path = require('path');
var config = require('./environment');

module.exports = function(app) {
  var env = app.get('env');

  app.set('views', config.root + '/server/views');
  app.engine('html', require('ejs').renderFile);
  app.set('view engine', 'html');
  app.use(compression());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use(bodyParser.json());
  app.use(methodOverride());
  app.use(cookieParser());
  
  if ('production' === env) {
    app.use(favicon(path.join(config.root, 'public', 'favicon.ico')));
    app.use(express.static(path.join(config.root, 'public')));
    app.set('appPath', config.root + '/public');
    app.use(morgan('dev'));
  }

  if ('development' === env || 'test' === env) {
    app.use(require('connect-livereload')());
    app.use(express.static(path.join(config.root, '.tmp')));
    app.use(express.static(path.join(config.root, 'client')));
    app.set('appPath', 'client');
    app.use(morgan('dev'));
    app.use(errorHandler()); // Error handler - has to be last
  }
};

================================================
FILE: server/ionic/scss-live/_action-sheet.scss
================================================
/**
 * Action Sheets
 * --------------------------------------------------
 */

.action-sheet-backdrop {
  @include transition(background-color 300ms ease-in-out);
  position: fixed;
  top: 0;
  left: 0;
  z-index: $z-index-action-sheet;
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,0);

  &.active {
    background-color: rgba(0,0,0,0.4);
  }
}

.action-sheet-wrapper {
  @include translate3d(0, 100%, 0);
  @include transition(all ease-in-out 300ms);
  position: absolute;
  bottom: 0;
  width: 100%;
}

.action-sheet-up {
  @include translate3d(0, 0, 0);
}

.action-sheet {
  margin-left: $sheet-margin;
  margin-right: $sheet-margin;
  width: auto;
  z-index: $z-index-action-sheet;
  overflow: hidden;

  .button {
    display: block;
    padding: 1px;
    width: 100%;
    border-radius: 0;
    border-color: $sheet-options-border-color;
    background-color: transparent;

    color: $sheet-options-text-color;
    font-size: 21px;

    &:hover {
      color: $sheet-options-text-color;
    }
    &.destructive {
      color: #ff3b30;
      &:hover {
        color: #ff3b30;
      }
    }
  }

  .button.active, .button.activated {
    box-shadow: none;
    border-color: $sheet-options-border-color;
    color: $sheet-options-text-color;
    background: $sheet-options-bg-active-color;
  }
}

.action-sheet-has-icons .icon {
  position: absolute;
  left: 16px;
}

.action-sheet-title {
  padding: $sheet-margin * 2;
  color: #8f8f8f;
  text-align: center;
  font-size: 13px;
}

.action-sheet-group {
  margin-bottom: $sheet-margin;
  border-radius: $sheet-border-radius;
  background-color: #fff;
  overflow: hidden;

  .button {
    border-width: 1px 0px 0px 0px;
  }
  .button:first-child:last-child {
    border-width: 0;
  }
}

.action-sheet-options {
  background: $sheet-options-bg-color;
}

.action-sheet-cancel {
  .button {
    font-weight: 500;
  }
}

.action-sheet-open {
  pointer-events: none;

  &.modal-open .modal {
    pointer-events: none;
  }

  .action-sheet-backdrop {
    pointer-events: auto;
  }
}


.platform-android {

  .action-sheet-backdrop.active {
    background-color: rgba(0,0,0,0.2);
  }

  .action-sheet {
    margin: 0;

    .action-sheet-title,
    .button {
      text-align: left;
      border-color: transparent;
      font-size: 16px;
      color: inherit;
    }

    .action-sheet-title {
      font-size: 14px;
      padding: 16px;
      color: #666;
    }

    .button.active,
    .button.activated {
      background: #e8e8e8;
    }
  }

  .action-sheet-group {
    margin: 0;
    border-radius: 0;
    background-color: #fafafa;
  }

  .action-sheet-cancel {
    display: none;
  }

  .action-sheet-has-icons {

    .button {
      padding-left: 56px;
    }

  }

}


================================================
FILE: server/ionic/scss-live/_animations.scss
================================================

// Slide up from the bottom, used for modals
// -------------------------------

.slide-in-up {
  @include translate3d(0, 100%, 0);
}
.slide-in-up.ng-enter,
.slide-in-up > .ng-enter {
  @include transition(all cubic-bezier(.1, .7, .1, 1) 400ms);
}
.slide-in-up.ng-enter-active,
.slide-in-up > .ng-enter-active {
  @include translate3d(0, 0, 0);
}

.slide-in-up.ng-leave,
.slide-in-up > .ng-leave {
  @include transition(all ease-in-out 250ms);
}


// Scale Out
// Scale from hero (1 in this case) to zero
// -------------------------------

@-webkit-keyframes scaleOut {
  from { -webkit-transform: scale(1); opacity: 1; }
  to { -webkit-transform: scale(0.8); opacity: 0; }
}
@keyframes scaleOut {
  from { transform: scale(1); opacity: 1; }
  to { transform: scale(0.8); opacity: 0; }
}


// Super Scale In
// Scale from super (1.x) to duper (1 in this case)
// -------------------------------

@-webkit-keyframes superScaleIn {
  from { -webkit-transform: scale(1.2); opacity: 0; }
  to { -webkit-transform: scale(1); opacity: 1 }
}
@keyframes superScaleIn {
  from { transform: scale(1.2); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}


================================================
FILE: server/ionic/scss-live/_backdrop.scss
================================================

.backdrop {
  position: fixed;
  top: 0;
  left: 0;
  z-index: $z-index-backdrop;

  width: 100%;
  height: 100%;

  background-color: $loading-backdrop-bg-color;

  visibility: hidden;
  opacity: 0;

  &.visible {
    visibility: visible;
  }
  &.active {
    opacity: 1;
  }

  @include transition($loading-backdrop-fadein-duration opacity linear);
}


================================================
FILE: server/ionic/scss-live/_badge.scss
================================================

/**
 * Badges
 * --------------------------------------------------
 */

.badge {
  @include badge-style($badge-default-bg, $badge-default-text);
  z-index: $z-index-badge;
  display: inline-block;
  padding: 3px 8px;
  min-width: 10px;
  border-radius: $badge-border-radius;
  vertical-align: baseline;
  text-align: center;
  white-space: nowrap;
  font-weight: $badge-font-weight;
  font-size: $badge-font-size;
  line-height: $badge-line-height;

  &:empty {
    display: none;
  }
}

//Be sure to override specificity of rule that 'badge color matches tab color by default'
.tabs .tab-item .badge,
.badge {
  &.badge-light {
    @include badge-style($badge-light-bg, $badge-light-text);
  }
  &.badge-stable {
    @include badge-style($badge-stable-bg, $badge-stable-text);
  }
  &.badge-positive {
    @include badge-style($badge-positive-bg, $badge-positive-text);
  }
  &.badge-calm {
    @include badge-style($badge-calm-bg, $badge-calm-text);
  }
  &.badge-assertive {
    @include badge-style($badge-assertive-bg, $badge-assertive-text);
  }
  &.badge-balanced {
    @include badge-style($badge-balanced-bg, $badge-balanced-text);
  }
  &.badge-energized {
    @include badge-style($badge-energized-bg, $badge-energized-text);
  }
  &.badge-royal {
    @include badge-style($badge-royal-bg, $badge-royal-text);
  }
  &.badge-dark {
    @include badge-style($badge-dark-bg, $badge-dark-text);
  }
}

// Quick fix for labels/badges in buttons
.button .badge {
  position: relative;
  top: -1px;
}


================================================
FILE: server/ionic/scss-live/_bar.scss
================================================

/**
 * Bar (Headers and Footers)
 * --------------------------------------------------
 */

.bar {
  @include display-flex();
  @include translate3d(0,0,0);
  @include user-select(none);
  position: absolute;
  right: 0;
  left: 0;
  z-index: $z-index-bar;

  box-sizing: border-box;
  padding: $bar-padding-portrait;

  width: 100%;
  height: $bar-height;
  border-width: 0;
  border-style: solid;
  border-top: 1px solid transparent;
  border-bottom: 1px solid $bar-default-border;

  background-color: $bar-default-bg;

  /* border-width: 1px will actually create 2 device pixels on retina */
  /* this nifty trick sets an actual 1px border on hi-res displays */
  background-size: 0;
  @media (min--moz-device-pixel-ratio: 1.5),
         (-webkit-min-device-pixel-ratio: 1.5),
         (min-device-pixel-ratio: 1.5),
         (min-resolution: 144dpi),
         (min-resolution: 1.5dppx) {
    border: none;
    background-image: linear-gradient(0deg, $bar-default-border, $bar-default-border 50%, transparent 50%);
    background-position: bottom;
    background-size: 100% 1px;
    background-repeat: no-repeat;
  }

  &.bar-clear {
    border: none;
    background: none;
    color: #fff;

    .button {
      color: #fff;
    }
    .title {
      color: #fff;
    }
  }

  &.item-input-inset {
    .item-input-wrapper {
      margin-top: -1px;

      input {
        padding-left: 8px;
        width: 94%;
        height: 28px;
        background: transparent;
      }
    }
  }

  &.bar-light {
    @include bar-style($bar-light-bg, $bar-light-border, $bar-light-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-light-border, $bar-light-border 50%, transparent 50%);
    }
  }
  &.bar-stable {
    @include bar-style($bar-stable-bg, $bar-stable-border, $bar-stable-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-stable-border, $bar-stable-border 50%, transparent 50%);
    }
  }
  &.bar-positive {
    @include bar-style($bar-positive-bg, $bar-positive-border, $bar-positive-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-positive-border, $bar-positive-border 50%, transparent 50%);
    }
  }
  &.bar-calm {
    @include bar-style($bar-calm-bg, $bar-calm-border, $bar-calm-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-calm-border, $bar-calm-border 50%, transparent 50%);
    }
  }
  &.bar-assertive {
    @include bar-style($bar-assertive-bg, $bar-assertive-border, $bar-assertive-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-assertive-border, $bar-assertive-border 50%, transparent 50%);
    }
  }
  &.bar-balanced {
    @include bar-style($bar-balanced-bg, $bar-balanced-border, $bar-balanced-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-balanced-border, $bar-positive-border 50%, transparent 50%);
    }
  }
  &.bar-energized {
    @include bar-style($bar-energized-bg, $bar-energized-border, $bar-energized-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-energized-border, $bar-energized-border 50%, transparent 50%);
    }
  }
  &.bar-royal {
    @include bar-style($bar-royal-bg, $bar-royal-border, $bar-royal-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-royal-border, $bar-royal-border 50%, transparent 50%);
    }
  }
  &.bar-dark {
    @include bar-style($bar-dark-bg, $bar-dark-border, $bar-dark-text);
    &.bar-footer{
      background-image: linear-gradient(180deg, $bar-dark-border, $bar-dark-border 50%, transparent 50%);
    }
  }

  // Title inside of a bar is centered
  .title {
    position: absolute;

    top: 0;
    right: 0;
    left: 0;
    z-index: $z-index-bar-title;
    overflow: hidden;

    margin: 0 10px;

    min-width: 30px;
    height: $bar-height - 1;

    text-align: center;

    // Go into ellipsis if too small
    text-overflow: ellipsis;
    white-space: nowrap;

    font-size: $bar-title-font-size;
    font-weight: $headings-font-weight;

    line-height: $bar-height;

    &.title-left {
      text-align: left;
    }
    &.title-right {
      text-align: right;
    }
  }

  .title a {
    color: inherit;
  }

  .button {
    z-index: $z-index-bar-button;
    padding: 0 $button-bar-button-padding;
    min-width: initial;
    min-height: $button-bar-button-height - 1;
    font-weight: 400;
    font-size: $button-bar-button-font-size;
    line-height: $button-bar-button-height;

    &.button-icon:before,
    .icon:before,
    &.icon:before,
    &.icon-left:before,
    &.icon-right:before {
      padding-right: 2px;
      padding-left: 2px;
      font-size: $button-bar-button-icon-size;
      line-height: $button-bar-button-height;
    }

    &.button-icon {
      font-size: $bar-title-font-size;
      .icon:before,
      &:before,
      &.icon-left:before,
      &.icon-right:before {
        vertical-align: top;
        font-size: $button-large-icon-size;
        line-height: $button-bar-button-height;
      }
    }
    &.button-clear {
      padding-right: 2px;
      padding-left: 2px;
      font-weight: 300;
      font-size: $bar-title-font-size;

      .icon:before,
      &.icon:before,
      &.icon-left:before,
      &.icon-right:before {
        font-size: $button-large-icon-size;
        line-height: $button-bar-button-height;
      }
    }

    &.back-button {
      display: block;
      margin-right: 5px;
      padding: 0;
      white-space: nowrap;
      font-weight: 400;
    }

    &.back-button.active,
    &.back-button.activated {
      opacity: 0.2;
    }
  }

  .button-bar > .button,
  .buttons > .button {
    min-height: $button-bar-button-height - 1;
    line-height: $button-bar-button-height;
  }

  .button-bar + .button,
  .button + .button-bar {
    margin-left: 5px;
  }

  // Android 4.4 messes with the display property
  .buttons,
  .buttons.primary-buttons,
  .buttons.secondary-buttons {
    display: inherit;
  }
  .buttons span {
    display: inline-block;
  }
  .buttons-left span {
    margin-right: 5px;
  }
  .buttons-right span {
    margin-left: 5px;
  }

  // Place the last button in a bar on the right of the bar
  .title + .button:last-child,
  > .button + .button:last-child,
  > .button.pull-right,
  .buttons.pull-right,
  .title + .buttons {
    position: absolute;
    top: 5px;
    right: 5px;
    bottom: 5px;
  }

}

.platform-android {

  .bar {

    .back-button .icon:before {
      font-size: 24px;
    }

    .title {
      font-size: 19px;
      line-height: 43px;
    }
  }

}

// Default styles for buttons inside of styled bars
.bar-light {
  .button {
    @include button-style($bar-light-bg, $bar-light-border, $bar-light-active-bg, $bar-light-active-border, $bar-light-text);
    @include button-clear($bar-light-text, $bar-title-font-size);
  }
}
.bar-stable {
  .button {
    @include button-style($bar-stable-bg, $bar-stable-border, $bar-stable-active-bg, $bar-stable-active-border, $bar-stable-text);
    @include button-clear($bar-stable-text, $bar-title-font-size);
  }
}
.bar-positive {
  .button {
    @include button-style($bar-positive-bg, $bar-positive-border, $bar-positive-active-bg, $bar-positive-active-border, $bar-positive-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}
.bar-calm {
  .button {
    @include button-style($bar-calm-bg, $bar-calm-border, $bar-calm-active-bg, $bar-calm-active-border, $bar-calm-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}
.bar-assertive {
  .button {
    @include button-style($bar-assertive-bg, $bar-assertive-border, $bar-assertive-active-bg, $bar-assertive-active-border, $bar-assertive-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}
.bar-balanced {
  .button {
    @include button-style($bar-balanced-bg, $bar-balanced-border, $bar-balanced-active-bg, $bar-balanced-active-border, $bar-balanced-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}
.bar-energized {
  .button {
    @include button-style($bar-energized-bg, $bar-energized-border, $bar-energized-active-bg, $bar-energized-active-border, $bar-energized-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}
.bar-royal {
  .button {
    @include button-style($bar-royal-bg, $bar-royal-border, $bar-royal-active-bg, $bar-royal-active-border, $bar-royal-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}
.bar-dark {
  .button {
    @include button-style($bar-dark-bg, $bar-dark-border, $bar-dark-active-bg, $bar-dark-active-border, $bar-dark-text);
    @include button-clear(#fff, $bar-title-font-size);
  }
}

// Header at top
.bar-header {
  top: 0;
  border-top-width: 0;
  border-bottom-width: 1px;
  &.has-tabs-top{
    border-bottom-width: 0px;
    background-image: none;
  }
}
.tabs-top .bar-header{
  border-bottom-width: 0px;
  background-image: none;
}

// Footer at bottom
.bar-footer {
  bottom: 0;
  border-top-width: 1px;
  border-bottom-width: 0;
  background-position: top;

  height: $bar-footer-height;

  &.item-input-inset {
    position: absolute;
  }
}

// Don't render padding if the bar is just for tabs
.bar-tabs {
  padding: 0;
}

.bar-subheader {
  top: $bar-height;
  display: block;

  height: $bar-subheader-height;
}
.bar-subfooter {
  bottom: $bar-footer-height;
  display: block;

  height: $bar-subfooter-height;
}

.nav-bar-block {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  z-index: $z-index-bar;
}

.bar .back-button.hide,
.bar .buttons .hide {
  display: none;
}


================================================
FILE: server/ionic/scss-live/_button-bar.scss
================================================

/**
 * Button Bar
 * --------------------------------------------------
 */

.button-bar {
  @include display-flex();
  @include flex(1);
  width: 100%;

  &.button-bar-inline {
    display: block;
    width: auto;

    @include clearfix();

    > .button {
      width: auto;
      display: inline-block;
      float: left;
    }
  }
}

.button-bar > .button {
  @include flex(1);
  display: block;
  
  overflow: hidden;

  padding: 0 16px;

  width: 0;

  border-width: 1px 0px 1px 1px;
  border-radius: 0;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;

  &:before,
  .icon:before {
    line-height: 44px;
  }

  &:first-child {
    border-radius: $button-border-radius 0px 0px $button-border-radius;
  }
  &:last-child {
    border-right-width: 1px;
    border-radius: 0px $button-border-radius $button-border-radius 0px;
  }
}


================================================
FILE: server/ionic/scss-live/_button.scss
================================================

/**
 * Buttons
 * --------------------------------------------------
 */

.button {
  // set the color defaults
  @include button-style($button-default-bg, $button-default-border, $button-default-active-bg, $button-default-active-border, $button-default-text);

  position: relative;
  display: inline-block;
  margin: 0;
  padding: 0 $button-padding;

  min-width: ($button-padding * 3) + $button-font-size;
  min-height: $button-height + 5px;

  border-width: $button-border-width;
  border-style: solid;
  border-radius: $button-border-radius;

  vertical-align: top;
  text-align: center;

  text-overflow: ellipsis;
  font-size: $button-font-size;
  line-height: $button-height - $button-border-width + 1px;

  cursor: pointer;

  &:after {
    // used to create a larger button "hit" area
    position: absolute;
    top: -6px;
    right: -6px;
    bottom: -6px;
    left: -6px;
    content: ' ';
  }

  .icon {
    vertical-align: top;
    pointer-events: none;
  }

  .icon:before,
  &.icon:before,
  &.icon-left:before,
  &.icon-right:before {
    display: inline-block;
    padding: 0 0 $button-border-width 0;
    vertical-align: inherit;
    font-size: $button-icon-size;
    line-height: $button-height - $button-border-width;
    pointer-events: none;
  }
  &.icon-left:before {
    float: left;
    padding-right: .2em;
    padding-left: 0;
  }
  &.icon-right:before {
    float: right;
    padding-right: 0;
    padding-left: .2em;
  }

  &.button-block, &.button-full {
    margin-top: $button-block-margin;
    margin-bottom: $button-block-margin;
  }

  &.button-light {
    @include button-style($button-light-bg, $button-light-border, $button-light-active-bg, $button-light-active-border, $button-light-text);
    @include button-clear($button-light-border);
    @include button-outline($button-light-border);
  }

  &.button-stable {
    @include button-style($button-stable-bg, $button-stable-border, $button-stable-active-bg, $button-stable-active-border, $button-stable-text);
    @include button-clear($button-stable-border);
    @include button-outline($button-stable-border);
  }

  &.button-positive {
    @include button-style($button-positive-bg, $button-positive-border, $button-positive-active-bg, $button-positive-active-border, $button-positive-text);
    @include button-clear($button-positive-bg);
    @include button-outline($button-positive-bg);
  }

  &.button-calm {
    @include button-style($button-calm-bg, $button-calm-border, $button-calm-active-bg, $button-calm-active-border, $button-calm-text);
    @include button-clear($button-calm-bg);
    @include button-outline($button-calm-bg);
  }

  &.button-assertive {
    @include button-style($button-assertive-bg, $button-assertive-border, $button-assertive-active-bg, $button-assertive-active-border, $button-assertive-text);
    @include button-clear($button-assertive-bg);
    @include button-outline($button-assertive-bg);
  }

  &.button-balanced {
    @include button-style($button-balanced-bg, $button-balanced-border, $button-balanced-active-bg, $button-balanced-active-border, $button-balanced-text);
    @include button-clear($button-balanced-bg);
    @include button-outline($button-balanced-bg);
  }

  &.button-energized {
    @include button-style($button-energized-bg, $button-energized-border, $button-energized-active-bg, $button-energized-active-border, $button-energized-text);
    @include button-clear($button-energized-bg);
    @include button-outline($button-energized-bg);
  }

  &.button-royal {
    @include button-style($button-royal-bg, $button-royal-border, $button-royal-active-bg, $button-royal-active-border, $button-royal-text);
    @include button-clear($button-royal-bg);
    @include button-outline($button-royal-bg);
  }

  &.button-dark {
    @include button-style($button-dark-bg, $button-dark-border, $button-dark-active-bg, $button-dark-active-border, $button-dark-text);
    @include button-clear($button-dark-bg);
    @include button-outline($button-dark-bg);
  }
}

.button-small {
  padding: 2px $button-small-padding 1px;
  min-width: $button-small-height;
  min-height: $button-small-height + 2;
  font-size: $button-small-font-size;
  line-height: $button-small-height - $button-border-width - 1;

  .icon:before,
  &.icon:before,
  &.icon-left:before,
  &.icon-right:before {
    font-size: $button-small-icon-size;
    line-height: $button-small-icon-size + 3;
    margin-top: 3px;
  }
}

.button-large {
  padding: 0 $button-large-padding;
  min-width: ($button-large-padding * 3) + $button-large-font-size;
  min-height: $button-large-height + 5;
  font-size: $button-large-font-size;
  line-height: $button-large-height - $button-border-width;

  .icon:before,
  &.icon:before,
  &.icon-left:before,
  &.icon-right:before {
    padding-bottom: ($button-border-width * 2);
    font-size: $button-large-icon-size;
    line-height: $button-large-height - ($button-border-width * 2) - 1;
  }
}

.button-icon {
  @include transition(opacity .1s);
  padding: 0 6px;
  min-width: initial;
  border-color: transparent;
  background: none;

  &.button.active,
  &.button.activated {
    border-color: transparent;
    background: none;
    box-shadow: none;
    opacity: 0.3;
  }

  .icon:before,
  &.icon:before {
    font-size: $button-large-icon-size;
  }
}

.button-clear {
  @include button-clear($button-default-border);
  @include transition(opacity .1s);
  padding: 0 $button-clear-padding;
  max-height: $button-height;
  border-color: transparent;
  background: none;
  box-shadow: none;

  &.active,
  &.activated {
    opacity: 0.3;
  }
}

.button-outline {
  @include button-outline($button-default-border);
  @include transition(opacity .1s);
  background: none;
  box-shadow: none;
}

.padding > .button.button-block:first-child {
  margin-top: 0;
}

.button-block {
  display: block;
  clear: both;

  &:after {
    clear: both;
  }
}

.button-full,
.button-full > .button {
  display: block;
  margin-right: 0;
  margin-left: 0;
  border-right-width: 0;
  border-left-width: 0;
  border-radius: 0;
}

button.button-block,
button.button-full,
.button-full > button.button,
input.button.button-block  {
  width: 100%;
}

a.button {
  text-decoration: none;

  .icon:before,
  &.icon:before,
  &.icon-left:before,
  &.icon-right:before {
    margin-top: 2px;
  }
}

.button.disabled,
.button[disabled] {
  opacity: .4;
  cursor: default !important;
  pointer-events: none;
}


================================================
FILE: server/ionic/scss-live/_checkbox.scss
================================================

/**
 * Checkbox
 * --------------------------------------------------
 */

.checkbox {
  // set the color defaults
  @include checkbox-style($checkbox-off-border-default, $checkbox-on-bg-default, $checkbox-on-border-default);

  position: relative;
  display: inline-block;
  padding: ($checkbox-height / 4) ($checkbox-width / 4);
  cursor: pointer;
}
.checkbox-light  {
  @include checkbox-style($checkbox-off-border-light, $checkbox-on-bg-light, $checkbox-off-border-light);
}
.checkbox-stable  {
  @include checkbox-style($checkbox-off-border-stable, $checkbox-on-bg-stable, $checkbox-off-border-stable);
}
.checkbox-positive  {
  @include checkbox-style($checkbox-off-border-positive, $checkbox-on-bg-positive, $checkbox-off-border-positive);
}
.checkbox-calm  {
  @include checkbox-style($checkbox-off-border-calm, $checkbox-on-bg-calm, $checkbox-off-border-calm);
}
.checkbox-assertive  {
  @include checkbox-style($checkbox-off-border-assertive, $checkbox-on-bg-assertive, $checkbox-off-border-assertive);
}
.checkbox-balanced  {
  @include checkbox-style($checkbox-off-border-balanced, $checkbox-on-bg-balanced, $checkbox-off-border-balanced);
}
.checkbox-energized{
  @include checkbox-style($checkbox-off-border-energized, $checkbox-on-bg-energized, $checkbox-off-border-energized);
}
.checkbox-royal  {
  @include checkbox-style($checkbox-off-border-royal, $checkbox-on-bg-royal, $checkbox-off-border-royal);
}
.checkbox-dark  {
  @include checkbox-style($checkbox-off-border-dark, $checkbox-on-bg-dark, $checkbox-off-border-dark);
}

.checkbox input:disabled:before,
.checkbox input:disabled + .checkbox-icon:before {
  border-color: $checkbox-off-border-light;
}

.checkbox input:disabled:checked:before,
.checkbox input:disabled:checked + .checkbox-icon:before {
  background: $checkbox-on-bg-light;
}


.checkbox.checkbox-input-hidden input {
  display: none !important;
}

.checkbox input,
.checkbox-icon {
  position: relative;
  width: $checkbox-width;
  height: $checkbox-height;
  display: block;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;

  &:before {
    // what the checkbox looks like when its not checked
    display: table;
    width: 100%;
    height: 100%;
    border-width: $checkbox-border-width;
    border-style: solid;
    border-radius: $checkbox-border-radius;
    background: $checkbox-off-bg-color;
    content: ' ';
    @include transition(background-color 20ms ease-in-out);
  }
}

.checkbox input:checked:before,
input:checked + .checkbox-icon:before {
  border-width: $checkbox-border-width + 1;
}

// the checkmark within the box
.checkbox input:after,
.checkbox-icon:after {
  @include transition(opacity .05s ease-in-out);
  @include rotate(-45deg);
  position: absolute;
  top: 33%;
  left: 25%;
  display: table;
  width: ($checkbox-width / 2);
  height: ($checkbox-width / 4) - 1;
  border: $checkbox-check-width solid $checkbox-check-color;
  border-top: 0;
  border-right: 0;
  content: ' ';
  opacity: 0;
}

.platform-android .checkbox-platform input:before,
.platform-android .checkbox-platform .checkbox-icon:before,
.checkbox-square input:before,
.checkbox-square .checkbox-icon:before {
  border-radius: 2px;
  width: 72%;
  height: 72%;
  margin-top: 14%;
  margin-left: 14%;
  border-width: 2px;
}

.platform-android .checkbox-platform input:after,
.platform-android .checkbox-platform .checkbox-icon:after,
.checkbox-square input:after,
.checkbox-square .checkbox-icon:after {
  border-width: 2px;
  top: 19%;
  left: 25%;
  width: ($checkbox-width / 2) - 1;
  height: 7px;
}

.grade-c .checkbox input:after,
.grade-c .checkbox-icon:after {
  @include rotate(0);
  top: 3px;
  left: 4px;
  border: none;
  color: $checkbox-check-color;
  content: '\2713';
  font-weight: bold;
  font-size: 20px;
}

// what the checkmark looks like when its checked
.checkbox input:checked:after,
input:checked + .checkbox-icon:after {
  opacity: 1;
}

// make sure item content have enough padding on left to fit the checkbox
.item-checkbox {
  padding-left: ($item-padding * 2) + $checkbox-width;

  &.active {
    box-shadow: none;
  }
}

// position the checkbox to the left within an item
.item-checkbox .checkbox {
  position: absolute;
  top: 50%;
  right: $item-padding / 2;
  left: $item-padding / 2;
  z-index: $z-index-item-checkbox;
  margin-top: (($checkbox-height + ($checkbox-height / 2)) / 2) * -1;
}


.item-checkbox.item-checkbox-right {
  padding-right: ($item-padding * 2) + $checkbox-width;
  padding-left: $item-padding;
}

.item-checkbox-right .checkbox input,
.item-checkbox-right .checkbox-icon {
  float: right;
}


================================================
FILE: server/ionic/scss-live/_form.scss
================================================
/**
 * Forms
 * --------------------------------------------------
 */

// Make all forms have space below them
form {
  margin: 0 0 $line-height-base;
}

// Groups of fields with labels on top (legends)
legend {
  display: block;
  margin-bottom: $line-height-base;
  padding: 0;
  width: 100%;
  border: $input-border-width solid $input-border;
  color: $dark;
  font-size: $font-size-base * 1.5;
  line-height: $line-height-base * 2;

  small {
    color: $stable;
    font-size: $line-height-base * .75;
  }
}

// Set font for forms
label,
input,
button,
select,
textarea {
  @include font-shorthand($font-size-base, normal, $line-height-base); // Set size, weight, line-height here
}
input,
button,
select,
textarea {
  font-family: $font-family-base; // And only set font-family here for those that need it (note the missing label element)
}


// Input List
// -------------------------------

.item-input {
  @include display-flex();
  @include align-items(center);
  position: relative;
  overflow: hidden;
  padding: 6px 0 5px 16px;

  input {
    @include border-radius(0);
    @include flex(1, 0, 220px);
    @include appearance(none);
    margin: 0;
    padding-right: 24px;
    background-color: transparent;
  }

  .button .icon {
    @include flex(0, 0, 24px);
    position: static;
    display: inline-block;
    height: auto;
    text-align: center;
    font-size: 16px;
  }

  .button-bar {
    @include border-radius(0);
    @include flex(1, 0, 220px);
    @include appearance(none);
  }

  .icon {
    min-width: 14px;
  }
}

.item-input-inset {
  @include display-flex();
  @include align-items(center);
  position: relative;
  overflow: hidden;
  padding: ($item-padding / 3) * 2;
}

.item-input-wrapper {
  @include display-flex();
  @include flex(1, 0);
  @include align-items(center);
  @include border-radius(4px);
  padding-right: 8px;
  padding-left: 8px;
  background: #eee;
}

.item-input-inset .item-input-wrapper input {
  padding-left: 4px;
  height: 29px;
  background: transparent;
  line-height: 18px;
}

.item-input-wrapper ~ .button {
  margin-left: ($item-padding / 3) * 2;
}

.input-label {
  @include flex(1, 0, 100px);
  display: table;
  padding: 7px 10px 7px 0px;
  max-width: 200px;
  width: 35%;
  color: $input-label-color;
  font-size: 16px;
}

.placeholder-icon {
  color: #aaa;
  &:first-child {
    padding-right: 6px;
  }
  &:last-child {
    padding-left: 6px;
  }
}

.item-stacked-label {
  display: block;
  background-color: transparent;
  box-shadow: none;

  .input-label, .icon {
    display: inline-block;
    padding: 4px 0 0 0px;
    vertical-align: middle;
  }
}

.item-stacked-label input,
.item-stacked-label textarea {
  @include border-radius(2px);
  padding: 4px 8px 3px 0;
  border: none;
  background-color: $input-bg;
}
.item-stacked-label input {
  overflow: hidden;
  height: $line-height-computed + $font-size-base + 12px;
}

.item-floating-label {
  display: block;
  background-color: transparent;
  box-shadow: none;

  .input-label {
    position: relative;
    padding: 5px 0 0 0;
    opacity: 0;
    top: 10px;
    @include transition(opacity .15s ease-in, top .2s linear);

    &.has-input {
      opacity: 1;
      top: 0;
      @include transition(opacity .15s ease-in, top .2s linear);
    }
  }
}


// Form Controls
// -------------------------------

// Shared size and type resets
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"] {
  display: block;
  padding-top: 2px;
  padding-left: 0;
  height: $line-height-computed + $font-size-base;
  color: $input-color;
  vertical-align: middle;
  font-size: $font-size-base;
  line-height: $font-size-base + 2;
}

.platform-ios,
.platform-android {
  input[type="datetime-local"],
  input[type="date"],
  input[type="month"],
  input[type="time"],
  input[type="week"] {
    padding-top: 8px;
  }
}

input,
textarea {
  width: 100%;
}
textarea {
  padding-left: 0;
  @include placeholder($input-color-placeholder, -3px);
}

// Reset height since textareas have rows
textarea {
  height: auto;
}

// Everything else
textarea,
input[type="text"],
input[type="password"],
input[type="datetime"],
input[type="datetime-local"],
input[type="date"],
input[type="month"],
input[type="time"],
input[type="week"],
input[type="number"],
input[type="email"],
input[type="url"],
input[type="search"],
input[type="tel"],
input[type="color"] {
  border: 0;
}

// Position radios and checkboxes better
input[type="radio"],
input[type="checkbox"] {
  margin: 0;
  line-height: normal;
}

// Reset width of input images, buttons, radios, checkboxes
input[type="file"],
input[type="image"],
input[type="submit"],
input[type="reset"],
input[type="button"],
input[type="radio"],
input[type="checkbox"] {
  width: auto; // Override of generic input selector
}

// Set the height of file to match text inputs
input[type="file"] {
  line-height: $input-height-base;
}

// Text input classes to hide text caret during scroll
.previous-input-focus,
.cloned-text-input + input,
.cloned-text-input + textarea {
  position: absolute !important;
  left: -9999px;
  width: 200px;
}


// Placeholder
// -------------------------------
input,
textarea {
  @include placeholder();
}


// DISABLED STATE
// -------------------------------

// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
input[readonly]:not(.cloned-text-input),
textarea[readonly]:not(.cloned-text-input),
select[readonly] {
  background-color: $input-bg-disabled;
  cursor: not-allowed;
}
// Explicitly reset the colors here
input[type="radio"][disabled],
input[type="checkbox"][disabled],
input[type="radio"][readonly],
input[type="checkbox"][readonly] {
  background-color: transparent;
}


================================================
FILE: server/ionic/scss-live/_grid.scss
================================================
/**
 * Grid
 * --------------------------------------------------
 * Using flexbox for the grid, inspired by Philip Walton:
 * http://philipwalton.github.io/solved-by-flexbox/demos/grids/
 * By default each .col within a .row will evenly take up
 * available width, and the height of each .col with take
 * up the height of the tallest .col in the same .row.
 */

.row {
  @include display-flex();
  padding: ($grid-padding-width / 2);
  width: 100%;
}

.row-wrap {
  @include flex-wrap(wrap);
}

.row + .row {
  margin-top: ($grid-padding-width / 2) * -1;
  padding-top: 0;
}

.col {
  @include flex(1);
  display: block;
  padding: ($grid-padding-width / 2);
  width: 100%;
}


/* Vertically Align Columns */
/* .row-* vertically aligns every .col in the .row */
.row-top {
  @include align-items(flex-start);
}
.row-bottom {
  @include align-items(flex-end);
}
.row-center {
  @include align-items(center);
}
.row-stretch {
  @include align-items(stretch);
}
.row-baseline {
  @include align-items(baseline);
}

/* .col-* vertically aligns an individual .col */
.col-top {
  @include align-self(flex-start);
}
.col-bottom {
  @include align-self(flex-end);
}
.col-center {
  @include align-self(center);
}

/* Column Offsets */
.col-offset-10 {
  margin-left: 10%;
}
.col-offset-20 {
  margin-left: 20%;
}
.col-offset-25 {
  margin-left: 25%;
}
.col-offset-33, .col-offset-34 {
  margin-left: 33.3333%;
}
.col-offset-50 {
  margin-left: 50%;
}
.col-offset-66, .col-offset-67 {
  margin-left: 66.6666%;
}
.col-offset-75 {
  margin-left: 75%;
}
.col-offset-80 {
  margin-left: 80%;
}
.col-offset-90 {
  margin-left: 90%;
}


/* Explicit Column Percent Sizes */
/* By default each grid column will evenly distribute */
/* across the grid. However, you can specify individual */
/* columns to take up a certain size of the available area */
.col-10 {
  @include flex(0, 0, 10%);
  max-width: 10%;
}
.col-20 {
  @include flex(0, 0, 20%);
  max-width: 20%;
}
.col-25 {
  @include flex(0, 0, 25%);
  max-width: 25%;
}
.col-33, .col-34 {
  @include flex(0, 0, 33.3333%);
  max-width: 33.3333%;
}
.col-50 {
  @include flex(0, 0, 50%);
  max-width: 50%;
}
.col-66, .col-67 {
  @include flex(0, 0, 66.6666%);
  max-width: 66.6666%;
}
.col-75 {
  @include flex(0, 0, 75%);
  max-width: 75%;
}
.col-80 {
  @include flex(0, 0, 80%);
  max-width: 80%;
}
.col-90 {
  @include flex(0, 0, 90%);
  max-width: 90%;
}


/* Responsive Grid Classes */
/* Adding a class of responsive-X to a row */
/* will trigger the flex-direction to */
/* change to column and add some margin */
/* to any columns in the row for clearity */

@include responsive-grid-break('.responsive-sm', $grid-responsive-sm-break);
@include responsive-grid-break('.responsive-md', $grid-responsive-md-break);
@include responsive-grid-break('.responsive-lg', $grid-responsive-lg-break);


================================================
FILE: server/ionic/scss-live/_items.scss
================================================
/**
 * Items
 * --------------------------------------------------
 */

.item {
  @include item-style($item-default-bg, $item-default-border, $item-default-text);

  position: relative;
  z-index: $z-index-item; // Make sure the borders and stuff don't get hidden by children
  display: block;

  margin: $item-border-width * -1;
  padding: $item-padding;

  border-width: $item-border-width;
  border-style: solid;
  font-size: $item-font-size;

  h2 {
    margin: 0 0 2px 0;
    font-size: 16px;
    font-weight: normal;
  }
  h3 {
    margin: 0 0 4px 0;
    font-size: 14px;
  }
  h4 {
    margin: 0 0 4px 0;
    font-size: 12px;
  }
  h5, h6 {
    margin: 0 0 3px 0;
    font-size: 10px;
  }
  p {
    color: #666;
    font-size: 14px;
    margin-bottom: 2px;
  }

  h1:last-child,
  h2:last-child,
  h3:last-child,
  h4:last-child,
  h5:last-child,
  h6:last-child,
  p:last-child {
    margin-bottom: 0;
  }

  // Align badges within items
  .badge {
    @include display-flex();
    position: absolute;
    top: $item-padding;
    right: ($item-padding * 2);
  }
  &.item-button-right .badge {
    right: ($item-padding * 2) + 35;
  }
  &.item-divider .badge {
    top: ceil($item-padding / 2);
  }
  .badge + .badge {
    margin-right: 5px;
  }

  // Different themes for items
  &.item-light {
    @include item-style($item-light-bg, $item-light-border, $item-light-text);
  }
  &.item-stable {
    @include item-style($item-stable-bg, $item-stable-border, $item-stable-text);
  }
  &.item-positive {
    @include item-style($item-positive-bg, $item-positive-border, $item-positive-text);
  }
  &.item-calm {
    @include item-style($item-calm-bg, $item-calm-border, $item-calm-text);
  }
  &.item-assertive {
    @include item-style($item-assertive-bg, $item-assertive-border, $item-assertive-text);
  }
  &.item-balanced {
    @include item-style($item-balanced-bg, $item-balanced-border, $item-balanced-text);
  }
  &.item-energized {
    @include item-style($item-energized-bg, $item-energized-border, $item-energized-text);
  }
  &.item-royal {
    @include item-style($item-royal-bg, $item-royal-border, $item-royal-text);
  }
  &.item-dark {
    @include item-style($item-dark-bg, $item-dark-border, $item-dark-text);
  }

  &[ng-click]:hover {
    cursor: pointer;
  }

}

.list-borderless .item,
.item-borderless {
  border-width: 0;
}

// Link and Button Active States
.item.active,
.item.activated,
.item-complex.active .item-content,
.item-complex.activated .item-content,
.item .item-content.active,
.item .item-content.activated {
  @include item-active-style($item-default-active-bg, $item-default-active-border);

  // Different active themes for <a> and <button> items
  &.item-light {
    @include item-active-style($item-light-active-bg, $item-light-active-border);
  }
  &.item-stable {
    @include item-active-style($item-stable-active-bg, $item-stable-active-border);
  }
  &.item-positive {
    @include item-active-style($item-positive-active-bg, $item-positive-active-border);
  }
  &.item-calm {
    @include item-active-style($item-calm-active-bg, $item-calm-active-border);
  }
  &.item-assertive {
    @include item-active-style($item-assertive-active-bg, $item-assertive-active-border);
  }
  &.item-balanced {
    @include item-active-style($item-balanced-active-bg, $item-balanced-active-border);
  }
  &.item-energized {
    @include item-active-style($item-energized-active-bg, $item-energized-active-border);
  }
  &.item-royal {
    @include item-active-style($item-royal-active-bg, $item-royal-active-border);
  }
  &.item-dark {
    @include item-active-style($item-dark-active-bg, $item-dark-active-border);
  }
}

// Handle text overflow
.item,
.item h1,
.item h2,
.item h3,
.item h4,
.item h5,
.item h6,
.item p,
.item-content,
.item-content h1,
.item-content h2,
.item-content h3,
.item-content h4,
.item-content h5,
.item-content h6,
.item-content p {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

// Linked list items
a.item {
  color: inherit;
  text-decoration: none;

  &:hover,
  &:focus {
    text-decoration: none;
  }
}


/**
 * Complex Items
 * --------------------------------------------------
 * Adding .item-complex allows the .item to be slidable and
 * have options underneath the button, but also requires an
 * additional .item-content element inside .item.
 * Basically .item-complex removes any default settings which
 * .item added, so that .item-content looks them as just .item.
 */

.item-complex,
a.item.item-complex,
button.item.item-complex {
  padding: 0;
}
.item-complex .item-content,
.item-radio .item-content {
  position: relative;
  z-index: $z-index-item;
  padding: $item-padding (ceil( ($item-padding * 3) + ($item-padding / 3) ) - 5) $item-padding $item-padding;
  border: none;
  background-color: white;
}

a.item-content {
  display: block;
  color: inherit;
  text-decoration: none;
}

.item-text-wrap .item,
.item-text-wrap .item-content,
.item-text-wrap,
.item-text-wrap h1,
.item-text-wrap h2,
.item-text-wrap h3,
.item-text-wrap h4,
.item-text-wrap h5,
.item-text-wrap h6,
.item-text-wrap p,
.item-complex.item-text-wrap .item-content,
.item-body h1,
.item-body h2,
.item-body h3,
.item-body h4,
.item-body h5,
.item-body h6,
.item-body p {
  overflow: visible;
  white-space: normal;
}
.item-complex.item-text-wrap,
.item-complex.item-text-wrap h1,
.item-complex.item-text-wrap h2,
.item-complex.item-text-wrap h3,
.item-complex.item-text-wrap h4,
.item-complex.item-text-wrap h5,
.item-complex.item-text-wrap h6,
.item-complex.item-text-wrap p {
  overflow: visible;
  white-space: normal;
}

// Link and Button Active States

.item-complex{
  // Stylized items
  &.item-light > .item-content{
    @include item-style($item-light-bg, $item-light-border, $item-light-text);
    &.active, &:active {
      @include item-active-style($item-light-active-bg, $item-light-active-border);
    }
  }
  &.item-stable > .item-content{
    @include item-style($item-stable-bg, $item-stable-border, $item-stable-text);
    &.active, &:active {
      @include item-active-style($item-stable-active-bg, $item-stable-active-border);
    }
  }
  &.item-positive > .item-content{
    @include item-style($item-positive-bg, $item-positive-border, $item-positive-text);
    &.active, &:active {
      @include item-active-style($item-positive-active-bg, $item-positive-active-border);
    }
  }
  &.item-calm > .item-content{
    @include item-style($item-calm-bg, $item-calm-border, $item-calm-text);
    &.active, &:active {
      @include item-active-style($item-calm-active-bg, $item-calm-active-border);
    }
  }
  &.item-assertive > .item-content{
    @include item-style($item-assertive-bg, $item-assertive-border, $item-assertive-text);
    &.active, &:active {
      @include item-active-style($item-assertive-active-bg, $item-assertive-active-border);
    }
  }
  &.item-balanced > .item-content{
    @include item-style($item-balanced-bg, $item-balanced-border, $item-balanced-text);
    &.active, &:active {
      @include item-active-style($item-balanced-active-bg, $item-balanced-active-border);
    }
  }
  &.item-energized > .item-content{
    @include item-style($item-energized-bg, $item-energized-border, $item-energized-text);
    &.active, &:active {
      @include item-active-style($item-energized-active-bg, $item-energized-active-border);
    }
  }
  &.item-royal > .item-content{
    @include item-style($item-royal-bg, $item-royal-border, $item-royal-text);
    &.active, &:active {
      @include item-active-style($item-royal-active-bg, $item-royal-active-border);
    }
  }
  &.item-dark > .item-content{
    @include item-style($item-dark-bg, $item-dark-border, $item-dark-text);
    &.active, &:active {
      @include item-active-style($item-dark-active-bg, $item-dark-active-border);
    }
  }
}


/**
 * Item Icons
 * --------------------------------------------------
 */

.item-icon-left .icon,
.item-icon-right .icon {
  @include display-flex();
  @include align-items(center);
  position: absolute;
  top: 0;
  height: 100%;
  font-size: $item-icon-font-size;

  &:before {
    display: block;
    width: $item-icon-font-size;
    text-align: center;
  }
}

.item .fill-icon {
  min-width: $item-icon-fill-font-size + 2;
  min-height: $item-icon-fill-font-size + 2;
  font-size: $item-icon-fill-font-size;
}

.item-icon-left {
  padding-left: ceil( ($item-padding * 3) + ($item-padding / 3) );

  .icon {
    left: ceil( ($item-padding / 3) * 2);
  }
}
.item-complex.item-icon-left {
  padding-left: 0;

  .item-content {
    padding-left: ceil( ($item-padding * 3) + ($item-padding / 3) );
  }
}

.item-icon-right {
  padding-right: ceil( ($item-padding * 3) + ($item-padding / 3) );

  .icon {
    right: ceil( ($item-padding / 3) * 2);
  }
}
.item-complex.item-icon-right {
  padding-right: 0;

  .item-content {
    padding-right: ceil( ($item-padding * 3) + ($item-padding / 3) );
  }
}

.item-icon-left.item-icon-right .icon:first-child {
  right: auto;
}
.item-icon-left.item-icon-right .icon:last-child,
.item-icon-left .item-delete .icon {
  left: auto;
}

.item-icon-left .icon-accessory,
.item-icon-right .icon-accessory {
  color: $item-icon-accessory-color;
  font-size: $item-icon-accessory-font-size;
}
.item-icon-left .icon-accessory {
  left: floor($item-padding / 5);
}
.item-icon-right .icon-accessory {
  right: floor($item-padding / 5);
}


/**
 * Item Button
 * --------------------------------------------------
 * An item button is a child button inside an .item (not the entire .item)
 */

.item-button-left {
  padding-left: ceil($item-padding * 4.5);
}

.item-button-left > .button,
.item-button-left .item-content > .button {
  @include display-flex();
  @include align-items(center);
  position: absolute;
  top: ceil($item-padding / 2);
  left: ceil( ($item-padding / 3) * 2);
  min-width: $item-icon-font-size + ($button-border-width * 2);
  min-height: $item-icon-font-size + ($button-border-width * 2);
  font-size: $item-button-font-size;
  line-height: $item-button-line-height;

  .icon:before {
    position: relative;
    left: auto;
    width: auto;
    line-height: $item-icon-font-size - 1;
  }

  > .button {
    margin: 0px 2px;
    min-height: $item-icon-font-size + ($button-border-width * 2);
    font-size: $item-button-font-size;
    line-height: $item-button-line-height;
  }
}

.item-button-right,
a.item.item-button-right,
button.item.item-button-right {
  padding-right: $item-padding * 5;
}

.item-button-right > .button,
.item-button-right .item-content > .button,
.item-button-right > .buttons,
.item-button-right .item-content > .buttons {
  @include display-flex();
  @include align-items(center);
  position: absolute;
  top: ceil($item-padding / 2);
  right: $item-padding;
  min-width: $item-icon-font-size + ($button-border-width * 2);
  min-height: $item-icon-font-size + ($button-border-width * 2);
  font-size: $item-button-font-size;
  line-height: $item-button-line-height;

  .icon:before {
    position: relative;
    left: auto;
    width: auto;
    line-height: $item-icon-font-size - 1;
  }

  > .button {
    margin: 0px 2px;
    min-width: $item-icon-font-size + ($button-border-width * 2);
    min-height: $item-icon-font-size + ($button-border-width * 2);
    font-size: $item-button-font-size;
    line-height: $item-button-line-height;
  }
}


// Item Avatar
// -------------------------------

.item-avatar,
.item-avatar .item-content,
.item-avatar-left,
.item-avatar-left .item-content {
  padding-left: $item-avatar-width + ($item-padding * 2);
  min-height: $item-avatar-width + ($item-padding * 2);

  > img:first-child,
  .item-image {
    position: absolute;
    top: $item-padding;
    left: $item-padding;
    max-width: $item-avatar-width;
    max-height: $item-avatar-height;
    width: 100%;
    border-radius: $item-avatar-border-radius;
  }
}

.item-avatar-right,
.item-avatar-right .item-content {
  padding-right: $item-avatar-width + ($item-padding * 2);
  min-height: $item-avatar-width + ($item-padding * 2);

  > img:first-child,
  .item-image {
    position: absolute;
    top: $item-padding;
    right: $item-padding;
    max-width: $item-avatar-width;
    max-height: $item-avatar-height;
    width: 100%;
    border-radius: $item-avatar-border-radius;
  }
}


// Item Thumbnails
// -------------------------------

.item-thumbnail-left,
.item-thumbnail-left .item-content {
  padding-top: $item-padding / 2;
  padding-left: $item-thumbnail-width + $item-thumbnail-margin + $item-padding;
  min-height: $item-thumbnail-height + ($item-thumbnail-margin * 2);

  > img:first-child,
  .item-image {
    position: absolute;
    top: $item-thumbnail-margin;
    left: $item-thumbnail-margin;
    max-width: $item-thumbnail-width;
    max-height: $item-thumbnail-height;
    width: 100%;
  }
}
.item-avatar.item-complex,
.item-avatar-left.item-complex,
.item-thumbnail-left.item-complex {
  padding-top: 0;
  padding-left: 0;
}

.item-thumbnail-right,
.item-thumbnail-right .item-content {
  padding-top: $item-padding / 2;
  padding-right: $item-thumbnail-width + $item-thumbnail-margin + $item-padding;
  min-height: $item-thumbnail-height + ($item-thumbnail-margin * 2);

  > img:first-child,
  .item-image {
    position: absolute;
    top: $item-thumbnail-margin;
    right: $item-thumbnail-margin;
    max-width: $item-thumbnail-width;
    max-height: $item-thumbnail-height;
    width: 100%;
  }
}
.item-avatar-right.item-complex,
.item-thumbnail-right.item-complex {
  padding-top: 0;
  padding-right: 0;
}


// Item Image
// -------------------------------

.item-image {
  padding: 0;
  text-align: center;

  img:first-child, .list-img {
    width: 100%;
    vertical-align: middle;
  }
}


// Item Body
// -------------------------------

.item-body {
  overflow: auto;
  padding: $item-padding;
  text-overflow: inherit;
  white-space: normal;

  h1, h2, h3, h4, h5, h6, p {
    margin-top: $item-padding;
    margin-bottom: $item-padding;
  }
}


// Item Divider
// -------------------------------

.item-divider {
  padding-top: ceil($item-padding / 2);
  padding-bottom: ceil($item-padding / 2);
  min-height: 30px;
  background-color: $item-divider-bg;
  color: $item-divider-color;
  font-weight: 500;
}

.platform-ios .item-divider-platform,
.item-divider-ios {
  padding-top: 26px;
  text-transform: uppercase;
  font-weight: 300;
  font-size: 13px;
  background-color: #efeff4;
  color: #555;
}

.platform-android .item-divider-platform,
.item-divider-android {
  font-weight: 300;
  font-size: 13px;
}


// Item Note
// -------------------------------

.item-note {
  float: right;
  color: #aaa;
  font-size: 14px;
}


// Item Editing
// -------------------------------

.item-left-editable .item-content,
.item-right-editable .item-content {
  // setup standard transition settings
  @include transition-duration( $item-edit-transition-duration );
  @include transition-timing-function( $item-edit-transition-function );
  -webkit-transition-property: -webkit-transform;
     -moz-transition-property: -moz-transform;
          transition-property: transform;
}

.list-left-editing .item-left-editable .item-content,
.item-left-editing.item-left-editable .item-content {
  // actively editing the left side of the item
  @include translate3d($item-left-edit-open-width, 0, 0);
}

.list-right-editing .item-right-editable .item-content,
.item-right-editing.item-right-editable .item-content {
  // actively editing the left side of the item
  @include translate3d(-$item-right-edit-open-width, 0, 0);
}

.item-remove-animate {
  &.ng-leave {
    @include transition-duration( $item-remove-transition-duration );
  }
  &.ng-leave .item-content,
  &.ng-leave:last-of-type {
    @include transition-duration( $item-remove-transition-duration );
    @include transition-timing-function( $item-remove-transition-function );
    @include transition-property( all );
  }

  &.ng-leave.ng-leave-active .item-content {
    opacity:0;
    -webkit-transform: translate3d(-100%, 0, 0) !important;
    transform: translate3d(-100%, 0, 0) !important;
  }
  &.ng-leave.ng-leave-active:last-of-type {
    opacity: 0;
  }

  &.ng-leave.ng-leave-active ~ ion-item:not(.ng-leave) {
    -webkit-transform: translate3d(0, unquote('-webkit-calc(-100% + 1px)'), 0);
    transform: translate3d(0, calc(-100% + 1px), 0);
    @include transition-duration( $item-remove-transition-duration );
    @include transition-timing-function( $item-remove-descendents-transition-function );
    @include transition-property( all );
  }
}



// Item Left Edit Button
// -------------------------------

.item-left-edit {
  @include transition(all $item-edit-transition-function $item-edit-transition-duration / 2);
  position: absolute;
  top: 0;
  left: 0;
  z-index: $z-index-item-edit;
  width: $item-left-edit-open-width;
  height: 100%;
  line-height: 100%;

  .button {
    height: 100%;

    &.icon {
      @include display-flex();
      @include align-items(center);
      position: absolute;
      top: 0;
      height: 100%;
    }
  }

  display: none;
  opacity: 0;
  @include translate3d( ($item-left-edit-left - $item-left-edit-open-width) / 2, 0, 0);
  &.visible {
    display: block;
    &.active {
      opacity: 1;
      @include translate3d($item-left-edit-left, 0, 0);
    }
  }
}
.list-left-editing .item-left-edit {
  @include transition-delay($item-edit-transition-duration / 2);
}

// Item Delete (Left side edit button)
// -------------------------------

.item-delete .button.icon {
  color: $item-delete-icon-color;
  font-size: $item-delete-icon-size;

  &:hover {
    opacity: .7;
  }
}


// Item Right Edit Button
// -------------------------------

.item-right-edit {
  @include transition(all $item-edit-transition-function $item-edit-transition-duration / 2);
  position: absolute;
  top: 0;
  right: 0;
  z-index: 0;
  width: $item-right-edit-open-width *  1.5;
  height: 100%;
  background: inherit;
  padding-left: 20px;

  .button {
    min-width: $item-right-edit-open-width;
    height: 100%;

    &.icon {
      @include display-flex();
      @include align-items(center);
      position: absolute;
      top: 0;
      height: 100%;
      font-size: $item-reorder-icon-size;
    }
  }

  display: none;
  opacity: 0;
  @include translate3d($item-right-edit-open-width / 2, 0, 0);
  &.visible {
    display: block;
    z-index: $z-index-item-reorder;
    &.active {
      opacity: 1;
      @include translate3d(0, 0, 0);
    }
  }
}
.list-right-editing .item-right-edit {
  @include transition-delay($item-edit-transition-duration / 2);
}


// Item Reordering (Right side edit button)
// -------------------------------

.item-reorder .button.icon {
  color: $item-reorder-icon-color;
  font-size: $item-reorder-icon-size;
}

.item-reordering {
  // item is actively being reordered
  position: absolute;
  left: 0;
  top: 0;
  z-index: $z-index-item-reordering;
  width: 100%;
  box-shadow: 0px 0px 10px 0px #aaa;

  .item-reorder {
    z-index: 1;
  }
}

.item-placeholder {
  // placeholder for the item that's being reordered
  opacity: 0.7;
}


/**
 * The hidden right-side buttons that can be exposed under a list item
 * with dragging.
 */
.item-options {
  position: absolute;
  top: 0;
  right: 0;
  z-index: $z-index-item-options;
  height: 100%;

  .button {
    height: 100%;
    border: none;
    border-radius: 0;
    @include display-inline-flex();
    @include align-items(center);

    &:before{
      margin: 0 auto;
    }
  }
}


================================================
FILE: server/ionic/scss-live/_list.scss
================================================

/**
 * Lists
 * --------------------------------------------------
 */

.list {
  position: relative;
  padding-top: $item-border-width;
  padding-bottom: $item-border-width;
  padding-left: 0; // reset padding because ul and ol
  margin-bottom: 20px;
}
.list:last-child {
  margin-bottom: 0px;
  &.card{
    margin-bottom:40px;
  }
}


/**
 * List Header
 * --------------------------------------------------
 */

.list-header {
  margin-top: $list-header-margin-top;
  padding: $list-header-padding;
  background-color: $list-header-bg;
  color: $list-header-color;
  font-weight: bold;
}

// when its a card make sure it doesn't duplicate top and bottom borders
.card.list .list-item {
  padding-right: 1px;
  padding-left: 1px;
}


/**
 * Cards and Inset Lists
 * --------------------------------------------------
 * A card and list-inset are close to the same thing, except a card as a box shadow.
 */

.card,
.list-inset {
  overflow: hidden;
  margin: ($content-padding * 2) $content-padding;
  border-radius: $card-border-radius;
  background-color: $card-body-bg;
}

.card {
  padding-top: $item-border-width;
  padding-bottom: $item-border-width;
  box-shadow: $card-box-shadow;

  .item {
    border-left: 0;
    border-right: 0;
  }
  .item:first-child {
    border-top: 0;
  }
  .item:last-child {
    border-bottom: 0;
  }
}

.padding {
  .card, .list-inset {
    margin-left: 0;
    margin-right: 0;
  }
}

.card .item,
.list-inset .item,
.padding > .list .item
{
  &:first-child {
    border-top-left-radius: $card-border-radius;
    border-top-right-radius: $card-border-radius;

    .item-content {
      border-top-left-radius: $card-border-radius;
      border-top-right-radius: $card-border-radius;
    }
  }
  &:last-child {
    border-bottom-right-radius: $card-border-radius;
    border-bottom-left-radius: $card-border-radius;

    .item-content {
      border-bottom-right-radius: $card-border-radius;
      border-bottom-left-radius: $card-border-radius;
    }
  }
}

.card .item:last-child,
.list-inset .item:last-child {
  margin-bottom: $item-border-width * -1;
}

.card .item,
.list-inset .item,
.padding > .list .item,
.padding-horizontal > .list .item {
  margin-right: 0;
  margin-left: 0;

  &.item-input input {
    padding-right: 44px;
  }
}
.padding-left > .list .item {
  margin-left: 0;
}
.padding-right > .list .item {
  margin-right: 0;
}


================================================
FILE: server/ionic/scss-live/_loaders.scss
================================================
/**
 * Loaders (Spinners)
 * --------------------------------------------------
 */

svg.loader {
  width: 28px;
  height: 28px;
  stroke: #333;
  fill: #333;
}

.loader-ios,
.loader-ios-small {

  line {
    stroke: #69717d;
  }

}

.loader-android {

  circle {
    stroke: #4b8bf4;
  }

}


================================================
FILE: server/ionic/scss-live/_loading.scss
================================================

/**
 * Loading
 * --------------------------------------------------
 */

.loading-container {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;

  z-index: $z-index-loading;

  @include display-flex();
  @include justify-content(center);
  @include align-items(center);

  @include transition(0.2s opacity linear);
  visibility: hidden;
  opacity: 0;

  &:not(.visible) .icon {
    display: none;
  }
  &.visible {
    visibility: visible;
  }
  &.active {
    opacity: 1;
  }

  .loading {
    padding: $loading-padding;

    border-radius: $loading-border-radius;
    background-color: $loading-bg-color;

    color: $loading-text-color;

    text-align: center;
    text-overflow: ellipsis;
    font-size: $loading-font-size;

    h1, h2, h3, h4, h5, h6 {
      color: $loading-text-color;
    }
  }
}


================================================
FILE: server/ionic/scss-live/_menu.scss
================================================

/**
 * Menus
 * --------------------------------------------------
 * Side panel structure
 */

.menu {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: $z-index-menu;
  overflow: hidden;

  min-height: 100%;
  max-height: 100%;
  width: $menu-width;

  background-color: $menu-bg;

  .scroll-content {
    z-index: $z-index-menu-scroll-content;
  }

  .bar-header {
    z-index: $z-index-menu-bar-header;
  }
}

.menu-content {
  @include transform(none);
  box-shadow: $menu-side-shadow;
}

.menu-open .menu-content .pane,
.menu-open .menu-content .scroll-content {
  pointer-events: none;
}

.grade-b .menu-content,
.grade-c .menu-content {
  @include box-sizing(content-box);
  right: -1px;
  left: -1px;
  border-right: 1px solid #ccc;
  border-left: 1px solid #ccc;
  box-shadow: none;
}

.menu-left {
  left: 0;
}

.menu-right {
  right: 0;
}

.aside-open.aside-resizing .menu-right {
  display: none;
}

.menu-animated {
  @include transition-transform($menu-
Download .txt
gitextract_mcss25s2/

├── .bowerrc
├── .buildignore
├── .gitignore
├── .travis.yml
├── .yo-rc.json
├── Gruntfile.js
├── LICENSE.md
├── README.md
├── bower.json
├── client/
│   ├── .htaccess
│   ├── .jshintrc
│   ├── app/
│   │   ├── app.css
│   │   ├── app.js
│   │   ├── compiler/
│   │   │   ├── compiler.service.js
│   │   │   └── compiler.service.spec.js
│   │   ├── main/
│   │   │   ├── main.controller.js
│   │   │   ├── main.controller.spec.js
│   │   │   ├── main.css
│   │   │   ├── main.html
│   │   │   └── main.js
│   │   └── theme/
│   │       ├── theme.directive.js
│   │       └── theme.directive.spec.js
│   ├── components/
│   │   └── preview/
│   │       ├── preview-buttons.html
│   │       ├── preview-card.html
│   │       ├── preview-components.html
│   │       ├── preview-form.html
│   │       ├── preview-header.html
│   │       ├── preview-list.html
│   │       └── preview-tabs.html
│   ├── index.html
│   └── robots.txt
├── e2e/
│   └── main/
│       ├── main.po.js
│       └── main.spec.js
├── ionic-tailor.sketch
├── karma.conf.js
├── package.json
├── protractor.conf.js
└── server/
    ├── .jshintrc
    ├── api/
    │   ├── compile/
    │   │   ├── compile.controller.js
    │   │   ├── compile.model.js
    │   │   ├── compile.spec.js
    │   │   └── index.js
    │   └── themes/
    │       ├── index.js
    │       ├── themes.controller.js
    │       ├── themes.model.js
    │       └── themes.spec.js
    ├── app.js
    ├── components/
    │   └── errors/
    │       └── index.js
    ├── config/
    │   ├── environment/
    │   │   ├── development.js
    │   │   ├── index.js
    │   │   ├── production.js
    │   │   └── test.js
    │   └── express.js
    ├── ionic/
    │   ├── scss-live/
    │   │   ├── _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
    │   │   ├── _loaders.scss
    │   │   ├── _loading.scss
    │   │   ├── _menu.scss
    │   │   ├── _mixins.scss
    │   │   ├── _modal.scss
    │   │   ├── _platform.scss
    │   │   ├── _popover.scss
    │   │   ├── _popup.scss
    │   │   ├── _progress.scss
    │   │   ├── _radio.scss
    │   │   ├── _range.scss
    │   │   ├── _refresher.scss
    │   │   ├── _reset.scss
    │   │   ├── _scaffolding.scss
    │   │   ├── _select.scss
    │   │   ├── _slide-box.scss
    │   │   ├── _split-pane.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
    │   ├── scss-prod/
    │   │   ├── _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
    │   │   ├── _loaders.scss
    │   │   ├── _loading.scss
    │   │   ├── _menu.scss
    │   │   ├── _mixins.scss
    │   │   ├── _modal.scss
    │   │   ├── _platform.scss
    │   │   ├── _popover.scss
    │   │   ├── _popup.scss
    │   │   ├── _progress.scss
    │   │   ├── _radio.scss
    │   │   ├── _range.scss
    │   │   ├── _refresher.scss
    │   │   ├── _reset.scss
    │   │   ├── _scaffolding.scss
    │   │   ├── _select.scss
    │   │   ├── _slide-box.scss
    │   │   ├── _split-pane.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
    │   ├── scss_test/
    │   │   ├── _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
    │   │   ├── _type.scss
    │   │   ├── _util.scss
    │   │   ├── _variables.scss
    │   │   └── ionic.scss
    │   └── tmp/
    │       ├── ionic-Zk2IRRDU4.app.css
    │       └── ionic-ZkD6jCwL4.app.css
    ├── routes.js
    └── views/
        └── 404.html
Download .txt
SYMBOL INDEX (5 symbols across 3 files)

FILE: server/api/compile/compile.controller.js
  function getNightly (line 135) | function getNightly(postData) {
  function CompileSass (line 191) | function CompileSass(outputString, dateID) {
  function handleError (line 209) | function handleError(res, err) {

FILE: server/api/themes/themes.controller.js
  function handleError (line 57) | function handleError(res, err) {

FILE: server/config/environment/index.js
  function requiredProcessEnv (line 6) | function requiredProcessEnv(name) {
Condensed preview — 171 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,365K chars).
[
  {
    "path": ".bowerrc",
    "chars": 47,
    "preview": "{\n    \"directory\": \"client/bower_components\"\n}\n"
  },
  {
    "path": ".buildignore",
    "chars": 8,
    "preview": "*.coffee"
  },
  {
    "path": ".gitignore",
    "chars": 80,
    "preview": "dist\nnode_modules\n.idea\n.tmp\nclient/bower_components\nserver/config/local.env.js\n"
  },
  {
    "path": ".travis.yml",
    "chars": 134,
    "preview": "language: node_js\nnode_js:\n  - '0.10'\n  - '0.11'\nbefore_script:\n  - npm install -g bower grunt-cli\n  - bower install\nser"
  },
  {
    "path": ".yo-rc.json",
    "chars": 847,
    "preview": "{\n  \"generator-angular-fullstack\": {\n    \"insertRoutes\": true,\n    \"registerRoutesFile\": \"server/routes.js\",\n    \"routes"
  },
  {
    "path": "Gruntfile.js",
    "chars": 18577,
    "preview": "'use strict';\n\nmodule.exports = function (grunt) {\n    var localConfig;\n    try {\n        localConfig = require('./serve"
  },
  {
    "path": "LICENSE.md",
    "chars": 1083,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Paolo Bernasconi\n\nPermission is hereby granted, free of charge, to any person "
  },
  {
    "path": "README.md",
    "chars": 1240,
    "preview": "[Ionic Theme Editor](http://ionic-theme-editor.herokuapp.com/)\n==================\n\n[![preview](https://github.com/pberna"
  },
  {
    "path": "bower.json",
    "chars": 751,
    "preview": "{\n    \"name\": \"projects\",\n    \"version\": \"0.0.1\",\n    \"dependencies\": {\n        \"angular\": \">=1.2.*\",\n        \"json3\": \""
  },
  {
    "path": "client/.htaccess",
    "chars": 24135,
    "preview": "# Apache Configuration File\n\n# (!) Using `.htaccess` files slows down Apache, therefore, if you have access\n# to the mai"
  },
  {
    "path": "client/.jshintrc",
    "chars": 664,
    "preview": "{\n  \"node\": true,\n  \"browser\": true,\n  \"esnext\": true,\n  \"bitwise\": true,\n  \"camelcase\": true,\n  \"curly\": true,\n  \"eqeqe"
  },
  {
    "path": "client/app/app.css",
    "chars": 16814,
    "preview": "/**************************************************\n * Bootstrap Fonts\n */\n\n@font-face {\n    font-family: 'Glyphicons Ha"
  },
  {
    "path": "client/app/app.js",
    "chars": 376,
    "preview": "'use strict';\n\nangular.module('projectsApp', [\n    'ngCookies',\n    'ngResource',\n    'ngSanitize',\n    'ui.router',\n   "
  },
  {
    "path": "client/app/compiler/compiler.service.js",
    "chars": 354,
    "preview": "'use strict';\n\nangular.module('projectsApp')\n    .service('Compiler', function ($http) {\n\n        return {\n            g"
  },
  {
    "path": "client/app/compiler/compiler.service.spec.js",
    "chars": 337,
    "preview": "'use strict';\n\ndescribe('Service: compiler', function () {\n\n  // load the service's module\n  beforeEach(module('projects"
  },
  {
    "path": "client/app/main/main.controller.js",
    "chars": 6686,
    "preview": "\"use strict\";\n\nangular.module(\"projectsApp\")\n\n    .controller(\"MainCtrl\", function ($scope, $timeout, ngDialog) {\n\n     "
  },
  {
    "path": "client/app/main/main.controller.spec.js",
    "chars": 714,
    "preview": "'use strict';\n\ndescribe('Controller: MainCtrl', function () {\n\n  // load the controller's module\n  beforeEach(module('pr"
  },
  {
    "path": "client/app/main/main.css",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "client/app/main/main.html",
    "chars": 13423,
    "preview": "<div class=\"content\">\n\n    <div class=\"side-panel\">\n        <header>\n            <img class=\"logo\" src=\"../assets/images"
  },
  {
    "path": "client/app/main/main.js",
    "chars": 232,
    "preview": "'use strict';\n\nangular.module('projectsApp')\n  .config(function ($stateProvider) {\n    $stateProvider\n      .state('main"
  },
  {
    "path": "client/app/theme/theme.directive.js",
    "chars": 1207,
    "preview": "'use strict';\n\nangular.module('projectsApp')\n    .directive('theme', function () {\n        return {\n            restrict"
  },
  {
    "path": "client/app/theme/theme.directive.spec.js",
    "chars": 476,
    "preview": "'use strict';\n\ndescribe('Directive: theme', function () {\n\n  // load the directive's module\n  beforeEach(module('project"
  },
  {
    "path": "client/components/preview/preview-buttons.html",
    "chars": 1746,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\""
  },
  {
    "path": "client/components/preview/preview-card.html",
    "chars": 1542,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\""
  },
  {
    "path": "client/components/preview/preview-components.html",
    "chars": 3412,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\""
  },
  {
    "path": "client/components/preview/preview-form.html",
    "chars": 2963,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\""
  },
  {
    "path": "client/components/preview/preview-header.html",
    "chars": 2252,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n    <link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\""
  },
  {
    "path": "client/components/preview/preview-list.html",
    "chars": 1995,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\">\n\t"
  },
  {
    "path": "client/components/preview/preview-tabs.html",
    "chars": 1366,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n\t<link rel=\"stylesheet\" href=\"http://code.ionicframework.com/nightly/css/ionic.min.css\">\n\t"
  },
  {
    "path": "client/index.html",
    "chars": 3691,
    "preview": "<!doctype html>\n<!--[if lt IE 7]>\n<html class=\"no-js lt-ie9 lt-ie8 lt-ie7\"> <![endif]-->\n<!--[if IE 7]>\n<html class=\"no-"
  },
  {
    "path": "client/robots.txt",
    "chars": 31,
    "preview": "# robotstxt.org\n\nUser-agent: *\n"
  },
  {
    "path": "e2e/main/main.po.js",
    "chars": 400,
    "preview": "/**\n * This file uses the Page Object pattern to define the main page for tests\n * https://docs.google.com/presentation/"
  },
  {
    "path": "e2e/main/main.spec.js",
    "chars": 429,
    "preview": "'use strict';\n\ndescribe('Main View', function() {\n  var page;\n\n  beforeEach(function() {\n    browser.get('/');\n    page "
  },
  {
    "path": "karma.conf.js",
    "chars": 2326,
    "preview": "// Karma configuration\n// http://karma-runner.github.io/0.10/config/configuration-file.html\n\nmodule.exports = function(c"
  },
  {
    "path": "package.json",
    "chars": 2690,
    "preview": "{\n  \"name\": \"projects\",\n  \"version\": \"0.0.0\",\n  \"main\": \"server/app.js\",\n  \"dependencies\": {\n    \"body-parser\": \"~1.0.0\""
  },
  {
    "path": "protractor.conf.js",
    "chars": 1598,
    "preview": "// Protractor configuration\n// https://github.com/angular/protractor/blob/master/referenceConf.js\n\n'use strict';\n\nexport"
  },
  {
    "path": "server/.jshintrc",
    "chars": 232,
    "preview": "{\n  \"node\": true,\n  \"esnext\": true,\n  \"bitwise\": true,\n  \"eqeqeq\": true,\n  \"immed\": true,\n  \"latedef\": true,\n  \"newcap\":"
  },
  {
    "path": "server/api/compile/compile.controller.js",
    "chars": 7621,
    "preview": "'use strict';\n\nvar _ = require('lodash');\nvar Compile = require('./compile.model');\nvar http = require('http');\nvar http"
  },
  {
    "path": "server/api/compile/compile.model.js",
    "chars": 228,
    "preview": "'use strict';\n\nvar mongoose = require('mongoose'),\n    Schema = mongoose.Schema;\n\nvar CompileSchema = new Schema({\n  nam"
  },
  {
    "path": "server/api/compile/compile.spec.js",
    "chars": 464,
    "preview": "'use strict';\n\nvar should = require('should');\nvar app = require('../../app');\nvar request = require('supertest');\n\ndesc"
  },
  {
    "path": "server/api/compile/index.js",
    "chars": 481,
    "preview": "'use strict';\n\nvar express = require('express');\nvar controller = require('./compile.controller');\n\nvar router = express"
  },
  {
    "path": "server/api/themes/index.js",
    "chars": 388,
    "preview": "'use strict';\n\nvar express = require('express');\nvar controller = require('./themes.controller');\n\nvar router = express."
  },
  {
    "path": "server/api/themes/themes.controller.js",
    "chars": 1592,
    "preview": "'use strict';\n\nvar _ = require('lodash');\nvar Themes = require('./themes.model');\n\n// Get list of themess\nexports.index "
  },
  {
    "path": "server/api/themes/themes.model.js",
    "chars": 225,
    "preview": "'use strict';\n\nvar mongoose = require('mongoose'),\n    Schema = mongoose.Schema;\n\nvar ThemesSchema = new Schema({\n  name"
  },
  {
    "path": "server/api/themes/themes.spec.js",
    "chars": 462,
    "preview": "'use strict';\n\nvar should = require('should');\nvar app = require('../../app');\nvar request = require('supertest');\n\ndesc"
  },
  {
    "path": "server/app.js",
    "chars": 744,
    "preview": "/**\n * Main application file\n */\n\n'use strict';\n\n// Set default node environment to development\nprocess.env.NODE_ENV = p"
  },
  {
    "path": "server/components/errors/index.js",
    "chars": 367,
    "preview": "/**\n * Error responses\n */\n\n'use strict';\n\nmodule.exports[404] = function pageNotFound(req, res) {\n  var viewFilePath = "
  },
  {
    "path": "server/config/environment/development.js",
    "chars": 221,
    "preview": "'use strict';\n\n// Development specific configuration\n// ==================================\nmodule.exports = {\n  // Mongo"
  },
  {
    "path": "server/config/environment/index.js",
    "chars": 1082,
    "preview": "'use strict';\n\nvar path = require('path');\nvar _ = require('lodash');\n\nfunction requiredProcessEnv(name) {\n  if(!process"
  },
  {
    "path": "server/config/environment/production.js",
    "chars": 595,
    "preview": "'use strict';\n\n// Production specific configuration\n// =================================\nmodule.exports = {\n  // Server "
  },
  {
    "path": "server/config/environment/test.js",
    "chars": 190,
    "preview": "'use strict';\n\n// Test specific configuration\n// ===========================\nmodule.exports = {\n  // MongoDB connection "
  },
  {
    "path": "server/config/express.js",
    "chars": 1407,
    "preview": "/**\n * Express configuration\n */\n\n'use strict';\n\nvar express = require('express');\nvar favicon = require('static-favicon"
  },
  {
    "path": "server/ionic/scss-live/_action-sheet.scss",
    "chars": 2737,
    "preview": "/**\n * Action Sheets\n * --------------------------------------------------\n */\n\n.action-sheet-backdrop {\n  @include tran"
  },
  {
    "path": "server/ionic/scss-live/_animations.scss",
    "chars": 1153,
    "preview": "\n// Slide up from the bottom, used for modals\n// -------------------------------\n\n.slide-in-up {\n  @include translate3d("
  },
  {
    "path": "server/ionic/scss-live/_backdrop.scss",
    "chars": 354,
    "preview": "\n.backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $z-index-backdrop;\n\n  width: 100%;\n  height: 100%;\n\n  ba"
  },
  {
    "path": "server/ionic/scss-live/_badge.scss",
    "chars": 1507,
    "preview": "\n/**\n * Badges\n * --------------------------------------------------\n */\n\n.badge {\n  @include badge-style($badge-default"
  },
  {
    "path": "server/ionic/scss-live/_bar.scss",
    "chars": 9536,
    "preview": "\n/**\n * Bar (Headers and Footers)\n * --------------------------------------------------\n */\n\n.bar {\n  @include display-f"
  },
  {
    "path": "server/ionic/scss-live/_button-bar.scss",
    "chars": 859,
    "preview": "\n/**\n * Button Bar\n * --------------------------------------------------\n */\n\n.button-bar {\n  @include display-flex();\n "
  },
  {
    "path": "server/ionic/scss-live/_button.scss",
    "chars": 6430,
    "preview": "\n/**\n * Buttons\n * --------------------------------------------------\n */\n\n.button {\n  // set the color defaults\n  @incl"
  },
  {
    "path": "server/ionic/scss-live/_checkbox.scss",
    "chars": 4626,
    "preview": "\n/**\n * Checkbox\n * --------------------------------------------------\n */\n\n.checkbox {\n  // set the color defaults\n  @i"
  },
  {
    "path": "server/ionic/scss-live/_form.scss",
    "chars": 5958,
    "preview": "/**\n * Forms\n * --------------------------------------------------\n */\n\n// Make all forms have space below them\nform {\n "
  },
  {
    "path": "server/ionic/scss-live/_grid.scss",
    "chars": 2839,
    "preview": "/**\n * Grid\n * --------------------------------------------------\n * Using flexbox for the grid, inspired by Philip Walt"
  },
  {
    "path": "server/ionic/scss-live/_items.scss",
    "chars": 19513,
    "preview": "/**\n * Items\n * --------------------------------------------------\n */\n\n.item {\n  @include item-style($item-default-bg, "
  },
  {
    "path": "server/ionic/scss-live/_list.scss",
    "chars": 2383,
    "preview": "\n/**\n * Lists\n * --------------------------------------------------\n */\n\n.list {\n  position: relative;\n  padding-top: $i"
  },
  {
    "path": "server/ionic/scss-live/_loaders.scss",
    "chars": 292,
    "preview": "/**\n * Loaders (Spinners)\n * --------------------------------------------------\n */\n\nsvg.loader {\n  width: 28px;\n  heigh"
  },
  {
    "path": "server/ionic/scss-live/_loading.scss",
    "chars": 825,
    "preview": "\n/**\n * Loading\n * --------------------------------------------------\n */\n\n.loading-container {\n  position: absolute;\n  "
  },
  {
    "path": "server/ionic/scss-live/_menu.scss",
    "chars": 1000,
    "preview": "\n/**\n * Menus\n * --------------------------------------------------\n * Side panel structure\n */\n\n.menu {\n  position: abs"
  },
  {
    "path": "server/ionic/scss-live/_mixins.scss",
    "chars": 15487,
    "preview": "\n// Button Mixins\n// --------------------------------------------------\n\n@mixin button-style($bg-color, $border-color, $"
  },
  {
    "path": "server/ionic/scss-live/_modal.scss",
    "chars": 2083,
    "preview": "\n/**\n * Modals\n * --------------------------------------------------\n * Modals are independent windows that slide in fro"
  },
  {
    "path": "server/ionic/scss-live/_platform.scss",
    "chars": 1564,
    "preview": "\n/**\n * Platform\n * --------------------------------------------------\n * Platform specific tweaks\n */\n\n.platform-ios.pl"
  },
  {
    "path": "server/ionic/scss-live/_popover.scss",
    "chars": 2951,
    "preview": "\n/**\n * Popovers\n * --------------------------------------------------\n * Popovers are independent views which float ove"
  },
  {
    "path": "server/ionic/scss-live/_popup.scss",
    "chars": 1972,
    "preview": "\n/**\n * Popups\n * --------------------------------------------------\n */\n\n.popup-container {\n  position: absolute;\n  top"
  },
  {
    "path": "server/ionic/scss-live/_progress.scss",
    "chars": 161,
    "preview": "\n/**\n * Progress\n * --------------------------------------------------\n */\n\nprogress {\n  display: block;\n  margin: $prog"
  },
  {
    "path": "server/ionic/scss-live/_radio.scss",
    "chars": 1201,
    "preview": "\n/**\n * Radio Button Inputs\n * --------------------------------------------------\n */\n\n.item-radio {\n  padding: 0;\n\n  &:"
  },
  {
    "path": "server/ionic/scss-live/_range.scss",
    "chars": 2838,
    "preview": "\n/**\n * Range\n * --------------------------------------------------\n */\n\ninput[type=\"range\"] {\n  display: inline-block;\n"
  },
  {
    "path": "server/ionic/scss-live/_refresher.scss",
    "chars": 2452,
    "preview": "\n// Scroll refresher (for pull to refresh)\n.scroll-refresher {\n  position: absolute;\n  top: -60px;\n  right: 0;\n  left: 0"
  },
  {
    "path": "server/ionic/scss-live/_reset.scss",
    "chars": 6919,
    "preview": "\n/**\n * Resets\n * --------------------------------------------------\n * Adapted from normalize.css and some reset.css. W"
  },
  {
    "path": "server/ionic/scss-live/_scaffolding.scss",
    "chars": 5282,
    "preview": "\n/**\n * Scaffolding\n * --------------------------------------------------\n */\n\n*,\n*:before,\n*:after {\n  @include box-siz"
  },
  {
    "path": "server/ionic/scss-live/_select.scss",
    "chars": 2597,
    "preview": "\n/**\n * Select\n * --------------------------------------------------\n */\n\n.item-select {\n  position: relative;\n\n  select"
  },
  {
    "path": "server/ionic/scss-live/_slide-box.scss",
    "chars": 828,
    "preview": "\n/**\n * Slide Box\n * --------------------------------------------------\n */\n\n.slider {\n  position: relative;\n  visibilit"
  },
  {
    "path": "server/ionic/scss-live/_split-pane.scss",
    "chars": 502,
    "preview": "\n/**\n * Split Pane\n * --------------------------------------------------\n */\n\n.split-pane {\n  @include display-flex();\n "
  },
  {
    "path": "server/ionic/scss-live/_tabs.scss",
    "chars": 13205,
    "preview": "/**\n * Tabs\n * --------------------------------------------------\n * A navigation bar with any number of tab items suppo"
  },
  {
    "path": "server/ionic/scss-live/_toggle.scss",
    "chars": 5191,
    "preview": "\n/**\n * Toggle\n * --------------------------------------------------\n */\n\n.item-toggle {\n  pointer-events: none;\n}\n\n.tog"
  },
  {
    "path": "server/ionic/scss-live/_transitions.scss",
    "chars": 3466,
    "preview": "\n// iOS View Transitions\n// -------------------------------\n\n$ios-transition-duration:              500ms !default;\n$ios"
  },
  {
    "path": "server/ionic/scss-live/_type.scss",
    "chars": 2845,
    "preview": "\n/**\n * Typography\n * --------------------------------------------------\n */\n\n\n// Body text\n// -------------------------"
  },
  {
    "path": "server/ionic/scss-live/_util.scss",
    "chars": 4044,
    "preview": "\n/**\n * Utility Classes\n * --------------------------------------------------\n */\n\n.hide {\n  display: none;\n}\n.opacity-h"
  },
  {
    "path": "server/ionic/scss-live/_variables.scss",
    "chars": 30517,
    "preview": "\n// Colors\n// -------------------------------\n\n$light:                           #fff !default;\n$stable:                "
  },
  {
    "path": "server/ionic/scss-live/ionic.scss",
    "chars": 559,
    "preview": "@charset \"UTF-8\";\n\n@import\n  // Ionicons\n  //\"ionicons/ionicons.scss\",\n\n  // Variables\n  \"mixins\",\n  \"variables\",\n\n  // "
  },
  {
    "path": "server/ionic/scss-live/ionicons/_ionicons-animation.scss",
    "chars": 1856,
    "preview": "// Animation Icons\n// --------------------------\n\n.#{$ionicons-prefix}spin {\n  -webkit-animation: spin 1s infinite linea"
  },
  {
    "path": "server/ionic/scss-live/ionicons/_ionicons-font.scss",
    "chars": 890,
    "preview": "// Ionicons Font Path\n// --------------------------\n\n@font-face {\n font-family: $ionicons-font-family;\n src:url(\"#{$ioni"
  },
  {
    "path": "server/ionic/scss-live/ionicons/_ionicons-icons.scss",
    "chars": 61512,
    "preview": "// Ionicons Icons\n// --------------------------\n\n.ionicons,\n.#{$ionicons-prefix}alert,\n.#{$ionicons-prefix}alert-circled"
  },
  {
    "path": "server/ionic/scss-live/ionicons/_ionicons-variables.scss",
    "chars": 19637,
    "preview": "// Ionicons Variables\n// --------------------------\n\n$ionicons-font-path: \"../fonts\" !default;\n$ionicons-font-family: \"I"
  },
  {
    "path": "server/ionic/scss-live/ionicons/ionicons.scss",
    "chars": 343,
    "preview": "@import \"ionicons-variables\";\n/*!\n  Ionicons, v#{$ionicons-version}\n  Created by Ben Sperry for the Ionic Framework, htt"
  },
  {
    "path": "server/ionic/scss-prod/_action-sheet.scss",
    "chars": 2737,
    "preview": "/**\n * Action Sheets\n * --------------------------------------------------\n */\n\n.action-sheet-backdrop {\n  @include tran"
  },
  {
    "path": "server/ionic/scss-prod/_animations.scss",
    "chars": 1153,
    "preview": "\n// Slide up from the bottom, used for modals\n// -------------------------------\n\n.slide-in-up {\n  @include translate3d("
  },
  {
    "path": "server/ionic/scss-prod/_backdrop.scss",
    "chars": 354,
    "preview": "\n.backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $z-index-backdrop;\n\n  width: 100%;\n  height: 100%;\n\n  ba"
  },
  {
    "path": "server/ionic/scss-prod/_badge.scss",
    "chars": 1507,
    "preview": "\n/**\n * Badges\n * --------------------------------------------------\n */\n\n.badge {\n  @include badge-style($badge-default"
  },
  {
    "path": "server/ionic/scss-prod/_bar.scss",
    "chars": 9536,
    "preview": "\n/**\n * Bar (Headers and Footers)\n * --------------------------------------------------\n */\n\n.bar {\n  @include display-f"
  },
  {
    "path": "server/ionic/scss-prod/_button-bar.scss",
    "chars": 859,
    "preview": "\n/**\n * Button Bar\n * --------------------------------------------------\n */\n\n.button-bar {\n  @include display-flex();\n "
  },
  {
    "path": "server/ionic/scss-prod/_button.scss",
    "chars": 6430,
    "preview": "\n/**\n * Buttons\n * --------------------------------------------------\n */\n\n.button {\n  // set the color defaults\n  @incl"
  },
  {
    "path": "server/ionic/scss-prod/_checkbox.scss",
    "chars": 4626,
    "preview": "\n/**\n * Checkbox\n * --------------------------------------------------\n */\n\n.checkbox {\n  // set the color defaults\n  @i"
  },
  {
    "path": "server/ionic/scss-prod/_form.scss",
    "chars": 5958,
    "preview": "/**\n * Forms\n * --------------------------------------------------\n */\n\n// Make all forms have space below them\nform {\n "
  },
  {
    "path": "server/ionic/scss-prod/_grid.scss",
    "chars": 2839,
    "preview": "/**\n * Grid\n * --------------------------------------------------\n * Using flexbox for the grid, inspired by Philip Walt"
  },
  {
    "path": "server/ionic/scss-prod/_items.scss",
    "chars": 19513,
    "preview": "/**\n * Items\n * --------------------------------------------------\n */\n\n.item {\n  @include item-style($item-default-bg, "
  },
  {
    "path": "server/ionic/scss-prod/_list.scss",
    "chars": 2383,
    "preview": "\n/**\n * Lists\n * --------------------------------------------------\n */\n\n.list {\n  position: relative;\n  padding-top: $i"
  },
  {
    "path": "server/ionic/scss-prod/_loaders.scss",
    "chars": 292,
    "preview": "/**\n * Loaders (Spinners)\n * --------------------------------------------------\n */\n\nsvg.loader {\n  width: 28px;\n  heigh"
  },
  {
    "path": "server/ionic/scss-prod/_loading.scss",
    "chars": 825,
    "preview": "\n/**\n * Loading\n * --------------------------------------------------\n */\n\n.loading-container {\n  position: absolute;\n  "
  },
  {
    "path": "server/ionic/scss-prod/_menu.scss",
    "chars": 1000,
    "preview": "\n/**\n * Menus\n * --------------------------------------------------\n * Side panel structure\n */\n\n.menu {\n  position: abs"
  },
  {
    "path": "server/ionic/scss-prod/_mixins.scss",
    "chars": 15487,
    "preview": "\n// Button Mixins\n// --------------------------------------------------\n\n@mixin button-style($bg-color, $border-color, $"
  },
  {
    "path": "server/ionic/scss-prod/_modal.scss",
    "chars": 2083,
    "preview": "\n/**\n * Modals\n * --------------------------------------------------\n * Modals are independent windows that slide in fro"
  },
  {
    "path": "server/ionic/scss-prod/_platform.scss",
    "chars": 1564,
    "preview": "\n/**\n * Platform\n * --------------------------------------------------\n * Platform specific tweaks\n */\n\n.platform-ios.pl"
  },
  {
    "path": "server/ionic/scss-prod/_popover.scss",
    "chars": 2951,
    "preview": "\n/**\n * Popovers\n * --------------------------------------------------\n * Popovers are independent views which float ove"
  },
  {
    "path": "server/ionic/scss-prod/_popup.scss",
    "chars": 1972,
    "preview": "\n/**\n * Popups\n * --------------------------------------------------\n */\n\n.popup-container {\n  position: absolute;\n  top"
  },
  {
    "path": "server/ionic/scss-prod/_progress.scss",
    "chars": 161,
    "preview": "\n/**\n * Progress\n * --------------------------------------------------\n */\n\nprogress {\n  display: block;\n  margin: $prog"
  },
  {
    "path": "server/ionic/scss-prod/_radio.scss",
    "chars": 1201,
    "preview": "\n/**\n * Radio Button Inputs\n * --------------------------------------------------\n */\n\n.item-radio {\n  padding: 0;\n\n  &:"
  },
  {
    "path": "server/ionic/scss-prod/_range.scss",
    "chars": 2838,
    "preview": "\n/**\n * Range\n * --------------------------------------------------\n */\n\ninput[type=\"range\"] {\n  display: inline-block;\n"
  },
  {
    "path": "server/ionic/scss-prod/_refresher.scss",
    "chars": 2452,
    "preview": "\n// Scroll refresher (for pull to refresh)\n.scroll-refresher {\n  position: absolute;\n  top: -60px;\n  right: 0;\n  left: 0"
  },
  {
    "path": "server/ionic/scss-prod/_reset.scss",
    "chars": 6919,
    "preview": "\n/**\n * Resets\n * --------------------------------------------------\n * Adapted from normalize.css and some reset.css. W"
  },
  {
    "path": "server/ionic/scss-prod/_scaffolding.scss",
    "chars": 5282,
    "preview": "\n/**\n * Scaffolding\n * --------------------------------------------------\n */\n\n*,\n*:before,\n*:after {\n  @include box-siz"
  },
  {
    "path": "server/ionic/scss-prod/_select.scss",
    "chars": 2597,
    "preview": "\n/**\n * Select\n * --------------------------------------------------\n */\n\n.item-select {\n  position: relative;\n\n  select"
  },
  {
    "path": "server/ionic/scss-prod/_slide-box.scss",
    "chars": 828,
    "preview": "\n/**\n * Slide Box\n * --------------------------------------------------\n */\n\n.slider {\n  position: relative;\n  visibilit"
  },
  {
    "path": "server/ionic/scss-prod/_split-pane.scss",
    "chars": 502,
    "preview": "\n/**\n * Split Pane\n * --------------------------------------------------\n */\n\n.split-pane {\n  @include display-flex();\n "
  },
  {
    "path": "server/ionic/scss-prod/_tabs.scss",
    "chars": 13205,
    "preview": "/**\n * Tabs\n * --------------------------------------------------\n * A navigation bar with any number of tab items suppo"
  },
  {
    "path": "server/ionic/scss-prod/_toggle.scss",
    "chars": 5191,
    "preview": "\n/**\n * Toggle\n * --------------------------------------------------\n */\n\n.item-toggle {\n  pointer-events: none;\n}\n\n.tog"
  },
  {
    "path": "server/ionic/scss-prod/_transitions.scss",
    "chars": 3466,
    "preview": "\n// iOS View Transitions\n// -------------------------------\n\n$ios-transition-duration:              500ms !default;\n$ios"
  },
  {
    "path": "server/ionic/scss-prod/_type.scss",
    "chars": 2845,
    "preview": "\n/**\n * Typography\n * --------------------------------------------------\n */\n\n\n// Body text\n// -------------------------"
  },
  {
    "path": "server/ionic/scss-prod/_util.scss",
    "chars": 4044,
    "preview": "\n/**\n * Utility Classes\n * --------------------------------------------------\n */\n\n.hide {\n  display: none;\n}\n.opacity-h"
  },
  {
    "path": "server/ionic/scss-prod/_variables.scss",
    "chars": 30517,
    "preview": "\n// Colors\n// -------------------------------\n\n$light:                           #fff !default;\n$stable:                "
  },
  {
    "path": "server/ionic/scss-prod/ionic.scss",
    "chars": 595,
    "preview": "@charset \"UTF-8\";\n\n@import\n  // Ionicons\n  \"ionicons/ionicons.scss\",\n\n  // Variables\n  \"mixins\",\n  \"variables\",\n\n  // Ba"
  },
  {
    "path": "server/ionic/scss-prod/ionicons/_ionicons-animation.scss",
    "chars": 1856,
    "preview": "// Animation Icons\n// --------------------------\n\n.#{$ionicons-prefix}spin {\n  -webkit-animation: spin 1s infinite linea"
  },
  {
    "path": "server/ionic/scss-prod/ionicons/_ionicons-font.scss",
    "chars": 890,
    "preview": "// Ionicons Font Path\n// --------------------------\n\n@font-face {\n font-family: $ionicons-font-family;\n src:url(\"#{$ioni"
  },
  {
    "path": "server/ionic/scss-prod/ionicons/_ionicons-icons.scss",
    "chars": 91501,
    "preview": "// Ionicons Icons\n// --------------------------\n\n.ionicons,\n.#{$ionicons-prefix}alert:before,\n.#{$ionicons-prefix}alert-"
  },
  {
    "path": "server/ionic/scss-prod/ionicons/_ionicons-variables.scss",
    "chars": 27507,
    "preview": "// Ionicons Variables\n// --------------------------\n\n$ionicons-font-path: \"../fonts\" !default;\n$ionicons-font-family: \"I"
  },
  {
    "path": "server/ionic/scss-prod/ionicons/ionicons.scss",
    "chars": 541,
    "preview": "@import \"ionicons-variables\";\n/*!\n  Ionicons, v2.0.1\n  Created by Ben Sperry for the Ionic Framework, http://ionicons.co"
  },
  {
    "path": "server/ionic/scss_test/_action-sheet.scss",
    "chars": 1540,
    "preview": "/**\n * Action Sheets\n * --------------------------------------------------\n */\n\n.action-sheet-backdrop {\n  @include tran"
  },
  {
    "path": "server/ionic/scss_test/_animations.scss",
    "chars": 23712,
    "preview": "/**\n * Animations\n * --------------------------------------------------\n * The animations in this file are \"simple\" - no"
  },
  {
    "path": "server/ionic/scss_test/_backdrop.scss",
    "chars": 314,
    "preview": "\n.backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: $z-index-backdrop;\n\n  width: 100%;\n  height: 100%;\n\n  ba"
  },
  {
    "path": "server/ionic/scss_test/_badge.scss",
    "chars": 1507,
    "preview": "\n/**\n * Badges\n * --------------------------------------------------\n */\n\n.badge {\n  @include badge-style($badge-default"
  },
  {
    "path": "server/ionic/scss_test/_bar.scss",
    "chars": 8885,
    "preview": "\n/**\n * Bar (Headers and Footers)\n * --------------------------------------------------\n */\n\n.bar {\n  @include display-f"
  },
  {
    "path": "server/ionic/scss_test/_button-bar.scss",
    "chars": 787,
    "preview": "\n/**\n * Button Bar\n * --------------------------------------------------\n */\n\n.button-bar {\n  @include display-flex();\n "
  },
  {
    "path": "server/ionic/scss_test/_button.scss",
    "chars": 6430,
    "preview": "\n/**\n * Buttons\n * --------------------------------------------------\n */\n\n.button {\n  // set the color defaults\n  @incl"
  },
  {
    "path": "server/ionic/scss_test/_checkbox.scss",
    "chars": 3750,
    "preview": "\n/**\n * Checkbox\n * --------------------------------------------------\n */\n\n.checkbox {\n  // set the color defaults\n  @i"
  },
  {
    "path": "server/ionic/scss_test/_form.scss",
    "chars": 5958,
    "preview": "/**\n * Forms\n * --------------------------------------------------\n */\n\n// Make all forms have space below them\nform {\n "
  },
  {
    "path": "server/ionic/scss_test/_grid.scss",
    "chars": 2839,
    "preview": "/**\n * Grid\n * --------------------------------------------------\n * Using flexbox for the grid, inspired by Philip Walt"
  },
  {
    "path": "server/ionic/scss_test/_items.scss",
    "chars": 17881,
    "preview": "/**\n * Items\n * --------------------------------------------------\n */\n\n.item {\n  @include item-style($item-default-bg, "
  },
  {
    "path": "server/ionic/scss_test/_list.scss",
    "chars": 2247,
    "preview": "\n/**\n * Lists\n * --------------------------------------------------\n */\n\n.list {\n  position: relative;\n  padding-top: $i"
  },
  {
    "path": "server/ionic/scss_test/_loading.scss",
    "chars": 825,
    "preview": "\n/**\n * Loading\n * --------------------------------------------------\n */\n\n.loading-container {\n  position: absolute;\n  "
  },
  {
    "path": "server/ionic/scss_test/_menu.scss",
    "chars": 1000,
    "preview": "\n/**\n * Menus\n * --------------------------------------------------\n * Side panel structure\n */\n\n.menu {\n  position: abs"
  },
  {
    "path": "server/ionic/scss_test/_mixins.scss",
    "chars": 16031,
    "preview": "\n// Button Mixins\n// --------------------------------------------------\n\n@mixin button-style($bg-color, $border-color, $"
  },
  {
    "path": "server/ionic/scss_test/_modal.scss",
    "chars": 2010,
    "preview": "\n/**\n * Modals\n * --------------------------------------------------\n * Modals are independent windows that slide in fro"
  },
  {
    "path": "server/ionic/scss_test/_platform.scss",
    "chars": 2941,
    "preview": "\n/**\n * Platform\n * --------------------------------------------------\n * Platform specific tweaks\n */\n\n\n/**\n * Apply ro"
  },
  {
    "path": "server/ionic/scss_test/_popover.scss",
    "chars": 2951,
    "preview": "\n/**\n * Popovers\n * --------------------------------------------------\n * Popovers are independent views which float ove"
  },
  {
    "path": "server/ionic/scss_test/_popup.scss",
    "chars": 1972,
    "preview": "\n/**\n * Popups\n * --------------------------------------------------\n */\n\n.popup-container {\n  position: absolute;\n  top"
  },
  {
    "path": "server/ionic/scss_test/_progress.scss",
    "chars": 161,
    "preview": "\n/**\n * Progress\n * --------------------------------------------------\n */\n\nprogress {\n  display: block;\n  margin: $prog"
  },
  {
    "path": "server/ionic/scss_test/_radio.scss",
    "chars": 1201,
    "preview": "\n/**\n * Radio Button Inputs\n * --------------------------------------------------\n */\n\n.item-radio {\n  padding: 0;\n\n  &:"
  },
  {
    "path": "server/ionic/scss_test/_range.scss",
    "chars": 2851,
    "preview": "\n/**\n * Range\n * --------------------------------------------------\n */\n\ninput[type=\"range\"] {\n  display: inline-block;\n"
  },
  {
    "path": "server/ionic/scss_test/_reset.scss",
    "chars": 6919,
    "preview": "\n/**\n * Resets\n * --------------------------------------------------\n * Adapted from normalize.css and some reset.css. W"
  },
  {
    "path": "server/ionic/scss_test/_scaffolding.scss",
    "chars": 7102,
    "preview": "\n/**\n * Scaffolding\n * --------------------------------------------------\n */\n\n*,\n*:before,\n*:after {\n  @include box-siz"
  },
  {
    "path": "server/ionic/scss_test/_select.scss",
    "chars": 2597,
    "preview": "\n/**\n * Select\n * --------------------------------------------------\n */\n\n.item-select {\n  position: relative;\n\n  select"
  },
  {
    "path": "server/ionic/scss_test/_slide-box.scss",
    "chars": 828,
    "preview": "\n/**\n * Slide Box\n * --------------------------------------------------\n */\n\n.slider {\n  position: relative;\n  visibilit"
  },
  {
    "path": "server/ionic/scss_test/_tabs.scss",
    "chars": 9879,
    "preview": "/**\n * Tabs\n * --------------------------------------------------\n * A navigation bar with any number of tab items suppo"
  },
  {
    "path": "server/ionic/scss_test/_toggle.scss",
    "chars": 3759,
    "preview": "\n/**\n * Toggle\n * --------------------------------------------------\n */\n\n.item-toggle {\n  pointer-events: none;\n}\n\n.tog"
  },
  {
    "path": "server/ionic/scss_test/_type.scss",
    "chars": 2845,
    "preview": "\n/**\n * Typography\n * --------------------------------------------------\n */\n\n\n// Body text\n// -------------------------"
  },
  {
    "path": "server/ionic/scss_test/_util.scss",
    "chars": 3963,
    "preview": "\n/**\n * Utility Classes\n * --------------------------------------------------\n */\n\n.hide {\n  display: none;\n}\n.opacity-h"
  },
  {
    "path": "server/ionic/scss_test/_variables.scss",
    "chars": 29920,
    "preview": "\n// Colors\n// -------------------------------\n\n$light:                           #fff !default;\n$stable:                "
  },
  {
    "path": "server/ionic/scss_test/ionic.scss",
    "chars": 533,
    "preview": "@charset \"UTF-8\";\n\n@import\n  // Ionicons\n  \"ionicons/ionicons.scss\",\n\n  // Variables\n  \"mixins\",\n  \"variables\",\n\n  // Ba"
  },
  {
    "path": "server/ionic/tmp/ionic-Zk2IRRDU4.app.css",
    "chars": 224085,
    "preview": "/*!\n  Ionicons, v1.4.1\n  Created by Ben Sperry for the Ionic Framework, http://ionicons.com/\n  https://twitter.com/benjs"
  },
  {
    "path": "server/ionic/tmp/ionic-ZkD6jCwL4.app.css",
    "chars": 224085,
    "preview": "/*!\n  Ionicons, v1.4.1\n  Created by Ben Sperry for the Ionic Framework, http://ionicons.com/\n  https://twitter.com/benjs"
  },
  {
    "path": "server/routes.js",
    "chars": 586,
    "preview": "/**\n * Main application routes\n */\n\n'use strict';\n\nvar errors = require('./components/errors');\n\nmodule.exports = functi"
  },
  {
    "path": "server/views/404.html",
    "chars": 3529,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Page Not Found :(</title>\n    <style>\n  "
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the pbernasconi/ionic-theme-editor GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 171 files (1.2 MB), approximately 371.8k tokens, and a symbol index with 5 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!