<commit_before>// - load cookies on request start
// - add helper to store cookies
// - autosave cookies on request end
//

'use strict';

var _      = require('lodash');
var cookie = require('cookie');

module.exports = function (N) {

  // Parse cookies
  //
  N.wire.before('server_chain:*', { priority: -90 }, function cookies_start(env, callback) {

    // Helper to read incoming cookies from client.
    function getCookie(name) {
      return getCookie.storage[name];
    }
    getCookie.storage = {};

    // Helper to write outgoing cookies from server.
    function setCookie(name, value, options) {
      setCookie.storage[name] = { value: value, options: options || {} };
    }
    setCookie.storage = {};

    // Helper to change value or options of already created outgoing cookie.
    function updateCookie(name, options) {
      options = options || {};

      var cookie = setCookie.storage[name];

      if (!cookie) {
        N.logger.error('Unable to update non-existent outgoing cookie %j', name);
        return;
      }

      cookie.value = options.value || cookie.value;
      _.extend(cookie.options, _.omit(options, 'value'));
    }

    // Parse incoming request cookies.
    if (env.origin.req.headers.cookie) {
      try {
        getCookie.storage = cookie.parse(env.origin.req.headers.cookie);
      } catch (err) {
        callback(err);
        return;
      }
    }

    // Expose.
    env.extras.getCookie    = getCookie;
    env.extras.setCookie    = setCookie;
    env.extras.updateCookie = updateCookie;
    callback();
  });

  // Send cookies that must be set on the client
  //
  N.wire.after('server_chain:*', { priority: 90, ensure: true }, function cookies_end(env, callback) {
    var cookies = [];

    // prepare list of cookies to be sent
    _.each(env.extras.setCookie.storage, function (data, name) {
      var options = _.extend({
        httpOnly: true
      , path: '/'
      }, data.options);

      cookies.push(cookie.serialize(name, data.value, options));
    });

    env.headers['Set-Cookie'] = cookies;
    callback();
  });
};
<commit_msg>Drop `env.extras.updateCookie`.<commit_after>// - load cookies on request start
// - add helper to store cookies
// - autosave cookies on request end
//

'use strict';

var _      = require('lodash');
var cookie = require('cookie');

module.exports = function (N) {

  // Parse cookies
  //
  N.wire.before('server_chain:*', { priority: -90 }, function cookies_start(env, callback) {

    // Helper to read incoming cookies from client.
    function getCookie(name) {
      return getCookie.storage[name];
    }
    getCookie.storage = {};

    // Helper to write outgoing cookies from server.
    function setCookie(name, value, options) {
      setCookie.storage[name] = { value: value, options: options || {} };
    }
    setCookie.storage = {};

    // Parse incoming request cookies.
    if (env.origin.req.headers.cookie) {
      try {
        getCookie.storage = cookie.parse(env.origin.req.headers.cookie);
      } catch (err) {
        callback(err);
        return;
      }
    }

    // Expose.
    env.extras.getCookie = getCookie;
    env.extras.setCookie = setCookie;
    callback();
  });

  // Send cookies that must be set on the client
  //
  N.wire.after('server_chain:*', { priority: 90, ensure: true }, function cookies_end(env, callback) {
    var cookies = [];

    // prepare list of cookies to be sent
    _.each(env.extras.setCookie.storage, function (data, name) {
      var options = _.extend({
        httpOnly: true
      , path: '/'
      }, data.options);

      cookies.push(cookie.serialize(name, data.value, options));
    });

    env.headers['Set-Cookie'] = cookies;
    callback();
  });
};
<|endoftext|>


<commit_before>import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  history: [],
  picks: [],
  players: [],
  settings: {
    app: {
      domes: ['ARI', 'ATL', 'DAL', 'DET', 'HOU', 'IND', 'MIN', 'NOS'],
      draftOrderTypes: {
        'random': 'ran',
        'sequential': 'seq',
        'serpentine': 'ser'
      },
      positions: [
        { key: 'QB', name: 'QB', category: 'Offense', order: 1 },
        { key: 'RB', name: 'RB', category: 'Offense', order: 2 },
        { key: 'WR', name: 'WR', category: 'Offense', order: 3 },
        { key: 'TE', name: 'TE', category: 'Offense', order: 4 },
        { key: 'DE', name: 'Defensive End', category: 'Defense', order: 5 },
        { key: 'DT', name: 'Defensive Tackle', category: 'Defense', order: 6 },
        { key: 'LB', name: 'Linebacker', category: 'Defense', order: 7 },
        { key: 'CB', name: 'Cornerback', category: 'Defense', order: 8 },
        { key: 'S', name: 'Safety', category: 'Defense', order: 9 },
        { key: 'Off', name: 'Offense', category: 'Team', order: 10 },
        { key: 'Def', name: 'Defense/Special Teams', category: 'Team', order: 11 },
        { key: 'TMQB', name: 'Team QB', category: 'Team', order: 12 },
        { key: 'TMRB', name: 'Team RB', category: 'Team', order: 13 },
        { key: 'TMWR', name: 'Team WR', category: 'Team', order: 14 },
        { key: 'TMTE', name: 'Team TE', category: 'Team', order: 15 },
        { key: 'TMDL', name: 'Team Defensive Line', category: 'Team', order: 16 },
        { key: 'TMLB', name: 'Team Linebackers', category: 'Team', order: 17 },
        { key: 'TMDB', name: 'Team Defensive Backs', category: 'Team', order: 18 },
        { key: 'TMPK', name: 'Team Place Kicker', category: 'Team', order: 19 },
        { key: 'TMPN', name: 'Team Punter', category: 'Team', order: 20 },
        { key: 'ST', name: 'Special Teams', category: 'Other', order: 21 },
        { key: 'PK', name: 'Kicker', category: 'Other', order: 22 },
        { key: 'PN', name: 'Punter', category: 'Other', order: 23 },
        { key: 'Coach', name: 'Coach', category: 'Other', order: 24 },
        { key: 'XX', name: 'Unknown', order: 25 }
      ]
    },
    /*
      Family settings
    */
    league: {
      draftOrderType: 'ser',
      keepers: false, // can't use until code handles only some players having keepers
      positions: [
        { key: 'QB', min: 2, max: 4 },
        { key: 'RB', min: 2, max: 6 },
        { key: 'WR', min: 2, max: 6 },
        { key: 'TE', min: 1, max: 6 },
        { key: 'PK', min: 1, max: 3 },
        { key: 'Def', min: 1, max: 3 }
      ],
      rosterSize: 18,
      secondsPerPick: 0,
      teams: [
        { name: 'Ya Ertz Me? Foles Reals', owner: 'Matt Koser', draftOrder: 1 },
        { name: 'Queens of the Forest', owner: 'Megan Hutt', draftOrder: 2 },
        { name: 'Kung Fu Manda', owner: 'Amanda Koser', draftOrder: 3 },
        { name: 'PApa Phillyman', owner: 'Don Koser', draftOrder: 4 },
        { name: 'Insert Pun Here', owner: 'Brian Koser', draftOrder: 5, isUser: true },
        { name: 'Mom’s Marauders', owner: 'Sue Koser', draftOrder: 6 },
        { name: 'Sith Knights', owner: 'Zach Koser', draftOrder: 7 },
        { name: 'Pensacola Pandas', owner: 'Josh Hutt', draftOrder: 8 }
      ]
    },
    team: {
      idealSize: [
        { positionKey: 'QB', count: 3 },
        { positionKey: 'RB', count: 5 },
        { positionKey: 'WR', count: 6 },
        { positionKey: 'TE', count: 2 },
        { positionKey: 'PK', count: 1 },
        { positionKey: 'Def', count: 1 }
      ],
      rankings: [],
      tags: [
        { name: 'avoid', players: ['2842', '6982', '7942', '9054', '9101', '9898', '10302', '10722', '11180', '11201', '11384', '11454', '11642', '11678', '11746', '12155', '13113', '13115', '13116', '13188'] },
        { name: 'handcuff', players: ['9087', '10300', '12626', '13138'] },
        { name: 'injuryprone', players: ['9054', '9693', '9823', '9902', '10695', '10722', '11248', '11670', '12151', '12186'] },
        { name: 'overpriced', players: ['8670', '9099', '9662', '9693', '9823', '11644'] },
        { name: 'target', players: ['0509', '0527', '7394', '7877', '8360', '8670', '8673', '9087', '9525', '9881', '9925', '10261', '10273', '10313', '10413', '10506', '10703', '10709', '11516', '11668', '11688', '11695', '12141', '12626', '13129'] }
      ],
      tiers: [
        { positionKey: 'QB', sizes: [3, 7, 3, 6, 6, 7] },
        { positionKey: 'RB', sizes: [] },
        { positionKey: 'WR', sizes: [] },
        { positionKey: 'TE', sizes: [1, 10] },
        { positionKey: 'PK', sizes: [] },
        { positionKey: 'Def', sizes: [4, 3] }
      ]
    }
    /*
      CTS settings
    */
    // league: {
    //   draftOrderType: 'ser',
    //   keepers: false,
    //   positions: [
    //     { key: 'QB', min: 1, max: 6 },
    //     { key: 'RB', min: 2, max: 6 },
    //     { key: 'WR', min: 2, max: 6 },
    //     { key: 'TE', min: 1, max: 6 },
    //     { key: 'PK', min: 1, max: 5 },
    //     { key: 'Def', min: 1, max: 5 }
    //   ],
    //   rosterSize: 14,
    //   secondsPerPick: 60,
    //   teams: [
    //     { name: 'Chase', owner: 'Chase Oubre', draftOrder: 1 },
    //     { name: 'Slow White Bronco', owner: 'Luke Smith', draftOrder: 2 },
    //     { name: 'Scott', owner: 'Scott Hartwell', draftOrder: 3 },
    //     { name: 'Kristymacs', owner: 'Kristy King', draftOrder: 4 },
    //     { name: 'yerfdogt', owner: 'Tim Godfrey', draftOrder: 5 },
    //     { name: 'tclinkscales', owner: 'Travis Clinkscales', draftOrder: 6 },
    //     { name: 'My Team Suxx', owner: 'Steven Grimes', draftOrder: 7 },
    //     { name: 'Pun Goes Here', owner: 'Brian Koser', draftOrder: 8, isUser: true }
    //     // { name: 'Team 1', owner: '?', draftOrder: 1 },
    //     // { name: 'Team 2', owner: '?', draftOrder: 2, isUser: true },
    //     // { name: 'Team 3', owner: '?', draftOrder: 3 },
    //     // { name: 'Team 4', owner: '?', draftOrder: 4 },
    //     // { name: 'Team 5', owner: '?', draftOrder: 5 },
    //     // { name: 'Team 6', owner: '?', draftOrder: 6 },
    //     // { name: 'Team 7', owner: '?', draftOrder: 7 },
    //     // { name: 'Team 8', owner: '?', draftOrder: 8 }
    //   ]
    // },
    // team: {
    //   idealSize: [
    //     { positionKey: 'QB', count: 3 },
    //     { positionKey: 'RB', count: 4 },
    //     { positionKey: 'WR', count: 4 },
    //     { positionKey: 'TE', count: 1 },
    //     { positionKey: 'PK', count: 1 },
    //     { positionKey: 'Def', count: 1 }
    //   ],
    //   rankings: [],
    //   tags: [
    //     { name: 'avoid', players: ['2842', '6982', '7942', '9054', '9101', '9898', '10302', '10722', '11180', '11201', '11384', '11454', '11642', '11678', '11746', '12155', '13113', '13115', '13116', '13188'] },
    //     { name: 'handcuff', players: ['9087', '10300', '12626', '13138'] },
    //     { name: 'injuryprone', players: ['9054', '9693', '9823', '9902', '10695', '10722', '11248', '11670', '12151', '12186'] },
    //     { name: 'overpriced', players: ['8670', '9099', '9662', '9693', '9823', '11644'] },
    //     { name: 'target', players: ['0509', '0527', '7394', '7877', '8360', '8670', '8673', '9087', '9525', '9881', '9925', '10261', '10273', '10313', '10413', '10506', '10703', '10709', '11516', '11668', '11688', '11695', '12141', '12626', '13129'] }
    //   ],
    //   tiers: [
    //     { positionKey: 'QB', sizes: [3, 7, 3, 6, 6, 7] },
    //     { positionKey: 'RB', sizes: [] },
    //     { positionKey: 'WR', sizes: [] },
    //     { positionKey: 'TE', sizes: [1, 10] },
    //     { positionKey: 'PK', sizes: [] },
    //     { positionKey: 'Def', sizes: [4, 3] }
    //   ]
    // }

    /*
      Crossroads settings
    */
    // league: {
    //   draftOrderType: 'ser',
    //   positions: [
    //     { key: 'QB', min: 1, max: 4 },
    //     { key: 'RB', min: 1, max: 8 },
    //     { key: 'WR', min: 2, max: 8 },
    //     { key: 'TE', min: 1, max: 3 },
    //     { key: 'PK', min: 1, max: 3 },
    //     { key: 'Def', min: 1, max: 3 },
    //     { key: 'Coach', min: 1, max: 10 }
    //   ],
    //   rosterSize: 17,
    //   secondsPerPick: 60,
    //   teams: [
    //     { name: 'The Commish', owner: 'Aaron Smith', draftOrder: 12, keeper: '7836' },
    //     { name: '’Aints -', owner: 'Matt McLean' draftOrder: 11 },
    //     { name: 'Play It Again Sam', owner: 'Brian Koser', draftOrder: 10, isUser: true },
    //     { name: 'O. J.', owner: 'Tuck Chastain', draftOrder: 9 },
    //     { name: 'Buck stops here', owner: 'Terry Buckner', draftOrder: 8 },
    //     { name: 'Small Arms Dealer', owner: 'Scott Hopkins', draftOrder: 7 },
    //     { name: 'Fluoride Bandits', owner: 'Shane Herrington', draftOrder: 6 },
    //     { name: 'Brown Mikes DeadBeat Bums', owner: 'Brown Mike',  draftOrder: 5 },
    //     { name: 'Alabama Yard rats', owner: 'Philip Quinney', draftOrder: 4 },
    //     { name: 'Cam Burglar', owner: 'Justin Tolbert', draftOrder: 3 },
    //     { name: 'Amen Corner', owner: 'Ben Harris', draftOrder: 2 },
    //     { name: 'Crossroads Zealots', owner: 'Joe Chastain', draftOrder: 1 }
    //   ]
    // },
    // team: {
    //   idealSize: [
    //     { positionKey: 'QB', count: 2 },
    //     { positionKey: 'RB', count: 4 },
    //     { positionKey: 'WR', count: 5 },
    //     { positionKey: 'TE', count: 2 },
    //     { positionKey: 'PK', count: 1 },
    //     { positionKey: 'Def', count: 2 },
    //     { positionKey: 'Coach', count: 1 }
    //   ]
    // }
  }
}

const mutations = {
  ADDPICK (state, pick) {
    state.picks.push(pick)
  },
  ADDSTATEENTRY (state, entry) {
    state.history.push(entry)
  },
  SETPLAYERS (state, players) {
    state.players = players
  },
  SETTEAMRANKINGS (state, rankings) {
    state.settings.team.rankings = rankings
  },
  UNDOLASTPICK (state) {
    state.picks.pop()
  },
  UNDOSTATEENTRY (state) {
    state.history.pop()
  },
  UPDATEKEEPERS (state, keeperPicks) {
    state.picks = keeperPicks
  }
}

export default new Vuex.Store({
  state,
  mutations
})
<commit_msg>Load teams<commit_after>import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  history: [],
  picks: [],
  players: [],
  settings: {
    app: {
      domes: ['ARI', 'ATL', 'DAL', 'DET', 'HOU', 'IND', 'MIN', 'NOS'],
      draftOrderTypes: {
        'random': 'ran',
        'sequential': 'seq',
        'serpentine': 'ser'
      },
      positions: [
        { key: 'QB', name: 'QB', category: 'Offense', order: 1 },
        { key: 'RB', name: 'RB', category: 'Offense', order: 2 },
        { key: 'WR', name: 'WR', category: 'Offense', order: 3 },
        { key: 'TE', name: 'TE', category: 'Offense', order: 4 },
        { key: 'DE', name: 'Defensive End', category: 'Defense', order: 5 },
        { key: 'DT', name: 'Defensive Tackle', category: 'Defense', order: 6 },
        { key: 'LB', name: 'Linebacker', category: 'Defense', order: 7 },
        { key: 'CB', name: 'Cornerback', category: 'Defense', order: 8 },
        { key: 'S', name: 'Safety', category: 'Defense', order: 9 },
        { key: 'Off', name: 'Offense', category: 'Team', order: 10 },
        { key: 'Def', name: 'Defense/Special Teams', category: 'Team', order: 11 },
        { key: 'TMQB', name: 'Team QB', category: 'Team', order: 12 },
        { key: 'TMRB', name: 'Team RB', category: 'Team', order: 13 },
        { key: 'TMWR', name: 'Team WR', category: 'Team', order: 14 },
        { key: 'TMTE', name: 'Team TE', category: 'Team', order: 15 },
        { key: 'TMDL', name: 'Team Defensive Line', category: 'Team', order: 16 },
        { key: 'TMLB', name: 'Team Linebackers', category: 'Team', order: 17 },
        { key: 'TMDB', name: 'Team Defensive Backs', category: 'Team', order: 18 },
        { key: 'TMPK', name: 'Team Place Kicker', category: 'Team', order: 19 },
        { key: 'TMPN', name: 'Team Punter', category: 'Team', order: 20 },
        { key: 'ST', name: 'Special Teams', category: 'Other', order: 21 },
        { key: 'PK', name: 'Kicker', category: 'Other', order: 22 },
        { key: 'PN', name: 'Punter', category: 'Other', order: 23 },
        { key: 'Coach', name: 'Coach', category: 'Other', order: 24 },
        { key: 'XX', name: 'Unknown', order: 25 }
      ]
    },
    /*
      Family settings
    */
    league: {
      draftOrderType: 'ser',
      keepers: false, // can't use until code handles only some players having keepers
      positions: [
        { key: 'QB', min: 2, max: 4 },
        { key: 'RB', min: 2, max: 6 },
        { key: 'WR', min: 2, max: 6 },
        { key: 'TE', min: 1, max: 6 },
        { key: 'PK', min: 1, max: 3 },
        { key: 'Def', min: 1, max: 3 }
      ],
      rosterSize: 18,
      secondsPerPick: 0,
      teams: [
        { name: 'Ya Ertz Me? Foles Reals', owner: 'Matt Koser', draftOrder: 1 },
        { name: 'Queens of the Forest', owner: 'Megan Hutt', draftOrder: 2 },
        { name: 'Kung Fu Manda', owner: 'Amanda Koser', draftOrder: 3 },
        { name: 'PApa Phillyman', owner: 'Don Koser', draftOrder: 4 },
        { name: 'Insert Pun Here', owner: 'Brian Koser', draftOrder: 5, isUser: true },
        { name: 'Mom’s Marauders', owner: 'Sue Koser', draftOrder: 6 },
        { name: 'Sith Knights', owner: 'Zach Koser', draftOrder: 7 },
        { name: 'Melissa Team', owner: 'Melissa Koser', draftOrder: 8 },
        { name: 'Melody Team', owner: 'Melody Tijerina', draftOrder: 9 },
        { name: 'Tim Team', owner: 'Tim Binzel', draftOrder: 10 },
        { name: 'Nathan Team', owner: 'Nathan Reimers', draftOrder: 11 },
        { name: 'Pensacola Pandas', owner: 'Josh Hutt', draftOrder: 12 }
      ]
    },
    team: {
      idealSize: [
        { positionKey: 'QB', count: 3 },
        { positionKey: 'RB', count: 5 },
        { positionKey: 'WR', count: 6 },
        { positionKey: 'TE', count: 2 },
        { positionKey: 'PK', count: 1 },
        { positionKey: 'Def', count: 1 }
      ],
      rankings: [],
      tags: [
        { name: 'avoid', players: ['2842', '6982', '7942', '9054', '9101', '9898', '10302', '10722', '11180', '11201', '11384', '11454', '11642', '11678', '11746', '12155', '13113', '13115', '13116', '13188'] },
        { name: 'handcuff', players: ['9087', '10300', '12626', '13138'] },
        { name: 'injuryprone', players: ['9054', '9693', '9823', '9902', '10695', '10722', '11248', '11670', '12151', '12186'] },
        { name: 'overpriced', players: ['8670', '9099', '9662', '9693', '9823', '11644'] },
        { name: 'target', players: ['0509', '0527', '7394', '7877', '8360', '8670', '8673', '9087', '9525', '9881', '9925', '10261', '10273', '10313', '10413', '10506', '10703', '10709', '11516', '11668', '11688', '11695', '12141', '12626', '13129'] }
      ],
      tiers: [
        { positionKey: 'QB', sizes: [3, 7, 3, 6, 6, 7] },
        { positionKey: 'RB', sizes: [] },
        { positionKey: 'WR', sizes: [] },
        { positionKey: 'TE', sizes: [1, 10] },
        { positionKey: 'PK', sizes: [] },
        { positionKey: 'Def', sizes: [4, 3] }
      ]
    }
    /*
      CTS settings
    */
    // league: {
    //   draftOrderType: 'ser',
    //   keepers: false,
    //   positions: [
    //     { key: 'QB', min: 1, max: 6 },
    //     { key: 'RB', min: 2, max: 6 },
    //     { key: 'WR', min: 2, max: 6 },
    //     { key: 'TE', min: 1, max: 6 },
    //     { key: 'PK', min: 1, max: 5 },
    //     { key: 'Def', min: 1, max: 5 }
    //   ],
    //   rosterSize: 14,
    //   secondsPerPick: 60,
    //   teams: [
    //     { name: 'Chase', owner: 'Chase Oubre', draftOrder: 1 },
    //     { name: 'Slow White Bronco', owner: 'Luke Smith', draftOrder: 2 },
    //     { name: 'Scott', owner: 'Scott Hartwell', draftOrder: 3 },
    //     { name: 'Kristymacs', owner: 'Kristy King', draftOrder: 4 },
    //     { name: 'yerfdogt', owner: 'Tim Godfrey', draftOrder: 5 },
    //     { name: 'tclinkscales', owner: 'Travis Clinkscales', draftOrder: 6 },
    //     { name: 'My Team Suxx', owner: 'Steven Grimes', draftOrder: 7 },
    //     { name: 'Pun Goes Here', owner: 'Brian Koser', draftOrder: 8, isUser: true }
    //     // { name: 'Team 1', owner: '?', draftOrder: 1 },
    //     // { name: 'Team 2', owner: '?', draftOrder: 2, isUser: true },
    //     // { name: 'Team 3', owner: '?', draftOrder: 3 },
    //     // { name: 'Team 4', owner: '?', draftOrder: 4 },
    //     // { name: 'Team 5', owner: '?', draftOrder: 5 },
    //     // { name: 'Team 6', owner: '?', draftOrder: 6 },
    //     // { name: 'Team 7', owner: '?', draftOrder: 7 },
    //     // { name: 'Team 8', owner: '?', draftOrder: 8 }
    //   ]
    // },
    // team: {
    //   idealSize: [
    //     { positionKey: 'QB', count: 3 },
    //     { positionKey: 'RB', count: 4 },
    //     { positionKey: 'WR', count: 4 },
    //     { positionKey: 'TE', count: 1 },
    //     { positionKey: 'PK', count: 1 },
    //     { positionKey: 'Def', count: 1 }
    //   ],
    //   rankings: [],
    //   tags: [
    //     { name: 'avoid', players: ['2842', '6982', '7942', '9054', '9101', '9898', '10302', '10722', '11180', '11201', '11384', '11454', '11642', '11678', '11746', '12155', '13113', '13115', '13116', '13188'] },
    //     { name: 'handcuff', players: ['9087', '10300', '12626', '13138'] },
    //     { name: 'injuryprone', players: ['9054', '9693', '9823', '9902', '10695', '10722', '11248', '11670', '12151', '12186'] },
    //     { name: 'overpriced', players: ['8670', '9099', '9662', '9693', '9823', '11644'] },
    //     { name: 'target', players: ['0509', '0527', '7394', '7877', '8360', '8670', '8673', '9087', '9525', '9881', '9925', '10261', '10273', '10313', '10413', '10506', '10703', '10709', '11516', '11668', '11688', '11695', '12141', '12626', '13129'] }
    //   ],
    //   tiers: [
    //     { positionKey: 'QB', sizes: [3, 7, 3, 6, 6, 7] },
    //     { positionKey: 'RB', sizes: [] },
    //     { positionKey: 'WR', sizes: [] },
    //     { positionKey: 'TE', sizes: [1, 10] },
    //     { positionKey: 'PK', sizes: [] },
    //     { positionKey: 'Def', sizes: [4, 3] }
    //   ]
    // }

    /*
      Crossroads settings
    */
    // league: {
    //   draftOrderType: 'ser',
    //   positions: [
    //     { key: 'QB', min: 1, max: 4 },
    //     { key: 'RB', min: 1, max: 8 },
    //     { key: 'WR', min: 2, max: 8 },
    //     { key: 'TE', min: 1, max: 3 },
    //     { key: 'PK', min: 1, max: 3 },
    //     { key: 'Def', min: 1, max: 3 },
    //     { key: 'Coach', min: 1, max: 10 }
    //   ],
    //   rosterSize: 17,
    //   secondsPerPick: 60,
    //   teams: [
    //     { name: 'The Commish', owner: 'Aaron Smith', draftOrder: 12, keeper: '7836' },
    //     { name: '’Aints -', owner: 'Matt McLean' draftOrder: 11 },
    //     { name: 'Play It Again Sam', owner: 'Brian Koser', draftOrder: 10, isUser: true },
    //     { name: 'O. J.', owner: 'Tuck Chastain', draftOrder: 9 },
    //     { name: 'Buck stops here', owner: 'Terry Buckner', draftOrder: 8 },
    //     { name: 'Small Arms Dealer', owner: 'Scott Hopkins', draftOrder: 7 },
    //     { name: 'Fluoride Bandits', owner: 'Shane Herrington', draftOrder: 6 },
    //     { name: 'Brown Mikes DeadBeat Bums', owner: 'Brown Mike',  draftOrder: 5 },
    //     { name: 'Alabama Yard rats', owner: 'Philip Quinney', draftOrder: 4 },
    //     { name: 'Cam Burglar', owner: 'Justin Tolbert', draftOrder: 3 },
    //     { name: 'Amen Corner', owner: 'Ben Harris', draftOrder: 2 },
    //     { name: 'Crossroads Zealots', owner: 'Joe Chastain', draftOrder: 1 }
    //   ]
    // },
    // team: {
    //   idealSize: [
    //     { positionKey: 'QB', count: 2 },
    //     { positionKey: 'RB', count: 4 },
    //     { positionKey: 'WR', count: 5 },
    //     { positionKey: 'TE', count: 2 },
    //     { positionKey: 'PK', count: 1 },
    //     { positionKey: 'Def', count: 2 },
    //     { positionKey: 'Coach', count: 1 }
    //   ]
    // }
  }
}

const mutations = {
  ADDPICK (state, pick) {
    state.picks.push(pick)
  },
  ADDSTATEENTRY (state, entry) {
    state.history.push(entry)
  },
  SETPLAYERS (state, players) {
    state.players = players
  },
  SETTEAMRANKINGS (state, rankings) {
    state.settings.team.rankings = rankings
  },
  UNDOLASTPICK (state) {
    state.picks.pop()
  },
  UNDOSTATEENTRY (state) {
    state.history.pop()
  },
  UPDATEKEEPERS (state, keeperPicks) {
    state.picks = keeperPicks
  }
}

export default new Vuex.Store({
  state,
  mutations
})
<|endoftext|>


<commit_before>import axios from 'services/axiosWrapper'
import { combineReducers } from 'redux'
import { uniqBy } from 'lodash'

const endpoint = '/time'

// TYPES
export const types = {
  FETCH_BY_TASK: 'TIME_FETCH_BY_TASK',
  FETCH_BY_USER: 'TIME_FETCH_BY_USER',
  CREATE: 'TIME_CREATE',
  FINISH: 'TIME_FINISH',
  EDIT: 'TIME_EDIT',
  DELETE: 'TIME_DELETE',
  TICK: 'TIME_TICK'
}

// ACTIONS
export const actions = {
  fetchByTask(taskId, params) {
    const url = `${endpoint}/by_task/${taskId}`
    const promise = axios.get(url, {params})
    .then(res => res.data)
    return {
      type: types.FETCH_BY_TASK,
      payload: promise,
      meta: {taskId, params}
    }
  },
  fetchByUser: (userId, params) => {
    const url = `${endpoint}/by_user/${userId}`
    const promise = axios.get(url, {params})
    .then(res => res.data)
    return {
      type: types.FETCH_BY_USER,
      payload: promise,
      meta: {userId, params}
    }
  },
  fetchOne: (timeId) => {
    const url = `${endpoint}/${timeId}`;
    const promise = axios.get(url)
    .then(res => res.data)
    return {
      type: types.FETCH_ONE,
      payload: promise,
      meta: {_id: timeId}
    }
  },
  save: (time, editMode) => {
    const method = editMode ? 'PUT':'POST'
    const url = editMode ? `${endpoint}/${time._id}` : endpoint
    const type = editMode ? types.EDIT : types.CREATE
    const promise = axios({
      method,
      url,
      data: time
    }).then(res => res.data)
    return {
      type,
      payload: promise,
      meta: time
    }
  },
  finish(time) {
    const url = `${endpoint}/${time._id}/finish`
    const promise = axios.post(url, {
      ...time,
      user: time.user._id
    })
    .then(res => res.data)
    return {
      type: types.FINISH,
      payload: promise,
      meta: time
    }
  },
  delete: (time) => {
    const url = `${endpoint}/${time._id}`
    const promise = axios({
      method: 'DELETE',
      url,
      data: time
    }).then(() => time)
    return {
      type: types.DELETE,
      payload: promise,
      meta: time
    }
  },
  tick() {
    return { type: types.TICK }
  }
}

// SELECTORS
export const selectors = {
  getByTaskId(state, taskId) {
    const slice = state.times.byTask[taskId] || {
      ids: [],
      params: {}
    }
    const times = slice.ids.map(id => state.times.entities[id]).filter(Boolean)
    return {times, pageParams: slice.params}
  },
  getByUserId(state, userId) {
    const slice = state.times.byUser[userId] || []
    const times = slice.map(id => state.times.entities[id])
                .filter(Boolean)
    return uniqBy(times, time => time.task._id)
  },
  getOne(state, taskId) {
    return state.times.entities[taskId]
  },
  getLoading(state) {
    return state.times.loading
  },
  getTick(state) {
    return state.times.tick
  }
}

/*
entities: {
  id1: {},
  id2: {}
},
byTask: {
  taskId1: {
    ids: [],
    params: {}
  }
},
byUser: {
  userId1: {
    ids: [],
    params: {}
  }
},
loading: true
*/

// REDUCER
const normalizeArrayByKey = (arr, idKey = "_id") => {
  return arr.reduce((prev, next) => {
    prev[next[idKey]] = next
    return prev
  }, {})
}
const ok = type => `${type}_SUCCESS`

const loadingReducer = (state = false, action = {}) => {
  const {type = ""} = action
  const hasTime = type.indexOf("TIME") !== -1
  const hasLoading = type.indexOf("LOADING") !== -1
  const hasSuccess = type.indexOf("SUCCESS") !== -1
  const hasError = type.indexOf("ERROR") !== -1
  if(hasTime && hasLoading) {
    return true
  }
  if(hasTime && (hasSuccess || hasError)) {
    return false
  }
  return state
}
const entitiesReducer = (state = {}, action = {}) => {
  const {type = "", payload = {}, meta = {}} = action
  switch(type) {
    case ok(types.FETCH_BY_TASK):
      return {
        ...state,
        ...normalizeArrayByKey(payload.docs)
      }
    case ok(types.FETCH_BY_USER):
      return {
        ...state,
        ...normalizeArrayByKey(payload)
      }
    case ok(types.CREATE):
    case ok(types.EDIT):
      return {
        ...state,
        [payload._id]: payload
      }
    case ok(types.FINISH):
      return {
        ...state,
        [payload._id]: {
          ...state[payload._id],
          endTime: payload.endTime
        }
      }
    case ok(types.DELETE):
      const copy = {...state}
      delete copy[meta._id]
      return copy
    default:
      return state
  }
}
const byTaskReducer = (state = {}, action = {}) => {
  const {type = "", payload = {}, meta = {}} = action
  if(type === ok(types.FETCH_BY_TASK)) {
    const {page, last, docs} = payload
    const oldSlice = state[meta.taskId] || {ids: [], params: {}}
    const newIds = docs.map(time => time._id)
      .filter(id => oldSlice.ids.indexOf(id) === -1)
    return {
      ...state,
      [meta.taskId]: {
        ids: oldSlice.ids.concat(newIds),
        params: {page, last}
      }
    }
  }
  if(type === ok(types.CREATE)) {
    const oldSlice = state[payload.task] || {ids: [], params: {}}
    return {
      ...state,
      [payload.task]: {
        ...oldSlice,
        ids: [payload._id].concat(oldSlice.ids)
      }
    }
  }
  return state
}
const byUserReducer = (state = {}, action = {}) => {
  const {type = "", payload = {}, meta = {}} = action
  if(type === ok(types.FETCH_BY_USER)) {
    const newIds = payload.map(time => time._id)
    return {
      ...state,
      [meta.userId]: newIds
    }
  }
  if(type === ok(types.CREATE)) {
    const oldSlice = state[payload.user] || []
    return {
      ...state,
      [payload.user]: [payload._id].concat(oldSlice)
    }
  }
  return state
}
const tickReducer = (state = Date.now(), action = {}) => {
  if(action.type === types.TICK) {
    return Date.now()
  }
  return state
}

const reducer = combineReducers({
  loading: loadingReducer,
  entities: entitiesReducer,
  byUser: byUserReducer,
  byTask: byTaskReducer,
  tick: tickReducer
})

export default reducer
<commit_msg>fix: finish time bug<commit_after>import axios from 'services/axiosWrapper'
import { combineReducers } from 'redux'
import { uniqBy } from 'lodash'

const endpoint = '/time'

// TYPES
export const types = {
  FETCH_BY_TASK: 'TIME_FETCH_BY_TASK',
  FETCH_BY_USER: 'TIME_FETCH_BY_USER',
  CREATE: 'TIME_CREATE',
  FINISH: 'TIME_FINISH',
  EDIT: 'TIME_EDIT',
  DELETE: 'TIME_DELETE',
  TICK: 'TIME_TICK'
}

// ACTIONS
export const actions = {
  fetchByTask(taskId, params) {
    const url = `${endpoint}/by_task/${taskId}`
    const promise = axios.get(url, {params})
    .then(res => res.data)
    return {
      type: types.FETCH_BY_TASK,
      payload: promise,
      meta: {taskId, params}
    }
  },
  fetchByUser: (userId, params) => {
    const url = `${endpoint}/by_user/${userId}`
    const promise = axios.get(url, {params})
    .then(res => res.data)
    return {
      type: types.FETCH_BY_USER,
      payload: promise,
      meta: {userId, params}
    }
  },
  fetchOne: (timeId) => {
    const url = `${endpoint}/${timeId}`;
    const promise = axios.get(url)
    .then(res => res.data)
    return {
      type: types.FETCH_ONE,
      payload: promise,
      meta: {_id: timeId}
    }
  },
  save: (time, editMode) => {
    const method = editMode ? 'PUT':'POST'
    const url = editMode ? `${endpoint}/${time._id}` : endpoint
    const type = editMode ? types.EDIT : types.CREATE
    const promise = axios({
      method,
      url,
      data: time
    }).then(res => res.data)
    return {
      type,
      payload: promise,
      meta: time
    }
  },
  finish(time) {
    const url = `${endpoint}/${time._id}/finish`
    const promise = axios.post(url, {
      ...time,
      user: time.user._id || time.user
    })
    .then(res => res.data)
    return {
      type: types.FINISH,
      payload: promise,
      meta: time
    }
  },
  delete: (time) => {
    const url = `${endpoint}/${time._id}`
    const promise = axios({
      method: 'DELETE',
      url,
      data: time
    }).then(() => time)
    return {
      type: types.DELETE,
      payload: promise,
      meta: time
    }
  },
  tick() {
    return { type: types.TICK }
  }
}

// SELECTORS
export const selectors = {
  getByTaskId(state, taskId) {
    const slice = state.times.byTask[taskId] || {
      ids: [],
      params: {}
    }
    const times = slice.ids.map(id => state.times.entities[id]).filter(Boolean)
    return {times, pageParams: slice.params}
  },
  getByUserId(state, userId) {
    const slice = state.times.byUser[userId] || []
    const times = slice.map(id => state.times.entities[id])
                .filter(Boolean)
    return uniqBy(times, time => time.task._id)
  },
  getOne(state, taskId) {
    return state.times.entities[taskId]
  },
  getLoading(state) {
    return state.times.loading
  },
  getTick(state) {
    return state.times.tick
  }
}

/*
entities: {
  id1: {},
  id2: {}
},
byTask: {
  taskId1: {
    ids: [],
    params: {}
  }
},
byUser: {
  userId1: {
    ids: [],
    params: {}
  }
},
loading: true
*/

// REDUCER
const normalizeArrayByKey = (arr, idKey = "_id") => {
  return arr.reduce((prev, next) => {
    prev[next[idKey]] = next
    return prev
  }, {})
}
const ok = type => `${type}_SUCCESS`

const loadingReducer = (state = false, action = {}) => {
  const {type = ""} = action
  const hasTime = type.indexOf("TIME") !== -1
  const hasLoading = type.indexOf("LOADING") !== -1
  const hasSuccess = type.indexOf("SUCCESS") !== -1
  const hasError = type.indexOf("ERROR") !== -1
  if(hasTime && hasLoading) {
    return true
  }
  if(hasTime && (hasSuccess || hasError)) {
    return false
  }
  return state
}
const entitiesReducer = (state = {}, action = {}) => {
  const {type = "", payload = {}, meta = {}} = action
  switch(type) {
    case ok(types.FETCH_BY_TASK):
      return {
        ...state,
        ...normalizeArrayByKey(payload.docs)
      }
    case ok(types.FETCH_BY_USER):
      return {
        ...state,
        ...normalizeArrayByKey(payload)
      }
    case ok(types.CREATE):
    case ok(types.EDIT):
      return {
        ...state,
        [payload._id]: payload
      }
    case ok(types.FINISH):
      return {
        ...state,
        [payload._id]: {
          ...state[payload._id],
          endTime: payload.endTime
        }
      }
    case ok(types.DELETE):
      const copy = {...state}
      delete copy[meta._id]
      return copy
    default:
      return state
  }
}
const byTaskReducer = (state = {}, action = {}) => {
  const {type = "", payload = {}, meta = {}} = action
  if(type === ok(types.FETCH_BY_TASK)) {
    const {page, last, docs} = payload
    const oldSlice = state[meta.taskId] || {ids: [], params: {}}
    const newIds = docs.map(time => time._id)
      .filter(id => oldSlice.ids.indexOf(id) === -1)
    return {
      ...state,
      [meta.taskId]: {
        ids: oldSlice.ids.concat(newIds),
        params: {page, last}
      }
    }
  }
  if(type === ok(types.CREATE)) {
    const oldSlice = state[payload.task] || {ids: [], params: {}}
    return {
      ...state,
      [payload.task]: {
        ...oldSlice,
        ids: [payload._id].concat(oldSlice.ids)
      }
    }
  }
  return state
}
const byUserReducer = (state = {}, action = {}) => {
  const {type = "", payload = {}, meta = {}} = action
  if(type === ok(types.FETCH_BY_USER)) {
    const newIds = payload.map(time => time._id)
    return {
      ...state,
      [meta.userId]: newIds
    }
  }
  if(type === ok(types.CREATE)) {
    const oldSlice = state[payload.user] || []
    return {
      ...state,
      [payload.user]: [payload._id].concat(oldSlice)
    }
  }
  return state
}
const tickReducer = (state = Date.now(), action = {}) => {
  if(action.type === types.TICK) {
    return Date.now()
  }
  return state
}

const reducer = combineReducers({
  loading: loadingReducer,
  entities: entitiesReducer,
  byUser: byUserReducer,
  byTask: byTaskReducer,
  tick: tickReducer
})

export default reducer
<|endoftext|>


<commit_before>import Component from 'flarum/Component';
import avatar from 'flarum/helpers/avatar';
import listItems from 'flarum/helpers/listItems';
import highlight from 'flarum/helpers/highlight';
import icon from 'flarum/helpers/icon';
import humanTime from 'flarum/utils/humanTime';
import ItemList from 'flarum/utils/ItemList';
import abbreviateNumber from 'flarum/utils/abbreviateNumber';
import Dropdown from 'flarum/components/Dropdown';
import TerminalPost from 'flarum/components/TerminalPost';
import PostPreview from 'flarum/components/PostPreview';
import SubtreeRetainer from 'flarum/utils/SubtreeRetainer';
import DiscussionControls from 'flarum/utils/DiscussionControls';
import slidable from 'flarum/utils/slidable';
import extractText from 'flarum/utils/extractText';

/**
 * The `DiscussionListItem` component shows a single discussion in the
 * discussion list.
 *
 * ### Props
 *
 * - `discussion`
 * - `params`
 */
export default class DiscussionListItem extends Component {
  constructor(...args) {
    super(...args);

    /**
     * Set up a subtree retainer so that the discussion will not be redrawn
     * unless new data comes in.
     *
     * @type {SubtreeRetainer}
     */
    this.subtree = new SubtreeRetainer(
      () => this.props.discussion.freshness,
      () => {
        const time = app.session.user && app.session.user.readTime();
        return time && time.getTime();
      },
      () => this.active()
    );
  }

  view() {
    const retain = this.subtree.retain();

    if (retain) return retain;

    const discussion = this.props.discussion;
    const startUser = discussion.startUser();
    const isUnread = discussion.isUnread();
    const showUnread = !this.showRepliesCount() && isUnread;
    const jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1);
    const relevantPosts = this.props.params.q ? discussion.relevantPosts() : [];
    const controls = DiscussionControls.controls(discussion, this).toArray();

    return (

        {controls.length ? Dropdown.component({
          icon: 'ellipsis-v',
          children: controls,
          className: 'DiscussionListItem-controls',
          buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right'
        }) : ''}

          {icon('check')}

            {avatar(startUser, {title: ''})}

            {listItems(discussion.badges().toArray())}

{highlight(discussion.title(), this.props.params.q)}

{listItems(this.infoItems().toArray())}

            {abbreviateNumber(discussion[showUnread ? 'unreadCount' : 'repliesCount']())}

          {relevantPosts && relevantPosts.length
            ?

                {relevantPosts.map(post => PostPreview.component({post, highlight: this.props.params.q}))}

            : ''}

    );
  }

  config(isInitialized) {
    if (isInitialized) return;

    // If we're on a touch device, set up the discussion row to be slidable.
    // This allows the user to drag the row to either side of the screen to
    // reveal controls.
    if ('ontouchstart' in window) {
      const slidableInstance = slidable(this.$().addClass('Slidable'));

      this.$('.DiscussionListItem-controls')
        .on('hidden.bs.dropdown', () => slidableInstance.reset());
    }
  }

  /**
   * Determine whether or not the discussion is currently being viewed.
   *
   * @return {Boolean}
   */
  active() {
    return m.route.param('id').split('-')[0] === this.props.discussion.id();
  }

  /**
   * Determine whether or not information about who started the discussion
   * should be displayed instead of information about the most recent reply to
   * the discussion.
   *
   * @return {Boolean}
   */
  showStartPost() {
    return ['newest', 'oldest'].indexOf(this.props.params.sort) !== -1;
  }

  /**
   * Determine whether or not the number of replies should be shown instead of
   * the number of unread posts.
   *
   * @return {Boolean}
   */
  showRepliesCount() {
    return this.props.params.sort === 'replies';
  }

  /**
   * Mark the discussion as read.
   */
  markAsRead() {
    const discussion = this.props.discussion;

    if (discussion.isUnread()) {
      discussion.save({readNumber: discussion.lastPostNumber()});
      m.redraw();
    }
  }

  /**
   * Build an item list of info for a discussion listing. By default this is
   * just the first/last post indicator.
   *
   * @return {ItemList}
   */
  infoItems() {
    const items = new ItemList();

    items.add('terminalPost',
      TerminalPost.component({
        discussion: this.props.discussion,
        lastPost: !this.showStartPost()
      })
    );

    return items;
  }
}
<commit_msg>Fix error on index page<commit_after>import Component from 'flarum/Component';
import avatar from 'flarum/helpers/avatar';
import listItems from 'flarum/helpers/listItems';
import highlight from 'flarum/helpers/highlight';
import icon from 'flarum/helpers/icon';
import humanTime from 'flarum/utils/humanTime';
import ItemList from 'flarum/utils/ItemList';
import abbreviateNumber from 'flarum/utils/abbreviateNumber';
import Dropdown from 'flarum/components/Dropdown';
import TerminalPost from 'flarum/components/TerminalPost';
import PostPreview from 'flarum/components/PostPreview';
import SubtreeRetainer from 'flarum/utils/SubtreeRetainer';
import DiscussionControls from 'flarum/utils/DiscussionControls';
import slidable from 'flarum/utils/slidable';
import extractText from 'flarum/utils/extractText';

/**
 * The `DiscussionListItem` component shows a single discussion in the
 * discussion list.
 *
 * ### Props
 *
 * - `discussion`
 * - `params`
 */
export default class DiscussionListItem extends Component {
  constructor(...args) {
    super(...args);

    /**
     * Set up a subtree retainer so that the discussion will not be redrawn
     * unless new data comes in.
     *
     * @type {SubtreeRetainer}
     */
    this.subtree = new SubtreeRetainer(
      () => this.props.discussion.freshness,
      () => {
        const time = app.session.user && app.session.user.readTime();
        return time && time.getTime();
      },
      () => this.active()
    );
  }

  view() {
    const retain = this.subtree.retain();

    if (retain) return retain;

    const discussion = this.props.discussion;
    const startUser = discussion.startUser();
    const isUnread = discussion.isUnread();
    const showUnread = !this.showRepliesCount() && isUnread;
    const jumpTo = Math.min(discussion.lastPostNumber(), (discussion.readNumber() || 0) + 1);
    const relevantPosts = this.props.params.q ? discussion.relevantPosts() : [];
    const controls = DiscussionControls.controls(discussion, this).toArray();

    return (

        {controls.length ? Dropdown.component({
          icon: 'ellipsis-v',
          children: controls,
          className: 'DiscussionListItem-controls',
          buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right'
        }) : ''}

          {icon('check')}

            {avatar(startUser, {title: ''})}

            {listItems(discussion.badges().toArray())}

{highlight(discussion.title(), this.props.params.q)}

{listItems(this.infoItems().toArray())}

            {abbreviateNumber(discussion[showUnread ? 'unreadCount' : 'repliesCount']())}

          {relevantPosts && relevantPosts.length
            ?

                {relevantPosts.map(post => PostPreview.component({post, highlight: this.props.params.q}))}

            : ''}

    );
  }

  config(isInitialized) {
    if (isInitialized) return;

    // If we're on a touch device, set up the discussion row to be slidable.
    // This allows the user to drag the row to either side of the screen to
    // reveal controls.
    if ('ontouchstart' in window) {
      const slidableInstance = slidable(this.$().addClass('Slidable'));

      this.$('.DiscussionListItem-controls')
        .on('hidden.bs.dropdown', () => slidableInstance.reset());
    }
  }

  /**
   * Determine whether or not the discussion is currently being viewed.
   *
   * @return {Boolean}
   */
  active() {
    const idParam = m.route.param('id');

    return idParam && idParam.split('-')[0] === this.props.discussion.id();
  }

  /**
   * Determine whether or not information about who started the discussion
   * should be displayed instead of information about the most recent reply to
   * the discussion.
   *
   * @return {Boolean}
   */
  showStartPost() {
    return ['newest', 'oldest'].indexOf(this.props.params.sort) !== -1;
  }

  /**
   * Determine whether or not the number of replies should be shown instead of
   * the number of unread posts.
   *
   * @return {Boolean}
   */
  showRepliesCount() {
    return this.props.params.sort === 'replies';
  }

  /**
   * Mark the discussion as read.
   */
  markAsRead() {
    const discussion = this.props.discussion;

    if (discussion.isUnread()) {
      discussion.save({readNumber: discussion.lastPostNumber()});
      m.redraw();
    }
  }

  /**
   * Build an item list of info for a discussion listing. By default this is
   * just the first/last post indicator.
   *
   * @return {ItemList}
   */
  infoItems() {
    const items = new ItemList();

    items.add('terminalPost',
      TerminalPost.component({
        discussion: this.props.discussion,
        lastPost: !this.showStartPost()
      })
    );

    return items;
  }
}
<|endoftext|>


<commit_before>

var InputElement = Backbone.Model.extend({
  initialize:function() {
    _.bindAll(this, 'markDirty', 'update_min_value', 'update_max_value', 'update_start_value');
    this.dirty = false;
    this.ui_options = {'element' : $('#input_element_'+this.get('id'))};
    this.bind('change:user_value', this.markDirty);
  },

  set_min_value : function(result) {
    var factor = this.get('factor');
    this.set({'min_value' : result});
  },
  set_max_value : function(result) {
    var factor = this.get('factor');
    this.set({'max_value' : result});
  },
  set_label : function(label) {
    if(!_.isString(label)) return;
    this.set({'label' : label});
  },
  set_start_value : function(result) {
    var factor = this.get('factor');
    var step_value = this.get('step_value');

    var rounded_result = Metric.round_number(result, this.get('number_to_round_with'));
    result = (rounded_result);

    if (step_value == 0.1 || step_value == 5)
      result = Metric.round_number(result, 1);

    this.set({'start_value' : result});
  },

  init_legacy_controller : function() {
    if (this.already_init != true) {
      App.inputElementsController.addInputElement(this);
      this.already_init = true;
    }
  },

  /**
   * Returns if this is dirty, meaning a attribute has changed.
   */
  isDirty:function() {
    if (this.get('input_element_type') == 'fixed') {
      return false;
    } else {
      return this.dirty;
    }
  },

  markDirty:function() {
    this.dirty = true;
  },

  setDirty:function(dirty) {
    this.dirty = dirty;
  }
});

var InputElementList = Backbone.Collection.extend({
  model : InputElement,

  initialize : function() {
    this.inputElements     = {};
    this.inputElementViews = {};

    this.shareGroups = {};
    this.balancers   = {};

    this.openInputElementInfoBox;
  },

  init_legacy_controller : function() {
    this.each(function(input_element) {
      input_element.init_legacy_controller();
    });
  },

  load_user_values : function() {
    _.bindAll(this, 'initialize_user_values');
    $.jsonp({
      url: App.scenario.user_values_url(),
      success : this.initialize_user_values,
      timeout: 15000
    });
  },

  initialize_user_values : function(user_value_hash) {
    this.each(function(input_element) {
      var values = user_value_hash[
        (input_element.get('input_id') || input_element.id) + ''];

      input_element.set_min_value(values.min_value);
      input_element.set_max_value(values.max_value);
      input_element.set_start_value(values.start_value);
      input_element.set_label(values.full_label);
      var user_value = values.user_value;
      var default_value = (_.isUndefined(user_value) || _.isNaN(user_value) || _.isNull(user_value)) ? values.start_value : user_value;
      input_element.set({user_value : default_value}, {silent : true});

      input_element.init_legacy_controller();
    });
  },

  /**
   * Get the string which contains the update values for all dirty input elements.
   */
  api_update_params:function() {
    return _.map(this.dirty(), function(el) {
      return ("input["+el.get('input_id')+"]=" + el.get("user_value"));
    }).join("&");
  },

  dirty : function() {
    return this.select(function(el) { return el.isDirty(); });
  },

  reset_dirty : function() {
    _.each(this.dirty(), function(el) { el.setDirty(false); })
  },

  /**
   * Add a constraint to the constraints.
   * @param options - must contain an element item
   */
  addInputElement:function(inputElement, options) {
    var options = inputElement.ui_options;
    this.inputElements[inputElement.id] = inputElement;
    var inputElementView = new InputElementView({model : inputElement, el : options.element});
    // The following binding was for obscure reasons preventing the videos
    // to work. Commented it out. Investigate. PZ Fri 3 Jun 2011 16:34:36 CEST
    // inputElementView.bind('show', $.proxy(this.handleInputElementInfoBoxShowed, this));

    this.inputElementViews[inputElement.id] = inputElementView;
    inputElementView.bind("change", $.proxy(this.handleUpdate, this));

    return true;
    this.initShareGroup(inputElement);
  },

  handleInputElementInfoBoxShowed:function(inputElementView) {
    var infoBox = inputElementView.sliderView.getInfoBox();
    if(this.openInputElementInfoBox && this.openInputElementInfoBox != infoBox)
      this.openInputElementInfoBox.hide();

    this.openInputElementInfoBox = infoBox;
  },

  /**
   * Initialize a share group for an input element if it has one.
   */
  initShareGroup:function(inputElement) {
    var inputElementView = this.inputElementViews[inputElement.id];
    var shareGroupKey = inputElement.get("share_group");
    if(shareGroupKey && shareGroupKey.length) {
      var shareGroup = this.getOrCreateShareGroup(shareGroupKey);
      shareGroup.bind("slider_updated",$.proxy(function(){ inputElement.markDirty();},this)); //set all sliders from same sharegroup to dirty when one is touched
      shareGroup.addSlider(inputElementView.sliderView.sliderVO);

      var balancer = this.getOrCreateBalancer(shareGroupKey);
      balancer.add(inputElementView);
    }
  },

  /**
   * Finds or creates the share group.
   */
  getOrCreateShareGroup:function(shareGroup) {

    if(!this.shareGroups[shareGroup])
      this.shareGroups[shareGroup] = new SliderGroup({'total_value':100}); // add group if not created yet

    return this.shareGroups[shareGroup];
  },

  getOrCreateBalancer: function(name) {
    if (! this.balancers.hasOwnProperty(name)) {
      this.balancers[name] = new InputElementGroup({ max: 100 });
    }

    return this.balancers[name];
  },

  /**
   * Does a update request to update the values.
   */
  handleUpdate:function() {
    this.trigger("change");
  }
});
window.input_elements = new InputElementList();

<commit_msg>That's not needed anymore; re-migrating fixed the missing value.<commit_after>

var InputElement = Backbone.Model.extend({
  initialize:function() {
    _.bindAll(this, 'markDirty', 'update_min_value', 'update_max_value', 'update_start_value');
    this.dirty = false;
    this.ui_options = {'element' : $('#input_element_'+this.get('id'))};
    this.bind('change:user_value', this.markDirty);
  },

  set_min_value : function(result) {
    var factor = this.get('factor');
    this.set({'min_value' : result});
  },
  set_max_value : function(result) {
    var factor = this.get('factor');
    this.set({'max_value' : result});
  },
  set_label : function(label) {
    if(!_.isString(label)) return;
    this.set({'label' : label});
  },
  set_start_value : function(result) {
    var factor = this.get('factor');
    var step_value = this.get('step_value');

    var rounded_result = Metric.round_number(result, this.get('number_to_round_with'));
    result = (rounded_result);

    if (step_value == 0.1 || step_value == 5)
      result = Metric.round_number(result, 1);

    this.set({'start_value' : result});
  },

  init_legacy_controller : function() {
    if (this.already_init != true) {
      App.inputElementsController.addInputElement(this);
      this.already_init = true;
    }
  },

  /**
   * Returns if this is dirty, meaning a attribute has changed.
   */
  isDirty:function() {
    if (this.get('input_element_type') == 'fixed') {
      return false;
    } else {
      return this.dirty;
    }
  },

  markDirty:function() {
    this.dirty = true;
  },

  setDirty:function(dirty) {
    this.dirty = dirty;
  }
});

var InputElementList = Backbone.Collection.extend({
  model : InputElement,

  initialize : function() {
    this.inputElements     = {};
    this.inputElementViews = {};

    this.shareGroups = {};
    this.balancers   = {};

    this.openInputElementInfoBox;
  },

  init_legacy_controller : function() {
    this.each(function(input_element) {
      input_element.init_legacy_controller();
    });
  },

  load_user_values : function() {
    _.bindAll(this, 'initialize_user_values');
    $.jsonp({
      url: App.scenario.user_values_url(),
      success : this.initialize_user_values,
      timeout: 15000
    });
  },

  initialize_user_values : function(user_value_hash) {
    this.each(function(input_element) {
      var values = user_value_hash['' + input_element.get('input_id')];
      input_element.set_min_value(values.min_value);
      input_element.set_max_value(values.max_value);
      input_element.set_start_value(values.start_value);
      input_element.set_label(values.full_label);
      var user_value = values.user_value;
      var default_value = (_.isUndefined(user_value) || _.isNaN(user_value) || _.isNull(user_value)) ? values.start_value : user_value;
      input_element.set({user_value : default_value}, {silent : true});

      input_element.init_legacy_controller();
    });
  },

  /**
   * Get the string which contains the update values for all dirty input elements.
   */
  api_update_params:function() {
    return _.map(this.dirty(), function(el) {
      return ("input["+el.get('input_id')+"]=" + el.get("user_value"));
    }).join("&");
  },

  dirty : function() {
    return this.select(function(el) { return el.isDirty(); });
  },

  reset_dirty : function() {
    _.each(this.dirty(), function(el) { el.setDirty(false); })
  },

  /**
   * Add a constraint to the constraints.
   * @param options - must contain an element item
   */
  addInputElement:function(inputElement, options) {
    var options = inputElement.ui_options;
    this.inputElements[inputElement.id] = inputElement;
    var inputElementView = new InputElementView({model : inputElement, el : options.element});
    // The following binding was for obscure reasons preventing the videos
    // to work. Commented it out. Investigate. PZ Fri 3 Jun 2011 16:34:36 CEST
    // inputElementView.bind('show', $.proxy(this.handleInputElementInfoBoxShowed, this));

    this.inputElementViews[inputElement.id] = inputElementView;
    inputElementView.bind("change", $.proxy(this.handleUpdate, this));

    return true;
    this.initShareGroup(inputElement);
  },

  handleInputElementInfoBoxShowed:function(inputElementView) {
    var infoBox = inputElementView.sliderView.getInfoBox();
    if(this.openInputElementInfoBox && this.openInputElementInfoBox != infoBox)
      this.openInputElementInfoBox.hide();

    this.openInputElementInfoBox = infoBox;
  },

  /**
   * Initialize a share group for an input element if it has one.
   */
  initShareGroup:function(inputElement) {
    var inputElementView = this.inputElementViews[inputElement.id];
    var shareGroupKey = inputElement.get("share_group");
    if(shareGroupKey && shareGroupKey.length) {
      var shareGroup = this.getOrCreateShareGroup(shareGroupKey);
      shareGroup.bind("slider_updated",$.proxy(function(){ inputElement.markDirty();},this)); //set all sliders from same sharegroup to dirty when one is touched
      shareGroup.addSlider(inputElementView.sliderView.sliderVO);

      var balancer = this.getOrCreateBalancer(shareGroupKey);
      balancer.add(inputElementView);
    }
  },

  /**
   * Finds or creates the share group.
   */
  getOrCreateShareGroup:function(shareGroup) {

    if(!this.shareGroups[shareGroup])
      this.shareGroups[shareGroup] = new SliderGroup({'total_value':100}); // add group if not created yet

    return this.shareGroups[shareGroup];
  },

  getOrCreateBalancer: function(name) {
    if (! this.balancers.hasOwnProperty(name)) {
      this.balancers[name] = new InputElementGroup({ max: 100 });
    }

    return this.balancers[name];
  },

  /**
   * Does a update request to update the values.
   */
  handleUpdate:function() {
    this.trigger("change");
  }
});
window.input_elements = new InputElementList();

<|endoftext|>


<commit_before>import { Client, channel } from './bridge';
import { View } from '../../bindings/html/view';

const client = new Client({
  service: 'l20n',
  endpoint: channel,
  timeout: false
});

document.l10n = new View(client, document);

window.addEventListener('pageshow', () => client.connect());
window.addEventListener('pagehide', () => client.disconnect());
window.addEventListener('languagechange', document.l10n);

//Bug 1204660 - Temporary proxy for shared code. Will be removed once
//              l10n.js migration is completed.
navigator.mozL10n = {
  setAttributes: document.l10n.setAttributes,
  getAttributes: document.l10n.getAttributes,
  formatValue: (...args) => document.l10n.formatValue(...args),
  translateFragment: (...args) => document.l10n.translateFragment(...args),
  once: cb => document.l10n.ready.then(cb),
  ready: cb => document.l10n.ready.then(() => {
    document.addEventListener('DOMRetranslated', cb);
    cb();
  }),
};
<commit_msg>Remove mozL10n proxy<commit_after>import { Client, channel } from './bridge';
import { View } from '../../bindings/html/view';

const client = new Client({
  service: 'l20n',
  endpoint: channel,
  timeout: false
});

document.l10n = new View(client, document);

window.addEventListener('pageshow', () => client.connect());
window.addEventListener('pagehide', () => client.disconnect());
window.addEventListener('languagechange', document.l10n);
<|endoftext|>


<commit_before>var solve = require('ndarray-lu-solve');
var crout = require('ndarray-crout-decomposition');
var ndarray = require('ndarray');
var scratch = require('ndarray-scratch');

module.exports = function (A, B, X) {
    if (A.dimension === undefined) {
        var sq = Math.sqrt(A.length);
        if (Math.floor(sq) !== sq) throw new Error('not a square length');
        A = ndarray(A, [ sq, sq ], [ 1, sq ]);
    }
    if (B.dimension === undefined) B = ndarray(B);

    var m = A.shape[0], n = A.shape[1];

    if (X === undefined) {
        X = scratch.malloc([ m ]);
    }
    if (X.dimension === undefined) {
        X = ndarray(X);
    }

    if (A.dimension !== 2) throw new Error('not a 2-dimensional matrix');
    if (m !== n) throw new Error('not a square matrix: ' + m + 'x' + n);

    var L = scratch.malloc([ m, m ]);
    var ok = crout(A, L, L);
    if (!ok) {
        scratch.free(L);
        return undefined;
    }

    var Y = scratch.malloc([ m ]);
    var res = solve(L, L, B, X, Y);
    scratch.free(Y)
    scratch.free(L);
    if (!res) return undefined
    return X;
};
<commit_msg>071e8503fbaeb8f1a0e0508b2dc7df9eeafaa09e, the good parts<commit_after>var solve = require('ndarray-lu-solve');
var crout = require('ndarray-crout-decomposition');
var ndarray = require('ndarray');
var scratch = require('ndarray-scratch');

module.exports = function (A, B, X) {
    if (A.dimension === undefined) {
        var sq = Math.sqrt(A.length);
        if (Math.floor(sq) !== sq) throw new Error('not a square length');
        A = ndarray(A, [ sq, sq ], [ 1, sq ]);
    }
    if (B.dimension === undefined) B = ndarray(B);

    var m = A.shape[0], n = A.shape[1];

    if (X === undefined) {
        X = scratch.malloc([ m ]);
    }
    if (X.dimension === undefined) {
        X = ndarray(X, [ m ]);
    }

    if (A.dimension !== 2) throw new Error('not a 2-dimensional matrix');
    if (m !== n) throw new Error('not a square matrix: ' + m + 'x' + n);

    var L = scratch.malloc([ m, m ]);
    var ok = crout(A, L, L);
    if (!ok) {
        scratch.free(L);
        return undefined;
    }

    var Y = scratch.malloc([ m ]);
    var res = solve(L, L, B, X, Y);
    scratch.free(Y)
    scratch.free(L);
    if (!res) return undefined
    return X;
};
<|endoftext|>


<commit_before>'use strict';

goog.provide('Blockly.Blocks.hedgehog');

goog.require('Blockly.Blocks');

/**
 * Common HSV hue for all blocks in this category.
 */
Blockly.Blocks.hedgehog.HUE = 120;
Blockly.Blocks.loops.HUE = 60;

// Common Help URL for all blocks in this category
Blockly.Blocks.hedgehog.HELPURL = "http://hedgehog.pria.at/";

Blockly.Blocks['hedgehog_scope'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("hedgehog scope");
        this.appendStatementInput("IN")
            .setCheck(null);
        this.setTooltip('all Hedgehog blocks have to be inside of this block');
    }
};

Blockly.Blocks['hedgehog_move2'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("move motor")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "MOTOR1")
            .appendField("and")
            .appendField(new Blockly.FieldNumber(1, 0, 3, 1), "MOTOR2");
        this.appendValueInput("SPEED")
            .setCheck("Number");
        this.appendValueInput("TIME")
            .setCheck("Number")
            .appendField("for");
        this.appendDummyInput()
            .appendField("seconds");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('move two motors for a certain duration');
    }
};

Blockly.Blocks['hedgehog_move'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("move motor")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "PORT");
        this.appendValueInput("SPEED")
            .setCheck("Number");
        this.appendValueInput("TIME")
            .setCheck("Number")
            .appendField("for");
        this.appendDummyInput()
            .appendField("seconds");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('move one motor for a certain duration');
    }
};

Blockly.Blocks['hedgehog_turn'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("turn motors")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "MOTOR1")
            .appendField("and")
            .appendField(new Blockly.FieldNumber(1, 0, 3, 1), "MOTOR2")
        this.appendValueInput("DIR")
            .setCheck("Number");
        this.appendValueInput("TIME")
            .appendField("for")
            .setCheck("Number")
            .setAlign(Blockly.ALIGN_CENTRE);
        this.appendDummyInput()
            .appendField("seconds");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('turn the Hedgog for a certain duration');
    }
};

Blockly.Blocks['hedgehog_dir'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["right", "1000"], ["left", "-1000"]]), "DIR");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_speed'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["forward", "1000"], ["backward", "-1000"]]), "SPEED");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_read_analog'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("read analog pin")
            .appendField(new Blockly.FieldNumber(0, 0, 7, 1), "PORT");
        this.setOutput(true, "Number");
        this.setTooltip('get the value of an analog pin');
    }
};

Blockly.Blocks['hedgehog_servo'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("set servo")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "PORT")
            .appendField("to");
        this.appendValueInput("ANGLE")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField("degrees");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('move a servo to a specified position');
    }
};

Blockly.Blocks['hedgehog_degrees'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        Blockly.FieldAngle.ROUND = 5;
        Blockly.FieldAngle.CLOCKWISE = true;
        Blockly.FieldAngle.OFFSET = 90;
        this.appendDummyInput()
            .appendField(new Blockly.FieldAngle(45), "ANGLE");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_sleep'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("sleep for")
        this.appendValueInput("TIME")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField("seconds");
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_read_digital'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("read digital pin")
            .appendField(new Blockly.FieldNumber(8, 8, 15, 1), "PORT");
        this.setOutput(true, "Boolean");
        this.setTooltip('get the value of an analog pin');
    }
};
<commit_msg>add arrow symbols to left/right<commit_after>'use strict';

goog.provide('Blockly.Blocks.hedgehog');

goog.require('Blockly.Blocks');

/**
 * Common HSV hue for all blocks in this category.
 */
Blockly.Blocks.hedgehog.HUE = 120;
Blockly.Blocks.loops.HUE = 60;

// Common Help URL for all blocks in this category
Blockly.Blocks.hedgehog.HELPURL = "http://hedgehog.pria.at/";

Blockly.Blocks['hedgehog_scope'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("hedgehog scope");
        this.appendStatementInput("IN")
            .setCheck(null);
        this.setTooltip('all Hedgehog blocks have to be inside of this block');
    }
};

Blockly.Blocks['hedgehog_move2'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("move motor")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "MOTOR1")
            .appendField("and")
            .appendField(new Blockly.FieldNumber(1, 0, 3, 1), "MOTOR2");
        this.appendValueInput("SPEED")
            .setCheck("Number");
        this.appendValueInput("TIME")
            .setCheck("Number")
            .appendField("for");
        this.appendDummyInput()
            .appendField("seconds");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('move two motors for a certain duration');
    }
};

Blockly.Blocks['hedgehog_move'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("move motor")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "PORT");
        this.appendValueInput("SPEED")
            .setCheck("Number");
        this.appendValueInput("TIME")
            .setCheck("Number")
            .appendField("for");
        this.appendDummyInput()
            .appendField("seconds");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('move one motor for a certain duration');
    }
};

Blockly.Blocks['hedgehog_turn'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("turn motors")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "MOTOR1")
            .appendField("and")
            .appendField(new Blockly.FieldNumber(1, 0, 3, 1), "MOTOR2")
        this.appendValueInput("DIR")
            .setCheck("Number");
        this.appendValueInput("TIME")
            .appendField("for")
            .setCheck("Number")
            .setAlign(Blockly.ALIGN_CENTRE);
        this.appendDummyInput()
            .appendField("seconds");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('turn the Hedgog for a certain duration');
    }
};

Blockly.Blocks['hedgehog_dir'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["right ⟳", "1000"], ["left ⟲", "-1000"]]), "DIR");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_speed'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField(new Blockly.FieldDropdown([["forward", "1000"], ["backward", "-1000"]]), "SPEED");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_read_analog'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("read analog pin")
            .appendField(new Blockly.FieldNumber(0, 0, 7, 1), "PORT");
        this.setOutput(true, "Number");
        this.setTooltip('get the value of an analog pin');
    }
};

Blockly.Blocks['hedgehog_servo'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("set servo")
            .appendField(new Blockly.FieldNumber(0, 0, 3, 1), "PORT")
            .appendField("to");
        this.appendValueInput("ANGLE")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField("degrees");
        this.setInputsInline(true);
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('move a servo to a specified position');
    }
};

Blockly.Blocks['hedgehog_degrees'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        Blockly.FieldAngle.ROUND = 5;
        Blockly.FieldAngle.CLOCKWISE = true;
        Blockly.FieldAngle.OFFSET = 90;
        this.appendDummyInput()
            .appendField(new Blockly.FieldAngle(45), "ANGLE");
        this.setOutput(true, "Number");
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_sleep'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("sleep for")
        this.appendValueInput("TIME")
            .setCheck("Number");
        this.appendDummyInput()
            .appendField("seconds");
        this.setPreviousStatement(true, null);
        this.setNextStatement(true, null);
        this.setTooltip('');
    }
};

Blockly.Blocks['hedgehog_read_digital'] = {
    init: function() {
        this.setColour(Blockly.Blocks.hedgehog.HUE);
        this.setHelpUrl(Blockly.Blocks.hedgehog.HELPURL);

        this.appendDummyInput()
            .appendField("read digital pin")
            .appendField(new Blockly.FieldNumber(8, 8, 15, 1), "PORT");
        this.setOutput(true, "Boolean");
        this.setTooltip('get the value of an analog pin');
    }
};
<|endoftext|>


<commit_before>//change this if we have longer commands
annyang.start();

function save_data(){
var input = document.getElementById("fname");
localStorage.setItem("fname", input.value);
}
var firstname = localStorage.getItem("fname");

function speak (phrase) {
    var worte = new SpeechSynthesisUtterance(phrase);
    worte.lang = "en-GB";
    window.speechSynthesis.speak(worte);
}
annyang. addCallback('resultNoMatch', function(){speak('I dont know what you mean');  document.getElementById("#resultplace").innerHTML = "I dont know what you mean.";});
// Just a list of functions that anyone can call
// you can call these in the console by typing actions.YourFunctioName()
var actions = {

    youtube: function (term) {
        window.location.href = 'https://www.youtube.com/results?search_query='+term;
    },

    google: function (term) {
        window.location.href = 'https://www.google.com/#q='+term;
    },
    d20: function () {
      var d20 = Math.floor(Math.random() * 20);
      speak(d20);
      document.getElementById("#resultplace").innerHTML = d20;
    },

    d6: function () {
      var d6 = Math.floor(Math.random() * 6);
      speak(d6);
      document.getElementById("#resultplace").innerHTML = d6;
    },
  wolfram: function(term) {
    $.get("https://api.wolframalpha.com/v2/query?input="+term+"&appid=THYQLJ-3K45Y2A7W5"), function(wolfram__) {
        speak(wolfram__);
        };
    //http://api.wolframalpha.com/v2/query?input=pi&appid=XXXX
    //var wolfram_ = "http://api.wolframalpha.com/v2/query?input="+term+"&appid=THYQLJ-3K45Y2A7W5";
    //speak(wolfram_);
  },
  weather: function (term) {
    $.get('https://api.openweathermap.org/data/2.5/weather?q='+term, function (theweather) {
      speak(theweather.temp);

  });

},
howu: function () {
  speak("I'm good");
  document.getElementById("#resultplace").innerHTML = "I'm good, thank you";

  },

}

function on() {
    speak("now listening")
}

// bind all of our spoken commands to the actions
if (annyang) {
    annyang.setLanguage('en-GB');

    // Define the triggers for the commands
    var commands = {
        '(hello)(hi)(hey)': function() {
            speak('hello ');
            document.getElementById("#resultplace").innerHTML = "hello ";
        },
        '(Who made you)(Who created you)': function() {
            speak('sam bolton');
            document.getElementById("#resultplace").innerHTML = "sam bolton";
        },
        '(hey aubrey)(aubrey)': function() {
            speak('Ready, sir');
            document.getElementById("#resultplace").innerHTML = "Ready, sir";

        },
        '(thats good) (that is good)': function() {
            speak('Ready, sir');
            document.getElementById("#resultplace").innerHTML = "good';
          },
        '(shutup) (shut up) (pause) (be quit) (go to sleep) (stop)': function() {
            annyang.pause();
            annyang.removeCommands();
            annyang.addCommands(commands2);
            annyang.resume();
          document.getElementById("#resultplace").innerHTML = "Paused";
        },

        '(hey aubrey can you) (can you) youtube *term': actions.youtube,
        'search *term': actions.search,
        '(hey aubrey can you) (can you) google *term': actions.google,
        'roll a d20': actions.d20,
        'roll a d6': actions.d6,
        'What is *term': actions.wolfram,
        'what is the weather in *term': actions.weather,
        '(How are you) (you good) (are you alright)': actions.howu,

    };
var commands2 = {
  //this is for the pause function only!
  '(wake up)(resume)(aubry wakeup)(start)': function() {
    annyang.pause();
    annyang.removeCommands();
    annyang.addCommands(commands);
    annyang.resume();
    document.getElementById("#resultplace").innerHTML = "Resumed";
  }

}
    // take our list of commands and stick them all in
    annyang.addCommands(commands);
}
<commit_msg>tasty bugs (killed em)<commit_after>//change this if we have longer commands
annyang.start({continuous: false});

function save_data(){
var input = document.getElementById("fname");
localStorage.setItem("fname", input.value);
}
var firstname = localStorage.getItem("fname");

function speak (phrase) {
    var worte = new SpeechSynthesisUtterance(phrase);
    worte.lang = "en-GB";
    window.speechSynthesis.speak(worte);
}

// Just a list of functions that anyone can call
// you can call these in the console by typing actions.YourFunctioName()
var actions = {

    youtube: function (term) {
        window.location.href = 'https://www.youtube.com/results?search_query='+term;
    },

    google: function (term) {
        window.location.href = 'https://www.google.com/#q='+term;
    },
    d20: function () {
      var d20 = Math.floor(Math.random() * 20);
      speak(d20);
      document.getElementById("#resultplace").innerHTML = d20;
    },

    d6: function () {
      var d6 = Math.floor(Math.random() * 6);
      speak(d6);
      document.getElementById("#resultplace").innerHTML = d6;
    },
  wolfram: function(term) {
    $.get("https://api.wolframalpha.com/v2/query?input="+term+"&appid=THYQLJ-3K45Y2A7W5"), function(wolfram__) {
        speak(wolfram__);
        };
    //http://api.wolframalpha.com/v2/query?input=pi&appid=XXXX
    //var wolfram_ = "http://api.wolframalpha.com/v2/query?input="+term+"&appid=THYQLJ-3K45Y2A7W5";
    //speak(wolfram_);
  },
  weather: function (term) {
    $.get('https://api.openweathermap.org/data/2.5/weather?q='+term, function (theweather) {
      speak(theweather.temp);

  });

},
howu: function () {
  speak("I'm good");
  document.getElementById("#resultplace").innerHTML = "I'm good, thank you";

  },

}

function on() {
    speak("now listening")
}

// bind all of our spoken commands to the actions
if (annyang) {
    annyang.setLanguage('en-GB');

    // Define the triggers for the commands
    var commands = {
        '(hello)(hi)(hey)': function() {
            speak('hello ');
            document.getElementById("#resultplace").innerHTML = "hello ";
        },
        annyang. addCallback('resultNoMatch', function(){speak('I dont know what you mean');  document.getElementById("#resultplace").innerHTML = "I dont know what you mean.";});
        '(Who made you)(Who created you)': function() {
            speak('sam bolton');
            document.getElementById("#resultplace").innerHTML = "sam bolton";
        },
        '(hey aubrey)(aubrey)': function() {
            speak('Ready, sir');
            document.getElementById("#resultplace").innerHTML = "Ready, sir";

        },
        '(thats good) (that is good)': function() {
            speak('Ready, sir');
            document.getElementById("#resultplace").innerHTML = "good";
          },
        '(shutup) (shut up) (pause) (be quit) (go to sleep) (stop)': function() {
            annyang.pause();
            annyang.removeCommands();
            annyang.addCommands(commands2);
            annyang.resume();
            annyang. addCallback('resultNoMatch', function(){});
          document.getElementById("#resultplace").innerHTML = "Paused";
        },

        '(hey aubrey can you) (can you) youtube *term': actions.youtube,
        'search *term': actions.search,
        '(hey aubrey can you) (can you) google *term': actions.google,
        'roll a d20': actions.d20,
        'roll a d6': actions.d6,
        'What is *term': actions.wolfram,
        'what is the weather in *term': actions.weather,
        '(How are you) (you good) (are you alright)': actions.howu,

    };
var commands2 = {
  //this is for the pause function only!
  '(wake up)(resume)(aubry wakeup)(start)': function() {
    annyang.pause();
    annyang.removeCommands();
    annyang.addCommands(commands);
    annyang.resume();
    document.getElementById("#resultplace").innerHTML = "Resumed";
  }

}
    // take our list of commands and stick them all in
    annyang.addCommands(commands);
}
<|endoftext|>


<commit_before>/*global SheetMusic, Piano */

var CANVAS = document.getElementById('game-board');
var CTX = CANVAS.getContext('2d');
var SETTINGS = getOptions();
var SHEET_MUSIC = new SheetMusic(SETTINGS);
var PIANO_WIDTH = 300;
var PIANO = new Piano(CTX, calcPianoX(), calcPianoY(), PIANO_WIDTH, 150);

PIANO.click(function() {
    this.draw();
    checkUserInput(this.pressedKeys.toArray(), false);
});

function checkUserInput(pressedKeys, strict) {
    if (compareKeys(SHEET_MUSIC.nextNotes(), pressedKeys, strict)) {
        SHEET_MUSIC.draw('green');
        SHEET_MUSIC.consumeNotes();
        setTimeout(function() {
            SHEET_MUSIC.draw();
            PIANO.release();
            PIANO.draw();
        }, 200);
    }
}

function compareKeys(correctKeys, pressedKeys, strict) {
    return correctKeys.every(function(note) {
        return pressedKeys.some(function(pNote) {
            return pNote.equals(note, strict);
        });
    });
}

function updateGame() {
    CTX.clearRect(0, 0, CANVAS.width, CANVAS.height);
    SETTINGS = getOptions();
    SHEET_MUSIC.update(getOptions());
    SHEET_MUSIC.draw();
    PIANO.update(calcPianoX(), calcPianoY());
    PIANO.draw();
}

function calcPianoY() {
    return SHEET_MUSIC.height() + 50;
}

function calcPianoX() {
    return CANVAS.width / 2 - PIANO_WIDTH / 2;
}

function getOptions() {
    var selectedKey = $('#selKey').val();
    var selectedClef = $('#selClef').val();
    var treble, bass;
    if (selectedClef === 'BOTH') {
        treble = bass = true;
    } else if (selectedClef === 'TREBLE') {
        treble = true;
        bass = false;
    } else {
        treble = false;
        bass = true;
    }
    return {
        'ctx': CTX,
        'key': selectedKey,
        'withTreble': treble,
        'withBass': bass
    };
}

function updateLocalSettings() {
    var settings = {
        mode: $('#selMode').val(),
        key: $('#selKey').val(),
        clef: $('#selClef').val()
    };
    localStorage.setItem('mahler-settings', JSON.stringify(settings));
}

$('#btn-start').click(function() {
    var mainBtn = this;
    var startClick = true;
    if ($(mainBtn).hasClass('clicked')) {
        $(mainBtn).removeClass('clicked');
        startClick = false;
    } else {
        $(mainBtn).addClass('clicked');
    }
    if (startClick) {
        updateLocalSettings();
        $('#game-menu').fadeOut(300, function() {
            updateGame();
            $('#game-board').show();
            $(mainBtn).text('OPTIONS');
        });
    } else {
        $('#game-board').fadeOut(300, function() {
            $('#game-menu').show();
            $(mainBtn).text('START');
        });
    }
});

$(document).ready(function() {
    var settings = localStorage.getItem('mahler-settings');
    if (settings !== null) {
        settings = JSON.parse(settings);
        $('#selMode').val(settings.mode);
        $('#selKey').val(settings.key);
        $('#selClef').val(settings.clef);
    }
});
<commit_msg>Replaced forgotten getOptions() call with SETTINGS variable<commit_after>/*global SheetMusic, Piano */

var CANVAS = document.getElementById('game-board');
var CTX = CANVAS.getContext('2d');
var SETTINGS = getOptions();
var SHEET_MUSIC = new SheetMusic(SETTINGS);
var PIANO_WIDTH = 300;
var PIANO = new Piano(CTX, calcPianoX(), calcPianoY(), PIANO_WIDTH, 150);

PIANO.click(function() {
    this.draw();
    checkUserInput(this.pressedKeys.toArray(), false);
});

function checkUserInput(pressedKeys, strict) {
    if (compareKeys(SHEET_MUSIC.nextNotes(), pressedKeys, strict)) {
        SHEET_MUSIC.draw('green');
        SHEET_MUSIC.consumeNotes();
        setTimeout(function() {
            SHEET_MUSIC.draw();
            PIANO.release();
            PIANO.draw();
        }, 200);
    }
}

function compareKeys(correctKeys, pressedKeys, strict) {
    return correctKeys.every(function(note) {
        return pressedKeys.some(function(pNote) {
            return pNote.equals(note, strict);
        });
    });
}

function updateGame() {
    CTX.clearRect(0, 0, CANVAS.width, CANVAS.height);
    SETTINGS = getOptions();
    SHEET_MUSIC.update(SETTINGS);
    SHEET_MUSIC.draw();
    PIANO.update(calcPianoX(), calcPianoY());
    PIANO.draw();
}

function calcPianoY() {
    return SHEET_MUSIC.height() + 50;
}

function calcPianoX() {
    return CANVAS.width / 2 - PIANO_WIDTH / 2;
}

function getOptions() {
    var selectedKey = $('#selKey').val();
    var selectedClef = $('#selClef').val();
    var treble, bass;
    if (selectedClef === 'BOTH') {
        treble = bass = true;
    } else if (selectedClef === 'TREBLE') {
        treble = true;
        bass = false;
    } else {
        treble = false;
        bass = true;
    }
    return {
        'ctx': CTX,
        'key': selectedKey,
        'withTreble': treble,
        'withBass': bass
    };
}

function updateLocalSettings() {
    var settings = {
        mode: $('#selMode').val(),
        key: $('#selKey').val(),
        clef: $('#selClef').val()
    };
    localStorage.setItem('mahler-settings', JSON.stringify(settings));
}

$('#btn-start').click(function() {
    var mainBtn = this;
    var startClick = true;
    if ($(mainBtn).hasClass('clicked')) {
        $(mainBtn).removeClass('clicked');
        startClick = false;
    } else {
        $(mainBtn).addClass('clicked');
    }
    if (startClick) {
        updateLocalSettings();
        $('#game-menu').fadeOut(300, function() {
            updateGame();
            $('#game-board').show();
            $(mainBtn).text('OPTIONS');
        });
    } else {
        $('#game-board').fadeOut(300, function() {
            $('#game-menu').show();
            $(mainBtn).text('START');
        });
    }
});

$(document).ready(function() {
    var settings = localStorage.getItem('mahler-settings');
    if (settings !== null) {
        settings = JSON.parse(settings);
        $('#selMode').val(settings.mode);
        $('#selKey').val(settings.key);
        $('#selClef').val(settings.clef);
    }
});
<|endoftext|>