<commit_before>'use strict';

/**
 * @ngdoc function
 * @name otaniemi3dApp.controller:OneDViewCtrl
 * @description
 * # oneDViewCtrl
 * Controller of the otaniemi3dApp
 */
angular.module('otaniemi3dApp')

  .controller('onedview', function ($scope, $location, Datahandler) {

    $scope.timeFrame = 'Latest';

    function selectTimeFrame(timeFrame) {
      var time = timeFrame;

      if (time) {
        $scope.timeFrame = time;
      } else {
        $scope.timeFrame = 'Latest';
      }

      Datahandler.fetchData(time).then(
        function(data) {
            $scope.gridOptions.data = data;
        },
        function() {
            console.log('Error: Failed to fetch sensor data');
        }
      );
    }

    var fetchDataPromise = Datahandler.fetchData();
    fetchDataPromise
      .then(function (data) {
        $scope.gridOptions.data = data;
        }, function (reason) {    // something gone wrong
        $scope.gridOptions.data = reason;
      });

    $scope.gridOptions = {
      enableFiltering: true,
      enableGridMenu: true,
      gridMenuShowHideColumns: false,
      gridMenuCustomItems: [
        {
          title: 'Latest',
          action: function() {
            selectTimeFrame('Latest');
          },
          active: function () {
            return $scope.timeFrame === 'Latest';
          }
        },
        {
          title: 'Day',
          action: function() {
            selectTimeFrame('Day');
          },
          active: function () {
            return $scope.timeFrame === 'Day';
          }
        },
        {
          title: 'Week',
          action: function() {
            selectTimeFrame('Week');
          },
          active: function () {
            return $scope.timeFrame === 'Week';
          }
        },
        {
          title: 'Month',
          action: function() {
            selectTimeFrame('Month');
          },
          active: function () {
            return $scope.timeFrame === 'Month';
          }
        },
        {
          title: 'Year',
          action: function() {
            selectTimeFrame('Year');
          },
          active: function () {
            return $scope.timeFrame === 'Year';
          }
        }
      ],
      columnDefs: [
        {
          field: 'room',
          filter: {
            condition:  function(searchTerm, cellValue) {
              var strippedValue = cellValue.toLowerCase();
              return strippedValue.indexOf(searchTerm.toLowerCase()) >= 0;
              }
            }
          },
        {
          field: 'type',
          filter: {
            condition:  function(searchTerm, cellValue) {
              var strippedValue = cellValue.toLowerCase();
              return strippedValue.indexOf(searchTerm.toLowerCase()) >= 0;
              }
            }
          },
        {
          field: 'value'
        }
      ]
    };
  });<commit_msg>Add filtering to value column in 1d view<commit_after>'use strict';

/**
 * @ngdoc function
 * @name otaniemi3dApp.controller:OneDViewCtrl
 * @description
 * # oneDViewCtrl
 * Controller of the otaniemi3dApp
 */
angular.module('otaniemi3dApp')

  .controller('onedview', function ($scope, $location, Datahandler, uiGridConstants) {

    $scope.timeFrame = 'Latest';

    function selectTimeFrame(timeFrame) {
      var time = timeFrame;

      if (time) {
        $scope.timeFrame = time;
      } else {
        $scope.timeFrame = 'Latest';
      }

      Datahandler.fetchData(time).then(
        function(data) {
            $scope.gridOptions.data = data;
        },
        function() {
            console.log('Error: Failed to fetch sensor data');
        }
      );
    }

    var fetchDataPromise = Datahandler.fetchData();
    fetchDataPromise
      .then(function (data) {
        $scope.gridOptions.data = data;
        }, function (reason) {    // something gone wrong
        $scope.gridOptions.data = reason;
      });

    $scope.gridOptions = {
      enableFiltering: true,
      enableGridMenu: true,
      gridMenuShowHideColumns: false,
      gridMenuCustomItems: [
        {
          title: 'Latest',
          action: function() {
            selectTimeFrame('Latest');
          },
          active: function () {
            return $scope.timeFrame === 'Latest';
          }
        },
        {
          title: 'Day',
          action: function() {
            selectTimeFrame('Day');
          },
          active: function () {
            return $scope.timeFrame === 'Day';
          }
        },
        {
          title: 'Week',
          action: function() {
            selectTimeFrame('Week');
          },
          active: function () {
            return $scope.timeFrame === 'Week';
          }
        },
        {
          title: 'Month',
          action: function() {
            selectTimeFrame('Month');
          },
          active: function () {
            return $scope.timeFrame === 'Month';
          }
        },
        {
          title: 'Year',
          action: function() {
            selectTimeFrame('Year');
          },
          active: function () {
            return $scope.timeFrame === 'Year';
          }
        }
      ],
      columnDefs: [
        {
          field: 'room',
          filters: [
            {
              condition:  function(searchTerm, cellValue) {
                var strippedValue = cellValue.toLowerCase();
                return strippedValue.indexOf(searchTerm.toLowerCase()) >= 0;
              },
              placeholder: 'room name'
            }
          ]
        },
        {
          field: 'type',
          filters: [
            {
              condition:  function(searchTerm, cellValue) {
                var strippedValue = cellValue.toLowerCase();
                return strippedValue.indexOf(searchTerm.toLowerCase()) >= 0;
              },
              placeholder: 'sensor type'
            }
          ]
        },
        {
          field: 'value',
          filters: [
            {
              condition: uiGridConstants.filter.GREATER_THAN,
              placeholder: 'greater than'
            },
            {
              condition: uiGridConstants.filter.LESS_THAN,
              placeholder: 'less than'
            }
          ]
        }
      ]
    };
  });<|endoftext|>


<commit_before>'use strict';

angular.module('searchApp')
  .filter('dateFilterPrettifier', function () {
    return function (input) {
        var s = input.replace(/-01-01T/g, '').replace(/-12-31T/g, '');
        s = s.replace(/00:00:00Z/g, '').replace(/23:59:59Z/g, '');
        console.log(s);
        return s;
    };
  });
<commit_msg>remove extraneous logging<commit_after>'use strict';

angular.module('searchApp')
  .filter('dateFilterPrettifier', function () {
    return function (input) {
        var s = input.replace(/-01-01T/g, '').replace(/-12-31T/g, '');
        s = s.replace(/00:00:00Z/g, '').replace(/23:59:59Z/g, '');
        return s;
    };
  });
<|endoftext|>


<commit_before>describe("Lavel.textAlign", function(){
    var context, core, label;

    beforeEach(function(){
        enchant();
        core = new enchant.Core(320, 320);
        // dummy label for activate canvas layer
        var dummyLabel = new Label('.');
        dummyLabel.moveTo(320, 320);
        core.rootScene.addChild(dummyLabel);
        context = document.getElementsByTagName('canvas')[0].getContext('2d');
        // using multibyte char in tests causes problem when running on phantomjs
        label = new Label('=');
        label.color = "#f00";
        label.font = '10px mono monospace';
    });

    var verifyTextAt = function(textAlign){
        var x = 4, image;
        if(textAlign === 'center') {
            x = label.width / 2;
        } else if (textAlign === 'right') {
            x = label.width - 5;
        }
        // this code is trying to avoid problem about difference of font
        var max = 0;
        for (var y = 0; y < 10; y++) {
            image = context.getImageData(x, y, 1, 1).data;
            max = Math.max(image[0], max);
        }
        return max > 128;
    };

    it("should not be ok with no alignment setting", function(){
        expect(verifyTextAt('left')).to.not.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });

    it("should align left", function(){
        label.textAlign = "left";
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });

    it("should align center", function(){
        label.textAlign = "center";
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.not.be.ok;
        expect(verifyTextAt('center')).to.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });

    it("should align right", function(){
        label.textAlign = "right";
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.not.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.be.ok;
    });

    it("should align left as default", function(){
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });
});
<commit_msg>fix typo<commit_after>describe("Label.textAlign", function(){
    var context, core, label;

    beforeEach(function(){
        enchant();
        core = new enchant.Core(320, 320);
        // dummy label for activate canvas layer
        var dummyLabel = new Label('.');
        dummyLabel.moveTo(320, 320);
        core.rootScene.addChild(dummyLabel);
        context = document.getElementsByTagName('canvas')[0].getContext('2d');
        // using multibyte char in tests causes problem when running on phantomjs
        label = new Label('=');
        label.color = "#f00";
        label.font = '10px mono monospace';
    });

    var verifyTextAt = function(textAlign){
        var x = 4, image;
        if(textAlign === 'center') {
            x = label.width / 2;
        } else if (textAlign === 'right') {
            x = label.width - 5;
        }
        // this code is trying to avoid problem about difference of font
        var max = 0;
        for (var y = 0; y < 10; y++) {
            image = context.getImageData(x, y, 1, 1).data;
            max = Math.max(image[0], max);
        }
        return max > 128;
    };

    it("should not be ok with no alignment setting", function(){
        expect(verifyTextAt('left')).to.not.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });

    it("should align left", function(){
        label.textAlign = "left";
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });

    it("should align center", function(){
        label.textAlign = "center";
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.not.be.ok;
        expect(verifyTextAt('center')).to.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });

    it("should align right", function(){
        label.textAlign = "right";
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.not.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.be.ok;
    });

    it("should align left as default", function(){
        core.rootScene.addChild(label);
        expect(verifyTextAt('left')).to.be.ok;
        expect(verifyTextAt('center')).to.not.be.ok;
        expect(verifyTextAt('right')).to.not.be.ok;
    });
});
<|endoftext|>


<commit_before>// https://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md
//
// we don't trigger livereload after JS changes, because JS changes also
// make nodemon restart the dev server, and if livereload takes place while
// the dev server is still restarting, we get an error page in the browser
// and a five-second delay.
//
// instead we notify livereload after the dev server starts up. this takes
// place inside the server code, not in gulp task code, because it has to
// happen in the callback to server.start, and we can't hook into that
// from gulp because of the "process gap" created by nodemon.

import watchify from 'watchify'
import browserify from 'browserify'
import gulp from 'gulp'
import source from 'vinyl-source-stream'
import buffer from 'vinyl-buffer'
import gutil from 'gulp-util'
import sourcemaps from 'gulp-sourcemaps'
import streamify from 'gulp-streamify'
import uglify from 'gulp-uglify'
import rev from 'gulp-rev'

const opts = {
  entries: ['./src/client']
}

const setup = b => {
  b.transform('babelify')
  b.transform('envify')
  b.transform('uglifyify')
  return b
}

export function watch () {
  var b = watchify(browserify(Object.assign({}, opts, watchify.args)))
  b.plugin('livereactload')
  b.on('log', gutil.log)
  setup(b)

  var update = function () {
    return b.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify error'))
    .pipe(source('index.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('public'))
  }

  b.on('update', update)

  return update()
}

export function bundle () {
  return setup(browserify(opts))
  .bundle()
  .on('error', gutil.log.bind(gutil, 'Browserify error'))
  .pipe(source('index.js'))
  .pipe(buffer())
  .pipe(sourcemaps.init({loadMaps: true}))
  .pipe(streamify(uglify()))
  .pipe(rev())
  .pipe(sourcemaps.write('./'))
  .pipe(gulp.dest('dist'))
  .pipe(rev.manifest({base: 'dist', path: 'dist/manifest.json', merge: true}))
  .pipe(gulp.dest('dist'))
}
<commit_msg>don't uglify js in dev<commit_after>// https://github.com/gulpjs/gulp/blob/master/docs/recipes/fast-browserify-builds-with-watchify.md
//
// we don't trigger livereload after JS changes, because JS changes also
// make nodemon restart the dev server, and if livereload takes place while
// the dev server is still restarting, we get an error page in the browser
// and a five-second delay.
//
// instead we notify livereload after the dev server starts up. this takes
// place inside the server code, not in gulp task code, because it has to
// happen in the callback to server.start, and we can't hook into that
// from gulp because of the "process gap" created by nodemon.

import watchify from 'watchify'
import browserify from 'browserify'
import gulp from 'gulp'
import source from 'vinyl-source-stream'
import buffer from 'vinyl-buffer'
import gutil from 'gulp-util'
import sourcemaps from 'gulp-sourcemaps'
import streamify from 'gulp-streamify'
import uglify from 'gulp-uglify'
import rev from 'gulp-rev'

const opts = {
  entries: ['./src/client']
}

const setup = b => {
  b.transform('babelify')
  b.transform('envify')
  return b
}

export function watch () {
  var b = watchify(browserify(Object.assign({}, opts, watchify.args)))
  b.plugin('livereactload')
  b.on('log', gutil.log)
  setup(b)

  var update = function () {
    return b.bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify error'))
    .pipe(source('index.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('public'))
  }

  b.on('update', update)

  return update()
}

export function bundle () {
  return setup(browserify(opts))
  .transform('uglifyify')
  .bundle()
  .on('error', gutil.log.bind(gutil, 'Browserify error'))
  .pipe(source('index.js'))
  .pipe(buffer())
  .pipe(sourcemaps.init({loadMaps: true}))
  .pipe(streamify(uglify()))
  .pipe(rev())
  .pipe(sourcemaps.write('./'))
  .pipe(gulp.dest('dist'))
  .pipe(rev.manifest({base: 'dist', path: 'dist/manifest.json', merge: true}))
  .pipe(gulp.dest('dist'))
}
<|endoftext|>


<commit_before>/*
 * grunt-build-html
 * https://github.com/tonai/grunt-build-html
 *
 * Copyright (c) 2013 Tony Cabaye
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var path      = require('path');
  var _         = grunt.util._;
  var debug     = grunt.log.debug;
  var backtrace = function(files) {
    var message = '[backtrace] : ';
    for (var i in files) {
      message += grunt.util.linefeed + files[i];
    }
    debug(grunt.util.normalizelf(message));
  };

  grunt.registerMultiTask('build_html', 'Build HTML templates recursively.', function() {
    var include          = null;
    var templates        = {};
    var templateSettings = {};

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      templates: []
    });

    // Manage template settings
    if (options.interpolate !== undefined) {
      templateSettings.interpolate = options.interpolate;
    }
    if (options.escape !== undefined) {
      templateSettings.escape = options.escape;
    }
    if (options.evaluate !== undefined) {
      templateSettings.evaluate = options.evaluate;
    }
    _.templateSettings = templateSettings;

    // Include method to be used in HTML files.
    include = function(tplName, data) {
      var files, templateData, html = '';
      if (typeof data == 'undefined') {
        data = {};
      }

      if (_.has(templates, tplName)) {
        files = _.clone(this.files);
        files.push(templates[tplName].filepath);
        templateData = {files: files};
        data.include = include.bind(templateData);
        try {
          html = _.template(templates[tplName].content, data);
        } catch (error) {
          grunt.log.error(error.message);
          backtrace(files);
        }
      } else {
        grunt.log.writeln('Template "' + tplName + '" does not exists.');
        backtrace(this.files);
      }

      return html;
    };

    // Process templates.
    _.each(grunt.file.expand(options.templates), function(tpl) {
      var tplName = path.basename(tpl, path.extname(tpl)).replace(/[\s]/g, '_');
      debug("loading template :", tplName);
      debug("  path is :", tpl);
      templates[tplName] = {
        content: grunt.file.read(tpl),
        filepath: tpl
      };
    });

    // Iterate over all specified file groups.
    this.files.forEach(function(file) {
      // Concat specified files.
      var src = file.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        var html = '';
        var templateData = {files: [filepath]};
        templateData.include = include.bind(templateData);
        options.filename = filepath;
        try {
          html = _.template(grunt.file.read(filepath), templateData);
        } catch (error) {
          grunt.log.error(error.message);
          backtrace(templateData.files);
        }
        return html;
      }).join(grunt.util.normalizelf(grunt.util.linefeed));

      // Write the destination file.
      grunt.file.write(file.dest, src);

      // Print a success message.
      grunt.log.ok('Build HTML file to "' + file.dest + '"');
    });
  });

};
<commit_msg>Template settings correction : Do not override standard delimiters if they are not set in configuration.<commit_after>/*
 * grunt-build-html
 * https://github.com/tonai/grunt-build-html
 *
 * Copyright (c) 2013 Tony Cabaye
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var path      = require('path');
  var _         = grunt.util._;
  var debug     = grunt.log.debug;
  var backtrace = function(files) {
    var message = '[backtrace] : ';
    for (var i in files) {
      message += grunt.util.linefeed + files[i];
    }
    debug(grunt.util.normalizelf(message));
  };

  grunt.registerMultiTask('build_html', 'Build HTML templates recursively.', function() {
    var include          = null;
    var templates        = {};
    var templateSettings = {};

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      templates: []
    });

    // Manage template settings
    if (options.interpolate !== undefined) {
      templateSettings.interpolate = options.interpolate;
    }
    if (options.escape !== undefined) {
      templateSettings.escape = options.escape;
    }
    if (options.evaluate !== undefined) {
      templateSettings.evaluate = options.evaluate;
    }

    // Include method to be used in HTML files.
    include = function(tplName, data) {
      var files, templateData, html = '';
      if (typeof data == 'undefined') {
        data = {};
      }

      if (_.has(templates, tplName)) {
        files = _.clone(this.files);
        files.push(templates[tplName].filepath);
        templateData = {files: files};
        data.include = include.bind(templateData);
        try {
          html = _.template(templates[tplName].content, data, templateSettings);
        } catch (error) {
          grunt.log.error(error.message);
          backtrace(files);
        }
      } else {
        grunt.log.writeln('Template "' + tplName + '" does not exists.');
        backtrace(this.files);
      }

      return html;
    };

    // Process templates.
    _.each(grunt.file.expand(options.templates), function(tpl) {
      var tplName = path.basename(tpl, path.extname(tpl)).replace(/[\s]/g, '_');
      debug("loading template :", tplName);
      debug("  path is :", tpl);
      templates[tplName] = {
        content: grunt.file.read(tpl),
        filepath: tpl
      };
    });

    // Iterate over all specified file groups.
    this.files.forEach(function(file) {
      // Concat specified files.
      var src = file.src.filter(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return false;
        } else {
          return true;
        }
      }).map(function(filepath) {
        var html = '';
        var templateData = {files: [filepath]};
        templateData.include = include.bind(templateData);
        options.filename = filepath;
        try {
          html = _.template(grunt.file.read(filepath), templateData, templateSettings);
        } catch (error) {
          grunt.log.error(error.message);
          backtrace(templateData.files);
        }
        return html;
      }).join(grunt.util.normalizelf(grunt.util.linefeed));

      // Write the destination file.
      grunt.file.write(file.dest, src);

      // Print a success message.
      grunt.log.ok('Build HTML file to "' + file.dest + '"');
    });
  });

};

<|endoftext|>


<commit_before>/*
 * grunt-require-gettext
 * https://github.com/open-xchange-frontend/grunt-require-gettext
 *
 * Copyright (c) 2014 Julian Bäume
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {

    grunt.registerMultiTask('compile_po', 'Compiles different po files to their corresponding requirejs gettext module.', function () {
        var done = this.async();
        var PO = require('pofile');
        var _ = require('lodash');
        var dest = this.files[0].dest;
        var options = this.options;

        grunt.file.mkdir(dest);
        if (this.files.length > 1 || !grunt.file.isDir(dest)) {
            grunt.fail.fatal('Target (' + dest + ') must be exactly _one_ directory');
            done(false);
        }

        this.files[0].src.filter(function (srcFile) {
            return srcFile.substr(-3) === '.po';
        }).forEach(function (poFile) {
            var fromFile;
            var templateFile = options().template;
            if (templateFile && grunt.file.isFile(templateFile)) {
                fromFile = grunt.file.read(templateFile);
            }
            /* jshint multistr: true */
            var template = fromFile ||
'define("<%= module %>.<%= language %>", [], function () {\n\
    return {\n\
        "module": "<%= module %>",\n\
        "language": "<%= language %>",\n\
        "nplurals": <%= nplurals %>,\n\
        "plural": "<%= plural %>",\n\
        "dictionary": {\n\
<% for (var msgid in dictionary) {%>\
            <%= JSON.stringify(msgid) %>: <%= JSON.stringify(dictionary[msgid]) %>,\n\
<% } %>\
        }\n\
    };\n\
});\n';
            /* jshint multistr: false */

            var showModuleWarning = false;
            PO.load(poFile, function (err, po) {
                if (err) {
                    grunt.fail.fatal(err);
                    done(false);
                }
                var modules = {};
                po.items.forEach(function (item) {
                    var module = item.references.filter(function (ref) {
                        return ref.substr(0, 7) === 'module:';
                    })[0];

                    if (!module) {
                        showModuleWarning = true;
                        grunt.verbose.warn('Ignoring item (no module found): ' + item.msgid);
                        grunt.verbose.warn(item);
                        grunt.verbose.warn('in file', poFile);
                        return;
                    }
                    module = module.substr(7);

                    module = module;
                    if (!modules[module]) {
                        modules[module] = [];
                    }
                    modules[module].push(item);
                });
                var mkIdStrMapping = function (acc, poItem) {
                    acc[poItem.msgid] = poItem.msgstr;
                    return acc;
                };

                var parsePluralForms = function (str) {
                    return str.split(';').map(function (val) {
                        var index = val.indexOf('=');
                        return [val.substr(0, index).trim(), val.substr(index + 1).trim()];
                    }).reduce(function (acc, arr) {
                        if (!arr[0] || !arr[1]) {
                            return acc;
                        }
                        acc[arr[0]] = arr[1];
                        return acc;
                    }, {});
                };

                for (var module in modules) {
                    var items = modules[module].reduce(mkIdStrMapping, {});
                    var pluralForms = parsePluralForms(po.headers['Plural-Forms']);
                    var data = {
                        module: module,
                        language: po.headers.Language,
                        nplurals: pluralForms.nplurals,
                        plural: pluralForms.plural,
                        dictionary: items
                    };

                    grunt.file.write(dest + module + '.' + data.language + '.js', _.template(template, data));
                }
                if (showModuleWarning) {
                    grunt.verbose.or.warn('Could not load module information for at least one item, run with --verbose to get more info');
                }
                done(true);
            });
        });
    });
};
<commit_msg>fix timing issue with async task<commit_after>/*
 * grunt-require-gettext
 * https://github.com/open-xchange-frontend/grunt-require-gettext
 *
 * Copyright (c) 2014 Julian Bäume
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {

    grunt.registerMultiTask('compile_po', 'Compiles different po files to their corresponding requirejs gettext module.', function () {
        var done = this.async();
        var PO = require('pofile');
        var _ = require('lodash');
        var dest = this.files[0].dest;
        var options = this.options;

        grunt.file.mkdir(dest);
        if (this.files.length > 1 || !grunt.file.isDir(dest)) {
            grunt.fail.fatal('Target (' + dest + ') must be exactly _one_ directory');
            done(false);
        }

        var last = this.files[0].src.length - 1;
        var showModuleWarning = false;
        this.files[0].src.forEach(function (poFile, index) {
            var fromFile;
            var templateFile = options().template;
            if (templateFile && grunt.file.isFile(templateFile)) {
                fromFile = grunt.file.read(templateFile);
            }
            /* jshint multistr: true */
            var template = fromFile ||
'define("<%= module %>.<%= language %>", [], function () {\n\
    return {\n\
        "module": "<%= module %>",\n\
        "language": "<%= language %>",\n\
        "nplurals": <%= nplurals %>,\n\
        "plural": "<%= plural %>",\n\
        "dictionary": {\n\
<% for (var msgid in dictionary) {%>\
            <%= JSON.stringify(msgid) %>: <%= JSON.stringify(dictionary[msgid]) %>,\n\
<% } %>\
        }\n\
    };\n\
});\n';
            /* jshint multistr: false */

            PO.load(poFile, function (err, po) {
                if (err) {
                    grunt.fail.fatal(err);
                    done(false);
                }
                var modules = {};
                po.items.forEach(function (item) {
                    var module = item.references.filter(function (ref) {
                        return ref.substr(0, 7) === 'module:';
                    })[0];

                    if (!module) {
                        showModuleWarning = true;
                        grunt.verbose.warn('Ignoring item (no module found): ' + item.msgid);
                        grunt.verbose.warn(item);
                        grunt.verbose.warn('in file', poFile);
                        return;
                    }
                    module = module.substr(7);

                    module = module;
                    if (!modules[module]) {
                        modules[module] = [];
                    }
                    modules[module].push(item);
                });
                var mkIdStrMapping = function (acc, poItem) {
                    acc[poItem.msgid] = poItem.msgstr;
                    return acc;
                };

                var parsePluralForms = function (str) {
                    return str.split(';').map(function (val) {
                        var index = val.indexOf('=');
                        return [val.substr(0, index).trim(), val.substr(index + 1).trim()];
                    }).reduce(function (acc, arr) {
                        if (!arr[0] || !arr[1]) {
                            return acc;
                        }
                        acc[arr[0]] = arr[1];
                        return acc;
                    }, {});
                };

                for (var module in modules) {
                    var items = modules[module].reduce(mkIdStrMapping, {});
                    var pluralForms = parsePluralForms(po.headers['Plural-Forms']);
                    var data = {
                        module: module,
                        language: po.headers.Language,
                        nplurals: pluralForms.nplurals,
                        plural: pluralForms.plural,
                        dictionary: items
                    };

                    grunt.file.write(dest + module + '.' + data.language + '.js', _.template(template, data));
                }

                if (index === last) {
                    if (showModuleWarning) {
                        grunt.verbose.or.warn('Could not load module information for at least one item, run with --verbose to get more info');
                    }
                    done(true);
                }
            });
        });
    });
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

var EventEmitter = require( 'events' ).EventEmitter
  , util = require( 'util' )
  , stringify = require( 'json-stable-stringify' );

function Expector(assert) {
  var expectations = []
    , instance = this
    , pEmit;

  EventEmitter.call( instance );
  pEmit = instance.emit;
  assert = makeAssert(assert);

  instance.emit = function() {

    for (var i = 0; i < arguments.length; ++i) {
      if (typeof arguments[0] !== 'string') {
        arguments[0] = stringify( arguments[0] );
      }
    }

    pEmit.apply( instance, arguments );
    return instance;
  };

  instance.__defineGetter__( 'expectations', function() {
    return expectations;
  });

  instance.check = function() {
    var message = 'met all expectations: ';
    message += util.inspect( expectations );
    assert.equal( expectations.length, 0, message );
    assert.end();
  };

  instance.expectNot = function( event ) {
    if (typeof event !== 'string') {
      event = stringify( event );
    }
    instance.on( event, function() {
      assert.fail( 'event is expected not to occur: ' + event );
    } );
    return instance;
  };

  instance.repeat = function( counter ) {
    assert.assert( typeof counter === 'number' );
    while(counter--) {
      expectations.push( expectations[ expectations.length - 1 ] );
    }
    return instance;
  };

  instance.expect = function( event, code ) {
    if (typeof event !== 'string') {
      event = stringify( event );
    }
    if (!expectations.length) {
      instance.once( event, check );
    }
    expectations.push( { event: event, code: code } );
    return instance;

    function check( code ) {
      var expectation = expectations[0];
      expectations.splice( 0, 1 );

      if (expectation.code != undefined) {

        if (code instanceof Array) {
          assert.assert( expectation.code instanceof Array );

          code.forEach( function( element, index) {
            code[index] = element.trim();
            if (index == code.length - 1) {
              var expected = expectation.code.toString()
                , received = code.toString();
              assert.deepEqual( received, expected );
            }
          } );
        }
        else if (typeof code === 'string') {
          assert.deepEqual( code.trim(), expectation.code.trim() );
        }
        else {
          assert.deepEqual( stringify(code), stringify( expectation.code ) );
        }
      }

      if (expectations.length) {
        instance.once( expectations[0].event, check );
      }
    }
  };
}

util.inherits( Expector, EventEmitter );

function SeqExpector(assert) {
  var instance = this
    , pEmit;

  assert = makeAssert(assert);

  Expector.call( instance, assert );

  pEmit = instance.emit;
  instance.emit = function() {
    if (typeof arguments[0] !== 'string') {
      arguments[0] = stringify( arguments[0] );
    }
    assert.assert( instance.expectations.length );
    assert.deepEqual( instance.expectations[0].event, arguments[0] );
    pEmit.apply( instance, arguments );
    return instance;
  };
}

function makeAssert(assert) {
  if (typeof assert === 'undefined') {
    assert = require( 'assert' );
    assert.assert = assert;
    assert.end = function() {};
  }
  return assert;
}

util.inherits( SeqExpector, Expector );

exports.Expector = Expector;
exports.SeqExpector = SeqExpector;<commit_msg>update syntax<commit_after>#!/usr/bin/env node

'use strict';

var EventEmitter = require( 'events' ).EventEmitter
  , util = require( 'util' )
  , stringify = require( 'json-stable-stringify' );

function Expector(assert) {
  var expectations = []
    , instance = this
    , pEmit;

  EventEmitter.call( instance );
  pEmit = instance.emit;
  assert = makeAssert(assert);

  instance.emit = function() {

    for (var i = 0; i < arguments.length; ++i) {
      if (typeof arguments[0] !== 'string') {
        arguments[0] = stringify( arguments[0] );
      }
    }

    pEmit.apply( instance, arguments );
    return instance;
  };

  instance.__defineGetter__( 'expectations', () => {
    return expectations;
  });

  instance.check = function() {
    var message = 'met all expectations: ';
    message += util.inspect( expectations );
    assert.equal( expectations.length, 0, message );
    assert.end();
  };

  instance.expectNot = function( event ) {
    if (typeof event !== 'string') {
      event = stringify( event );
    }
    instance.on( event, function() {
      assert.fail( 'event is expected not to occur: ' + event );
    } );
    return instance;
  };

  instance.repeat = function( counter ) {
    assert.assert( typeof counter === 'number' );
    while(counter--) {
      expectations.push( expectations[ expectations.length - 1 ] );
    }
    return instance;
  };

  instance.expect = function( event, code ) {
    if (typeof event !== 'string') {
      event = stringify( event );
    }
    if (!expectations.length) {
      instance.once( event, check );
    }
    expectations.push( { event: event, code: code } );
    return instance;

    function check( code ) {
      var expectation = expectations[0];
      expectations.splice( 0, 1 );

      if (expectation.code != undefined) {

        if (code instanceof Array) {
          assert.assert( expectation.code instanceof Array );

          code.forEach( function( element, index) {
            code[index] = element.trim();
            if (index == code.length - 1) {
              var expected = expectation.code.toString()
                , received = code.toString();
              assert.deepEqual( received, expected );
            }
          } );
        }
        else if (typeof code === 'string') {
          assert.deepEqual( code.trim(), expectation.code.trim() );
        }
        else {
          assert.deepEqual( stringify(code), stringify( expectation.code ) );
        }
      }

      if (expectations.length) {
        instance.once( expectations[0].event, check );
      }
    }
  };
}

util.inherits( Expector, EventEmitter );

function SeqExpector(assert) {
  var instance = this
    , pEmit;

  assert = makeAssert(assert);

  Expector.call( instance, assert );

  pEmit = instance.emit;
  instance.emit = function() {
    if (typeof arguments[0] !== 'string') {
      arguments[0] = stringify( arguments[0] );
    }
    assert.assert( instance.expectations.length );
    assert.deepEqual( instance.expectations[0].event, arguments[0] );
    pEmit.apply( instance, arguments );
    return instance;
  };
}

function makeAssert(assert) {
  if (typeof assert === 'undefined') {
    assert = require( 'assert' );
    assert.assert = assert;
    assert.end = function() {};
  }
  return assert;
}

util.inherits( SeqExpector, Expector );

exports.Expector = Expector;
exports.SeqExpector = SeqExpector;<|endoftext|>


<commit_before>import standardSqlFormatter from "xr/sqlFormatter/standardSqlFormatter";

describe("standardSqlFormatter", function() {
    it("formats simple SELECT query", function() {
        const result = standardSqlFormatter.format("SELECT count(*),Column1 FROM Table1;");
        expect(result).toBe(
            "SELECT\n" +
            "  count(*),\n" +
            "  Column1\n" +
            "FROM\n" +
            "  Table1;\n"
        );
    });

    it("formats SELECT query with complex WHERE", function() {
        const result = standardSqlFormatter.format(
            "SELECT count(*),'Column1','Testing', 'Testing Three' FROM Table1 WHERE Column1 = 'testing' " +
            "AND ( (Column2 = Column3 OR Column4 >= NOW()) );"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  count(*),\n" +
            "  'Column1',\n" +
            "  'Testing',\n" +
            "  'Testing Three'\n" +
            "FROM\n" +
            "  Table1\n" +
            "WHERE\n" +
            "  Column1 = 'testing'\n" +
            "  AND (\n" +
            "    (\n" +
            "      Column2 = Column3\n" +
            "      OR Column4 >= NOW()\n" +
            "    )\n" +
            "  );\n"
        );
    });

    it("formats SELECT with toplevel reserved words", function() {
        const result = standardSqlFormatter.format(
            "SELECT * FROM foo WHERE name = 'John' GROUP BY some_column " +
            "HAVING column > 10 ORDER BY other_column LIMIT 5,10 OFFSET 20;"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  *\n" +
            "FROM\n" +
            "  foo\n" +
            "WHERE\n" +
            "  name = 'John'\n" +
            "GROUP BY\n" +
            "  some_column\n" +
            "HAVING\n" +
            "  column > 10\n" +
            "ORDER BY\n" +
            "  other_column\n" +
            "LIMIT\n" +
            "  5, 10 OFFSET 20;\n"
        );
    });

    it("formats SELECT query with SELECT query inside it", function() {
        const result = standardSqlFormatter.format(
            "SELECT *, SUM(*) AS sum FROM (SELECT * FROM Posts LIMIT 30) WHERE a > b"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  *,\n" +
            "  SUM(*) AS sum\n" +
            "FROM\n" +
            "  (\n" +
            "    SELECT\n" +
            "      *\n" +
            "    FROM\n" +
            "      Posts\n" +
            "    LIMIT\n" +
            "      30\n" +
            "  )\n" +
            "WHERE\n" +
            "  a > b\n"
        );
    });

    it("formats SELECT query with INNER JOIN", function() {
        const result = standardSqlFormatter.format(
            "SELECT customer_id.from, COUNT(order_id) AS total FROM customers " +
            "INNER JOIN orders ON customers.customer_id = orders.customer_id;"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  customer_id.from,\n" +
            "  COUNT(order_id) AS total\n" +
            "FROM\n" +
            "  customers\n" +
            "  INNER JOIN orders ON customers.customer_id = orders.customer_id;\n"
        );
    });

    it("formats SELECT query with different comments", function() {
        const result = standardSqlFormatter.format(
            "SELECT\n" +
            "/* This is a block comment\n" +
            "*/\n" +
            "* FROM\n" +
            "-- This is another comment\n" +
            "MyTable # One final comment\n" +
            "WHERE 1 = 2;"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  /* This is a block comment\n" +
            "  */\n" +
            "  *\n" +
            "FROM\n" +
            "  -- This is another comment\n" +
            "  MyTable # One final comment\n" +
            "WHERE\n" +
            "  1 = 2;\n"
        );
    });

    it("formats SELECT query with different variable types", function() {
        const result = standardSqlFormatter.format(
            "SELECT @variable, @'variable name';"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  @variable,\n" +
            "  @'variable name';\n"
        );
    });

    it("formats simple INSERT query", function() {
        const result = standardSqlFormatter.format(
            "INSERT INTO Customers (ID, MoneyBalance, Address, City) VALUES (12,-123.4, 'Skagen 2111','Stavanger');"
        );
        expect(result).toBe(
            "INSERT INTO Customers (ID, MoneyBalance, Address, City)\n" +
            "VALUES\n" +
            "  (\n" +
            "    12, -123.4, 'Skagen 2111', 'Stavanger'\n" +
            "  );\n"
        );
    });

    it("formats long INSERT query including SELECT, IF and INNER JOIN parts", function() {
        const result = standardSqlFormatter.format(
            "INSERT INTO `PREFIX_specific_price` (`id_product`, `id_shop`, `id_currency`, `id_country`, `id_group`, `priority`, " +
            "`price`, `from_quantity`, `reduction`,   `reduction_type`, `from`, `to`) (" +
            "SELECT dq.`id_product`, 1, 1,0,1, 0, 0.00, dq.`quantity`, IF(dq.`id_discount_type` = 2, dq.`value`, dq.`value` / 100)," +
            "IF (dq.`id_discount_type` = 2, 'amount', 'percentage'), '0000-00-00 00:00:00', '0000-00-00 00:00:00' " +
            "FROM `PREFIX_discount_quantity` dq INNER JOIN `PREFIX_product` p ON (p.`id_product` = dq.`id_product`));"
        );
        expect(result).toBe(
            "INSERT INTO `PREFIX_specific_price` (\n" +
            "  `id_product`, `id_shop`, `id_currency`,\n" +
            "  `id_country`, `id_group`, `priority`,\n" +
            "  `price`, `from_quantity`, `reduction`,\n" +
            "  `reduction_type`, `from`, `to`\n" +
            ") (\n" +
            "  SELECT\n" +
            "    dq.`id_product`,\n" +
            "    1,\n" +
            "    1,\n" +
            "    0,\n" +
            "    1,\n" +
            "    0,\n" +
            "    0.00,\n" +
            "    dq.`quantity`,\n" +
            "    IF(\n" +
            "      dq.`id_discount_type` = 2, dq.`value`,\n" +
            "      dq.`value` / 100\n" +
            "    ),\n" +
            "    IF (\n" +
            "      dq.`id_discount_type` = 2, 'amount',\n" +
            "      'percentage'\n" +
            "    ),\n" +
            "    '0000-00-00 00:00:00',\n" +
            "    '0000-00-00 00:00:00'\n" +
            "  FROM\n" +
            "    `PREFIX_discount_quantity` dq\n" +
            "    INNER JOIN `PREFIX_product` p ON (p.`id_product` = dq.`id_product`)\n" +
            ");\n"
        );
    });

    it("formats simple UPDATE query", function() {
        const result = standardSqlFormatter.format(
            "uPDATE Customers set ContactName='Alfred Schmidt', City='Hamburg' WHERE CustomerName='Alfreds Futterkiste';"
        );
        expect(result).toBe(
            "uPDATE\n" +
            "  Customers\n" +
            "set\n" +
            "  ContactName = 'Alfred Schmidt',\n" +
            "  City = 'Hamburg'\n" +
            "WHERE\n" +
            "  CustomerName = 'Alfreds Futterkiste';\n"
        );
    });

    it("formats simple DELETE query", function() {
        const result = standardSqlFormatter.format(
            "DELETE FROM Customers WHERE CustomerName='Alfred' AND Phone=5002132;"
        );
        expect(result).toBe(
            "DELETE FROM\n" +
            "  Customers\n" +
            "WHERE\n" +
            "  CustomerName = 'Alfred'\n" +
            "  AND Phone = 5002132;\n"
        );
    });

    it("formats simple DROP query", function() {
        const result = standardSqlFormatter.format(
            "DROP TABLE IF EXISTS admin_role;"
        );
        expect(result).toBe(
            "DROP\n" +
            "  TABLE IF EXISTS admin_role;\n"
        );
    });

    it("formats uncomplete query", function() {
        const result = standardSqlFormatter.format("SELECT count(");
        expect(result).toBe(
            "SELECT\n" +
            "  count(\n"
        );
    });

    it("formats query that ends with open comment", function() {
        const result = standardSqlFormatter.format("SELECT count(*)\n/*Comment");
        expect(result).toBe(
            "SELECT\n" +
            "  count(*)\n" +
            "  /*Comment\n"
        );
    });

    it("formats UPDATE query with AS part", function() {
        const result = standardSqlFormatter.format(
            "UPDATE customers SET totalorders = ordersummary.total  FROM ( SELECT * FROM bank) As ordersummary"
        );
        expect(result).toBe(
            "UPDATE\n" +
            "  customers\n" +
            "SET\n" +
            "  totalorders = ordersummary.total\n" +
            "FROM\n" +
            "  (\n" +
            "    SELECT\n" +
            "      *\n" +
            "    FROM\n" +
            "      bank\n" +
            "  ) As ordersummary\n"
        );
    });

    it("formats top-level and newline multi-word reserved words with inconsistent spacing", function() {
        const result = standardSqlFormatter.format("SELECT * FROM foo LEFT \t OUTER  \n JOIN bar ORDER \n BY blah");
        expect(result).toBe(
            "SELECT\n" +
            "  *\n" +
            "FROM\n" +
            "  foo\n" +
            "  LEFT OUTER JOIN bar\n" +
            "ORDER BY\n" +
            "  blah\n"
        );
    });

    it("formats single-char operators", function() {
        expect(standardSqlFormatter.format("foo = bar")).toBe("foo = bar\n");
        expect(standardSqlFormatter.format("foo < bar")).toBe("foo < bar\n");
        expect(standardSqlFormatter.format("foo > bar")).toBe("foo > bar\n");
        expect(standardSqlFormatter.format("foo + bar")).toBe("foo + bar\n");
        expect(standardSqlFormatter.format("foo - bar")).toBe("foo - bar\n");
        expect(standardSqlFormatter.format("foo * bar")).toBe("foo * bar\n");
        expect(standardSqlFormatter.format("foo / bar")).toBe("foo / bar\n");
        expect(standardSqlFormatter.format("foo % bar")).toBe("foo % bar\n");
    });

    it("formats multi-char operators", function() {
        expect(standardSqlFormatter.format("foo != bar")).toBe("foo != bar\n");
        expect(standardSqlFormatter.format("foo <> bar")).toBe("foo <> bar\n");
        expect(standardSqlFormatter.format("foo == bar")).toBe("foo == bar\n"); // N1QL
        expect(standardSqlFormatter.format("foo || bar")).toBe("foo || bar\n"); // Oracle, Postgres, N1QL string concat

        expect(standardSqlFormatter.format("foo <= bar")).toBe("foo <= bar\n");
        expect(standardSqlFormatter.format("foo >= bar")).toBe("foo >= bar\n");

        expect(standardSqlFormatter.format("foo !< bar")).toBe("foo !< bar\n");
        expect(standardSqlFormatter.format("foo !> bar")).toBe("foo !> bar\n");
    });

    it("formats logical operators", function() {
        expect(standardSqlFormatter.format("foo ALL bar")).toBe("foo ALL bar\n");
        expect(standardSqlFormatter.format("foo = ANY (1, 2, 3)")).toBe("foo = ANY (1, 2, 3)\n");
        expect(standardSqlFormatter.format("EXISTS bar")).toBe("EXISTS bar\n");
        expect(standardSqlFormatter.format("foo IN (1, 2, 3)")).toBe("foo IN (1, 2, 3)\n");
        expect(standardSqlFormatter.format("foo LIKE 'hello%'")).toBe("foo LIKE 'hello%'\n");
        expect(standardSqlFormatter.format("foo IS NULL")).toBe("foo IS NULL\n");
        expect(standardSqlFormatter.format("UNIQUE foo")).toBe("UNIQUE foo\n");
    });

    it("formats AND/OR operators", function() {
        expect(standardSqlFormatter.format("foo BETWEEN bar AND baz")).toBe("foo BETWEEN bar\nAND baz\n");
        expect(standardSqlFormatter.format("foo AND bar")).toBe("foo\nAND bar\n");
        expect(standardSqlFormatter.format("foo OR bar")).toBe("foo\nOR bar\n");
    });

    it("recognizes strings", function() {
        expect(standardSqlFormatter.format("\"foo JOIN bar\"")).toBe("\"foo JOIN bar\"\n");
        expect(standardSqlFormatter.format("'foo JOIN bar'")).toBe("'foo JOIN bar'\n");
        expect(standardSqlFormatter.format("`foo JOIN bar`")).toBe("`foo JOIN bar`\n");
        expect(standardSqlFormatter.format("[foo JOIN bar]")).toBe("[foo JOIN bar]\n");
    });

    it("recognizes escaped strings", function() {
        expect(standardSqlFormatter.format("\"foo \\\" JOIN bar\"")).toBe("\"foo \\\" JOIN bar\"\n");
        expect(standardSqlFormatter.format("'foo \\' JOIN bar'")).toBe("'foo \\' JOIN bar'\n");
        expect(standardSqlFormatter.format("`foo `` JOIN bar`")).toBe("`foo `` JOIN bar`\n");
        expect(standardSqlFormatter.format("[foo ]] JOIN bar]")).toBe("[foo ]] JOIN bar]\n");
    });
});
<commit_msg>XR-3710 Separate test for preserving case of keywords<commit_after>import standardSqlFormatter from "xr/sqlFormatter/standardSqlFormatter";

describe("standardSqlFormatter", function() {
    it("formats simple SELECT query", function() {
        const result = standardSqlFormatter.format("SELECT count(*),Column1 FROM Table1;");
        expect(result).toBe(
            "SELECT\n" +
            "  count(*),\n" +
            "  Column1\n" +
            "FROM\n" +
            "  Table1;\n"
        );
    });

    it("formats SELECT query with complex WHERE", function() {
        const result = standardSqlFormatter.format(
            "SELECT count(*),'Column1','Testing', 'Testing Three' FROM Table1 WHERE Column1 = 'testing' " +
            "AND ( (Column2 = Column3 OR Column4 >= NOW()) );"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  count(*),\n" +
            "  'Column1',\n" +
            "  'Testing',\n" +
            "  'Testing Three'\n" +
            "FROM\n" +
            "  Table1\n" +
            "WHERE\n" +
            "  Column1 = 'testing'\n" +
            "  AND (\n" +
            "    (\n" +
            "      Column2 = Column3\n" +
            "      OR Column4 >= NOW()\n" +
            "    )\n" +
            "  );\n"
        );
    });

    it("formats SELECT with toplevel reserved words", function() {
        const result = standardSqlFormatter.format(
            "SELECT * FROM foo WHERE name = 'John' GROUP BY some_column " +
            "HAVING column > 10 ORDER BY other_column LIMIT 5,10 OFFSET 20;"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  *\n" +
            "FROM\n" +
            "  foo\n" +
            "WHERE\n" +
            "  name = 'John'\n" +
            "GROUP BY\n" +
            "  some_column\n" +
            "HAVING\n" +
            "  column > 10\n" +
            "ORDER BY\n" +
            "  other_column\n" +
            "LIMIT\n" +
            "  5, 10 OFFSET 20;\n"
        );
    });

    it("preserves case of keywords", function() {
        const result = standardSqlFormatter.format(
            "select distinct * frOM foo left join bar WHERe a > 1 and b = 3"
        );
        expect(result).toBe(
            "select\n" +
            "  distinct *\n" +
            "frOM\n" +
            "  foo\n" +
            "  left join bar\n" +
            "WHERe\n" +
            "  a > 1\n" +
            "  and b = 3\n"
        );
    });

    it("formats SELECT query with SELECT query inside it", function() {
        const result = standardSqlFormatter.format(
            "SELECT *, SUM(*) AS sum FROM (SELECT * FROM Posts LIMIT 30) WHERE a > b"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  *,\n" +
            "  SUM(*) AS sum\n" +
            "FROM\n" +
            "  (\n" +
            "    SELECT\n" +
            "      *\n" +
            "    FROM\n" +
            "      Posts\n" +
            "    LIMIT\n" +
            "      30\n" +
            "  )\n" +
            "WHERE\n" +
            "  a > b\n"
        );
    });

    it("formats SELECT query with INNER JOIN", function() {
        const result = standardSqlFormatter.format(
            "SELECT customer_id.from, COUNT(order_id) AS total FROM customers " +
            "INNER JOIN orders ON customers.customer_id = orders.customer_id;"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  customer_id.from,\n" +
            "  COUNT(order_id) AS total\n" +
            "FROM\n" +
            "  customers\n" +
            "  INNER JOIN orders ON customers.customer_id = orders.customer_id;\n"
        );
    });

    it("formats SELECT query with different comments", function() {
        const result = standardSqlFormatter.format(
            "SELECT\n" +
            "/* This is a block comment\n" +
            "*/\n" +
            "* FROM\n" +
            "-- This is another comment\n" +
            "MyTable # One final comment\n" +
            "WHERE 1 = 2;"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  /* This is a block comment\n" +
            "  */\n" +
            "  *\n" +
            "FROM\n" +
            "  -- This is another comment\n" +
            "  MyTable # One final comment\n" +
            "WHERE\n" +
            "  1 = 2;\n"
        );
    });

    it("formats SELECT query with different variable types", function() {
        const result = standardSqlFormatter.format(
            "SELECT @variable, @'variable name';"
        );
        expect(result).toBe(
            "SELECT\n" +
            "  @variable,\n" +
            "  @'variable name';\n"
        );
    });

    it("formats simple INSERT query", function() {
        const result = standardSqlFormatter.format(
            "INSERT INTO Customers (ID, MoneyBalance, Address, City) VALUES (12,-123.4, 'Skagen 2111','Stavanger');"
        );
        expect(result).toBe(
            "INSERT INTO Customers (ID, MoneyBalance, Address, City)\n" +
            "VALUES\n" +
            "  (\n" +
            "    12, -123.4, 'Skagen 2111', 'Stavanger'\n" +
            "  );\n"
        );
    });

    it("formats long INSERT query including SELECT, IF and INNER JOIN parts", function() {
        const result = standardSqlFormatter.format(
            "INSERT INTO `PREFIX_specific_price` (`id_product`, `id_shop`, `id_currency`, `id_country`, `id_group`, `priority`, " +
            "`price`, `from_quantity`, `reduction`,   `reduction_type`, `from`, `to`) (" +
            "SELECT dq.`id_product`, 1, 1,0,1, 0, 0.00, dq.`quantity`, IF(dq.`id_discount_type` = 2, dq.`value`, dq.`value` / 100)," +
            "IF (dq.`id_discount_type` = 2, 'amount', 'percentage'), '0000-00-00 00:00:00', '0000-00-00 00:00:00' " +
            "FROM `PREFIX_discount_quantity` dq INNER JOIN `PREFIX_product` p ON (p.`id_product` = dq.`id_product`));"
        );
        expect(result).toBe(
            "INSERT INTO `PREFIX_specific_price` (\n" +
            "  `id_product`, `id_shop`, `id_currency`,\n" +
            "  `id_country`, `id_group`, `priority`,\n" +
            "  `price`, `from_quantity`, `reduction`,\n" +
            "  `reduction_type`, `from`, `to`\n" +
            ") (\n" +
            "  SELECT\n" +
            "    dq.`id_product`,\n" +
            "    1,\n" +
            "    1,\n" +
            "    0,\n" +
            "    1,\n" +
            "    0,\n" +
            "    0.00,\n" +
            "    dq.`quantity`,\n" +
            "    IF(\n" +
            "      dq.`id_discount_type` = 2, dq.`value`,\n" +
            "      dq.`value` / 100\n" +
            "    ),\n" +
            "    IF (\n" +
            "      dq.`id_discount_type` = 2, 'amount',\n" +
            "      'percentage'\n" +
            "    ),\n" +
            "    '0000-00-00 00:00:00',\n" +
            "    '0000-00-00 00:00:00'\n" +
            "  FROM\n" +
            "    `PREFIX_discount_quantity` dq\n" +
            "    INNER JOIN `PREFIX_product` p ON (p.`id_product` = dq.`id_product`)\n" +
            ");\n"
        );
    });

    it("formats simple UPDATE query", function() {
        const result = standardSqlFormatter.format(
            "UPDATE Customers SET ContactName='Alfred Schmidt', City='Hamburg' WHERE CustomerName='Alfreds Futterkiste';"
        );
        expect(result).toBe(
            "UPDATE\n" +
            "  Customers\n" +
            "SET\n" +
            "  ContactName = 'Alfred Schmidt',\n" +
            "  City = 'Hamburg'\n" +
            "WHERE\n" +
            "  CustomerName = 'Alfreds Futterkiste';\n"
        );
    });

    it("formats simple DELETE query", function() {
        const result = standardSqlFormatter.format(
            "DELETE FROM Customers WHERE CustomerName='Alfred' AND Phone=5002132;"
        );
        expect(result).toBe(
            "DELETE FROM\n" +
            "  Customers\n" +
            "WHERE\n" +
            "  CustomerName = 'Alfred'\n" +
            "  AND Phone = 5002132;\n"
        );
    });

    it("formats simple DROP query", function() {
        const result = standardSqlFormatter.format(
            "DROP TABLE IF EXISTS admin_role;"
        );
        expect(result).toBe(
            "DROP\n" +
            "  TABLE IF EXISTS admin_role;\n"
        );
    });

    it("formats uncomplete query", function() {
        const result = standardSqlFormatter.format("SELECT count(");
        expect(result).toBe(
            "SELECT\n" +
            "  count(\n"
        );
    });

    it("formats query that ends with open comment", function() {
        const result = standardSqlFormatter.format("SELECT count(*)\n/*Comment");
        expect(result).toBe(
            "SELECT\n" +
            "  count(*)\n" +
            "  /*Comment\n"
        );
    });

    it("formats UPDATE query with AS part", function() {
        const result = standardSqlFormatter.format(
            "UPDATE customers SET totalorders = ordersummary.total  FROM ( SELECT * FROM bank) AS ordersummary"
        );
        expect(result).toBe(
            "UPDATE\n" +
            "  customers\n" +
            "SET\n" +
            "  totalorders = ordersummary.total\n" +
            "FROM\n" +
            "  (\n" +
            "    SELECT\n" +
            "      *\n" +
            "    FROM\n" +
            "      bank\n" +
            "  ) AS ordersummary\n"
        );
    });

    it("formats top-level and newline multi-word reserved words with inconsistent spacing", function() {
        const result = standardSqlFormatter.format("SELECT * FROM foo LEFT \t OUTER  \n JOIN bar ORDER \n BY blah");
        expect(result).toBe(
            "SELECT\n" +
            "  *\n" +
            "FROM\n" +
            "  foo\n" +
            "  LEFT OUTER JOIN bar\n" +
            "ORDER BY\n" +
            "  blah\n"
        );
    });

    it("formats single-char operators", function() {
        expect(standardSqlFormatter.format("foo = bar")).toBe("foo = bar\n");
        expect(standardSqlFormatter.format("foo < bar")).toBe("foo < bar\n");
        expect(standardSqlFormatter.format("foo > bar")).toBe("foo > bar\n");
        expect(standardSqlFormatter.format("foo + bar")).toBe("foo + bar\n");
        expect(standardSqlFormatter.format("foo - bar")).toBe("foo - bar\n");
        expect(standardSqlFormatter.format("foo * bar")).toBe("foo * bar\n");
        expect(standardSqlFormatter.format("foo / bar")).toBe("foo / bar\n");
        expect(standardSqlFormatter.format("foo % bar")).toBe("foo % bar\n");
    });

    it("formats multi-char operators", function() {
        expect(standardSqlFormatter.format("foo != bar")).toBe("foo != bar\n");
        expect(standardSqlFormatter.format("foo <> bar")).toBe("foo <> bar\n");
        expect(standardSqlFormatter.format("foo == bar")).toBe("foo == bar\n"); // N1QL
        expect(standardSqlFormatter.format("foo || bar")).toBe("foo || bar\n"); // Oracle, Postgres, N1QL string concat

        expect(standardSqlFormatter.format("foo <= bar")).toBe("foo <= bar\n");
        expect(standardSqlFormatter.format("foo >= bar")).toBe("foo >= bar\n");

        expect(standardSqlFormatter.format("foo !< bar")).toBe("foo !< bar\n");
        expect(standardSqlFormatter.format("foo !> bar")).toBe("foo !> bar\n");
    });

    it("formats logical operators", function() {
        expect(standardSqlFormatter.format("foo ALL bar")).toBe("foo ALL bar\n");
        expect(standardSqlFormatter.format("foo = ANY (1, 2, 3)")).toBe("foo = ANY (1, 2, 3)\n");
        expect(standardSqlFormatter.format("EXISTS bar")).toBe("EXISTS bar\n");
        expect(standardSqlFormatter.format("foo IN (1, 2, 3)")).toBe("foo IN (1, 2, 3)\n");
        expect(standardSqlFormatter.format("foo LIKE 'hello%'")).toBe("foo LIKE 'hello%'\n");
        expect(standardSqlFormatter.format("foo IS NULL")).toBe("foo IS NULL\n");
        expect(standardSqlFormatter.format("UNIQUE foo")).toBe("UNIQUE foo\n");
    });

    it("formats AND/OR operators", function() {
        expect(standardSqlFormatter.format("foo BETWEEN bar AND baz")).toBe("foo BETWEEN bar\nAND baz\n");
        expect(standardSqlFormatter.format("foo AND bar")).toBe("foo\nAND bar\n");
        expect(standardSqlFormatter.format("foo OR bar")).toBe("foo\nOR bar\n");
    });

    it("recognizes strings", function() {
        expect(standardSqlFormatter.format("\"foo JOIN bar\"")).toBe("\"foo JOIN bar\"\n");
        expect(standardSqlFormatter.format("'foo JOIN bar'")).toBe("'foo JOIN bar'\n");
        expect(standardSqlFormatter.format("`foo JOIN bar`")).toBe("`foo JOIN bar`\n");
        expect(standardSqlFormatter.format("[foo JOIN bar]")).toBe("[foo JOIN bar]\n");
    });

    it("recognizes escaped strings", function() {
        expect(standardSqlFormatter.format("\"foo \\\" JOIN bar\"")).toBe("\"foo \\\" JOIN bar\"\n");
        expect(standardSqlFormatter.format("'foo \\' JOIN bar'")).toBe("'foo \\' JOIN bar'\n");
        expect(standardSqlFormatter.format("`foo `` JOIN bar`")).toBe("`foo `` JOIN bar`\n");
        expect(standardSqlFormatter.format("[foo ]] JOIN bar]")).toBe("[foo ]] JOIN bar]\n");
    });
});
<|endoftext|>


<commit_before>'use strict';

module.exports = function(grunt) {
    var path = require('path'),
        lang = require('mercenary').lang,
        extend = lang.extend;

    grunt.task.registerMultiTask(
        'formidable',
        'Generate a static site with formidable',
        function() {
            var done = this.async(),
                options = this.options({
                    // The root of the project, from which other paths will be resolved.
                    // Defaults to './src' with respect to the grunt base directory
                    // (usually the same as the grunt file).
                    root: path.join('src'),
                    // The build directory into which the site's files will be generated.
                    // Defaults to '../build' with respect to the root.
                    build: null,
                    // The path to the top-level urls module with respect to the root and
                    // without the '.js' extension. Defaults to 'urls'.
                    urls: null,
                    // Template directory globbing patterns for findiing directories in
                    // addition to the standard '**/templates' pattern. Defaults to [].
                    templates: null,
                    // The template rendering engine to use. Defaults to 'swig'.
                    templating: null,
                    // Global template context, useful for passing environment variables
                    // from grunt into a formidable project's templates.
                    context: null,
                    // Plugins for swig.
                    swig: {
                        filters: {},
                        tags: {},
                        extensions: {}
                    },
                    // Allow overwrite of existing rendered files. When false, an attempted
                    // overwrite will raise a fatal exception. Defaults to true.
                    overwrite: null
                });

            // Instantiate the formidable instance, invoke it and wait for the results.
            (require('formidable/settings')
            // The simulated settings.js path.
            .configure(path.join(options.root, 'settings.js'))
            // The settings.
            .load(
                extend({}, options, {
                    log: {
                        info: function(message) {
                            grunt.log.ok(message || '');
                        },
                        warn: function(message) {
                            grunt.log.error(message || '');
                        },
                        fail: function(message, code) {
                            grunt.fail.fatal(message, code);
                        }
                    },
                    verbose: grunt.option('verbose') || false,
                    debug: grunt.option('debug') || false
                }))()
            .then(function() {
                done(true);
            }));
        });
};
<commit_msg>Added support to pass through the meta option.<commit_after>'use strict';

module.exports = function(grunt) {
    var path = require('path'),
        lang = require('mercenary').lang,
        extend = lang.extend;

    grunt.task.registerMultiTask(
        'formidable',
        'Generate a static site with formidable',
        function() {
            var done = this.async(),
                options = this.options({
                    // The root of the project, from which other paths will be resolved.
                    // Defaults to './src' with respect to the grunt base directory
                    // (usually the same as the grunt file).
                    root: path.join('src'),
                    // The build directory into which the site's files will be generated.
                    // Defaults to '../build' with respect to the root.
                    build: null,
                    // The path to the top-level urls module with respect to the root and
                    // without the '.js' extension. Defaults to 'urls'.
                    urls: null,
                    // Template directory globbing patterns for findiing directories in
                    // addition to the standard '**/templates' pattern. Defaults to [].
                    templates: null,
                    // The template rendering engine to use. Defaults to 'swig'.
                    templating: null,
                    // Global template context, useful for passing environment variables
                    // from grunt into a formidable project's templates.
                    context: null,
                    // Context key name for the rendering metadata that will be passed into
                    // template contexts. Defaults to 'meta'.
                    meta: null,
                    // Plugins for swig.
                    swig: {
                        filters: {},
                        tags: {},
                        extensions: {}
                    },
                    // Allow overwrite of existing rendered files. When false, an attempted
                    // overwrite will raise a fatal exception. Defaults to true.
                    overwrite: null
                });

            // Instantiate the formidable instance, invoke it and wait for the results.
            (require('formidable/settings')
            // The simulated settings.js path.
            .configure(path.join(options.root, 'settings.js'))
            // The settings.
            .load(
                extend({}, options, {
                    log: {
                        info: function(message) {
                            grunt.log.ok(message || '');
                        },
                        warn: function(message) {
                            grunt.log.error(message || '');
                        },
                        fail: function(message, code) {
                            grunt.fail.fatal(message, code);
                        }
                    },
                    verbose: grunt.option('verbose') || false,
                    debug: grunt.option('debug') || false
                }))()
            .then(function() {
                done(true);
            }));
        });
};
<|endoftext|>


<commit_before>var MochaWrapper = require('./lib/MochaWrapper');
var fs = require('fs');
var path = require('path');
var hooker = require('hooker');
var mkdirpSync = require('mkdirp').sync;

module.exports = function(grunt) {

  // Helper to capture task output (adapted from tests for grunt-contrib-jshint)
  var capture = function(captureFile, quiet, run, done) {
    var fd;
    if (captureFile) {
      mkdirpSync(path.dirname(captureFile));
      fd = fs.openSync(captureFile, 'w');
    }
    // Hook process.stdout.write
    hooker.hook(process.stdout, 'write', {
      // This gets executed before the original process.stdout.write
      pre: function(result) {
        // Write result to file if it was opened
        if (fd) {
          fs.writeSync(fd, result);
        }
        // Prevent the original process.stdout.write from executing if quiet was specified
        if (quiet) {
          return hooker.preempt();
        }
      }
    });
    // Execute the code whose output is to be captured
    run(function(error, failureCount) {
      // close the file if it was opened
      if (fd) {
        fs.closeSync(fd);
      }
      // Restore process.stdout.write to its original value
      hooker.unhook(process.stdout, 'write');
      // Actually test the actually-logged stdout string to the expected value
      done(error, failureCount);
    });
  };

  grunt.registerMultiTask('mochaTest', 'Run node unit tests with Mocha', function() {
    var done = this.async();
    var options = this.options();
    var files = this.files;

    // mocha CLI parameters
    var params = ['grep', 'ui', 'reporter', 'timeout', 'invert', 'ignoreLeaks', 'growl', 'globals', 'require', 'colors', 'slow'];

    // for every supplied CLI parameter overwrite task option
    params.forEach(function(param) {
      options[param] = grunt.option(param) || options[param];
    });

    // check if there are files to test
    if (this.filesSrc.length === 0) {
      grunt.log.write('No files to check...');
      grunt.log.ok();
      done(true);
      return;
    }

    // Another hack copied from
    // https://github.com/gregrperkins/grunt-mocha-hack
    // This time we are preventing grunt handling asynchronous
    // exceptions that are thrown when handling asynchronous exceptions
    // (I think)
    var uncaughtExceptionHandlers = process.listeners('uncaughtException');
    process.removeAllListeners('uncaughtException');
    var unmanageExceptions = function() {
      // Fix for leaking exception handlers suggested by https://github.com/davedoesdev
      var names = process.listeners('uncaughtException').map(function (f) {
        return f.name;
      });
      uncaughtExceptionHandlers.forEach(function (f) {
        if (names.indexOf(f.name) < 0) {
          process.on('uncaughtException', f);
        }
      });
    };
    var restore = function() {
      unmanageExceptions();
    };

    capture(options.captureFile, options.quiet, function(complete) {
      var mochaWrapper = new MochaWrapper({
        files: files,
        options: options
      });
      mochaWrapper.run(function(error, failureCount) {
        if (error) {
          grunt.log.error('Mocha exploded!');
          grunt.log.error(error.stack);
          complete(error);
        } else {
          complete(null, failureCount);
        }
      });
    }, function(error, failureCount) {
      // restore the uncaught exception handlers
      restore();
      if (error) {
        done(false);
      } else if (options.noFail) {
        done(true);
      } else {
        done(failureCount === 0);
      }
    });
  });
};
<commit_msg>ignore workaround in coverage report<commit_after>var MochaWrapper = require('./lib/MochaWrapper');
var fs = require('fs');
var path = require('path');
var hooker = require('hooker');
var mkdirpSync = require('mkdirp').sync;

module.exports = function(grunt) {

  // Helper to capture task output (adapted from tests for grunt-contrib-jshint)
  var capture = function(captureFile, quiet, run, done) {
    var fd;
    if (captureFile) {
      mkdirpSync(path.dirname(captureFile));
      fd = fs.openSync(captureFile, 'w');
    }
    // Hook process.stdout.write
    hooker.hook(process.stdout, 'write', {
      // This gets executed before the original process.stdout.write
      pre: function(result) {
        // Write result to file if it was opened
        if (fd) {
          fs.writeSync(fd, result);
        }
        // Prevent the original process.stdout.write from executing if quiet was specified
        if (quiet) {
          return hooker.preempt();
        }
      }
    });
    // Execute the code whose output is to be captured
    run(function(error, failureCount) {
      // close the file if it was opened
      if (fd) {
        fs.closeSync(fd);
      }
      // Restore process.stdout.write to its original value
      hooker.unhook(process.stdout, 'write');
      // Actually test the actually-logged stdout string to the expected value
      done(error, failureCount);
    });
  };

  grunt.registerMultiTask('mochaTest', 'Run node unit tests with Mocha', function() {
    var done = this.async();
    var options = this.options();
    var files = this.files;

    // mocha CLI parameters
    var params = ['grep', 'ui', 'reporter', 'timeout', 'invert', 'ignoreLeaks', 'growl', 'globals', 'require', 'colors', 'slow'];

    // for every supplied CLI parameter overwrite task option
    params.forEach(function(param) {
      options[param] = grunt.option(param) || options[param];
    });

    // check if there are files to test
    if (this.filesSrc.length === 0) {
      grunt.log.write('No files to check...');
      grunt.log.ok();
      done(true);
      return;
    }

    // Another hack copied from
    // https://github.com/gregrperkins/grunt-mocha-hack
    // This time we are preventing grunt handling asynchronous
    // exceptions that are thrown when handling asynchronous exceptions
    // (I think)
    var uncaughtExceptionHandlers = process.listeners('uncaughtException');
    process.removeAllListeners('uncaughtException');
    /* istanbul ignore next */
    var unmanageExceptions = function() {
      // Fix for leaking exception handlers suggested by https://github.com/davedoesdev
      var names = process.listeners('uncaughtException').map(function (f) {
        return f.name;
      });
      uncaughtExceptionHandlers.forEach(function (f) {
        if (names.indexOf(f.name) < 0) {
          process.on('uncaughtException', f);
        }
      });
    };
    var restore = function() {
      unmanageExceptions();
    };

    capture(options.captureFile, options.quiet, function(complete) {
      var mochaWrapper = new MochaWrapper({
        files: files,
        options: options
      });
      mochaWrapper.run(function(error, failureCount) {
        if (error) {
          grunt.log.error('Mocha exploded!');
          grunt.log.error(error.stack);
          complete(error);
        } else {
          complete(null, failureCount);
        }
      });
    }, function(error, failureCount) {
      // restore the uncaught exception handlers
      restore();
      if (error) {
        done(false);
      } else if (options.noFail) {
        done(true);
      } else {
        done(failureCount === 0);
      }
    });
  });
};
<|endoftext|>


<commit_before>define(['cytoscape/dist/cytoscape'], function(cytoscape){
	return function(options){
		var nextId = 1;
		var allElements = document.documentElement.getElementsByTagName('*');
		var container = document.body.appendChild(document.createElement('div'));
		container.style.position = 'absolute';
		container.style.left = '0px';
		container.style.right = '0px';
		container.style.top = '0px';
		container.style.bottom = '0px';
		container.style.zIndex = '1000000';
		var boundX = container.offsetWidth;
		var boundY = container.offsetHeight;
		var configuration = {
			container: container,
			style: [ // the stylesheet for the graph
				{
					selector: 'node',
					style: {
						'label': 'data(label)',
						'text-valign': 'center'
					}
				},
				{
					selector: 'node[type="element"]',
					style: {
						opacity: 0.1,
						'background-color': '#00a',
						height: 'data(height)',
						width: 'data(width)',
						shape: 'rectangle',
						'z-index': 'data(zIndex)'
					}
				},
				{
					selector: 'node[type="renderer"]',
					style: {
						'background-color': '#444',
						shape: 'ellipse',
						width: '60px',
						height: '40px',
						'z-index': 10000
					}
				},
				{
					selector: 'node[type="variable"]',
					style: {
						'background-color': '#666',
						shape: 'rectangle',
						width: '80px',
						height: '40px',
						'z-index': 10000
					}
				},

				{
					selector: 'edge',
					style: {
						'width': 3,
						'label': 'data(label)',
						'line-color': '#ccc',
						'target-arrow-color': '#ccc',
						'target-arrow-shape': 'triangle'
					}
				}
			],
			zoom: 1,
  		pan: { x: 0, y: 0 },
  		zoomingEnabled: false,
		  userZoomingEnabled: false,
		  panningEnabled: false,
		  userPanningEnabled: false,
  		layout: {
				name: 'preset',
				boundingBox: {
					x1: 0,
					y1: 0,
					x2: boundX,
					y2: boundY
				},
				componentSpacing: 150,
				avoidOverlap: false
			}
		};
		var nodes = [];
		var edges = [];
		configuration.elements = {
			nodes: nodes,
			edges: edges
		};

		var processed = {};
		function valueToString(value){
			return fitString('' + value);
		}
		function fitString(string){
			if(string.length > 20){
				return string.slice(0, 20) + '...';
			}
			return string;
		}
		function placeNode(from){
			var best, bestScore = 1;
			var fromX = from.x;
			var fromY = from.y;
			for(var i = 0; i < 200000 / bestScore; i++){
				var possibleX = fromX + 200 * Math.cos(i);
				var possibleY = fromY + 200 * Math.sin(i * 1.43213);
				if(possibleX > 0 && possibleX < boundX && possibleY > 0 && possibleY < boundY){
					var closest = 1000000000;
					for(var j = 0, l = nodes.length; j < l; j++){
						var nodePosition = nodes[j].position;
						var distance = (nodePosition.x - possibleX) * (nodePosition.x - possibleX) + (nodePosition.y - possibleY) * (nodePosition.y - possibleY);
						if (distance < closest){
							closest = distance;
						}
					}
					var score = closest - i * i * 10 + (possibleY - fromY) * (from.downstream ? 30 : -30) + 10000;
					if(score > bestScore){
						bestScore = score;
						best = {
							x: possibleX,
							y: possibleY
						};
					}
				}
			}
			return best;
		}
		function addConnection(source, target, label){
			cy.add({
				group: 'edges',
				data: {
					label: label,
					source: source,
					target: target
				}
			});
		}
		function processVariable(variable, from){
			var variableId;
			if(variable.getId){
				variableId = 'variable-' + variable.getId();
			}else{
				variableId = 'subscriber-' + (variable.id || (variable.id = nextId++));
			}
			if(processed[variableId]){
				return variableId;
			}
			processed[variableId] = true;
			var position = placeNode(from);
			var variableNode = {
				group: 'nodes',
				data: {
					type: 'variable',
					shape: variable._properties ?
						'octagon' : variable.functionVariable ?
						'diamond' : 'rectangle',
					label: valueToString(variable.valueOf()),
					value: variable,
					id: variableId
				},
				position: position
			};
			cy.add(variableNode);
			nodes.push(variableNode);
			for(var i in variable._properties){
				addConnection(variableId, processVariable(variable._properties[i], position), i);
			}
			position.downstream = true;
			var args = variable.args;
			if(args){
				for(var i = 0; i < args.length; i++){
					addConnection(processVariable(args[i], position), variableId, '' + i);
				}
			}
			if(variable.functionVariable){
				addConnection(processVariable(variable.functionVariable, position), variableId, 'map');
			}
			if(variable.notifyingValue){
				addConnection(processVariable(variable.notifyingValue, position), variableId, 'value');
			}
			if(variable.parent){
				processVariable(variable.parent, position);
			}
			return variableId;
		}

		for(var i = 0, l = allElements.length; i < l; i++){
			var element = allElements[i];
			if(element.offsetParent && element.alkaliRenderers){
				var height = element.offsetHeight;
				var width = element.offsetWidth;
				nodes.push({
					data:{
						type: 'element',
						height: height,
						width: width,
						opacity: 0.1,
						zIndex: i,
						element: element,
						label: element.tagName + element.className.replace(/\S+/g, function(part){
							return '.' + part;
						}),
						id: 'element-' + i
					},/*
					position: {
						x: 40,
						y: 40
					},
					locked: true
	*/

					position: window.$ ? {
						x: $(element).offset().left + width / 2,
						y: $(element).offset().top + height / 2
					}: {
						x: 0,
						y: 0
					},
					locked: true
				});

	//console.log($(element).position().left, $(element).position().top);
			}
		}
		cy = cytoscape(configuration);
		cy.on('click', function(event){
			if(!event.cyTarget.data){
				return;
			}
			var element = event.cyTarget.data('element');
			if(!element){
				var value = event.cyTarget.data('value');
				if(value){
					value = value.valueOf();
					try{
						if(typeof value != 'function'){
							value = JSON.stringify(value);
						}
					}catch(e){}
					alert(value);
				}
				return;
			}

			var id = event.cyTarget.data('id');
			var elementPosition = event.cyTarget.position();
			var renderers = element.alkaliRenderers;
			for(var j = 0; j < renderers.length; j++){
				var renderer = renderers[j];
				var rendererNode = {
					group: 'nodes',
					data: {
						type: 'renderer',
						label: fitString('Renderer'),
						value: renderer.name || renderer.renderUpdate,
						id: 'updater-' + renderer.getId()
					},
					position: placeNode(elementPosition)
				}
				cy.add(rendererNode);
				nodes.push(rendererNode);
				addConnection('updater-' + renderer.getId(), id, '');
				addConnection(processVariable(renderer.variable, rendererNode.position), 'updater-' + renderer.getId(), '');
			}
//			cy.layout(configuration.layout);
		});
	};
});<commit_msg>Pure HTML display<commit_after>define(['alkali/Updater'], function(Updater, cytoscape){
	function getAbsoluteX(element){
		var rect = element.getBoundingClientRect()
		return rect.left + window.pageXOffset - document.documentElement.clientLeft;
	}
	function getAbsoluteY(element){
		var rect = element.getBoundingClientRect()
		return rect.top + window.pageYOffset - document.documentElement.clientTop;
	}
	return function(options){
		var nextId = 1;
		var allElements = document.documentElement.getElementsByTagName('*');
		var container = document.body.appendChild(document.createElement('div'));
		container.style.position = 'absolute';
		container.style.left = '0px';
		container.style.right = '0px';
		container.style.top = '0px';
		container.style.bottom = '0px';
		container.style.fontFamily = 'sans-serif, Arial';
		container.style.fontSize = '10px';
		container.style.zIndex = '1000000';
		var boundX = container.offsetWidth;
		var boundY = container.offsetHeight;
		var configuration = {
			container: container,
			style: [ // the stylesheet for the graph
				{
					selector: 'node',
					style: {
						'label': 'data(label)',
						'text-valign': 'center'
					}
				},
				{
					selector: 'node[type="element"]',
					style: {
						opacity: 0.1,
						'background-color': '#00a',
						height: 'data(height)',
						width: 'data(width)',
						shape: 'rectangle',
						'z-index': 'data(zIndex)'
					}
				},
				{
					selector: 'node[type="renderer"]',
					style: {
						'background-color': '#444',
						shape: 'ellipse',
						width: '60px',
						height: '40px',
						'z-index': 10000
					}
				},
				{
					selector: 'node[type="variable"]',
					style: {
						'background-color': '#666',
						shape: 'rectangle',
						width: '80px',
						height: '40px',
						'z-index': 10000
					}
				},

				{
					selector: 'edge',
					style: {
						'width': 3,
						'label': 'data(label)',
						'line-color': '#ccc',
						'target-arrow-color': '#ccc',
						'target-arrow-shape': 'triangle'
					}
				}
			],
			zoom: 1,
  		pan: { x: 0, y: 0 },
  		zoomingEnabled: false,
		  userZoomingEnabled: false,
		  panningEnabled: false,
		  userPanningEnabled: false,
  		layout: {
				name: 'preset',
				boundingBox: {
					x1: 0,
					y1: 0,
					x2: boundX,
					y2: boundY
				},
				componentSpacing: 150,
				avoidOverlap: false
			}
		};
		var nodes = [];
		var edges = [];
		configuration.elements = {
			nodes: nodes,
			edges: edges
		};

		var processed = {};
		function valueToString(value){
			return fitString('' + value);
		}
		function fitString(string){
			if(string.length > 20){
				return string.slice(0, 20) + '...';
			}
			return string;
		}
		function placeNode(from){
			var best, bestScore = 1;
			var fromX = from.x;
			var fromY = from.y;
			for(var i = 0; i < 200000 / bestScore; i++){
				var possibleX = fromX + 200 * Math.cos(i);
				var possibleY = fromY + 200 * Math.sin(i * 1.43213);
				if(possibleX > 0 && possibleX < boundX - 100 && possibleY > 0 && possibleY < boundY - 50){
					var closest = 1000000000;
					for(var j = 0, l = nodes.length; j < l; j++){
						var nodePosition = nodes[j].position;
						var distance = (nodePosition.x - possibleX) * (nodePosition.x - possibleX) + (nodePosition.y - possibleY) * (nodePosition.y - possibleY);
						if (distance < closest){
							closest = distance;
						}
					}
					var score = closest - i * i * 10 + (possibleY - fromY) * (from.downstream ? 30 : -30) + 10000;
					if(score > bestScore){
						bestScore = score;
						best = {
							x: possibleX,
							y: possibleY,
							z: from.z || 100
						};
					}
				}
			}
			return best;
		}
		function editDialog(element){
			var box = container.appendChild(document.createElement('div'));
			var title = box.appendChild(document.createElement('div'));
			title.textContent = 'Edit value';
			var closeButton = box.appendChild(document.createElement('div'));
			closeButton.textContent = 'X';
			closeButton.style.float = 'right';
			closeButton.style.cursor = 'pointer';
			closeButton.addEventListener('click', function(){
				dismiss()
			});
			box.style.position = 'absolute';
			box.style.boxShadow = '2px 2px 3px #888';
			box.style.backgroundColor = '#eee';
			box.style.border = '1px solid #888';
			box.style.borderRadius = '3px';
			box.style.left = '400px';
			box.style.top = '300px';
			box.style.padding = '10px';
			box.style.zIndex = '10000';
			editArea = box.appendChild(document.createElement('textarea'));
			editArea.style.width = '500px';
			editArea.style.height = '250px';
			var variable = element.variable;
			var value = variable.valueOf();
			var asSource = typeof value === 'function' ? value.toString() : JSON.stringify(value, null, '\t');
			editArea.value = asSource;
			var ok = box.appendChild(document.createElement('button'));
			ok.style.display = 'block';
			ok.style.margin = '10px';
			ok.innerHTML = 'Save';
			ok.addEventListener('click', function(){
				try {
					variable.put(eval('(' + editArea.value + ')'));
					dismiss();
				}catch(error){
					alert(error);
				}
			});
			function dismiss(event){
				if(!event || !box.contains(event.target) && container.contains(box)){
					container.removeChild(box);
				}
				container.removeEventListener(dismiss);
			}
			container.addEventListener('click', dismiss);
		}
		function createVariableBox(position, text, parent){
			var box = (parent || container).appendChild(document.createElement('div'));
			if(!parent){
				box.style.position = 'absolute';
				box.style.left = position.x + 'px';
				box.style.top = position.y + 'px';
			}else{
				box.style.margin = '5px';
			}
			box.style.boxShadow = '2px 2px 3px #888';
			box.style.backgroundColor = '#eee';
			box.style.border = '1px solid #888';
			box.style.borderRadius = '3px';
			box.style.padding = '4px';
			box.style.zIndex = position.z || 100;
			box.textContent = text;
			if(!position.x || parent){
				position.x = getAbsoluteX(box);
				position.y = getAbsoluteY(box);
			}
			position.height = box.offsetHeight;
			position.width = box.offsetWidth;
			return box;
		}
		function addConnection(source, target, label){
			var arrow = container.appendChild(document.createElement('div'));
			var arrowTriangle = arrow.appendChild(document.createElement('div'));
			arrowTriangle.style.position = 'absolute';
			arrowTriangle.style.left = '80%';
			arrowTriangle.style.top = '-7px';
			arrowTriangle.style.width = '0';
			arrowTriangle.style.height = '0';
			arrowTriangle.style.borderTop = '10px solid transparent';
			arrowTriangle.style.borderBottom = '10px solid transparent';
			arrowTriangle.style.borderLeft = '10px solid #888';
			arrow.style.position = 'absolute';
			var sourceX = source.x + (source.width || 100) / 2;
			var sourceY = source.y + (source.height || 30) / 2;
			var targetX = target.x + (target.width || 100) / 2;
			var targetY = target.y + (target.height || 30) / 2;
			arrow.style.left = sourceX + 'px';
			arrow.style.top = sourceY + 'px';
			arrow.style.backgroundColor = '#888';
			arrow.style.height = '4px';
			arrow.style.width = Math.sqrt(Math.pow(targetX - sourceX, 2) + Math.pow(targetY - sourceY, 2)) + 'px';
			arrow.style.zIndex = Math.min(source.z, target.z) - 1;
			arrow.style.transformOrigin = '0 0';
			var angle = Math.atan((targetY - sourceY) / (targetX - sourceX));
			if(targetX < sourceX){
				angle += Math.PI;
			}
			arrow.style.transform = 'rotate(' + angle + 'rad)';
			return arrow;
			/*cy.add({
				group: 'edges',
				data: {
					label: label,
					source: source,
					target: target
				}
			});*/
		}
		function processVariable(variable, position, parent, key){
			var variableId;
			if(variable.parent){
				processVariable(variable.parent, placeNode({x: position.x, y: position.y, z: position.z - 2}));
			}
			if(variable.getId){
				variableId = 'variable-' + variable.getId();
			}else{
				variableId = 'subscriber-' + (variable.id || (variable.id = nextId++));
			}
			if(processed[variableId]){
				return processed[variableId];
			}
			processed[variableId] = position;
			var variableNode = {
				group: 'nodes',
				data: {
					type: 'variable',
					parent: parent,
					shape: variable._properties ?
						'octagon' : variable.functionVariable ?
						'diamond' : 'rectangle',
					label: valueToString(variable.valueOf()),
					value: variable,
					id: variableId
				},
				position: position
			};
			//cy.add(variableNode);
			var variableBox = position.element = createVariableBox(position, '', parent && parent.element);
			var labelNode = variableBox.appendChild(document.createElement('span'));
			labelNode.textContent = 'undefined';
			if(key){
				labelNode.textContent = key + ': undefined';
			}
			new Updater.ElementUpdater({
				element: labelNode,
				variable: variable,
				renderUpdate: function(newValue){
					var label = '' + newValue;
					if(key){
						label = key + ': ' + label;
					}
					labelNode.textContent = fitString(label);
				}
			});

			variableBox.variable = variable;
			nodes.push(variableNode);
			var i = 0;
			for(var childKey in variable._properties){
				i++;
				processVariable(variable._properties[childKey], {z: position.z + 2}, position, childKey);
			}
			position.downstream = true;
			var args = variable.args;
			if(args){
				for(var i = 0; i < args.length; i++){
					addConnection(processVariable(args[i], placeNode(position)), position, '' + i);
				}
			}
			if(variable.functionVariable){
				addConnection(processVariable(variable.functionVariable, {x: 10, y: 40}, position), position, 'map');
			}
			if(variable.notifyingValue){
				addConnection(processVariable(variable.notifyingValue, placeNode(position)), position, 'value');
			}
			return processed[variableId] = position;
		}

		for(var i = 0, l = allElements.length; i < l; i++){
			var element = allElements[i];
			if(element.offsetParent && element.alkaliRenderers){
				var height = element.offsetHeight;
				var width = element.offsetWidth;
				var elementOverlay = container.appendChild(document.createElement('div'));
				elementOverlay.style.position = 'absolute';
				elementOverlay.style.left = getAbsoluteX(element) + 'px';
				elementOverlay.style.top = getAbsoluteY(element) + 'px';
				elementOverlay.style.width = width + 'px';
				elementOverlay.style.height = height + 'px';
				elementOverlay.style.backgroundColor = '#00f';
				elementOverlay.style.opacity = 0.2;
				elementOverlay.style.zIndex = 1;
				elementOverlay.className = 'element-overlay';
				elementOverlay.nodeId = 'element-' + i;
				elementOverlay.targetElement = element;
				nodes.push({
					data:{
						type: 'element',
						height: height,
						width: width,
						opacity: 0.1,
						zIndex: i,
						element: element,
						label: element.tagName + element.className.replace(/\S+/g, function(part){
							return '.' + part;
						}),
						id: 'element-' + i
					},/*
					position: {
						x: 40,
						y: 40
					},
					locked: true
	*/

					position: window.$ ? {
						x: getAbsoluteX(element) + width / 2,
						y: getAbsoluteY(element) + height / 2
					}: {
						x: 0,
						y: 0
					},
					locked: true
				});

	//console.log($(element).position().left, $(element).position().top);
			}
		}
		//cy = cytoscape(configuration);
		container.addEventListener('click', function(event){
			var litmusElement = event.target;
			while(litmusElement){
				if(litmusElement == container){
					return;
				}
				if(litmusElement.variable){
					editDialog(litmusElement);
					return;
				}
				if(litmusElement.targetElement){
					var element = litmusElement.targetElement;
					if(element){
						var id = event.target.nodeId;
						var elementPosition = {
							x: litmusElement.offsetLeft,
							y: litmusElement.offsetTop,
							z: 100
						};
						var renderers = element.alkaliRenderers;
						for(var j = 0; j < renderers.length; j++){
							var renderer = renderers[j];
							var rendererNode = {
								group: 'nodes',
								data: {
									type: 'renderer',
									label: fitString('Renderer'),
									value: renderer.name || renderer.renderUpdate,
									id: 'updater-' + renderer.getId()
								},
								position: placeNode(elementPosition)
							};
							var rendererPosition = placeNode(elementPosition);
							var rendererBox = createVariableBox(rendererPosition, fitString('Renderer ' + (renderer.name || '')));

							//cy.add(rendererNode);
							nodes.push(rendererNode);
							addConnection(rendererPosition, elementPosition, '');
							addConnection(processVariable(renderer.variable, placeNode(rendererNode.position)), rendererPosition, '');
						}

					}
					return;
				}
				litmusElement = litmusElement.parentNode;
			}
//			cy.layout(configuration.layout);
		});
	};
});<|endoftext|>