<commit_before>'use strict';

var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');

module.exports = function () {

  var props = this.props;
  var destPath = this.destinationPath();

  props._ = {
    kebabCase: _.kebabCase,
    camelCase: _.camelCase,
    capitalize: _.capitalize
  };

  // create directories
  mkdirp(path.join(destPath, 'src/fonts'));
  mkdirp(path.join(destPath, 'src/img'));

  // dotfiles
  this.fs.copy(this.templatePath('gitignore'), '.gitignore');
  this.fs.copy(this.templatePath('editorconfig'), '.editorconfig');
  this.fs.copy(this.templatePath('eslintrc'), '.eslintrc');
  this.fs.copy(this.templatePath('htmlhintrc'), '.htmlhintrc');
  this.fs.copy(this.templatePath('sass-lint.yml'), '.sass-lint.yml');
  this.fs.copy(this.templatePath('stylelintrc'), '.stylelintrc');
  this.fs.copyTpl(this.templatePath('gulpfile.babel.js'), 'gulpfile.babel.js', props);
  this.fs.copy(this.templatePath('README.md'),'README.md');
  this.fs.copyTpl(this.templatePath('package.json'),'package.json', props);

  // gulp configs
  this.fs.copy(this.templatePath('gulp/config.js'),'gulp/config.js');
  this.fs.copy(this.templatePath('gulp/util/handle-errors.js'),'gulp/util/handle-errors.js');

  // common tasks
  // this.fs.copyTpl(this.templatePath('gulp/tasks/default.js'),'gulp/tasks/default.js');
  // this.fs.copyTpl(this.templatePath('gulp/tasks/build.js'),'gulp/tasks/build.js', props);
  // this.fs.copyTpl(this.templatePath('gulp/tasks/watch.js'),'gulp/tasks/watch.js', props);

  this.fs.copyTpl(this.templatePath('gulp/tasks/copy.js'),'gulp/tasks/copy.js', props);
  this.fs.copy(this.templatePath('gulp/tasks/clean.js'),'gulp/tasks/clean.js');
  this.fs.copy(this.templatePath('gulp/tasks/server.js'),'gulp/tasks/server.js');

  if(props.preview){
    this.fs.copy(this.templatePath('gulp/tasks/index/index.html'),'gulp/tasks/index/index.html');
    this.fs.copy(this.templatePath('gulp/tasks/list-pages.js'),'gulp/tasks/list-pages.js');
  }

  this.sprites = props.sprites; // or in /templates/src/sass/app.sass use options.sprites
  // compile templates tasks
  switch (props.templates) {
    case 'nunjucks':
      this.fs.copy(this.templatePath('gulp/tasks/nunjucks.js'),'gulp/tasks/nunjucks.js');
      break;
    // case 'swig':
    //   this.fs.copy(this.templatePath('gulp/tasks/swig.js'),'gulp/tasks/swig.js');
    //   break;
    // case 'jade':
    //   this.fs.copy(this.templatePath('gulp/tasks/jade.js'),'gulp/tasks/jade.js');
    //   break;
    case 'pug':
      this.fs.copy(this.templatePath('gulp/tasks/pug.js'),'gulp/tasks/pug.js');
      break;
  }

  switch (props.css) {
    case 'sass':
      this.fs.copy(this.templatePath('gulp/tasks/sass.js'),'gulp/tasks/sass.js');
      break;
    case 'postcss':
      this.fs.copy(this.templatePath('gulp/tasks/postcss.js'),'gulp/tasks/postcss.js');
      break;
  }

  // image optimization task
  if (props.imagemin) {
    this.fs.copy(this.templatePath('gulp/tasks/imagemin.js'),'gulp/tasks/imagemin.js');
  }

  this.fs.copy(this.templatePath('gulp/tasks/svgo.js'),'gulp/tasks/svgo.js');
  if (props.svgo) {
    this.fs.copy(this.templatePath('src/img/svgo/facebook.svg'),'src/img/svgo/facebook.svg');
    this.fs.copy(this.templatePath('src/img/svgo'), 'src/img/svgo');
  }

  if (props.sprites.length) {
    this.fs.copy(this.templatePath('src/icons/facebook.png'), 'src/icons/facebook.png');
    this.fs.copy(this.templatePath('src/icons/facebook.svg'), 'src/icons/facebook.svg');
    this.fs.copy(this.templatePath('src/icons/facebook@2x.png'), 'src/icons/facebook@2x.png');
  }

  // iconfont task

  if (props.sprites.indexOf('iconfont') !== -1) {
    this.fs.copy(this.templatePath('gulp/tasks/iconfont/iconfont.js'),'gulp/tasks/iconfont/iconfont.js');
    this.fs.copy(this.templatePath('gulp/tasks/iconfont/iconfont.html'),'gulp/tasks/iconfont/iconfont.html');

    switch (props.css) {
      case 'sass':
        this.fs.copy(this.templatePath('gulp/tasks/iconfont/_iconfont.scss'),'gulp/tasks/iconfont/_iconfont.scss');
        break;
      case 'postcss':
        this.fs.copy(this.templatePath('gulp/tasks/iconfont/_iconfont.sss'),'gulp/tasks/iconfont/_iconfont.sss');
        break;
    }
  }

  // svg sprites task

    this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-svg.js'),'gulp/tasks/sprite-svg.js',props);

    switch (props.css) {
      case 'sass':
        this.fs.copy(this.templatePath('gulp/tasks/sprite-svg/_sprite-svg.scss'),'gulp/tasks/sprite-svg/_sprite-svg.scss');
        break;
      case 'postcss':
        this.fs.copy(this.templatePath('gulp/tasks/sprite-svg/_sprite-svg.sss'),'gulp/tasks/sprite-svg/_sprite-svg.sss');
        break;
    }

  // png sprites task
  if (props.sprites.indexOf('png') !== -1) {
    this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-png/sprite-png.js'),'gulp/tasks/sprite-png/sprite-png.js',props);

    switch (props.css) {
      case 'sass':
        this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-png/sprite.template.mustache'),'gulp/tasks/sprite-png/sprite.template.mustache',props);
        break;
      case 'postcss':
        this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-png/sprite.sss.template.mustache'),'gulp/tasks/sprite-png/sprite.sss.template.mustache',props);
        break;
    }
  }

  if(props.preview){
    this.fs.copyTpl(this.templatePath('src/index.yaml'),'src/index.yaml', props);
  }

  // copy directories
  // if (props.bundler === 'webpack') {
    this.fs.copy(this.templatePath('src/js/app-webpack.js'), 'src/js/app.js');
  // } else {
  //   this.fs.copy(this.templatePath('src/js/app.js'), 'src/js/app.js');
  //   this.fs.copy(this.templatePath('src/js/lib'), 'src/js/lib')

  // }

  // if (props.bundler === 'webpack') {
    this.fs.copy(this.templatePath('gulp/tasks/webpack.js'), 'gulp/tasks/webpack.js');
    this.fs.copy(this.templatePath('src/js/lib/sayHello-webpack.js'), 'src/js/lib/sayHello.js');
    this.fs.copy(this.templatePath('src/js/lib/detectTouch-webpack.js'), 'src/js/lib/detectTouch.js');
    this.fs.copy(this.templatePath('webpack.config.js'),'webpack.config.js');
  // }
  // else{
  //   this.fs.copy(this.templatePath('gulp/tasks/js.js'), 'gulp/tasks/js.js');
  //   this.fs.copy(this.templatePath('src/js/lib/sayHello.js'), 'src/js/lib/sayHello.js');
  //   this.fs.copy(this.templatePath('src/js/lib/detectTouch.js'), 'src/js/lib/detectTouch.js');
  // }
  this.fs.copy(this.templatePath('babelrc'), '.babelrc');

  if (props.css === 'sass') {
    // this.directory('src/sass', 'src/sass');
    this.fs.copy(this.templatePath('src/sass'), 'src/sass');
    this.fs.copyTpl(this.templatePath('src/sass/app.sass'), 'src/sass/app.sass',props);
  } else{
    this.fs.copy(this.templatePath('src/postcss'), 'src/sass');
    this.fs.copyTpl(this.templatePath('src/sass/app.sss'), 'src/sass/app.sss',props);
  }

  switch (props.templates) {
    case 'nunjucks':
      this.fs.copy(this.templatePath('src/templates-nunjucks'), 'src/templates');
      if(!props.preview){
        this.fs.delete('src/templates/page.html');
        this.fs.copy(this.templatePath('src/templates-nunjucks/page.html'), 'src/templates/index.html');
      }
      break;
    case 'swig':
      this.fs.copy(this.templatePath('src/templates-swig'), 'src/templates');
      break;
    case 'jade':
      this.fs.copy(this.templatePath('src/templates-jade'), 'src/templates');
      break;
    case 'pug':
      this.fs.copy(this.templatePath('src/templates-pug'), 'src/templates');
      break;
    case 'html':
      this.fs.copy(this.templatePath('src/templates-html'), 'src');
      break;
  }
};
<commit_msg>add pug preview\not preview variants<commit_after>'use strict';

var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');

module.exports = function () {

  var props = this.props;
  var destPath = this.destinationPath();

  props._ = {
    kebabCase: _.kebabCase,
    camelCase: _.camelCase,
    capitalize: _.capitalize
  };

  // create directories
  mkdirp(path.join(destPath, 'src/fonts'));
  mkdirp(path.join(destPath, 'src/img'));

  // dotfiles
  this.fs.copy(this.templatePath('gitignore'), '.gitignore');
  this.fs.copy(this.templatePath('editorconfig'), '.editorconfig');
  this.fs.copy(this.templatePath('eslintrc'), '.eslintrc');
  this.fs.copy(this.templatePath('htmlhintrc'), '.htmlhintrc');
  this.fs.copy(this.templatePath('sass-lint.yml'), '.sass-lint.yml');
  this.fs.copy(this.templatePath('stylelintrc'), '.stylelintrc');
  this.fs.copyTpl(this.templatePath('gulpfile.babel.js'), 'gulpfile.babel.js', props);
  this.fs.copy(this.templatePath('README.md'),'README.md');
  this.fs.copyTpl(this.templatePath('package.json'),'package.json', props);

  // gulp configs
  this.fs.copy(this.templatePath('gulp/config.js'),'gulp/config.js');
  this.fs.copy(this.templatePath('gulp/util/handle-errors.js'),'gulp/util/handle-errors.js');

  // common tasks
  // this.fs.copyTpl(this.templatePath('gulp/tasks/default.js'),'gulp/tasks/default.js');
  // this.fs.copyTpl(this.templatePath('gulp/tasks/build.js'),'gulp/tasks/build.js', props);
  // this.fs.copyTpl(this.templatePath('gulp/tasks/watch.js'),'gulp/tasks/watch.js', props);

  this.fs.copyTpl(this.templatePath('gulp/tasks/copy.js'),'gulp/tasks/copy.js', props);
  this.fs.copy(this.templatePath('gulp/tasks/clean.js'),'gulp/tasks/clean.js');
  this.fs.copy(this.templatePath('gulp/tasks/server.js'),'gulp/tasks/server.js');

  if(props.preview){
    this.fs.copy(this.templatePath('gulp/tasks/index/index.html'),'gulp/tasks/index/index.html');
    this.fs.copy(this.templatePath('gulp/tasks/list-pages.js'),'gulp/tasks/list-pages.js');
  }

  this.sprites = props.sprites; // or in /templates/src/sass/app.sass use options.sprites
  // compile templates tasks
  switch (props.templates) {
    case 'nunjucks':
      this.fs.copy(this.templatePath('gulp/tasks/nunjucks.js'),'gulp/tasks/nunjucks.js');
      break;
    // case 'swig':
    //   this.fs.copy(this.templatePath('gulp/tasks/swig.js'),'gulp/tasks/swig.js');
    //   break;
    // case 'jade':
    //   this.fs.copy(this.templatePath('gulp/tasks/jade.js'),'gulp/tasks/jade.js');
    //   break;
    case 'pug':
      this.fs.copy(this.templatePath('gulp/tasks/pug.js'),'gulp/tasks/pug.js');
      break;
  }

  switch (props.css) {
    case 'sass':
      this.fs.copy(this.templatePath('gulp/tasks/sass.js'),'gulp/tasks/sass.js');
      break;
    case 'postcss':
      this.fs.copy(this.templatePath('gulp/tasks/postcss.js'),'gulp/tasks/postcss.js');
      break;
  }

  // image optimization task
  if (props.imagemin) {
    this.fs.copy(this.templatePath('gulp/tasks/imagemin.js'),'gulp/tasks/imagemin.js');
  }

  this.fs.copy(this.templatePath('gulp/tasks/svgo.js'),'gulp/tasks/svgo.js');
  if (props.svgo) {
    this.fs.copy(this.templatePath('src/img/svgo/facebook.svg'),'src/img/svgo/facebook.svg');
    this.fs.copy(this.templatePath('src/img/svgo'), 'src/img/svgo');
  }

  if (props.sprites.length) {
    this.fs.copy(this.templatePath('src/icons/facebook.png'), 'src/icons/facebook.png');
    this.fs.copy(this.templatePath('src/icons/facebook.svg'), 'src/icons/facebook.svg');
    this.fs.copy(this.templatePath('src/icons/facebook@2x.png'), 'src/icons/facebook@2x.png');
  }

  // iconfont task

  if (props.sprites.indexOf('iconfont') !== -1) {
    this.fs.copy(this.templatePath('gulp/tasks/iconfont/iconfont.js'),'gulp/tasks/iconfont/iconfont.js');
    this.fs.copy(this.templatePath('gulp/tasks/iconfont/iconfont.html'),'gulp/tasks/iconfont/iconfont.html');

    switch (props.css) {
      case 'sass':
        this.fs.copy(this.templatePath('gulp/tasks/iconfont/_iconfont.scss'),'gulp/tasks/iconfont/_iconfont.scss');
        break;
      case 'postcss':
        this.fs.copy(this.templatePath('gulp/tasks/iconfont/_iconfont.sss'),'gulp/tasks/iconfont/_iconfont.sss');
        break;
    }
  }

  // svg sprites task

    this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-svg.js'),'gulp/tasks/sprite-svg.js',props);

    switch (props.css) {
      case 'sass':
        this.fs.copy(this.templatePath('gulp/tasks/sprite-svg/_sprite-svg.scss'),'gulp/tasks/sprite-svg/_sprite-svg.scss');
        break;
      case 'postcss':
        this.fs.copy(this.templatePath('gulp/tasks/sprite-svg/_sprite-svg.sss'),'gulp/tasks/sprite-svg/_sprite-svg.sss');
        break;
    }

  // png sprites task
  if (props.sprites.indexOf('png') !== -1) {
    this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-png/sprite-png.js'),'gulp/tasks/sprite-png/sprite-png.js',props);

    switch (props.css) {
      case 'sass':
        this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-png/sprite.template.mustache'),'gulp/tasks/sprite-png/sprite.template.mustache',props);
        break;
      case 'postcss':
        this.fs.copyTpl(this.templatePath('gulp/tasks/sprite-png/sprite.sss.template.mustache'),'gulp/tasks/sprite-png/sprite.sss.template.mustache',props);
        break;
    }
  }

  if(props.preview){
    this.fs.copyTpl(this.templatePath('src/index.yaml'),'src/index.yaml', props);
  }

  // copy directories
  // if (props.bundler === 'webpack') {
    this.fs.copy(this.templatePath('src/js/app-webpack.js'), 'src/js/app.js');
  // } else {
  //   this.fs.copy(this.templatePath('src/js/app.js'), 'src/js/app.js');
  //   this.fs.copy(this.templatePath('src/js/lib'), 'src/js/lib')

  // }

  // if (props.bundler === 'webpack') {
    this.fs.copy(this.templatePath('gulp/tasks/webpack.js'), 'gulp/tasks/webpack.js');
    this.fs.copy(this.templatePath('src/js/lib/sayHello-webpack.js'), 'src/js/lib/sayHello.js');
    this.fs.copy(this.templatePath('src/js/lib/detectTouch-webpack.js'), 'src/js/lib/detectTouch.js');
    this.fs.copy(this.templatePath('webpack.config.js'),'webpack.config.js');
  // }
  // else{
  //   this.fs.copy(this.templatePath('gulp/tasks/js.js'), 'gulp/tasks/js.js');
  //   this.fs.copy(this.templatePath('src/js/lib/sayHello.js'), 'src/js/lib/sayHello.js');
  //   this.fs.copy(this.templatePath('src/js/lib/detectTouch.js'), 'src/js/lib/detectTouch.js');
  // }
  this.fs.copy(this.templatePath('babelrc'), '.babelrc');

  if (props.css === 'sass') {
    // this.directory('src/sass', 'src/sass');
    this.fs.copy(this.templatePath('src/sass'), 'src/sass');
    this.fs.copyTpl(this.templatePath('src/sass/app.sass'), 'src/sass/app.sass',props);
  } else{
    this.fs.copy(this.templatePath('src/postcss'), 'src/sass');
    this.fs.copyTpl(this.templatePath('src/sass/app.sss'), 'src/sass/app.sss',props);
  }

  switch (props.templates) {
    case 'nunjucks':
      this.fs.copy(this.templatePath('src/templates-nunjucks'), 'src/templates');
      if(!props.preview){
        this.fs.delete('src/templates/page.html');
        this.fs.copy(this.templatePath('src/templates-nunjucks/page.html'), 'src/templates/index.html');
      }
      break;
    case 'pug':
      this.fs.copy(this.templatePath('src/templates-pug'), 'src/templates');
      if(!props.preview){
        this.fs.delete('src/templates/page.pug');
        this.fs.copy(this.templatePath('src/templates-pug/page.pug'), 'src/templates/index.pug');
      }
      break;
    case 'swig':
      this.fs.copy(this.templatePath('src/templates-swig'), 'src/templates');
      break;
    case 'jade':
      this.fs.copy(this.templatePath('src/templates-jade'), 'src/templates');
      break;
    case 'html':
      this.fs.copy(this.templatePath('src/templates-html'), 'src');
      break;
  }
};
<|endoftext|>


<commit_before>class MealService {
    constructor(DayModel, MealModel, FirebaseStorageService) {
        Object.assign(this, {DayModel, MealModel, FirebaseStorageService});
        this.meals = this.MealModel.emptyMealsList(); //useless
    }

    updateMealInfo(mealContent, date, userId, mealType, mealNo) {
        const fullDateName = moment(date).format("YYYY-M-D"); //in case nonformatted date were passed
        this.FirebaseStorageService.getSingleDateMealsList(fullDateName, userId).then((response) => {
            const newDayContent = this._resolveNewDayData(response, date, mealContent, mealType, mealNo);
            this.cleanAndSetMealsList(fullDateName, newDayContent, userId);
        });
    }

    cleanAndSetMealsList(date, rawData, id) {
        const cleanData = MealService._cleanEmptyRecipes(angular.copy(rawData));
        this.FirebaseStorageService.setSingleDateMealsList(date, cleanData, id);
    }

    _resolveNewDayData(oldDayContent, date, mealContent, mealType, mealNo)  {
        //check if there is smth. for this DAY
        if (oldDayContent === null) {
            return this._createNewDayWithNewContent(date, mealContent, mealType, mealNo);
        } else {
            //check if we already have smth. for this MEAL
            const oldMealContent = oldDayContent.mealsList.find(meal => meal.mealNo === mealNo);

            if (!!oldMealContent) {
                MealService._editMeal(oldMealContent, mealContent, mealType);
                return oldDayContent;
            } else {
                const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
                oldDayContent.mealsList.push(meal);
                return oldDayContent;
            }
        }
    }

    _createNewMealWithNewContent(mealContent, mealNo, mealType) {
        const newMeal = this.MealModel.createNewMeal(mealNo);
        return MealService._editMeal(newMeal, mealContent, mealType);
    }

    _createNewDayWithNewContent(date, mealContent, mealType, mealNo) {
        const day = this.DayModel.createNewDay(moment(date));
        const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
        day.mealsList.push(meal);
        return day;
    }

    static _editMeal(meal, newContent, mealType) {
        if (mealType === 'list') {
            meal.dishesList = meal.dishesList.concat(newContent.productsList);
        } else if (mealType === 'recipe') {
            meal.dishesList.push(newContent);
        } else if (mealType === 'stored') {
            meal.dishesList = meal.dishesList.concat(newContent.dishesList);
        }

        return meal;
    }

    static _cleanEmptyRecipes(data) {
        data.mealsList.forEach(a => a.dishesList.map((b, i) => {
            if (b.type === 'recipe' && b.productsList.length === 0) {
                a.dishesList.splice(i, 1);
            }
        }));
        return data;
    }

    deleteMeal(mealName, date) {
        const storedDayName = date.format("YYYY-M-D");
        let availableItem = this.getMealsList(storedDayName);
        let i = availableItem.mealsList.findIndex(b => b.mealName === mealName);
        availableItem.mealsList.splice(i, 1);
        this.updateCleanMealsList(storedDayName,availableItem);
    };

    findDateRangeMealList(start, q) {
        const dayNames = [];
        const results = [];

        for (let i = 0; i < q; i++) {
            dayNames.push(moment(start).add(i, 'days').format("YYYY-M-D"));
        }

        dayNames.forEach((a) => {
            results.push({
                fullDate: a,
                mealsList: this.findMealList(a)
            });
        });

        return results;
    };

    findMealList(forDate) {
        let data = this.getMealsList(forDate);
        if (data === null) return this.meals;
        if (data != null) {
            if (data.mealsList === undefined) {
                return this.meals; //empty meals
            } else {
                for (let i = 0; i < this.meals.length; i++) {
                    let k = data.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                    if (k.length === 0) {
                        data.mealsList.push(this.meals[i]);
                    } else {
                        //just leave as it is
                    }
                }
                return data.mealsList;
            }
        }
    };

    getMealsList(forDate) {
        let all = [];
        try {
            all = JSON.parse(localStorage.getItem(forDate));
        } catch (error) {
            console.log(error);
        }
        return all;
    }

}

Mealpler.service('MealService', MealService);<commit_msg>MP-42: added refactored method findDateRangeMealList<commit_after>class MealService {
    constructor(DayModel, MealModel, FirebaseStorageService) {
        Object.assign(this, {DayModel, MealModel, FirebaseStorageService});
        this.meals = this.MealModel.emptyMealsList(); //useless
    }

    findDateRangeMealList(start, q, userId) {
        const dayNames = [];
        //let results = [];

        for (let i = 0; i < q; i++) {
            dayNames.push(moment(start).add(i, 'days').format("YYYY-M-D"));
        }

        return this.FirebaseStorageService.getAllMealsForUser(userId).then((response) => {
            return this._resolveExistingMealData(response, dayNames);
        });
    };

    updateMealInfo(mealContent, date, userId, mealType, mealNo) {
        const fullDateName = moment(date).format("YYYY-M-D"); //in case nonformatted date were passed
        this.FirebaseStorageService.getSingleDateMealsList(fullDateName, userId).then((response) => {
            const newDayContent = this._resolveNewDayData(response, date, mealContent, mealType, mealNo);
            this.cleanAndSetMealsList(fullDateName, newDayContent, userId);
        });
    }

    cleanAndSetMealsList(date, rawData, id) {
        const cleanData = MealService._cleanEmptyRecipes(angular.copy(rawData));
        this.FirebaseStorageService.setSingleDateMealsList(date, cleanData, id);
    }

    _resolveNewDayData(oldDayContent, date, mealContent, mealType, mealNo)  {
        //check if there is smth. for this DAY
        if (oldDayContent === null) {
            return this._createNewDayWithNewContent(date, mealContent, mealType, mealNo);
        } else {
            //check if we already have smth. for this MEAL
            const oldMealContent = oldDayContent.mealsList.find(meal => meal.mealNo === mealNo);

            if (!!oldMealContent) {
                MealService._editMeal(oldMealContent, mealContent, mealType);
                return oldDayContent;
            } else {
                const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
                oldDayContent.mealsList.push(meal);
                return oldDayContent;
            }
        }
    }

    _createNewMealWithNewContent(mealContent, mealNo, mealType) {
        const newMeal = this.MealModel.createNewMeal(mealNo);
        return MealService._editMeal(newMeal, mealContent, mealType);
    }

    _createNewDayWithNewContent(date, mealContent, mealType, mealNo) {
        const day = this.DayModel.createNewDay(moment(date));
        const meal = this._createNewMealWithNewContent(mealContent, mealNo, mealType);
        day.mealsList.push(meal);
        return day;
    }

    static _editMeal(meal, newContent, mealType) {
        if (mealType === 'list') {
            meal.dishesList = meal.dishesList.concat(newContent.productsList);
        } else if (mealType === 'recipe') {
            meal.dishesList.push(newContent);
        } else if (mealType === 'stored') {
            meal.dishesList = meal.dishesList.concat(newContent.dishesList);
        }

        return meal;
    }

    static _cleanEmptyRecipes(data) {
        data.mealsList.forEach(a => a.dishesList.map((b, i) => {
            if (b.type === 'recipe' && b.productsList.length === 0) {
                a.dishesList.splice(i, 1);
            }
        }));
        return data;
    }

    deleteMeal(mealName, date) {
        const storedDayName = date.format("YYYY-M-D");
        let availableItem = this.getMealsList(storedDayName);
        let i = availableItem.mealsList.findIndex(b => b.mealName === mealName);
        availableItem.mealsList.splice(i, 1);
        this.updateCleanMealsList(storedDayName,availableItem);
    };

    _resolveExistingMealData(data, datesList) {
        const resolved = [];
        if (data === null) {
            datesList.forEach((singleDate) => {
                resolved.push(getEmptyDay.call(this, singleDate));
            })
        } else {
            datesList.forEach((singleDate) => {
                let existingDay = null;
                for (const storedDay in data) {
                    if (storedDay === singleDate) {
                        existingDay = data[storedDay];
                    }
                }
                if (existingDay === null) {
                    resolved.push(getEmptyDay.call(this, singleDate));
                } else {
                    if (existingDay.mealsList === undefined) {
                        existingDay.mealsList = this.MealModel.emptyMealsList();
                    } else {
                        for (let i = 0; i < this.meals.length; i++) {
                            let k = existingDay.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                            if (k.length === 0) {
                                existingDay.mealsList.push(this.meals[i]);
                            } else {
                                //just leave as it is if all meals are there
                            }
                        }
                    }
                    resolved.push(existingDay);
                }
            })
        }

        return resolved;

        function getEmptyDay(date) {
            const newDay = this.DayModel.createNewDay(moment(date));
            newDay.mealsList = this.MealModel.emptyMealsList();
            return newDay;
        }
    }

    findMealList(data) {
        //let data = this.getMealsList(forDate);
        if (data === null) return this.meals;
        if (data != null) {
            if (data.mealsList === undefined) {
                return this.meals; //empty meals
            } else {
                for (let i = 0; i < this.meals.length; i++) {
                    let k = data.mealsList.filter(b => b.mealNo === this.meals[i].mealNo);
                    if (k.length === 0) {
                        data.mealsList.push(this.meals[i]);
                    } else {
                        //just leave as it is
                    }
                }
                return data.mealsList;
            }
        }
    };

    getMealsList(forDate) {
        let all = [];
        try {
            all = JSON.parse(localStorage.getItem(forDate));
        } catch (error) {
            console.log(error);
        }
        return all;
    }

}

Mealpler.service('MealService', MealService);<|endoftext|>


<commit_before>(function() {
  var renderer = Iris.Renderer.extend({
    about : {
      name: "treegraph",
	  author: "Annette Greiner",
	  version: "1.0",
	  requires: [ 'd3.js' ],
	  defaults: { width: 600,
	    height: 400,
	    padding: 0,
	    data: "exampleData()"
	    },
	  classes: ["link", "node"],
	  dataFormat: "tree"
	  },
	exampleData: function(){
	//TODO: Write a parser for newick.
	//var dataobj = {"name":26,"children":[{"name":25,"children":[{"name":"AT3G52430.1@Atha","size":3},{"name":23,"children":[{"name":"Sb05g005970.1@Sbic","size":4},{"name":21,"children":[{"name":"BRADI4G23367.1@Bdis","size":5},{"name":19,"children":[{"name":"LOC_Os11g09010.3@Osat","size":6},{"name":17,"children":[{"name":"BGIOSGA025494-PA@Oind","size":7},{"name":"BGIOSGA025495-PA@Oind","size":7}],"size":6}],"size":5}],"size":4}],"size":3}],"size":2},{"name":14,"children":[{"name":"AT5G14930.2@Atha","size":3},{"name":12,"children":[{"name":11,"children":[{"name":"AT3G48080.1@Atha","size":5},{"name":"AT3G48090.1@Atha","size":5}],"size":4},{"name":8,"children":[{"name":"Sb02g024030.1@Sbic","size":5},{"name":6,"children":[{"name":"BRADI4G29600.1@Bdis","size":6},{"name":4,"children":[{"name":"ORGLA09G0067400.1@Ogla","size":7},{"name":2,"children":[{"name":"LOC_Os09g22450.1@Osat","size":8},{"name":"BGIOSGA030701-PA@Oind","size":8}],"size":7}],"size":6}],"size":5}],"size":4}],"size":3}],"size":2}],"size":1};

	var dataobj = renderer.array_to_tree([ [ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia coli", "Escherichia coli K-12", "Escherichia coli str. K-12 substr. MG1655" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia coli", "Escherichia coli K-12", "Escherichia coli BW2952" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia coli", "Escherichia coli 53638" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia fergusonii", "Escherichia fergusonii ATCC 35469" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia albertii", "Escherichia albertii TW07627" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Sodalis", "Sodalis glossinidius", "Sodalis glossinidius str. 'morsitans'" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "unclassified Enterobacteriaceae", "ant, tsetse, mealybug, aphid, etc. endosymbionts", "aphid secondary symbionts", "Candidatus Hamiltonella", "Candidatus Hamiltonella defensa", "Candidatus Hamiltonella defensa 5AT (Acyrthosiphon pisum)" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Buchnera", "Buchnera aphidicola", "Buchnera aphidicola (Schizaphis graminum)", "Buchnera aphidicola str. Sg (Schizaphis graminum)" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Proteus", "Proteus mirabilis", "Proteus mirabilis HI4320" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Vibrionales", "Vibrionaceae", "Vibrio", "Vibrio shilonii", "Vibrio shilonii AK1" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Aeromonadales", "Aeromonadaceae", "Tolumonas", "Tolumonas auensis", "Tolumonas auensis DSM 9187" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Moritellaceae", "Moritella", "Moritella sp. PE36" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Ferrimonadaceae", "Ferrimonas", "Ferrimonas balearica", "Ferrimonas balearica DSM 9799" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Shewanellaceae", "Shewanella", "Shewanella amazonensis", "Shewanella amazonensis SB2B" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Shewanellaceae", "Shewanella", "Shewanella loihica", "Shewanella loihica PV-4" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Pseudoalteromonadaceae", "Pseudoalteromonas", "Pseudoalteromonas atlantica", "Pseudoalteromonas atlantica T6c" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Alteromonadaceae", "Glaciecola", "Glaciecola sp. HTCC2999" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Alteromonadaceae", "Alteromonas", "Alteromonas macleodii", "Alteromonas macleodii str. 'Deep ecotype'" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Colwelliaceae", "Colwellia", "Colwellia psychrerythraea", "Colwellia psychrerythraea 34H" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Pseudoalteromonadaceae", "Pseudoalteromonas", "Pseudoalteromonas tunicata", "Pseudoalteromonas tunicata D2"],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Idiomarinaceae", "Idiomarina", "Idiomarina baltica", "Idiomarina baltica OS145" ],["Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Idiomarinaceae", "Idiomarina", "Idiomarina loihiensis", "Idiomarina loihiensis L2TR" ] ]);

	return  dataobj;
      },
	render : function( options ) {

	if (options.data.length) {
	  options.data = renderer.array_to_tree(options.data);
	}

	options.target.innerHTML = "";
	var cluster = d3.layout.cluster()
	  .size([options.height, options.width/2 ]);

	var diagonal = d3.svg.diagonal()
	  .projection(function(d) { return [d.y, d.x]; });

	var vis = d3.select(options.target).append("svg")
	  .attr("width", options.width)
	  .attr("height", options.height)
	  .append("g")
	  .attr("transform", "translate(20, 0)");

	var nodes = cluster.nodes(options.data);

	var link = vis.selectAll("path.link")
	  .data(cluster.links(nodes))
	  .enter().append("path")
	  .attr("class", "link")
	  .attr("d", diagonal)
	  .attr("style", "fill: none; stroke: #ccc;", "stroke-width: 1.5px;");

	var node = vis.selectAll("g.node")
	  .data(nodes)
	  .enter().append("g")
	  .attr("class", "node")
	  .attr("style", "font: 16px sans-serif; font-style: italic;")
	  .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

	node.append("circle")
	  .attr("r", 3)
	  .attr("style", function(d) {
	      var stroke="stroke: grey; stroke-width: 0.5px;";
	      return d.children ? stroke+"fill: steelblue;" :  stroke+"fill: #D73027"; })
	  .attr("title", function(d) {
	      return d.name;
	    });

	node.append("text")
	  .attr("dx", function(d) { return d.children ? -8 : 8; })
	  .attr("dy", 3)
	  .attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
	  .attr("font-family", "\"Helvetica Neue\",Helvetica,Verdana")
	  .attr("font-size", "10")
	  .attr("style", "fill: #666")
	  .text(function(d) { return d.children ? "" :  d.name; });
      },
	array_to_tree : function (data) {
	var newdata = { "name": "root", "children": [] };
	var nodes = newdata["children"];
	for (i=0; i<data.length; i++) {
	  var pnode = nodes;
	  var row = data[i];
	  for (h=0; h<row.length; h++) {
	    var found = 0;
	    var node;
	    for (j=0; j<nodes.length; j++) {
	      if (nodes[j]["name"] == data[i][h]) {
		found = 1;
		node = nodes[j];
		break;
	      }
	    }
	    if (! found) {
	      node = { "name": data[i][h] };
	      if (h < row.length - 1) {
		node["children"] = [];
	      }
	      nodes.push( node );
	    }
	    nodes = node["children"];
	  }
	  nodes = pnode;
	}
	return newdata;
      }
    });

 }).call(this);
<commit_msg>Merging a few changes.<commit_after>(function() {
  var renderer = Iris.Renderer.extend({
    about : {
      name: "treegraph",
	  author: "Annette Greiner",
	  version: "1.0",
	  requires: [ 'd3.js' ],
	  defaults: { width: 600,
	    height: 400,
	    padding: 0,
	    data: "exampleData()"
	    },
	  classes: ["link", "node"],
	  dataFormat: "tree"
	  },
	exampleData: function(){
	//TODO: Write a parser for newick.
	//var dataobj = {"name":26,"children":[{"name":25,"children":[{"name":"AT3G52430.1@Atha","size":3},{"name":23,"children":[{"name":"Sb05g005970.1@Sbic","size":4},{"name":21,"children":[{"name":"BRADI4G23367.1@Bdis","size":5},{"name":19,"children":[{"name":"LOC_Os11g09010.3@Osat","size":6},{"name":17,"children":[{"name":"BGIOSGA025494-PA@Oind","size":7},{"name":"BGIOSGA025495-PA@Oind","size":7}],"size":6}],"size":5}],"size":4}],"size":3}],"size":2},{"name":14,"children":[{"name":"AT5G14930.2@Atha","size":3},{"name":12,"children":[{"name":11,"children":[{"name":"AT3G48080.1@Atha","size":5},{"name":"AT3G48090.1@Atha","size":5}],"size":4},{"name":8,"children":[{"name":"Sb02g024030.1@Sbic","size":5},{"name":6,"children":[{"name":"BRADI4G29600.1@Bdis","size":6},{"name":4,"children":[{"name":"ORGLA09G0067400.1@Ogla","size":7},{"name":2,"children":[{"name":"LOC_Os09g22450.1@Osat","size":8},{"name":"BGIOSGA030701-PA@Oind","size":8}],"size":7}],"size":6}],"size":5}],"size":4}],"size":3}],"size":2}],"size":1};

	var dataobj = renderer.array_to_tree([ [ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia coli", "Escherichia coli K-12", "Escherichia coli str. K-12 substr. MG1655" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia coli", "Escherichia coli K-12", "Escherichia coli BW2952" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia coli", "Escherichia coli 53638" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia fergusonii", "Escherichia fergusonii ATCC 35469" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Escherichia", "Escherichia albertii", "Escherichia albertii TW07627" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Sodalis", "Sodalis glossinidius", "Sodalis glossinidius str. 'morsitans'" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "unclassified Enterobacteriaceae", "ant, tsetse, mealybug, aphid, etc. endosymbionts", "aphid secondary symbionts", "Candidatus Hamiltonella", "Candidatus Hamiltonella defensa", "Candidatus Hamiltonella defensa 5AT (Acyrthosiphon pisum)" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Buchnera", "Buchnera aphidicola", "Buchnera aphidicola (Schizaphis graminum)", "Buchnera aphidicola str. Sg (Schizaphis graminum)" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacteriales", "Enterobacteriaceae", "Proteus", "Proteus mirabilis", "Proteus mirabilis HI4320" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Vibrionales", "Vibrionaceae", "Vibrio", "Vibrio shilonii", "Vibrio shilonii AK1" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Aeromonadales", "Aeromonadaceae", "Tolumonas", "Tolumonas auensis", "Tolumonas auensis DSM 9187" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Moritellaceae", "Moritella", "Moritella sp. PE36" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Ferrimonadaceae", "Ferrimonas", "Ferrimonas balearica", "Ferrimonas balearica DSM 9799" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Shewanellaceae", "Shewanella", "Shewanella amazonensis", "Shewanella amazonensis SB2B" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Shewanellaceae", "Shewanella", "Shewanella loihica", "Shewanella loihica PV-4" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Pseudoalteromonadaceae", "Pseudoalteromonas", "Pseudoalteromonas atlantica", "Pseudoalteromonas atlantica T6c" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Alteromonadaceae", "Glaciecola", "Glaciecola sp. HTCC2999" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Alteromonadaceae", "Alteromonas", "Alteromonas macleodii", "Alteromonas macleodii str. 'Deep ecotype'" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Colwelliaceae", "Colwellia", "Colwellia psychrerythraea", "Colwellia psychrerythraea 34H" ],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Pseudoalteromonadaceae", "Pseudoalteromonas", "Pseudoalteromonas tunicata", "Pseudoalteromonas tunicata D2"],[ "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Idiomarinaceae", "Idiomarina", "Idiomarina baltica", "Idiomarina baltica OS145" ],["Bacteria", "Proteobacteria", "Gammaproteobacteria", "Alteromonadales", "Idiomarinaceae", "Idiomarina", "Idiomarina loihiensis", "Idiomarina loihiensis L2TR" ] ]);

	return  dataobj;
      },
	render : function( options ) {

	if (options.data.length) {
	  options.data = renderer.array_to_tree(options.data);
	}

	options.target.innerHTML = "";
	var cluster = d3.layout.cluster()
	  .size([options.height, options.width/2 ]);

	var diagonal = d3.svg.diagonal()
	  .projection(function(d) { return [d.y, d.x]; });

	var vis = d3.select(options.target).append("svg")
	  .attr("width", options.width)
	  .attr("height", options.height)
	  .append("g")
	  .attr("transform", "translate(20, 0)");

	var nodes = cluster.nodes(options.data);

	var link = vis.selectAll("path.link")
	  .data(cluster.links(nodes))
	  .enter().append("path")
	  .attr("class", "link")
	  .attr("d", diagonal)
	  .attr("style", "fill: none; stroke: #ccc;", "stroke-width: 1.5px;");

	var node = vis.selectAll("g.node")
	  .data(nodes)
	  .enter().append("g")
	  .attr("class", "node")
	  .attr("style", "font: 16px sans-serif; font-style: italic;")
	  .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

	node.append("circle")
	  .attr("r", 3)
	  .attr("style", function(d) {
	      var stroke="stroke: grey; stroke-width: 0.5px;";
	      return d.children ? stroke+"fill: steelblue;" :  stroke+"fill: #D73027"; })
	  .attr("title", function(d) {
	      return d.name;
	    });

	node.append("text")
	  .attr("dx", function(d) { return d.children ? -8 : 8; })
	  .attr("dy", 3)
	  .attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
	  .attr("font-family", "\"Helvetica Neue\",Helvetica,Verdana")
	  .attr("font-size", "10")
	  .attr("style", "fill: #666")
	  .text(function(d) { return d.children ? "" :  d.name; });
      },
	array_to_tree : function (data) {
	var newdata = { "name": "root", "children": [] };
	var nodes = newdata["children"];
	for (i=0; i<data.length; i++) {
	  var pnode = nodes;
	  var row = data[i];
	  for (h=0; h<row.length; h++) {
	    var found = 0;
	    var node;
	    for (j=0; j<nodes.length; j++) {
	      if (nodes[j]["name"] == data[i][h]) {
		found = 1;
		node = nodes[j];
		break;
	      }
	    }
	    if (! found) {
	      node = { "name": data[i][h] };
	      if (h < row.length - 1) {
		node["children"] = [];
	      }
	      nodes.push( node );
	    }
	    nodes = node["children"];
	  }
	  nodes = pnode;
	}
	return newdata;
      }
    });

 }).call(this);
<|endoftext|>


<commit_before>function currentLocationMatches(action_path) {
  return $("body.gobierto_participation_" + action_path).length > 0
}

$(document).on('turbolinks:load', function() {

  // Toggle description for Process#show stages diagram
  $('.toggle_description').click(function() {
    $(this).parents('.timeline_row').toggleClass('toggled');

    $(this).find('.fa').toggleClass('fa-caret-right fa-caret-down');
    $(this).siblings('.description').toggle();
  });

  $.fn.extend({
    toggleText: function(a, b){
      return this.text(this.text() == b ? a : b);
    }
  });

  $('.button_toggle').on('click', function() {
    $('.button.hidden').toggleClass('hidden');
  })

  if (currentLocationMatches("processes_poll_answers_new")) {
    window.GobiertoParticipation.process_polls_controller.show();
  } else if (currentLocationMatches("processes_show")) {
    window.GobiertoParticipation.processes_controller.show();
  }

  // fix this to be only in the home
  window.GobiertoParticipation.poll_teaser_controller.show();
});
<commit_msg>Add active class in participation navigation menu using JS<commit_after>function currentLocationMatches(action_path) {
  return $("body.gobierto_participation_" + action_path).length > 0
}

$(document).on('turbolinks:load', function() {

  // Toggle description for Process#show stages diagram
  $('.toggle_description').click(function() {
    $(this).parents('.timeline_row').toggleClass('toggled');

    $(this).find('.fa').toggleClass('fa-caret-right fa-caret-down');
    $(this).siblings('.description').toggle();
  });

  $.fn.extend({
    toggleText: function(a, b){
      return this.text(this.text() == b ? a : b);
    }
  });

  $('.button_toggle').on('click', function() {
    $('.button.hidden').toggleClass('hidden');
  })

  if (currentLocationMatches("processes_poll_answers_new")) {
    window.GobiertoParticipation.process_polls_controller.show();
  } else if (currentLocationMatches("processes_show")) {
    window.GobiertoParticipation.processes_controller.show();
  }

  // fix this to be only in the home
  window.GobiertoParticipation.poll_teaser_controller.show();

  // Add active class to menu
  $('nav a[href="' + window.location.pathname + '"]').parent().addClass('active');
});
<|endoftext|>


<commit_before>'use strict';

module.exports = function(gulp, $, paths) {
  // build js for dev
  gulp.task('js:dev', ['vendor-js', 'app-js']);

  // build vendor js
  gulp.task('vendor-js', function() {
    return gulp.src($.mainBowerFiles({filter: '**/*.js'}))
      .pipe($.concat('vendor.js'))
      .pipe($.size({title: "VENDOR JS", showFiles: true}))
      .pipe($.if(!global.prod, gulp.dest(paths.dev.js), gulp.dest(paths.prod.js)));
  });

  // build app js
  gulp.task('app-js', function() {
    return gulp.src(paths.src.js)
      .pipe($.if(!global.prod, $.sourcemaps.init()))
        .pipe($.concat('app.js'))
      .pipe($.if(!global.prod, $.sourcemaps.write()))
      .pipe($.size({title: "APP JS", showFiles: true}))
      .pipe($.if(!global.prod, gulp.dest(paths.dev.js), gulp.dest(paths.prod.js)));
  });

  // build js for prod
  gulp.task('js:prod', ['js:dev'], function() {
    return gulp.src([
        // order is important here
        paths.prod.js + '/vendor.js',
        paths.prod.js + '/app.js'
      ])
      .pipe($.concat('app.min.js'))
      .pipe($.uglify())
      .pipe($.size({title: "APP JS", showFiles: true}))
      .pipe(gulp.dest(paths.prod.js));
  });
};
<commit_msg>modify js:prod task<commit_after>'use strict';

module.exports = function(gulp, $, paths) {
  // build js for dev
  gulp.task('js:dev', ['vendor-js', 'app-js']);

  // build vendor js
  gulp.task('vendor-js', function() {
    return gulp.src($.mainBowerFiles({filter: '**/*.js'}))
      .pipe($.concat('vendor.js'))
      .pipe($.size({title: "VENDOR JS", showFiles: true}))
      .pipe($.if(!global.prod, gulp.dest(paths.dev.js), gulp.dest(paths.prod.js)));
  });

  // build app js
  gulp.task('app-js', function() {
    return gulp.src(paths.src.js)
      .pipe($.if(!global.prod, $.sourcemaps.init()))
        .pipe($.concat('app.js'))
      .pipe($.if(!global.prod, $.sourcemaps.write()))
      .pipe($.size({title: "APP JS", showFiles: true}))
      .pipe($.if(!global.prod, gulp.dest(paths.dev.js), gulp.dest(paths.prod.js)));
  });

  // build js for prod
  gulp.task('js:prod', ['js:dev'], function() {
    var sourceFiles = [
      // order is important here
      paths.prod.js + '/vendor.js',
      paths.prod.js + '/app.js'
    ];

    return gulp.src(sourceFiles)
      .pipe($.concat('app.min.js'))
      .pipe($.uglify())
      .pipe($.size({title: "APP JS", showFiles: true}))
      .pipe(gulp.dest(paths.prod.js))
      .on('end', function() {
        return $.del(sourceFiles);
      });
  });
};
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var platforms = require('./platforms');
var docker = require('./docker');

var prompts = [
  {
    type: 'input',
    name: 'projectName',
    message: 'Machine-name of your project?',
    // Name of the parent directory.
    default: _.last(process.cwd().split('/')),
    validate: function (input) {
      return (input.search(' ') === -1) ? true : 'No spaces allowed.';
    }
  },
  {
    type: 'list',
    name: 'drupalDistroVersion',
    message: 'Choose your Drupal version:',
    choices: [
      '7.x',
      '8.x'
    ],
    default: '7.x'
  },
  {
    type: 'list',
    name: 'hosting',
    message: 'Choose your hosting platform:',
    choices: function(answers) {
      return platforms.toPromptOptions(answers);
    },
    default: 'outrigger'
  },
  {
    type: 'list',
    name: 'webserver',
    message: 'Choose your webserver:',
    choices: function (answers) {
      var options = docker.imageOptions(answers.hosting, 'www');
      options.push('custom');
      return options;
    }
  },
  {
    name: 'webImage',
    message: 'Specify an override of the webserver Docker image (default is an example, not necessarily the image used.):',
    default: 'phase2/apache-php:php70',
    when: function(answers) {
      return answers.webserver == 'custom';
    },
    validate: function(input) {
      if (!_.isString(input) || input.length == 0 || input.search(' ') !== -1) {
        return 'A valid docker image identifier is required.';
      }

      return true;
    }
  },
  {
    type: 'list',
    name: 'cacheInternal',
    message: 'Choose a cache backend:',
    choices: function(answers) {
      var options = docker.imageOptions(answers.hosting, 'cache');
      options.push('database');
      return options;
    },
    default: function (answers) {
      if (answers.drupalDistroVersion == '8.x') {
        return 'database';
      }
      return 'memcache';
    }

  },
  {
    type: 'list',
    name: 'proxyCache',
    message: 'Choose a proxy cache:',
    choices: function(answers) {
      var options = docker.imageOptions(answers.hosting, 'proxy');
      options.push('none');
      return options;
    },
    when: function (answers) {
      return docker.hasService(answers.hosting, 'proxy');
    },
    default: 'none'
  },
  {
    type: 'list',
    name: 'mail',
    message: 'Choose an email handling approach:',
    choices: function(answers) {
      var options = docker.imageOptions(answers.hosting, 'mail');
      options.push('none');
      return options;
    },
    when: function (answers) {
      return docker.hasService(answers.hosting, 'mail');
    },
    default: 'none'
  },
  {
    type: 'checkbox',
    name: 'environments',
    message: 'Select default standing environments:',
    default: [
      'dev',
      'qa',
      'review'
    ],
    choices: [
      {
        value: 'dev',
        name: 'Development - Automatically updates when PRs are merged.',
        short: 'Development'
      },
      {
        value: 'qa',
        name: 'QA - Regularly scheduled deployments for manual Phase2 testing.',
        short: 'QA'
      },
      {
        value: 'review',
        name: 'Review - Milestone review sandbox for client use.',
        short: 'Review'
      }
    ]
  },
  {
    type: 'input',
    name: 'domain',
    message: 'Domain for local development (www.<domain>.vm):',
    default: _.last(process.cwd().split('/')).replace(/_|\s/, '-'),
    validate: function (input) {
      return input.match(/_|\s/) == undefined ? true : 'Please use a value qualified for use as a domain name. No spaces or underscores allowed.';
    }
  },
  {
    type: 'input',
    name: 'gitRepoUrl',
    message: 'URL to the Git Repo for checkout by Jenkins and other tools:',
    default: function(answers) {
      var gitBaseUrl = platforms.load()[answers.hosting].tools.git.baseUrl;
      return gitBaseUrl + answers.projectName + '.git';
    }
  },
  {
    type: 'input',
    name: 'flowdockApiKey',
    message: 'API key for the project flow (found in your account under API Tokens), leave blank to skip:',
  }
];

module.exports = prompts;
<commit_msg>Remove 'phase2' from prompts.<commit_after>'use strict';

var _ = require('lodash');
var platforms = require('./platforms');
var docker = require('./docker');

var prompts = [
  {
    type: 'input',
    name: 'projectName',
    message: 'Machine-name of your project?',
    // Name of the parent directory.
    default: _.last(process.cwd().split('/')),
    validate: function (input) {
      return (input.search(' ') === -1) ? true : 'No spaces allowed.';
    }
  },
  {
    type: 'list',
    name: 'drupalDistroVersion',
    message: 'Choose your Drupal version:',
    choices: [
      '7.x',
      '8.x'
    ],
    default: '7.x'
  },
  {
    type: 'list',
    name: 'hosting',
    message: 'Choose your hosting platform:',
    choices: function(answers) {
      return platforms.toPromptOptions(answers);
    },
    default: 'outrigger'
  },
  {
    type: 'list',
    name: 'webserver',
    message: 'Choose your webserver:',
    choices: function (answers) {
      var options = docker.imageOptions(answers.hosting, 'www');
      options.push('custom');
      return options;
    }
  },
  {
    name: 'webImage',
    message: 'Specify an override of the webserver Docker image (default is an example, not necessarily the image used.):',
    default: 'outrigger/apache-php:php70',
    when: function(answers) {
      return answers.webserver == 'custom';
    },
    validate: function(input) {
      if (!_.isString(input) || input.length == 0 || input.search(' ') !== -1) {
        return 'A valid docker image identifier is required.';
      }

      return true;
    }
  },
  {
    type: 'list',
    name: 'cacheInternal',
    message: 'Choose a cache backend:',
    choices: function(answers) {
      var options = docker.imageOptions(answers.hosting, 'cache');
      options.push('database');
      return options;
    },
    default: function (answers) {
      if (answers.drupalDistroVersion == '8.x') {
        return 'database';
      }
      return 'memcache';
    }

  },
  {
    type: 'list',
    name: 'proxyCache',
    message: 'Choose a proxy cache:',
    choices: function(answers) {
      var options = docker.imageOptions(answers.hosting, 'proxy');
      options.push('none');
      return options;
    },
    when: function (answers) {
      return docker.hasService(answers.hosting, 'proxy');
    },
    default: 'none'
  },
  {
    type: 'list',
    name: 'mail',
    message: 'Choose an email handling approach:',
    choices: function(answers) {
      var options = docker.imageOptions(answers.hosting, 'mail');
      options.push('none');
      return options;
    },
    when: function (answers) {
      return docker.hasService(answers.hosting, 'mail');
    },
    default: 'none'
  },
  {
    type: 'checkbox',
    name: 'environments',
    message: 'Select default standing environments:',
    default: [
      'dev',
      'qa',
      'review'
    ],
    choices: [
      {
        value: 'dev',
        name: 'Development - Automatically updates when PRs are merged.',
        short: 'Development'
      },
      {
        value: 'qa',
        name: 'QA - Regularly scheduled deployments for manual testing.',
        short: 'QA'
      },
      {
        value: 'review',
        name: 'Review - Milestone review sandbox for client use.',
        short: 'Review'
      }
    ]
  },
  {
    type: 'input',
    name: 'domain',
    message: 'Domain for local development (www.<domain>.vm):',
    default: _.last(process.cwd().split('/')).replace(/_|\s/, '-'),
    validate: function (input) {
      return input.match(/_|\s/) == undefined ? true : 'Please use a value qualified for use as a domain name. No spaces or underscores allowed.';
    }
  },
  {
    type: 'input',
    name: 'gitRepoUrl',
    message: 'URL to the Git Repo for checkout by Jenkins and other tools:',
    default: function(answers) {
      var gitBaseUrl = platforms.load()[answers.hosting].tools.git.baseUrl;
      return gitBaseUrl + answers.projectName + '.git';
    }
  },
  {
    type: 'input',
    name: 'flowdockApiKey',
    message: 'API key for the project flow (found in your account under API Tokens), leave blank to skip:',
  }
];

module.exports = prompts;
<|endoftext|>


<commit_before>var exports,console,$true,$false;//IGNORE
function Comparison(x){}//IGNORE
function ArraySequence(x){}//IGNORE
function Entry(a,b){}//IGNORE
function Singleton(x){}//IGNORE
function SequenceBuilder(){}//IGNORE
function Integer(x){}//IGNORE
function Boolean$(f){}//IGNORE
function String$(f,x){}//IGNORE

function print(line) { console.log(line.getString().value) }
exports.print=print;

var larger = Comparison("larger");
function getLarger() { return larger }
var smaller = Comparison("smaller");
function getSmaller() { return smaller }
var equal = Comparison("equal");
function getEqual() { return equal }
function largest(x, y) { return x.compare(y) === larger ? x : y }
function smallest(x, y) { return x.compare(y) === smaller ? x : y }

exports.getLarger=getLarger;
exports.getSmaller=getSmaller;
exports.getEqual=getEqual;
exports.largest=largest;
exports.smallest=smallest;

//receives ArraySequence, returns element
function min(seq) {
    var v = seq.value[0];
    if (seq.value.length > 1) {
        for (var i = 1; i < seq.value.length; i++) {
            v = smallest(v, seq.value[i]);
        }
    }
    return v;
}
//receives ArraySequence, returns element
function max(seq) {
    var v = seq.value[0];
    if (seq.value.length > 1) {
        for (var i = 1; i < seq.value.length; i++) {
            v = largest(v, seq.value[i]);
        }
    }
    return v;
}
//receives ArraySequence of ArraySequences, returns flat ArraySequence
function join(seqs) {
    var builder = [];
    for (var i = 0; i < seqs.value.length; i++) {
        builder = builder.concat(seqs.value[i].value);
    }
    return ArraySequence(builder);
}
//receives ArraySequences, returns ArraySequence
function zip(keys, items) {
    var entries = []
    var numEntries = Math.min(keys.value.length, items.value.length);
    for (var i = 0; i < numEntries; i++) {
        entries[i] = Entry(keys.value[i], items.value[i]);
    }
    return ArraySequence(entries);
}
//receives and returns ArraySequence
function coalesce(seq) {
    var newseq = [];
    for (var i = 0; i < seq.value.length; i++) {
        if (seq.value[i]) {
            newseq = newseq.concat(seq.value[i]);
        }
    }
    return ArraySequence(newseq);
}

//receives ArraySequence and CeylonObject, returns new ArraySequence
function append(seq, elem) {
    return ArraySequence(seq.value.concat(elem));
}
function prepend(seq, elem) {
    if (seq.getEmpty() === $true) {
        return Singleton(elem);
    } else {
        var sb = SequenceBuilder();
        sb.append(elem);
        sb.appendAll(seq);
        return sb.getSequence();
    }
}

//Receives ArraySequence, returns ArraySequence (with Entries)
function entries(seq) {
    var e = [];
    for (var i = 0; i < seq.value.length; i++) {
        e.push(Entry(Integer(i), seq.value[i]));
    }
    return ArraySequence(e);
}

exports.min=min;
exports.max=max;
exports.join=join;
exports.zip=zip;
exports.coalesce=coalesce;
exports.append=append;
exports.prepend=prepend;
exports.entries=entries;

//These are operators for handling nulls
function exists(value) {
    return value === null || value === undefined ? $false : $true;
}
function nonempty(value) {
    return value === null || value === undefined ? $false : Boolean$(value.getEmpty() === $false);
}

function isOfType(obj, typeName) {
    if (obj === null) return Boolean$(typeName==="ceylon.language.Nothing" || typeName==="ceylon.language.Void");
    var cons = obj.$$;
    if (cons === undefined) cons = obj.constructor.$$;
    if (cons === undefined) cons = obj.constructor;
    return Boolean$(typeName in cons.T$all);
}
function isOfTypes(obj, types) {
    if (obj===null) { //TODO check if this is right
        return types.l.indexOf('ceylon.language.Nothing')>=0 || types.l.indexOf('ceylon.language.Void')>=0;
    }
    var unions = false;
    var inters = true;
    var _ints=false;
    var cons = obj.$$;
    if (cons === undefined) cons = obj.constructor.$$;
    if (cons === undefined) cons = obj.constructor;
    for (var i = 0; i < types.l.length; i++) {
        var t = types.l[i];
        var partial = false;
        if (typeof t === 'string') {
            partial = t in cons.T$all;
        } else {
            partial = isOfTypes(obj, t);
        }
        if (types.t==='u') {
            unions = partial || unions;
        } else {
            inters = partial && inters;
            _ints=true;
        }
    }
    return _ints ? inters||unions : unions;
}

function className(obj) {
    if (obj === null) return String$('ceylon.language.Nothing');
    var cons = obj.$$;
    if (cons === undefined) cons = obj.constructor.$$;
    if (cons === undefined) cons = obj.constructor;
    return String$(cons.T$name);
}

function identityHash(obj) {
    return obj.identifiableObjectID;
}

exports.exists=exists;
exports.nonempty=nonempty;
exports.isOfType=isOfType;
exports.isOfTypes=isOfTypes;
exports.className=className;
exports.identityHash=identityHash;
<commit_msg>remove unnecessary lines<commit_after>var exports,console,$true,$false;//IGNORE
function Comparison(x){}//IGNORE
function ArraySequence(x){}//IGNORE
function Entry(a,b){}//IGNORE
function Singleton(x){}//IGNORE
function SequenceBuilder(){}//IGNORE
function Integer(x){}//IGNORE
function Boolean$(f){}//IGNORE
function String$(f,x){}//IGNORE

function print(line) { console.log(line.getString().value) }
exports.print=print;

var larger = Comparison("larger");
function getLarger() { return larger }
var smaller = Comparison("smaller");
function getSmaller() { return smaller }
var equal = Comparison("equal");
function getEqual() { return equal }
function largest(x, y) { return x.compare(y) === larger ? x : y }
function smallest(x, y) { return x.compare(y) === smaller ? x : y }

exports.getLarger=getLarger;
exports.getSmaller=getSmaller;
exports.getEqual=getEqual;
exports.largest=largest;
exports.smallest=smallest;

//receives ArraySequence, returns element
function min(seq) {
    var v = seq.value[0];
    if (seq.value.length > 1) {
        for (var i = 1; i < seq.value.length; i++) {
            v = smallest(v, seq.value[i]);
        }
    }
    return v;
}
//receives ArraySequence, returns element
function max(seq) {
    var v = seq.value[0];
    if (seq.value.length > 1) {
        for (var i = 1; i < seq.value.length; i++) {
            v = largest(v, seq.value[i]);
        }
    }
    return v;
}
//receives ArraySequence of ArraySequences, returns flat ArraySequence
function join(seqs) {
    var builder = [];
    for (var i = 0; i < seqs.value.length; i++) {
        builder = builder.concat(seqs.value[i].value);
    }
    return ArraySequence(builder);
}
//receives ArraySequences, returns ArraySequence
function zip(keys, items) {
    var entries = []
    var numEntries = Math.min(keys.value.length, items.value.length);
    for (var i = 0; i < numEntries; i++) {
        entries[i] = Entry(keys.value[i], items.value[i]);
    }
    return ArraySequence(entries);
}
//receives and returns ArraySequence
function coalesce(seq) {
    var newseq = [];
    for (var i = 0; i < seq.value.length; i++) {
        if (seq.value[i]) {
            newseq = newseq.concat(seq.value[i]);
        }
    }
    return ArraySequence(newseq);
}

//receives ArraySequence and CeylonObject, returns new ArraySequence
function append(seq, elem) {
    return ArraySequence(seq.value.concat(elem));
}
function prepend(seq, elem) {
    if (seq.getEmpty() === $true) {
        return Singleton(elem);
    } else {
        var sb = SequenceBuilder();
        sb.append(elem);
        sb.appendAll(seq);
        return sb.getSequence();
    }
}

//Receives ArraySequence, returns ArraySequence (with Entries)
function entries(seq) {
    var e = [];
    for (var i = 0; i < seq.value.length; i++) {
        e.push(Entry(Integer(i), seq.value[i]));
    }
    return ArraySequence(e);
}

exports.min=min;
exports.max=max;
exports.join=join;
exports.zip=zip;
exports.coalesce=coalesce;
exports.append=append;
exports.prepend=prepend;
exports.entries=entries;

//These are operators for handling nulls
function exists(value) {
    return value === null || value === undefined ? $false : $true;
}
function nonempty(value) {
    return value === null || value === undefined ? $false : Boolean$(value.getEmpty() === $false);
}

function isOfType(obj, typeName) {
    if (obj === null) return Boolean$(typeName==="ceylon.language.Nothing" || typeName==="ceylon.language.Void");
    var cons = obj.$$;
    if (cons === undefined) cons = obj.constructor;
    return Boolean$(typeName in cons.T$all);
}
function isOfTypes(obj, types) {
    if (obj===null) { //TODO check if this is right
        return types.l.indexOf('ceylon.language.Nothing')>=0 || types.l.indexOf('ceylon.language.Void')>=0;
    }
    var unions = false;
    var inters = true;
    var _ints=false;
    var cons = obj.$$;
    if (cons === undefined) cons = obj.constructor;
    for (var i = 0; i < types.l.length; i++) {
        var t = types.l[i];
        var partial = false;
        if (typeof t === 'string') {
            partial = t in cons.T$all;
        } else {
            partial = isOfTypes(obj, t);
        }
        if (types.t==='u') {
            unions = partial || unions;
        } else {
            inters = partial && inters;
            _ints=true;
        }
    }
    return _ints ? inters||unions : unions;
}

function className(obj) {
    if (obj === null) return String$('ceylon.language.Nothing');
    var cons = obj.$$;
    if (cons === undefined) cons = obj.constructor;
    return String$(cons.T$name);
}

function identityHash(obj) {
    return obj.identifiableObjectID;
}

exports.exists=exists;
exports.nonempty=nonempty;
exports.isOfType=isOfType;
exports.isOfTypes=isOfTypes;
exports.className=className;
exports.identityHash=identityHash;
<|endoftext|>


<commit_before>import { assert } from 'chai';
import sinon from 'sinon';
import Rectangle from 'kittik-shape-rectangle';
import Slide from '../../src/Slide';

describe('Animation::Slide', () => {
  it('Should properly get/set direction', () => {
    const animation = new Slide({direction: 'inLeft'});
    assert.equal(animation.getDirection(), 'inLeft');
    assert.instanceOf(animation.setDirection('inRight'), Slide);
    assert.equal(animation.getDirection(), 'inRight');
  });

  it('Should properly throw error if direction is not supports', () => {
    const animation = new Slide();
    assert.throws(() => animation.setDirection('wrong'), Error, 'Unknown direction: wrong');
  });

  it('Should properly parse coordinates for shape based on direction', () => {
    const animation = new Slide();
    const shape = new Rectangle();

    assert.instanceOf(animation.setDirection('inUp'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: 10, startY: -5, endX: 10, endY: 10});

    assert.instanceOf(animation.setDirection('inDown'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: 10,
      startY: process.stdout.rows + 5,
      endX: 10,
      endY: 10
    });

    assert.instanceOf(animation.setDirection('inLeft'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: -15, startY: 10, endX: 10, endY: 10});

    assert.instanceOf(animation.setDirection('inRight'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: process.stdout.columns + 15,
      startY: 10,
      endX: 10,
      endY: 10
    });

    assert.instanceOf(animation.setDirection('outUp'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: 10, startY: 10, endX: 10, endY: -5});

    assert.instanceOf(animation.setDirection('outDown'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: 10,
      startY: 10,
      endX: 10,
      endY: process.stdout.rows + 5
    });

    assert.instanceOf(animation.setDirection('outLeft'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: 10, startY: 10, endX: -15, endY: 10});

    assert.instanceOf(animation.setDirection('outRight'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: 10,
      startY: 10,
      endX: process.stdout.columns,
      endY: 10
    });
  });

  it('Should properly call the animate() method', done => {
    const animation = new Slide();
    const shape = new Rectangle();
    const mock = sinon.mock(animation);

    mock.expects('animateProperty').twice().returns(Promise.resolve());

    animation.animate(shape).then(() => {
      mock.verify();
      done();
    });
  });

  it('Should properly serialize animation to Object', () => {
    const animation = new Slide();

    assert.deepEqual(animation.toObject(), {
      type: 'Slide',
      options: {
        duration: 1000,
        easing: 'outQuad',
        direction: 'inRight'
      }
    });
  });
});
<commit_msg>test(animation): Add missing tests<commit_after>import { assert } from 'chai';
import sinon from 'sinon';
import Rectangle from 'kittik-shape-rectangle';
import Slide from '../../src/Slide';

describe('Animation::Slide', () => {
  it('Should properly get/set direction', () => {
    const animation = new Slide({direction: 'inLeft'});
    assert.equal(animation.getDirection(), 'inLeft');
    assert.instanceOf(animation.setDirection('inRight'), Slide);
    assert.equal(animation.getDirection(), 'inRight');
  });

  it('Should properly throw error if direction is not supports', () => {
    const animation = new Slide();
    assert.throws(() => animation.setDirection('wrong'), Error, 'Unknown direction: wrong');
  });

  it('Should properly parse coordinates for shape based on direction', () => {
    const animation = new Slide();
    const shape = new Rectangle();

    assert.instanceOf(animation.setDirection('inUp'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: 10, startY: -5, endX: 10, endY: 10});

    assert.instanceOf(animation.setDirection('inDown'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: 10,
      startY: process.stdout.rows + 5,
      endX: 10,
      endY: 10
    });

    assert.instanceOf(animation.setDirection('inLeft'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: -15, startY: 10, endX: 10, endY: 10});

    assert.instanceOf(animation.setDirection('inRight'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: process.stdout.columns + 15,
      startY: 10,
      endX: 10,
      endY: 10
    });

    assert.instanceOf(animation.setDirection('outUp'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: 10, startY: 10, endX: 10, endY: -5});

    assert.instanceOf(animation.setDirection('outDown'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: 10,
      startY: 10,
      endX: 10,
      endY: process.stdout.rows + 5
    });

    assert.instanceOf(animation.setDirection('outLeft'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {startX: 10, startY: 10, endX: -15, endY: 10});

    assert.instanceOf(animation.setDirection('outRight'), Slide);
    assert.deepEqual(animation._parseCoordinates(shape), {
      startX: 10,
      startY: 10,
      endX: process.stdout.columns,
      endY: 10
    });
  });

  it('Should properly call the animate() method', done => {
    const animation = new Slide();
    const shape = new Rectangle();
    const mock = sinon.mock(animation);

    mock.expects('animateProperty').twice().returns(Promise.resolve());

    animation.animate(shape).then(() => {
      mock.verify();
      done();
    });
  });

  it('Should properly serialize animation to Object', () => {
    const animation = new Slide();

    assert.deepEqual(animation.toObject(), {
      type: 'Slide',
      options: {
        duration: 1000,
        easing: 'outQuad',
        direction: 'inRight'
      }
    });
  });

  it('Should properly create Animation instance from object', () => {
    const obj = {
      type: 'Slide',
      options: {
        duration: 4000,
        easing: 'inOutExpo',
        direction: 'inLeft'
      }
    };

    const animation = Slide.fromObject(obj);
    assert.instanceOf(animation, Slide);
    assert.equal(animation.getDuration(), 4000);
    assert.equal(animation.getEasing(), 'inOutExpo');
    assert.equal(animation.getDirection(), 'inLeft');
    assert.isFunction(animation.animate);
  });
});
<|endoftext|>


<commit_before>/*
  Leaflet.AwesomeMarkers, a plugin that adds colorful iconic markers for Leaflet, based on the Font Awesome icons
  (c) 2012-2013, Lennard Voogdt

  http://leafletjs.com
  https://github.com/lvoogdt
*/
(function (window, document, undefined) {
/*
 * Leaflet.AwesomeMarkers assumes that you have already included the Leaflet library.
 */

L.AwesomeMarkers = {};

L.AwesomeMarkers.version = '1.0';

L.AwesomeMarkers.Icon = L.Icon.extend({
  options: {
    iconSize: [35, 45],
    iconAnchor:   [17, 42],
    popupAnchor: [1, -32],
    shadowAnchor: [10, 12],
    icon: 'font', // All the font-awesome icons are possible
    shadowSize: [36, 16],
    className: 'awesome-marker',
    color: 'blue' // red, orange, green, blue, purple
  },

  initialize: function (options) {
    options = L.setOptions(this, options);
  },

  createIcon: function () {
    var div = document.createElement('div'),
        options = this.options;

    if (options.icon) {
      div.innerHTML = this._createInner();
    }

    if (options.bgPos) {
      div.style.backgroundPosition =
              (-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px';
    }

    this._setIconStyles(div, 'icon-' + options.color);
    return div;
  },

  _createInner: function() {
    var iconClass;
    if(this.options.icon.slice(0,5)==="icon-"){
      iconClass=this.options.icon;
    }else{
      iconClass="icon-"+this.options.icon;
    }
    return "";
  },

  _setIconStyles: function (img, name) {
    var options = this.options,
        size = L.point(options[name + 'Size']),
        anchor;

    if (name === 'shadow') {
      anchor = L.point(options.shadowAnchor || options.iconAnchor);
    } else {
      anchor = L.point(options.iconAnchor);
    }

    if (!anchor && size) {
      anchor = size.divideBy(2, true);
    }

    img.className = 'awesome-marker-' + name + ' ' + options.className;

    if (anchor) {
      img.style.marginLeft = (-anchor.x) + 'px';
      img.style.marginTop  = (-anchor.y) + 'px';
    }

    if (size) {
      img.style.width  = size.x + 'px';
      img.style.height = size.y + 'px';
    }
  },

  createShadow: function () {
    var div = document.createElement('div'),
        options = this.options;

    this._setIconStyles(div, 'shadow');
    return div;
  }
});

L.AwesomeMarkers.icon = function (options) {
  return new L.AwesomeMarkers.Icon(options);
};

}(this, document));

<commit_msg>change default icon to home<commit_after>/*
  Leaflet.AwesomeMarkers, a plugin that adds colorful iconic markers for Leaflet, based on the Font Awesome icons
  (c) 2012-2013, Lennard Voogdt

  http://leafletjs.com
  https://github.com/lvoogdt
*/
(function (window, document, undefined) {
/*
 * Leaflet.AwesomeMarkers assumes that you have already included the Leaflet library.
 */

L.AwesomeMarkers = {};

L.AwesomeMarkers.version = '1.0';

L.AwesomeMarkers.Icon = L.Icon.extend({
  options: {
    iconSize: [35, 45],
    iconAnchor:   [17, 42],
    popupAnchor: [1, -32],
    shadowAnchor: [10, 12],
    shadowSize: [36, 16],
    className: 'awesome-marker',
    icon: 'home',
    color: 'blue'
  },

  initialize: function (options) {
    options = L.setOptions(this, options);
  },

  createIcon: function () {
    var div = document.createElement('div'),
        options = this.options;

    if (options.icon) {
      div.innerHTML = this._createInner();
    }

    if (options.bgPos) {
      div.style.backgroundPosition =
              (-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px';
    }

    this._setIconStyles(div, 'icon-' + options.color);
    return div;
  },

  _createInner: function() {
    var iconClass;
    if(this.options.icon.slice(0,5)==="icon-"){
      iconClass=this.options.icon;
    }else{
      iconClass="icon-"+this.options.icon;
    }
    return "";
  },

  _setIconStyles: function (img, name) {
    var options = this.options,
        size = L.point(options[name + 'Size']),
        anchor;

    if (name === 'shadow') {
      anchor = L.point(options.shadowAnchor || options.iconAnchor);
    } else {
      anchor = L.point(options.iconAnchor);
    }

    if (!anchor && size) {
      anchor = size.divideBy(2, true);
    }

    img.className = 'awesome-marker-' + name + ' ' + options.className;

    if (anchor) {
      img.style.marginLeft = (-anchor.x) + 'px';
      img.style.marginTop  = (-anchor.y) + 'px';
    }

    if (size) {
      img.style.width  = size.x + 'px';
      img.style.height = size.y + 'px';
    }
  },

  createShadow: function () {
    var div = document.createElement('div'),
        options = this.options;

    this._setIconStyles(div, 'shadow');
    return div;
  }
});

L.AwesomeMarkers.icon = function (options) {
  return new L.AwesomeMarkers.Icon(options);
};

}(this, document));

<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* 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.
*/

'use strict';

// MODULES //

var ReadableStream = require( 'readable-stream' ).Readable; // eslint-disable-line stdlib/no-redeclare
var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive;
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var copy = require( '@stdlib/utils/copy' );
var inherit = require( '@stdlib/utils/inherit' );
var setNonEnumerable = require( '@stdlib/utils/define-nonenumerable-property' );
var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var rarcsine = require( '@stdlib/random/iterators/arcsine' );
var DEFAULTS = require( './defaults.json' );
var validate = require( './validate.js' );
var debug = require( './debug.js' );

// MAIN //

/**
* Stream constructor for generating a stream of pseudorandom numbers drawn from an arcsine distribution.
*
* @constructor
* @param {number} a - minimum support
* @param {number} b - maximum support
* @param {Options} [options] - stream options
* @param {string} [options.sep='\n'] - separator used to join streamed data
* @param {boolean} [options.objectMode=false] - specifies whether the stream should operate in object mode
* @param {(string|null)} [options.encoding=null] - specifies how `Buffer` objects should be decoded to strings
* @param {NonNegativeNumber} [options.highWaterMark] - specifies the maximum number of bytes to store in the internal buffer before ceasing to generate additional pseudorandom numbers
* @param {NonNegativeInteger} [options.iter] - number of iterations
* @throws {TypeError} `a` must be a number
* @throws {TypeError} `b` must be a number
* @throws {RangeError} `a` must be less than `b`
* @throws {TypeError} options must be an object
* @throws {TypeError} must provide valid options
* @returns {RandomStream} Stream instance
*
* @example
* var inspectStream = require( '@stdlib/streams/utils/inspect' );
*
* function log( chunk ) {
*    console.log( chunk );
* }
*
* var opts = {
*     'iter': 10
* };
*
* var stream = new RandomStream( 2.0, 5.0, opts );
*
* stream.pipe( inspectStream( log )  );
*/
function RandomStream( a, b, options ) {
	var opts;
	var err;
	if ( !( this instanceof RandomStream ) ) {
		if ( arguments.length > 2 ) {
			return new RandomStream( a, b, options );
		}
		return new RandomStream( a, b );
	}
	if ( !isNumber( a ) || isnan( a ) ) {
		throw new TypeError( 'invalid argument. First argument must be a number primitive and not `NaN`. Value: `'+a+'`.' );
	}
	if ( !isNumber( b ) || isnan( b ) ) {
		throw new TypeError( 'invalid argument. Second argument must be a number primitive and not `NaN`. Value: `'+b+'`.' );
	}
	if ( a >= b ) {
		throw new RangeError( 'invalid argument. Minimum support `a` must be less than maximum support `b`. Value: `['+a+','+b+']`.');
	}
	opts = copy( DEFAULTS );
	if ( arguments.length > 2 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	// Make the stream a readable stream:
	debug( 'Creating a readable stream configured with the following options: %s.', JSON.stringify( opts ) );
	ReadableStream.call( this, opts );

	// Destruction state:
	setNonEnumerable( this, '_destroyed', false );

	// Cache whether the stream is operating in object mode:
	setNonEnumerable( this, '_objectMode', opts.objectMode );

	// Cache the separator:
	setNonEnumerable( this, '_sep', opts.sep );

	// Initialize an iteration counter:
	setNonEnumerable( this, '_iter', 0 );

	// Create the underlying PRNG iterator:
	setReadOnly( this, 'prng', rarcsine( a, b, opts ) );

	return this;
}

/*
* Inherit from the `ReadableStream` prototype.
*/
inherit( RandomStream, ReadableStream );

/**
* Implements the `_read` method.
*
* @private
* @memberof RandomStream.prototype
* @function _read
* @param {number} size - number (of bytes) to read
*/
RandomStream.prototype._read = require( './_read.js' ); // eslint-disable-line no-underscore-dangle

/**
* Gracefully destroys a stream, providing backwards compatibility.
*
* @memberof RandomStream.prototype
* @function destroy
* @param {Object} [error] - optional error message
* @returns {RandomStream} Stream instance
*/
RandomStream.prototype.destroy = require( './destroy.js' );

// EXPORTS //

module.exports = RandomStream;
<commit_msg>Rename variable<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* 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.
*/

'use strict';

// MODULES //

var Readable = require( 'readable-stream' ).Readable;
var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive;
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var copy = require( '@stdlib/utils/copy' );
var inherit = require( '@stdlib/utils/inherit' );
var setNonEnumerable = require( '@stdlib/utils/define-nonenumerable-property' );
var setReadOnly = require( '@stdlib/utils/define-read-only-property' );
var rarcsine = require( '@stdlib/random/iterators/arcsine' );
var DEFAULTS = require( './defaults.json' );
var validate = require( './validate.js' );
var debug = require( './debug.js' );

// MAIN //

/**
* Stream constructor for generating a stream of pseudorandom numbers drawn from an arcsine distribution.
*
* @constructor
* @param {number} a - minimum support
* @param {number} b - maximum support
* @param {Options} [options] - stream options
* @param {string} [options.sep='\n'] - separator used to join streamed data
* @param {boolean} [options.objectMode=false] - specifies whether the stream should operate in object mode
* @param {(string|null)} [options.encoding=null] - specifies how `Buffer` objects should be decoded to strings
* @param {NonNegativeNumber} [options.highWaterMark] - specifies the maximum number of bytes to store in the internal buffer before ceasing to generate additional pseudorandom numbers
* @param {NonNegativeInteger} [options.iter] - number of iterations
* @throws {TypeError} `a` must be a number
* @throws {TypeError} `b` must be a number
* @throws {RangeError} `a` must be less than `b`
* @throws {TypeError} options must be an object
* @throws {TypeError} must provide valid options
* @returns {RandomStream} Stream instance
*
* @example
* var inspectStream = require( '@stdlib/streams/utils/inspect' );
*
* function log( chunk ) {
*    console.log( chunk );
* }
*
* var opts = {
*     'iter': 10
* };
*
* var stream = new RandomStream( 2.0, 5.0, opts );
*
* stream.pipe( inspectStream( log )  );
*/
function RandomStream( a, b, options ) {
	var opts;
	var err;
	if ( !( this instanceof RandomStream ) ) {
		if ( arguments.length > 2 ) {
			return new RandomStream( a, b, options );
		}
		return new RandomStream( a, b );
	}
	if ( !isNumber( a ) || isnan( a ) ) {
		throw new TypeError( 'invalid argument. First argument must be a number primitive and not `NaN`. Value: `'+a+'`.' );
	}
	if ( !isNumber( b ) || isnan( b ) ) {
		throw new TypeError( 'invalid argument. Second argument must be a number primitive and not `NaN`. Value: `'+b+'`.' );
	}
	if ( a >= b ) {
		throw new RangeError( 'invalid argument. Minimum support `a` must be less than maximum support `b`. Value: `['+a+','+b+']`.');
	}
	opts = copy( DEFAULTS );
	if ( arguments.length > 2 ) {
		err = validate( opts, options );
		if ( err ) {
			throw err;
		}
	}
	// Make the stream a readable stream:
	debug( 'Creating a readable stream configured with the following options: %s.', JSON.stringify( opts ) );
	Readable.call( this, opts );

	// Destruction state:
	setNonEnumerable( this, '_destroyed', false );

	// Cache whether the stream is operating in object mode:
	setNonEnumerable( this, '_objectMode', opts.objectMode );

	// Cache the separator:
	setNonEnumerable( this, '_sep', opts.sep );

	// Initialize an iteration counter:
	setNonEnumerable( this, '_iter', 0 );

	// Create the underlying PRNG iterator:
	setReadOnly( this, 'prng', rarcsine( a, b, opts ) );

	return this;
}

/*
* Inherit from the `Readable` prototype.
*/
inherit( RandomStream, Readable );

/**
* Implements the `_read` method.
*
* @private
* @memberof RandomStream.prototype
* @function _read
* @param {number} size - number (of bytes) to read
*/
RandomStream.prototype._read = require( './_read.js' ); // eslint-disable-line no-underscore-dangle

/**
* Gracefully destroys a stream, providing backwards compatibility.
*
* @memberof RandomStream.prototype
* @function destroy
* @param {Object} [error] - optional error message
* @returns {RandomStream} Stream instance
*/
RandomStream.prototype.destroy = require( './destroy.js' );

// EXPORTS //

module.exports = RandomStream;
<|endoftext|>


<commit_before>/*!
GPII Flow Manager

Copyright 2012 OCAD University

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/

(function () {

    "use strict";

    var fluid = require("infusion"),
        path = require("path"),
        gpii = fluid.registerNamespace("gpii");

    fluid.require("kettle", require);
    fluid.require("./UserLogin.js", require);
    fluid.require("./Settings.js", require);
    fluid.require("./UserLogout.js", require);
    fluid.require("./UserSave.js", require);
    fluid.require("./UserUpdate.js", require);

    fluid.require("lifecycleManager", require);

    fluid.defaults("gpii.flowManager", {
        gradeNames: ["kettle.app", "autoInit"],
        urls: {
            preferences: "",
            deviceReporter: "",
            matchMaker: "",
            solutionsReporter: "",
            lifecycleManagerServer: ""
        },
        root: path.join(__dirname, ".."),
        components: {
            preferencesDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.preferences",
                    termMap: {
                        token: "%token"
                    }
                }
            },
            deviceReporterDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.deviceReporter"
                }
            },
            matchMakerDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.matchMaker",
                    writable: true
                }
            },
            lifecycleManagerServerDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.lifecycleManagerServer",
                    writable: true,
                    termMap: {
                        operation: "%operation",
                        token: "%token"
                    }
                }
            }
        },
        handlers: {
            userLogin: {
                route: "/user/:token/login",
                type: "get"
            },
            userLogout: {
                route: "/user/:token/logout",
                type: "get"
            }
        }
    });

    fluid.defaults("gpii.flowManager.dev", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        distributeOptions: {
            source: "{that}.options.urlExpanderGradeNames",
            target: "{that urlExpander}.options.gradeNames"
        },
        urlExpanderGradeNames: ["kettle.urlExpander.development"]
    });

    fluid.defaults("gpii.flowManager.save", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        handlers: {
            userSave: {
                route: "/save/:token?",
                type: "post"
            }
        },
        distributeOptions: {
            source: "{that}.options.writable",
            target: "{that > preferencesDataSource}.options.writable"
        },
        writable: true
    });

    fluid.defaults("gpii.flowManager.io", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        handlers: {
            userUpdate: {
                route: "/update",
                type: "io",
                useSession: "existing"
            },
            userLogin: {
                useSession: "create"
            },
            userLogout: {
                useSession: "existing"
            },
            userSave: {
                useSession: "existing"
            }
        }
    });

    fluid.defaults("gpii.flowManager.io.server", {
        gradeNames: ["fluid.littleComponent", "autoInit"],
        distributeOptions: {
            source: "{that}.options.validateToken",
            target: "{that > sessionManager}.options.invokers.validate"
        },
        validateToken: {
            funcName: "gpii.flowManager.io.validateToken"
        }
    });

    gpii.flowManager.io.validateToken = function (request) {
        return !!request.session && !!request.session.session.token;
    };

    fluid.defaults("gpii.flowManager.cloudBased", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        mergePolicy: {
            handleUnsupported: "noexpand"
        },
        components: {
            deviceReporterDataSource: {
                type: "fluid.emptySubcomponent"
            },
            lifecycleManagerServerDataSource: {
                type: "fluid.emptySubcomponent"
            }
        },
        urls: {
            deviceReporter: "",
        },
        handlers: {
            settings: {
                route: "/:token/settings/:device",
                type: "get"
            },
            userLogin: null,
            userLogout: null
        }
    });

    fluid.defaults("kettle.gradeLinkageRecord.requestSession", {
        gradeNames: ["autoInit", "fluid.gradeLinkageRecord"],
        contextGrades: ["kettle.use.session.request"],
        resultGrades: ["gpii.flowManager.requestSession"]
    });

    fluid.defaults("gpii.flowManager.requestSession", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        distributeOptions: {
            source: "{that}.options.handlerGradeNames",
            target: "{that handler}.options.gradeNames"
        },
        handlerGradeNames: ["gpii.flowManager.handlerSession"]
    })

})();<commit_msg>GPII-75: simplified validate token utility.<commit_after>/*!
GPII Flow Manager

Copyright 2012 OCAD University

Licensed under the New BSD license. You may not use this file except in
compliance with this License.

You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/

(function () {

    "use strict";

    var fluid = require("infusion"),
        path = require("path"),
        gpii = fluid.registerNamespace("gpii");

    fluid.require("kettle", require);
    fluid.require("./UserLogin.js", require);
    fluid.require("./Settings.js", require);
    fluid.require("./UserLogout.js", require);
    fluid.require("./UserSave.js", require);
    fluid.require("./UserUpdate.js", require);

    fluid.require("lifecycleManager", require);

    fluid.defaults("gpii.flowManager", {
        gradeNames: ["kettle.app", "autoInit"],
        urls: {
            preferences: "",
            deviceReporter: "",
            matchMaker: "",
            solutionsReporter: "",
            lifecycleManagerServer: ""
        },
        root: path.join(__dirname, ".."),
        components: {
            preferencesDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.preferences",
                    termMap: {
                        token: "%token"
                    }
                }
            },
            deviceReporterDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.deviceReporter"
                }
            },
            matchMakerDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.matchMaker",
                    writable: true
                }
            },
            lifecycleManagerServerDataSource: {
                type: "kettle.dataSource.URL",
                options: {
                    gradeNames: ["kettle.dataSource.simpleCallbackWrapper"],
                    url: "{gpii.flowManager}.options.urls.lifecycleManagerServer",
                    writable: true,
                    termMap: {
                        operation: "%operation",
                        token: "%token"
                    }
                }
            }
        },
        handlers: {
            userLogin: {
                route: "/user/:token/login",
                type: "get"
            },
            userLogout: {
                route: "/user/:token/logout",
                type: "get"
            }
        }
    });

    fluid.defaults("gpii.flowManager.dev", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        distributeOptions: {
            source: "{that}.options.urlExpanderGradeNames",
            target: "{that urlExpander}.options.gradeNames"
        },
        urlExpanderGradeNames: ["kettle.urlExpander.development"]
    });

    fluid.defaults("gpii.flowManager.save", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        handlers: {
            userSave: {
                route: "/save/:token?",
                type: "post"
            }
        },
        distributeOptions: {
            source: "{that}.options.writable",
            target: "{that > preferencesDataSource}.options.writable"
        },
        writable: true
    });

    fluid.defaults("gpii.flowManager.io", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        handlers: {
            userUpdate: {
                route: "/update",
                type: "io",
                useSession: "existing"
            },
            userLogin: {
                useSession: "create"
            },
            userLogout: {
                useSession: "existing"
            },
            userSave: {
                useSession: "existing"
            }
        }
    });

    fluid.defaults("gpii.flowManager.io.server", {
        gradeNames: ["fluid.littleComponent", "autoInit"],
        distributeOptions: {
            source: "{that}.options.validateToken",
            target: "{that > sessionManager}.options.invokers.validate"
        },
        validateToken: {
            funcName: "gpii.flowManager.io.validateToken"
        }
    });

    gpii.flowManager.io.validateToken = function (request) {
        return request.session && request.session.session.token;
    };

    fluid.defaults("gpii.flowManager.cloudBased", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        mergePolicy: {
            handleUnsupported: "noexpand"
        },
        components: {
            deviceReporterDataSource: {
                type: "fluid.emptySubcomponent"
            },
            lifecycleManagerServerDataSource: {
                type: "fluid.emptySubcomponent"
            }
        },
        urls: {
            deviceReporter: "",
        },
        handlers: {
            settings: {
                route: "/:token/settings/:device",
                type: "get"
            },
            userLogin: null,
            userLogout: null
        }
    });

    fluid.defaults("kettle.gradeLinkageRecord.requestSession", {
        gradeNames: ["autoInit", "fluid.gradeLinkageRecord"],
        contextGrades: ["kettle.use.session.request"],
        resultGrades: ["gpii.flowManager.requestSession"]
    });

    fluid.defaults("gpii.flowManager.requestSession", {
        gradeNames: ["autoInit", "fluid.littleComponent"],
        distributeOptions: {
            source: "{that}.options.handlerGradeNames",
            target: "{that handler}.options.gradeNames"
        },
        handlerGradeNames: ["gpii.flowManager.handlerSession"]
    })

})();<|endoftext|>