<commit_before>'use strict';
// 1.0.3

angular.module('amChartsDirective', []).directive('amChart', ['$q', function ($q) {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      options: '=',
      height: '=',
      width: '='
    },
    template: '

',
    link: function ($scope, $el) {

      // use existing outer id to create new id
      var id = $el[0].id;
      $el.attr('id', id);
      var chart;

      // we can't render a chart without any data
      if ($scope.options.data) {
        var renderChart = function (amChartOptions) {
          var o = amChartOptions || $scope.options;

          // set height and width
          var height = $scope.height || '100%';
          var width = $scope.width || '100%';

          $el.css({
            'height': height,
            'width': width
          });

          // instantiate new chart object
          if (o.type === 'xy') {
            chart = o.theme ? new AmCharts.AmXYChart(AmCharts.themes[o.theme]) : new AmCharts.AmXYChart();
          } else if (o.type === 'pie') {
            chart = o.theme ? new AmCharts.AmPieChart(AmCharts.themes[o.theme]) : new AmCharts.AmPieChart();
          } else {
            chart = o.theme ? new AmCharts.AmSerialChart(AmCharts.themes[o.theme]) : new AmCharts.AmSerialChart();
          }

          /** set some default values that amCharts doesnt provide **/
          $q.when(o.data)
            .then(function (data) {

              chart.dataProvider = data;
              // if a category field is not specified, attempt to use the first field from an object in the array
              chart.categoryField = o.categoryField || Object.keys(o.data[0])[0];
              chart.startDuration = 0.5; // default animation length, because everyone loves a little pizazz

              // AutoMargin is on by default, but the default 20px all around seems to create unnecessary white space around the control
              chart.autoMargins = true;
              chart.marginTop = 0;
              chart.marginLeft = 0;
              chart.marginBottom = 0;
              chart.marginRight = 0;

              // modify default creditsPosition
              chart.creditsPosition = 'top-right';

              var chartKeys = Object.keys(o);
              for (var i = 0; i < chartKeys.length; i++) {
                if (typeof o[chartKeys[i]] !== 'object' && typeof o[chartKeys[i]] !== 'function') {
                  chart[chartKeys[i]] = o[chartKeys[i]];
                }
              }

              function generateGraphProperties(data) {
                // Assign Category Axis Properties
                if (o.categoryAxis) {
                  var categoryAxis = chart.categoryAxis;

                  if (categoryAxis) {
                    /* if we need to create any default values, we should assign them here */
                    categoryAxis.parseDates = true;

                    var keys = Object.keys(o.categoryAxis);
                    for (var i = 0; i < keys.length; i++) {
                      if (!angular.isObject(o.categoryAxis[keys[i]]) || angular.isArray(o.categoryAxis[keys[i]])) {
                        categoryAxis[keys[i]] = o.categoryAxis[keys[i]];
                      } else {
                        console.log('Stripped categoryAxis obj ' + keys[i]);
                      }
                    }
                    chart.categoryAxis = categoryAxis;
                  }
                }

                // Create value axis

                /* if we need to create any default values, we should assign them here */

                var addValueAxis = function (a) {
                  var valueAxis = new AmCharts.ValueAxis();

                  var keys = Object.keys(a);
                  for (var i = 0; i < keys.length; i++) {
                    if (typeof a[keys[i]] !== 'object') {
                      valueAxis[keys[i]] = a[keys[i]];
                    }
                  }
                  chart.addValueAxis(valueAxis);
                };

                if (o.valueAxes && o.valueAxes.length > 0) {
                  for (var i = 0; i < o.valueAxes.length; i++) {
                    addValueAxis(o.valueAxes[i]);
                  }
                }

                //reusable function to create graph
                var addGraph = function (g) {
                  var graph = new AmCharts.AmGraph();
                  /** set some default values that amCharts doesnt provide **/
                    // if a category field is not specified, attempt to use the second field from an object in the array as a default value
                  graph.valueField = g.valueField || Object.keys(o.data[0])[1];
                  graph.balloonText = '[[category]]: [[value]]';
                  if (g) {
                    var keys = Object.keys(g);
                    // iterate over all of the properties in the graph object and apply them to the new AmGraph
                    for (var i = 0; i < keys.length; i++) {
                      graph[keys[i]] = g[keys[i]];
                    }
                  }
                  chart.addGraph(graph);
                };

                // create the graphs
                if (o.graphs && o.graphs.length > 0) {
                  for (var i = 0; i < o.graphs.length; i++) {
                    addGraph(o.graphs[i]);
                  }
                } else {
                  addGraph();
                }

                var chartCursor = new AmCharts.ChartCursor();
                if (o.chartCursor) {
                  var keys = Object.keys(o.chartCursor);
                  for (var i = 0; i < keys.length; i++) {
                    if (typeof o.chartCursor[keys[i]] !== 'object') {
                      chartCursor[keys[i]] = o.chartCursor[keys[i]];
                    }
                  }
                }
                chart.addChartCursor(chartCursor);

                if (o.chartScrollbar) {
                  var scrollbar = new AmCharts.ChartScrollbar();
                  var keys = Object.keys(o.chartScrollbar);
                  for (var i = 0; i < keys.length; i++) {
                    scrollbar[keys[i]] = o.chartScrollbar[keys[i]];
                  }
                  chart.chartScrollbar = scrollbar;
                }
              }

              function generatePieProperties() {
                if (o.balloon) {
                  var balloon = new AmBalloon();
                  var keys = Object.keys(o.chartScrollbar);
                  var keys = Object.keys(o.chartScrollbar);
                  for (var i = 0; i < keys.length; i++) {
                    balloon[keys[i]] = o.balloon[keys[i]];
                  }
                  chart.balloon = balloon;
                }
              }

              if (o.legend) {
                var legend = new AmCharts.AmLegend();
                var keys = Object.keys(o.legend);
                for (var i = 0; i < keys.length; i++) {
                  legend[keys[i]] = o.legend[keys[i]];
                }
                chart.legend = legend;
              }

              if (o.type === 'pie') {
                generatePieProperties();
              } else {
                generateGraphProperties();
              }

              if (o.titles) {
                for (var i = 0;i < o.titles.length;i++) {
                  var title = o.titles[i];
                  chart.addTitle(title.text, title.size, title.color, title.alpha, title.bold);
                };
              }

              // WRITE
              chart.write(id);

            });
        }; //renderchart

        // Render the chart
        renderChart();

        // EVENTS =========================================================================

        $scope.$on('amCharts.triggerChartAnimate', function (event, id) {
          if (id === $el[0].id || !id) {
            chart.animateAgain();
          }
        });

        $scope.$on('amCharts.updateData', function (event, data, id) {
          if (id === $el[0].id || !id) {
            chart.dataProvider = data;
            chart.validateData();
          }

        });

        $scope.$on('amCharts.validateNow', function (event, validateData, skipEvents, id) {
          if (id === $el[0].id || !id) {
            chart.validateNow(validateData === undefined ? true : validateData,
              skipEvents === undefined ? false : skipEvents);
          }
        });

        $scope.$on('amCharts.renderChart', function (event, amChartOptions, id) {
          if (id === $el[0].id || !id) {
            renderChart(amChartOptions);
          }
        });
      }
    }
  };
}]);
<commit_msg>Fix balloon config<commit_after>'use strict';
// 1.0.3

angular.module('amChartsDirective', []).directive('amChart', ['$q', function ($q) {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      options: '=',
      height: '=',
      width: '='
    },
    template: '

',
    link: function ($scope, $el) {

      // use existing outer id to create new id
      var id = $el[0].id;
      $el.attr('id', id);
      var chart;

      // we can't render a chart without any data
      if ($scope.options.data) {
        var renderChart = function (amChartOptions) {
          var o = amChartOptions || $scope.options;

          // set height and width
          var height = $scope.height || '100%';
          var width = $scope.width || '100%';

          $el.css({
            'height': height,
            'width': width
          });

          // instantiate new chart object
          if (o.type === 'xy') {
            chart = o.theme ? new AmCharts.AmXYChart(AmCharts.themes[o.theme]) : new AmCharts.AmXYChart();
          } else if (o.type === 'pie') {
            chart = o.theme ? new AmCharts.AmPieChart(AmCharts.themes[o.theme]) : new AmCharts.AmPieChart();
          } else {
            chart = o.theme ? new AmCharts.AmSerialChart(AmCharts.themes[o.theme]) : new AmCharts.AmSerialChart();
          }

          /** set some default values that amCharts doesnt provide **/
          $q.when(o.data)
            .then(function (data) {

              chart.dataProvider = data;
              // if a category field is not specified, attempt to use the first field from an object in the array
              chart.categoryField = o.categoryField || Object.keys(o.data[0])[0];
              chart.startDuration = 0.5; // default animation length, because everyone loves a little pizazz

              // AutoMargin is on by default, but the default 20px all around seems to create unnecessary white space around the control
              chart.autoMargins = true;
              chart.marginTop = 0;
              chart.marginLeft = 0;
              chart.marginBottom = 0;
              chart.marginRight = 0;

              // modify default creditsPosition
              chart.creditsPosition = 'top-right';

              var chartKeys = Object.keys(o);
              for (var i = 0; i < chartKeys.length; i++) {
                if (typeof o[chartKeys[i]] !== 'object' && typeof o[chartKeys[i]] !== 'function') {
                  chart[chartKeys[i]] = o[chartKeys[i]];
                }
              }

              function generateGraphProperties(data) {
                // Assign Category Axis Properties
                if (o.categoryAxis) {
                  var categoryAxis = chart.categoryAxis;

                  if (categoryAxis) {
                    /* if we need to create any default values, we should assign them here */
                    categoryAxis.parseDates = true;

                    var keys = Object.keys(o.categoryAxis);
                    for (var i = 0; i < keys.length; i++) {
                      if (!angular.isObject(o.categoryAxis[keys[i]]) || angular.isArray(o.categoryAxis[keys[i]])) {
                        categoryAxis[keys[i]] = o.categoryAxis[keys[i]];
                      } else {
                        console.log('Stripped categoryAxis obj ' + keys[i]);
                      }
                    }
                    chart.categoryAxis = categoryAxis;
                  }
                }

                // Create value axis

                /* if we need to create any default values, we should assign them here */

                var addValueAxis = function (a) {
                  var valueAxis = new AmCharts.ValueAxis();

                  var keys = Object.keys(a);
                  for (var i = 0; i < keys.length; i++) {
                    if (typeof a[keys[i]] !== 'object') {
                      valueAxis[keys[i]] = a[keys[i]];
                    }
                  }
                  chart.addValueAxis(valueAxis);
                };

                if (o.valueAxes && o.valueAxes.length > 0) {
                  for (var i = 0; i < o.valueAxes.length; i++) {
                    addValueAxis(o.valueAxes[i]);
                  }
                }

                //reusable function to create graph
                var addGraph = function (g) {
                  var graph = new AmCharts.AmGraph();
                  /** set some default values that amCharts doesnt provide **/
                    // if a category field is not specified, attempt to use the second field from an object in the array as a default value
                  graph.valueField = g.valueField || Object.keys(o.data[0])[1];
                  graph.balloonText = '[[category]]: [[value]]';
                  if (g) {
                    var keys = Object.keys(g);
                    // iterate over all of the properties in the graph object and apply them to the new AmGraph
                    for (var i = 0; i < keys.length; i++) {
                      graph[keys[i]] = g[keys[i]];
                    }
                  }
                  chart.addGraph(graph);
                };

                // create the graphs
                if (o.graphs && o.graphs.length > 0) {
                  for (var i = 0; i < o.graphs.length; i++) {
                    addGraph(o.graphs[i]);
                  }
                } else {
                  addGraph();
                }

                var chartCursor = new AmCharts.ChartCursor();
                if (o.chartCursor) {
                  var keys = Object.keys(o.chartCursor);
                  for (var i = 0; i < keys.length; i++) {
                    if (typeof o.chartCursor[keys[i]] !== 'object') {
                      chartCursor[keys[i]] = o.chartCursor[keys[i]];
                    }
                  }
                }
                chart.addChartCursor(chartCursor);

                if (o.chartScrollbar) {
                  var scrollbar = new AmCharts.ChartScrollbar();
                  var keys = Object.keys(o.chartScrollbar);
                  for (var i = 0; i < keys.length; i++) {
                    scrollbar[keys[i]] = o.chartScrollbar[keys[i]];
                  }
                  chart.chartScrollbar = scrollbar;
                }

                if (o.balloon) {
                  chart.balloon = o.balloon;
                }
              }

              function generatePieProperties() {
                if (o.balloon) {
                  chart.balloon = o.balloon;
                }
              }

              if (o.legend) {
                var legend = new AmCharts.AmLegend();
                var keys = Object.keys(o.legend);
                for (var i = 0; i < keys.length; i++) {
                  legend[keys[i]] = o.legend[keys[i]];
                }
                chart.legend = legend;
              }

              if (o.type === 'pie') {
                generatePieProperties();
              } else {
                generateGraphProperties();
              }

              if (o.titles) {
                for (var i = 0;i < o.titles.length;i++) {
                  var title = o.titles[i];
                  chart.addTitle(title.text, title.size, title.color, title.alpha, title.bold);
                };
              }

              // WRITE
              chart.write(id);

            });
        }; //renderchart

        // Render the chart
        renderChart();

        // EVENTS =========================================================================

        $scope.$on('amCharts.triggerChartAnimate', function (event, id) {
          if (id === $el[0].id || !id) {
            chart.animateAgain();
          }
        });

        $scope.$on('amCharts.updateData', function (event, data, id) {
          if (id === $el[0].id || !id) {
            chart.dataProvider = data;
            chart.validateData();
          }

        });

        $scope.$on('amCharts.validateNow', function (event, validateData, skipEvents, id) {
          if (id === $el[0].id || !id) {
            chart.validateNow(validateData === undefined ? true : validateData,
              skipEvents === undefined ? false : skipEvents);
          }
        });

        $scope.$on('amCharts.renderChart', function (event, amChartOptions, id) {
          if (id === $el[0].id || !id) {
            renderChart(amChartOptions);
          }
        });
      }
    }
  };
}]);
<|endoftext|>


<commit_before>const gulp = require('gulp');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify-es').default;
const clean = require('gulp-clean');
const eslint = require('gulp-eslint');
const gulpIf = require('gulp-if');
const mocha = require('gulp-mocha');
const sourcemaps = require('gulp-sourcemaps');
const livereload = require('gulp-livereload');
const sequence = require('run-sequence');
const symlink = require('gulp-symlink');
const fs = require('fs');
const path = require('path');
const rmdir = require('rmdir');
const yaml = require('gulp-yaml');

gulp.task('lintSrcs', () => {
  return gulp
    .src(['./src/**/*.js'])
    .pipe(
      eslint({
        useEslintrc: true,
        fix: true
      })
    )
    .pipe(eslint.format())
    .pipe(
      gulpIf(file => {
        return file.eslint != null && file.eslint.fixed;
      }, gulp.dest('./src'))
    )
    .pipe(eslint.failAfterError());
});

gulp.task('lintTests', () => {
  return gulp
    .src(['./tests/**/*.js'])
    .pipe(
      eslint({
        emitWarning: true,
        useEslintrc: true,
        fix: true
      })
    )
    .pipe(eslint.format())
    .pipe(
      gulpIf(file => {
        return file.eslint != null && file.eslint.fixed;
      }, gulp.dest('./tests'))
    )
    .pipe(eslint.failAfterError());
});

gulp.task('lint', done => {
  sequence('lintSrcs', 'lintTests', done);
});

gulp.task('clean', () => {
  gulp
    .src([
      './dist/*',
      './dist/*.*',
      './dist',
      './*.tgz',
      './services/environment',
      './services/start_systemd.sh',
      './services/systemd/candy-red.service',
      './services/systemd/environment'
    ])
    .pipe(clean({ force: true }));
});

gulp.task('nodes', () => {
  return Promise.all(
    fs
      .readdirSync('node_modules/')
      .filter(f => f.indexOf('local-node-') === 0)
      .filter(f => {
        try {
          return fs.statSync(`node_modules/${f}`).isDirectory();
        } catch (_) {
          return false;
        }
      })
      .map(f => {
        return new Promise((resolve, reject) =>
          rmdir(`node_modules/${f}`, err => {
            if (err) {
              return reject(err);
            }
            return resolve();
          })
        );
      })
  ).then(() => {
    return gulp.src('./dist/nodes/local-*').pipe(
      symlink(f => {
        return path.join(`node_modules/${f.relative}`);
      })
    );
  });
});

gulp.task('copyResources', () => {
  gulp
    .src([
      './src/**/*.{css,ico,png,html,json,yaml,yml}',
      '!./src/mo/**/*.{yaml,yml}'
    ])
    .pipe(gulp.dest('./dist'));
});

gulp.task('favicons', () => {
  return gulp
    .src('./src/public/images/icon*.png')
    .pipe(gulp.dest('./node_modules/node-red-dashboard/dist'));
});

gulp.task('mo', () => {
  return gulp
    .src(['./src/mo/**/*.{yaml,yml}'])
    .pipe(yaml({ safe: true }))
    .pipe(gulp.dest('./dist/mo'));
});

gulp.task('buildSrcs', ['copyResources', 'mo', 'favicons'], () => {
  return gulp
    .src('./src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(
      babel({
        minified: true,
        compact: true,
        configFile: './.babelrc'
      })
    )
    .on('error', console.error.bind(console))
    .pipe(
      uglify({
        mangle: {},
        compress: {
          dead_code: true,
          drop_debugger: true,
          properties: true,
          unused: true,
          toplevel: true,
          if_return: true,
          drop_console: false,
          conditionals: true,
          unsafe_math: true,
          unsafe: true
        }
      })
    )
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dist'))
    .pipe(livereload());
});

gulp.task('build', done => {
  sequence('buildSrcs', 'nodes', done);
});

gulp.task('copyTestResources', () => {
  gulp
    .src('./tests/**/*.{css,ico,png,html,json,yaml,yml}')
    .pipe(gulp.dest('./dist'));
});

gulp.task('buildTests', ['buildSrcs', 'copyTestResources'], () => {
  return gulp
    .src('./tests/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(babel({ configFile: './.babelrc' }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dist'));
});

gulp.task('watch', ['build'], () => {
  livereload.listen();
  gulp.watch('./src/*.js', ['build']);
});

gulp.task('runTests', () => {
  return gulp
    .src(['./dist/**/*.test.js'], { read: false })
    .pipe(
      mocha({
        require: ['source-map-support/register'],
        reporter: 'spec'
      })
    )
    .once('error', () => process.exit(1))
    .once('end', () => process.exit());
});

gulp.task('test', done => {
  sequence('lint', 'buildTests', 'runTests', done);
});

gulp.task('default', ['build']);
<commit_msg>Fix the wrong path to mo files<commit_after>const gulp = require('gulp');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify-es').default;
const clean = require('gulp-clean');
const eslint = require('gulp-eslint');
const gulpIf = require('gulp-if');
const mocha = require('gulp-mocha');
const sourcemaps = require('gulp-sourcemaps');
const livereload = require('gulp-livereload');
const sequence = require('run-sequence');
const symlink = require('gulp-symlink');
const fs = require('fs');
const path = require('path');
const rmdir = require('rmdir');
const yaml = require('gulp-yaml');

gulp.task('lintSrcs', () => {
  return gulp
    .src(['./src/**/*.js'])
    .pipe(
      eslint({
        useEslintrc: true,
        fix: true
      })
    )
    .pipe(eslint.format())
    .pipe(
      gulpIf(file => {
        return file.eslint != null && file.eslint.fixed;
      }, gulp.dest('./src'))
    )
    .pipe(eslint.failAfterError());
});

gulp.task('lintTests', () => {
  return gulp
    .src(['./tests/**/*.js'])
    .pipe(
      eslint({
        emitWarning: true,
        useEslintrc: true,
        fix: true
      })
    )
    .pipe(eslint.format())
    .pipe(
      gulpIf(file => {
        return file.eslint != null && file.eslint.fixed;
      }, gulp.dest('./tests'))
    )
    .pipe(eslint.failAfterError());
});

gulp.task('lint', done => {
  sequence('lintSrcs', 'lintTests', done);
});

gulp.task('clean', () => {
  gulp
    .src([
      './dist/*',
      './dist/*.*',
      './dist',
      './*.tgz',
      './services/environment',
      './services/start_systemd.sh',
      './services/systemd/candy-red.service',
      './services/systemd/environment'
    ])
    .pipe(clean({ force: true }));
});

gulp.task('nodes', () => {
  return Promise.all(
    fs
      .readdirSync('node_modules/')
      .filter(f => f.indexOf('local-node-') === 0)
      .filter(f => {
        try {
          return fs.statSync(`node_modules/${f}`).isDirectory();
        } catch (_) {
          return false;
        }
      })
      .map(f => {
        return new Promise((resolve, reject) =>
          rmdir(`node_modules/${f}`, err => {
            if (err) {
              return reject(err);
            }
            return resolve();
          })
        );
      })
  ).then(() => {
    return gulp.src('./dist/nodes/local-*').pipe(
      symlink(f => {
        return path.join(`node_modules/${f.relative}`);
      })
    );
  });
});

gulp.task('copyResources', () => {
  gulp
    .src([
      './src/**/*.{css,ico,png,html,json,yaml,yml}',
      '!./src/device-manager/mo/**/*.{yaml,yml}'
    ])
    .pipe(gulp.dest('./dist'));
});

gulp.task('favicons', () => {
  return gulp
    .src('./src/public/images/icon*.png')
    .pipe(gulp.dest('./node_modules/node-red-dashboard/dist'));
});

gulp.task('mo', () => {
  return gulp
    .src(['./src/device-manager/mo/**/*.{yaml,yml}'])
    .pipe(yaml({ safe: true }))
    .pipe(gulp.dest('./dist/device-manager/mo'));
});

gulp.task('buildSrcs', ['copyResources', 'mo', 'favicons'], () => {
  return gulp
    .src('./src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(
      babel({
        minified: true,
        compact: true,
        configFile: './.babelrc'
      })
    )
    .on('error', console.error.bind(console))
    .pipe(
      uglify({
        mangle: {},
        compress: {
          dead_code: true,
          drop_debugger: true,
          properties: true,
          unused: true,
          toplevel: true,
          if_return: true,
          drop_console: false,
          conditionals: true,
          unsafe_math: true,
          unsafe: true
        }
      })
    )
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dist'))
    .pipe(livereload());
});

gulp.task('build', done => {
  sequence('buildSrcs', 'nodes', done);
});

gulp.task('copyTestResources', () => {
  gulp
    .src('./tests/**/*.{css,ico,png,html,json,yaml,yml}')
    .pipe(gulp.dest('./dist'));
});

gulp.task('buildTests', ['buildSrcs', 'copyTestResources'], () => {
  return gulp
    .src('./tests/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(babel({ configFile: './.babelrc' }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dist'));
});

gulp.task('watch', ['build'], () => {
  livereload.listen();
  gulp.watch('./src/*.js', ['build']);
});

gulp.task('runTests', () => {
  return gulp
    .src(['./dist/**/*.test.js'], { read: false })
    .pipe(
      mocha({
        require: ['source-map-support/register'],
        reporter: 'spec'
      })
    )
    .once('error', () => process.exit(1))
    .once('end', () => process.exit());
});

gulp.task('test', done => {
  sequence('lint', 'buildTests', 'runTests', done);
});

gulp.task('default', ['build']);
<|endoftext|>


<commit_before>/*
 * Create a list with manages list items.
 */
function List() {
    this.items = [];
    this.currentTime = Date.now();
}

(function (static_, proto_) {

    /*
     * Adds an item to the list.
     * Parameter is item.
     */
    proto_.addItem = function (item) {
        this.items.push(item);
        this.items.sort(this._sortFunction.bind(this));
    };

    /*
     * Executes all item callback functions that
     * should've happened now.
     */
    proto_.run = function () {
        this.currentTime = Date.now();

        this.items.forEach(this._forEachItemRun.bind(this));
    };

    /*
     * For each item execute it if the time has
     * passed.
     */
    proto_._forEachItemRun = function (item) {
        if (item.startTime < this.currentTime) {
            item.callback();

            item.executed = true;
        }
    };

    /*
     * Sorts the items in order by their start times.
     */
    proto_._sortFunction = function (itemA, itemB) {
        if (itemA.startTime > itemB.startTime)
            return true;

        return false;
    };

}(List, List.prototype));

module.exports = List;
<commit_msg>Adds method reset for resetting all Item execute booleans<commit_after>/*
 * Create a list with manages list items.
 */
function List() {
    this.items = [];
    this.currentTime = Date.now();
}

(function (static_, proto_) {

    /*
     * Adds an item to the list.
     * Parameter is item.
     */
    proto_.addItem = function (item) {
        this.items.push(item);
        this.items.sort(this._sortFunction.bind(this));
    };

    /*
     * Executes all item callback functions that
     * should've happened now.
     */
    proto_.run = function () {
        this.currentTime = Date.now();

        this.items.forEach(this._forEachItemRun.bind(this));
    };

    /*
     * Resets all item executed booleans.
     */
    proto_.reset = function () {
        this.items.forEach(function (item) {
            item.executed = false;
        });
    };

    /*
     * For each item execute it if the time has
     * passed.
     */
    proto_._forEachItemRun = function (item) {
        if (item.startTime < this.currentTime) {
            item.callback();

            item.executed = true;
        }
    };

    /*
     * Sorts the items in order by their start times.
     */
    proto_._sortFunction = function (itemA, itemB) {
        if (itemA.startTime > itemB.startTime)
            return true;

        return false;
    };

}(List, List.prototype));

module.exports = List;
<|endoftext|>


<commit_before>'use strict';

var controller = require('../controllers');
var helpers = require('../helpers');

module.exports = function(app, express) {
	// ROUTE FOR DISPLAYING DASHBOARD
	app.get('/api/users/:user_id/clients', function(req,res){
		controller.dashboard.get(req,res);
	});

	// ROUTE FOR CREATING A NEW USER
	app.post('/api/users/:user_id/clients', function(req,res){
		 controller.user.post(req,res);
	});

	// ROUTE FOR DISPLAYING PARTICULAR CLIENT
	app.get('/api/users/:user_id/clients/:client_id', function(req,res){
		controller.client.get(req,res);
	})

	// ROUTE FOR CREATING A NEW CLIENT
	// app.post('/api/users/:user_id/clients', function(req,res){
	// 	controller.client.post(req,res);
	// })

  // ROUTE FOR UPDATING A CLIENT
	app.put('/api/users/:user_id/clients/:client_id', controller.client.put);

	// ROUTE FOR GETTING FEED FOR A PARTICULAR CLIENT
	app.get('/api/users/:user_id/clients/:client_id/feed', function(req,res){
		// SOMEHOW GET THE CLIENT RECORD FROM CLIENT DATABASE
		// LOOK AT THE COLUMNS IN THE CLIENT RECORD, CREATE A PARAMS OBJECT BASED ON THAT
		// SEND THAT TO CONTROLLER.FEED.GET
		// PARAMS OBJ: {'client_company':'Togos', 'client_zipcode':'94303'}

		controller.feed.getOneClient(req,res);
	})
};<commit_msg>adds route to reset the db with demo data<commit_after>'use strict';

var controller = require('../controllers');
var helpers = require('../helpers');

module.exports = function(app, express) {
	// ROUTE FOR RESETTING DB WITH DEMO DATA
	app.get('/api/resetDBWithData', function(req, res){
		controller.client.reset();
		controller.user.reset();
		res.send('success');
	});

	// ROUTE FOR DISPLAYING DASHBOARD
	app.get('/api/users/:user_id/clients', function(req,res){
		controller.dashboard.get(req,res);
	});

	// ROUTE FOR CREATING A NEW USER
	app.post('/api/users/:user_id/clients', function(req,res){
		 controller.user.post(req,res);
	});

	// ROUTE FOR DISPLAYING PARTICULAR CLIENT
	app.get('/api/users/:user_id/clients/:client_id', function(req,res){
		controller.client.get(req,res);
	});

	// ROUTE FOR CREATING A NEW CLIENT
	// app.post('/api/users/:user_id/clients', function(req,res){
	// 	controller.client.post(req,res);
	// })

  // ROUTE FOR UPDATING A CLIENT
	app.put('/api/users/:user_id/clients/:client_id', controller.client.put);

	// ROUTE FOR GETTING FEED FOR A PARTICULAR CLIENT
	app.get('/api/users/:user_id/clients/:client_id/feed', function(req,res){
		// SOMEHOW GET THE CLIENT RECORD FROM CLIENT DATABASE
		// LOOK AT THE COLUMNS IN THE CLIENT RECORD, CREATE A PARAMS OBJECT BASED ON THAT
		// SEND THAT TO CONTROLLER.FEED.GET
		// PARAMS OBJ: {'client_company':'Togos', 'client_zipcode':'94303'}

		controller.feed.getOneClient(req,res);
	})
};
<|endoftext|>


<commit_before>'use strict'
var cleanup = require('rollup-plugin-cleanup');
var { src, dest, series, parallel } = require('gulp');
var insert = require('gulp-insert');
var mocha = require('gulp-mocha');
var nodeResolve = require('rollup-plugin-node-resolve');
var rename = require('gulp-rename');
var rollup = require('rollup');
var rollupTypescript = require('rollup-plugin-typescript');
var typescript = require('typescript');
var uglify = require('gulp-uglify');

var items = [
    require('./build/npm/navigation/package.json'),
    Object.assign({ globals: { navigation: 'Navigation', react: 'React',
            'react-dom': 'ReactDOM' } },
        require('./build/npm/navigation-react/package.json')),
    Object.assign({ globals: { navigation: 'Navigation',
            'navigation-react': 'NavigationReact', react: 'React' } },
        require('./build/npm/navigation-react-mobile/package.json')),
    Object.assign({ globals: { navigation: 'Navigation', react: 'React',
            'navigation-react': 'NavigationReact', 'react-native': 'ReactNative' },
            format: 'es' },
        require('./build/npm/navigation-react-native/package.json')),
];
function rollupTask(name, input, file, globals, format) {
    return rollup.rollup({
        input,
        external: Array.isArray(globals) ? globals : Object.keys(globals),
        plugins: [
            rollupTypescript({
                typescript: typescript,
                importHelpers: true,
                target: 'es3',
                module: 'es6',
                jsx: 'react'
            }),
            nodeResolve({ jsnext: true, main: true }),
            cleanup()
        ]
    }).then((bundle) => bundle.write({ format, name, globals, file }));
}
function buildTask(name, input, file, globals, details) {
    var info = `/**
 * ${details.name} v${details.version}
 * (c) Graham Mendick - ${details.homepage}
 * License: ${details.license}
 */
`;
    return rollupTask(name, input, file, globals, 'iife')
        .then(() => (
            src(file)
                .pipe(insert.prepend(info))
                .pipe(dest('./build/dist'))
                .pipe(rename(file.replace(/js$/, 'min.js')))
                .pipe(uglify({ mangle: { reserved: details.reserved } }))
                .pipe(insert.prepend(info))
                .pipe(dest('.'))
        ));
}
var packageNative = () => {
    var nativeFolders = ['android', 'ios']
        .map(folder => `./NavigationReactNative/src/${folder}/**/*`);
    return src(nativeFolders, {base: './NavigationReactNative/src'})
        .pipe(dest('./build/npm/navigation-react-native'));
};
var nameFunc = (func, name) => {
    func.displayName = name;
    return func;
};
var itemTasks = items.reduce((tasks, item) => {
    var packageName = item.name;
    var upperName = packageName.replace(/\b./g, (val) => val.toUpperCase());
    var name = upperName.replace(/-/g, '');
    var tsFrom = './' + name + '/src/' + name + '.ts';
    var jsTo = './build/dist/' + packageName.replace(/-/g, '.') + '.js';
    var jsPackageTo = './build/npm/' + packageName + '/' + packageName.replace(/-/g, '.') + '.js';
    item.name = upperName.replace(/-/g, ' ');
    var { globals = {}, format = 'cjs' } = item;
    tasks.buildTasks.push(
        nameFunc(() => buildTask(name, tsFrom, jsTo, globals, item), 'build' + name));
    tasks.packageTasks.push(
        nameFunc(() => rollupTask(name, tsFrom, jsPackageTo, globals, format), 'package' + name)
    );
    return tasks;
}, { buildTasks: [], packageTasks: [] });

var tests = [
    { name: 'NavigationRouting', to: 'navigationRouting.test.js' },
    { name: 'StateConfig', to: 'stateConfig.test.js' },
    { name: 'Navigation', to: 'navigation.test.js' },
    { name: 'NavigationData', to: 'navigationData.test.js' },
    { name: 'FluentNavigation', to: 'fluentNavigation.test.js' },
    { name: 'NavigationLink', to: 'navigationLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'NavigationBackLink', to: 'navigationBackLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'RefreshLink', to: 'refreshLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'FluentLink', to: 'fluentLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'UseScene', to: 'useScene.test.js', folder: 'ReactMobile', ext: 'tsx' }
];
function testTask(name, input, file) {
    var globals = [
        'assert', 'react', 'react-dom', 'react-dom/test-utils', 'jsdom',
        'tslib', 'navigation', 'navigation-react',  'navigation-react-mobile'
    ];
    return rollupTask(name, input, file, globals, 'cjs')
        .then(() =>
            src(file)
                .pipe(mocha({ reporter: 'progress' }))
                .on('error', err => console.log(err.message))
        );
}
var testTasks = tests.reduce((tasks, test) => {
    var folder = './Navigation' + (test.folder || '') + '/test/';
    var file = folder + test.name + 'Test.' + (test.ext || 'ts');
    var to = './build/dist/' + test.to;
    tasks.push(nameFunc(() => testTask(test.name, file, to), 'test' + test.name));
    return tasks;
}, []);
var packageDeps = parallel(
    itemTasks.packageTasks.find(({displayName}) => displayName === 'packageNavigation'),
    itemTasks.packageTasks.find(({displayName}) => displayName === 'packageNavigationReact'),
    itemTasks.packageTasks.find(({displayName}) => displayName === 'packageNavigationReactMobile')
);
exports.build = parallel(...itemTasks.buildTasks);
exports.package = parallel(packageNative, ...itemTasks.packageTasks);
exports.test = series(packageDeps, parallel(...testTasks));

<commit_msg>Renamed test entry to match file name<commit_after>'use strict'
var cleanup = require('rollup-plugin-cleanup');
var { src, dest, series, parallel } = require('gulp');
var insert = require('gulp-insert');
var mocha = require('gulp-mocha');
var nodeResolve = require('rollup-plugin-node-resolve');
var rename = require('gulp-rename');
var rollup = require('rollup');
var rollupTypescript = require('rollup-plugin-typescript');
var typescript = require('typescript');
var uglify = require('gulp-uglify');

var items = [
    require('./build/npm/navigation/package.json'),
    Object.assign({ globals: { navigation: 'Navigation', react: 'React',
            'react-dom': 'ReactDOM' } },
        require('./build/npm/navigation-react/package.json')),
    Object.assign({ globals: { navigation: 'Navigation',
            'navigation-react': 'NavigationReact', react: 'React' } },
        require('./build/npm/navigation-react-mobile/package.json')),
    Object.assign({ globals: { navigation: 'Navigation', react: 'React',
            'navigation-react': 'NavigationReact', 'react-native': 'ReactNative' },
            format: 'es' },
        require('./build/npm/navigation-react-native/package.json')),
];
function rollupTask(name, input, file, globals, format) {
    return rollup.rollup({
        input,
        external: Array.isArray(globals) ? globals : Object.keys(globals),
        plugins: [
            rollupTypescript({
                typescript: typescript,
                importHelpers: true,
                target: 'es3',
                module: 'es6',
                jsx: 'react'
            }),
            nodeResolve({ jsnext: true, main: true }),
            cleanup()
        ]
    }).then((bundle) => bundle.write({ format, name, globals, file }));
}
function buildTask(name, input, file, globals, details) {
    var info = `/**
 * ${details.name} v${details.version}
 * (c) Graham Mendick - ${details.homepage}
 * License: ${details.license}
 */
`;
    return rollupTask(name, input, file, globals, 'iife')
        .then(() => (
            src(file)
                .pipe(insert.prepend(info))
                .pipe(dest('./build/dist'))
                .pipe(rename(file.replace(/js$/, 'min.js')))
                .pipe(uglify({ mangle: { reserved: details.reserved } }))
                .pipe(insert.prepend(info))
                .pipe(dest('.'))
        ));
}
var packageNative = () => {
    var nativeFolders = ['android', 'ios']
        .map(folder => `./NavigationReactNative/src/${folder}/**/*`);
    return src(nativeFolders, {base: './NavigationReactNative/src'})
        .pipe(dest('./build/npm/navigation-react-native'));
};
var nameFunc = (func, name) => {
    func.displayName = name;
    return func;
};
var itemTasks = items.reduce((tasks, item) => {
    var packageName = item.name;
    var upperName = packageName.replace(/\b./g, (val) => val.toUpperCase());
    var name = upperName.replace(/-/g, '');
    var tsFrom = './' + name + '/src/' + name + '.ts';
    var jsTo = './build/dist/' + packageName.replace(/-/g, '.') + '.js';
    var jsPackageTo = './build/npm/' + packageName + '/' + packageName.replace(/-/g, '.') + '.js';
    item.name = upperName.replace(/-/g, ' ');
    var { globals = {}, format = 'cjs' } = item;
    tasks.buildTasks.push(
        nameFunc(() => buildTask(name, tsFrom, jsTo, globals, item), 'build' + name));
    tasks.packageTasks.push(
        nameFunc(() => rollupTask(name, tsFrom, jsPackageTo, globals, format), 'package' + name)
    );
    return tasks;
}, { buildTasks: [], packageTasks: [] });

var tests = [
    { name: 'NavigationRouting', to: 'navigationRouting.test.js' },
    { name: 'StateConfig', to: 'stateConfig.test.js' },
    { name: 'Navigation', to: 'navigation.test.js' },
    { name: 'NavigationData', to: 'navigationData.test.js' },
    { name: 'FluentNavigation', to: 'fluentNavigation.test.js' },
    { name: 'NavigationLink', to: 'navigationLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'NavigationBackLink', to: 'navigationBackLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'RefreshLink', to: 'refreshLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'FluentLink', to: 'fluentLink.test.js', folder: 'React', ext: 'tsx' },
    { name: 'UseSceneNavigating', to: 'useSceneNavigating.test.js', folder: 'ReactMobile', ext: 'tsx' }
];
function testTask(name, input, file) {
    var globals = [
        'assert', 'react', 'react-dom', 'react-dom/test-utils', 'jsdom',
        'tslib', 'navigation', 'navigation-react',  'navigation-react-mobile'
    ];
    return rollupTask(name, input, file, globals, 'cjs')
        .then(() =>
            src(file)
                .pipe(mocha({ reporter: 'progress' }))
                .on('error', err => console.log(err.message))
        );
}
var testTasks = tests.reduce((tasks, test) => {
    var folder = './Navigation' + (test.folder || '') + '/test/';
    var file = folder + test.name + 'Test.' + (test.ext || 'ts');
    var to = './build/dist/' + test.to;
    tasks.push(nameFunc(() => testTask(test.name, file, to), 'test' + test.name));
    return tasks;
}, []);
var packageDeps = parallel(
    itemTasks.packageTasks.find(({displayName}) => displayName === 'packageNavigation'),
    itemTasks.packageTasks.find(({displayName}) => displayName === 'packageNavigationReact'),
    itemTasks.packageTasks.find(({displayName}) => displayName === 'packageNavigationReactMobile')
);
exports.build = parallel(...itemTasks.buildTasks);
exports.package = parallel(packageNative, ...itemTasks.packageTasks);
exports.test = series(packageDeps, parallel(...testTasks));

<|endoftext|>


<commit_before>"use strict";
/**
 * Geoprocessing utilities for doing spatial analysis within the Google Maps API.
 * All they really provide is hit testing, so we'll expand that to include any
 * standard geoprocessing algorithms that we need.
 * See https://developers.google.com/maps/documentation/javascript/3.exp/reference#spherical
 * and https://developers.google.com/maps/documentation/javascript/3.exp/reference#poly
 */
define({

    /**
     * Calculates a bounding box for a google.maps.Polygon
     * @param polygon
     * @returns google.maps.LatLngBounds representing the minimum bounding rectangle
     */
    bounds: function (polygon) {
        var minx = 180, maxx = -180, miny = 90, maxy = -90;
        polygon.getPath().forEach(function (ltlng) {
            var lng = ltlng.lng(),
                lat = ltlng.lat();
            minx = Math.min(minx, lng);
            maxx = Math.max(maxx, lng);
            miny = Math.min(miny, lat);
            maxy = Math.max(maxy, lat);
        });

        return new google.maps.LatLngBounds(
            new google.maps.LatLng(minx, miny),
            new google.maps.LatLng(maxx, maxy)
        );

    },

    /**
     * Joins a set of points into a set of polygons.
     * Note that for now it simply sums the point count and adds it as a property to the polygon Feature.
     * @param {Feature[]} polygons - array of Features that represent the polygons to check points against.
     * @param {Feature[]} points - array of Features that represent the points to bin into polygons.
     * @param {String} property - property name to store the point count value
     */
    spatialJoinWithin: function (polygons, points, property) {

        var start = Date.now(),
            getBounds = this.bounds,
            polyCount = 0,
            comparisonCount = 0;

        //sort ascending x, so we can short-circuit hit test loops
        //this lets us only do an actual hit test on points within a longitude "band",
        //which saves quite a bit of time
        points.sort(function (p1, p2) {
            return p1.getGeometry().get().lng() - p2.getGeometry().get().lng();
        });

        //finds first index greater than lng
        function findMinIndex(points, lng) {
            //TODO: replace this with a binary search
            for (var i = 0; i < points.length; i += 1) {
                if (points[i].getGeometry().get().lng() >= lng) {
                    return i;
                }
            }
            return 0;
        }

        polygons.forEach(function (polygon) {

            var count = 0,
                poly,
                bounds,
                index,
                point,
                i;

            try {

                //need to convert data polygons to base polygons for containsLocation
                poly = new google.maps.Polygon({
                        paths: polygon.getGeometry().getArray().map(function (ring) {
                            return ring.getArray();
                        })
                    });

                bounds = getBounds(poly);

                index = findMinIndex(points, bounds.getSouthWest().lng());

                for (i = index; i < points.length; i += 1) {

                    point = points[i];
                    comparisonCount += 1;

                    try {
                        var pointLtLng = point.getGeometry().get(),
                            lng = pointLtLng.lng(),
                            contained;

                        contained = google.maps.geometry.poly.containsLocation(pointLtLng, poly);

                        if (contained) {
                            count += 1;
                        } else if (lng > bounds.getNorthEast().lng()) {
                            break;
                        }

                    } catch (e) {
                        //ignore bad points
                        console.log('Error with point ' + point.getId());
                    }

                }

                polyCount += 1;

            } catch (e) {
                //some of the census data may have unsupported geometry for this simple analysis (e.g., donuts)
                console.log('Error joining with polygon ' + polygon.getId());
            } finally {
                polygon.setProperty(property, count);
            }

        });

        console.log('successful polygons ' + polyCount);
        console.log('comparisons: ' + comparisonCount + ' (out of ' + (polygons.length * points.length) + ' brute force)');
        console.log('spatial join: ' + (Date.now() - start) + 'ms');

    }

});<commit_msg>added a modified binary search to find minimum x indices faster<commit_after>"use strict";
/**
 * Geoprocessing utilities for doing spatial analysis within the Google Maps API.
 * All they really provide is hit testing, so we'll expand that to include any
 * standard geoprocessing algorithms that we need.
 * See https://developers.google.com/maps/documentation/javascript/3.exp/reference#spherical
 * and https://developers.google.com/maps/documentation/javascript/3.exp/reference#poly
 */
define({

    /**
     * Calculates a bounding box for a google.maps.Polygon
     * @param polygon
     * @returns google.maps.LatLngBounds representing the minimum bounding rectangle
     */
    bounds: function (polygon) {
        var minx = 180, maxx = -180, miny = 90, maxy = -90;
        polygon.getPath().forEach(function (ltlng) {
            var lng = ltlng.lng(),
                lat = ltlng.lat();
            minx = Math.min(minx, lng);
            maxx = Math.max(maxx, lng);
            miny = Math.min(miny, lat);
            maxy = Math.max(maxy, lat);
        });

        return new google.maps.LatLngBounds(
            new google.maps.LatLng(miny, minx),
            new google.maps.LatLng(maxy, maxx)
        );

    },

    //finds minimum index in an array of sorted points that meets the specified long.
    //performs a modified binary search that accounts for non-exact match of longs.
    minimumLngIndex: function (points, bounds) {

        var min = 0,
            max = points.length - 1,
            lng = bounds.getSouthWest().lng(),
            index,
            plng;

        while (min <= max) {
            index = Math.floor((min + max) / 2);
            plng = points[index].getGeometry().get().lng();
            if (plng < lng) {
                min = index + 1;
            } else if (plng >= lng) {
                if (index === 0) {
                    return index;
                } else if (points[index - 1].getGeometry().get().lng() > lng) {
                    max = index - 1;
                } else {
                    return index;
                }
            }
        }

        return 0;

    },

    /**
     * Joins a set of points into a set of polygons.
     * Note that for now it simply sums the point count and adds it as a property to the polygon Feature.
     * @param {Feature[]} polygons - array of Features that represent the polygons to check points against.
     * @param {Feature[]} points - array of Features that represent the points to bin into polygons.
     * @param {String} property - property name to store the point count value
     */
    spatialJoinWithin: function (polygons, points, property) {

        var start = Date.now(),
            getBounds = this.bounds,
            getMinX = this.minimumLngIndex,
            polyCount = 0,
            comparisonCount = 0;

        //sort ascending x, so we can short-circuit hit test loops
        //this lets us only do an actual hit test on points within a longitude "band",
        //which saves quite a bit of time
        points.sort(function (p1, p2) {
            return p1.getGeometry().get().lng() - p2.getGeometry().get().lng();
        });

        polygons.forEach(function (polygon) {

            var count = 0,
                poly,
                bounds,
                index,
                point,
                i;

            try {

                //need to convert data polygons to base polygons for containsLocation
                poly = new google.maps.Polygon({
                        paths: polygon.getGeometry().getArray().map(function (ring) {
                            return ring.getArray();
                        })
                    });

                bounds = getBounds(poly);
                index = getMinX(points, bounds);

                for (i = index; i < points.length; i += 1) {

                    point = points[i];
                    comparisonCount += 1;

                    try {
                        var pointLtLng = point.getGeometry().get(),
                            lng = pointLtLng.lng(),
                            contained;

                        contained = google.maps.geometry.poly.containsLocation(pointLtLng, poly);

                        if (contained) {
                            count += 1;
                        } else if (lng > bounds.getNorthEast().lng()) {
                            break;
                        }

                    } catch (e) {
                        //ignore bad points
                        console.log('Error with point ' + point.getId());
                    }

                }

                polyCount += 1;

            } catch (e) {
                //some of the census data may have unsupported geometry for this simple analysis (e.g., donuts)
                console.log('Error joining with polygon ' + polygon.getId());
            } finally {
                polygon.setProperty(property, count);
            }

        });

        console.log('successful polygons ' + polyCount);
        console.log('comparisons: ' + comparisonCount + ' (out of ' + (polygons.length * points.length) + ' brute force)');
        console.log('spatial join: ' + (Date.now() - start) + 'ms');

    }

});<|endoftext|>


<commit_before>/*eslint-env node */
/*eslint object-shorthand: 0 quote-props: 0 */
const fs = require('fs');
const path = require('path');

const fsPlus = require('fs-plus');
const gobble = require('gobble');
const sander = gobble.sander;
const buble = require('buble');
const rollupLib = require('rollup');

const time = new Date();
const commitHash = process.env.COMMIT_HASH || 'unknown';
const version = require('./package.json').version;
const banner = `/*
	Ractive.js v${version}
	Build: ${commitHash}
	Date: ${time}
	Website: http://ractivejs.org
	License: MIT
*/`;

const runtimeModulesToIgnore = ['src/parse/_parse.js'];
const placeholders = {
	BUILD_PLACEHOLDER_VERSION: version
};

const src = gobble('src').moveTo('src').transform(transpile, { accept: ['.js'] }).transform(replacePlaceholders);
const tests = gobble('tests').include(['helpers/**/*', 'browser/**/*', 'node/**/*']).moveTo('tests').transform(transpile, { accept: ['.js'] });
const browserTests = gobble([src, tests.include(['tests/helpers/**/*', 'tests/browser/**/*'])]);
const nodeTests = gobble([src, tests.include(['tests/helpers/**/*', 'tests/node/**/*'])]);
const manifest = gobble('templates/manifests').transform(replacePlaceholders);
const qunit = gobble('templates/qunit').moveTo('tests');
const bin = gobble('bin').moveTo('bin');
const lib = gobble('lib').moveTo('lib');
const typings = gobble('typings').moveTo('typings');
const sandbox = gobble('sandbox');
const polyfills = src.transform(copy, { dir: 'src' }).include(['polyfills.js']);

module.exports = ({
	'dev:browser'() {
		const lib = buildUmdLib('ractive.js', []);
		const tests = buildBrowserTests();
		const polyfills = buildUmdPolyfill();
		return gobble([lib, polyfills, tests, sandbox, qunit]);
	},
	'production'() {
		const libEsFull = buildESLib('ractive.mjs', []);
		const libEsRuntime = buildESLib('runtime.mjs', runtimeModulesToIgnore);

		const libUmdFull = buildUmdLib('ractive.js', []);
		const libUmdRuntime = buildUmdLib('runtime.js', runtimeModulesToIgnore);

		const libEs = gobble([libEsFull, libEsRuntime]);
		const libUmd = gobble([libUmdFull, libUmdRuntime]);
		const libUmdMin = libUmd.transform('uglifyjs', { ext: '.min.js', preamble: banner });

		const polyfillEs = buildESPolyfill();
		const polyfillUmd = buildUmdPolyfill();
		const polyfillUmdMin = polyfillUmd.transform('uglifyjs', { ext: '.min.js' });

		const browserTests = buildBrowserTests();
		const nodeTests = buildNodeTests();

		return gobble([libEs, libUmd, libUmdMin, polyfillEs, polyfillUmd, polyfillUmdMin, qunit, browserTests, nodeTests, bin, lib, typings, manifest]);
	}
})[gobble.env()]();

////////////////////////////////////////////////////////////////////////////////

/* Bundle builders */

// Builds a UMD bundle of Ractive
function buildUmdLib(dest, excludedModules) {
	return src.transform(rollup, {
		plugins: [skipModule(excludedModules)],
		moduleName: 'Ractive',
		format: 'umd',
		entry: 'src/Ractive.js',
		dest: dest,
		banner: banner,
		noConflict: true,
		cache: false
	});
}

// Builds an ES bundle of Ractive
function buildESLib(dest, excludedModules) {
	return src.transform(rollup, {
		plugins: [skipModule(excludedModules)],
		format: 'es',
		entry: 'src/Ractive.js',
		dest: dest,
		banner: banner,
		cache: false
	});
}

// Builds a UMD bundle for browser/PhantomJS tests.
function buildBrowserTests() {
	return gobble([
		browserTests,
		browserTests.transform(buildTestEntryPoint, { dir: 'tests/browser' })
	])
		.transform(copy)
		.transform(rollup, {
			moduleName: 'RactiveBrowserTests',
			format: 'iife',
			entry: 'tests.js',
			dest: 'browser.js',
			globals: {
				qunit: 'QUnit',
				simulant: 'simulant'
			},
			external: ['qunit', 'simulant'],
			cache: false
		}).moveTo('tests');
}

// Builds a CJS bundle for node tests.
function buildNodeTests() {
	return gobble([
		nodeTests,
		nodeTests.transform(buildTestEntryPoint, { dir: 'tests/node' })
	])
		.transform(copy)
		.transform(rollup, {
			format: 'cjs',
			entry: 'tests.js',
			dest: 'node.js',
			external: ['cheerio'],
			cache: false
		}).moveTo('tests');
}

function buildUmdPolyfill() {
	return polyfills.transform(rollup, {
		moduleName: 'RactivePolyfills',
		format: 'umd',
		entry: 'polyfills.js',
		dest: 'polyfills.js',
		cache: false
	});
}

function buildESPolyfill() {
	return polyfills.transform(rollup, {
		format: 'es',
		entry: 'polyfills.js',
		dest: 'polyfills.mjs',
		cache: false
	});
}

/* Rollup plugins */

// Replaces a modules content with a null export to omit module contents.
// TODO: Must return sourcemap
function skipModule(excludedModules) {
	return {
		name: 'skipModule',
		transform: function (src, modulePath) {
			// Gobble has a predictable directory structure of gobble/transform/number
			// so we slice at 3 to slice relative to project root.
			const moduleRelativePath = path.relative(__dirname, modulePath).split(path.sep).slice(3).join(path.sep);
			return excludedModules.indexOf(moduleRelativePath) > -1 ? 'export default null; export const shared = {};' : src;
		}
	};
}

/* Gobble transforms */

// Essentially gobble-buble but takes out the middleman.
function transpile(src, options) {
	return buble.transform(src, {
		target: { ie: 9 },
		transforms: { modules: false }
	});
}

// Builds an entrypoint in the designated directory that imports all test specs
// and calls them one after the other in tree-listing order.
function buildTestEntryPoint(inDir, outDir, options) {
	const _options = Object.assign({ dir: '' }, options);
	const testPaths = fsPlus.listTreeSync(path.join(inDir, _options.dir)).filter(testPath => fsPlus.isFileSync(testPath) && path.extname(testPath) === '.js');
	const testImports = testPaths.map((testPath, index) => `import test${index} from './${path.relative(inDir, testPath).replace(/\\/g, '/')}';`).join('\n');
	const testCalls = testPaths.map((testPath, index) => `test${index}();`).join('\n');
	fs.writeFileSync(path.join(outDir, 'tests.js'), `${testImports}\n${testCalls}`, 'utf8');
	return Promise.resolve();
}

// Looks for placeholders in the code and replaces them.
// TODO: Must return sourcemap
function replacePlaceholders(src, options) {
	return Object.keys(placeholders).reduce((out, placeholder) => {
		return out.replace(new RegExp(`${placeholder}`, 'g'), placeholders[placeholder]);
	}, src);
}

// This is because Gobble's grab and Rollup's resolution is broken
// https://github.com/gobblejs/gobble/issues/89
// https://github.com/rollup/rollup/issues/1291
function copy(inputdir, outputdir, options) {
	const _options = Object.assign({ dir: '.' }, options);
	fsPlus.copySync(path.join(inputdir, _options.dir), outputdir);
	return Promise.resolve();
}

function rollup(indir, outdir, options) {
	if (!options.entry) throw new Error('You must supply `options.entry`');

	options.dest = path.resolve(outdir, options.dest || options.entry);
	options.entry = path.resolve(indir, options.entry);

	return rollupLib.rollup(options).then(function(bundle) {
		return bundle.write(options);
	});
}
<commit_msg>Create dedicated test bundler gobble script<commit_after>/*eslint-env node */
/*eslint object-shorthand: 0 quote-props: 0 */
const fs = require('fs');
const path = require('path');

const fsPlus = require('fs-plus');
const gobble = require('gobble');
const sander = gobble.sander;
const buble = require('buble');
const rollupLib = require('rollup');

const time = new Date();
const commitHash = process.env.COMMIT_HASH || 'unknown';
const version = require('./package.json').version;
const banner = `/*
	Ractive.js v${version}
	Build: ${commitHash}
	Date: ${time}
	Website: http://ractivejs.org
	License: MIT
*/`;

const runtimeModulesToIgnore = ['src/parse/_parse.js'];
const placeholders = {
	BUILD_PLACEHOLDER_VERSION: version
};

const src = gobble('src').moveTo('src').transform(transpile, { accept: ['.js'] }).transform(replacePlaceholders);
const tests = gobble('tests').include(['helpers/**/*', 'browser/**/*', 'node/**/*']).moveTo('tests').transform(transpile, { accept: ['.js'] });
const browserTests = gobble([src, tests.include(['tests/helpers/**/*', 'tests/browser/**/*'])]);
const nodeTests = gobble([src, tests.include(['tests/helpers/**/*', 'tests/node/**/*'])]);
const manifest = gobble('templates/manifests').transform(replacePlaceholders);
const qunit = gobble('templates/qunit').moveTo('tests');
const bin = gobble('bin').moveTo('bin');
const lib = gobble('lib').moveTo('lib');
const typings = gobble('typings').moveTo('typings');
const sandbox = gobble('sandbox');
const polyfills = src.transform(copy, { dir: 'src' }).include(['polyfills.js']);

module.exports = ({
	'dev:browser'() {
		const lib = buildUmdLib('ractive.js', []);
		const tests = buildBrowserTests();
		const polyfills = buildUmdPolyfill();
		return gobble([lib, polyfills, tests, sandbox, qunit]);
	},
	'bundle:test'() {
		const lib = buildUmdLib('ractive.js', []);
		const browserTests = buildBrowserTests();
		const nodeTests = buildNodeTests();
		const polyfills = buildUmdPolyfill();
		return gobble([lib, polyfills, qunit, browserTests, nodeTests]);
	},
	'bundle:release'() {
		const libEsFull = buildESLib('ractive.mjs', []);
		const libEsRuntime = buildESLib('runtime.mjs', runtimeModulesToIgnore);

		const libUmdFull = buildUmdLib('ractive.js', []);
		const libUmdRuntime = buildUmdLib('runtime.js', runtimeModulesToIgnore);

		const libEs = gobble([libEsFull, libEsRuntime]);
		const libUmd = gobble([libUmdFull, libUmdRuntime]);
		const libUmdMin = libUmd.transform('uglifyjs', { ext: '.min.js', preamble: banner });

		const polyfillEs = buildESPolyfill();
		const polyfillUmd = buildUmdPolyfill();
		const polyfillUmdMin = polyfillUmd.transform('uglifyjs', { ext: '.min.js' });

		return gobble([libEs, libUmd, libUmdMin, polyfillEs, polyfillUmd, polyfillUmdMin, bin, lib, typings, manifest]);
	}
})[gobble.env()]();

////////////////////////////////////////////////////////////////////////////////

/* Bundle builders */

// Builds a UMD bundle of Ractive
function buildUmdLib(dest, excludedModules) {
	return src.transform(rollup, {
		plugins: [skipModule(excludedModules)],
		moduleName: 'Ractive',
		format: 'umd',
		entry: 'src/Ractive.js',
		dest: dest,
		banner: banner,
		noConflict: true,
		cache: false
	});
}

// Builds an ES bundle of Ractive
function buildESLib(dest, excludedModules) {
	return src.transform(rollup, {
		plugins: [skipModule(excludedModules)],
		format: 'es',
		entry: 'src/Ractive.js',
		dest: dest,
		banner: banner,
		cache: false
	});
}

// Builds a UMD bundle for browser/PhantomJS tests.
function buildBrowserTests() {
	return gobble([
		browserTests,
		browserTests.transform(buildTestEntryPoint, { dir: 'tests/browser' })
	])
		.transform(copy)
		.transform(rollup, {
			moduleName: 'RactiveBrowserTests',
			format: 'iife',
			entry: 'tests.js',
			dest: 'browser.js',
			globals: {
				qunit: 'QUnit',
				simulant: 'simulant'
			},
			external: ['qunit', 'simulant'],
			cache: false
		}).moveTo('tests');
}

// Builds a CJS bundle for node tests.
function buildNodeTests() {
	return gobble([
		nodeTests,
		nodeTests.transform(buildTestEntryPoint, { dir: 'tests/node' })
	])
		.transform(copy)
		.transform(rollup, {
			format: 'cjs',
			entry: 'tests.js',
			dest: 'node.js',
			external: ['cheerio'],
			cache: false
		}).moveTo('tests');
}

function buildUmdPolyfill() {
	return polyfills.transform(rollup, {
		moduleName: 'RactivePolyfills',
		format: 'umd',
		entry: 'polyfills.js',
		dest: 'polyfills.js',
		cache: false
	});
}

function buildESPolyfill() {
	return polyfills.transform(rollup, {
		format: 'es',
		entry: 'polyfills.js',
		dest: 'polyfills.mjs',
		cache: false
	});
}

/* Rollup plugins */

// Replaces a modules content with a null export to omit module contents.
// TODO: Must return sourcemap
function skipModule(excludedModules) {
	return {
		name: 'skipModule',
		transform: function (src, modulePath) {
			// Gobble has a predictable directory structure of gobble/transform/number
			// so we slice at 3 to slice relative to project root.
			const moduleRelativePath = path.relative(__dirname, modulePath).split(path.sep).slice(3).join(path.sep);
			return excludedModules.indexOf(moduleRelativePath) > -1 ? 'export default null; export const shared = {};' : src;
		}
	};
}

/* Gobble transforms */

// Essentially gobble-buble but takes out the middleman.
function transpile(src, options) {
	return buble.transform(src, {
		target: { ie: 9 },
		transforms: { modules: false }
	});
}

// Builds an entrypoint in the designated directory that imports all test specs
// and calls them one after the other in tree-listing order.
function buildTestEntryPoint(inDir, outDir, options) {
	const _options = Object.assign({ dir: '' }, options);
	const testPaths = fsPlus.listTreeSync(path.join(inDir, _options.dir)).filter(testPath => fsPlus.isFileSync(testPath) && path.extname(testPath) === '.js');
	const testImports = testPaths.map((testPath, index) => `import test${index} from './${path.relative(inDir, testPath).replace(/\\/g, '/')}';`).join('\n');
	const testCalls = testPaths.map((testPath, index) => `test${index}();`).join('\n');
	fs.writeFileSync(path.join(outDir, 'tests.js'), `${testImports}\n${testCalls}`, 'utf8');
	return Promise.resolve();
}

// Looks for placeholders in the code and replaces them.
// TODO: Must return sourcemap
function replacePlaceholders(src, options) {
	return Object.keys(placeholders).reduce((out, placeholder) => {
		return out.replace(new RegExp(`${placeholder}`, 'g'), placeholders[placeholder]);
	}, src);
}

// This is because Gobble's grab and Rollup's resolution is broken
// https://github.com/gobblejs/gobble/issues/89
// https://github.com/rollup/rollup/issues/1291
function copy(inputdir, outputdir, options) {
	const _options = Object.assign({ dir: '.' }, options);
	fsPlus.copySync(path.join(inputdir, _options.dir), outputdir);
	return Promise.resolve();
}

function rollup(indir, outdir, options) {
	if (!options.entry) throw new Error('You must supply `options.entry`');

	options.dest = path.resolve(outdir, options.dest || options.entry);
	options.entry = path.resolve(indir, options.entry);

	return rollupLib.rollup(options).then(function (bundle) {
		return bundle.write(options);
	});
}
<|endoftext|>


<commit_before>const invokeLambdaFunction = require('../src/lambda-invoke-function');

const supportedEventTypes = [
    'message',
    'message.channels'
];

function route(api, request) {
    return new Promise(resolve => {
        if (typeof request.body !== 'object') {
            throw new Error('Unexepcted request format.');
        }

        // Slack sends a verification token with each request. We use this to verify
        // that the message is really coming from Slack and not someone else that
        // found our endpoint. The verification token is different for each
        // instance of Slack and can be found on the "Basic Information" page of the
        // app settings.
        if (request.body.token !== request.env.slackAppVerificationToken) {
            console.log('Invalid app verification token.');
            resolve();
            return;
        }

        // Slack asks us to verify the endpoint (once).
        if (request.body.type === 'url_verification') {
            console.log('Responding to Slack URL verification challenge....');
            resolve({ challenge: request.body.challenge });
            return;
        }

        if (request.body.type !== 'event_callback' || typeof request.body.event !== 'object') {
            console.log(`Unexpected event type: ${request.body.type}`);
            resolve();
            return;
        }

        // Event subscriptions are managed in the Slack App settings.
        if (supportedEventTypes.indexOf(request.body.event.type) === -1) {
            console.log(`Unsupported event type: ${request.body.event.type}`);
            resolve();
            return;
        }

        // Skip altered messages for now to avoid bot confusion
        if (request.body.event.hasOwnProperty('subtype') && request.body.event.subtype == 'message') {
            console.log(`Subtype of "${request.body.event.subtype}" suggests a modified message. Skipping.`);
            resolve();
            return;
        }

        // Don't respond to other bots.
        if (request.body.event.bot_id) {
            console.log('Ignoring message from myself or a fellow bot, bye!');
            resolve();
            return;
        }

        // Add API Gateway stage to message. We'll need this to determine where to
        // route the message.
        console.log(`Incoming event sent to ${request.context.stage} stage.`);
        request.body.event.stage = request.context.stage;

        // Also add the stage's environment variables to the message so
        // we use the right database and all
        request.body.event.env = request.env;

        // Invoke router Lambda function.
        resolve(invokeLambdaFunction(request.body.event, 'slack-events-api-message-handler'));
    })
    .then(() => {
        // We should respond to Slack with 200 to indicate that we've received the
        // event. If we do not, Slack will retry three times with back-off.
        console.log("Said 'OK' to Slack.");
        return new api.ApiResponse('OK', { 'Content-Type': 'text/plain' }, 200);
    })
    .catch(error => {
        // We should *still* respond to Slack with 200, we'll just log it.
        console.error(error.message);
        return new api.ApiResponse('OK', { 'Content-Type': 'text/plain' }, 200);
    });
}

module.exports = route;
<commit_msg>added team_id to the event data<commit_after>const invokeLambdaFunction = require('../src/lambda-invoke-function');

const supportedEventTypes = [
    'message',
    'message.channels'
];

function route(api, request) {
    return new Promise(resolve => {
        if (typeof request.body !== 'object') {
            throw new Error('Unexepcted request format.');
        }

        // Slack sends a verification token with each request. We use this to verify
        // that the message is really coming from Slack and not someone else that
        // found our endpoint. The verification token is different for each
        // instance of Slack and can be found on the "Basic Information" page of the
        // app settings.
        if (request.body.token !== request.env.slackAppVerificationToken) {
            console.log('Invalid app verification token.');
            resolve();
            return;
        }

        // Slack asks us to verify the endpoint (once).
        if (request.body.type === 'url_verification') {
            console.log('Responding to Slack URL verification challenge....');
            resolve({ challenge: request.body.challenge });
            return;
        }

        if (request.body.type !== 'event_callback' || typeof request.body.event !== 'object') {
            console.log(`Unexpected event type: ${request.body.type}`);
            resolve();
            return;
        }

        // Event subscriptions are managed in the Slack App settings.
        if (supportedEventTypes.indexOf(request.body.event.type) === -1) {
            console.log(`Unsupported event type: ${request.body.event.type}`);
            resolve();
            return;
        }

        // Skip altered messages for now to avoid bot confusion
        if (request.body.event.hasOwnProperty('subtype') && request.body.event.subtype == 'message') {
            console.log(`Subtype of "${request.body.event.subtype}" suggests a modified message. Skipping.`);
            resolve();
            return;
        }

        // Don't respond to other bots.
        if (request.body.event.bot_id) {
            console.log('Ignoring message from myself or a fellow bot, bye!');
            resolve();
            return;
        }

        // Add API Gateway stage to message. We'll need this to determine where to
        // route the message.
        console.log(`Incoming event sent to ${request.context.stage} stage.`);
        request.body.event.stage = request.context.stage;

        // Also add the stage's environment variables to the message so
        // we use the right database and all
        request.body.event.env = request.env;
        request.body.event.team_id = request.body.team_id;

        // Invoke router Lambda function.
        resolve(invokeLambdaFunction(request.body.event, 'slack-events-api-message-handler'));
    })
    .then(() => {
        // We should respond to Slack with 200 to indicate that we've received the
        // event. If we do not, Slack will retry three times with back-off.
        console.log("Said 'OK' to Slack.");
        return new api.ApiResponse('OK', { 'Content-Type': 'text/plain' }, 200);
    })
    .catch(error => {
        // We should *still* respond to Slack with 200, we'll just log it.
        console.error(error.message);
        return new api.ApiResponse('OK', { 'Content-Type': 'text/plain' }, 200);
    });
}

module.exports = route;
<|endoftext|>


<commit_before>/*! YU2FVL - jQuery Youtube Url To FullScreen Video Lightbox - v0.1.0 - 2016-02-07
* http://otakod.es/yu2fvl
* Copyright (c) 2016 darkylmnx; Licensed MIT */
!function(t,s,e){var i=t(s),n="https://www.youtube.com/embed/",a="?enablejsapi=1",o=function(t){return/youtu\.be/.test(t)?t.split("youtu.be/")[1].split("?")[0].split("&")[0].split("#")[0]:/youtube\.com\/v\//.test(t)?t.split("youtube.com/v/")[1].split("?")[0].split("&")[0].split("#")[0]:/youtube\.com\/embed\//.test(t)?t.split("youtube.com/embed/")[1].split("?")[0].split("&")[0].split("#")[0]:/youtube.com|youtuberepeater.com|listenonrepeat.com/.test(t)?t.split("v=")[1].split("&")[0].split("#")[0]:!1},l=function(t,s,e){-1!==t.src.indexOf("youtube.com/embed")&&t.contentWindow.postMessage(JSON.stringify({event:"command",func:s,args:e||[]}),"*")},d={display:"none",position:"fixed"},c={width:"100%",height:"100%"},u={display:"none",position:"fixed",top:0,left:0,width:"100%",height:"100%"};t.fn.yu2fvl=function(s){function p(s,o){function p(){var t=i.width()-r.minPaddingX,s=i.height()-r.minPaddingY,e=t/s,n=r.ratio;e>n?(C.height(s),C.width(s*n)):(C.width(t),C.height(t/n)),C.css("left",(i.width()-C.width())/2),C.css("top",(i.height()-C.height())/2)}function f(t){t.on("click",function(t){t.preventDefault(),l(g[0],"playVideo"),m()})}function h(t){t.on("click",function(t){t.preventDefault(),l(g[0],"pauseVideo"),y()})}function m(){v.stop().fadeIn("fast"),C.stop().fadeIn("fast")}function y(){v.stop().fadeOut("fast"),C.stop().fadeOut("fast")}var C=t(e.createElement("DIV")).addClass(r.cssClass).css(d),v=t(e.createElement("DIV")).addClass(r.cssClass+r.overlayCssClass).css(u),b=t(e.createElement("BUTTON")).addClass(r.cssClass+r.closeCssClass).html(r.closeText),g=t(e.createElement("IFRAME")).addClass(r.cssClass+r.iframeCssClass).attr({src:n+o+a}).css(c);C.append(g).append(b),t("body").append(v).append(C),f(s),h(b.add(v)),i.on("resize",p).trigger("resize")}var r=t.extend({minPaddingX:50,minPaddingY:50,ratio:16/9,cssClass:"yu2fvl",overlayCssClass:"-overlay",iframeCssClass:"-iframe",closeCssClass:"-close",closeText:"X",vid:!1},s);return r.vid!==!1?(p(this,r.vid),this):this.each(function(){var s=t(this);p(s,o(s.attr("href")))})}}(jQuery,window,document);<commit_msg>Updating minified version<commit_after>/*! YU2FVL - jQuery Youtube Url To FullScreen Video Lightbox - v0.1.0 - 2016-02-07
* http://otakod.es/yu2fvl
* Copyright (c) 2016 darkylmnx; Licensed MIT */
!function(t,e,s){var i=t(e),n="https://www.youtube.com/embed/",o="?enablejsapi=1",a=function(t){return/youtu\.be/.test(t)?t.split("youtu.be/")[1].split("?")[0].split("&")[0].split("#")[0]:/youtube\.com\/v\//.test(t)?t.split("youtube.com/v/")[1].split("?")[0].split("&")[0].split("#")[0]:/youtube\.com\/embed\//.test(t)?t.split("youtube.com/embed/")[1].split("?")[0].split("&")[0].split("#")[0]:/youtube.com|youtuberepeater.com|listenonrepeat.com/.test(t)?t.split("v=")[1].split("&")[0].split("#")[0]:!1},l=function(t,e,s){-1!==t.src.indexOf("youtube.com/embed")&&t.contentWindow.postMessage(JSON.stringify({event:"command",func:e,args:s||[]}),"*")},c={display:"none",position:"fixed"},d={width:"100%",height:"100%"},u={display:"none",position:"fixed",top:0,left:0,width:"100%",height:"100%"};t.fn.yu2fvl=function(e){function p(e,a){function p(){var t=i.width()-f.minPaddingX,e=i.height()-f.minPaddingY,s=t/e,n=f.ratio;s>n?(C.height(e),C.width(e*n)):(C.width(t),C.height(t/n)),C.css("left",(i.width()-C.width())/2),C.css("top",(i.height()-C.height())/2)}function r(){l(w[0],"playVideo"),v()}function m(t){t.on("click",function(t){t.preventDefault(),r()})}function h(t){t.on("click",function(t){t.preventDefault(),l(w[0],"pauseVideo"),y()})}function v(){b.stop().fadeIn("fast"),C.stop().fadeIn("fast")}function y(){b.stop().fadeOut("fast"),C.stop().fadeOut("fast",function(){f.open&&(b.remove(),C.remove())})}var C=t(s.createElement("DIV")).addClass(f.cssClass).css(c),b=t(s.createElement("DIV")).addClass(f.cssClass+f.overlayCssClass).css(u),g=t(s.createElement("BUTTON")).addClass(f.cssClass+f.closeCssClass).html(f.closeText),w=t(s.createElement("IFRAME")).addClass(f.cssClass+f.iframeCssClass).attr({src:n+a+o}).css(d);C.append(w).append(g),t("body").append(b).append(C),f.open?w.on("load",function(){r()}):m(e),h(g.add(b)),i.on("resize",p).trigger("resize")}var f=t.extend({minPaddingX:50,minPaddingY:50,ratio:16/9,cssClass:"yu2fvl",overlayCssClass:"-overlay",iframeCssClass:"-iframe",closeCssClass:"-close",closeText:"X",open:!1,vid:!1},e);return f.vid!==!1?(p(this,f.vid),this):this.each(function(){var e=t(this);p(e,a(e.attr("href")))})}}(jQuery,window,document);<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright 2012 Vassili Philippov <vassiliphilippov@onepf.org>
 * Copyright 2014 Ruslan Sayfutdinov <ruslan@sayfutdinov.com>
 * Copyright 2012 One Platform Foundation <www.onepf.org>
 * Copyright 2012 Yandex <www.yandex.com>
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 ******************************************************************************/

/**
 * Localization related logic of AppDF Editor
 * Depends on: jquery.js, appdfedior.js, bootstrap.js,
 */

var appdfLocalization = (function() {

    var MAX_LOCALIZATION_TABS = 5;

    function getDescriptionLanguages(localesNavId) {
        var langs = [];
        $("#" + localesNavId + "-header").find("a").each(function() {
            var strHref = $(this).attr("href").toLowerCase();
            if (strHref.indexOf("#" + localesNavId + "-tab-") == 0) {
                // Cut language code from href
                langs.push(strHref.substr((localesNavId + "-tab-").length + 1));
            };
        });
        return langs;
    };

    function selectLanguage(languageCode, localesNavId) {
        $("#" + localesNavId + "-header").find('a[href="#' + localesNavId + '-tab-' + languageCode + '"]').tab('show');
    };

    function addLocalization(languageCode, languageName, localesNavId) {
        var descriptionLangs = getDescriptionLanguages(localesNavId);

        //Preventing adding one language twice
        if (descriptionLangs.indexOf(languageCode) >= 0) {
            return;
        };

        var strHtmlHeader = '
' + languageName + '
';

        var $tabHeader = $("#" + localesNavId + "-header");

        //We do not allow more than MAX_LOCALIZATION_TABS tabs, if more we add it to the "More" tab
        if ($tabHeader.children().length<MAX_LOCALIZATION_TABS) {
            $tabHeader.children("li:last").before($(strHtmlHeader));
        } else {
            $tabHeader.find('ul.dropdown-menu').append($(strHtmlHeader));
        };

        //Create new tab content container
        var strHtmlContent = '

';
        var $tabContent = $("#" + localesNavId + "-content")
        $tabContent.append($(strHtmlContent));

        //reset all warnings before cloning.
        $tabContent.children("div#" + localesNavId + "-tab-default").find("input,select,textarea").trigger("clear.validation");

        //Add copy of default langauge content to just created container
        var strHtmlClone = $tabContent.children("div#" + localesNavId + "-tab-default").html();
        var $localizedDescription = $(strHtmlClone);
        if (localesNavId === "description-locales") {
            prepareJustCopiedDescription($localizedDescription);
        }
        $tabContent.children().last().append($localizedDescription);

        //Open just created tab and create a handler
        $tabHeader.find('a[href="#' + localesNavId + '-tab-' + languageCode + '"]').tab('show');
        $tabHeader.find('a[href="#' + localesNavId + '-tab-' + languageCode + '"]').click(function (e) {
            e.preventDefault();
            $(this).tab('show');
        });
    };

    function prepareJustCopiedDescription($e) {
        //reset promo images
        appdfImages.addLargePromo($e.find(".large-promo-image-reset")[0]);
        appdfImages.addSmallPromo($e.find(".small-promo-image-reset")[0]);

    	//Remove image fields that were non-empty in the default language
    	$e.find(".image-input-group").find("input.image-input").not(".empty-image").closest(".image-input-group").remove();
    	$e.find(".image-input-group").find("input.screenshot-input").not(".empty-image").closest(".image-input-group").remove();
    	$e.find(".image-input-group").find("input.appicon-input").not(".empty-image").closest(".image-input-group").remove();

        //Remove the required "*" symbol from the end of all labels because all fields in a localization are optional
    	$e.find(".required-mark").remove();

        $e.find(".warning").removeClass("warning");

        //Remove all additionally added keywords
        $e.find("input[id^=description-texts-keywords-more-]").closest(".input-container").remove();
    };

    function removeAllLocalizations(localesNavId) {
        var $tabHeader = $("#" + localesNavId + "-header");
        var $tabContent = $("#" + localesNavId + "-content");

        $tabHeader.find("a").each(function() {
            var strHref = $(this).attr("href");
            if (strHref != "#" + localesNavId + "-tab-default" && strHref != "#") {
                $(this).closest("li").remove();
                $tabContent.children("div" + strHref).remove();
            };
        });
    };

    function removeSelectedLocalization(localesNavId) {
        var $tabHeader = $("#" + localesNavId + "-header");
        var $tabContent = $("#" + localesNavId + "-content");
        var strHref = $tabHeader.find(".active").children("a").attr("href");

        if (strHref.match("#" + localesNavId + "-tab-default")) {
            alert("Cannot remove default (English) localization");
            return;
        };

        //First we check if "More" is selected
        if (strHref=="#") {
            strHref = $tabHeader.find(".active").find(".active").children("a").attr("href");
            $tabHeader.find(".active").find(".active").remove();
            $tabContent.children("div" + strHref).remove();
        } else {
            $tabHeader.find(".active").remove();
            $tabContent.children("div" + strHref).remove();
        };

        selectLanguage("default", localesNavId);
    };

    function showAllLocalizationDialog(localesNavId) {
        var $modal = $("#add-localization-modal");
        var $okButton = $modal.find(".btn-primary");

        $okButton.unbind("click").click(function(event) {
            event.preventDefault();
            $modal.modal('hide');
            addLocalization($("#add-localization-modal-language").val(), $("#add-localization-modal-language").children(":selected").text(), localesNavId);
        });

        $modal.modal("show");
    };

    function init() {
        $('body').on('click', '.tab-addlocalization', function(event) {
            showAllLocalizationDialog($(this).closest("div.tabbable").attr("id"));
            return false;
        });

        $('body').on('click', '.tab-removeselectedlocalization', function(event) {
            var localesNavId = $(this).closest("div.tabbable").attr("id");
            removeSelectedLocalization(localesNavId);
            var $tabHeader = $("#" + localesNavId + "-header");
            $tabHeader.find("li.dropdown.open").removeClass("open");
            return false;
        });
    };

    function isDefaultLanguage($el) {
        var $tab = $el.closest(".tab-pane");
        var tabId = $tab.attr('id');
        return tabId.match("\-tab\-default$");
    };

    return {
        init : init,
        removeAllLocalizations : removeAllLocalizations,
        addLocalization : addLocalization,
        selectLanguage : selectLanguage,
        isDefaultLanguage : isDefaultLanguage,
        getDescriptionLanguages : getDescriptionLanguages
    };
})();

$(function() {
    appdfLocalization.init();
});
<commit_msg>Add validation to created locale tabs<commit_after>/*******************************************************************************
 * Copyright 2012 Vassili Philippov <vassiliphilippov@onepf.org>
 * Copyright 2014 Ruslan Sayfutdinov <ruslan@sayfutdinov.com>
 * Copyright 2012 One Platform Foundation <www.onepf.org>
 * Copyright 2012 Yandex <www.yandex.com>
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 ******************************************************************************/

/**
 * Localization related logic of AppDF Editor
 * Depends on: jquery.js, appdfeditor.js, bootstrap.js,
 */

var appdfLocalization = (function() {

    var MAX_LOCALIZATION_TABS = 5;

    function getDescriptionLanguages(localesNavId) {
        var langs = [];
        $("#" + localesNavId + "-header").find("a").each(function() {
            var strHref = $(this).attr("href").toLowerCase();
            if (strHref.indexOf("#" + localesNavId + "-tab-") == 0) {
                // Cut language code from href
                langs.push(strHref.substr((localesNavId + "-tab-").length + 1));
            };
        });
        return langs;
    };

    function selectLanguage(languageCode, localesNavId) {
        $("#" + localesNavId + "-header").find('a[href="#' + localesNavId + '-tab-' + languageCode + '"]').tab('show');
    };

    function addLocalization(languageCode, languageName, localesNavId) {
        var descriptionLangs = getDescriptionLanguages(localesNavId);

        //Preventing adding one language twice
        if (descriptionLangs.indexOf(languageCode) >= 0) {
            return;
        };

        var strHtmlHeader = '
' + languageName + '
';

        var $tabHeader = $("#" + localesNavId + "-header");

        //We do not allow more than MAX_LOCALIZATION_TABS tabs, if more we add it to the "More" tab
        if ($tabHeader.children().length<MAX_LOCALIZATION_TABS) {
            $tabHeader.children("li:last").before($(strHtmlHeader));
        } else {
            $tabHeader.find('ul.dropdown-menu').append($(strHtmlHeader));
        };

        //Create new tab content container
        var strHtmlContent = '

';
        var $tabContent = $("#" + localesNavId + "-content");
        $tabContent.append($(strHtmlContent));

        //reset all warnings before cloning.
        $tabContent.children("div#" + localesNavId + "-tab-default").find("input,select,textarea").trigger("clear.validation");

        //Add copy of default langauge content to just created container
        var strHtmlClone = $tabContent.children("div#" + localesNavId + "-tab-default").html();
        var $localizedDescription = $(strHtmlClone);
        if (localesNavId === "description-locales") {
            prepareJustCopiedDescription($localizedDescription);
        }
        $tabContent.children().last().append($localizedDescription);

        //Open just created tab and create a handler
        $tabHeader.find('a[href="#' + localesNavId + '-tab-' + languageCode + '"]').tab('show');
        $tabHeader.find('a[href="#' + localesNavId + '-tab-' + languageCode + '"]').click(function (e) {
            e.preventDefault();
            $(this).tab('show');
        });

        $validateElements = $tabContent.children("div#" + localesNavId + "-tab-" + languageCode).find("input,textarea, select");
        appdfEditor.addValidationToElements($validateElements);
    };

    function prepareJustCopiedDescription($e) {
        //reset promo images
        appdfImages.addLargePromo($e.find(".large-promo-image-reset")[0]);
        appdfImages.addSmallPromo($e.find(".small-promo-image-reset")[0]);

    	//Remove image fields that were non-empty in the default language
    	$e.find(".image-input-group").find("input.image-input").not(".empty-image").closest(".image-input-group").remove();
    	$e.find(".image-input-group").find("input.screenshot-input").not(".empty-image").closest(".image-input-group").remove();
    	$e.find(".image-input-group").find("input.appicon-input").not(".empty-image").closest(".image-input-group").remove();

        //Remove the required "*" symbol from the end of all labels because all fields in a localization are optional
    	$e.find(".required-mark").remove();

        $e.find(".warning").removeClass("warning");

        //Remove all additionally added keywords
        $e.find("input[id^=description-texts-keywords-more-]").closest(".input-container").remove();
    };

    function removeAllLocalizations(localesNavId) {
        var $tabHeader = $("#" + localesNavId + "-header");
        var $tabContent = $("#" + localesNavId + "-content");

        $tabHeader.find("a").each(function() {
            var strHref = $(this).attr("href");
            if (strHref != "#" + localesNavId + "-tab-default" && strHref != "#") {
                $(this).closest("li").remove();
                $tabContent.children("div" + strHref).remove();
            };
        });
    };

    function removeSelectedLocalization(localesNavId) {
        var $tabHeader = $("#" + localesNavId + "-header");
        var $tabContent = $("#" + localesNavId + "-content");
        var strHref = $tabHeader.find(".active").children("a").attr("href");

        if (strHref.match("#" + localesNavId + "-tab-default")) {
            alert("Cannot remove default (English) localization");
            return;
        };

        //First we check if "More" is selected
        if (strHref=="#") {
            strHref = $tabHeader.find(".active").find(".active").children("a").attr("href");
            $tabHeader.find(".active").find(".active").remove();
            $tabContent.children("div" + strHref).remove();
        } else {
            $tabHeader.find(".active").remove();
            $tabContent.children("div" + strHref).remove();
        };

        selectLanguage("default", localesNavId);
    };

    function showAllLocalizationDialog(localesNavId) {
        var $modal = $("#add-localization-modal");
        var $okButton = $modal.find(".btn-primary");

        $okButton.unbind("click").click(function(event) {
            event.preventDefault();
            $modal.modal('hide');
            addLocalization($("#add-localization-modal-language").val(), $("#add-localization-modal-language").children(":selected").text(), localesNavId);
        });

        $modal.modal("show");
    };

    function init() {
        $('body').on('click', '.tab-addlocalization', function(event) {
            showAllLocalizationDialog($(this).closest("div.tabbable").attr("id"));
            return false;
        });

        $('body').on('click', '.tab-removeselectedlocalization', function(event) {
            var localesNavId = $(this).closest("div.tabbable").attr("id");
            removeSelectedLocalization(localesNavId);
            var $tabHeader = $("#" + localesNavId + "-header");
            $tabHeader.find("li.dropdown.open").removeClass("open");
            return false;
        });
    };

    function isDefaultLanguage($el) {
        var $tab = $el.closest(".tab-pane");
        var tabId = $tab.attr('id');
        return tabId.match("\-tab\-default$");
    };

    return {
        init : init,
        removeAllLocalizations : removeAllLocalizations,
        addLocalization : addLocalization,
        selectLanguage : selectLanguage,
        isDefaultLanguage : isDefaultLanguage,
        getDescriptionLanguages : getDescriptionLanguages
    };
})();

$(function() {
    appdfLocalization.init();
});
<|endoftext|>


<commit_before>var ws = require('ws'),
    quotes = require('./quotes');

var socketServer = function() {
    var data = null,
        timerID = null,
        listener = null,
        WebSocketServer = ws.Server,
        url = require('url'),
        domain = require('domain'),
        socketDomain = domain.create(),
        httpDomain = domain.create(),

        socketListen = function(port) {
            socketDomain.on('error', function(err) {
                console.log('Error caught in socket domain:' + err);
            });

            socketDomain.run(function() {
                listener = new WebSocketServer({ port: port });

                listener.broadcast = function(data) {
                    listener.clients.forEach(function(client) {
                        client.send(data);
                    });
                };

                listener.on('listening',function(){
                    console.log('SocketServer is running');
                });

                listener.on('connection', function (socket) {

                    console.log('Connected to client');

                    socket.on('message', function (data) {
                        //console.log('Message received:', data);
                    });

                    socket.on('close', function () {
                        try {
                            socket.close();

                            if (listener.clients.length == 0) {
                                clearInterval(timerID);
                                data = null;
                            }
                        }
                        catch (e) {
                            console.log(e);
                        }
                    });

                });
            });
        },

        getQuotes = function() {
            var json = {"quotes" : quotes};

            processJson(json);
        },

        sendQuote = function() {
            if (listener.clients.length > 0) {
                var randomQuoteIndex = Math.floor(Math.random() * data.quotes.length);
                listener.broadcast(data.quotes[randomQuoteIndex]);
            }
        },

        processJson = function(json) {
            data = json;
            sendQuote();
            timerID = setInterval(sendQuote, 5000);

        },

        init = function(socketPort, callback) {
            socketListen(socketPort);
            callback(listener);
        };

    return {
        init: init
    };

}();

module.exports = socketServer;
<commit_msg>Code clean-up<commit_after>var ws = require('ws');

var socketServer = function() {
    var data = null,
        timerID = null,
        listener = null,
        WebSocketServer = ws.Server,
        url = require('url'),
        domain = require('domain'),
        socketDomain = domain.create(),
        httpDomain = domain.create(),

        socketListen = function(port) {
            socketDomain.on('error', function(err) {
                console.log('Error caught in socket domain:' + err);
            });

            socketDomain.run(function() {
                listener = new WebSocketServer({ port: port });

                listener.broadcast = function(data) {
                    listener.clients.forEach(function(client) {
                        client.send(data);
                    });
                };

                listener.on('listening',function(){
                    console.log('SocketServer is running');
                });

                listener.on('connection', function (socket) {

                    console.log('Connected to client');

                    socket.on('message', function (data) {
                        //console.log('Message received:', data);
                    });

                    socket.on('close', function () {
                        try {
                            socket.close();

                            if (listener.clients.length == 0) {
                                clearInterval(timerID);
                                data = null;
                            }
                        }
                        catch (e) {
                            console.log(e);
                        }
                    });

                });
            });
        },

        init = function(socketPort, callback) {
            socketListen(socketPort);
            callback(listener);
        };

    return {
        init: init
    };

}();

module.exports = socketServer;
<|endoftext|>