<commit_before>var fs = require('promised-io/fs');
var promise = require('promised-io/promise');
var path = require('path');
var glob = require('glob');
var util = require('util');
var _ = require('lodash');

module.exports = function (grunt) {

  grunt.registerMultiTask('sync', 'Synchronize content of two directories.', function () {
    var done = this.async();
    var logger = grunt[this.data.verbose ? 'log' : 'verbose'];
    var updateOnly = !this.data.updateAndDelete;
    var justPretend = !!this.data.pretend;
    var failOnError = !!this.data.failOnError;
    var ignoredPatterns = this.data.ignoreInDest;
    var comparatorFactory = getComparatorFactory(this.data.compareUsing || 'mtime', logger);
    var expandedPaths = {};

    var getExpandedPaths = function (origDest) {
      if (!expandedPaths[origDest]) {
        // Always include destination as processed.
        expandedPaths[origDest] = [origDest.replace(new RegExp('\\' + path.sep + '$'), '')];
        return expandedPaths[origDest];
      }
      return expandedPaths[origDest];
    };

    promise.all(this.files.map(function (fileDef) {
      var isCompactForm = this.data.src && this.data.dest;
      var cwd = fileDef.cwd ? fileDef.cwd : '.';
      var isExpanded = fileDef.orig.expand;
      var origDest = path.join(fileDef.orig.dest, '');

      var processedDestinations = getExpandedPaths(origDest);

      return promise.all(fileDef.src.map(function (src) {
        var dest;
        // when using expanded mapping dest is the destination file
        // not the destination folder
        if (isExpanded || isCompactForm) {
          dest = convertPathsToSystemSpecific(fileDef.dest);
        } else {
          dest = path.join(fileDef.dest, src);
        }
        if (!updateOnly) {
          processedDestinations.push(dest);
          // Make sure to add directory of file as well (handle cases when source has pattern for files only)
          addDirectoriesPaths(processedDestinations, dest);
        }
        // Process pair
        return processPair(justPretend, failOnError, logger, comparatorFactory, path.join(cwd, src), dest);
      }));

    }, this)).then(function () {
      if (updateOnly) {
        return;
      }

      var getDestPaths = function (dest, pattern) {
        var defer = new promise.Deferred();
        glob(pattern, {
          cwd: dest,
          dot: true
        }, function (err, result) {
          if (err) {
            defer.reject(err);
            return;
          }
          defer.resolve(result.map(function (filePath) {
            return path.join(dest, filePath);
          }));
        });
        return defer.promise;
      };

      var getIgnoredPaths = function (dest, ignore) {
        var defer = new promise.Deferred();
        if (!ignore) {
          defer.resolve([]);
          return defer.promise;
        }

        if (!util.isArray(ignore)) {
          ignore = [ignore];
        }

        promise.all(ignore.map(function (pattern) {
          return getDestPaths(dest, pattern);
        })).then(function (results) {
          var flat = results.reduce(function (memo, a) {
            return memo.concat(a);
          }, []);
          defer.resolve(flat);
        }, function (err) {
          defer.reject(err);
        });

        return defer.promise;
      };

      // Second pass
      return promise.all(Object.keys(expandedPaths).map(function (dest) {
        var processedDestinations = convertPathsToSystemSpecific(expandedPaths[dest]);

        // We have to do second pass to remove objects from dest
        var destPaths = getDestPaths(dest, '**');

        // Check if we have any ignore patterns
        var ignoredPaths = getIgnoredPaths(dest, ignoredPatterns);

        return promise.all([destPaths, ignoredPaths, processedDestinations]);
      })).then(function (result) {
        var files = result.map(function (destAndIgnored) {
          var paths = convertPathsToSystemSpecific(destAndIgnored[0]);
          var ignoredPaths = convertPathsToSystemSpecific(destAndIgnored[1]);

          return [paths, ignoredPaths, destAndIgnored[2]];
        }).reduce(function (memo, destAndIgnored) {
          return memo.map(function (val, key) {
            return val.concat(destAndIgnored[key]);
          });
        }, [[], [], []]);

        // TODO Find some faster way to ensure uniqueness here
        var paths = _.uniq(files[0]);
        var ignoredPaths = _.uniq(files[1]);
        var processedDestinations = _.uniq(files[2]);

        // Calculate diff
        var toRemove = fastArrayDiff(paths, processedDestinations);
        // And filter also ignored paths
        toRemove = fastArrayDiff(toRemove, ignoredPaths);

        return removePaths(justPretend, logger, toRemove);
      });
    }).then(done);
  });

  function processPair (justPretend, failOnError, logger, comparatorFactory, src, dest) {

    // stat destination file
    return promise.all([fs.stat(src), fs.stat(dest)]).then(function (result) {
      var srcStat = result[0];
      var destStat = result[1];

      var isSrcDirectory = srcStat.isDirectory();
      var typeDiffers = isSrcDirectory !== destStat.isDirectory();
      var haventChangedFn = comparatorFactory(src, srcStat, dest, destStat);

      overwriteOrUpdate(isSrcDirectory, typeDiffers, haventChangedFn);
    }, function () {
      // we got an error which means that destination file does not exist
      // so make a copy
      if (grunt.file.isDir(src)) {
        logger.writeln('Creating ' + dest.cyan);

        doOrPretend(function () {
          tryMkdir(dest);
        });
      } else {
        logger.writeln('Copying ' + src.cyan + ' -> ' + dest.cyan);

        doOrPretend(function () {
          tryCopy(src, dest);
        });
      }
    });

    function doOrPretend (operation) {
      if (justPretend) {
        return;
      }
      operation();
    }

    function warnOrFail (msg) {
      if (failOnError) {
        grunt.fail.warn(msg);
        return;
      }
      grunt.log.warn(msg);
    }

    function tryCopy (src, dest) {
      try {
        grunt.file.copy(src, dest);
      } catch (e) {
        warnOrFail('Cannot copy to ' + dest.red);
      }
    }

    function tryMkdir (dest) {
      try {
        grunt.file.mkdir(dest);
      } catch (e) {
        warnOrFail('Cannot create directory ' + dest.red);
      }
    }

    function overwriteDest (src, dest) {
      try {
        grunt.file['delete'](dest);
        grunt.file.copy(src, dest);
      } catch (e) {
        warnOrFail('Cannot overwrite ' + dest.red);
      }
    }

    function overwriteOrUpdate (isSrcDirectory, typeDiffers, haventChangedFn) {

      // If types differ we have to overwrite destination.
      if (typeDiffers) {
        logger.writeln('Overwriting ' + dest.cyan + ' because type differs.');

        doOrPretend(function () {
          overwriteDest(src, dest);
        });
        return;
      }

      // we can now compare the files
      if (isSrcDirectory || haventChangedFn()) {
        return;
      }

      logger.writeln('Updating file ' + dest.cyan);
      doOrPretend(function () {
        // and just update destination
        tryCopy(src, dest);
      });
    }
  }

  function removePaths (justPretend, logger, paths) {

    return promise.all(paths.map(function (file) {
      return fs.stat(file).then(function (stat) {
        return {
          file: file,
          isDirectory: stat.isDirectory()
        };
      });
    })).then(function (stats) {
      var paths = splitFilesAndDirs(stats);

      // First we need to process files
      return promise.all(paths.files.map(function (filePath) {
        logger.writeln('Unlinking ' + filePath.cyan + ' because it was removed from src.');

        if (justPretend) {
          return;
        }
        return fs.unlink(filePath);
      })).then(function () {
        // Then process directories in ascending order
        var sortedDirs = paths.dirs.sort(function (a, b) {
          return b.length - a.length;
        });

        return sortedDirs.map(function (dir) {
          logger.writeln('Removing dir ' + dir.cyan + ' because not longer in src.');
          if (justPretend) {
            return;
          }
          return fs.rmdirSync(dir);
        });
      });
    });
  }

  function splitFilesAndDirs (stats) {
    return stats.reduce(function (memo, stat) {
      if (stat.isDirectory) {
        memo.dirs.push(stat.file);
      } else {
        memo.files.push(stat.file);
      }
      return memo;
    }, {
      files: [],
      dirs: []
    });
  }

  function fastArrayDiff (from, diff) {
    diff.map(function (v) {
      from[from.indexOf(v)] = undefined;
    });
    return from.filter(function (v) {
      return v;
    });
  }

  function convertPathToSystemSpecific (pathToConvert) {
    var newPath = path.join.apply(path, pathToConvert.split('/'));
    var startsWithSlash = pathToConvert[0] === '/';
    if (startsWithSlash) {
      return '/' + newPath;
    }

    return newPath;
  }

  function convertPathsToSystemSpecific (paths) {
    if (!paths.map) {
      return convertPathToSystemSpecific (paths);
    }

    return paths.map(function (filePath) {
      return convertPathToSystemSpecific (filePath);
    });
  }

  function addDirectoriesPaths (arr, dest) {
    var f = dest.split(path.sep);
    var i, p;
    p = f[0];

    for (i = 1; i < f.length - 1; ++i) {
      p += path.sep + f[i];
      if (arr.indexOf(p) === -1) {
        arr.push(p);
      }
    }
  }

  function getComparatorFactory(compareUsing, logger) {

    var md5;

    switch (compareUsing) {
      case 'md5':
        md5 = require('md5-file');
        return createMd5Comparator;
      case 'mtime':
        return createMTimeComparator;
      default:
        logger.writeln("Invalid 'compareUsing' option, falling back to default 'mtime'");
        return createMTimeComparator;
    }

    function createMTimeComparator(src, srcStat, dest, destStat) {
      return function() {
        return srcStat.mtime.getTime() <= destStat.mtime.getTime();
      };
    }

    function createMd5Comparator(src, srcStat, dest, destStat) {
      return function() {
        return md5(src) == md5(dest);
      };
    }
  }

};
<commit_msg>Support copy options, that are passed to grunt.file.copy (#56)<commit_after>var fs = require('promised-io/fs');
var promise = require('promised-io/promise');
var path = require('path');
var glob = require('glob');
var util = require('util');
var _ = require('lodash');

module.exports = function (grunt) {

  grunt.registerMultiTask('sync', 'Synchronize content of two directories.', function () {
    var done = this.async();
    var logger = grunt[this.data.verbose ? 'log' : 'verbose'];
    var updateOnly = !this.data.updateAndDelete;
    var justPretend = !!this.data.pretend;
    var failOnError = !!this.data.failOnError;
    var ignoredPatterns = this.data.ignoreInDest;
    var comparatorFactory = getComparatorFactory(this.data.compareUsing || 'mtime', logger);
    var expandedPaths = {};
    var options = this.options({
      encoding: grunt.file.defaultEncoding,
      // processContent/processContentExclude deprecated renamed to process/noProcess
      processContent: false,
      processContentExclude: []
    });
    var copyOptions = {
      encoding: options.encoding,
      process: options.process || options.processContent,
      noProcess: options.noProcess || options.processContentExclude
    };

    var getExpandedPaths = function (origDest) {
      if (!expandedPaths[origDest]) {
        // Always include destination as processed.
        expandedPaths[origDest] = [origDest.replace(new RegExp('\\' + path.sep + '$'), '')];
        return expandedPaths[origDest];
      }
      return expandedPaths[origDest];
    };

    promise.all(this.files.map(function (fileDef) {
      var isCompactForm = this.data.src && this.data.dest;
      var cwd = fileDef.cwd ? fileDef.cwd : '.';
      var isExpanded = fileDef.orig.expand;
      var origDest = path.join(fileDef.orig.dest, '');

      var processedDestinations = getExpandedPaths(origDest);

      return promise.all(fileDef.src.map(function (src) {
        var dest;
        // when using expanded mapping dest is the destination file
        // not the destination folder
        if (isExpanded || isCompactForm) {
          dest = convertPathsToSystemSpecific(fileDef.dest);
        } else {
          dest = path.join(fileDef.dest, src);
        }
        if (!updateOnly) {
          processedDestinations.push(dest);
          // Make sure to add directory of file as well (handle cases when source has pattern for files only)
          addDirectoriesPaths(processedDestinations, dest);
        }
        // Process pair
        return processPair(justPretend, failOnError, logger, comparatorFactory, path.join(cwd, src), dest, copyOptions);
      }));

    }, this)).then(function () {
      if (updateOnly) {
        return;
      }

      var getDestPaths = function (dest, pattern) {
        var defer = new promise.Deferred();
        glob(pattern, {
          cwd: dest,
          dot: true
        }, function (err, result) {
          if (err) {
            defer.reject(err);
            return;
          }
          defer.resolve(result.map(function (filePath) {
            return path.join(dest, filePath);
          }));
        });
        return defer.promise;
      };

      var getIgnoredPaths = function (dest, ignore) {
        var defer = new promise.Deferred();
        if (!ignore) {
          defer.resolve([]);
          return defer.promise;
        }

        if (!util.isArray(ignore)) {
          ignore = [ignore];
        }

        promise.all(ignore.map(function (pattern) {
          return getDestPaths(dest, pattern);
        })).then(function (results) {
          var flat = results.reduce(function (memo, a) {
            return memo.concat(a);
          }, []);
          defer.resolve(flat);
        }, function (err) {
          defer.reject(err);
        });

        return defer.promise;
      };

      // Second pass
      return promise.all(Object.keys(expandedPaths).map(function (dest) {
        var processedDestinations = convertPathsToSystemSpecific(expandedPaths[dest]);

        // We have to do second pass to remove objects from dest
        var destPaths = getDestPaths(dest, '**');

        // Check if we have any ignore patterns
        var ignoredPaths = getIgnoredPaths(dest, ignoredPatterns);

        return promise.all([destPaths, ignoredPaths, processedDestinations]);
      })).then(function (result) {
        var files = result.map(function (destAndIgnored) {
          var paths = convertPathsToSystemSpecific(destAndIgnored[0]);
          var ignoredPaths = convertPathsToSystemSpecific(destAndIgnored[1]);

          return [paths, ignoredPaths, destAndIgnored[2]];
        }).reduce(function (memo, destAndIgnored) {
          return memo.map(function (val, key) {
            return val.concat(destAndIgnored[key]);
          });
        }, [[], [], []]);

        // TODO Find some faster way to ensure uniqueness here
        var paths = _.uniq(files[0]);
        var ignoredPaths = _.uniq(files[1]);
        var processedDestinations = _.uniq(files[2]);

        // Calculate diff
        var toRemove = fastArrayDiff(paths, processedDestinations);
        // And filter also ignored paths
        toRemove = fastArrayDiff(toRemove, ignoredPaths);

        return removePaths(justPretend, logger, toRemove);
      });
    }).then(done);
  });

  function processPair (justPretend, failOnError, logger, comparatorFactory, src, dest, copyOptions) {

    // stat destination file
    return promise.all([fs.stat(src), fs.stat(dest)]).then(function (result) {
      var srcStat = result[0];
      var destStat = result[1];

      var isSrcDirectory = srcStat.isDirectory();
      var typeDiffers = isSrcDirectory !== destStat.isDirectory();
      var haventChangedFn = comparatorFactory(src, srcStat, dest, destStat);

      overwriteOrUpdate(isSrcDirectory, typeDiffers, haventChangedFn);
    }, function () {
      // we got an error which means that destination file does not exist
      // so make a copy
      if (grunt.file.isDir(src)) {
        logger.writeln('Creating ' + dest.cyan);

        doOrPretend(function () {
          tryMkdir(dest);
        });
      } else {
        logger.writeln('Copying ' + src.cyan + ' -> ' + dest.cyan);

        doOrPretend(function () {
          tryCopy(src, dest, copyOptions);
        });
      }
    });

    function doOrPretend (operation) {
      if (justPretend) {
        return;
      }
      operation();
    }

    function warnOrFail (msg) {
      if (failOnError) {
        grunt.fail.warn(msg);
        return;
      }
      grunt.log.warn(msg);
    }

    function tryCopy (src, dest, copyOptions) {
      try {
        grunt.file.copy(src, dest, copyOptions);
      } catch (e) {
        warnOrFail('Cannot copy to ' + dest.red);
      }
    }

    function tryMkdir (dest) {
      try {
        grunt.file.mkdir(dest);
      } catch (e) {
        warnOrFail('Cannot create directory ' + dest.red);
      }
    }

    function overwriteDest (src, dest) {
      try {
        grunt.file['delete'](dest);
        grunt.file.copy(src, dest, copyOptions);
      } catch (e) {
        warnOrFail('Cannot overwrite ' + dest.red);
      }
    }

    function overwriteOrUpdate (isSrcDirectory, typeDiffers, haventChangedFn) {

      // If types differ we have to overwrite destination.
      if (typeDiffers) {
        logger.writeln('Overwriting ' + dest.cyan + ' because type differs.');

        doOrPretend(function () {
          overwriteDest(src, dest, copyOptions);
        });
        return;
      }

      // we can now compare the files
      if (isSrcDirectory || haventChangedFn()) {
        return;
      }

      logger.writeln('Updating file ' + dest.cyan);
      doOrPretend(function () {
        // and just update destination
        tryCopy(src, dest, copyOptions);
      });
    }
  }

  function removePaths (justPretend, logger, paths) {

    return promise.all(paths.map(function (file) {
      return fs.stat(file).then(function (stat) {
        return {
          file: file,
          isDirectory: stat.isDirectory()
        };
      });
    })).then(function (stats) {
      var paths = splitFilesAndDirs(stats);

      // First we need to process files
      return promise.all(paths.files.map(function (filePath) {
        logger.writeln('Unlinking ' + filePath.cyan + ' because it was removed from src.');

        if (justPretend) {
          return;
        }
        return fs.unlink(filePath);
      })).then(function () {
        // Then process directories in ascending order
        var sortedDirs = paths.dirs.sort(function (a, b) {
          return b.length - a.length;
        });

        return sortedDirs.map(function (dir) {
          logger.writeln('Removing dir ' + dir.cyan + ' because not longer in src.');
          if (justPretend) {
            return;
          }
          return fs.rmdirSync(dir);
        });
      });
    });
  }

  function splitFilesAndDirs (stats) {
    return stats.reduce(function (memo, stat) {
      if (stat.isDirectory) {
        memo.dirs.push(stat.file);
      } else {
        memo.files.push(stat.file);
      }
      return memo;
    }, {
      files: [],
      dirs: []
    });
  }

  function fastArrayDiff (from, diff) {
    diff.map(function (v) {
      from[from.indexOf(v)] = undefined;
    });
    return from.filter(function (v) {
      return v;
    });
  }

  function convertPathToSystemSpecific (pathToConvert) {
    var newPath = path.join.apply(path, pathToConvert.split('/'));
    var startsWithSlash = pathToConvert[0] === '/';
    if (startsWithSlash) {
      return '/' + newPath;
    }

    return newPath;
  }

  function convertPathsToSystemSpecific (paths) {
    if (!paths.map) {
      return convertPathToSystemSpecific (paths);
    }

    return paths.map(function (filePath) {
      return convertPathToSystemSpecific (filePath);
    });
  }

  function addDirectoriesPaths (arr, dest) {
    var f = dest.split(path.sep);
    var i, p;
    p = f[0];

    for (i = 1; i < f.length - 1; ++i) {
      p += path.sep + f[i];
      if (arr.indexOf(p) === -1) {
        arr.push(p);
      }
    }
  }

  function getComparatorFactory(compareUsing, logger) {

    var md5;

    switch (compareUsing) {
      case 'md5':
        md5 = require('md5-file');
        return createMd5Comparator;
      case 'mtime':
        return createMTimeComparator;
      default:
        logger.writeln("Invalid 'compareUsing' option, falling back to default 'mtime'");
        return createMTimeComparator;
    }

    function createMTimeComparator(src, srcStat, dest, destStat) {
      return function() {
        return srcStat.mtime.getTime() <= destStat.mtime.getTime();
      };
    }

    function createMd5Comparator(src, srcStat, dest, destStat) {
      return function() {
        return md5(src) == md5(dest);
      };
    }
  }

};
<|endoftext|>


<commit_before>var frontend    = require('../controllers/frontend'),
    config      = require('../config'),
    express     = require('express'),
    utils       = require('../utils'),

    frontendRoutes;

frontendRoutes = function (middleware) {
    var router = express.Router(),
        subdir = config.paths.subdir,
        routeKeywords = config.routeKeywords;

    // ### Admin routes
    router.get(/^\/(logout|signout)\/$/, function redirect(req, res) {
        /*jslint unparam:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/ghost/signout/');
    });
    router.get(/^\/signup\/$/, function redirect(req, res) {
        /*jslint unparam:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/ghost/signup/');
    });

    // redirect to /ghost and let that do the authentication to prevent redirects to /ghost//admin etc.
    router.get(/^\/((ghost-admin|admin|wp-admin|dashboard|signin|login)\/?)$/, function (req, res) {
        /*jslint unparam:true*/
        res.redirect(subdir + '/ghost/');
    });

    // password-protected frontend route
    router.get('/' + routeKeywords.private + '/',
        middleware.isPrivateSessionAuth,
        frontend.private
    );
    router.post('/' + routeKeywords.private + '/',
        middleware.isPrivateSessionAuth,
        middleware.spamProtectedPrevention,
        middleware.authenticateProtection,
        frontend.private
    );

    // ### Frontend routes
    router.get('/rss/', frontend.rss);
    router.get('/rss/:page/', frontend.rss);
    router.get('/feed/', function redirect(req, res) {
        /*jshint unused:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/rss/');
    });

    // Tags
    router.get('/' + routeKeywords.tag + '/:slug/rss/', frontend.rss);
    router.get('/' + routeKeywords.tag + '/:slug/rss/:page/', frontend.rss);
    router.get('/' + routeKeywords.tag + '/:slug/' + routeKeywords.page + '/:page/', frontend.tag);
    router.get('/' + routeKeywords.tag + '/:slug/', frontend.tag);

    // Authors
    router.get('/' + routeKeywords.author + '/:slug/rss/', frontend.rss);
    router.get('/' + routeKeywords.author + '/:slug/rss/:page/', frontend.rss);
    router.get('/' + routeKeywords.author + '/:slug/' + routeKeywords.page + '/:page/', frontend.author);
    router.get('/' + routeKeywords.author + '/:slug/', frontend.author);

    // Post Live Preview
    router.get('/' + routeKeywords.preview + '/:uuid', frontend.preview);

    // Default
    router.get('/' + routeKeywords.page + '/:page/', frontend.homepage);
    router.get('/', frontend.homepage);
    router.get('*', frontend.single);

    // custom code for adding a contact form with nodemailer
    // if you want to pass arguments to the function
    // it must be router.get instead of tarikk’s router.post
    router.get('mail/', frontend.submitContactForm);
    // this is an experiment
    // router.get('/mail', function (req, res) {
    //     res.setHeader('Access-Control-Allow-Origin', 'http://petersekan.de');
    //     res.setHeader('Access-Control-Allow-Methods', 'GET');
    //     frontend.submitContactForm

    // });
    // end of custom code

    return router;
};

module.exports = frontendRoutes;
<commit_msg>edit path in frontend routes "/mail/"<commit_after>var frontend    = require('../controllers/frontend'),
    config      = require('../config'),
    express     = require('express'),
    utils       = require('../utils'),

    frontendRoutes;

frontendRoutes = function (middleware) {
    var router = express.Router(),
        subdir = config.paths.subdir,
        routeKeywords = config.routeKeywords;

    // ### Admin routes
    router.get(/^\/(logout|signout)\/$/, function redirect(req, res) {
        /*jslint unparam:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/ghost/signout/');
    });
    router.get(/^\/signup\/$/, function redirect(req, res) {
        /*jslint unparam:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/ghost/signup/');
    });

    // redirect to /ghost and let that do the authentication to prevent redirects to /ghost//admin etc.
    router.get(/^\/((ghost-admin|admin|wp-admin|dashboard|signin|login)\/?)$/, function (req, res) {
        /*jslint unparam:true*/
        res.redirect(subdir + '/ghost/');
    });

    // password-protected frontend route
    router.get('/' + routeKeywords.private + '/',
        middleware.isPrivateSessionAuth,
        frontend.private
    );
    router.post('/' + routeKeywords.private + '/',
        middleware.isPrivateSessionAuth,
        middleware.spamProtectedPrevention,
        middleware.authenticateProtection,
        frontend.private
    );

    // ### Frontend routes
    router.get('/rss/', frontend.rss);
    router.get('/rss/:page/', frontend.rss);
    router.get('/feed/', function redirect(req, res) {
        /*jshint unused:true*/
        res.set({'Cache-Control': 'public, max-age=' + utils.ONE_YEAR_S});
        res.redirect(301, subdir + '/rss/');
    });

    // Tags
    router.get('/' + routeKeywords.tag + '/:slug/rss/', frontend.rss);
    router.get('/' + routeKeywords.tag + '/:slug/rss/:page/', frontend.rss);
    router.get('/' + routeKeywords.tag + '/:slug/' + routeKeywords.page + '/:page/', frontend.tag);
    router.get('/' + routeKeywords.tag + '/:slug/', frontend.tag);

    // Authors
    router.get('/' + routeKeywords.author + '/:slug/rss/', frontend.rss);
    router.get('/' + routeKeywords.author + '/:slug/rss/:page/', frontend.rss);
    router.get('/' + routeKeywords.author + '/:slug/' + routeKeywords.page + '/:page/', frontend.author);
    router.get('/' + routeKeywords.author + '/:slug/', frontend.author);

    // Post Live Preview
    router.get('/' + routeKeywords.preview + '/:uuid', frontend.preview);

    // Default
    router.get('/' + routeKeywords.page + '/:page/', frontend.homepage);
    router.get('/', frontend.homepage);
    router.get('*', frontend.single);

    // custom code for adding a contact form with nodemailer
    // if you want to pass arguments to the function
    // it must be router.get instead of tarikk’s router.post
    router.get('/mail/', frontend.submitContactForm);
    // this is an experiment
    // router.get('/mail', function (req, res) {
    //     res.setHeader('Access-Control-Allow-Origin', 'http://petersekan.de');
    //     res.setHeader('Access-Control-Allow-Methods', 'GET');
    //     frontend.submitContactForm

    // });
    // end of custom code

    return router;
};

module.exports = frontendRoutes;
<|endoftext|>


<commit_before>import 'react-native';
import React from 'react';
import Index from '../index.ios.js';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <Index />
  );
});
<commit_msg>Update index.ios.js<commit_after>import 'react-native';
import React from 'react';
import Index from '../index.ios.js';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <setup />
    ).toJSON();
  expect(tree).toMatchSnapshot();
});
<|endoftext|>


<commit_before>// @flow
import type { $Application } from 'express';
import typeof Mservice from '../../../../index';
import type { PluginInterface } from '../../../../types';

const Errors = require('common-errors');
const http = require('http');
const is = require('is');
const Promise = require('bluebird');
const attachRouter = require('./router/attach');
const _require = require('../../../../utils/require');

function createExpressServer(config: Object, service: Mservice): PluginInterface {
  const enableDestroy = _require('server-destroy');
  const express = _require('express');

  const handler: $Application = express();
  const server = http.createServer(handler);
  const properties = config.server.handlerConfig && config.server.handlerConfig.properties;

  if (is.object(properties)) {
    Object.keys(properties).forEach(key => handler.set(key, properties[key]));
  }

  if (config.router.enabled) {
    attachRouter(service, handler, config.router);
  }

  service._http = {
    handler,
    server,
  };

  // make sure we can destroy it
  enableDestroy(server);

  function startServer() {
    if (service.http.server.listening === true) {
      return Promise.reject(new Errors.NotPermittedError('Http server was already started'));
    }

    if (config.server.attachSocketIO) {
      if (!service._socketIO) {
        return Promise.reject(new Errors.NotPermittedError('SocketIO plugin not found'));
      }

      service.socketIO.listen(service.http.server);
    }

    return Promise
      .fromCallback(callback => (
        service.http.server.listen(config.server.port, config.server.host, callback)
      ))
      .then(() => service.emit('plugin:start:http', service.http))
      .then(() => {
        const expressServer = service.http;
        expressServer.closeAsync = Promise.promisify(expressServer.close, { context: expressServer });
        expressServer.destroyAsync = Promise.promisify(expressServer.destroy, { context: expressServer });
        return expressServer;
      });
  }

  function stopServer() {
    if (config.server.attachSocketIO) {
      if (!service._socketIO) {
        return Promise.reject(new Errors.NotPermittedError('SocketIO plugin not found'));
      }

      service.socketIO.httpServer = null;
      service.socketIO.close();
    }

    return service.http
      .closeAsync()
      .timeout(5000)
      .catch(Promise.TimeoutError, () => service.http.destroyAsync())
      .then(() => service.emit('plugin:stop:http'));
  }

  return {
    connect: startServer,
    close: stopServer,
  };
}

module.exports = createExpressServer;
<commit_msg>fix: just use server reference<commit_after>// @flow
import type { $Application } from 'express';
import typeof Mservice from '../../../../index';
import type { PluginInterface } from '../../../../types';

const Errors = require('common-errors');
const http = require('http');
const is = require('is');
const Promise = require('bluebird');
const attachRouter = require('./router/attach');
const _require = require('../../../../utils/require');

function createExpressServer(config: Object, service: Mservice): PluginInterface {
  const enableDestroy = _require('server-destroy');
  const express = _require('express');

  const handler: $Application = express();
  const server = http.createServer(handler);
  const properties = config.server.handlerConfig && config.server.handlerConfig.properties;

  if (is.object(properties)) {
    Object.keys(properties).forEach(key => handler.set(key, properties[key]));
  }

  if (config.router.enabled) {
    attachRouter(service, handler, config.router);
  }

  service._http = {
    handler,
    server,
  };

  // make sure we can destroy it
  enableDestroy(server);

  function startServer() {
    if (server.listening === true) {
      return Promise.reject(new Errors.NotPermittedError('Http server was already started'));
    }

    if (config.server.attachSocketIO) {
      if (!service._socketIO) {
        return Promise.reject(new Errors.NotPermittedError('SocketIO plugin not found'));
      }

      service.socketIO.listen(server);
    }

    return Promise
      .fromCallback(callback => (
        server.listen(config.server.port, config.server.host, callback)
      ))
      .then(() => service.emit('plugin:start:http', service.http))
      .then(() => {
        const httpServer = server;
        httpServer.closeAsync = Promise.promisify(httpServer.close, { context: httpServer });
        httpServer.destroyAsync = Promise.promisify(httpServer.destroy, { context: httpServer });
        return service.http;
      });
  }

  function stopServer() {
    if (config.server.attachSocketIO) {
      if (!service._socketIO) {
        return Promise.reject(new Errors.NotPermittedError('SocketIO plugin not found'));
      }

      service.socketIO.httpServer = null;
      service.socketIO.close();
    }

    return service.http
      .server.closeAsync()
      .timeout(5000)
      .catch(Promise.TimeoutError, () => server.destroyAsync())
      .then(() => service.emit('plugin:stop:http'));
  }

  return {
    connect: startServer,
    close: stopServer,
  };
}

module.exports = createExpressServer;
<|endoftext|>


<commit_before>import React from 'react';
import { Form, Input, Upload, Button, Icon, Menu, Dropdown, Modal, message, Badge, Tabs } from 'antd';
const TabPane = Tabs.TabPane;
const FormItem = Form.Item;
import AuthStore from "../stores/auth";
import UserStore from "../stores/user";
class User extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            currentUser: {},
            user: {},
            activepanel: '1'
        }
    }
    componentDidMount() {
        document.title = "用户中❤";
        this.getCurrentUser();
        AuthStore.addChangeListener(this.getCurrentUser.bind(this));
        if (this.props.params.id) {
            this.getUserById(this.props.params.id);
        }
    }
    componentWillUnmount() {
        AuthStore.removeChangeListener(this.getCurrentUser.bind(this));
    }
    componentDidUpdate(prevProps) {
        var userId = this.props.params.id;
        if (userId) {
            this.getUserById(userId)
        }
    }
    getCurrentUser() {
        this.setState({
            currentUser: AuthStore.getUser()
        })
    }
    getUserById(id) {
        UserStore.getUserById(id, (err, user) => {
            this.setState({
                user: user
            })
        })
    }
    edit() {
        this.setState({
            activepanel: '2'
        })
    }
    submit(e) {
        e.preventDefault();
        this.setState({
            activepanel: '1'
        })
    }
    like() {
        message.success('添加成功!', 3)
    }
    render() {
        let currentUser = this.state.currentUser;
        let user = this.state.user || currentUser;
        let activepanel = this.state.activepanel;
        const { getFieldProps } = this.props.form;
        const formItemLayout = {
            labelCol: { span: 6 },
            wrapperCol: { span: 14 },
        };
        const props = {
            action: '/upload.do',
            listType: 'picture-card',
            defaultFileList: [{
                uid: -1,
                name: 'xxx.png',
                status: 'done',
                url: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
                thumbUrl: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
            }]
        };
        return (

                        <Tabs activeKey={activepanel}>
                            <TabPane tab="选项卡一" key="1">

用户名{user.username}

邮箱{user.email}

注册时间2015-05-06

                                        <Button onClick={this.edit.bind(this)} type="ghost" shape="circle" title="修改" size="small">
                                            <Icon type="setting" size="small"/>
                                        </Button>
                                        <Button onClick={this.like.bind(this)} type="ghost" title="关注" size="small" style={{marginLeft: '10px'}}>
                                            加好友
                                        </Button>

                            </TabPane>
                            <TabPane tab="选项卡二" key="2">

                                    <Form horizontal onSubmit={this.submit.bind(this)}>
                                        <FormItem
                                          {...formItemLayout}
                                          label="用户头像：">
                                          <Upload {...props}>
                                            <Icon type="plus" />

上传照片

                                          </Upload>
                                        </FormItem>
                                        <FormItem
                                          {...formItemLayout}
                                          label="用户昵称：" required>
                                          <Input type="text" {...getFieldProps('name')} placeholder="请输入用户昵称"/>
                                        </FormItem>
                                        <FormItem
                                          {...formItemLayout}
                                          label="邮箱：" required>
                                          <Input type="text" {...getFieldProps('name')} placeholder="请输入邮箱地址"/>
                                        </FormItem>
                                        <FormItem wrapperCol={{ span: 14, offset: 6 }} style={{ marginTop: 24 }}>
                                           <Button
                                            type="ghost"
                                            htmlType="submit"
                                            style={{width: '45%'}}>取消
                                           </Button>
                                           <Button
                                            type="primary"
                                            htmlType="submit"
                                            style={{width: '45%', marginLeft: '22px'}}>立即修改
                                           </Button>
                                        </FormItem>
                                    </Form>

                            </TabPane>
                        </Tabs>

                            我的好友

        );
    }
}
User = Form.create()(User);
export default User;
<commit_msg>优化个人卡片<commit_after>import React from 'react';
import { Form, Input, Upload, Button, Icon, Menu, Dropdown, Modal, message, Badge, Tabs } from 'antd';
const TabPane = Tabs.TabPane;
const FormItem = Form.Item;
import AuthStore from "../stores/auth";
import UserStore from "../stores/user";
class User extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            currentUser: {},
            user: {},
            activepanel: '1'
        }
    }
    componentDidMount() {
        document.title = "用户中❤";
        this.getCurrentUser();
        AuthStore.addChangeListener(this.getCurrentUser.bind(this));
        if (this.props.params.id) {
            this.getUserById(this.props.params.id);
        }
    }
    componentWillUnmount() {
        AuthStore.removeChangeListener(this.getCurrentUser.bind(this));
    }
    componentDidUpdate(prevProps) {
        var userId = this.props.params.id;
        if (userId) {
            this.getUserById(userId)
        }
    }
    getCurrentUser() {
        this.setState({
            currentUser: AuthStore.getUser() || {}
        })
    }
    getUserById(id) {
        UserStore.getUserById(id, (err, user) => {
            this.setState({
                user: user || {}
            })
        })
    }
    edit() {
        this.setState({
            activepanel: '2'
        })
    }
    submit(e) {
        e.preventDefault();
        this.setState({
            activepanel: '1'
        })
    }
    like() {
        message.success('添加成功!', 3)
    }
    render() {
        let currentUser = this.state.currentUser;
        let user = this.state.user || currentUser;
        let activepanel = this.state.activepanel;
        const { getFieldProps } = this.props.form;
        const formItemLayout = {
            labelCol: { span: 6 },
            wrapperCol: { span: 14 },
        };
        const props = {
            action: '/upload.do',
            listType: 'picture-card',
            defaultFileList: [{
                uid: -1,
                name: 'xxx.png',
                status: 'done',
                url: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
                thumbUrl: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
            }]
        };
        return (

                        <Tabs activeKey={activepanel}>
                            <TabPane tab="选项卡一" key="1">

用户名{user.username}

邮箱{user.email}

注册时间2015-05-06

                                        {user._id == currentUser._id ?
                                        <Button onClick={this.edit.bind(this)} type="ghost" shape="circle" title="修改" size="small">
                                            <Icon type="setting" size="small"/>
                                        </Button>
                                        : ''
                                        }
                                        {user._id != currentUser._id ?
                                        <Button onClick={this.like.bind(this)} type="ghost" title="关注" size="small" style={{marginLeft: '10px'}}>
                                            加好友
                                        </Button>
                                        : ''
                                        }

                            </TabPane>
                            <TabPane tab="选项卡二" key="2">

                                    <Form horizontal onSubmit={this.submit.bind(this)}>
                                        <FormItem
                                          {...formItemLayout}
                                          label="用户头像：">
                                          <Upload {...props}>
                                            <Icon type="plus" />

上传照片

                                          </Upload>
                                        </FormItem>
                                        <FormItem
                                          {...formItemLayout}
                                          label="用户昵称：" required>
                                          <Input type="text" {...getFieldProps('name')} placeholder="请输入用户昵称"/>
                                        </FormItem>
                                        <FormItem
                                          {...formItemLayout}
                                          label="邮箱：" required>
                                          <Input type="text" {...getFieldProps('name')} placeholder="请输入邮箱地址"/>
                                        </FormItem>
                                        <FormItem wrapperCol={{ span: 14, offset: 6 }} style={{ marginTop: 24 }}>
                                           <Button
                                            type="ghost"
                                            htmlType="submit"
                                            style={{width: '45%'}}>取消
                                           </Button>
                                           <Button
                                            type="primary"
                                            htmlType="submit"
                                            style={{width: '45%', marginLeft: '22px'}}>立即修改
                                           </Button>
                                        </FormItem>
                                    </Form>

                            </TabPane>
                        </Tabs>

                            我的好友

        );
    }
}
User = Form.create()(User);
export default User;
<|endoftext|>


<commit_before>function SolarAltitude(win, doc, $, domId, cubeColors) {
    var priv = {}, pub = {};

    // ----------------------------------------------------------------------------------------------- Private

    priv.shapes = {
        world: $(domId),
        north: $(domId + ' .north'),
        east:  $(domId + ' .east'),
        south: $(domId + ' .south'),
        west:  $(domId + ' .west'),
        roof:  $(domId + ' .roof')
    };

    priv.cubeColors = cubeColors;

    priv.brightness = {
        min: 25,
        max: 100
    };

    priv.day = 24; // hours per day

    priv.time = 8; // 00:00 - 24:00

    priv.worldColors = {
        list: [
            { r: 255, g: 255, b: 255 }
        ],
        amount: 1
    };

    priv.solarColors = {
        list: [
            { r: 0,   g: 0,   b: 255 }, // 00:00 - Midnight color
            { r: 255, g: 0,   b: 0   }, // 06:00 - Sunrise color
            { r: 255, g: 255, b: 0   }, // 12:00 - Midday color
            { r: 255, g: 0,   b: 0   }  // 18:00 - Sunset color
        ],
        amount: 4
    };

    priv.solarIntensity = {
        list: [
            // [ north, east, south, west, roof]
            [0.8, 0.5, 0.2, 0.5, 1.0], // 00:00 - Solar light shines from the north
            [0.5, 0.8, 0.5, 0.2, 1.0], // 06:00 - Solar light shines from the east
            [0.2, 0.5, 0.8, 0.5, 1.0], // 12:00 - Solar light shines from the south
            [0.5, 0.2, 0.5, 0.8, 1.0]  // 18:00 - Solar light shines from the west
        ],
        amount: 4
    };

    // -----------------------------------------------------------------------------------------------------------------

    priv.getRelativeNumber = function getRelativeNumber(start, end, time, scale) {
        var timeScale = (time % scale);

        if (start >= end) {
            return (start - (timeScale * (start - end) / scale));
        }
        else {
            return (start + (timeScale * (end - start) / scale));
        }
    };

    priv.getRgb = function getRgb(color1, color2, time, scale) {
        return {
            r: priv.getRelativeNumber(color1.r, color2.r, time, scale),
            g: priv.getRelativeNumber(color1.g, color2.g, time, scale),
            b: priv.getRelativeNumber(color1.b, color2.b, time, scale)
        }
    };

    priv.getColor = function getColor(colorList, time) {
        var colorAmount = colorList.amount,
            colors      = priv.getListEntries(colorList, time),
            day         = priv.day,
            scale       = day / colorAmount,
            colorIndex  = Math.floor(time / scale),
            result      = {r: 0, g: 0, b: 0};

        return priv.getRgb(colors[0], colors[1], time, scale);
    };

    priv.getListEntries = function getListEntries(currentList, time) {
        var list   = currentList.list,
            amount = currentList.amount,
            day    = priv.day,
            scale  = day / amount,
            index  = Math.floor(time / scale),
            result = [];

        if (amount == 1) {
            result[0] = list[0];
            result[1] = list[0];
        }
        else {
            if (index < amount) {
                result[0] = list[index];
            }
            else {
                result[0] = list[0];
            }

            if ((index + 1) < amount) {
                result[1] = list[(index + 1)];
            }
            else {
                result[1] = list[0];
            }
        }

        return result;
    };

    // ------------------------------------------------------------------------------------------------ Public

    pub.init = function () {
        pub.updateColors();

        // Simulate a day
        /** /
        setInterval(function() {
            priv.time = Math.round((priv.time + 0.1) * 100) / 100;
            if (priv.time >= priv.day) {
                priv.time = 0;
            }
            pub.updateColors();
            console.log('Time: ', priv.time);
        }, 100);
        /**/
    };

    /**
     * Returns brightness as percentage of the day between min and max.
     */
    pub.getBrightness = function getBrightness(time) {
        var min = priv.brightness.min,
            max = priv.brightness.max,
            day = priv.day;

        return ((((min - max) * Math.cos(((Math.PI * time) * 2 / day))) + max + min) / 2);
    };

    pub.getSolarColor = function getSolarColor(time) {
        return priv.getColor(priv.solarColors, time);
    };

    pub.getMapColor = function getMapColor(time) {
        return priv.getColor(priv.worldColors, time)
    };

    pub.getCubeColor = function getCubeColor(time) {
        var colorAmount = priv.cubeColors.amount,
            colors      = priv.getListEntries(priv.cubeColors, time),
            day         = priv.day,
            scale       = day / colorAmount,
            colorIndex  = Math.floor(time / scale),
            result      = [],
            i, shapeAmount;

        shapeAmount = Math.min(colors[0].length, colors[1].length);
        for (i = 0; i < shapeAmount; i++) {
            result[i] = priv.getRgb(colors[0][i], colors[1][i], time, scale);
        }

        return result;
    };

    pub.getSolarIntensity = function getSolarIntensity(time) {
        var list      = priv.solarIntensity.list,
            amount    = priv.solarIntensity.amount,
            intensity = priv.getListEntries(priv.solarIntensity, time),
            day       = priv.day,
            scale     = day / amount,
            result    = [],
            i, shapeAmount;

        shapeAmount = Math.min(intensity[0].length, intensity[1].length);
        for (i = 0; i < shapeAmount; i++) {
            result[i] = priv.getRelativeNumber(intensity[0][i], intensity[1][i], time, scale);
        }

        return result;
    };

    pub.updateColors = function updateColors() {
        var brightness     = 100,
            time           = priv.time,
            solarColor     = { r: 255, g: 255, b: 255 },
            solarIntensity = { north: 0, east: 0, south: 0, west: 0, roof: 0},
            worldColor     = { r: 255, g: 255, b: 255},
            cubeColor      = {
                north: { r: 127, g: 127, b: 127 },
                east:  { r: 127, g: 127, b: 127 },
                south: { r: 127, g: 127, b: 127 },
                west:  { r: 127, g: 127, b: 127 },
                roof:  { r: 127, g: 127, b: 127 }
            },
            r, g, b;

        // Dynamic light and brightness
        /**/
        brightness     = pub.getBrightness(time);
        solarColor     = pub.getSolarColor(time);
        solarIntensity = pub.getSolarIntensity(time);
        worldColor     = pub.getMapColor(time);
        cubeColor      = pub.getCubeColor(time);
        /**/

        // Render world color
        r = Math.round(((worldColor.r + solarColor.r) / (2*100)) * brightness);
        g = Math.round(((worldColor.g + solarColor.g) / (2*100)) * brightness);
        b = Math.round(((worldColor.b + solarColor.b) / (2*100)) * brightness);
        priv.shapes.world.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round(((cubeColor[0].r + (solarColor.r * solarIntensity[0])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[0].g + (solarColor.g * solarIntensity[0])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[0].b + (solarColor.b * solarIntensity[0])) / (2 * 100)) * brightness);
        priv.shapes.north.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render east color
        r = Math.round(((cubeColor[1].r + (solarColor.r * solarIntensity[1])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[1].g + (solarColor.g * solarIntensity[1])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[1].b + (solarColor.b * solarIntensity[1])) / (2 * 100)) * brightness);
        priv.shapes.east.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render south color
        r = Math.round(((cubeColor[2].r + (solarColor.r * solarIntensity[2])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[2].g + (solarColor.g * solarIntensity[2])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[2].b + (solarColor.b * solarIntensity[2])) / (2 * 100)) * brightness);
        priv.shapes.south.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render west color
        r = Math.round(((cubeColor[3].r + (solarColor.r * solarIntensity[3])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[3].g + (solarColor.g * solarIntensity[3])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[3].b + (solarColor.b * solarIntensity[3])) / (2 * 100)) * brightness);
        priv.shapes.west.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render roof color
        r = Math.round(((cubeColor[4].r + solarColor.r * solarIntensity[4]) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[4].g + solarColor.g * solarIntensity[4]) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[4].b + solarColor.b * solarIntensity[4]) / (2 * 100)) * brightness);
        priv.shapes.roof.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');
    };

    // ------------------------------------------------------------------------------------------------ Return

    return pub;

}

// ----------------------------------------------------------------------------------------------------- Run application

jQuery(document).ready(function() {
    'use strict';

    var red = {
            list: [[
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0}
            ]],
            amount: 1
        },
        green = {
            list: [[
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0}
            ]],
            amount: 1
        },
        blue = {
            list: [[
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255}
            ]],
            amount: 1
        },
        grey = {
            list: [[
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0}
            ], [
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0}
            ], [
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255}
            ]],
            amount: 2
        },

        solarAltitudeRed   = new SolarAltitude(window, document, jQuery, '#appRed', red),
        solarAltitudeGreen = new SolarAltitude(window, document, jQuery, '#appGreen', green),
        solarAltitudeBlue  = new SolarAltitude(window, document, jQuery, '#appBlue', blue),
        solarAltitudeGrey  = new SolarAltitude(window, document, jQuery, '#appGrey', grey);

    solarAltitudeRed.init();
    solarAltitudeGreen.init();
    solarAltitudeBlue.init();
    solarAltitudeGrey.init();
});
<commit_msg>Method logic split into separated methods.<commit_after>function SolarAltitude(win, doc, $, domId, cubeColors) {
    var priv = {}, pub = {};

    // ----------------------------------------------------------------------------------------------- Private

    priv.shapes = {
        world: $(domId),
        north: $(domId + ' .north'),
        east:  $(domId + ' .east'),
        south: $(domId + ' .south'),
        west:  $(domId + ' .west'),
        roof:  $(domId + ' .roof')
    };

    priv.cubeColors = cubeColors;

    priv.brightness = {
        min: 25,
        max: 100
    };

    priv.day = 24; // hours per day

    priv.time = 8; // 00:00 - 24:00

    priv.worldColors = {
        list: [
            { r: 255, g: 255, b: 255 }
        ],
        amount: 1
    };

    priv.solarColors = {
        list: [
            { r: 0,   g: 0,   b: 255 }, // 00:00 - Midnight color
            { r: 255, g: 0,   b: 0   }, // 06:00 - Sunrise color
            { r: 255, g: 255, b: 0   }, // 12:00 - Midday color
            { r: 255, g: 0,   b: 0   }  // 18:00 - Sunset color
        ],
        amount: 4
    };

    priv.solarIntensity = {
        list: [
            // [ north, east, south, west, roof]
            [0.8, 0.5, 0.2, 0.5, 1.0], // 00:00 - Solar light shines from the north
            [0.5, 0.8, 0.5, 0.2, 1.0], // 06:00 - Solar light shines from the east
            [0.2, 0.5, 0.8, 0.5, 1.0], // 12:00 - Solar light shines from the south
            [0.5, 0.2, 0.5, 0.8, 1.0]  // 18:00 - Solar light shines from the west
        ],
        amount: 4
    };

    // -----------------------------------------------------------------------------------------------------------------

    priv.getRelativeNumber = function getRelativeNumber(start, end, time, scale) {
        var timeScale = (time % scale);

        if (start >= end) {
            return (start - (timeScale * (start - end) / scale));
        }
        else {
            return (start + (timeScale * (end - start) / scale));
        }
    };

    priv.getRgbColor = function getRgbColor(rgbStart, rgbEnd, time, scale) {
        return {
            r: priv.getRelativeNumber(rgbStart.r, rgbEnd.r, time, scale),
            g: priv.getRelativeNumber(rgbStart.g, rgbEnd.g, time, scale),
            b: priv.getRelativeNumber(rgbStart.b, rgbEnd.b, time, scale)
        }
    };

    priv.getListEntries = function getListEntries(currentList, time) {
        var list   = currentList.list,
            amount = currentList.amount,
            day    = priv.day,
            scale  = day / amount,
            index  = Math.floor(time / scale),
            result = [];

        if (amount == 1) {
            result[0] = list[0];
            result[1] = list[0];
        }
        else {
            if (index < amount) {
                result[0] = list[index];
            }
            else {
                result[0] = list[0];
            }

            if ((index + 1) < amount) {
                result[1] = list[(index + 1)];
            }
            else {
                result[1] = list[0];
            }
        }

        return result;
    };

    priv.getColor = function getColor(colorList, time) {
        var colorAmount = colorList.lenth,
            colors      = priv.getListEntries(colorList, time),
            day         = priv.day,
            scale       = day / colorAmount,
            colorIndex  = Math.floor(time / scale),
            result      = {r: 0, g: 0, b: 0};

        return priv.getRgbColor(colors[0], colors[1], time, scale);
    };

    // ------------------------------------------------------------------------------------------------ Public

    pub.init = function () {
        pub.updateColors();

        // Simulate a day
        /** /
        setInterval(function() {
            priv.time = Math.round((priv.time + 0.1) * 100) / 100;
            if (priv.time >= priv.day) {
                priv.time = 0;
            }
            pub.updateColors();
            console.log('Time: ', priv.time);
        }, 100);
        /**/
    };

    /**
     * Returns brightness as percentage of the day between min and max.
     */
    pub.getBrightness = function getBrightness(time) {
        var min = priv.brightness.min,
            max = priv.brightness.max,
            day = priv.day;

        return ((((min - max) * Math.cos(((Math.PI * time) * 2 / day))) + max + min) / 2);
    };

    pub.getSolarColor = function getSolarColor(time) {
        return priv.getColor(priv.solarColors.list, time);
    };

    pub.getMapColor = function getMapColor(time) {
        return priv.getColor(priv.worldColors.list, time)
    };

    pub.getCubeColor = function getCubeColor(time) {
        var colorAmount = priv.cubeColors.amount,
            colors      = priv.getListEntries(priv.cubeColors, time),
            day         = priv.day,
            scale       = day / colorAmount,
            colorIndex  = Math.floor(time / scale),
            result      = [],
            i, shapeAmount;

        shapeAmount = Math.min(colors[0].length, colors[1].length);
        for (i = 0; i < shapeAmount; i++) {
            result[i] = priv.getRgbColor(colors[0][i], colors[1][i], time, scale);
        }

        return result;
    };

    pub.getSolarIntensity = function getSolarIntensity(time) {
        var list      = priv.solarIntensity.list,
            amount    = priv.solarIntensity.amount,
            intensity = priv.getListEntries(priv.solarIntensity, time),
            day       = priv.day,
            scale     = day / amount,
            result    = [],
            i, shapeAmount;

        shapeAmount = Math.min(intensity[0].length, intensity[1].length);
        for (i = 0; i < shapeAmount; i++) {
            result[i] = priv.getRelativeNumber(intensity[0][i], intensity[1][i], time, scale);
        }

        return result;
    };

    pub.updateColors = function updateColors() {
        var brightness     = 100,
            time           = priv.time,
            solarColor     = { r: 255, g: 255, b: 255 },
            solarIntensity = { north: 0, east: 0, south: 0, west: 0, roof: 0},
            worldColor     = { r: 255, g: 255, b: 255},
            cubeColor      = {
                north: { r: 127, g: 127, b: 127 },
                east:  { r: 127, g: 127, b: 127 },
                south: { r: 127, g: 127, b: 127 },
                west:  { r: 127, g: 127, b: 127 },
                roof:  { r: 127, g: 127, b: 127 }
            },
            r, g, b;

        // Dynamic light and brightness
        /**/
        brightness     = pub.getBrightness(time);
        solarColor     = pub.getSolarColor(time);
        solarIntensity = pub.getSolarIntensity(time);
        worldColor     = pub.getMapColor(time);
        cubeColor      = pub.getCubeColor(time);
        /**/

        // Render world color
        r = Math.round(((worldColor.r + solarColor.r) / (2*100)) * brightness);
        g = Math.round(((worldColor.g + solarColor.g) / (2*100)) * brightness);
        b = Math.round(((worldColor.b + solarColor.b) / (2*100)) * brightness);
        priv.shapes.world.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render north color
        r = Math.round(((cubeColor[0].r + (solarColor.r * solarIntensity[0])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[0].g + (solarColor.g * solarIntensity[0])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[0].b + (solarColor.b * solarIntensity[0])) / (2 * 100)) * brightness);
        priv.shapes.north.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render east color
        r = Math.round(((cubeColor[1].r + (solarColor.r * solarIntensity[1])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[1].g + (solarColor.g * solarIntensity[1])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[1].b + (solarColor.b * solarIntensity[1])) / (2 * 100)) * brightness);
        priv.shapes.east.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render south color
        r = Math.round(((cubeColor[2].r + (solarColor.r * solarIntensity[2])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[2].g + (solarColor.g * solarIntensity[2])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[2].b + (solarColor.b * solarIntensity[2])) / (2 * 100)) * brightness);
        priv.shapes.south.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render west color
        r = Math.round(((cubeColor[3].r + (solarColor.r * solarIntensity[3])) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[3].g + (solarColor.g * solarIntensity[3])) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[3].b + (solarColor.b * solarIntensity[3])) / (2 * 100)) * brightness);
        priv.shapes.west.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');

        // Render roof color
        r = Math.round(((cubeColor[4].r + solarColor.r * solarIntensity[4]) / (2 * 100)) * brightness);
        g = Math.round(((cubeColor[4].g + solarColor.g * solarIntensity[4]) / (2 * 100)) * brightness);
        b = Math.round(((cubeColor[4].b + solarColor.b * solarIntensity[4]) / (2 * 100)) * brightness);
        priv.shapes.roof.css('background', 'rgb(' + r + ',' + g + ',' + b + ')');
    };

    // ------------------------------------------------------------------------------------------------ Return

    return pub;

}

// ----------------------------------------------------------------------------------------------------- Run application

jQuery(document).ready(function() {
    'use strict';

    var red = {
            list: [[
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0}
            ]],
            amount: 1
        },
        green = {
            list: [[
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0}
            ]],
            amount: 1
        },
        blue = {
            list: [[
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255}
            ]],
            amount: 1
        },
        grey = {
            list: [[
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0},
                {r: 255, g: 0, b: 0}
            ], [
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0},
                {r: 0, g: 255, b: 0}
            ], [
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255},
                {r: 0, g: 0, b: 255}
            ]],
            amount: 2
        },

        solarAltitudeRed   = new SolarAltitude(window, document, jQuery, '#appRed', red),
        solarAltitudeGreen = new SolarAltitude(window, document, jQuery, '#appGreen', green),
        solarAltitudeBlue  = new SolarAltitude(window, document, jQuery, '#appBlue', blue),
        solarAltitudeGrey  = new SolarAltitude(window, document, jQuery, '#appGrey', grey);

    solarAltitudeRed.init();
    solarAltitudeGreen.init();
    solarAltitudeBlue.init();
    solarAltitudeGrey.init();
});
<|endoftext|>


<commit_before>/* eslint-disable new-cap */

const handlers = require('./handlers');
const express = require('express');
const router = express.Router();
const jsonParser = require('body-parser').json();
const middlewares = require('georap-middlewares');

router.get('/', handlers.getOne);
router.delete('/', handlers.removeOne);

router.get('/attachments', handlers.getAttachments);
router.post('/geom', jsonParser, handlers.changeGeom);
router.get('/entries', middlewares.skipLimitParser, handlers.getEntries);
router.post('/name', jsonParser, handlers.changeName);
router.post('/tags', jsonParser, handlers.changeTags); // TODO remove
router.post('/status', jsonParser, handlers.changeStatus);
router.post('/type', jsonParser, handlers.changeType);
router.post('/thumbnail', jsonParser, handlers.changeThumbnail);

module.exports = router;
<commit_msg>Setup capability locations-update<commit_after>/* eslint-disable new-cap */

const able = require('georap-able').middleware;
const handlers = require('./handlers');
const express = require('express');
const router = express.Router();
const jsonParser = require('body-parser').json();
const middlewares = require('georap-middlewares');

router.get('/', handlers.getOne);
router.delete('/', handlers.removeOne); // Internal remove rule checking

router.get('/attachments', handlers.getAttachments);

router.post('/geom', able('locations-update'),
            jsonParser, handlers.changeGeom);

router.get('/entries', middlewares.skipLimitParser, handlers.getEntries);

router.post('/name', able('locations-update'),
            jsonParser, handlers.changeName);

router.post('/tags', able('locations-update'),
            jsonParser, handlers.changeTags); // TODO remove
router.post('/status', able('locations-update'),
            jsonParser, handlers.changeStatus);
router.post('/type', able('locations-update'),
            jsonParser, handlers.changeType);

router.post('/thumbnail', able('locations-update'),
            jsonParser, handlers.changeThumbnail);

module.exports = router;
<|endoftext|>


<commit_before>/*global Widget */

function IncrementalGraphWidget(widget, configName) {

    this.widget = widget;
    this.configName = configName;
    this.chart = null;

    this.dataToBind = {
        'value': '',
        'arrowClass': '',
        'percentageDiff': 0,
        'oldValue': ''
    };
}

IncrementalGraphWidget.prototype = new Widget();
IncrementalGraphWidget.prototype.constructor = IncrementalGraphWidget;

$.extend(IncrementalGraphWidget.prototype, {
    /**
     * Invoked after each response from long polling server
     *
     * @param response Response from long polling server
     */
    handleResponse: function (response) {
        this.prepareData(response);
    },

    /**
     * Updates widget's state
     */
    prepareData: function (response) {

        var currentPoint = response.data,
            currentValue = currentPoint.y,
            pointX = parseFloat(currentPoint.x) * 1000,
            pointY = parseFloat(currentPoint.y);

        /**
         * Calculating diff from last collected value
         */
        $.extend(this.dataToBind, this.setDifference(this.oldValue, currentValue));

        this.dataToBind.value = currentValue;
        this.oldValue = currentValue;

        if (this.chart !== null) {
            this.handleChangeRate();
            this.updateValue();
        } else {
            this.renderTemplate(this.dataToBind);
            this.setupGraph();
        }
        this.chart.highcharts().series[0].addPoint([pointX, pointY], true, (this.chart.highcharts().series[0].data.length >= this.params.maxPoints));
        $(this.widget).blinkStop();
        if (((this.params.thresholdComparator == 'higherIsBetter') && (currentValue <= this.params.criticalValue)) || ((this.params.thresholdComparator == 'lowerIsBetter') && (currentValue >= this.params.criticalValue))) {
            $(this.widget).blink({opacity: 0.2});
        }
        this.chart.highcharts().xAxis[0].removePlotLine('deployment');
        for (var i=0; i<currentPoint.events.length; i++) {
            var deployment = currentPoint.events[i];
            this.chart.highcharts().xAxis[0].addPlotLine({
                id: 'deployment',
                label: { text: deployment.title, style: { color: 'orange' } },
                value: parseFloat(deployment.date) * 1000,
                color: 'orange',
                width: 2,
                zIndex: 5
            });
        }

        /**
         * Animate and format main value
         */
        this.animateNumber(this.$widget.find('.value .content'), this.oldValue, this.dataToBind.value);

        /**
         * Animate and format numeric difference if that exists
         */
        var oldValueElement = this.$widget.find('.difference .old-value');

        if ($.isNumeric(oldValueElement[0].innerText)) {
            this.animateNumber(oldValue, this.oldValue, this.dataToBind.value);
        }
    },

    handleChangeRate: function() {
        $('.change-rate', this.widget)
            .show()
            .removeClass('better worse').addClass(this.dataToBind.trend)
            .find('i')
            .removeClass().addClass(this.dataToBind.arrowClass).parent()
            .find('.percentageDiff')
            .html(this.dataToBind.percentageDiff).parent()
            .find('.old-value')
            .html(this.dataToBind.oldValue);
    },

    updateValue: function() {
        $('h2.value > .content', this.widget).html(this.dataToBind.value);
    },

    setupGraph: function() {
        var zones = [];
        if (parseFloat(this.$widget.attr('data-threshold-caution-value')) > 0
            && parseFloat(this.$widget.attr('data-threshold-critical-value')) > 0) {
            zones = [
                {
                    value: this.$widget.attr('data-threshold-caution-value'),
                    className: 'value-normal'
                }, {
                    value: this.$widget.attr('data-threshold-critical-value'),
                    fillColor: '#fff46b',
                    color: '#fffda6',
                    className: 'value-caution'
                }, {
                    fillColor: '#e62a34',
                    color: '#f03542',
                    className: 'value-critical'
                }
            ];

            if (
                typeof(this.params.thresholdComparator) !== 'undefined'
                && this.params.thresholdComparator === 'higherIsBetter'
            ) {
                console.log(this.$widget);
                zones = [
                    {
                        value: this.$widget.attr('data-threshold-critical-value'),
                        className: 'value-critical',
                        fillColor: '#e62a34',
                        color: '#f03542'
                    },
                    {
                        value: this.$widget.attr('data-threshold-caution-value'),
                        className: 'value-caution',
                        fillColor: '#fff46b',
                        color: '#fffda6'
                    },
                    {
                        className: 'value-normal'
                    }
                ];
            }
        }

        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });
        $('.change-rate', this.widget).hide();
        this.chart = $('.graph', this.widget).highcharts({
            chart: {
                type: this.params.graphType
            },
            title: {
                text: ''
            },
            xAxis: {
                title: '',
                type: 'datetime',
                dateTimeLabelFormats: {
                    millisecond: '%H:%M',
                    second: '%H:%M'
                },
                tickPixelInterval: this.params.graphTickPixelInterval
            },
            yAxis: {
                title: ''
            },
            tooltip: {
                pointFormat: 'Value of {point.y} noted.'
            },
            plotOptions: {
                area: {
                    pointStart: 1940,
                    marker: {
                        enabled: false,
                        symbol: 'circle',
                        radius: 2,
                        states: {
                            hover: {
                                enabled: true
                            }
                        }
                    }
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [
                {
                    title: {
                        text: ''
                    },
                    data: [],
                    zones: zones
                }
            ]
        });
    }
});
<commit_msg>Fix thresholds in incrementalGraph<commit_after>/*global Widget */

function IncrementalGraphWidget(widget, configName) {

    this.widget = widget;
    this.configName = configName;
    this.chart = null;

    this.dataToBind = {
        'value': '',
        'arrowClass': '',
        'percentageDiff': 0,
        'oldValue': ''
    };
}

IncrementalGraphWidget.prototype = new Widget();
IncrementalGraphWidget.prototype.constructor = IncrementalGraphWidget;

$.extend(IncrementalGraphWidget.prototype, {
    /**
     * Invoked after each response from long polling server
     *
     * @param response Response from long polling server
     */
    handleResponse: function (response) {
        this.prepareData(response);
    },

    /**
     * Updates widget's state
     */
    prepareData: function (response) {

        var currentPoint = response.data,
            currentValue = currentPoint.y,
            pointX = parseFloat(currentPoint.x) * 1000,
            pointY = parseFloat(currentPoint.y);

        /**
         * Calculating diff from last collected value
         */
        $.extend(this.dataToBind, this.setDifference(this.oldValue, currentValue));

        this.dataToBind.value = currentValue;
        this.oldValue = currentValue;

        if (this.chart !== null) {
            this.handleChangeRate();
            this.updateValue();
        } else {
            this.renderTemplate(this.dataToBind);
            this.setupGraph();
        }
        this.chart.highcharts().series[0].addPoint([pointX, pointY], true, (this.chart.highcharts().series[0].data.length >= this.params.maxPoints));
        $(this.widget).blinkStop();
        if (((this.params.thresholdComparator == 'higherIsBetter') && (currentValue <= this.params.criticalValue)) || ((this.params.thresholdComparator == 'lowerIsBetter') && (currentValue >= this.params.criticalValue))) {
            $(this.widget).blink({opacity: 0.2});
        }
        this.chart.highcharts().xAxis[0].removePlotLine('deployment');
        for (var i=0; i<currentPoint.events.length; i++) {
            var deployment = currentPoint.events[i];
            this.chart.highcharts().xAxis[0].addPlotLine({
                id: 'deployment',
                label: { text: deployment.title, style: { color: 'orange' } },
                value: parseFloat(deployment.date) * 1000,
                color: 'orange',
                width: 2,
                zIndex: 5
            });
        }

        /**
         * Animate and format main value
         */
        this.animateNumber(this.$widget.find('.value .content'), this.oldValue, this.dataToBind.value);

        /**
         * Animate and format numeric difference if that exists
         */
        var oldValueElement = this.$widget.find('.difference .old-value');

        if ($.isNumeric(oldValueElement[0].innerText)) {
            this.animateNumber(oldValue, this.oldValue, this.dataToBind.value);
        }

        this.checkThresholds(currentValue);
    },

    handleChangeRate: function() {
        $('.change-rate', this.widget)
            .show()
            .removeClass('better worse').addClass(this.dataToBind.trend)
            .find('i')
            .removeClass().addClass(this.dataToBind.arrowClass).parent()
            .find('.percentageDiff')
            .html(this.dataToBind.percentageDiff).parent()
            .find('.old-value')
            .html(this.dataToBind.oldValue);
    },

    updateValue: function() {
        $('h2.value > .content', this.widget).html(this.dataToBind.value);
    },

    setupGraph: function() {
        var zones = [];
        if (parseFloat(this.params['caution-value']) > 0
            && parseFloat(this.params['critical-value']) > 0) {
            zones = [
                {
                    value: this.params['caution-value'],
                    className: 'value-normal'
                }, {
                    value: this.params['critical-value'],
                    fillColor: '#fff46b',
                    color: '#fffda6',
                    className: 'value-caution'
                }, {
                    fillColor: '#e62a34',
                    color: '#f03542',
                    className: 'value-critical'
                }
            ];

            if (
                typeof(this.params.thresholdComparator) !== 'undefined'
                && this.params.thresholdComparator === 'higherIsBetter'
            ) {
                zones = [
                    {
                        value: this.params['critical-value'],
                        className: 'value-critical',
                        fillColor: '#e62a34',
                        color: '#f03542'
                    },
                    {
                        value: this.params['caution-value'],
                        className: 'value-caution',
                        fillColor: '#fff46b',
                        color: '#fffda6'
                    },
                    {
                        className: 'value-normal'
                    }
                ];
            }
        }

        Highcharts.setOptions({
            global: {
                useUTC: false
            }
        });
        $('.change-rate', this.widget).hide();
        this.chart = $('.graph', this.widget).highcharts({
            chart: {
                type: this.params.graphType
            },
            title: {
                text: ''
            },
            xAxis: {
                title: '',
                type: 'datetime',
                dateTimeLabelFormats: {
                    millisecond: '%H:%M',
                    second: '%H:%M'
                },
                tickPixelInterval: this.params.graphTickPixelInterval
            },
            yAxis: {
                title: ''
            },
            tooltip: {
                pointFormat: 'Value of {point.y} noted.'
            },
            plotOptions: {
                area: {
                    pointStart: 1940,
                    marker: {
                        enabled: false,
                        symbol: 'circle',
                        radius: 2,
                        states: {
                            hover: {
                                enabled: true
                            }
                        }
                    }
                }
            },
            legend: {
                enabled: false
            },
            exporting: {
                enabled: false
            },
            series: [
                {
                    title: {
                        text: ''
                    },
                    data: [],
                    zones: zones
                }
            ]
        });
    }
});
<|endoftext|>