<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2014 FusionCharts Technologies
//
// 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.

(function () {
    var fc = angular.module('ng-fusioncharts', []);

    fc.directive('fusioncharts', ['$http', function ($http) {
        return {
            scope: {
                width: '@',
                height: '@',
                data: '@',
                dataset: '@',
                categories: '@',
                chart: '@',
                linkdedata: '@',
                trendlines: '@',
                vtrendlines: '@',
                annotations: '@',
                colorrange: '@',
                lineset: '@',
                axis: '@',
                connectors: '@',
                pointers: '@',
                value: '@',
                processes: '@',
                tasks: '@',
                rows: '@',
                columns: '@',
                map: '@',
                markers: '@'
            },
            link: function (scope, element, attrs) {
                var eventsObj = {},
                    attribs = Object.keys(attrs),
                    chart = null,
                    events = {
                        '*': function (ev, props) {
                            if(eventsObj.hasOwnProperty(ev.eventType)) {
                                eventsObj[ev.eventType](ev, props);
                          }
                        }
                    };
                if(attrs.events) {
                    if(scope.$parent[attrs.events]) {
                        var _eobj = scope.$parent[attrs.events];
                        for(var key in _eobj) {
                            if(_eobj.hasOwnProperty(key)) {
                                eventsObj[key.toLowerCase()] = _eobj[key];
                            }
                        }
                    }
                }
                for(var i=0; i<attribs.length; i++) {
                    var attr = attribs[i];
                    if(attr.match(/^on/i)) {
                        var key = attr.slice(2).toLowerCase ();
                        eventsObj[key] = scope.$parent[attrs[attr]];
                    }
                }
                if(attrs.config) {
                    chart = new FusionCharts(scope[attrs.config]);
                    scope[attrs.chartobject] = chart;
                    chart.render ();
                } else {
                    var chartConfigObject = {
                        type: attrs.type,
                        width: attrs.width,
                        height: attrs.height,
                        renderAt: element[0],
                        dataFormat: attrs.dataformat || 'json',
                        dataSource: {},
                        events: events
                    };
                    attrs.$observe('width', function (newVal) {
                        chart.resizeTo (scope.width, scope.height);
                    });
                    attrs.$observe('height', function (newVal) {
                        chart.resizeTo (scope.width, scope.height);
                    });
                    if(attrs.datasource) {
                        chartConfigObject.dataSource = scope[attrs.datasource];
                        attrs.$observe('datasource', function (newVal) {
                            if(chartConfigObject.dataFormat === 'json') {
                                chart.setChartData (JSON.parse(newVal));
                            } else if(chartConfigObject.dataFormat === 'xml') {
                                chart.setXMLData (newVal);
                            } else if(chartConfigObject.dataFormat === 'jsonurl') {
                                chart.setJSONUrl(newVal);
                            } else if(chartConfigObject.dataFormat === 'xmlurl') {
                                chart.setXMLUrl(newVal);
                            }
                        }, true);
                    } else {
                        attrs.$observe('chart', function (newVal) {
                            setTimeout(function () {
                                chartConfigObject.dataSource.chart = JSON.parse(newVal);
                                chart.setJSONData (chartConfigObject.dataSource);
                            }, 0);
                        }, true)
                        if(attrs.data) {
                            attrs.$observe('data', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.data = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                }, 0);
                            }, true);
                        }
                        if(attrs.categories) {
                            attrs.$observe('categories', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.categories = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                }, 0);
                            }, true);
                        }
                        if(attrs.dataset) {
                            attrs.$observe('dataset', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.dataset = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.linkeddata) {
                            attrs.$observe('linkeddata', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.linkeddata = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.trendlines) {
                            attrs.$observe('trendlines', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.trendlines = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.vtrendlines) {
                            attrs.$observe('vtrendlines', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.vtrendlines = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.annotations) {
                            attrs.$observe('annotations', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.annotations = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.colorrange) {
                            attrs.$observe('colorrange', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.colorrange = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.lineset) {
                            attrs.$observe('lineset', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.lineset = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.axis) {
                            attrs.$observe('axis', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.axis = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.connectors) {
                            attrs.$observe('connectors', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.connectors = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.pointers) {
                            attrs.$observe('pointers', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.pointers = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.value) {
                            attrs.$observe('value', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.value = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.processes) {
                            attrs.$observe('processes', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.processes = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.tasks) {
                            attrs.$observe('tasks', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.tasks = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.rows) {
                            attrs.$observe('rows', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.rows = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.columns) {
                            attrs.$observe('columns', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.columns = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.map) {
                            attrs.$observe('map', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.map = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.markers) {
                            attrs.$observe('markers', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.markers = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                    }

                    var chart = new FusionCharts(chartConfigObject);
                    scope[attrs.chartobject] = chart;
                    chart.render ();
                }
            }
        }
    }
    ]);
}());<commit_msg>LinkedData typo error when defining attribute<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2014 FusionCharts Technologies
//
// 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.

(function () {
    var fc = angular.module('ng-fusioncharts', []);

    fc.directive('fusioncharts', ['$http', function ($http) {
        return {
            scope: {
                width: '@',
                height: '@',
                data: '@',
                dataset: '@',
                categories: '@',
                chart: '@',
                linkeddata: '@',
                trendlines: '@',
                vtrendlines: '@',
                annotations: '@',
                colorrange: '@',
                lineset: '@',
                axis: '@',
                connectors: '@',
                pointers: '@',
                value: '@',
                processes: '@',
                tasks: '@',
                rows: '@',
                columns: '@',
                map: '@',
                markers: '@'
            },
            link: function (scope, element, attrs) {
                var eventsObj = {},
                    attribs = Object.keys(attrs),
                    chart = null,
                    events = {
                        '*': function (ev, props) {
                            if(eventsObj.hasOwnProperty(ev.eventType)) {
                                eventsObj[ev.eventType](ev, props);
                          }
                        }
                    };
                if(attrs.events) {
                    if(scope.$parent[attrs.events]) {
                        var _eobj = scope.$parent[attrs.events];
                        for(var key in _eobj) {
                            if(_eobj.hasOwnProperty(key)) {
                                eventsObj[key.toLowerCase()] = _eobj[key];
                            }
                        }
                    }
                }
                for(var i=0; i<attribs.length; i++) {
                    var attr = attribs[i];
                    if(attr.match(/^on/i)) {
                        var key = attr.slice(2).toLowerCase ();
                        eventsObj[key] = scope.$parent[attrs[attr]];
                    }
                }
                if(attrs.config) {
                    chart = new FusionCharts(scope[attrs.config]);
                    scope[attrs.chartobject] = chart;
                    chart.render ();
                } else {
                    var chartConfigObject = {
                        type: attrs.type,
                        width: attrs.width,
                        height: attrs.height,
                        renderAt: element[0],
                        dataFormat: attrs.dataformat || 'json',
                        dataSource: {},
                        events: events
                    };
                    attrs.$observe('width', function (newVal) {
                        chart.resizeTo (scope.width, scope.height);
                    });
                    attrs.$observe('height', function (newVal) {
                        chart.resizeTo (scope.width, scope.height);
                    });
                    if(attrs.datasource) {
                        chartConfigObject.dataSource = scope[attrs.datasource];
                        attrs.$observe('datasource', function (newVal) {
                            if(chartConfigObject.dataFormat === 'json') {
                                chart.setChartData (JSON.parse(newVal));
                            } else if(chartConfigObject.dataFormat === 'xml') {
                                chart.setXMLData (newVal);
                            } else if(chartConfigObject.dataFormat === 'jsonurl') {
                                chart.setJSONUrl(newVal);
                            } else if(chartConfigObject.dataFormat === 'xmlurl') {
                                chart.setXMLUrl(newVal);
                            }
                        }, true);
                    } else {
                        attrs.$observe('chart', function (newVal) {
                            setTimeout(function () {
                                chartConfigObject.dataSource.chart = JSON.parse(newVal);
                                chart.setJSONData (chartConfigObject.dataSource);
                            }, 0);
                        }, true)
                        if(attrs.data) {
                            attrs.$observe('data', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.data = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                }, 0);
                            }, true);
                        }
                        if(attrs.categories) {
                            attrs.$observe('categories', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.categories = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                }, 0);
                            }, true);
                        }
                        if(attrs.dataset) {
                            attrs.$observe('dataset', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.dataset = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.linkeddata) {
                            attrs.$observe('linkeddata', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.linkeddata = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.trendlines) {
                            attrs.$observe('trendlines', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.trendlines = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.vtrendlines) {
                            attrs.$observe('vtrendlines', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.vtrendlines = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.annotations) {
                            attrs.$observe('annotations', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.annotations = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.colorrange) {
                            attrs.$observe('colorrange', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.colorrange = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.lineset) {
                            attrs.$observe('lineset', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.lineset = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.axis) {
                            attrs.$observe('axis', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.axis = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.connectors) {
                            attrs.$observe('connectors', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.connectors = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.pointers) {
                            attrs.$observe('pointers', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.pointers = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.value) {
                            attrs.$observe('value', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.value = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.processes) {
                            attrs.$observe('processes', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.processes = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.tasks) {
                            attrs.$observe('tasks', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.tasks = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.rows) {
                            attrs.$observe('rows', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.rows = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.columns) {
                            attrs.$observe('columns', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.columns = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.map) {
                            attrs.$observe('map', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.map = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                        if(attrs.markers) {
                            attrs.$observe('markers', function (newVal) {
                                setTimeout(function () {
                                    chartConfigObject.dataSource.markers = JSON.parse(newVal);
                                    chart.setJSONData (chartConfigObject.dataSource);
                                });
                            }, true);
                        }
                    }

                    var chart = new FusionCharts(chartConfigObject);
                    scope[attrs.chartobject] = chart;
                    chart.render ();
                }
            }
        }
    }
    ]);
}());
<|endoftext|>


<commit_before>'use strict';

var npmDest = 'dist';
var buildDest = 'dist';
var entryJS = 'src/js/app.js';
var devDest = 'dev/';
var tmpDir = '.tmp';
var devBundle = devDest + '/fittable.js';

module.exports = function (grunt) {
  // Project configuration
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    concurrent: {
      options: {
        logConcurrentOutput: true
      },
      dev: {
        tasks: [
          'browserSync',              // start static files server
          'compass:dev',              // start compass watch
          'watch:copy:dev',           // copy HTML files
          'browserify:dev',           // start watchify
          'shell:bundleMonitoring',   // start monitoring bundle changes
        ],
      },
      dist: {

      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            tmpDir,
            'dist/*',
            '!dist/.git*'
          ]
        }]
      },
      dev: {
        files: [{
          dot: true,
          src: [
            devDest,
            tmpDir
          ]
        }]
      }
    },

    // Compiles Sass to CSS and generates necessary files if requested
    // autoprefixer is invoked from compass, see config.rb
    compass: {
      dev: {
        options: {
          sassDir: 'src/scss',
          cssDir: devDest,
          noLineComments: true,
          watch: true
        }
      },
      dist: {
        options: {
          sassDir: 'src/scss',
          cssDir: buildDest,
          environment: 'production'
        }
      }
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      'copy:dev': {
        files: ['src/*.html'],
        tasks: ['copy:dev']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          cwd: 'src/',
          dest: buildDest,
          flatten: false,
          src: [
            'index.html',
            'landing.html',
            'img/**',
          ]
        }]
      },
      npm: {
        files: [{
          expand: true,
          dest: npmDest,
          cwd: './src',
          src: [
            'lang/*'
          ]
        }]
      },
      dev: {
        files: [{
          expand: true,
          cwd: 'src/',
          dest: devDest,
          flatten: false,
          src: [
            'index.html',
            'landing.html',
            'img/**',
          ]
        }]
      },
    },

    // Browserify
    browserify: {
      options: {
        transform: [ 'babelify' ],
        browserifyOptions: {
          debug: true,
          standalone: 'fittable'
        }
      },
      dev: {
        src: entryJS,
        dest: devBundle,
        options: {
          watch: true,
          keepAlive: true,
          transform: [[{}, 'babelify'], [{global: true, preventCache: false}, 'livereactload']],
          browserifyOptions: {
            debug: true,
            standalone: 'fittable'
          }
        }
      },
      dist: {
        files: {
          'dist/fittable.js': entryJS
        }
      },
      min: {
        options: {
          transform: [ 'babelify' ],
          plugin: [ 'minifyify' ]
        },
        files: {
          'dist/fittable.min.js': entryJS
        }
      }
    },

    // Babel: Used for npm prepublishing, otherwise see browserify
    babel: {
      options: {
        sourceMap: false
      },
      npm: {
        files: [{
            expand: true,
            cwd: 'src/js',
            src: ['**/*.js'],
            dest: npmDest + '/js'
        }]
      }
    },

    shell: {
      bundleMonitoring: {
        command: 'node_modules/.bin/livereactload monitor ' + devBundle
      }
    },

    // browserSync: Provides static server and assets reloading
    browserSync: {
      bsFiles: {
          src: [
            devDest + '/*.css',
            devDest + '/*.html'
          ]
      },
      options: {
        server: {
          baseDir: devDest
        }
      }
    }

  });

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  grunt.registerTask('dev', [
    'concurrent:dev'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'compass:dist',
    'autoprefixer:dist',
    'browserify:dist',
    'browserify:min',
    'copy:dist',
    'copy:distImgs'
  ]);

  grunt.registerTask('build:npm', [
    'build',
    'babel:npm',
    'copy:npm'
  ]);

  grunt.registerTask('default', ['dev']);
};
<commit_msg>Make build tasks concurrent<commit_after>'use strict';

var npmDest = 'dist';
var buildDest = 'dist';
var entryJS = 'src/js/app.js';
var devDest = 'dev/';
var tmpDir = '.tmp';
var devBundle = devDest + '/fittable.js';

module.exports = function (grunt) {
  // Project configuration
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    concurrent: {
      options: {
        logConcurrentOutput: true
      },
      dev: {
        tasks: [
          'browserSync',              // start static files server
          'compass:dev',              // start compass watch
          'watch:copy:dev',           // copy HTML files
          'browserify:dev',           // start watchify
          'shell:bundleMonitoring',   // start monitoring bundle changes
        ],
      },
      dist: {
        tasks: [
          'compass:dist',
          'browserify:dist',
          'browserify:min',
          'copy:dist',
        ]
      },
      npm: {
        tasks: [
          'babel:npm',
          'copy:npm'
        ]
      }
    },

    // Empties folders to start fresh
    clean: {
      dist: {
        files: [{
          dot: true,
          src: [
            tmpDir,
            'dist/*',
            '!dist/.git*'
          ]
        }]
      },
      dev: {
        files: [{
          dot: true,
          src: [
            devDest,
            tmpDir
          ]
        }]
      }
    },

    // Compiles Sass to CSS and generates necessary files if requested
    // autoprefixer is invoked from compass, see config.rb
    compass: {
      dev: {
        options: {
          sassDir: 'src/scss',
          cssDir: devDest,
          noLineComments: true,
          watch: true
        }
      },
      dist: {
        options: {
          sassDir: 'src/scss',
          cssDir: buildDest,
          environment: 'production'
        }
      }
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
      'copy:dev': {
        files: ['src/*.html'],
        tasks: ['copy:dev']
      }
    },

    // Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          cwd: 'src/',
          dest: buildDest,
          flatten: false,
          src: [
            'index.html',
            'landing.html',
            'img/**',
          ]
        }]
      },
      npm: {
        files: [{
          expand: true,
          dest: npmDest,
          cwd: './src',
          src: [
            'lang/*'
          ]
        }]
      },
      dev: {
        files: [{
          expand: true,
          cwd: 'src/',
          dest: devDest,
          flatten: false,
          src: [
            'index.html',
            'landing.html',
            'img/**',
          ]
        }]
      },
    },

    // Browserify
    browserify: {
      options: {
        transform: [ 'babelify' ],
        browserifyOptions: {
          debug: true,
          standalone: 'fittable'
        }
      },
      dev: {
        src: entryJS,
        dest: devBundle,
        options: {
          watch: true,
          keepAlive: true,
          transform: [[{}, 'babelify'], [{global: true, preventCache: false}, 'livereactload']],
          browserifyOptions: {
            debug: true,
            standalone: 'fittable'
          }
        }
      },
      dist: {
        files: {
          'dist/fittable.js': entryJS
        }
      },
      min: {
        options: {
          transform: [ 'babelify' ],
          plugin: [ 'minifyify' ]
        },
        files: {
          'dist/fittable.min.js': entryJS
        }
      }
    },

    // Babel: Used for npm prepublishing, otherwise see browserify
    babel: {
      options: {
        sourceMap: false
      },
      npm: {
        files: [{
            expand: true,
            cwd: 'src/js',
            src: ['**/*.js'],
            dest: npmDest + '/js'
        }]
      }
    },

    shell: {
      bundleMonitoring: {
        command: 'node_modules/.bin/livereactload monitor ' + devBundle
      }
    },

    // browserSync: Provides static server and assets reloading
    browserSync: {
      bsFiles: {
          src: [
            devDest + '/*.css',
            devDest + '/*.html'
          ]
      },
      options: {
        server: {
          baseDir: devDest
        }
      }
    }

  });

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  grunt.registerTask('dev', [
    'concurrent:dev'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'concurrent:dist',
  ]);

  grunt.registerTask('build:npm', [
    'build',
    'concurrent:npm'
  ]);

  grunt.registerTask('default', ['dev']);
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('django-formset.jquery.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    clean: {
      files: ['dist']
    },
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      },
    },
    qunit: {
      files: ['test/**/*.html']
    },
    jshint: {
      gruntfile: {
        options: {
          jshintrc: '.jshintrc'
        },
        src: 'Gruntfile.js'
      },
    },
    coffeelint: {
      src: {
        src: ['src/**/*.coffee']
      },
      test: {
        src: ['test/**/*.coffee']
      },
      options: {
        'arrow_spacing': {'level': 'error'},
        'colon_assignment_spacing': {'level': 'error',
                                     'spacing': {'left': 0, 'right': 1}},
        'cyclomatic_complexity': {'level': 'error'},
        'line_endings': {'level': 'error'},
        'newlines_after_classes': {'level': 'error'},
        'no_empty_param_list': {'level': 'error'},
        'no_implicit_parens': {'level': 'error'},
        'no_standalone_at': {'level': 'error'},
        'space_operators': {'level': 'error'},
      },
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      src: {
        files: ['src/**/*.coffee'],
        tasks: ['coffee:src', 'coffeelint:src', 'qunit', 'clean', 'concat', 'uglify']
      },
      test: {
        files: ['test/**/*.coffee', 'test/django-formset.html'],
        tasks: ['coffee:test', 'coffeelint:test', 'qunit', 'clean', 'concat', 'uglify']
      },
    },
    coffee: {
      options: {
        bare: true,
        sourceMap: true,
      },
      src: {
        files: {
          'src/django-formset.js': 'src/django-formset.coffee'
        },
      },
      test: {
        files: {
          'test/django-formset_test.js': 'test/django-formset_test.coffee'
        },
      },
    },
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-coffeelint');

  // Default task.
  grunt.registerTask('default', ['coffee', 'coffeelint', 'jshint', 'qunit', 'clean', 'concat', 'uglify']);

};
<commit_msg>Demote cyclomatic complexity to warn until I decide whether I'll put the<commit_after>'use strict';

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    // Metadata.
    pkg: grunt.file.readJSON('django-formset.jquery.json'),
    banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
      '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
      ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
    // Task configuration.
    clean: {
      files: ['dist']
    },
    concat: {
      options: {
        banner: '<%= banner %>',
        stripBanners: true
      },
      dist: {
        src: ['src/<%= pkg.name %>.js'],
        dest: 'dist/<%= pkg.name %>.js'
      },
    },
    uglify: {
      options: {
        banner: '<%= banner %>'
      },
      dist: {
        src: '<%= concat.dist.dest %>',
        dest: 'dist/<%= pkg.name %>.min.js'
      },
    },
    qunit: {
      files: ['test/**/*.html']
    },
    jshint: {
      gruntfile: {
        options: {
          jshintrc: '.jshintrc'
        },
        src: 'Gruntfile.js'
      },
    },
    coffeelint: {
      src: {
        src: ['src/**/*.coffee']
      },
      test: {
        src: ['test/**/*.coffee']
      },
      options: {
        'arrow_spacing': {'level': 'error'},
        'colon_assignment_spacing': {'level': 'error',
                                     'spacing': {'left': 0, 'right': 1}},
        'cyclomatic_complexity': {'level': 'warn'},
        'line_endings': {'level': 'error'},
        'newlines_after_classes': {'level': 'error'},
        'no_empty_param_list': {'level': 'error'},
        'no_implicit_parens': {'level': 'error'},
        'no_standalone_at': {'level': 'error'},
        'space_operators': {'level': 'error'},
      },
    },
    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      src: {
        files: ['src/**/*.coffee'],
        tasks: ['coffee:src', 'coffeelint:src', 'qunit', 'clean', 'concat', 'uglify']
      },
      test: {
        files: ['test/**/*.coffee', 'test/django-formset.html'],
        tasks: ['coffee:test', 'coffeelint:test', 'qunit', 'clean', 'concat', 'uglify']
      },
    },
    coffee: {
      options: {
        bare: true,
        sourceMap: true,
      },
      src: {
        files: {
          'src/django-formset.js': 'src/django-formset.coffee'
        },
      },
      test: {
        files: {
          'test/django-formset_test.js': 'test/django-formset_test.coffee'
        },
      },
    },
  });

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-coffeelint');

  // Default task.
  grunt.registerTask('default', ['coffee', 'coffeelint', 'jshint', 'qunit', 'clean', 'concat', 'uglify']);

};
<|endoftext|>


<commit_before>import fetch from 'isomorphic-fetch';

import {REQUEST_KEYS, RECIEVE_KEYS, RECIEVE_VALUE} from '../constants/keyValueTypes';

export function requestKeys = (namespace) => ({ type: REQUEST_KEYS, namespace})
export function receiveKeys = (keys) => ({ type: RECEIVE_KEYS, keys, recievedAt: Date.now()})
export function recieveValue = (value) => ({ type: RECIEVE_VALUE, value, recievedAt: Date.now()})

export function getKeys = function(namespace){
  return dispatch => {
    dispatch(requestKeys(namespace));
    return fetch(`https://play.dhis2.org/test/api/25/dataStore/${namespace}`, {
      method: "GET",
      mode: "cors",
      headers: {
        "Authorization": `Basic ${btoa("admin:district")}`,
        "Accept": "application/json",
        "Content-Type": "application/json"
      }
    }).then(response => {
      return response.json();
    }).then(json => {
      getValues(json, namespace);
      dispatch(receiveKeys(json));
    }).catch(error => {
      console.log(error.message);
    });
}

export function getValues(keys, namespace) {
  keys.map((key) => {
    return dispatch => {
      return fetch(`https://play.dhis2.org/test/api/25/dataStore/${namespace}/${key}`, {
        method: "GET",
        mode: "cors",
        headers: {
          "Authorization": `Basic ${btoa("admin:district")}`,
          "Accept": "application/json",
          "Content-Type": "application/json"
        }
      }).then(response => {
        return response.json();
      }).then(json => {
        dispatch(recieveValue(json));
      }.catch(error => {
        console.log(error.message);
      });
    }
  }
}
<commit_msg>Fixed arrow function syntax<commit_after>import fetch from 'isomorphic-fetch';

import {REQUEST_KEYS, RECIEVE_KEYS, RECIEVE_VALUE} from '../constants/keyValueTypes';

export const requestKeys = namespace => ({ type: REQUEST_KEYS, namespace})
export const receiveKeys = keys => ({ type: RECEIVE_KEYS, keys, recievedAt: Date.now()})
export const recieveValue = value => ({ type: RECIEVE_VALUE, value, recievedAt: Date.now()})

export function getKeys = function(namespace){
  return dispatch => {
    dispatch(requestKeys(namespace));
    return fetch(`https://play.dhis2.org/test/api/25/dataStore/${namespace}`, {
      method: "GET",
      mode: "cors",
      headers: {
        "Authorization": `Basic ${btoa("admin:district")}`,
        "Accept": "application/json",
        "Content-Type": "application/json"
      }
    }).then(response => {
      return response.json();
    }).then(json => {
      getValues(json, namespace);
      dispatch(receiveKeys(json));
    }).catch(error => {
      console.log(error.message);
    });
}

export function getValues(keys, namespace) {
  keys.map((key) => {
    return dispatch => {
      return fetch(`https://play.dhis2.org/test/api/25/dataStore/${namespace}/${key}`, {
        method: "GET",
        mode: "cors",
        headers: {
          "Authorization": `Basic ${btoa("admin:district")}`,
          "Accept": "application/json",
          "Content-Type": "application/json"
        }
      }).then(response => {
        return response.json();
      }).then(json => {
        dispatch(recieveValue(json));
      }.catch(error => {
        console.log(error.message);
      });
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    sg_release: {
      release: {
        options: {
          skipBowerInstall: true,
          files: ['package.json'],
          commitMessagePrefix: '',
          pushTo: 'origin',
          commitFiles: ['-a']
        }
      }
    }
  });

  grunt.registerTask('release', 'Makes a new release tag of your application to your Git repo', [
    'sg_release'
  ]);
}
<commit_msg>Release v0.10.0<commit_after>'use strict';

module.exports = function (grunt) {

  // Load grunt tasks automatically
  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    sg_release: {
      release: {
        options: {
          skipBowerInstall: true,
          tagName: 'v%VERSION%',
          files: ['package.json'],
          commitMessagePrefix: '',
          pushTo: 'origin',
          commitFiles: ['-a']
        }
      }
    }
  });

  grunt.registerTask('release', 'Makes a new release tag of your application to your Git repo', [
    'sg_release'
  ]);
}
<|endoftext|>


<commit_before>$(document).ready(function() {
    var mapCanvas = $('#map-canvas');
    var mapOptions = {
	center: { lat: 60.1841396, lng: 24.8300838 },
	zoom: 12
    };
    var map = new google.maps.Map(mapCanvas[0], mapOptions);
    map.data.setStyle(function(feature) {
	var type = feature.getProperty('type');
	var title = feature.getProperty('predtype');
	if (type === 'Prediction') {
	    var pointColor = 'magenta';
	    switch(feature.getProperty('activity')) {
	    case 'UNSPECIFIED':
		pointColor = 'yellow';
		break;
	    default:
		pointColor = 'black';
	    } // end-of-switch
	    return {
		icon: {
		    path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
		    scale: 3,
		    fillColor: pointColor,
		    fillOpacity: 1.0,
		    strokeColor: 'white'
		},
		title: title
	    };
	} else if (type === 'something_else') {
	    return {
		icon: {
		    path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
		    scale: 3,
		    fillColor: 'yellow',
		    fillOpacity: 1.0,
		    strokeColor: 'black'
		},
		title: title
	    };
	}
    });

	/* map.data.forEach(function(feature) {
	    map.data.remove(feature);
	} */
	$.getJSON('../predict/' + device_id, function(response) {
	    map.data.addGeoJson(response);
		/*
		if (response.features.length > 1) {
			var bounds = new google.maps.LatLngBounds();
			response.features.forEach(function (feature) {
				var coords = feature.geometry.coordinates;
		    	bounds.extend(new google.maps.LatLng(coords[1],coords[0]));
			});
			map.fitBounds(bounds);
		} */
	});
    });
<commit_msg>Streamlining prediction visualisation script v2.<commit_after>$(document).ready(function() {
    var mapCanvas = $('#map-canvas');
    var mapOptions = {
	center: { lat: 60.1841396, lng: 24.8300838 },
	zoom: 12
    };
    var map = new google.maps.Map(mapCanvas[0], mapOptions);
    map.data.setStyle(function(feature) {
	var type = feature.getProperty('type');
	var title = feature.getProperty('predtype');
	if (type === 'Prediction') {
	    var pointColor = 'magenta';
	    switch(feature.getProperty('activity')) {
	    case 'UNSPECIFIED':
		pointColor = 'yellow';
		break;
	    default:
		pointColor = 'black';
	    } // end-of-switch
	    return {
		icon: {
		    path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,
		    scale: 3,
		    fillColor: pointColor,
		    fillOpacity: 1.0,
		    strokeColor: 'blue'
		},
		title: title
	    };
	} else if (type === 'something_else') {
	    return {
		icon: {
		    path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
		    scale: 3,
		    fillColor: 'yellow',
		    fillOpacity: 1.0,
		    strokeColor: 'black'
		},
		title: title
	    };
	}
    });

	$.getJSON('../predict/' + device_id, function(response) {
	    map.data.addGeoJson(response);
	});
    });
<|endoftext|>


<commit_before>// Config file for Javascript minification and concatenation.
// See http://gruntjs.com/

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-mincss');
  grunt.loadNpmTasks('grunt-livescript');
  grunt.loadNpmTasks('grunt-wrap');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  var debikiDesktopFiles = [
      'client/vendor/bootstrap-tooltip.js', //
      'client/vendor/diff_match_patch.js',
      'client/vendor/html-sanitizer-bundle.js',
      'client/vendor/javascript-yaml-parser.js',
      'client/vendor/jquery-cookie.js',
      'client/vendor/jquery-scrollable.js', //
      'client/vendor/livescript/prelude-browser.js',
      'client/vendor/popuplib.js',
      'client/vendor/waypoints.js',
      'client/debiki/tagdog.js',
      'target/client/debiki/bootstrap-angularjs.js',
      'target/client/debiki/debiki-action-delete.js',
      'target/client/debiki/debiki-action-dialogs.js',
      'target/client/debiki/debiki-action-edit.js',
      'target/client/debiki/debiki-action-flag.js',
      'target/client/debiki/debiki-action-links.js',
      'target/client/debiki/debiki-action-rate.js',
      'target/client/debiki/debiki-action-reply.js',
      'target/client/debiki/debiki-actions-inline.js',
      'target/client/debiki/debiki-arrows-png.js',
      'target/client/debiki/debiki-arrows-svg.js',
      'target/client/debiki/debiki-cur-user.js',
      'target/client/debiki/debiki-diff-match-patch.js',
      'target/client/debiki/debiki-edit-history.js',
      'target/client/debiki/debiki-form-anims.js',
      'target/client/debiki/debiki-http-dialogs.js',
      'target/client/debiki/debiki-inline-threads.js',
      'target/client/debiki/debiki-jquery-dialogs.js',
      'target/client/debiki/debiki-jquery-find.js',
      'target/client/debiki/debiki-keyboard-shortcuts.js', //
      'target/client/debiki/debiki-layout.js',
      'target/client/debiki/debiki-login-guest.js',
      'target/client/debiki/debiki-login.js',
      'target/client/debiki/debiki-login-openid.js',
      'target/client/debiki/debiki-logout-dialog.js',
      'target/client/debiki/debiki-markup.js',
      'target/client/debiki/debiki-merge-changes.js',
      'target/client/debiki/debiki-monitor-reading-progress.js',
      'target/client/debiki/debiki-patch-page.js',
      'target/client/debiki/debiki-post-header.js',
      'target/client/debiki/debiki-resize.js',
      'target/client/debiki/debiki-scroll-into-view.js',
      'target/client/debiki/debiki-show-and-highlight.js',
      'target/client/debiki/debiki-show-interactions.js',
      'target/client/debiki/debiki-show-location-in-nav.js',
      'target/client/debiki/debiki-toggle-collapsed.js',
      //'target/client/debiki/debiki-unread.js',
      'target/client/debiki/debiki-util.js',
      'target/client/debiki/debiki-util-browser.js',
      'target/client/debiki/debiki-util-play.js',
      'target/client/debiki/debiki-utterscroll-init-tips.js',//
      'client/debiki/debiki-utterscroll.js',//
      'target/client/debiki/debiki-forum.js',
      'target/client/debiki/debiki-page-path.js',
      'target/client/debiki/debiki-create-page.js',
      'target/client/debiki/debiki.js']

  var debikiTouchFiles = [
      'client/vendor/diff_match_patch.js',
      'client/vendor/html-sanitizer-bundle.js',
      'client/vendor/javascript-yaml-parser.js',
      'client/vendor/jquery-cookie.js',
      'client/vendor/livescript/prelude-browser.js',
      'client/vendor/popuplib.js',
      'client/vendor/waypoints.js',
      'client/debiki/tagdog.js',
      'target/client/debiki/android-zoom-bug-workaround.js', //
      'target/client/debiki/bootstrap-angularjs.js',
      'target/client/debiki/debiki-action-delete.js',
      'target/client/debiki/debiki-action-dialogs.js',
      'target/client/debiki/debiki-action-edit.js',
      'target/client/debiki/debiki-action-flag.js',
      'target/client/debiki/debiki-action-links.js',
      'target/client/debiki/debiki-action-rate.js',
      'target/client/debiki/debiki-action-reply.js',
      'target/client/debiki/debiki-actions-inline.js',
      'target/client/debiki/debiki-arrows-png.js',
      'target/client/debiki/debiki-arrows-svg.js',
      'target/client/debiki/debiki-cur-user.js',
      'target/client/debiki/debiki-diff-match-patch.js',
      'target/client/debiki/debiki-edit-history.js',
      'target/client/debiki/debiki-form-anims.js',
      'target/client/debiki/debiki-http-dialogs.js',
      'target/client/debiki/debiki-inline-threads.js',
      'target/client/debiki/debiki-jquery-dialogs.js',
      'target/client/debiki/debiki-jquery-find.js',
      'target/client/debiki/debiki-layout.js',
      'target/client/debiki/debiki-login-guest.js',
      'target/client/debiki/debiki-login.js',
      'target/client/debiki/debiki-login-openid.js',
      'target/client/debiki/debiki-logout-dialog.js',
      'target/client/debiki/debiki-markup.js',
      'target/client/debiki/debiki-merge-changes.js',
      'target/client/debiki/debiki-monitor-reading-progress.js',
      'target/client/debiki/debiki-patch-page.js',
      'target/client/debiki/debiki-post-header.js',
      'target/client/debiki/debiki-resize.js',
      'target/client/debiki/debiki-scroll-into-view.js',
      'target/client/debiki/debiki-show-and-highlight.js',
      'target/client/debiki/debiki-show-interactions.js',
      'target/client/debiki/debiki-show-location-in-nav.js',
      'target/client/debiki/debiki-toggle-collapsed.js',
      //'target/client/debiki/debiki-unread.js',
      'target/client/debiki/debiki-util.js',
      'target/client/debiki/debiki-util-browser.js',
      'target/client/debiki/debiki-util-play.js',
      'target/client/debiki/debiki-forum.js',
      'target/client/debiki/debiki-page-path.js',
      'target/client/debiki/debiki-create-page.js',
      'target/client/debiki/debiki.js']

  grunt.initConfig({
    pkg: '<json:package.json>',
    banner: grunt.file.read('client/banner.js'),
    meta: {
      name: 'debiki-app-play',
      banner: '<%= banner %>'
    },
    livescript: {
      options: {
        // See https://github.com/DavidSouther/grunt-livescript/blob/master/tasks/livescript.js
      },
      src: {
        files: {
          // This doesn't work any more:
          // Transpiled files will appear in target/client/**/*.js.
          //'target/client/*.js': 'client/**/*.ls'
          // Instead, COULD refactor this to:
          //   single-file.js: all/files/in/dir/*.ls

          'target/client/debiki/debiki-forum.js': 'client/debiki/debiki-forum.ls',
          'target/client/debiki/debiki-dashbar.js': 'client/debiki/debiki-dashbar.ls',
          'target/client/debiki/debiki-toggle-collapsed.js': 'client/debiki/debiki-toggle-collapsed.ls',
          'target/client/debiki/debiki-diff-match-patch.js': 'client/debiki/debiki-diff-match-patch.ls',
          'target/client/debiki/debiki-action-dialogs.js': 'client/debiki/debiki-action-dialogs.ls',
          'target/client/debiki/debiki-unread.js': 'client/debiki/debiki-unread.ls',
          'target/client/debiki/debiki-monitor-reading-progress.js': 'client/debiki/debiki-monitor-reading-progress.ls',
          'target/client/debiki/debiki-page-path.js': 'client/debiki/debiki-page-path.ls',
          'target/client/debiki/debiki-create-page.js': 'client/debiki/debiki-create-page.ls',
          'target/client/debiki/debiki-layout.js': 'client/debiki/debiki-layout.ls',
          'target/client/debiki/bootstrap-angularjs.js': 'client/debiki/bootstrap-angularjs.ls',
          'target/client/debiki/debiki-patch-page.js': 'client/debiki/debiki-patch-page.ls',
          'target/client/spa/install/install-ng-app.js': 'client/spa/install/install-ng-app.ls',
          'target/client/spa/admin/js/users.js': 'client/spa/admin/js/users.ls',
          'target/client/spa/admin/js/activity.js': 'client/spa/admin/js/activity.ls',
          'target/client/spa/admin/js/debiki-v0-server-mock.js': 'client/spa/admin/js/debiki-v0-server-mock.ls',
          'target/client/spa/admin/js/modal-dialog.js': 'client/spa/admin/js/modal-dialog.ls',
          'target/client/spa/admin/js/contents.js': 'client/spa/admin/js/contents.ls',
          'target/client/spa/admin/js/module-and-services.js': 'client/spa/admin/js/module-and-services.ls',
          'target/client/spa/js/new-website-choose-name.js': 'client/spa/js/new-website-choose-name.ls',
          'target/client/spa/js/new-website-choose-owner.js': 'client/spa/js/new-website-choose-owner.ls'
        }
      }
    },
    wrap: {
      javascript: {
        src: 'client/**/*.js',
        // Files will appear in target/client/**/*.js — apparently,
        // the whole `src` path is appendet to `dest` (unlike the
        // `livescript` task above, which only appends the `/**/*.ls`
        // path to the destination path).
        dest: 'target/',
        wrapper: ['(function() {\n', '\n}).call(this);']
      }
    },
    concat: {
      options: {
        // See https://npmjs.org/package/grunt-contrib-concat
      },
      dist: {
       files: {
        'public/res/combined-debiki.css': [
            'client/banner.css',
            'public/res/jquery-ui/jquery-ui-1.8.16.custom.css',
            'client/debiki/debiki.css',
            'client/debiki/debiki-play.css'],

        'public/res/admin.css': [
            'client/admin/admin-theme.css',
            'client/spa/admin/css/admin-page.css',
            'client/spa/debiki-spa-common.css'],

        'public/res/combined-debiki-desktop.js':
            debikiDesktopFiles,

        'public/res/combined-debiki-touch.js':
            debikiTouchFiles,

        'public/res/debiki-spa-common.js': [
            'target/client/vendor/livescript/prelude-browser-min.js',
            'target/client/vendor/bootstrap-tooltip.js', // -popup.js dependee
            'target/client/vendor/bootstrap-*.js',
            'target/client/vendor/angular-ui/module.js',
            'target/client/vendor/angular-ui/directives/jq/jq.js',
            'target/client/vendor/angular-ui/directives/modal/modal.js',
            'target/client/debiki/debiki-util.js',
            'target/client/spa/js/angular-util.js'],

        'public/res/debiki-spa-admin.js': [
            'client/vendor/diff_match_patch.js',
            'target/client/debiki/debiki-diff-match-patch.js',
            'target/client/debiki/debiki-page-path.js',
            'target/client/spa/admin/js/*.js',
            'target/client/spa/admin/js/modal-dialog.js'], // requires AngularJS module

        'public/res/debiki-spa-install-first-site.js': [
            'target/client/spa/install/install-ng-app.js'],

        'public/res/debiki-spa-admin-server-mock.js': [
            'target/client/spa/admin/js/debiki-v0-server-mock.js'],

        'public/res/debiki-spa-new-website-choose-owner.js': [
            'target/client/spa/js/new-website-choose-owner.js'],

        'public/res/debiki-spa-new-website-choose-name.js': [
            'target/client/spa/js/new-website-choose-name.js'],

        'public/res/debiki-dashbar.js': [
            'target/client/debiki/debiki-dashbar.js'],

        'public/res/debiki-pagedown.js': [
          'modules/pagedown/Markdown.Converter.js',
          'client/compiledjs/PagedownJavaInterface.js']
       }
      },
    },
    uglify: {
      all: {
        options: {}, // see https://npmjs.org/package/grunt-contrib-uglify
        files: {
          'public/res/combined-debiki-desktop.min.js': [
              '<banner>',
              'public/res/combined-debiki-desktop.js'],

          'public/res/combined-debiki-touch.min.js': [
              '<banner>',
              'public/res/combined-debiki-touch.js'],

          'public/res/debiki-pagedown.min.js': [
              'public/res/debiki-pagedown.js']
        }
      }
    },
    /*
    // This results in malfunctioning CSS?
    // And a """Warning: Object #<Object> has no method 'expandFiles'
    // Use --force to continue.""" error, as of Grunt v0.4.1 (May 2013),
    // see <https://github.com/gruntjs/grunt/wiki/Configuring-tasks
    //        #building-the-files-object-dynamically>
    // for info on how to perhaps fix that error.
    mincss: {
      compress: {
        files: {
          'public/res/combined-debiki.min.css': [
            'public/res/combined-debiki.css']
        }
      }
    }, */
    watch: {
      all: {
        files: [
            'client/**/*.js',
            'client/**/*.ls',
            'client/**/*.css'],
        tasks: ['default'],
        options: {
          interrupt: true
        }
      }
    }
  });

  grunt.registerTask('default', ['livescript', 'wrap', 'concat', 'uglify']); //, 'mincss']);

};

// vim: et ts=2 sw=2 list
<commit_msg>Build LiveScript target file list automatically<commit_after>// Config file for Javascript minification and concatenation.
// See http://gruntjs.com/

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-mincss');
  grunt.loadNpmTasks('grunt-livescript');
  grunt.loadNpmTasks('grunt-wrap');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-uglify');

  var debikiDesktopFiles = [
      'client/vendor/bootstrap-tooltip.js', //
      'client/vendor/diff_match_patch.js',
      'client/vendor/html-sanitizer-bundle.js',
      'client/vendor/javascript-yaml-parser.js',
      'client/vendor/jquery-cookie.js',
      'client/vendor/jquery-scrollable.js', //
      'client/vendor/livescript/prelude-browser.js',
      'client/vendor/popuplib.js',
      'client/vendor/waypoints.js',
      'client/debiki/tagdog.js',
      'target/client/debiki/bootstrap-angularjs.js',
      'target/client/debiki/debiki-action-delete.js',
      'target/client/debiki/debiki-action-dialogs.js',
      'target/client/debiki/debiki-action-edit.js',
      'target/client/debiki/debiki-action-flag.js',
      'target/client/debiki/debiki-action-links.js',
      'target/client/debiki/debiki-action-rate.js',
      'target/client/debiki/debiki-action-reply.js',
      'target/client/debiki/debiki-actions-inline.js',
      'target/client/debiki/debiki-arrows-png.js',
      'target/client/debiki/debiki-arrows-svg.js',
      'target/client/debiki/debiki-cur-user.js',
      'target/client/debiki/debiki-diff-match-patch.js',
      'target/client/debiki/debiki-edit-history.js',
      'target/client/debiki/debiki-form-anims.js',
      'target/client/debiki/debiki-http-dialogs.js',
      'target/client/debiki/debiki-inline-threads.js',
      'target/client/debiki/debiki-jquery-dialogs.js',
      'target/client/debiki/debiki-jquery-find.js',
      'target/client/debiki/debiki-keyboard-shortcuts.js', //
      'target/client/debiki/debiki-layout.js',
      'target/client/debiki/debiki-login-guest.js',
      'target/client/debiki/debiki-login.js',
      'target/client/debiki/debiki-login-openid.js',
      'target/client/debiki/debiki-logout-dialog.js',
      'target/client/debiki/debiki-markup.js',
      'target/client/debiki/debiki-merge-changes.js',
      'target/client/debiki/debiki-monitor-reading-progress.js',
      'target/client/debiki/debiki-patch-page.js',
      'target/client/debiki/debiki-post-header.js',
      'target/client/debiki/debiki-resize.js',
      'target/client/debiki/debiki-scroll-into-view.js',
      'target/client/debiki/debiki-show-and-highlight.js',
      'target/client/debiki/debiki-show-interactions.js',
      'target/client/debiki/debiki-show-location-in-nav.js',
      'target/client/debiki/debiki-toggle-collapsed.js',
      //'target/client/debiki/debiki-unread.js',
      'target/client/debiki/debiki-util.js',
      'target/client/debiki/debiki-util-browser.js',
      'target/client/debiki/debiki-util-play.js',
      'target/client/debiki/debiki-utterscroll-init-tips.js',//
      'client/debiki/debiki-utterscroll.js',//
      'target/client/debiki/debiki-forum.js',
      'target/client/debiki/debiki-page-path.js',
      'target/client/debiki/debiki-create-page.js',
      'target/client/debiki/debiki.js']

  var debikiTouchFiles = [
      'client/vendor/diff_match_patch.js',
      'client/vendor/html-sanitizer-bundle.js',
      'client/vendor/javascript-yaml-parser.js',
      'client/vendor/jquery-cookie.js',
      'client/vendor/livescript/prelude-browser.js',
      'client/vendor/popuplib.js',
      'client/vendor/waypoints.js',
      'client/debiki/tagdog.js',
      'target/client/debiki/android-zoom-bug-workaround.js', //
      'target/client/debiki/bootstrap-angularjs.js',
      'target/client/debiki/debiki-action-delete.js',
      'target/client/debiki/debiki-action-dialogs.js',
      'target/client/debiki/debiki-action-edit.js',
      'target/client/debiki/debiki-action-flag.js',
      'target/client/debiki/debiki-action-links.js',
      'target/client/debiki/debiki-action-rate.js',
      'target/client/debiki/debiki-action-reply.js',
      'target/client/debiki/debiki-actions-inline.js',
      'target/client/debiki/debiki-arrows-png.js',
      'target/client/debiki/debiki-arrows-svg.js',
      'target/client/debiki/debiki-cur-user.js',
      'target/client/debiki/debiki-diff-match-patch.js',
      'target/client/debiki/debiki-edit-history.js',
      'target/client/debiki/debiki-form-anims.js',
      'target/client/debiki/debiki-http-dialogs.js',
      'target/client/debiki/debiki-inline-threads.js',
      'target/client/debiki/debiki-jquery-dialogs.js',
      'target/client/debiki/debiki-jquery-find.js',
      'target/client/debiki/debiki-layout.js',
      'target/client/debiki/debiki-login-guest.js',
      'target/client/debiki/debiki-login.js',
      'target/client/debiki/debiki-login-openid.js',
      'target/client/debiki/debiki-logout-dialog.js',
      'target/client/debiki/debiki-markup.js',
      'target/client/debiki/debiki-merge-changes.js',
      'target/client/debiki/debiki-monitor-reading-progress.js',
      'target/client/debiki/debiki-patch-page.js',
      'target/client/debiki/debiki-post-header.js',
      'target/client/debiki/debiki-resize.js',
      'target/client/debiki/debiki-scroll-into-view.js',
      'target/client/debiki/debiki-show-and-highlight.js',
      'target/client/debiki/debiki-show-interactions.js',
      'target/client/debiki/debiki-show-location-in-nav.js',
      'target/client/debiki/debiki-toggle-collapsed.js',
      //'target/client/debiki/debiki-unread.js',
      'target/client/debiki/debiki-util.js',
      'target/client/debiki/debiki-util-browser.js',
      'target/client/debiki/debiki-util-play.js',
      'target/client/debiki/debiki-forum.js',
      'target/client/debiki/debiki-page-path.js',
      'target/client/debiki/debiki-create-page.js',
      'target/client/debiki/debiki.js']

  grunt.initConfig({
    pkg: '<json:package.json>',
    banner: grunt.file.read('client/banner.js'),
    meta: {
      name: 'debiki-app-play',
      banner: '<%= banner %>'
    },
    livescript: {
      options: {
        // See <https://github.com/DavidSouther/grunt-livescript/blob/master/
        //        tasks/livescript.js>
      },
      src: {
        files: [{
          // Transpiled files will appear in target/client/**/*.js.
          expand: true,
          cwd: 'client/',
          src: '**/*.ls',
          dest: 'target/client',
          ext: '.js'
        }]
      }
    },
    wrap: {
      javascript: {
        src: 'client/**/*.js',
        // Files will appear in target/client/**/*.js — apparently,
        // the whole `src` path is appendet to `dest` (unlike the
        // `livescript` task above, which only appends the `/**/*.ls`
        // path to the destination path).
        dest: 'target/',
        wrapper: ['(function() {\n', '\n}).call(this);']
      }
    },
    concat: {
      options: {
        // See https://npmjs.org/package/grunt-contrib-concat
      },
      dist: {
       files: {
        'public/res/combined-debiki.css': [
            'client/banner.css',
            'public/res/jquery-ui/jquery-ui-1.8.16.custom.css',
            'client/debiki/debiki.css',
            'client/debiki/debiki-play.css'],

        'public/res/admin.css': [
            'client/admin/admin-theme.css',
            'client/spa/admin/css/admin-page.css',
            'client/spa/debiki-spa-common.css'],

        'public/res/combined-debiki-desktop.js':
            debikiDesktopFiles,

        'public/res/combined-debiki-touch.js':
            debikiTouchFiles,

        'public/res/debiki-spa-common.js': [
            'target/client/vendor/livescript/prelude-browser-min.js',
            'target/client/vendor/bootstrap-tooltip.js', // -popup.js dependee
            'target/client/vendor/bootstrap-*.js',
            'target/client/vendor/angular-ui/module.js',
            'target/client/vendor/angular-ui/directives/jq/jq.js',
            'target/client/vendor/angular-ui/directives/modal/modal.js',
            'target/client/debiki/debiki-util.js',
            'target/client/spa/js/angular-util.js'],

        'public/res/debiki-spa-admin.js': [
            'client/vendor/diff_match_patch.js',
            'target/client/debiki/debiki-diff-match-patch.js',
            'target/client/debiki/debiki-page-path.js',
            'target/client/spa/admin/js/*.js',
            'target/client/spa/admin/js/modal-dialog.js'], // requires AngularJS module

        'public/res/debiki-spa-install-first-site.js': [
            'target/client/spa/install/install-ng-app.js'],

        'public/res/debiki-spa-admin-server-mock.js': [
            'target/client/spa/admin/js/debiki-v0-server-mock.js'],

        'public/res/debiki-spa-new-website-choose-owner.js': [
            'target/client/spa/js/new-website-choose-owner.js'],

        'public/res/debiki-spa-new-website-choose-name.js': [
            'target/client/spa/js/new-website-choose-name.js'],

        'public/res/debiki-dashbar.js': [
            'target/client/debiki/debiki-dashbar.js'],

        'public/res/debiki-pagedown.js': [
          'modules/pagedown/Markdown.Converter.js',
          'client/compiledjs/PagedownJavaInterface.js']
       }
      },
    },
    uglify: {
      all: {
        options: {}, // see https://npmjs.org/package/grunt-contrib-uglify
        files: {
          'public/res/combined-debiki-desktop.min.js': [
              '<banner>',
              'public/res/combined-debiki-desktop.js'],

          'public/res/combined-debiki-touch.min.js': [
              '<banner>',
              'public/res/combined-debiki-touch.js'],

          'public/res/debiki-pagedown.min.js': [
              'public/res/debiki-pagedown.js']
        }
      }
    },
    /*
    // This results in malfunctioning CSS?
    // And a """Warning: Object #<Object> has no method 'expandFiles'
    // Use --force to continue.""" error, as of Grunt v0.4.1 (May 2013),
    // see <https://github.com/gruntjs/grunt/wiki/Configuring-tasks
    //        #building-the-files-object-dynamically>
    // for info on how to perhaps fix that error.
    mincss: {
      compress: {
        files: {
          'public/res/combined-debiki.min.css': [
            'public/res/combined-debiki.css']
        }
      }
    }, */
    watch: {
      all: {
        files: [
            'client/**/*.js',
            'client/**/*.ls',
            'client/**/*.css'],
        tasks: ['default'],
        options: {
          interrupt: true
        }
      }
    }
  });

  grunt.registerTask('default', ['livescript', 'wrap', 'concat', 'uglify']); //, 'mincss']);

};

// vim: et ts=2 sw=2 list
<|endoftext|>


<commit_before>// Utility function to get the value of a get request argument
function get(name){
   if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
   return decodeURIComponent(name[1]);
}

function pushDogeHistory() {
	history.pushState(null, null, "dogeify?userText=" + encodeURIComponent($('#userTextArea').val()))
	ga('send', 'pageview', "dogeify?userText=" + encodeURIComponent($('#userTextArea').val()));
}

// Send an ajax POST request, and handle/format the dogeified response.
function doDogeAjax(text) {
		  $.ajax({
		    'url' : '/dogeify',
		    'type' : 'POST',
		    'data' : {
		      'userText' : text
		    },
		  //The response from the server
		    'success' : function(data) {
		      if (data != "fail") {
				$('#dogeTextTitle').show();
				pushDogeHistory();
				$('#getResponse').html('');
				var dogePairs = data.list[1];
				for (var i = 0; i < dogePairs.length; i++) {
					var dogePair = dogePairs[i];
					var dogeText = dogePair[0];
					var color = dogePair[1];
					var div = $('')
					div.addClass("wow");
					div.css({'color': color});
					div.text(dogeText + " ");
					div.appendTo('#getResponse');
				};
		      }
		    }
		  });
}

function doLuckyAjax() {
          $.ajax({
            'url' : '/lucky',
          //The response from the server
            'success' : function(data) {
              if (data != "fail") {
		$('#dogeTextTitle').show();
                $('#getResponse').html('');
                var undogedText = data.list[0];
                $('#userTextArea').val(undogedText);
		pushDogeHistory();
                var dogePairs = data.list[1];
                for (var i = 0; i < dogePairs.length; i++) {
                    var dogePair = dogePairs[i];
                    var dogeText = dogePair[0];
                    var color = dogePair[1];
		    var div = $('')
		    div.addClass("wow");
		    div.css({'color': color});
		    div.text(dogeText + " ");
		    div.appendTo('#getResponse');
                };
              }
            }
          });
}

/**
 * Character Counter v1.5.1
 * ======================
 *
 * Character Counter is a simple, Twitter style character counter.
 *
 * https://github.com/dtisgodsson/jquery-character-counter
 *
 * @author Darren Taylor
 * @author Email: shout@darrenonthe.net
 * @author Twitter: darrentaytay
 * @author Website: http://darrenonthe.net
 *
 */
(function($) {

    $.fn.characterCounter = function(opts){

        var defaults = {
            exceeded: false,
            counterSelector: false,
            limit: 150,
            renderTotal: false,
            counterWrapper: 'span',
            counterCssClass: 'counter',
            counterFormat: '%1',
            counterExceededCssClass: 'exceeded',
            increaseCounting: false,
            onExceed: function(count) {},
            onDeceed: function(count) {},
            customFields: {}
        };

        var options = $.extend(defaults, opts);

        return this.each(function() {
            var html5len = $(this).attr('maxlength');
            if (typeof html5len !== typeof undefined && html5len !== false) {
                $.extend(defaults, {
                    limit: parseInt($(this).attr('maxlength'))
                });
            }
            if (!options.counterSelector) {
                $(this).after(generateCounter());
            }
            bindEvents(this);
            checkCount(this);
        });

        function customFields(params)
        {
            var i, html='';

            for (i in params)
            {
                html += ' ' + i + '="' + params[i] + '"';
            }

            return html;
        }

        function generateCounter()
        {
            var classString = options.counterCssClass;

            if ( options.customFields.class )
            {
                classString += " " + options.customFields.class;
                delete options.customFields['class'];
            }

            return '<'+ options.counterWrapper +customFields(options.customFields)+' class="' + classString + '"></'+ options.counterWrapper +'>';
        }

        function renderText(count)
        {
            var rendered_count = options.counterFormat.replace(/%1/, count);

            if ( options.renderTotal )
            {
                rendered_count += '/'+ options.limit;
            }

            return rendered_count;
        }

        function checkCount(element)
        {
            var characterCount = $(element).val().length;
            var counter = options.counterSelector ? $(options.counterSelector) : $(element).nextAll("." + options.counterCssClass).first();
            var remaining = options.limit - characterCount;
            var condition = remaining < 0;

            if ( options.increaseCounting )
            {
                remaining = characterCount;
                condition = remaining > options.limit;
            }

            if ( condition )
            {
                counter.addClass(options.counterExceededCssClass);
                options.exceeded = true;
                options.onExceed(characterCount);
            }
            else
            {
                if ( options.exceeded ) {
                    counter.removeClass(options.counterExceededCssClass);
                    options.onDeceed(characterCount);
                    options.exceeded = false;
                }
            }

            counter.html(renderText(remaining));
        }

        function bindEvents(element)
        {
            $(element)
                .on("input change", function () {
                    checkCount(element);
                });
        }
    };

})(jQuery);
<commit_msg>such scrollbar. wow. So top. how lucky.<commit_after>// Utility function to get the value of a get request argument
function get(name){
   if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
   return decodeURIComponent(name[1]);
}

function pushDogeHistory() {
	history.pushState(null, null, "dogeify?userText=" + encodeURIComponent($('#userTextArea').val()))
	ga('send', 'pageview', "dogeify?userText=" + encodeURIComponent($('#userTextArea').val()));
}

// Send an ajax POST request, and handle/format the dogeified response.
function doDogeAjax(text) {
		  $.ajax({
		    'url' : '/dogeify',
		    'type' : 'POST',
		    'data' : {
		      'userText' : text
		    },
		  //The response from the server
		    'success' : function(data) {
		      if (data != "fail") {
				$('#dogeTextTitle').show();
				pushDogeHistory();
				$('#getResponse').html('');
				var dogePairs = data.list[1];
				for (var i = 0; i < dogePairs.length; i++) {
					var dogePair = dogePairs[i];
					var dogeText = dogePair[0];
					var color = dogePair[1];
					var div = $('')
					div.addClass("wow");
					div.css({'color': color});
					div.text(dogeText + " ");
					div.appendTo('#getResponse');
				};
		      }
		    }
		  });
}

function doLuckyAjax() {
          $.ajax({
            'url' : '/lucky',
          //The response from the server
            'success' : function(data) {
              if (data != "fail") {
		$('#dogeTextTitle').show();
                $('#getResponse').html('');
                var undogedText = data.list[0];
                $('#userTextArea').val(undogedText);
		pushDogeHistory();
                var dogePairs = data.list[1];
                for (var i = 0; i < dogePairs.length; i++) {
                    var dogePair = dogePairs[i];
                    var dogeText = dogePair[0];
                    var color = dogePair[1];
		    var div = $('')
		    div.addClass("wow");
		    div.css({'color': color});
		    div.text(dogeText + " ");
		    div.appendTo('#getResponse');
                };

		// Scroll the textarea to the top so
		// the user can see the new input
                $('#userTextArea').scrollTop(0);
              }
            }
          });
}

/**
 * Character Counter v1.5.1
 * ======================
 *
 * Character Counter is a simple, Twitter style character counter.
 *
 * https://github.com/dtisgodsson/jquery-character-counter
 *
 * @author Darren Taylor
 * @author Email: shout@darrenonthe.net
 * @author Twitter: darrentaytay
 * @author Website: http://darrenonthe.net
 *
 */
(function($) {

    $.fn.characterCounter = function(opts){

        var defaults = {
            exceeded: false,
            counterSelector: false,
            limit: 150,
            renderTotal: false,
            counterWrapper: 'span',
            counterCssClass: 'counter',
            counterFormat: '%1',
            counterExceededCssClass: 'exceeded',
            increaseCounting: false,
            onExceed: function(count) {},
            onDeceed: function(count) {},
            customFields: {}
        };

        var options = $.extend(defaults, opts);

        return this.each(function() {
            var html5len = $(this).attr('maxlength');
            if (typeof html5len !== typeof undefined && html5len !== false) {
                $.extend(defaults, {
                    limit: parseInt($(this).attr('maxlength'))
                });
            }
            if (!options.counterSelector) {
                $(this).after(generateCounter());
            }
            bindEvents(this);
            checkCount(this);
        });

        function customFields(params)
        {
            var i, html='';

            for (i in params)
            {
                html += ' ' + i + '="' + params[i] + '"';
            }

            return html;
        }

        function generateCounter()
        {
            var classString = options.counterCssClass;

            if ( options.customFields.class )
            {
                classString += " " + options.customFields.class;
                delete options.customFields['class'];
            }

            return '<'+ options.counterWrapper +customFields(options.customFields)+' class="' + classString + '"></'+ options.counterWrapper +'>';
        }

        function renderText(count)
        {
            var rendered_count = options.counterFormat.replace(/%1/, count);

            if ( options.renderTotal )
            {
                rendered_count += '/'+ options.limit;
            }

            return rendered_count;
        }

        function checkCount(element)
        {
            var characterCount = $(element).val().length;
            var counter = options.counterSelector ? $(options.counterSelector) : $(element).nextAll("." + options.counterCssClass).first();
            var remaining = options.limit - characterCount;
            var condition = remaining < 0;

            if ( options.increaseCounting )
            {
                remaining = characterCount;
                condition = remaining > options.limit;
            }

            if ( condition )
            {
                counter.addClass(options.counterExceededCssClass);
                options.exceeded = true;
                options.onExceed(characterCount);
            }
            else
            {
                if ( options.exceeded ) {
                    counter.removeClass(options.counterExceededCssClass);
                    options.onDeceed(characterCount);
                    options.exceeded = false;
                }
            }

            counter.html(renderText(remaining));
        }

        function bindEvents(element)
        {
            $(element)
                .on("input change", function () {
                    checkCount(element);
                });
        }
    };

})(jQuery);
<|endoftext|>


<commit_before>module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-tizen');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-htmlmin');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadTasks('tools/grunt-tasks');

  grunt.initConfig({
    packageInfo: grunt.file.readJSON('package.json'),
    chromeInfo: grunt.file.readJSON('data/manifest.json'),

    clean: ['build'],

    tizen_configuration: {
      // location on the device to install the tizen-app.sh script to
      // (default: '/tmp')
      tizenAppScriptDir: '/home/developer/',

      // path to the config.xml file for the Tizen wgt file
      // (default: 'config.xml')
      configFile: 'data/config.xml',

      // path to the sdb command (default: process.env.SDB or 'sdb')
      sdbCmd: 'sdb'
    },

    // minify JS
    uglify: {
      dist: {
        files: {
          'build/app/js/annex.js': ['app/js/annex.js'],
          'build/app/js/scaleBody.js': ['app/js/scaleBody.js']
        }
      }
    },

    // minify CSS
    cssmin: {
      dist: {
        files: {
          'build/app/css/annex.css': ['app/css/annex.css'],
          'build/app/css/i18n.css': ['app/css/i18n.css']
        }
      }
    },

    copy: {
      common: {
        files: [
          { expand: true, cwd: '.', src: ['app/lib/**'], dest: 'build/' },
          { expand: true, cwd: '.', src: ['app/fonts/**'], dest: 'build/' },
          { expand: true, cwd: '.', src: ['app/audio/**'], dest: 'build/' },
          { expand: true, cwd: '.', src: ['LICENSE'], dest: 'build/app/' },
          { expand: true, cwd: '.', src: ['README.txt'], dest: 'build/app/' },
          { expand: true, cwd: '.', src: ['app/_locales/**'], dest: 'build/' }
        ]
      },
      wgt: {
        files: [
          { expand: true, cwd: 'build/app/', src: ['**'], dest: 'build/wgt/' },
          { expand: true, cwd: 'data/', src: ['config.xml'], dest: 'build/wgt/' },
          { expand: true, cwd: '.', src: ['icon_128.png'], dest: 'build/wgt/' }
        ]
      },
      crx: {
        files: [
          { expand: true, cwd: 'build/app/', src: ['**'], dest: 'build/crx/' },
          { expand: true, cwd: '.', src: ['manifest.json'], dest: 'build/crx/' },
          { expand: true, cwd: '.', src: ['icon*.png'], dest: 'build/crx/' }
        ]
      },
      sdk: {
        files: [
          { expand: true, cwd: 'build/app/', src: ['**'], dest: 'build/sdk/' },
          { expand: true, cwd: '.', src: ['app/css/*.css'], dest: 'build/sdk/css/' },
          { expand: true, cwd: '.', src: ['app/js/*.js'], dest: 'build/sdk/js/' },
          { expand: true, cwd: '.', src: ['app/*.html'], dest: 'build/sdk/' },
          { expand: true, cwd: 'data/', src: ['config.xml'], dest: 'build/sdk/' },
          { expand: true, cwd: '.', src: ['icon*.png'], dest: 'build/sdk/' }
        ]
      }
    },

    htmlmin: {
      dist: {
        files: [
          { expand: true, cwd: '.', src: ['app/*.html'], dest: 'build/' }
        ],
        options: {
          removeComments: true,
          collapseWhitespace: true,
          removeCommentsFromCDATA: false,
          removeCDATASectionsFromCDATA: false,
          removeEmptyAttributes: true,
          removeEmptyElements: false
        }
      }
    },

    imagemin: {
      dist: {
        options: {
          optimizationLevel: 3,
          progressive: true
        },
        files: [
          { expand: true, cwd: '.', src: ['app/images/**'], dest: 'build/' }
        ]
      }
    },

    // make wgt package in build/ directory
    package: {
      wgt: {
        appName: '<%= packageInfo.name %>',
        version: '<%= packageInfo.version %>',
        files: 'build/wgt/**',
        stripPrefix: 'build/wgt/',
        outDir: 'build',
        suffix: '.wgt',
        addGitCommitId: false
      },
      sdk: {
        appName: '<%= packageInfo.name %>',
        version: '<%= packageInfo.version %>',
        files: 'build/sdk/**',
        stripPrefix: 'build/sdk/',
        outDir: 'build',
        suffix: '.wgt',
      }
    },

    simple_server: {
      port: 30303,
      dir: 'build/app/'
    },

    tizen: {
      push: {
        action: 'push',
        localFiles: {
          pattern: 'build/*.wgt',
          filter: 'latest'
        },
        remoteDir: '/home/developer/'
      },

      install: {
        action: 'install',
        remoteFiles: {
          pattern: '/home/developer/annex*.wgt',
          filter: 'latest'
        }
      },

      uninstall: {
        action: 'uninstall'
      },

      start: {
        action: 'start',
        stopOnFailure: true
      },

      stop: {
        action: 'stop',
        stopOnFailure: false
      },

      debug: {
        action: 'debug',
        browserCmd: 'google-chrome %URL%',
        localPort: 9090,
        stopOnFailure: true
      }
    }
  });

  grunt.registerTask('dist', [
    'clean',
    'imagemin:dist',
    'uglify:dist',
    'cssmin:dist',
    'htmlmin:dist',
    'copy:common'
  ]);

  grunt.registerTask('crx', ['dist', 'copy:crx']);
  grunt.registerTask('wgt', ['dist', 'copy:wgt', 'package:wgt']);

  grunt.registerTask('sdk', [
    'clean',
    'imagemin:dist',
    'copy:common',
    'copy:sdk',
    'package:sdk'
  ]);

  grunt.registerTask('perf', [
    'dist',
    'uglify:perf',
    'inline',
    'copy:wgt',
    'package:wgt'
  ]);

  grunt.registerTask('install', [
    'tizen:push',
    'tizen:stop',
    'tizen:uninstall',
    'tizen:install',
    'tizen:start'
  ]);

  grunt.registerTask('wait', function () {
    var done = this.async();
    setTimeout(function () {
      done();
    }, 10000);
  });

  grunt.registerTask('restart', ['tizen:stop', 'tizen:start']);

  grunt.registerTask('server', ['dist', 'simple_server']);

  grunt.registerTask('wgt-install', ['wgt', 'install']);
  grunt.registerTask('sdk-install', ['sdk', 'install']);

  grunt.registerTask('default', 'wgt');
};
<commit_msg>Removing fonts/ from Gruntfile.js.<commit_after>module.exports = function (grunt) {

  grunt.loadNpmTasks('grunt-tizen');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-htmlmin');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadTasks('tools/grunt-tasks');

  grunt.initConfig({
    packageInfo: grunt.file.readJSON('package.json'),
    chromeInfo: grunt.file.readJSON('data/manifest.json'),

    clean: ['build'],

    tizen_configuration: {
      // location on the device to install the tizen-app.sh script to
      // (default: '/tmp')
      tizenAppScriptDir: '/home/developer/',

      // path to the config.xml file for the Tizen wgt file
      // (default: 'config.xml')
      configFile: 'data/config.xml',

      // path to the sdb command (default: process.env.SDB or 'sdb')
      sdbCmd: 'sdb'
    },

    // minify JS
    uglify: {
      dist: {
        files: {
          'build/app/js/annex.js': ['app/js/annex.js'],
          'build/app/js/scaleBody.js': ['app/js/scaleBody.js']
        }
      }
    },

    // minify CSS
    cssmin: {
      dist: {
        files: {
          'build/app/css/annex.css': ['app/css/annex.css'],
          'build/app/css/i18n.css': ['app/css/i18n.css']
        }
      }
    },

    copy: {
      common: {
        files: [
          { expand: true, cwd: '.', src: ['app/lib/**'], dest: 'build/' },
          { expand: true, cwd: '.', src: ['app/audio/**'], dest: 'build/' },
          { expand: true, cwd: '.', src: ['LICENSE'], dest: 'build/app/' },
          { expand: true, cwd: '.', src: ['README.txt'], dest: 'build/app/' },
          { expand: true, cwd: '.', src: ['app/_locales/**'], dest: 'build/' }
        ]
      },
      wgt: {
        files: [
          { expand: true, cwd: 'build/app/', src: ['**'], dest: 'build/wgt/' },
          { expand: true, cwd: 'data/', src: ['config.xml'], dest: 'build/wgt/' },
          { expand: true, cwd: '.', src: ['icon_128.png'], dest: 'build/wgt/' }
        ]
      },
      crx: {
        files: [
          { expand: true, cwd: 'build/app/', src: ['**'], dest: 'build/crx/' },
          { expand: true, cwd: '.', src: ['manifest.json'], dest: 'build/crx/' },
          { expand: true, cwd: '.', src: ['icon*.png'], dest: 'build/crx/' }
        ]
      },
      sdk: {
        files: [
          { expand: true, cwd: 'build/app/', src: ['**'], dest: 'build/sdk/' },
          { expand: true, cwd: '.', src: ['app/css/*.css'], dest: 'build/sdk/css/' },
          { expand: true, cwd: '.', src: ['app/js/*.js'], dest: 'build/sdk/js/' },
          { expand: true, cwd: '.', src: ['app/*.html'], dest: 'build/sdk/' },
          { expand: true, cwd: 'data/', src: ['config.xml'], dest: 'build/sdk/' },
          { expand: true, cwd: '.', src: ['icon*.png'], dest: 'build/sdk/' }
        ]
      }
    },

    htmlmin: {
      dist: {
        files: [
          { expand: true, cwd: '.', src: ['app/*.html'], dest: 'build/' }
        ],
        options: {
          removeComments: true,
          collapseWhitespace: true,
          removeCommentsFromCDATA: false,
          removeCDATASectionsFromCDATA: false,
          removeEmptyAttributes: true,
          removeEmptyElements: false
        }
      }
    },

    imagemin: {
      dist: {
        options: {
          optimizationLevel: 3,
          progressive: true
        },
        files: [
          { expand: true, cwd: '.', src: ['app/images/**'], dest: 'build/' }
        ]
      }
    },

    // make wgt package in build/ directory
    package: {
      wgt: {
        appName: '<%= packageInfo.name %>',
        version: '<%= packageInfo.version %>',
        files: 'build/wgt/**',
        stripPrefix: 'build/wgt/',
        outDir: 'build',
        suffix: '.wgt',
        addGitCommitId: false
      },
      sdk: {
        appName: '<%= packageInfo.name %>',
        version: '<%= packageInfo.version %>',
        files: 'build/sdk/**',
        stripPrefix: 'build/sdk/',
        outDir: 'build',
        suffix: '.wgt',
      }
    },

    simple_server: {
      port: 30303,
      dir: 'build/app/'
    },

    tizen: {
      push: {
        action: 'push',
        localFiles: {
          pattern: 'build/*.wgt',
          filter: 'latest'
        },
        remoteDir: '/home/developer/'
      },

      install: {
        action: 'install',
        remoteFiles: {
          pattern: '/home/developer/annex*.wgt',
          filter: 'latest'
        }
      },

      uninstall: {
        action: 'uninstall'
      },

      start: {
        action: 'start',
        stopOnFailure: true
      },

      stop: {
        action: 'stop',
        stopOnFailure: false
      },

      debug: {
        action: 'debug',
        browserCmd: 'google-chrome %URL%',
        localPort: 9090,
        stopOnFailure: true
      }
    }
  });

  grunt.registerTask('dist', [
    'clean',
    'imagemin:dist',
    'uglify:dist',
    'cssmin:dist',
    'htmlmin:dist',
    'copy:common'
  ]);

  grunt.registerTask('crx', ['dist', 'copy:crx']);
  grunt.registerTask('wgt', ['dist', 'copy:wgt', 'package:wgt']);

  grunt.registerTask('sdk', [
    'clean',
    'imagemin:dist',
    'copy:common',
    'copy:sdk',
    'package:sdk'
  ]);

  grunt.registerTask('perf', [
    'dist',
    'uglify:perf',
    'inline',
    'copy:wgt',
    'package:wgt'
  ]);

  grunt.registerTask('install', [
    'tizen:push',
    'tizen:stop',
    'tizen:uninstall',
    'tizen:install',
    'tizen:start'
  ]);

  grunt.registerTask('wait', function () {
    var done = this.async();
    setTimeout(function () {
      done();
    }, 10000);
  });

  grunt.registerTask('restart', ['tizen:stop', 'tizen:start']);

  grunt.registerTask('server', ['dist', 'simple_server']);

  grunt.registerTask('wgt-install', ['wgt', 'install']);
  grunt.registerTask('sdk-install', ['sdk', 'install']);

  grunt.registerTask('default', 'wgt');
};
<|endoftext|>