<commit_before>/*!
 * Bootstrap's Gruntfile
 * http://getbootstrap.com
 * Copyright 2013-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

module.exports = function (grunt) {
  'use strict';

  // Force use of Unix newlines
  grunt.util.linefeed = '\n';

  RegExp.quote = function (string) {
    return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
  };

  var fs = require('fs');
  var path = require('path');
  var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
  var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
  var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
  // var updateShrinkwrap = require('./grunt/shrinkwrap.js');

  // Project configuration.
  grunt.initConfig({

    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*!\n' +
            ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
            ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
            ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
            ' */\n',
    jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',

    // Task configuration.
    clean: {
      dist: ['dist', 'docs/dist']
    },

    jshint: {
      options: {
        jshintrc: 'js/.jshintrc'
      },
      grunt: {
        options: {
          jshintrc: 'grunt/.jshintrc'
        },
        src: ['Gruntfile.js', 'grunt/*.js']
      },
      src: {
        src: 'js/*.js'
      },
      test: {
        src: 'js/tests/unit/*.js'
      },
      assets: {
        src: ['docs/assets/js/_src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
      }
    },

    jscs: {
      options: {
        config: 'js/.jscsrc'
      },
      grunt: {
        options: {
          requireCamelCaseOrUpperCaseIdentifiers: null,
          requireParenthesesAroundIIFE: true
        },
        src: '<%= jshint.grunt.src %>'
      },
      src: {
        src: '<%= jshint.src.src %>'
      },
      test: {
        src: '<%= jshint.test.src %>'
      },
      assets: {
        options: {
          requireCamelCaseOrUpperCaseIdentifiers: null
        },
        src: '<%= jshint.assets.src %>'
      }
    },

    concat: {
      options: {
        banner: '<%= banner %>\n<%= jqueryCheck %>',
        stripBanners: false
      },
      bootstrap: {
        src: [
          'js/transition.js',
          'js/alert.js',
          'js/button.js',
          'js/carousel.js',
          'js/collapse.js',
          'js/dropdown.js',
          'js/modal.js',
          'js/tooltip.js',
          'js/popover.js',
          'js/scrollspy.js',
          'js/tab.js',
          'js/affix.js'
        ],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },

    uglify: {
      bootstrap: {
        options: {
          banner: '<%= banner %>'
        },
        src: '<%= concat.bootstrap.dest %>',
        dest: 'dist/js/<%= pkg.name %>.min.js'
      },
      customize: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/_vendor/less.min.js',
          'docs/assets/js/_vendor/jszip.min.js',
          'docs/assets/js/_vendor/uglify.min.js',
          'docs/assets/js/_vendor/blob.js',
          'docs/assets/js/_vendor/filesaver.js',
          'docs/assets/js/raw-files.min.js',
          'docs/assets/js/_src/customizer.js'
        ],
        dest: 'docs/assets/js/customize.min.js'
      },
      docsJs: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/_vendor/holder.js',
          'docs/assets/js/_src/application.js'
        ],
        dest: 'docs/assets/js/docs.min.js'
      }
    },

    qunit: {
      options: {
        inject: 'js/tests/unit/phantom.js'
      },
      files: 'js/tests/index.html'
    },

    less: {
      compileCore: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
        }
      },
      compileTheme: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>-theme.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
        }
      },
      minify: {
        options: {
          cleancss: true
        },
        files: {
          'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
          'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
        }
      }
    },

    autoprefixer: {
      options: {
        browsers: ['last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4', 'opera 12']
      },
      core: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>.css'
      },
      theme: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>-theme.css'
      },
      docs: {
        src: 'docs/assets/css/_src/docs.css'
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: ['**/*.css'],
        dest: 'docs/examples/'
      }
    },

    csslint: {
      options: {
        csslintrc: 'less/.csslintrc'
      },
      src: [
        'dist/css/bootstrap.css',
        'dist/css/bootstrap-theme.css'
      ],
      examples: [
        'docs/examples/**/*.css'
      ],
      docs: {
        options: {
          ids: false,
          'overqualified-elements': false
        },
        src: 'docs/assets/css/_src/docs.css'
      }
    },

    cssmin: {
      options: {
        compatibility: 'ie8',
        keepSpecialComments: '*',
        noAdvanced: true
      },
      docs: {
        src: [
          'docs/assets/css/_src/docs.css',
          'docs/assets/css/_src/pygments-manni.css'
        ],
        dest: 'docs/assets/css/docs.min.css'
      }
    },

    usebanner: {
      options: {
        position: 'top',
        banner: '<%= banner %>'
      },
      files: {
        src: 'dist/css/*.css'
      }
    },

    csscomb: {
      options: {
        config: 'less/.csscomb.json'
      },
      dist: {
        expand: true,
        cwd: 'dist/css/',
        src: ['*.css', '!*.min.css'],
        dest: 'dist/css/'
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: '**/*.css',
        dest: 'docs/examples/'
      },
      docs: {
        files: {
          'docs/assets/css/_src/docs.css': 'docs/assets/css/_src/docs.css'
        }
      }
    },

    copy: {
      fonts: {
        expand: true,
        src: 'fonts/*',
        dest: 'dist/'
      },
      docs: {
        expand: true,
        cwd: './dist',
        src: [
          '{css,js}/*.min.*',
          'css/*.map',
          'fonts/*'
        ],
        dest: 'docs/dist'
      }
    },

    connect: {
      server: {
        options: {
          port: 3000,
          base: '.'
        }
      }
    },

    jekyll: {
      docs: {}
    },

    jade: {
      compile: {
        options: {
          pretty: true,
          data: function () {
            var filePath = path.join(__dirname, 'less/variables.less');
            var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'});
            var parser = new BsLessdocParser(fileContent);
            return {sections: parser.parseFile()};
          }
        },
        files: {
          'docs/_includes/customizer-variables.html': 'docs/_jade/customizer-variables.jade',
          'docs/_includes/nav/customize.html': 'docs/_jade/customizer-nav.jade'
        }
      }
    },

    validation: {
      options: {
        charset: 'utf-8',
        doctype: 'HTML5',
        failHard: true,
        reset: true,
        relaxerror: [
          'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
          'Element img is missing required attribute src.'
        ]
      },
      files: {
        src: '_gh_pages/**/*.html'
      }
    },

    watch: {
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
      less: {
        files: 'less/*.less',
        tasks: 'less'
      }
    },

    sed: {
      versionNumber: {
        pattern: (function () {
          var old = grunt.option('oldver');
          return old ? RegExp.quote(old) : old;
        })(),
        replacement: grunt.option('newver'),
        recursive: true
      }
    },

    'saucelabs-qunit': {
      all: {
        options: {
          build: process.env.TRAVIS_JOB_ID,
          concurrency: 10,
          urls: ['http://127.0.0.1:3000/js/tests/index.html'],
          browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
        }
      }
    },

    exec: {
      npmUpdate: {
        command: 'npm update'
      },
    //   npmShrinkWrap: {
    //     command: 'npm shrinkwrap --dev'
    //   }
    }
  });

  // These plugins provide necessary tasks.
  require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
  require('time-grunt')(grunt);

  // Docs HTML validation task
  grunt.registerTask('validate-html', ['jekyll', 'validation']);

  // Test task.
  var testSubtasks = [];
  // Skip core tests if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') {
    testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
  }
  // Skip HTML validation if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') {
    testSubtasks.push('validate-html');
  }
  // Only run Sauce Labs tests if there's a Sauce access key
  if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
      // Skip Sauce if running a different subset of the test suite
      (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) {
    testSubtasks.push('connect');
    testSubtasks.push('saucelabs-qunit');
  }
  grunt.registerTask('test', testSubtasks);

  // JS distribution task.
  grunt.registerTask('dist-js', ['concat', 'uglify']);

  // CSS distribution task.
  grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
  grunt.registerTask('dist-css', ['less-compile', 'autoprefixer', 'usebanner', 'csscomb', 'less:minify', 'cssmin']);

  // Docs distribution task.
  grunt.registerTask('dist-docs', 'copy:docs');

  // Full distribution task.
  grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);

  // Default task.
  grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer']);

  // Version numbering task.
  // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
  // This can be overzealous, so its changes should always be manually reviewed!
  grunt.registerTask('change-version-number', 'sed');

  grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); });

  // task for building customizer
  grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
  grunt.registerTask('build-customizer-html', 'jade');
  grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
    var banner = grunt.template.process('<%= banner %>');
    generateRawFiles(grunt, banner);
  });

  // Task for updating the npm packages used by the Travis build.
  // grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
  // grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
};
<commit_msg>unfuck the gruntifle<commit_after>/*!
 * Bootstrap's Gruntfile
 * http://getbootstrap.com
 * Copyright 2013-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

module.exports = function (grunt) {
  'use strict';

  // Force use of Unix newlines
  grunt.util.linefeed = '\n';

  RegExp.quote = function (string) {
    return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
  };

  var fs = require('fs');
  var path = require('path');
  var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
  var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
  var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
  var updateShrinkwrap = require('./grunt/shrinkwrap.js');

  // Project configuration.
  grunt.initConfig({

    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*!\n' +
            ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
            ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
            ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
            ' */\n',
    jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',

    // Task configuration.
    clean: {
      dist: ['dist', 'docs/dist']
    },

    jshint: {
      options: {
        jshintrc: 'js/.jshintrc'
      },
      grunt: {
        options: {
          jshintrc: 'grunt/.jshintrc'
        },
        src: ['Gruntfile.js', 'grunt/*.js']
      },
      src: {
        src: 'js/*.js'
      },
      test: {
        src: 'js/tests/unit/*.js'
      },
      assets: {
        src: ['docs/assets/js/_src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
      }
    },

    jscs: {
      options: {
        config: 'js/.jscsrc'
      },
      grunt: {
        options: {
          requireCamelCaseOrUpperCaseIdentifiers: null,
          requireParenthesesAroundIIFE: true
        },
        src: '<%= jshint.grunt.src %>'
      },
      src: {
        src: '<%= jshint.src.src %>'
      },
      test: {
        src: '<%= jshint.test.src %>'
      },
      assets: {
        options: {
          requireCamelCaseOrUpperCaseIdentifiers: null
        },
        src: '<%= jshint.assets.src %>'
      }
    },

    concat: {
      options: {
        banner: '<%= banner %>\n<%= jqueryCheck %>',
        stripBanners: false
      },
      bootstrap: {
        src: [
          'js/transition.js',
          'js/alert.js',
          'js/button.js',
          'js/carousel.js',
          'js/collapse.js',
          'js/dropdown.js',
          'js/modal.js',
          'js/tooltip.js',
          'js/popover.js',
          'js/scrollspy.js',
          'js/tab.js',
          'js/affix.js'
        ],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },

    uglify: {
      bootstrap: {
        options: {
          banner: '<%= banner %>'
        },
        src: '<%= concat.bootstrap.dest %>',
        dest: 'dist/js/<%= pkg.name %>.min.js'
      },
      customize: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/_vendor/less.min.js',
          'docs/assets/js/_vendor/jszip.min.js',
          'docs/assets/js/_vendor/uglify.min.js',
          'docs/assets/js/_vendor/blob.js',
          'docs/assets/js/_vendor/filesaver.js',
          'docs/assets/js/raw-files.min.js',
          'docs/assets/js/_src/customizer.js'
        ],
        dest: 'docs/assets/js/customize.min.js'
      },
      docsJs: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/_vendor/holder.js',
          'docs/assets/js/_src/application.js'
        ],
        dest: 'docs/assets/js/docs.min.js'
      }
    },

    qunit: {
      options: {
        inject: 'js/tests/unit/phantom.js'
      },
      files: 'js/tests/index.html'
    },

    less: {
      compileCore: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
        }
      },
      compileTheme: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>-theme.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
        }
      },
      minify: {
        options: {
          cleancss: true
        },
        files: {
          'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
          'dist/css/<%= pkg.name %>-rtl.min.css': 'dist/css/<%= pkg.name %>-rtl.css',
          'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
        }
      }
    },

    autoprefixer: {
      options: {
        browsers: ['last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4', 'opera 12']
      },
      core: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>.css'
      },
      theme: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>-theme.css'
      },
      docs: {
        src: 'docs/assets/css/_src/docs.css'
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: ['**/*.css'],
        dest: 'docs/examples/'
      }
    },

    csslint: {
      options: {
        csslintrc: 'less/.csslintrc'
      },
      src: [
        'dist/css/bootstrap.css',
        'dist/css/bootstrap-theme.css'
      ],
      examples: [
        'docs/examples/**/*.css'
      ],
      docs: {
        options: {
          ids: false,
          'overqualified-elements': false
        },
        src: 'docs/assets/css/_src/docs.css'
      }
    },

    cssmin: {
      options: {
        compatibility: 'ie8',
        keepSpecialComments: '*'
      },
      docs: {
        src: [
          'docs/assets/css/_src/docs.css',
          'docs/assets/css/_src/pygments-manni.css'
        ],
        dest: 'docs/assets/css/docs.min.css'
      }
    },

    usebanner: {
      options: {
        position: 'top',
        banner: '<%= banner %>'
      },
      files: {
        src: 'dist/css/*.css'
      }
    },

    csscomb: {
      options: {
        config: 'less/.csscomb.json'
      },
      dist: {
        expand: true,
        cwd: 'dist/css/',
        src: ['*.css', '!*.min.css'],
        dest: 'dist/css/'
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: '**/*.css',
        dest: 'docs/examples/'
      },
      docs: {
        files: {
          'docs/assets/css/_src/docs.css': 'docs/assets/css/_src/docs.css'
        }
      }
    },

    copy: {
      fonts: {
        expand: true,
        src: 'fonts/*',
        dest: 'dist/'
      },
      docs: {
        expand: true,
        cwd: './dist',
        src: [
          '{css,js}/*.min.*',
          'css/*.map',
          'fonts/*'
        ],
        dest: 'docs/dist'
      }
    },

    connect: {
      server: {
        options: {
          port: 3000,
          base: '.'
        }
      }
    },

    jekyll: {
      docs: {}
    },

    jade: {
      compile: {
        options: {
          pretty: true,
          data: function () {
            var filePath = path.join(__dirname, 'less/variables.less');
            var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'});
            var parser = new BsLessdocParser(fileContent);
            return {sections: parser.parseFile()};
          }
        },
        files: {
          'docs/_includes/customizer-variables.html': 'docs/_jade/customizer-variables.jade',
          'docs/_includes/nav/customize.html': 'docs/_jade/customizer-nav.jade'
        }
      }
    },

    validation: {
      options: {
        charset: 'utf-8',
        doctype: 'HTML5',
        failHard: true,
        reset: true,
        relaxerror: [
          'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
          'Element img is missing required attribute src.'
        ]
      },
      files: {
        src: '_gh_pages/**/*.html'
      }
    },

    watch: {
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
      less: {
        files: 'less/*.less',
        tasks: 'less'
      }
    },

    sed: {
      versionNumber: {
        pattern: (function () {
          var old = grunt.option('oldver');
          return old ? RegExp.quote(old) : old;
        })(),
        replacement: grunt.option('newver'),
        recursive: true
      }
    },

    'saucelabs-qunit': {
      all: {
        options: {
          build: process.env.TRAVIS_JOB_ID,
          concurrency: 10,
          urls: ['http://127.0.0.1:3000/js/tests/index.html'],
          browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
        }
      }
    },

    exec: {
      npmUpdate: {
        command: 'npm update'
      },
      npmShrinkWrap: {
        command: 'npm shrinkwrap --dev'
      }
    }
  });

  // These plugins provide necessary tasks.
  require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
  require('time-grunt')(grunt);

  // Docs HTML validation task
  grunt.registerTask('validate-html', ['jekyll', 'validation']);

  // Test task.
  var testSubtasks = [];
  // Skip core tests if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') {
    testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
  }
  // Skip HTML validation if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') {
    testSubtasks.push('validate-html');
  }
  // Only run Sauce Labs tests if there's a Sauce access key
  if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
      // Skip Sauce if running a different subset of the test suite
      (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) {
    testSubtasks.push('connect');
    testSubtasks.push('saucelabs-qunit');
  }
  grunt.registerTask('test', testSubtasks);

  // JS distribution task.
  grunt.registerTask('dist-js', ['concat', 'uglify']);

  // CSS distribution task.
  grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
  grunt.registerTask('dist-css', ['less-compile', 'autoprefixer', 'usebanner', 'csscomb', 'less:minify', 'cssmin']);

  // Docs distribution task.
  grunt.registerTask('dist-docs', 'copy:docs');

  // Full distribution task.
  grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);

  // Default task.
  grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']);

  // Version numbering task.
  // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
  // This can be overzealous, so its changes should always be manually reviewed!
  grunt.registerTask('change-version-number', 'sed');

  grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); });

  // task for building customizer
  grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
  grunt.registerTask('build-customizer-html', 'jade');
  grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
    var banner = grunt.template.process('<%= banner %>');
    generateRawFiles(grunt, banner);
  });

  // Task for updating the npm packages used by the Travis build.
  grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
  grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
};
<|endoftext|>


<commit_before>/**
ProcessPuzzle User Interface
Backend agnostic, desktop like configurable, browser font-end based on MochaUI.
Copyright (C) 2011  Joe Kueser, Zsolt Zsuffa

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//ComponentStateManager.js
//= require_directory ../FundamentalTypes
//= require ../Singleton/Singleton.js

var ComponentStateManager = new Class({
   Implements: [Options, Class.Singleton],

   options: {
      stateUriTransformer: DefaultStateUriTransformer
   },

   //Constructors
   initialize: function( options ) { return this.check() || this.setUp( options ); },

   setUp : function( options ) {
      this.setOptions( options );
      this.stateMachine = new HashMap();
      this.stateUriTransformer = new this.options.stateUriTransformer( this );
   }.protect(),

   //Public accessor and mutator methods
   parse : function( sourceString ){
      var tokenizer = new StringTokenizer( sourceString, { delimiters : ';' } );
      while( tokenizer.hasMoreTokens() ){
         var token = tokenizer.nextToken();
         var componentName = token.substring( 0, token.indexOf( ":" ));
         var componentStateString = token.substring( token.indexOf( ":" ) +1 );
         var componentState = eval( "(" + componentStateString.trim() + ")" );

         this.storeCurrentState( componentName.trim(), componentState );
      };
   },

   reset : function() {
      this.stateMachine.clear();
   },

   resetStateFromUri: function( uri ){
      this.reset();
      this.stateUriTransformer.transformUriToState( uri );
   },

   retrieveCurrentState : function( componentName ){
      return this.stateMachine.get( componentName );
   },

   storeCurrentState : function( componentName, currentState ){
      if( componentName && currentState ) this.stateMachine.put( componentName, currentState );
   },

   toString: function(){
      var stateString = "";
      this.stateMachine.each( function( componentStateEntry, index ){
         if( stateString != "" ) stateString += "; ";

         stateString += componentStateEntry.getKey() + ": ";

         var valueString = "";
         var value = componentStateEntry.getValue();
         if( typeOf( value ) == "string" ) valueString = "'" + value + "'";
         else if( typeOf( value ) == "object" ){
            valueString = "{";
            for ( var property in value ) {
               if( valueString != "{" ) valueString += ", ";
               valueString += property + ": '" + value[property] + "'";
            }
            valueString += "}";
         }
         else valueString = "'" + value.toString() + "'";

         stateString += valueString;
      }, this );

      return stateString;
   },

   transformStateToUri: function(){
      return this.stateUriTransformer.transformStateToUri();
   },

   //Properties
   getStateUriTransformer: function() { return this.stateUriTransformer; }
});<commit_msg>Requires DefaultStateUriTransformer.js<commit_after>/**
ProcessPuzzle User Interface
Backend agnostic, desktop like configurable, browser font-end based on MochaUI.
Copyright (C) 2011  Joe Kueser, Zsolt Zsuffa

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//ComponentStateManager.js
//= require_directory ../FundamentalTypes
//= require ../Singleton/Singleton.js
//= require ../ComponentStateManager/DefaultStateUriTransformer.js

var ComponentStateManager = new Class({
   Implements: [Options, Class.Singleton],

   options: {
      stateUriTransformer: DefaultStateUriTransformer
   },

   //Constructors
   initialize: function( options ) { return this.check() || this.setUp( options ); },

   setUp : function( options ) {
      this.setOptions( options );
      this.stateMachine = new HashMap();
      this.stateUriTransformer = new this.options.stateUriTransformer( this );
   }.protect(),

   //Public accessor and mutator methods
   parse : function( sourceString ){
      var tokenizer = new StringTokenizer( sourceString, { delimiters : ';' } );
      while( tokenizer.hasMoreTokens() ){
         var token = tokenizer.nextToken();
         var componentName = token.substring( 0, token.indexOf( ":" ));
         var componentStateString = token.substring( token.indexOf( ":" ) +1 );
         var componentState = eval( "(" + componentStateString.trim() + ")" );

         this.storeCurrentState( componentName.trim(), componentState );
      };
   },

   reset : function() {
      this.stateMachine.clear();
   },

   resetStateFromUri: function( uri ){
      this.reset();
      this.stateUriTransformer.transformUriToState( uri );
   },

   retrieveCurrentState : function( componentName ){
      return this.stateMachine.get( componentName );
   },

   storeCurrentState : function( componentName, currentState ){
      if( componentName && currentState ) this.stateMachine.put( componentName, currentState );
   },

   toString: function(){
      var stateString = "";
      this.stateMachine.each( function( componentStateEntry, index ){
         if( stateString != "" ) stateString += "; ";

         stateString += componentStateEntry.getKey() + ": ";

         var valueString = "";
         var value = componentStateEntry.getValue();
         if( typeOf( value ) == "string" ) valueString = "'" + value + "'";
         else if( typeOf( value ) == "object" ){
            valueString = "{";
            for ( var property in value ) {
               if( valueString != "{" ) valueString += ", ";
               valueString += property + ": '" + value[property] + "'";
            }
            valueString += "}";
         }
         else valueString = "'" + value.toString() + "'";

         stateString += valueString;
      }, this );

      return stateString;
   },

   transformStateToUri: function(){
      return this.stateUriTransformer.transformStateToUri();
   },

   //Properties
   getStateUriTransformer: function() { return this.stateUriTransformer; }
});<|endoftext|>


<commit_before>/*
 * Generated on 2014-05-13
 * generator-assemble v0.4.11
 * https://github.com/assemble/generator-assemble
 *
 * Copyright (c) 2014 Hariadi Hinta
 * Licensed under the MIT license.
 */

'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// '<%= config.src %>/templates/pages/{,*/}*.hbs'
// use this if you want to match all subfolders:
// '<%= config.src %>/templates/pages/**/*.hbs'

module.exports = function(grunt) {

  require('time-grunt')(grunt);

  // Project configuration.
  grunt.initConfig({

    config: {
      assets: 'assets',
      src: 'src',
      dist: 'dist'
    },
    copy: {
      assets: {
        files: [
          {expand: true, cwd: '<%= config.assets %>', src: ['**'], dest: '<%= config.dist %>'},
        ]
      }
    },
    watch: {
      assemble: {
        files: ['<%= config.src %>/{content,pages,data,templates}/**/*.{md,hbs,yml}'],
        tasks: ['assemble']
      },
      assets: {
        files: [
          '<%= config.assets %>/{,*/}*.css',
          '<%= config.assets %>/{,*/}*.js',
          '<%= config.assets %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ],
        tasks: ['copy:assets']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= config.dist %>/{,*/}*.html',
          '<%= config.dist %>/{,*/}*.css',
          '<%= config.dist %>/{,*/}*.js',
          '<%= config.dist %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: '127.0.0.1'
      },
      livereload: {
        options: {
          open: true,
          base: [
            '<%= config.dist %>'
          ]
        }
      }
    },

    assemble: {
      options: {
        helpers: ['handlebars-helper-compose'],
        compose: {
          sep: '<!-- section -->'
        },
        marked: {
          gfm: true,
          tables: true,
          smartLists: true
        }
      },
      pages: {
        options: {
          flatten: true,
          collections: [{
            name: 'events',
            inflection: 'event'
          }],
          layout: '<%= config.src %>/templates/layouts/default.hbs',
          data: '<%= config.src %>/data/*.{json,yml}',
          partials: '<%= config.src %>/templates/partials/*.hbs'
        },
        files: {
          '<%= config.dist %>/': ['<%= config.src %>/pages/*.hbs',
          '<%= config.src %>/content/events/**/*.hbs']
        }
      }
    },

    // Before generating any new files,
    // remove any previously-created files.
    clean: ['<%= config.dist %>/**/*.{html,xml}']

  });

  grunt.loadNpmTasks('assemble');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.registerTask('server', [
    'clean',
    'assemble',
    'connect:livereload',
    'watch'
  ]);

  grunt.registerTask('build', [
    'clean',
    'copy:assets',
    'assemble'
  ]);

  grunt.registerTask('default', [
    'build'
  ]);

};
<commit_msg>adding copy assets<commit_after>/*
 * Generated on 2014-05-13
 * generator-assemble v0.4.11
 * https://github.com/assemble/generator-assemble
 *
 * Copyright (c) 2014 Hariadi Hinta
 * Licensed under the MIT license.
 */

'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// '<%= config.src %>/templates/pages/{,*/}*.hbs'
// use this if you want to match all subfolders:
// '<%= config.src %>/templates/pages/**/*.hbs'

module.exports = function(grunt) {

  require('time-grunt')(grunt);

  // Project configuration.
  grunt.initConfig({

    config: {
      assets: 'assets',
      src: 'src',
      dist: 'dist'
    },
    copy: {
      assets: {
        files: [
          {expand: true, cwd: '<%= config.assets %>', src: ['**'], dest: '<%= config.dist %>'},
        ]
      }
    },
    watch: {
      assemble: {
        files: ['<%= config.src %>/{content,pages,data,templates}/**/*.{md,hbs,yml}'],
        tasks: ['assemble']
      },
      assets: {
        files: [
          '<%= config.assets %>/{,*/}*.css',
          '<%= config.assets %>/{,*/}*.js',
          '<%= config.assets %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ],
        tasks: ['copy:assets']
      },
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          '<%= config.dist %>/{,*/}*.html',
          '<%= config.dist %>/{,*/}*.css',
          '<%= config.dist %>/{,*/}*.js',
          '<%= config.dist %>/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },

    connect: {
      options: {
        port: 9000,
        livereload: 35729,
        // change this to '0.0.0.0' to access the server from outside
        hostname: '127.0.0.1'
      },
      livereload: {
        options: {
          open: true,
          base: [
            '<%= config.dist %>'
          ]
        }
      }
    },

    assemble: {
      options: {
        helpers: ['handlebars-helper-compose'],
        compose: {
          sep: '<!-- section -->'
        },
        marked: {
          gfm: true,
          tables: true,
          smartLists: true
        }
      },
      pages: {
        options: {
          flatten: true,
          collections: [{
            name: 'events',
            inflection: 'event'
          }],
          layout: '<%= config.src %>/templates/layouts/default.hbs',
          data: '<%= config.src %>/data/*.{json,yml}',
          partials: '<%= config.src %>/templates/partials/*.hbs'
        },
        files: {
          '<%= config.dist %>/': ['<%= config.src %>/pages/*.hbs',
          '<%= config.src %>/content/events/**/*.hbs']
        }
      }
    },

    // Before generating any new files,
    // remove any previously-created files.
    clean: ['<%= config.dist %>/**/*.{html,xml}']

  });

  grunt.loadNpmTasks('assemble');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-connect');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.registerTask('server', [
    'clean',
    'copy:assets',
    'assemble',
    'connect:livereload',
    'watch'
  ]);

  grunt.registerTask('build', [
    'clean',
    'copy:assets',
    'assemble'
  ]);

  grunt.registerTask('default', [
    'build'
  ]);

};
<|endoftext|>


<commit_before>/*
converter.js
Module that provides functions to conversion tweaks to beers that better match the Untappd search database

Copyright (c) 2015

Patrick Crager

*/

module.exports = {

	handle: function(beer) {
		beer.brewery = beer.brewery.
			replace('PIZZA BOY/ TROEGS/ ABC', 'TROEGS/PIZZA BOY/ABC').
			// only consider the string to the left of a forward slash or ampersand,
			// common with collab beers that untappd tends to screw up with when searching on
			replace(/(\/|&).+$/g, '').
			// additional brewery fixes on a case-by-case basis
			replace('OSKARBLUES', 'OSKAR BLUES').
			replace('THE RAVEN', 'BALTIMORE-WASHINGTON BEER WORKS');

		beer.name = beer.name.
			// remove any bracketed special text in the name, [NITRO], [FIRKIN], [SOUR] etc.
			replace(/ *\[[^)]*\] */g, '').
			// remove special hyphen'd text sometimes added to the end as a special notice, ex. BEERNAME -LAST KEG!!
			replace(/ (-).+$/g, '').
			// additional name fixes on a case-by-case basis
			replace('2013', '').
			replace('2014', '').
			replace('2015', '').
			replace('2016', '').
			replace('8OZ', '').
			replace('JAI-ALAI', 'JAI ALAI').
			replace('MELONOUS IPA', 'MELONOUS').
			replace("DALE'S IPA", "DALE'S").
			replace("GINGER APPLES CIDER", "GINGER APPLES").
			replace('MADRA ALTA', 'MADRA ALLTA').
			replace('BLOSSOM HONEY LAGER', 'BLOSSOM HONEY').
			replace('BRAAAAINS', 'BRAAAIINS').
			replace('WEED EATER', 'WEEDEATER');
	}

};
<commit_msg>New conversions<commit_after>/*
converter.js
Module that provides functions to conversion tweaks to beers that better match the Untappd search database

Copyright (c) 2015

Patrick Crager

*/

module.exports = {

	handle: function(beer) {
		beer.brewery = beer.brewery.
			replace('PIZZA BOY/ TROEGS/ ABC', 'TROEGS/PIZZA BOY/ABC').
			// only consider the string to the left of a forward slash or ampersand,
			// common with collab beers that untappd tends to screw up with when searching on
			replace(/(\/|&).+$/g, '').
			// additional brewery fixes on a case-by-case basis
			replace('OSKARBLUES', 'OSKAR BLUES').
			replace('THE RAVEN', 'BALTIMORE-WASHINGTON BEER WORKS');

		beer.name = beer.name.
			// remove any bracketed special text in the name, [NITRO], [FIRKIN], [SOUR] etc.
			replace(/ *\[[^)]*\] */g, '').
			// remove special hyphen'd text sometimes added to the end as a special notice, ex. BEERNAME -LAST KEG!!
			replace(/ (-).+$/g, '').
			// additional name fixes on a case-by-case basis
			replace('2013', '').
			replace('2014', '').
			replace('2015', '').
			replace('2016', '').
			replace('8OZ', '').
			replace('HONEYCRISP', 'HONEY CRISP').
			replace('DREAM-ROOT BEER FLOAT', 'DREAM ROOT BEER').
			replace('JAI-ALAI', 'JAI ALAI').
			replace('MELONOUS IPA', 'MELONOUS').
			replace("DALE'S IPA", "DALE'S").
			replace("GINGER APPLES CIDER", "GINGER APPLES").
			replace('MADRA ALTA', 'MADRA ALLTA').
			replace('BLOSSOM HONEY LAGER', 'BLOSSOM HONEY').
			replace('BRAAAAINS', 'BRAAAIINS').
			replace('WEED EATER', 'WEEDEATER');
	}

};
<|endoftext|>


<commit_before>$(function() {
    $("#status").text("");

    var totalPoints = 500, updateInterval = 200, windowGap = 40;
    var procdata = [], procplot = [];
    var tempdata = [], tempplot = [];
    var cpu_info_cache = [], temp_data_cache = 0;
    var pi = 0, ti = 0;

    function dataToRes(data) {
        var res = [];
        for (i=0; i<data.length; i++) {
            res[i] = [ i, data[i] ];
        }
        return res;
    }

    function setProcPlots() {
        for (var n=0; n< procplot.length; n++) {
            procplot[n] = $.plot("#cpu"+n, [ dataToRes(procdata[n]) ], {
                series: {
                    shadowSize: 0,
                    color: 'rgba(0,0,0,0)'
                },
                lines: {
                    fill: true,
                    fillColor:
                    n==0 ? { colors: [ 'rgba(255,64,64,0.6)', 'rgba(255,0,0,0.8)' ] }
                         : { colors: [ 'rgba(64,255,64,0.6)', 'rgba(0,255,0,0.8)' ] }
                },
                grid: {
                    color: "#008000",
                    backgroundColor: "#000000"
                },
                yaxis: {
                    min: -1,
                    max: 101,
                    color: "#808080",
                    tickSize: [25]
                },
                xaxis: {
                    show: false
                }
            });

            var overlay = function(index) {
                return function(plot, cvs) {
                    if (!plot) { return; }
                    var cvsWidth = plot.width() / 2;
                    var text = index == 0 ? 'Total CPU' : 'CPU'+index;
                    cvs.font = "bold 40px Arial";
                    cvs.fillStyle = 'rgba(128,128,128,0.5)';
                    cvs.textAlign = 'center';
                    cvs.fillText(text, cvsWidth, 65);
                    return cvs;
                }
            };
            procplot[n].hooks.drawOverlay.push(overlay(n));
        }
    }

    function initProcCharts() {
        $.ajax({
            url: "cpu.api",
            type: "post",
            data: { counter:"0" }
        }).done(function(cpu_info) {
            if (cpu_info.length==2) { cpu_info_cache = [ cpu_info[0] ]; }
            else { cpu_info_cache = cpu_info; }

            for (var n=cpu_info.length-1; n>=0; n--) {
                if (n>0) {
                    $("#cpu0").after("

");
                }

                procdata[n] = new Array(totalPoints);
                for (var i = 0; i < totalPoints-1; i++) {
                    procdata[n][i] = 0;
                }
                procdata[n][totalPoints-1] = cpu_info[n];
            }
            procplot = new Array(cpu_info.length);
            setProcPlots();
        });
    }

    function updateProcGraphs(cpu_info) {
        $("#cpuinfo").text(cpu_info[0]+"% ("+(cpu_info.length-1)+" CPU)");
        for (var n=cpu_info.length-1; n>=0; n--) {
            procdata[n] = procdata[n].slice(1);
            procdata[n].push(cpu_info[n]);
            procplot[n].setData([dataToRes(procdata[n])]);
            procplot[n].draw();
        }
    }

    function updateProc() {
        if (pi++ % 4 == 0) {
            $.ajax({
                url: "cpu.api",
                type: "post",
                data: { counter:"0" }
            }).done(function(cpu_info) {
                if (cpu_info.length==2) { cpu_info_cache = [ cpu_info[0] ]; }
                else { cpu_info_cache = cpu_info; }
                updateProcGraphs(cpu_info_cache);
            });
        }
        else {
            updateProcGraphs(cpu_info_cache);
        }
    }

    function setTempPlot() {
        tempplot = $.plot("#tempChart", [ dataToRes(tempdata) ], {
            series: {
                shadowSize: 0,
                color: 'rgba(0,0,0,0)'
            },
            lines: {
                fill: true,
                fillColor: { colors: [ 'rgba(160,160,255,0.8)', 'rgba(255,0,0,0.8)' ] }
            },
            grid: {
                color: "#6B8E23",
                backgroundColor: "#000000"
            },
            yaxis: {
                min: 20,
                max: 90,
                color: "#808080",
                tickSize: [10]
            },
            xaxis: {
                show: false
            }
        });

        tempplot.hooks.drawOverlay.push(function(plot, cvs) {
            if (!plot) { return; }
            var cvsWidth = plot.width() / 2;
            var text = 'Temperature';
            cvs.font = "bold 40px Arial";
            cvs.fillStyle = 'rgba(128,128,128,0.5)';
            cvs.textAlign = 'center';
            cvs.fillText(text, cvsWidth, 65);
            return cvs;
        });
    }

    function initTempChart() {
        $.ajax({
            url: "temp.api",
            type: "post",
        }).done(function(data) {
            if (data!=="?") {
                temp_data_cache = data;
                $("#temp").text(temp_data_cache + "\u00B0C");
                tempdata = new Array(totalPoints);
                for (var i = 0; i < totalPoints-1; i++) {
                    tempdata[i] = 0;
                }
                tempdata[totalPoints-1] = temp_data_cache;
                setTempPlot();
            }
            else
            {
                $("#temp").text("");
                $("#tempChart").hide();
                $("#tempLabel").hide();
            }
        });
    }

    function updateTempGraph(data) {
        $("#temp").text(temp_data_cache + "\u00B0C");
        tempdata = tempdata.slice(1);
        tempdata.push(temp_data_cache);
        tempplot.setData([dataToRes(tempdata)]);
        tempplot.draw();
    }

    function updateTemp() {
        if (ti++ % 20 == 0) {
            $.ajax({
                url: "temp.api",
                type: "post",
            }).done(function(data) {
                if (data!=="?") {
                    temp_data_cache = data;
                    updateTempGraph(temp_data_cache);
                }
            });
        }
        else {
            updateTempGraph(temp_data_cache);
        }
    }

    $(window).bind("resize", function() {
        setProcPlots();
        setTempPlot();
    });

    function showUpdates() {
        updateTemp();
        updateProc();
    }

    initTempChart();
    initProcCharts();
    setInterval(showUpdates, updateInterval);
});
<commit_msg>Only shows the total CPU graph when there is a single CPU<commit_after>$(function() {
    $("#status").text("");

    var totalPoints = 500, updateInterval = 200, windowGap = 40;
    var procdata = [], procplot = [];
    var tempdata = [], tempplot = [];
    var cpu_info_cache = [], temp_data_cache = 0;
    var pi = 0, ti = 0;

    function dataToRes(data) {
        var res = [];
        for (i=0; i<data.length; i++) {
            res[i] = [ i, data[i] ];
        }
        return res;
    }

    function setProcPlots() {
        for (var n=0; n< procplot.length; n++) {
            procplot[n] = $.plot("#cpu"+n, [ dataToRes(procdata[n]) ], {
                series: {
                    shadowSize: 0,
                    color: 'rgba(0,0,0,0)'
                },
                lines: {
                    fill: true,
                    fillColor:
                    n==0 ? { colors: [ 'rgba(255,64,64,0.6)', 'rgba(255,0,0,0.8)' ] }
                         : { colors: [ 'rgba(64,255,64,0.6)', 'rgba(0,255,0,0.8)' ] }
                },
                grid: {
                    color: "#008000",
                    backgroundColor: "#000000"
                },
                yaxis: {
                    min: -1,
                    max: 101,
                    color: "#808080",
                    tickSize: [25]
                },
                xaxis: {
                    show: false
                }
            });

            var overlay = function(index) {
                return function(plot, cvs) {
                    if (!plot) { return; }
                    var cvsWidth = plot.width() / 2;
                    var text = index == 0 ? 'Total CPU' : 'CPU'+index;
                    cvs.font = "bold 40px Arial";
                    cvs.fillStyle = 'rgba(128,128,128,0.5)';
                    cvs.textAlign = 'center';
                    cvs.fillText(text, cvsWidth, 65);
                    return cvs;
                }
            };
            procplot[n].hooks.drawOverlay.push(overlay(n));
        }
    }

    function initProcCharts() {
        $.ajax({
            url: "cpu.api",
            type: "post",
            data: { counter:"0" }
        }).done(function(cpu_info) {
            if (cpu_info.length==2) { cpu_info_cache = [ cpu_info[0] ]; }
            else { cpu_info_cache = cpu_info; }

            for (var n=cpu_info_cache.length-1; n>=0; n--) {
                if (n>0) {
                    $("#cpu0").after("

");
                }

                procdata[n] = new Array(totalPoints);
                for (var i = 0; i < totalPoints-1; i++) {
                    procdata[n][i] = 0;
                }
                procdata[n][totalPoints-1] = cpu_info[n];
            }
            procplot = new Array(cpu_info.length);
            setProcPlots();
        });
    }

    function updateProcGraphs(cpu_info) {
        $("#cpuinfo").text(cpu_info[0]+"% ("+(cpu_info.length-1)+" CPU)");
        for (var n=cpu_info.length-1; n>=0; n--) {
            procdata[n] = procdata[n].slice(1);
            procdata[n].push(cpu_info[n]);
            procplot[n].setData([dataToRes(procdata[n])]);
            procplot[n].draw();
        }
    }

    function updateProc() {
        if (pi++ % 4 == 0) {
            $.ajax({
                url: "cpu.api",
                type: "post",
                data: { counter:"0" }
            }).done(function(cpu_info) {
                if (cpu_info.length==2) { cpu_info_cache = [ cpu_info[0] ]; }
                else { cpu_info_cache = cpu_info; }
                updateProcGraphs(cpu_info_cache);
            });
        }
        else {
            updateProcGraphs(cpu_info_cache);
        }
    }

    function setTempPlot() {
        tempplot = $.plot("#tempChart", [ dataToRes(tempdata) ], {
            series: {
                shadowSize: 0,
                color: 'rgba(0,0,0,0)'
            },
            lines: {
                fill: true,
                fillColor: { colors: [ 'rgba(160,160,255,0.8)', 'rgba(255,0,0,0.8)' ] }
            },
            grid: {
                color: "#6B8E23",
                backgroundColor: "#000000"
            },
            yaxis: {
                min: 20,
                max: 90,
                color: "#808080",
                tickSize: [10]
            },
            xaxis: {
                show: false
            }
        });

        tempplot.hooks.drawOverlay.push(function(plot, cvs) {
            if (!plot) { return; }
            var cvsWidth = plot.width() / 2;
            var text = 'Temperature';
            cvs.font = "bold 40px Arial";
            cvs.fillStyle = 'rgba(128,128,128,0.5)';
            cvs.textAlign = 'center';
            cvs.fillText(text, cvsWidth, 65);
            return cvs;
        });
    }

    function initTempChart() {
        $.ajax({
            url: "temp.api",
            type: "post",
        }).done(function(data) {
            if (data!=="?") {
                temp_data_cache = data;
                $("#temp").text(temp_data_cache + "\u00B0C");
                tempdata = new Array(totalPoints);
                for (var i = 0; i < totalPoints-1; i++) {
                    tempdata[i] = 0;
                }
                tempdata[totalPoints-1] = temp_data_cache;
                setTempPlot();
            }
            else
            {
                $("#temp").text("");
                $("#tempChart").hide();
                $("#tempLabel").hide();
            }
        });
    }

    function updateTempGraph(data) {
        $("#temp").text(temp_data_cache + "\u00B0C");
        tempdata = tempdata.slice(1);
        tempdata.push(temp_data_cache);
        tempplot.setData([dataToRes(tempdata)]);
        tempplot.draw();
    }

    function updateTemp() {
        if (ti++ % 20 == 0) {
            $.ajax({
                url: "temp.api",
                type: "post",
            }).done(function(data) {
                if (data!=="?") {
                    temp_data_cache = data;
                    updateTempGraph(temp_data_cache);
                }
            });
        }
        else {
            updateTempGraph(temp_data_cache);
        }
    }

    $(window).bind("resize", function() {
        setProcPlots();
        setTempPlot();
    });

    function showUpdates() {
        updateTemp();
        updateProc();
    }

    initTempChart();
    initProcCharts();
    setInterval(showUpdates, updateInterval);
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name         LikeAllTheThings
// @namespace    http://www.tommy-ryan.com
// @version      0.1
// @description  A simple script to like all the posts your friends make
// @author       TALLBOY
// @match        https://www.facebook.com/
// @grant        none
// ==/UserScript==

(function(w) {
	"use strict";

	var mainContain = document.getElementById('mainContainer');
	var offset = mainContain.offsetTop;

	function getLikeButtons() {
		var likes = document.querySelectorAll('.UFILikeLink');
		console.dir(likes);

		return likes;
	};

	function scrollToNextLike(like) {
		var likeOffset = like.offsetTop;
		mainContain.scrollTo = likeOffset;
		return true;
	};

	function processLikes() {
		var likes = getLikeButtons();
		for (var i=0; i < likes.length; i++) {
			//like['title'] = 'Like this'
			//like['title'] = 'Unlike this'
			if (likes[i]['title'] == 'Like this') {
				console.log('Like me!', likes[i]);
				// Throttle the clicks a bit so we don't get banned from Facebook
				setTimeout(function() {
					likes[i].click();
				}, 1000);
			};
			scrollToNextLike(likes[i]);
		};
	};

	processLikes();
	setInterval(processLikes, 5000);

}(window));

<commit_msg>Added update/download URLs<commit_after>// ==UserScript==
// @name         LikeAllTheThings
// @namespace    http://www.tommy-ryan.com
// @version      0.1
// @description  A simple script to like all the posts your friends make
// @author       TALLBOY
// @updateURL    https://raw.githubusercontent.com/tallboy/LikeAllTheThings/master/likeAllTheThings.js
// @downloadURL  https://raw.githubusercontent.com/tallboy/LikeAllTheThings/master/likeAllTheThings.js
// @match        https://www.facebook.com/
// @grant        none
// ==/UserScript==

(function(w) {
	"use strict";

	var mainContain = document.getElementById('mainContainer');
	var offset = mainContain.offsetTop;

	function getLikeButtons() {
		var likes = document.querySelectorAll('.UFILikeLink');
		console.dir(likes);

		return likes;
	};

	function scrollToNextLike(like) {
		var likeOffset = like.offsetTop;
		mainContain.scrollTo = likeOffset;
		return true;
	};

	function processLikes() {
		var likes = getLikeButtons();
		for (var i=0; i < likes.length; i++) {
			//like['title'] = 'Like this'
			//like['title'] = 'Unlike this'
			if (likes[i]['title'] == 'Like this') {
				console.log('Like me!', likes[i]);
				// Throttle the clicks a bit so we don't get banned from Facebook
				setTimeout(function() {
					likes[i].click();
				}, 1000);
			};
			scrollToNextLike(likes[i]);
		};
	};

	processLikes();
	setInterval(processLikes, 5000);

}(window));

<|endoftext|>


<commit_before>/**
 * Shopware 4
 * Copyright © shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 *
 * @category   Shopware
 * @package    Order
 * @subpackage View
 * @copyright Copyright (c) shopware AG (http://www.shopware.de)
 * @version    $Id$
 * @author     Stephan Pohl
 * @author     $Author$
 */

//{namespace name=backend/plugin_manager/main}
//{block name="backend/plugin_manager/view/store/view"}
Ext.define('Shopware.apps.PluginManager.view.store.View', {
    extend: 'Ext.panel.Panel',
    unstyled: true,
    alias: 'widget.plugin-manager-store-view',
    autoScroll: true,
    border: 0,
    cls: Ext.baseCSSPrefix + 'plugin-manager-store-view',

	snippets: {
		vat_price: '{s name=store/view/vat_price}* All prices incl. VAT{/s}',
		show_all: '{s name=store/view/show_all}Show all{/s}',
		hint: '{s name=store/view/hint}Hint{/s}',
		of: '{s name=store/view/of} of {/s}',
		free: '{s name=store/view/free}Free{/s}'
	},

    /**
     * Initializes the component
     *
     * @public
     * @constructor
     * @return void
     */
    initComponent: function() {
        var me = this;

        me.addEvents('changeCategory', 'openArticle');
        me.topSellerView = me.createHighlightsView();
        me.categoryView = me.createCategoryView();

        me.items = [ me.topSellerView, me.categoryView ];
        me.dockedItems = [ me.createTaxNotice() ];

        me.callParent(arguments);
    },

    createTaxNotice: function() {
		var me = this;
        return Ext.create('Ext.container.Container', {
            dock: 'bottom',
            cls: Ext.baseCSSPrefix + 'tax-notice',
            html: me.snippets.vat_price
        });
    },

    /**
     * Creates the highlight (= topseller) view.
     *
     * @public
     * @return [object] Ext.view.View
     */
    createHighlightsView: function() {
        var me = this, store = me.topSellerStore;

        return Ext.create('Ext.view.View', {
            itemSelector: '.clickable',
            store: store,
            tpl: me.createStoreViewTemplate('highlights', 2),
            cls: Ext.baseCSSPrefix + 'community-highlights',
            listeners: {
                scope: me,
                afterrender: function(view) {
                    var el = view.getEl();
                    el.on('click', function(e, t) {
                        var targetEl = Ext.get(t),
                            href = targetEl.getAttribute('href'),
                            articleId, categoryId

                        if(href == '#open-details') {
                            articleId = targetEl.getAttribute('data-articleId');
                            categoryId = targetEl.getAttribute('data-categoryId');
                            categoryId = ~~(1 * categoryId);

                            var record = me.communityStore.getById(categoryId);
                            me.fireEvent('openArticle', articleId, record, 'community');
                            window.location.hash = '';
                        } else {
                            return false;
                        }
                    }, me, { delegate: '.should-clickable' });
                }
            }
        });
    },

    createCategoryView: function() {
        var me = this, store = me.communityStore;
        return Ext.create('Ext.view.View', {
            itemSelector: '.clickable',
            store: store,
            tpl: me.createStoreViewTemplate('listing', 3),
            cls: Ext.baseCSSPrefix + 'community-categories',
            listeners: {
                scope: me,
                afterrender: function(view) {
                    var el = view.getEl();
                    el.on('click', function(e, t) {
                        var targetEl = Ext.get(t),
                            href = targetEl.getAttribute('href'),
                            categoryId, articleId, record;

                        if(href == '#show-all') {
                            categoryId = targetEl.getAttribute('data-action');
                            categoryId = ~~(1 * categoryId);

                            record = me.categoryStore.getById(categoryId);
                            me.fireEvent('changeCategory', me.categoryView, record, t);
                            window.location.hash = '';
                        } else if(href == '#open-details') {
                            articleId = targetEl.getAttribute('data-articleId');
                            categoryId = targetEl.getAttribute('data-categoryId');
                            categoryId = ~~(1 * categoryId);

                            record = me.communityStore.getById(categoryId);
                            me.fireEvent('openArticle', articleId, record, 'community');
                            window.location.hash = '';
                        } else {
                            return false;
                        }
                    }, me, { delegate: '.should-clickable' });
                }
            }
        });
    },

    createStoreViewTemplate: function(cls, perPage) {
        var me = this;

        return new Ext.XTemplate(
            '{literal}
',
                    '<tpl for=".">',
                        '<tpl if="this.checkCategoryFilled(values) === true">',
                        '
',
                            '
',
                                '
{description}
',
                                ''+me.snippets.show_all+' »',
                            '
',
                            '{[this.createRows(values, '+ perPage +')]}',
                        '
',
                        '</tpl>',
                    '</tpl>',
            '
{/literal}',
            {
                checkCategoryFilled: function(values) {
                    return !!values.products.length;
                },
                createRows: function(values, perRow) {
                    var maxCount = values.products.length,
                        rowCount = Math.ceil(maxCount / perRow),
                        rows = '', index = 0;

                    for(var j = 0; j < rowCount; j++) {
                        var row = '
';
                        for(var i = 0; i < perRow; i++) {
                            if(values.products[index]) {
                                row += this.createColumn(values.products[index], perRow, values.id);
                            }
                            index++;
                        }
                        row += '
';
                        rows += row;
                    }
                    return rows;
                },

                createColumn: function(values, perRow, categoryId) {
                    var column = '
';

                    if(values.addons && values.addons.highlight) {
                        column += '
'+me.snippets.hint+'
';
                    }

                    column += '
' + this.createThumbnail(values, perRow) + '
';
                    column += this.createDetails(values, categoryId);
                    column += '
';
                    return column;
                },

                createDetails: function(values, categoryId) {
                    var details = '
';
                    if(values.name) {
                        details += '
' + Ext.String.ellipsis(values.name, 40) + '
';
                    }

                    if(values.attributes && values.supplierName) {
                        details += 'v' + values.attributes.version + me.snippets.of + Ext.String.ellipsis(values.supplierName, 18) + '';
                    }

                    if(values.description) {
                        details += '
' + Ext.util.Format.stripTags(values.description) + '
';
                    }

                    var price = '';
                    Ext.each(values.details, function(item) {
                        if(item.rent_version === true) {
                            price = item.price;
                        }
                    });

                    if(!price) {
                        price = values.details[0].price;
                    } else {
                        price = 'ab ' + price;
                    }

                    if(price == 0) {
                        price = me.snippets.free;
                    } else {
                        price += '€ *';
                    }
                    if (values.vote_average) {
                        var starCount = ~~(1 * values.vote_average) * 2;
                        details += '

'
                    }

                    details += '
';
                        details += '
' + price + '
';
                        details += 'Details »';
                    details += '
';

                    details += '
';
                    return details;
                },

                createThumbnail: function(values, perRow) {
                    var images = values.images, image, ret = '';

                    if(values.attributes.certificate == '1') {
                        ret += '

';
                    }
                    // No picture image
                    if(!images.length) {
                        ret += '
'+values.name+'
';
                        return ret;
                    }

                    // Get the thumbnail
                    if(images[0].thumbnails && images[0].thumbnails[3]) {

                        if(perRow == 2) {
                            image = images[0].thumbnails[3];
                        } else {
                            image = images[0].thumbnails[2];
                        }
                    }

                    ret += '
'+values.name+'
';
                    return ret;
                }
            }
        );
    }
});
//{/block}
<commit_msg>#SW-7671 - Fixed the bug where the detail window won't open up in the plugin store in IE 10 - Changed the categoryId and articleId retrieval from the Ext.dom.Element to the DOM Element itself<commit_after>/**
 * Shopware 4
 * Copyright © shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 *
 * @category   Shopware
 * @package    Order
 * @subpackage View
 * @copyright Copyright (c) shopware AG (http://www.shopware.de)
 * @version    $Id$
 * @author     Stephan Pohl
 * @author     $Author$
 */

//{namespace name=backend/plugin_manager/main}
//{block name="backend/plugin_manager/view/store/view"}
Ext.define('Shopware.apps.PluginManager.view.store.View', {
    extend: 'Ext.panel.Panel',
    unstyled: true,
    alias: 'widget.plugin-manager-store-view',
    autoScroll: true,
    border: 0,
    cls: Ext.baseCSSPrefix + 'plugin-manager-store-view',

	snippets: {
		vat_price: '{s name=store/view/vat_price}* All prices incl. VAT{/s}',
		show_all: '{s name=store/view/show_all}Show all{/s}',
		hint: '{s name=store/view/hint}Hint{/s}',
		of: '{s name=store/view/of} of {/s}',
		free: '{s name=store/view/free}Free{/s}'
	},

    /**
     * Initializes the component
     *
     * @public
     * @constructor
     * @return void
     */
    initComponent: function() {
        var me = this;

        me.addEvents('changeCategory', 'openArticle');
        me.topSellerView = me.createHighlightsView();
        me.categoryView = me.createCategoryView();

        me.items = [ me.topSellerView, me.categoryView ];
        me.dockedItems = [ me.createTaxNotice() ];

        me.callParent(arguments);
    },

    createTaxNotice: function() {
		var me = this;
        return Ext.create('Ext.container.Container', {
            dock: 'bottom',
            cls: Ext.baseCSSPrefix + 'tax-notice',
            html: me.snippets.vat_price
        });
    },

    /**
     * Creates the highlight (= topseller) view.
     *
     * @public
     * @return [object] Ext.view.View
     */
    createHighlightsView: function() {
        var me = this, store = me.topSellerStore;

        return Ext.create('Ext.view.View', {
            itemSelector: '.clickable',
            store: store,
            tpl: me.createStoreViewTemplate('highlights', 2),
            cls: Ext.baseCSSPrefix + 'community-highlights',
            listeners: {
                scope: me,
                afterrender: function(view) {
                    var el = view.getEl();
                    el.on('click', function(e, t) {
                        var href = t.getAttribute('href'),
                            articleId, categoryId;

                        if(href == '#open-details') {
                            articleId = t.getAttribute('data-articleId');
                            categoryId = t.getAttribute('data-categoryId');
                            categoryId = ~~(1 * categoryId);

                            var record = me.communityStore.getById(categoryId);
                            me.fireEvent('openArticle', articleId, record, 'community');
                            window.location.hash = '';
                        } else {
                            return false;
                        }
                    }, me, { delegate: '.should-clickable' });
                }
            }
        });
    },

    createCategoryView: function() {
        var me = this, store = me.communityStore;
        return Ext.create('Ext.view.View', {
            itemSelector: '.clickable',
            store: store,
            tpl: me.createStoreViewTemplate('listing', 3),
            cls: Ext.baseCSSPrefix + 'community-categories',
            listeners: {
                scope: me,
                afterrender: function(view) {
                    var el = view.getEl();
                    el.on('click', function(e, t) {
                        var href = t.getAttribute('href'),
                            categoryId, articleId, record;

                        if(href == '#show-all') {
                            categoryId = t.getAttribute('data-action');
                            categoryId = ~~(1 * categoryId);

                            record = me.categoryStore.getById(categoryId);
                            me.fireEvent('changeCategory', me.categoryView, record, t);
                            window.location.hash = '';
                        } else if(href == '#open-details') {
                            articleId = t.getAttribute('data-articleId');
                            categoryId = t.getAttribute('data-categoryId');
                            categoryId = ~~(1 * categoryId);

                            record = me.communityStore.getById(categoryId);
                            me.fireEvent('openArticle', articleId, record, 'community');
                            window.location.hash = '';
                        } else {
                            return false;
                        }
                    }, me, { delegate: '.should-clickable' });
                }
            }
        });
    },

    createStoreViewTemplate: function(cls, perPage) {
        var me = this;

        return new Ext.XTemplate(
            '{literal}
',
                    '<tpl for=".">',
                        '<tpl if="this.checkCategoryFilled(values) === true">',
                        '
',
                            '
',
                                '
{description}
',
                                ''+me.snippets.show_all+' »',
                            '
',
                            '{[this.createRows(values, '+ perPage +')]}',
                        '
',
                        '</tpl>',
                    '</tpl>',
            '
{/literal}',
            {
                checkCategoryFilled: function(values) {
                    return !!values.products.length;
                },
                createRows: function(values, perRow) {
                    var maxCount = values.products.length,
                        rowCount = Math.ceil(maxCount / perRow),
                        rows = '', index = 0;

                    for(var j = 0; j < rowCount; j++) {
                        var row = '
';
                        for(var i = 0; i < perRow; i++) {
                            if(values.products[index]) {
                                row += this.createColumn(values.products[index], perRow, values.id);
                            }
                            index++;
                        }
                        row += '
';
                        rows += row;
                    }
                    return rows;
                },

                createColumn: function(values, perRow, categoryId) {
                    var column = '
';

                    if(values.addons && values.addons.highlight) {
                        column += '
'+me.snippets.hint+'
';
                    }

                    column += '
' + this.createThumbnail(values, perRow) + '
';
                    column += this.createDetails(values, categoryId);
                    column += '
';
                    return column;
                },

                createDetails: function(values, categoryId) {
                    var details = '
';
                    if(values.name) {
                        details += '
' + Ext.String.ellipsis(values.name, 40) + '
';
                    }

                    if(values.attributes && values.supplierName) {
                        details += 'v' + values.attributes.version + me.snippets.of + Ext.String.ellipsis(values.supplierName, 18) + '';
                    }

                    if(values.description) {
                        details += '
' + Ext.util.Format.stripTags(values.description) + '
';
                    }

                    var price = '';
                    Ext.each(values.details, function(item) {
                        if(item.rent_version === true) {
                            price = item.price;
                        }
                    });

                    if(!price) {
                        price = values.details[0].price;
                    } else {
                        price = 'ab ' + price;
                    }

                    if(price == 0) {
                        price = me.snippets.free;
                    } else {
                        price += '€ *';
                    }
                    if (values.vote_average) {
                        var starCount = ~~(1 * values.vote_average) * 2;
                        details += '

'
                    }

                    details += '
';
                        details += '
' + price + '
';
                        details += 'Details »';
                    details += '
';

                    details += '
';
                    return details;
                },

                createThumbnail: function(values, perRow) {
                    var images = values.images, image, ret = '';

                    if(values.attributes.certificate == '1') {
                        ret += '

';
                    }
                    // No picture image
                    if(!images.length) {
                        ret += '
'+values.name+'
';
                        return ret;
                    }

                    // Get the thumbnail
                    if(images[0].thumbnails && images[0].thumbnails[3]) {

                        if(perRow == 2) {
                            image = images[0].thumbnails[3];
                        } else {
                            image = images[0].thumbnails[2];
                        }
                    }

                    ret += '
'+values.name+'
';
                    return ret;
                }
            }
        );
    }
});
//{/block}
<|endoftext|>


<commit_before>var init = function (initialise_callback) {
		var lisp_fns = {
				"+": {
					"minArity": 1,
					"maxArity": Infinity,
					"dataType": "number",
					"fn": function (args) {
						var rtn = 0; // CLISP returns 0 if `+` is given no arguments.
						while (args.length) {
							rtn += args.shift();
						};
						return rtn;
					}
				},
				"-": function (args) {
					var rtn = args.shift();
					while (args.length) {
						rtn -= args.shift();
					};
					return rtn;
				},
				"*": function (args) {
					var rtn = 1; // CLISP returns 1 if `*` is given no arguments.
					while (args.length) {
						rtn *= args.shift();
					};
					return rtn;
				},
				"/": function (args) {
					var rtn = args.shift();
					while (args.length) {
						rtn /= args.shift();
					}
					return rtn;
				}
			},

			wrap_function = function (fn_object) {

				// Decide on how the function should be accessed.
				var fn = fn_object.fn || fn_object,
					maxArity = fn_object.maxArity || Infinity,
					minArity = fn_object.minArity || 0,
					dataType = fn_object.dataType || [ "number", "string" ],
					checkType = function (arg) {
						var rtn = false,
							d;
						if (dataType instanceof Array) {
							for (d = dataType.length - 1; (d + 1) && !rtn; d -= 1) {
								rtn = (typeof arg === dataType[d]);
							}
						} else if (typeof dataType === "string") {
							rtn = typeof arg === dataType;
						}
						return rtn;
					};

				return function (args) {
					var rtn = {},
						func_rtn,
						a,
						unpacked = [];

					if (args instanceof Array) {
						a = args.length;

						if (a > maxArity) {
							rtn.error = "Test error message. Too many arguments.";
						} else if (a < minArity) {
							rtn.error = "Test error message. Too few arguments.";
						}

						// Search for any one argument that goes against type, whilst unpacking.
						for (; a && checkType(unpacked[a - 1] = (args[a - 1].value || args[a - 1])); a -= 1); // no body

						// When a is falsy, the arguments are type-safe.
						if (!a) {
							func_rtn = fn(unpacked);
							if (typeof func_rtn === "object" && (func_rtn.hasOwnProperty("value") || func_rtn.hasOwnProperty("error"))) {
								rtn = func_rtn;
							} else {
								rtn.value = func_rtn;
							}
						} else {
							rtn.error = "The argument " + (args[a - 1].value || args[a - 1]) + " was the wrong type.";
						}
					} else {
						rtn.error = "Fault with Lijst. Arguments not passed as array.";
					}
					return rtn;
				}
			},

			separate_terms = function (input) {
				var str = input,
					arr = [],
					rst = "",
					rex = /(\s+)|(")|(\()|(\))|(.$)/g,
					begin_term = 0,
					end_term = 0,
					paren_level = 0,
					quote_level = false,
					rfn = function ($m, $1, $2, $3, $4, $5, offset, whole_string) {
						var out;
						if ($2 && !paren_level) {
							console.log(quote_level);
							quote_level = !quote_level;
							if (quote_level) {
								begin_term = offset;
							} else {
								end_term = offset + $m.length;
								out = whole_string.slice(begin_term, end_term);
								begin_term = end_term;
							}
						} else if ($3 && !quote_level) {
							paren_level += 1;
							if (!paren_level) {
								begin_term = offset;
							}
						} else if ($4 && !quote_level) {
							paren_level -= 1;
							if (!paren_level) {
								end_term = offset + $m.length;
								out = whole_string.slice(begin_term, end_term);
								begin_term = end_term;
							}
						} else if ($1 && !paren_level && !quote_level) {
							end_term = offset;
							out = whole_string.slice(begin_term, end_term);
							begin_term = end_term + $m.length;
						} else if ($5 && !quote_level) {
							end_term = whole_string.length;
							out = whole_string.slice(begin_term, end_term);
							begin_term = end_term + $m.length;
						}

						if (out) { arr.push(out); };
						return $m;
					};

				rst = str.replace(rex, rfn);
				return arr;
			},

			evaluate_term = function (term) {
				var rtn,
					arr,
					fun,
					arg = [],
					term = term[0];
				if (/\D/g.test(term)) {
					if (/^\(.*\)$/.test(term)) {
						if (term.slice(1, -1)) {
							arr = separate_terms(term.slice(1, -1));
							fun = arr.shift();
							while (arr.length) {
								arg.push(evaluate_term(arr.splice(0, 1)));
							}
							if (lisp_fns.hasOwnProperty(fun)) {
								rtn = lisp_fns[fun](arg);
							} else {
								// TODO: What if there is no such function?
							}
						} else {
							// If parentheses are empty.
							rtn = "NIL";
						}
					} else if (/^".*"$/g.test(term)) {
						console.log(term);
						rtn = term;
					}
				} else {
					rtn = +term;
				}
				return rtn;
			},

			// Top-level processing of input.
			process_input = function (input, callback_each_term) {
				var rtn,
					arr = separate_terms(input),
					rst;

				while (arr.length) {
					// Extract first term from array and evaluate.
					rst = evaluate_term(arr.splice(0, 1));
					// Do something with the input and results.
					callback_each_term(input, print_result(rst));
					// Reset the input. We have already done something with it once.
					input = "";
				}

				return rtn;
			},

			print_result = function (result) {
				var rtn;
				if (result.hasOwnProperty("value")) {
					if (typeof result.value === "number") {
						rtn = "" + result.value;
					} else {
						rtn = result.value;
					}
				} else if (result.hasOwnProperty("error")) {
					rtn = result.error;
				} else {
					rtn = "Error at printing stage. No value or processing error found.";
				}
				return rtn;
			},

			f;

		// Wrap predefined lisp functions in error-checking function.
		for (f in lisp_fns) {
			if (lisp_fns.hasOwnProperty(f)) {
				lisp_fns[f] = wrap_function(lisp_fns[f]);
			}
		}

		evaluate_term = wrap_function(evaluate_term);

		initialise_callback();

		return {
			process_input: process_input
		};

	};

// Node JS compatibility
if (typeof exports !== "undefined") {
	exports.init = init;
}<commit_msg>Corrected arity expectation for the + lisp_fn.<commit_after>var init = function (initialise_callback) {
		var lisp_fns = {
				"+": {
					"minArity": 0,
					"maxArity": Infinity,
					"dataType": "number",
					"fn": function (args) {
						var rtn = 0; // CLISP returns 0 if `+` is given no arguments.
						while (args.length) {
							rtn += args.shift();
						};
						return rtn;
					}
				},
				"-": function (args) {
					var rtn = args.shift();
					while (args.length) {
						rtn -= args.shift();
					};
					return rtn;
				},
				"*": function (args) {
					var rtn = 1; // CLISP returns 1 if `*` is given no arguments.
					while (args.length) {
						rtn *= args.shift();
					};
					return rtn;
				},
				"/": function (args) {
					var rtn = args.shift();
					while (args.length) {
						rtn /= args.shift();
					}
					return rtn;
				}
			},

			wrap_function = function (fn_object) {

				// Decide on how the function should be accessed.
				var fn = fn_object.fn || fn_object,
					maxArity = fn_object.maxArity || Infinity,
					minArity = fn_object.minArity || 0,
					dataType = fn_object.dataType || [ "number", "string" ],
					checkType = function (arg) {
						var rtn = false,
							d;
						if (dataType instanceof Array) {
							for (d = dataType.length - 1; (d + 1) && !rtn; d -= 1) {
								rtn = (typeof arg === dataType[d]);
							}
						} else if (typeof dataType === "string") {
							rtn = typeof arg === dataType;
						}
						return rtn;
					};

				return function (args) {
					var rtn = {},
						func_rtn,
						a,
						unpacked = [];

					if (args instanceof Array) {
						a = args.length;

						if (a > maxArity) {
							rtn.error = "Test error message. Too many arguments.";
						} else if (a < minArity) {
							rtn.error = "Test error message. Too few arguments.";
						}

						// Search for any one argument that goes against type, whilst unpacking.
						for (; a && checkType(unpacked[a - 1] = (args[a - 1].value || args[a - 1])); a -= 1); // no body

						// When a is falsy, the arguments are type-safe.
						if (!a) {
							func_rtn = fn(unpacked);
							if (typeof func_rtn === "object" && (func_rtn.hasOwnProperty("value") || func_rtn.hasOwnProperty("error"))) {
								rtn = func_rtn;
							} else {
								rtn.value = func_rtn;
							}
						} else {
							rtn.error = "The argument " + (args[a - 1].value || args[a - 1]) + " was the wrong type.";
						}
					} else {
						rtn.error = "Fault with Lijst. Arguments not passed as array.";
					}
					return rtn;
				}
			},

			separate_terms = function (input) {
				var str = input,
					arr = [],
					rst = "",
					rex = /(\s+)|(")|(\()|(\))|(.$)/g,
					begin_term = 0,
					end_term = 0,
					paren_level = 0,
					quote_level = false,
					rfn = function ($m, $1, $2, $3, $4, $5, offset, whole_string) {
						var out;
						if ($2 && !paren_level) {
							console.log(quote_level);
							quote_level = !quote_level;
							if (quote_level) {
								begin_term = offset;
							} else {
								end_term = offset + $m.length;
								out = whole_string.slice(begin_term, end_term);
								begin_term = end_term;
							}
						} else if ($3 && !quote_level) {
							paren_level += 1;
							if (!paren_level) {
								begin_term = offset;
							}
						} else if ($4 && !quote_level) {
							paren_level -= 1;
							if (!paren_level) {
								end_term = offset + $m.length;
								out = whole_string.slice(begin_term, end_term);
								begin_term = end_term;
							}
						} else if ($1 && !paren_level && !quote_level) {
							end_term = offset;
							out = whole_string.slice(begin_term, end_term);
							begin_term = end_term + $m.length;
						} else if ($5 && !quote_level) {
							end_term = whole_string.length;
							out = whole_string.slice(begin_term, end_term);
							begin_term = end_term + $m.length;
						}

						if (out) { arr.push(out); };
						return $m;
					};

				rst = str.replace(rex, rfn);
				return arr;
			},

			evaluate_term = function (term) {
				var rtn,
					arr,
					fun,
					arg = [],
					term = term[0];
				if (/\D/g.test(term)) {
					if (/^\(.*\)$/.test(term)) {
						if (term.slice(1, -1)) {
							arr = separate_terms(term.slice(1, -1));
							fun = arr.shift();
							while (arr.length) {
								arg.push(evaluate_term(arr.splice(0, 1)));
							}
							if (lisp_fns.hasOwnProperty(fun)) {
								rtn = lisp_fns[fun](arg);
							} else {
								// TODO: What if there is no such function?
							}
						} else {
							// If parentheses are empty.
							rtn = "NIL";
						}
					} else if (/^".*"$/g.test(term)) {
						console.log(term);
						rtn = term;
					}
				} else {
					rtn = +term;
				}
				return rtn;
			},

			// Top-level processing of input.
			process_input = function (input, callback_each_term) {
				var rtn,
					arr = separate_terms(input),
					rst;

				while (arr.length) {
					// Extract first term from array and evaluate.
					rst = evaluate_term(arr.splice(0, 1));
					// Do something with the input and results.
					callback_each_term(input, print_result(rst));
					// Reset the input. We have already done something with it once.
					input = "";
				}

				return rtn;
			},

			print_result = function (result) {
				var rtn;
				if (result.hasOwnProperty("value")) {
					if (typeof result.value === "number") {
						rtn = "" + result.value;
					} else {
						rtn = result.value;
					}
				} else if (result.hasOwnProperty("error")) {
					rtn = result.error;
				} else {
					rtn = "Error at printing stage. No value or processing error found.";
				}
				return rtn;
			},

			f;

		// Wrap predefined lisp functions in error-checking function.
		for (f in lisp_fns) {
			if (lisp_fns.hasOwnProperty(f)) {
				lisp_fns[f] = wrap_function(lisp_fns[f]);
			}
		}

		evaluate_term = wrap_function(evaluate_term);

		initialise_callback();

		return {
			process_input: process_input
		};

	};

// Node JS compatibility
if (typeof exports !== "undefined") {
	exports.init = init;
}<|endoftext|>