<commit_before>//! moment.js locale configuration
//! locale : ukrainian (uk)
//! author : zemlanin : https://github.com/zemlanin
//! Author : Menelion Elensúle : https://github.com/Oire

    function plural(word, num) {
        var forms = word.split('_');
        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
    }
    function relativeTimeWithPlural(number, withoutSuffix, key) {
        var format = {
            'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
            'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
            'dd': 'день_дні_днів',
            'MM': 'місяць_місяці_місяців',
            'yy': 'рік_роки_років'
        };
        if (key === 'm') {
            return withoutSuffix ? 'хвилина' : 'хвилину';
        }
        else if (key === 'h') {
            return withoutSuffix ? 'година' : 'годину';
        }
        else {
            return number + ' ' + plural(format[key], +number);
        }
    }
    function processHoursFunction(str) {
        return function () {
            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
        };
    }

    var uk = moment.defineLocale('uk', {
        months : function (m, format) {
            var months = {
                'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),
                'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),
            },
            nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
                'accusative' :
                'nominative';
            return months[nounCase][m.month()];
        },
        monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),
        weekdays : function (w, format) {
            var weekdays = {
                'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
                'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
                'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_'),
            },
            nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
                'accusative' :
                ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
                    'genitive' :
                    'nominative');
            return weekdays[nounCase][w.day()];
        },
        weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
        longDateFormat : {
            LT : 'HH:mm',
            LTS : 'HH:mm:ss',
            L : 'DD.MM.YYYY',
            LL : 'D MMMM YYYY р.',
            LLL : 'D MMMM YYYY р., HH:mm',
            LLLL : 'dddd, D MMMM YYYY р., HH:mm'
        },
        calendar : {
            sameDay: processHoursFunction('[Сьогодні '),
            nextDay: processHoursFunction('[Завтра '),
            lastDay: processHoursFunction('[Вчора '),
            nextWeek: processHoursFunction('[У] dddd ['),
            lastWeek: function () {
                switch (this.day()) {
                case 0:
                case 3:
                case 5:
                case 6:
                    return processHoursFunction('[Минулої] dddd [').call(this);
                case 1:
                case 2:
                case 4:
                    return processHoursFunction('[Минулого] dddd [').call(this);
                }
            },
            sameElse: 'L'
        },
        relativeTime : {
            future : 'за %s',
            past : '%s тому',
            s : 'декілька секунд',
            m : relativeTimeWithPlural,
            mm : relativeTimeWithPlural,
            h : 'годину',
            hh : relativeTimeWithPlural,
            d : 'день',
            dd : relativeTimeWithPlural,
            M : 'місяць',
            MM : relativeTimeWithPlural,
            y : 'рік',
            yy : relativeTimeWithPlural
        },
        // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
        meridiemParse: /ночі|ранку|дня|вечора/,
        isPM: function (input) {
            return /^(дня|вечора)$/.test(input);
        },
        meridiem : function (hour, minute, isLower) {
            if (hour < 4) {
                return 'ночі';
            } else if (hour < 12) {
                return 'ранку';
            } else if (hour < 17) {
                return 'дня';
            } else {
                return 'вечора';
            }
        },
        ordinalParse: /\d{1,2}-(й|го)/,
        ordinal: function (number, period) {
            switch (period) {
            case 'M':
            case 'd':
            case 'DDD':
            case 'w':
            case 'W':
                return number + '-й';
            case 'D':
                return number + '-го';
            default:
                return number;
            }
        },
        week : {
            dow : 1, // Monday is the first day of the week.
            doy : 7  // The week that contains Jan 1st is the first week of the year.
        }
    });
<commit_msg>fix   locale/config.js<commit_after>// Ukrainian [uk]
function plural(word, num) {
  const forms = word.split('_')
  return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]) // eslint-disable-line
}
function relativeTimeWithPlural(number, withoutSuffix, key) {
  const format = {
    mm: withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
    hh: 'година_години_годин',
    dd: 'день_дні_днів',
    MM: 'місяць_місяці_місяців',
    yy: 'рік_роки_років'
  }
  if (key === 'm') {
    return withoutSuffix ? 'хвилина' : 'хвилину'
  }
  return `${number} ${plural(format[key], +number)}`
}

dayjs.locale({
  name: 'uk',
  weekdays: 'Неділя_Понеділок_Вівторок_Середа_Четвер_Пʼятниця_Субота'.split('_'),
  weekdaysShort: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
  weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
  months: 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'),
  ordinal: n => `${n}.`,
  weekStart: 1,
  formats: {
    LT: 'H:mm',
    LTS: 'H:mm:ss',
    L: 'DD.MM.YYYY',
    LL: 'D MMMM YYYY',
    LLL: 'D MMM YYYY | H:mm',
    LLLL: 'D MMMM YYYY | H:mm'
  },
  relativeTime: {
    future: 'за %s',
    past: '%s тому',
    s: 'декілька секунд',
    m: relativeTimeWithPlural,
    mm: relativeTimeWithPlural,
    h: 'годину',
    hh: relativeTimeWithPlural,
    d: 'день',
    dd: relativeTimeWithPlural,
    M: 'місяц',
    MM: relativeTimeWithPlural,
    y: 'рік',
    yy: relativeTimeWithPlural
  },
})
<|endoftext|>


<commit_before>define(function () {
  return function (data, type) {
    var output = {};
    var grid = Math.ceil(Math.sqrt(data.length));

    switch (type) {
      case "grid":
        output.rows = grid;
        output.columns = grid;
        break;

      case "columns":
        output.rows = 1;
        output.columns = data.length;
        break;

      default:
        output.rows = data.length;
        output.columns = 1;
        break;
    }

    return output;
  };
});<commit_msg>update<commit_after>define(function () {
  return function (data, type) {
    var grid = Math.ceil(Math.sqrt(data.length));
    var output = {};

    switch (type) {
      case "grid":
        output.rows = grid;
        output.columns = grid;
        break;

      case "columns":
        output.rows = 1;
        output.columns = data.length;
        break;

      default:
        output.rows = data.length;
        output.columns = 1;
        break;
    }

    return output;
  };
});<|endoftext|>


<commit_before>var cluster = require('cluster');
var _       = require('lodash');
var comrade = require('./');

if (cluster.isMaster) {
  var Consumer = new comrade.Consumer('postgres://localhost/postgres', function(err, client) {

    var numbersToProcess = _.range(1, 1000);
    var workerResults = [];
    var iAmDone = _.after(numbersToProcess.length, function() {
      console.log('All done!');
      console.log(_.countBy(workerResults));
    });

    _.each(numbersToProcess, function(num) {
      (function(num) {
        Consumer.createJob({ input: num })
        .then(function(results) {
          workerResults.push(results.worker);
          iAmDone();
        });
      })(num);
    });

    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
  });
  console.log('I am the master!');
}

if (cluster.isWorker) {
  var Worker = new comrade.Worker('postgres://localhost/postgres', function(err, client) {
    Worker.watchForJobs(function(payload, cb) {
      cb(null, { result: payload.input * 2, worker: cluster.worker.id });
    });
  }, cluster.worker.id);
}
<commit_msg>Added queue names to concurrency test<commit_after>var cluster = require('cluster');
var _       = require('lodash');
var comrade = require('./');

if (cluster.isMaster) {
  var Consumer = new comrade.Consumer('postgres://localhost/postgres', function(err, client) {

    var numbersToProcess = _.range(1, 1000);
    var workerResults = [];
    var iAmDone = _.after(numbersToProcess.length, function() {
      console.log('All done!');
      console.log(_.countBy(workerResults));
    });

    _.each(numbersToProcess, function(num) {
      (function(num) {
        Consumer.createJob('default', { input: num })
        .then(function(results) {
          workerResults.push(results.worker);
          iAmDone();
        });
      })(num);
    });

    cluster.fork();
    cluster.fork();
    cluster.fork();
    cluster.fork();
  });
  console.log('I am the master!');
}

if (cluster.isWorker) {
  var Worker = new comrade.Worker('postgres://localhost/postgres', function(err, client) {
    Worker.watchForJobs('default', function(payload, cb) {
      cb(null, { result: payload.input * 2, worker: cluster.worker.id });
    });
  }, cluster.worker.id);
}
<|endoftext|>


<commit_before><commit_msg>update node-base64.js submodule<commit_after><|endoftext|>


<commit_before>import React, { Component } from 'react';
import './css/Dungeon.css';

const damage = [7, 20, 32, 42, 58];  // per dungeon
// let reward = 10  // add 10 for each level;

export default class Dungeon extends Component {

	constructor(props) {
		super(props);
	    this.state = {enemyLife: 50, reward: 10}; // add 50 per dungeon
	}

	componentDidMount() {
		window.addEventListener('keydown', this.onKeyDown);
	}

	componentWillUnmount() {
		window.removeEventListener('keydown', this.onKeyDown);
	}

	onKeyDown = (event) => {
		// prevent page scrolling from the arrow keys:
	    event.preventDefault();
	    switch (event.keyCode) {
	    	case 37:
	    		this.moveLeft();
	    		break;
	    	case 38:
	    		this.moveUp();
	    		break;
	    	case 39:
	    		this.moveRight();
	    		break;
	    	case 40:
	    		this.moveDown();
	    		break;
	    	default:
	    		// do nothing
	    }
	}

	moveUp() {
		const {health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;

		// don't leave the board:
		if (cursor.y === 0) return;

		if (cells[cursor.y - 1][cursor.x].className.includes("empty")) {
			cells[cursor.y - 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y--;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("health")) {
		    this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("enemy")) {
		    if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("weapon")) {
		    // change weapon:
			let weapon = this.props.weapons[dungeon + 1];
		    if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
		    this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("stairs")) {
		    let enemyLife = 50 + dungeon * 50;
		    this.move(health, dungeon + 1, cells, cursor);
		    // create new board:
		    setTimeout(function () {
		      //resetDungeon();
		      //createDungeon();
		      //refresh();
		    }, 500);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("boss")) {
		    // fight the boss:
		    // fightBoss();
		}
	}

	moveRight() {
		const {boardWidth, health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;

		// don't leave the board:
		if (cursor.x + 1 === boardWidth) return;

		if (cells[cursor.y][cursor.x + 1].className.includes("empty")) {
			cells[cursor.y][cursor.x + 1].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.x++;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("health")) {
			this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("enemy")) {
			if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("weapon")) {
			// change weapon:
			let weapon = this.props.weapons[dungeon + 1];
			if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("stairs")) {
			// change dungeon:
			let enemyLife = 50 + dungeon * 50;
			this.move(health, dungeon + 1, cells, cursor);
			// create new board:
			/*setTimeout(function () {
				resetDungeon();
				createDungeon();
				refresh();
			}, 500);*/
		} else if (cells[cursor.y][cursor.x + 1].className.includes("boss")) {
			// fight the boss:
			// fightBoss();
		}
	}

	moveDown() {
		const {boardHeight, health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;

		// don't leave the board:
		if (cursor.y + 1 === boardHeight) return;

		if (cells[cursor.y + 1][cursor.x].className.includes("empty")) {
			cells[cursor.y + 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y++;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("health")) {
		    this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("enemy")) {
		    if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("weapon")) {
		    // change weapon:
		    let weapon = this.props.weapons[dungeon + 1];
		    if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
		    this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("stairs")) {
		    // change dungeon:
		    let enemyLife = 50 + dungeon * 50;
		    this.move(health, dungeon + 1, cells, cursor);
		    // create new board:
		    /*setTimeout(function () {
		    	resetDungeon();
		    	createDungeon();
		    	refresh();
		    }, 500);*/
		} else if (cells[cursor.y + 1][cursor.x].className.includes("boss")) {
			// fight the boss:
		    // fightBoss();
		}
	}

	moveLeft() {
		const {boardHeight, health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;
		const {reward} = this.state;

		// don't leave the board:
		if (cursor.x - 1 < 0) return;

		if (cells[cursor.y][cursor.x - 1].className.includes("empty")) {
			cells[cursor.y][cursor.x - 1].className = "cell cursor"
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.x--;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("health")) {
		    this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("enemy")) {
		    if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("weapon")) {
		    // change weapon:
		    let weapon = this.props.weapons[dungeon + 1];
		    if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
		    this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("stairs")) {
		    // change dungeon:
		    let enemyLife = 50 + dungeon * 50;
		    this.move(health, dungeon + 1, cells, cursor);
		    // create new board:
		    /*setTimeout(function () {
		    	resetDungeon();
		    	createDungeon();
		    	refresh();
		    }, 500);*/
		} else if (cells[cursor.y][cursor.x - 1].className.includes("boss")) {
			  // fight the boss:
			  // fightBoss();
		}
	}

	move(health, dungeon, cells, cursor) {
	    // if (dark) moveDarkness();
		this.props.move(health, dungeon, cells, cursor);
	}

	defeat() {
		console.log("defeat");
		const {dungeon} = this.props;
		let {health, attack, nextLevelPoints, level} = this.props;
		let {reward} = this.state;
		let dead = false;

		let myDamage = Math.floor(Math.random() * damage[dungeon] / 3) * this.getSign() + damage[dungeon];
		console.log("myDamage = " + myDamage);
		let enemyDamage = Math.floor(Math.random() * attack / 3) * this.getSign() + attack;
		console.log("enemyDamage = " + enemyDamage);
		let enemyLife = enemyLife - enemyDamage;
		console.log("enemyLife = " + enemyLife);
		if (enemyLife > 0) {
			health = health - myDamage;
		    if (health <= 0) {
		    	dead = true;
		    	console.log("dead = " + dead);
		    	// refresh();
		    	// reset();
		    }
		    // refresh();
		    return false;
		} else if (enemyLife <= 0) {
			enemyLife = 50 + dungeon * 50;
			nextLevelPoints = nextLevelPoints - reward;
		    if (nextLevelPoints === 0) {
		    	level++;
		    	// weapon bonus for fine tuning:
		    	switch (level) {
		        	case 2:
		        		attack += 78;
		        		break;
		        	case 3:
		        		attack += 64;
		        		break;
		        	case 4:
		        		attack += 128;
		        		break;
		    	}
		    	nextLevelPoints = 60 + level * 60;
		    	reward = 10 + level * 10;
		    	health += level * 20;
		    }
		    return true;
		}
	}

	getSign() {
		var r = Math.floor(Math.random() * 2);
		switch (r) {
		case 0:
			return 1;
		case 1:
			return -1;
		}
	}

	render() {
		return (

				{this.props.cells.map(row =>
{row.map(cell =>

)}
)}

		);
	}
}

<commit_msg>completed health<commit_after>import React, { Component } from 'react';
import './css/Dungeon.css';

const damage = [7, 20, 32, 42, 58];  // per dungeon
// let reward = 10  // add 10 for each level;

export default class Dungeon extends Component {

	constructor(props) {
		super(props);
	    this.state = {enemyLife: 50, reward: 10}; // add 50 per dungeon
	}

	componentDidMount() {
		window.addEventListener('keydown', this.onKeyDown);
	}

	componentWillUnmount() {
		window.removeEventListener('keydown', this.onKeyDown);
	}

	onKeyDown = (event) => {
		// prevent page scrolling from the arrow keys:
	    event.preventDefault();
	    switch (event.keyCode) {
	    	case 37:
	    		this.moveLeft();
	    		break;
	    	case 38:
	    		this.moveUp();
	    		break;
	    	case 39:
	    		this.moveRight();
	    		break;
	    	case 40:
	    		this.moveDown();
	    		break;
	    	default:
	    		// do nothing
	    }
	}

	moveUp() {
		const {health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;

		// don't leave the board:
		if (cursor.y === 0) return;

		if (cells[cursor.y - 1][cursor.x].className.includes("empty")) {
			cells[cursor.y - 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y--;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("health")) {
			cells[cursor.y - 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y--;
		    this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("enemy")) {
		    if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("weapon")) {
		    // change weapon:
			let weapon = this.props.weapons[dungeon + 1];
		    if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
		    this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("stairs")) {
		    let enemyLife = 50 + dungeon * 50;
		    this.move(health, dungeon + 1, cells, cursor);
		    // create new board:
		    setTimeout(function () {
		      //resetDungeon();
		      //createDungeon();
		      //refresh();
		    }, 500);
		} else if (cells[cursor.y - 1][cursor.x].className.includes("boss")) {
		    // fight the boss:
		    // fightBoss();
		}
	}

	moveRight() {
		const {boardWidth, health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;

		// don't leave the board:
		if (cursor.x + 1 === boardWidth) return;

		if (cells[cursor.y][cursor.x + 1].className.includes("empty")) {
			cells[cursor.y][cursor.x + 1].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.x++;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("health")) {
			cells[cursor.y][cursor.x + 1].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.x++;
			this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("enemy")) {
			if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("weapon")) {
			// change weapon:
			let weapon = this.props.weapons[dungeon + 1];
			if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x + 1].className.includes("stairs")) {
			// change dungeon:
			let enemyLife = 50 + dungeon * 50;
			this.move(health, dungeon + 1, cells, cursor);
			// create new board:
			/*setTimeout(function () {
				resetDungeon();
				createDungeon();
				refresh();
			}, 500);*/
		} else if (cells[cursor.y][cursor.x + 1].className.includes("boss")) {
			// fight the boss:
			// fightBoss();
		}
	}

	moveDown() {
		const {boardHeight, health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;

		// don't leave the board:
		if (cursor.y + 1 === boardHeight) return;

		if (cells[cursor.y + 1][cursor.x].className.includes("empty")) {
			cells[cursor.y + 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y++;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("health")) {
			cells[cursor.y + 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y++;
		    this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("enemy")) {
			cells[cursor.y + 1][cursor.x].className = "cell cursor";
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.y++;
		    if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("weapon")) {
		    // change weapon:
		    let weapon = this.props.weapons[dungeon + 1];
		    if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
		    this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y + 1][cursor.x].className.includes("stairs")) {
		    // change dungeon:
		    let enemyLife = 50 + dungeon * 50;
		    this.move(health, dungeon + 1, cells, cursor);
		    // create new board:
		    /*setTimeout(function () {
		    	resetDungeon();
		    	createDungeon();
		    	refresh();
		    }, 500);*/
		} else if (cells[cursor.y + 1][cursor.x].className.includes("boss")) {
			// fight the boss:
		    // fightBoss();
		}
	}

	moveLeft() {
		const {boardHeight, health, cells, cursor, dungeon} = this.props;
		let {attack} = this.props;
		const {reward} = this.state;

		// don't leave the board:
		if (cursor.x - 1 < 0) return;

		if (cells[cursor.y][cursor.x - 1].className.includes("empty")) {
			cells[cursor.y][cursor.x - 1].className = "cell cursor"
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.x--;
			this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("health")) {
			cells[cursor.y][cursor.x - 1].className = "cell cursor"
			cells[cursor.y][cursor.x].className = "cell empty";
			cursor.x--;
		    this.move(health + 20, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("enemy")) {
		    if (this.defeat()) this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("weapon")) {
		    // change weapon:
		    let weapon = this.props.weapons[dungeon + 1];
		    if (attack < this.props.attackValues[dungeon + 1]) attack = this.props.attackValues[dungeon + 1];
		    this.move(health, dungeon, cells, cursor);
		} else if (cells[cursor.y][cursor.x - 1].className.includes("stairs")) {
		    // change dungeon:
		    let enemyLife = 50 + dungeon * 50;
		    this.move(health, dungeon + 1, cells, cursor);
		    // create new board:
		    /*setTimeout(function () {
		    	resetDungeon();
		    	createDungeon();
		    	refresh();
		    }, 500);*/
		} else if (cells[cursor.y][cursor.x - 1].className.includes("boss")) {
			  // fight the boss:
			  // fightBoss();
		}
	}

	move(health, dungeon, cells, cursor) {
	    // if (dark) moveDarkness();
		this.props.move(health, dungeon, cells, cursor);
	}

	defeat() {
		console.log("defeat");
		const {dungeon} = this.props;
		let {health, attack, nextLevelPoints, level} = this.props;
		let {reward} = this.state;
		let dead = false;

		let myDamage = Math.floor(Math.random() * damage[dungeon] / 3) * this.getSign() + damage[dungeon];
		console.log("myDamage = " + myDamage);
		let enemyDamage = Math.floor(Math.random() * attack / 3) * this.getSign() + attack;
		console.log("enemyDamage = " + enemyDamage);
		let enemyLife = enemyLife - enemyDamage;
		console.log("enemyLife = " + enemyLife);
		if (enemyLife > 0) {
			health = health - myDamage;
		    if (health <= 0) {
		    	dead = true;
		    	console.log("dead = " + dead);
		    	// refresh();
		    	// reset();
		    }
		    // refresh();
		    return false;
		} else if (enemyLife <= 0) {
			enemyLife = 50 + dungeon * 50;
			nextLevelPoints = nextLevelPoints - reward;
		    if (nextLevelPoints === 0) {
		    	level++;
		    	// weapon bonus for fine tuning:
		    	switch (level) {
		        	case 2:
		        		attack += 78;
		        		break;
		        	case 3:
		        		attack += 64;
		        		break;
		        	case 4:
		        		attack += 128;
		        		break;
		    	}
		    	nextLevelPoints = 60 + level * 60;
		    	reward = 10 + level * 10;
		    	health += level * 20;
		    }
		    return true;
		}
	}

	getSign() {
		var r = Math.floor(Math.random() * 2);
		switch (r) {
		case 0:
			return 1;
		case 1:
			return -1;
		}
	}

	render() {
		return (

				{this.props.cells.map(row =>
{row.map(cell =>

)}
)}

		);
	}
}

<|endoftext|>


<commit_before>dojo.provide("dojox.lang.mix");

// This is a highly experimental functionality,
// it will be split later on individual files,
// and mixed with OO package

// TODO: do we need to use hasOwnProperty() everywhere?

(function(){
	var empty = {}, mix = dojox.lang.mix;

	mix.processProps = function(props, rename, remove){
		// summary: process properties in place by renaming and removing them as needed,
		//			only own properties are processed.
		// description: properties are filtered by "skip" parameter, then renamed.
		// props: Object: the object to be processed
		// rename: Object?: the dictionary for renaming
		// remove: Array?|Object?: the source of properties to be skipped

		if(props){
			var t, i, j, l;
			// delete properties
			if(remove){
				if(dojo.isArray(remove)){
					for(j = 0, l = remove.length; j < l; ++j){
						delete props[remove[j]];
					}
				}else{
					for(i in remove){
						if(remove.hasOwnProperty(i)){
							delete props[i];
						}
					}
				}
			}

			// rename properties
			if(rename){
				for(i in rename){
					if(rename.hasOwnProperty(i) && props.hasOwnProperty(i)){
						t = props[i];
						delete props[i];
						props[rename[i]] = t;
					}
				}
			}
		}
		return props;	// Object
	};

	// preprocessing mixins

	var Filter = function(value, rename, skip){
		// summary: filters an object by skipping properties and renaming them
		// value: Object: object to be filtered
		// rename: Object: the dictionary for renaming
		// skip: Array?|Object?: the source of properties to be skipped
		this.value = value;
		this.rename = rename || empty;
		if(skip && dojo.isArray(skip)){
			var p = {};
			for(var j=0, l=skip.length; j<l; ++j){
				p[skip[j]] = 1;
			}
			this.skip = p;
		}else{
			this.skip = skip || empty;
		}
	};
	dojo.extend(Filter, {
		filter: function(name){
			// summary: takes in name, and filters it according to criteria
			// name: String: an input name
			// returns: String: can be the same name, new name,
			// or an empty string (when it should be deleted
			if(this.skip.hasOwnProperty(name)){ return ""; }
			return this.rename.hasOwnProperty(name) ? this.rename[name] : name;
		}
	});

	// mixing in members with decorators

	var Decorator = function(value){
		// summary: this class serves as a base class for all decorators
		// value: Object: a property to be mixed in later
		this.value = value;
	};
	dojo.extend(Decorator, {
		process: function(target, name){
			// summary: the default processing
			// target: Object: target object to accept a property
			// name: String: property's name
			if(this.value instanceof Decorator){
				this.value.process(target, name);
			}else{
				target[name] = this.value;
			}
		}
	});

	/*
	 * Example:
	 *  |	mix.mixer(target,
	 *  |		mix.augment(someDefaultProperties),
	 *  |		mix.filter(someOtherProperties, {exec: "doIt"}),
	 *  |		{
	 *  |			constructor: function(a, x){
	 *  |				// we assume that constructors are chained automatically
	 *  |				this.x = x;
	 *  |			},
	 *  |			advance: function(n){
	 *  |				// this is normal undecorated method
	 *  |				this.x += n;
	 *  |			},
	 *  |			log: mix.chainAfter(function(){
	 *  |				// this function will be called after the previous log()
	 *  |				console.log("x = ", this.x);
	 *  |			}),
	 *  |			debug: mix.augment(function(){
	 *  |				// this function will be added only if it was not defined yet
	 *  |				console.debug(this);
	 *  |			}),
	 *  |			display: mix.override(function(){
	 *  |				// this function will replace a previously defined display(),
	 *  |				// otherwise it is not added
	 *  |
	 *  |				// ignore the call, and do nothing
	 *  |			})
	 *  |		}
	 *  |	);
	 */

	mix.mixer = function(target, source){
		// summary: mixes two objects processing decorators
		// target: Object: target to receive new/updated properties
		// source: Object...: source of properties, more than one source is allowed
		// returns: Object: target

		// mixer can apply decorators by default for predefined names
		// (it doesn't do it now)
		// examples (see predefined decorators below):
		//	- undecorated "constructor" can be treated similar to chainAfter
		//	- undecorated "destroy" can be treated as chainBefore

		var dcr = null, flt = null, i, l = arguments.length, name, prop, targetName;
		for(i = 1, l; i < l; ++i){
			source = arguments[i];
			if(source instanceof Decorator){
				// use the instance of decorator as a default processor
				dcr = source;
				// extract the real source
				source = dcr.value;
			}
			if(source instanceof Filter){
				flt = source;
				source = flt.value;
			}
			for(name in source){
				if(source.hasOwnProperty(name)){
					prop = source[name];
					targetName = flt ? flt.filter(name) : name;
					if(!targetName){
						// skip filtered out names
						continue;
					}
					if(prop instanceof Decorator){
						// decorator: process it
						prop.process(target, targetName);
					}else{
						// no decorator: use the default
						if(dcr){
							dcr.value = prop;
							dcr.process(target, targetName);
						}else{
							target[targetName] = prop;
						}
					}
				}
			}
			if(flt){
				source = flt;
				flt = null;
			}
			if(dcr){
				dcr.value = source;
				dcr = null;
			}
		}
		return target;	// Object
	};

	mix.makeFilter = function(mixin){
		// summary: subclasses Filter and returns new class
		// mixin: Object: new methods
		// returns: Object: new class

		// don't do it at home!
		dojo.declare("dojox.__temp__", Filter, mixin || empty);
		var t = dojox.__temp__;
		delete dojox.__temp__;
		return t;	// Object
	};

	mix.createFilter = function(filter){
		// summary: simple helper function to construct decorator creators
		// filter: Function: the processing function
		// returns: Function
		var Filter = mix.makeFilter(filter && {filter: filter} || empty);
		return function(value){ return new Filter(value); };	// Function
	};

	mix.makeDecorator = function(mixin){
		// summary: subclasses Decorator and returns new class
		// mixin: Object: new methods
		// returns: Object: new class

		// don't do it at home!
		dojo.declare("dojox.__temp__", Decorator, mixin || empty);
		var t = dojox.__temp__;
		delete dojox.__temp__;
		return t;	// Object
	};

	mix.createDecorator = function(process){
		// summary: simple helper function to construct decorator creators
		// process: Function: the processing function
		// returns: Function
		var Decorator = mix.makeDecorator(process && {process: process} || empty);
		return function(value){ return new Decorator(value); };	// Function
	};

	// predefined decorators

	var ReplaceContextDecorator = mix.makeDecorator({
		constructor: function(context, value){
			this.value = value;	// override value
			this.context = context;
		},
		process: function(target, name){
			// summary: call the method in different context
			// passing the original "this", original arguments,
			// method's name, and the old value as 4 arguments
			// target: Object: target object to accept a property
			// name: String: property's name
			var old = target[name], current = this.value, context = this.context;
			target[name] = function(){
				return current.call(context, this, arguments, name, old);
			};
		}
	});

	// TODO: should we check for properties to be actually functions?

	dojo.mixin(mix, {
		// defalt renaming and skipping filter
		filter: mix.createFilter(),
		// conditional mixing
		augment: mix.createDecorator(function(target, name){
			// summary: add property, if it was not defined before
			if(!(name in target)){ target[name] = this.value; }
		}),
		override: mix.createDecorator(function(target, name){
			// summary: override property only if it was already present
			if(name in target){ target[name] = this.value; }
		}),
		// substitutions
		replaceContext: function(context, value){
			// summary: call the method in different context
			// passing the original "this", original arguments,
			// method's name, and the old value as 4 arguments
			// context: Object: context for the call
			// value: Function: function to call
			return new ReplaceContextDecorator(context, value);
		},
		shuffle: mix.createDecorator(function(target, name){
			// summary: replaces arguments for old method
			if(name in target){
				var old = target[name], current = this.value;
				target[name] = function(){
					return old.apply(this, current.apply(this, arguments));
				};
			}
		}),
		// chaining (see AOP mixing below for another way to do it)
		chainBefore: mix.createDecorator(function(target, name){
			// summary: creates a chain of calls where the new method is called
			// before the old method
			if(name in target){
				var old = target[name], current = this.value;
				target[name] = function(){
					current.apply(this, arguments);
					return old.apply(this, arguments);
				};
			}else{
				target[name] = this.value;
			}
		}),
		chainAfter: mix.createDecorator(function(target, name){
			// summary: creates a chain of calls where the new method is called
			// after the old method
			if(name in target){
				var old = target[name], current = this.value;
				target[name] = function(){
					old.apply(this, arguments);
					return current.apply(this, arguments);
				};
			}else{
				target[name] = this.value;
			}
		}),
		// light-weight AOP mixing
		before: mix.createDecorator(function(target, name){
			// summary: creates a "before" advise
			var old = target[name], before = this.value;
			target[name] = old ?
				function(){
					before.apply(this, arguments);
					return old.apply(this, arguments);
				} :
				function(){
					before.apply(this, arguments);
				};
		}),
		around: mix.createDecorator(function(target, name){
			// summary: creates an "around" advise,
			// the previous value is passed as a first argument and can be "unknown",
			// arguments are passed as a second argument
			var old = target[name], around = this.value;
			target[name] = old ?
				function(){
					return around.call(this, old, arguments);
				} :
				function(){
					return around.call(this, null, arguments);
				};
		}),
		afterReturning: mix.createDecorator(function(target, name){
			// summary: creates an "afterReturning" advise,
			// the returned value is passed as the only argument
			var old = target[name], afterReturning = this.value;
			target[name] = old ?
				function(){
					var ret = old.apply(this, arguments);
					afterReturning.call(this, ret);
					return ret;
				} :
				function(){
					afterReturning.call(this);
				};
		}),
		afterThrowing: mix.createDecorator(function(target, name){
			// summary: creates an "afterThrowing" advise,
			// the exception is passed as the only argument
			var old = target[name], afterThrowing = this.value;
			if(old){
				target[name] = function(){
					var ret;
					try{
						ret = old.apply(this, arguments);
					}catch(e){
						afterThrowing.call(this, e);
						throw e;
					}
					return ret;
				};
			}
		}),
		after: mix.createDecorator(function(target, name){
			// summary: creates an "after" advise,
			// it takes no arguments
			var old = target[name], after = this.value;
			target[name] = old ?
				function(){
					var ret;
					try{
						ret = old.apply(this, arguments);
					}finally{
						after.call(this);
					}
					return ret;
				} :
				function(){
					after.call(this);
				}
		})
	});

	/*
		TODO: more possible decorators for the Mixer:
			- AOP-related:
				- concept checks
				- logging/debugging
				- argument manipulation
				- wormholing
				- memoizing
			- renaming properties to avoid conflicts
			- add complimentary properties
			- special treatment of certain names (e.g., event names starting with "on")
	*/
})();
<commit_msg>lang: removing mix.js as obsolete superceded by dojox.lang.oo, !strict.<commit_after><|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple, Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

/** Vary based on current platform. */
SC.NATURAL_SCROLLER_THICKNESS = 16;

/** @class

  Displays a horizontal or vertical scroller.  You will not usually need to
  work with scroller views directly, but you may override this class to
  implement your own custom scrollers.

  @extends SC.View
  @since SproutCore 1.0
*/
SC.ScrollerView = SC.View.extend({

  classNames: ['sc-scroller-view'],

  // ..........................................................
  // PROPERTIES
  //

  /**
   Used by the SC.ScrollView to properly layout the scrollers.
  */
  scrollerThickness: SC.NATURAL_SCROLLER_THICKNESS,

  /**
    The scroller offset value.  This value will adjust between the minimum
    and maximum values that you set.

    @property
  */
  value: 0,

  /**
    The minimum offset value for the scroller.  When the scroller is at the
    top/left, it will have this value.

    @property
  */
  minimum: 0,

  /**
    The maximum offset value for the scroller.  This will be used to calculate
    the internal height/width of the scroller itself.

    @property
  */
  maximum: 0,

  /**
    YES if enable scrollbar, NO to disable it.  Scrollbars will automatically
    disable if the maximum scroll width does not exceed their capacity.

    @property
  */
  isEnabled: YES,

  /**
    Determine the layout direction.  Determines whether the scrollbar should
    appear horizontal or vertical.  This must be set when the view is created.
    Changing this once the view has been created will have no effect.

    @property
  */
  layoutDirection: SC.LAYOUT_VERTICAL,

  /**
    Returns the owner view property the scroller should modify.  If this
    property is non-null and the owner view defines this property, then the
    scroller will automatically update this property whenever its own value
    changes.

    The default value of this property is computed based on the
    layoutDirection.  You can override this property to provide your own
    calculation if necessary or to return null if you want to disable this
    behavior.

    @property {String}
  */
  ownerScrollValueKey: function() {
    var key = null;
    switch(this.get('layoutDirection')) {
      case SC.LAYOUT_VERTICAL:
        key = 'verticalScrollOffset' ;
        break;
      case SC.LAYOUT_HORIZONTAL:
        key = 'horizontalScrollOffset' ;
        break;
      default:
        key = null ;
    }
    return key ;
  }.property('layoutDirection').cacheable(),

  // ..........................................................
  // INTERNAL SUPPORT
  //

  displayProperties: 'minimum maximum isEnabled'.w(),

  /** @private
    Update the scroll location or inner height/width if needed.
  */
  render: function(context, firstTime) {
    // console.log('%@.render(context=%@, firstTime=%@)'.fmt(this, context, firstTime?'YES':'NO'));
    var dir = this.get('layoutDirection') ;
    var min = this.get('minimum'), max = this.get('maximum') ;
    var enabled = this.get('isEnabled'), value = this.get('value') ;

     // calculate required size...
    var size = (enabled) ? max-min-2 : 0 ;

    switch (dir) {
      case SC.LAYOUT_VERTICAL:
        // if (firstTime) context.addClass('sc-vertical') ;
        context.addClass('sc-vertical') ;
        context.push('

'.fmt(size)) ;
        break ;
      case SC.LAYOUT_HORIZONTAL:
        // if (firstTime) context.addClass('sc-horizontal') ;
        context.addClass('sc-horizontal') ;
        context.push('

'.fmt(size)) ;
        break ;
      default:
        throw "You must set a layoutDirection for your scroller class." ;
    }
  },

  didCreateLayer: function() {
    // console.log('%@.didCreateLayer called'.fmt(this));
    var callback = this._sc_scroller_scrollDidChange ;
    SC.Event.add(this.$(), 'scroll', this, callback) ;

    // set scrollOffset first time
    var amt = this.get('value') - this.get('minimum') ;
    var layer = this.get('layer') ;

    switch (this.get('layoutDirection')) {
      case SC.LAYOUT_VERTICAL:
        layer.scrollTop = amt ;
        break;

      case SC.LAYOUT_HORIZONTAL:
        layer.scrollLeft = amt ;
        break;
    }
  },

  willDestroyLayer: function() {
    // console.log('%@.willDestroyLayer()'.fmt(this));
    var callback = this._sc_scroller_scrollDidChange ;
    SC.Event.remove(this.$(), 'scroll', this, callback) ;
  },

  // after 50msec, fire event again
  _sc_scroller_armScrollTimer: function() {
    if (!this._sc_scrollTimer) {
      SC.RunLoop.begin();
      var method = this._sc_scroller_scrollDidChange ;
      this._sc_scrollTimer = this.invokeLater(method, 50) ;
      SC.RunLoop.end();
    }
  },

  _sc_scroller_scrollDidChange: function() {

    var now = Date.now(), last = this._sc_lastScroll;
    if (last && (now-last)<50) return this._sc_scroller_armScrollTimer();
    this._sc_scrollTimer = null;
    this._sc_lastScroll = now;

    SC.RunLoop.begin();

    if (!this.get('isEnabled')) return ; // nothing to do.

    var layer = this.get('layer'), loc = 0 ;
    switch (this.get('layoutDirection')) {
      case SC.LAYOUT_VERTICAL:
        this._sc_scrollValue = loc = layer.scrollTop ;
        break ;

      case SC.LAYOUT_HORIZONTAL:
        this._sc_scrollValue = loc = layer.scrollLeft ;
        break ;
    }

    this.set('value', loc + this.get('minimum')) ;

    SC.RunLoop.end();
  },

  /** @private */
  _sc_scroller_valueDidChange: function() {
    console.log('%@._sc_scroller_valueDidChange called'.fmt(this));

    var v = (this.get('value')||0) - (this.get('minimum')||0),
        layer;

    if (v !== this._sc_scrollValue) {
      layer = this.get('layer');
      switch (this.get('layoutDirection')) {
        case SC.LAYOUT_VERTICAL:
          layer.scrollTop = v;
          break ;

        case SC.LAYOUT_HORIZONTAL:
          layer.scrollLeft = v;
          break ;
      }
    }

    // notify owner if it has a different scroll value
    var key = this.get('ownerScrollValueKey');
    if (key && this.owner && (this.owner[key] !== undefined)) {
      this.owner.setIfChanged(key, this.get('value')) ;
    }
  }.observes('value')

});
<commit_msg>Comment out log in SC.Scroller<commit_after>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple, Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

/** Vary based on current platform. */
SC.NATURAL_SCROLLER_THICKNESS = 16;

/** @class

  Displays a horizontal or vertical scroller.  You will not usually need to
  work with scroller views directly, but you may override this class to
  implement your own custom scrollers.

  @extends SC.View
  @since SproutCore 1.0
*/
SC.ScrollerView = SC.View.extend({

  classNames: ['sc-scroller-view'],

  // ..........................................................
  // PROPERTIES
  //

  /**
   Used by the SC.ScrollView to properly layout the scrollers.
  */
  scrollerThickness: SC.NATURAL_SCROLLER_THICKNESS,

  /**
    The scroller offset value.  This value will adjust between the minimum
    and maximum values that you set.

    @property
  */
  value: 0,

  /**
    The minimum offset value for the scroller.  When the scroller is at the
    top/left, it will have this value.

    @property
  */
  minimum: 0,

  /**
    The maximum offset value for the scroller.  This will be used to calculate
    the internal height/width of the scroller itself.

    @property
  */
  maximum: 0,

  /**
    YES if enable scrollbar, NO to disable it.  Scrollbars will automatically
    disable if the maximum scroll width does not exceed their capacity.

    @property
  */
  isEnabled: YES,

  /**
    Determine the layout direction.  Determines whether the scrollbar should
    appear horizontal or vertical.  This must be set when the view is created.
    Changing this once the view has been created will have no effect.

    @property
  */
  layoutDirection: SC.LAYOUT_VERTICAL,

  /**
    Returns the owner view property the scroller should modify.  If this
    property is non-null and the owner view defines this property, then the
    scroller will automatically update this property whenever its own value
    changes.

    The default value of this property is computed based on the
    layoutDirection.  You can override this property to provide your own
    calculation if necessary or to return null if you want to disable this
    behavior.

    @property {String}
  */
  ownerScrollValueKey: function() {
    var key = null;
    switch(this.get('layoutDirection')) {
      case SC.LAYOUT_VERTICAL:
        key = 'verticalScrollOffset' ;
        break;
      case SC.LAYOUT_HORIZONTAL:
        key = 'horizontalScrollOffset' ;
        break;
      default:
        key = null ;
    }
    return key ;
  }.property('layoutDirection').cacheable(),

  // ..........................................................
  // INTERNAL SUPPORT
  //

  displayProperties: 'minimum maximum isEnabled'.w(),

  /** @private
    Update the scroll location or inner height/width if needed.
  */
  render: function(context, firstTime) {
    // console.log('%@.render(context=%@, firstTime=%@)'.fmt(this, context, firstTime?'YES':'NO'));
    var dir = this.get('layoutDirection') ;
    var min = this.get('minimum'), max = this.get('maximum') ;
    var enabled = this.get('isEnabled'), value = this.get('value') ;

     // calculate required size...
    var size = (enabled) ? max-min-2 : 0 ;

    switch (dir) {
      case SC.LAYOUT_VERTICAL:
        // if (firstTime) context.addClass('sc-vertical') ;
        context.addClass('sc-vertical') ;
        context.push('

'.fmt(size)) ;
        break ;
      case SC.LAYOUT_HORIZONTAL:
        // if (firstTime) context.addClass('sc-horizontal') ;
        context.addClass('sc-horizontal') ;
        context.push('

'.fmt(size)) ;
        break ;
      default:
        throw "You must set a layoutDirection for your scroller class." ;
    }
  },

  didCreateLayer: function() {
    // console.log('%@.didCreateLayer called'.fmt(this));
    var callback = this._sc_scroller_scrollDidChange ;
    SC.Event.add(this.$(), 'scroll', this, callback) ;

    // set scrollOffset first time
    var amt = this.get('value') - this.get('minimum') ;
    var layer = this.get('layer') ;

    switch (this.get('layoutDirection')) {
      case SC.LAYOUT_VERTICAL:
        layer.scrollTop = amt ;
        break;

      case SC.LAYOUT_HORIZONTAL:
        layer.scrollLeft = amt ;
        break;
    }
  },

  willDestroyLayer: function() {
    // console.log('%@.willDestroyLayer()'.fmt(this));
    var callback = this._sc_scroller_scrollDidChange ;
    SC.Event.remove(this.$(), 'scroll', this, callback) ;
  },

  // after 50msec, fire event again
  _sc_scroller_armScrollTimer: function() {
    if (!this._sc_scrollTimer) {
      SC.RunLoop.begin();
      var method = this._sc_scroller_scrollDidChange ;
      this._sc_scrollTimer = this.invokeLater(method, 50) ;
      SC.RunLoop.end();
    }
  },

  _sc_scroller_scrollDidChange: function() {

    var now = Date.now(), last = this._sc_lastScroll;
    if (last && (now-last)<50) return this._sc_scroller_armScrollTimer();
    this._sc_scrollTimer = null;
    this._sc_lastScroll = now;

    SC.RunLoop.begin();

    if (!this.get('isEnabled')) return ; // nothing to do.

    var layer = this.get('layer'), loc = 0 ;
    switch (this.get('layoutDirection')) {
      case SC.LAYOUT_VERTICAL:
        this._sc_scrollValue = loc = layer.scrollTop ;
        break ;

      case SC.LAYOUT_HORIZONTAL:
        this._sc_scrollValue = loc = layer.scrollLeft ;
        break ;
    }

    this.set('value', loc + this.get('minimum')) ;

    SC.RunLoop.end();
  },

  /** @private */
  _sc_scroller_valueDidChange: function() {
    //console.log('%@._sc_scroller_valueDidChange called'.fmt(this));

    var v = (this.get('value')||0) - (this.get('minimum')||0),
        layer;

    if (v !== this._sc_scrollValue) {
      layer = this.get('layer');
      switch (this.get('layoutDirection')) {
        case SC.LAYOUT_VERTICAL:
          layer.scrollTop = v;
          break ;

        case SC.LAYOUT_HORIZONTAL:
          layer.scrollLeft = v;
          break ;
      }
    }

    // notify owner if it has a different scroll value
    var key = this.get('ownerScrollValueKey');
    if (key && this.owner && (this.owner[key] !== undefined)) {
      this.owner.setIfChanged(key, this.get('value')) ;
    }
  }.observes('value')

});
<|endoftext|>


<commit_before>/**
 * blame.js is user JavaScript file wich will be include to github page and adds new feachures on blame page.i
 *
 * @author Andrew Kulakov <avk@8xx8.ru>
 * @version 1.0.0
 * @license https://github.com/Andrew8xx8/blame.js/blob/master/MIT-LICENSE.txt
 * @copyright Andrew Kulakov (c) 2011
 */

(function (globals) {

    var apiRoot = "https://github.com/api/v2/json/",

    jsonp = function (url, callback, context) {
        script = document.createElement("script");

        var prefix = "?";
        if (url.indexOf("?") >= 0)
            prefix = "&";

        url += prefix + "callback=" + encodeURIComponent(callback);

        url += "&login=&authToken=";

        script.setAttribute("src", apiRoot + url);

        document.getElementsByTagName('head')[0].appendChild(script);
    },

    blame = globals.blame = {};

    blame.fileTemplate = '{name}
';
    blame.popupTemplate = '
Commit
'
        + '
Modified
{modified}'
        + '
Added:
{added}'
        + '
Deleted
{deleted}'
        + '
Committed by {username}
';

    blame.popupPosition = {x: '0px', y: '0px'};
    blame.lock = false;

    blame.loadCommit = function (data){

        var popup = ' ', added = 'none', deleted = 'none', modified = 'none';

        if ( data.commit.added != null) {
            added = '';
            for (var i in data.commit.added) {
                added += blame.fetchTemplate(blame.fileTemplate, {'name' :  data.commit.added[i]});
            }
        }

        if ( data.commit.modified != null) {
            modified = '';
            for (var i in data.commit.modified) {
                modified += blame.fetchTemplate(blame.fileTemplate, {'name' :  data.commit.modified[i].filename});
            }
        }

        if ( data.commit.added != null) {
            for (var i in data.commit.added) {
                added += blame.fetchTemplate(blame.fileTemplate, {'name' :  data.commit.added[i]});
            }
        }

        popup = blame.fetchTemplate(blame.popupTemplate, {
            'modified' : modified,
            'added'    : added,
            'deleted'  : deleted,
            'username' : data.commit.author.name,
            'email'    : data.commit.author.email,
            'userlogin': data.commit.author.login
        });

        $('#blame-popup').html(popup);

        $('#blame-popup').css({
            'left': blame.popupPosition.x,
            'top':  blame.popupPosition.y,
        });

        $('#blame-popup').fadeIn();
        blame.lock = false;
    };

    blame.fetchTemplate = function(template, data){
        var result = template;

        for(var i in data) {
            name = '{' + i + '}';
            result = result.replace(name, data[i]);
        }
        return result;
    };

    blame.register = function() {
        $('.blame .commitinfo').click(function(){
//            if (blame.lock) return;
            blame.lock = true;

            blame.popupPosition.x = ($(this).offset().left + 500) + 'px';
            blame.popupPosition.y = $(this).offset().top + 'px';

            current_commit = $(this).find('a:first').html();
            $('.blame .commitinfo').css({'background-color': 'transparent'});
            $('.blame .commitinfo code a').each(function(index, value){
                if(current_commit == $(value).html()) {
                    $(value).parent().parent().css({'background-color': '#faa'});
                }
            });

            jsonp("commits/show" + $(this).find('a:first').attr('href').replace(/\/commit\//, '/'), 'blame.loadCommit');
        });

        $('body').append('

');
        $('#blame-popup').css({
            'position': 'absolute',
            'width':    '300px',
            'z-index': '100500',
            'display': 'none',
            'background': '#fff',
            'opacity': 0.9,
            'padding': '20px',
            'padding-top': '10px'
        });
    }

}(window));

$(document).ready(function(){
    blame.register();
});
<commit_msg>[~] New template & colors<commit_after>/**
 * blame.js is user JavaScript file wich will be include to github page and adds new feachures on blame page.i
 *
 * @author Andrew Kulakov <avk@8xx8.ru>
 * @version 1.0.0
 * @license https://github.com/Andrew8xx8/blame.js/blob/master/MIT-LICENSE.txt
 * @copyright Andrew Kulakov (c) 2011
 */

(function (globals) {

    var apiRoot = "https://github.com/api/v2/json/",

    jsonp = function (url, callback, context) {
        script = document.createElement("script");

        var prefix = "?";
        if (url.indexOf("?") >= 0)
            prefix = "&";

        url += prefix + "callback=" + encodeURIComponent(callback);

        url += "&login=&authToken=";

        script.setAttribute("src", apiRoot + url);

        document.getElementsByTagName('head')[0].appendChild(script);
    },

    blame = globals.blame = {};

    blame.fileTemplate = '
{name}

';
    blame.popupTemplate =
    '
' +
        '
Commit: {commit_hash}
' +
        '
' +
            '
Committed date: {committed_date}
'+
            'Authored date: {authored_date}
'+
            'by {username}
'+
            '
Message
' +
            '
{message}
' +
       '
' +
    '
' +
    '
' +
        '
Files
' +
        '
' +
            '
Modified
' +
            '
{modified}
' +
            '
Added:
' +
            '
{added}
' +
            '
Deleted
' +
            '
{deleted}
' +
       '
' +
    '
' +
    '
' +
        '
Files
' +
        '
' +
            '
Modified
' +
            '
{modified}
' +
            '
Added:
' +
            '
{added}
' +
            '
Deleted
' +
            '
{deleted}
' +
       '
' +
    '
';

    blame.popupPosition = {x: '0px', y: '0px'};
    blame.lock = false;

    blame.loadCommit = function (data){

        var popup = ' ', added = 'none', deleted = 'none', modified = 'none';

        if ( data.commit.added != null) {
            added = '';
            for (var i in data.commit.added) {
                added += blame.fetchTemplate(blame.fileTemplate, {'name' :  data.commit.added[i]});
            }
        }

        if ( data.commit.modified != null) {
            modified = '';
            for (var i in data.commit.modified) {
                modified += blame.fetchTemplate(blame.fileTemplate, {'name' :  data.commit.modified[i].filename});
            }
        }

        if ( data.commit.added != null) {
            for (var i in data.commit.added) {
                added += blame.fetchTemplate(blame.fileTemplate, {'name' :  data.commit.added[i]});
            }
        }

        popup = blame.fetchTemplate(blame.popupTemplate, {
            'modified' : modified,
            'added'    : added,
            'deleted'  : deleted,
            'username' : data.commit.author.name,
            'email'    : data.commit.author.email,
            'userlogin': data.commit.author.login
        });

        $('#blame-popup').html(popup);

        $('#blame-popup').css({
            'left': blame.popupPosition.x,
            'top':  blame.popupPosition.y,
        });

        $('#blame-popup').fadeIn();
        blame.lock = false;
    };

    blame.fetchTemplate = function(template, data){
        var result = template;

        for(var i in data) {
            name = '{' + i + '}';
            result = result.replace(name, data[i]);
        }
        return result;
    };

    blame.register = function() {
        $('.blame .commitinfo').click(function(){
//            if (blame.lock) return;
            blame.lock = true;

            blame.popupPosition.x = ($(this).offset().left + 500) + 'px';
            blame.popupPosition.y = $(this).offset().top + 'px';

            current_commit = $(this).find('a:first').html();
            $('.blame .commitinfo').css({'background-color': 'transparent'});
            $('.blame .commitinfo code a').each(function(index, value){
                if(current_commit == $(value).html()) {
                    $(value).parent().parent().css({'background-color': '#faa'});
                }
            });

            jsonp("commits/show" + $(this).find('a:first').attr('href').replace(/\/commit\//, '/'), 'blame.loadCommit');
        });

        $('body').append('

');
        $('#blame-popup').css({
            'position': 'absolute',
            'width':    'auto',
            'z-index': '100500',
            'display': 'none',
            'background': '#fff',
            'padding': '4px',
            'padding-top': '10px',
            'color' :  '#444'
        });
    }

}(window));

$(document).ready(function(){
    blame.register();
});
<|endoftext|>


<commit_before>// @flow
import React, {Component} from 'react';
import type {Dispatch, State} from 'redux';
import CSSModules from 'react-css-modules';
import {connect} from 'react-redux';
import type {WorkType, WorksType, ColumnType} from '../actions/type';
import {nextPage, closeColumn} from '../../actions/column';
import List from './list';
import styles from './column.css';

type Props = {
	works: Array<WorkType>,
	column: ColumnType,
	dispatch: Dispatch;
}

@CSSModules(styles)
class Column extends Component {
	props: Props;

	shouldComponentUpdate(nextProps) {
		if (this.props.works.length !== nextProps.works.length) {
			return true;
		}
		return false;
	}

	handleClose = () => {
		this.props.dispatch(closeColumn(this.props.column.id));
	}

	handleOnNextPage = () => {
		this.props.dispatch(nextPage(this.props.column.id));
	}

	render() {
		const {column, works} = this.props;
		return (

				<List
					title={column.title}
					works={works}
					onClose={this.handleClose}
					onNextPage={this.handleOnNextPage}
					/>

		);
	}
}

function filter(nums: Array<number>, works: WorksType, tags: Array<string>) {
	return nums
		.map(i => works[i])
		.filter(work => work.tags.every(tag => tags.every(t => t !== tag)));
}

function mapStateToProps(state: State, ownProps) {
	const {entities, manage} = state;
	const {works} = entities;
	const {column} = ownProps;
	const workList = column.works ? filter(column.works, works, manage.filter.tags) : [];

	return {
		works: workList
	};
}

export default connect(mapStateToProps)(Column);
<commit_msg>Fix import path<commit_after>// @flow
import React, {Component} from 'react';
import type {Dispatch, State} from 'redux';
import CSSModules from 'react-css-modules';
import {connect} from 'react-redux';
import type {WorkType, WorksType, ColumnType} from '../../actions/type';
import {nextPage, closeColumn} from '../../actions/column';
import List from './list';
import styles from './column.css';

type Props = {
	works: Array<WorkType>,
	column: ColumnType,
	dispatch: Dispatch;
}

@CSSModules(styles)
class Column extends Component {
	props: Props;

	shouldComponentUpdate(nextProps) {
		if (this.props.works.length !== nextProps.works.length) {
			return true;
		}
		return false;
	}

	handleClose = () => {
		this.props.dispatch(closeColumn(this.props.column.id));
	}

	handleOnNextPage = () => {
		this.props.dispatch(nextPage(this.props.column.id));
	}

	render() {
		const {column, works} = this.props;
		return (

				<List
					title={column.title}
					works={works}
					onClose={this.handleClose}
					onNextPage={this.handleOnNextPage}
					/>

		);
	}
}

function filter(nums: Array<number>, works: WorksType, tags: Array<string>) {
	return nums
		.map(i => works[i])
		.filter(work => work.tags.every(tag => tags.every(t => t !== tag)));
}

function mapStateToProps(state: State, ownProps) {
	const {entities, manage} = state;
	const {works} = entities;
	const {column} = ownProps;
	const workList = column.works ? filter(column.works, works, manage.filter.tags) : [];

	return {
		works: workList
	};
}

export default connect(mapStateToProps)(Column);
<|endoftext|>


<commit_before>const nest = require('depnest')
const pull = require('pull-stream')
const Scroller = require('pull-scroll')

exports.gives = nest('router.html.page')

exports.needs = nest({
  'feed.pull.channel': 'first',
  'main.html.scroller': 'first',
  message: {
    html: {
      compose: 'first',
      render: 'first'
    }
    // 'sync.unbox': 'first'
  }
})

exports.create = function (api) {
  return nest('router.html.page', channelView)

  function channelView (path) {
    if (path[0] !== '#') return

    var channel = path.substr(1)

    var composer = api.message.html.compose({ meta: { type: 'post', channel } })
    var { container, content } = api.main.html.scroller({ prepend: composer })

    var openChannelSource = api.feed.pull.channel(channel)

    pull(
      openChannelSource({old: false}),
      Scroller(container, content, api.message.html.render, true, false)
    )

    pull(
      openChannelSource({reverse: true}),
      Scroller(container, content, api.message.html.render, false, false)
    )

    return container
  }
}

<commit_msg>channel bug fix!<commit_after>const nest = require('depnest')
const pull = require('pull-stream')
const Scroller = require('pull-scroll')

exports.gives = nest('router.html.page')

exports.needs = nest({
  'feed.pull.channel': 'first',
  'main.html.scroller': 'first',
  message: {
    html: {
      compose: 'first',
      render: 'first'
    }
    // 'sync.unbox': 'first'
  }
})

exports.create = function (api) {
  return nest('router.html.page', channelView)

  function channelView (path) {
    if (path && !path.match(/#\w+/)) return

    var channel = path.substr(1)

    var composer = api.message.html.compose({ meta: { type: 'post', channel } })
    var { container, content } = api.main.html.scroller({ prepend: composer })

    var openChannelSource = api.feed.pull.channel(channel)

    pull(
      openChannelSource({old: false}),
      Scroller(container, content, api.message.html.render, true, false)
    )

    pull(
      openChannelSource({reverse: true}),
      Scroller(container, content, api.message.html.render, false, false)
    )

    return container
  }
}

<|endoftext|>


<commit_before>import path from "path"

// ! client side loader only \\
export default ({ config }) => {
  const { webpackConfig } = config
  return {
    ...webpackConfig,
    module: {
      ...webpackConfig.module,
      loaders: [
        ...webpackConfig.module.loaders,
        {
          test: /\.json$/,
          loader: "json-loader",
        },
        {
          test: /\.js$/,
          loaders: [
            `babel-loader${
              config.dev ? "?presets[]=babel-preset-react-hmre" : ""
            }`,
            "eslint-loader?fix",
          ],
          include: [
            path.resolve(config.cwd, "scripts"),
            path.resolve(config.cwd, "web_modules"),
            // because docs use non transpiled code
            path.resolve(config.cwd, "..", "src"),
          ],
        },
      ],
    },

    entry: {
      "phenomic-client": path.join(__dirname, "index-client"),
    },
  }
}
<commit_msg>Enable long term caching for docs website (#404)<commit_after>import path from "path"
import webpack from "webpack"

// ! client side loader only \\
export default ({ config }) => {
  const { webpackConfig } = config
  return {
    ...webpackConfig,
    module: {
      ...webpackConfig.module,
      loaders: [
        ...webpackConfig.module.loaders,
        {
          test: /\.json$/,
          loader: "json-loader",
        },
        {
          test: /\.js$/,
          loaders: [
            `babel-loader${
              config.dev ? "?presets[]=babel-preset-react-hmre" : ""
            }`,
            "eslint-loader?fix",
          ],
          include: [
            path.resolve(config.cwd, "scripts"),
            path.resolve(config.cwd, "web_modules"),
            // because docs use non transpiled code
            path.resolve(config.cwd, "..", "src"),
          ],
        },
      ],
    },

    entry: {
      "phenomic-client": path.join(__dirname, "index-client"),
      "phenomic-bundle": [
        "react",
        "react-dom",
        "redux",
        "react-redux",
        "react-helmet",
        "whatwg-fetch",
      ],
    },

    ...config.production && {
      output: {
        ...webpackConfig.output,
        filename: "[name].[chunkhash].js",
        chunkFilename: "[chunkhash].js",
      },

      plugins: [
        ...webpackConfig.plugins,
        new webpack.optimize.CommonsChunkPlugin({
          names: [ "phenomic-bundle", "manifest" ],
        }),
      ],
    },
  }
}
<|endoftext|>


<commit_before>/* global adjustControlsWidth */

/**
 * Mail
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 * @copyright Christoph Wurst 2016
 */

define(function(require) {
	'use strict';

	var Marionette = require('marionette');
	var Handlebars = require('handlebars');
	var _ = require('underscore');
	var $ = require('jquery');
	var Attachments = require('models/attachments');
	var HtmlHelper = require('util/htmlhelper');
	var ComposerView = require('views/composerview');
	var MessageAttachmentsView = require('views/messageattachments');
	var MessageTemplate = require('text!templates/message.html');

	return Marionette.View.extend({
		template: Handlebars.compile(MessageTemplate),
		className: 'mail-message-container',
		message: null,
		reply: null,
		account: null,
		folder: null,
		ui: {
			messageIframe: 'iframe'
		},
		regions: {
			replyComposer: '#reply-composer',
			attachments: '.mail-message-attachments'
		},
		initialize: function(options) {
			this.account = options.account;
			this.folder = options.folder;
			this.message = options.model;
			this.reply = {
				replyToList: this.message.get('replyToList'),
				replyCc: this.message.get('replyCc'),
				toEmail: this.message.get('toEmail'),
				replyCcList: this.message.get('replyCcList'),
				body: ''
			};

			// Add body content to inline reply (text mails)
			if (!this.message.get('hasHtmlBody')) {
				var date = new Date(this.message.get('dateIso'));
				var minutes = date.getMinutes();
				var text = HtmlHelper.htmlToText(this.message.get('body'));

				this.reply.body = '\n\n\n\n' +
					this.message.get('from') + ' – ' +
					$.datepicker.formatDate('D, d. MM yy ', date) +
					date.getHours() + ':' + (minutes < 10 ? '0' : '') + minutes + '\n> ' +
					text.replace(/\n/g, '\n> ');
			}

			// Save current messages's content for later use (forward)
			if (!this.message.get('hasHtmlBody')) {
				require('state').currentMessageBody = this.message.get('body');
			}
			require('state').currentMessageSubject = this.message.get('subject');

			// Render the message body
			adjustControlsWidth();

			// Hide forward button until the message has finished loading
			if (this.message.get('hasHtmlBody')) {
				$('#forward-button').hide();
			}
		},
		onIframeLoad: function() {
			// Expand height to not have two scrollbars
			this.getUI('messageIframe').height(this.getUI('messageIframe').contents().find('html').height() + 20);
			// Fix styling
			this.getUI('messageIframe').contents().find('body').css({
				'margin': '0',
				'font-weight': 'normal',
				'font-size': '.8em',
				'line-height': '1.6em',
				'font-family': '"Open Sans", Frutiger, Calibri, "Myriad Pro", Myriad, sans-serif',
				'color': '#000'
			});
			// Fix font when different font is forced
			this.getUI('messageIframe').contents().find('font').prop({
				'face': 'Open Sans',
				'color': '#000'
			});
			this.getUI('messageIframe').contents().find('.moz-text-flowed').css({
				'font-family': 'inherit',
				'font-size': 'inherit'
			});
			// Expand height again after rendering to account for new size
			this.getUI('messageIframe').height(this.getUI('messageIframe').contents().find('html').height() + 20);
			// Grey out previous replies
			this.getUI('messageIframe').contents().find('blockquote').css({
				'color': '#888'
			});
			// Remove spinner when loading finished
			this.getUI('messageIframe').parent().removeClass('icon-loading');

			// Does the html mail have blocked images?
			var hasBlockedImages = false;
			if (this.getUI('messageIframe').contents().
				find('[data-original-src],[data-original-style]').length) {
				hasBlockedImages = true;
			}

			// Show/hide button to load images
			if (hasBlockedImages) {
				$('#show-images-text').show();
			} else {
				$('#show-images-text').hide();
			}

			// Add body content to inline reply (html mails)
			var text = this.getUI('messageIframe').contents().find('body').html();
			text = HtmlHelper.htmlToText(text);
			var date = new Date(this.message.get('dateIso'));
			this.replyComposer.currentView.setReplyBody(this.message.get('from'), date, text);

			// Safe current mesages's content for later use (forward)
			require('state').currentMessageBody = text;

			// Show forward button
			this.$('#forward-button').show();
		},
		onRender: function() {
			this.getUI('messageIframe').on('load', _.bind(this.onIframeLoad, this));

			this.showChildView('attachments', new MessageAttachmentsView({
				collection: new Attachments(this.message.get('attachments')),
				message: this.model
			}));

			// setup reply composer view
			this.showChildView('replyComposer', new ComposerView({
				type: 'reply',
				accounts: require('state').accounts,
				account: this.account,
				folder: this.folder,
				repliedMessage: this.message,
				data: this.reply
			}));
		}
	});
});
<commit_msg>access childView with 'getChildView' helper method<commit_after>/* global adjustControlsWidth */

/**
 * Mail
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Christoph Wurst <christoph@winzerhof-wurst.at>
 * @copyright Christoph Wurst 2016
 */

define(function(require) {
	'use strict';

	var Marionette = require('marionette');
	var Handlebars = require('handlebars');
	var _ = require('underscore');
	var $ = require('jquery');
	var Attachments = require('models/attachments');
	var HtmlHelper = require('util/htmlhelper');
	var ComposerView = require('views/composerview');
	var MessageAttachmentsView = require('views/messageattachments');
	var MessageTemplate = require('text!templates/message.html');

	return Marionette.View.extend({
		template: Handlebars.compile(MessageTemplate),
		className: 'mail-message-container',
		message: null,
		reply: null,
		account: null,
		folder: null,
		ui: {
			messageIframe: 'iframe'
		},
		regions: {
			replyComposer: '#reply-composer',
			attachments: '.mail-message-attachments'
		},
		initialize: function(options) {
			this.account = options.account;
			this.folder = options.folder;
			this.message = options.model;
			this.reply = {
				replyToList: this.message.get('replyToList'),
				replyCc: this.message.get('replyCc'),
				toEmail: this.message.get('toEmail'),
				replyCcList: this.message.get('replyCcList'),
				body: ''
			};

			// Add body content to inline reply (text mails)
			if (!this.message.get('hasHtmlBody')) {
				var date = new Date(this.message.get('dateIso'));
				var minutes = date.getMinutes();
				var text = HtmlHelper.htmlToText(this.message.get('body'));

				this.reply.body = '\n\n\n\n' +
					this.message.get('from') + ' – ' +
					$.datepicker.formatDate('D, d. MM yy ', date) +
					date.getHours() + ':' + (minutes < 10 ? '0' : '') + minutes + '\n> ' +
					text.replace(/\n/g, '\n> ');
			}

			// Save current messages's content for later use (forward)
			if (!this.message.get('hasHtmlBody')) {
				require('state').currentMessageBody = this.message.get('body');
			}
			require('state').currentMessageSubject = this.message.get('subject');

			// Render the message body
			adjustControlsWidth();

			// Hide forward button until the message has finished loading
			if (this.message.get('hasHtmlBody')) {
				$('#forward-button').hide();
			}
		},
		onIframeLoad: function() {
			// Expand height to not have two scrollbars
			this.getUI('messageIframe').height(this.getUI('messageIframe').contents().find('html').height() + 20);
			// Fix styling
			this.getUI('messageIframe').contents().find('body').css({
				'margin': '0',
				'font-weight': 'normal',
				'font-size': '.8em',
				'line-height': '1.6em',
				'font-family': '"Open Sans", Frutiger, Calibri, "Myriad Pro", Myriad, sans-serif',
				'color': '#000'
			});
			// Fix font when different font is forced
			this.getUI('messageIframe').contents().find('font').prop({
				'face': 'Open Sans',
				'color': '#000'
			});
			this.getUI('messageIframe').contents().find('.moz-text-flowed').css({
				'font-family': 'inherit',
				'font-size': 'inherit'
			});
			// Expand height again after rendering to account for new size
			this.getUI('messageIframe').height(this.getUI('messageIframe').contents().find('html').height() + 20);
			// Grey out previous replies
			this.getUI('messageIframe').contents().find('blockquote').css({
				'color': '#888'
			});
			// Remove spinner when loading finished
			this.getUI('messageIframe').parent().removeClass('icon-loading');

			// Does the html mail have blocked images?
			var hasBlockedImages = false;
			if (this.getUI('messageIframe').contents().
				find('[data-original-src],[data-original-style]').length) {
				hasBlockedImages = true;
			}

			// Show/hide button to load images
			if (hasBlockedImages) {
				$('#show-images-text').show();
			} else {
				$('#show-images-text').hide();
			}

			// Add body content to inline reply (html mails)
			var text = this.getUI('messageIframe').contents().find('body').html();
			text = HtmlHelper.htmlToText(text);
			var date = new Date(this.message.get('dateIso'));
			this.getChildView('replyComposer').setReplyBody(this.message.get('from'), date, text);

			// Safe current mesages's content for later use (forward)
			require('state').currentMessageBody = text;

			// Show forward button
			this.$('#forward-button').show();
		},
		onRender: function() {
			this.getUI('messageIframe').on('load', _.bind(this.onIframeLoad, this));

			this.showChildView('attachments', new MessageAttachmentsView({
				collection: new Attachments(this.message.get('attachments')),
				message: this.model
			}));

			// setup reply composer view
			this.showChildView('replyComposer', new ComposerView({
				type: 'reply',
				accounts: require('state').accounts,
				account: this.account,
				folder: this.folder,
				repliedMessage: this.message,
				data: this.reply
			}));
		}
	});
});
<|endoftext|>


<commit_before>var _ = require('lodash');
var crypto = require('crypto');

/** @module User */
module.exports = {
  attributes: {
    username: {
      type: 'string',
      unique: true,
      index: true,
      notNull: true
    },
    email: {
      type: 'email',
      notNull: true,
      unique: true,
      index: true
    },
    passports: {
      collection: 'Passport',
      via: 'user'
    },

    getGravatarUrl: function () {
      var md5 = crypto.createHash('md5');
      md5.update(this.email);
      return 'https://gravatar.com/avatar/'+ md5.digest('hex');
    },

    toJSON: function () {
      var user = this.toObject();
      delete user.password;
      user.gravatarUrl = this.getGravatarUrl();
      return user;
    }
  },

  create: function (user) {
    return new Promise(function (resolve, reject) {
      sails.services.passport.protocols.local.createUser(user, function (error, created) {
        if (error) return reject(error);

        resolve(created);
      });
    });
  }
};
<commit_msg>implement User.register<commit_after>var _ = require('lodash');
var crypto = require('crypto');

/** @module User */
module.exports = {
  attributes: {
    username: {
      type: 'string',
      unique: true,
      index: true,
      notNull: true
    },
    email: {
      type: 'email',
      notNull: true,
      unique: true,
      index: true
    },
    passports: {
      collection: 'Passport',
      via: 'user'
    },

    getGravatarUrl: function () {
      var md5 = crypto.createHash('md5');
      md5.update(this.email);
      return 'https://gravatar.com/avatar/'+ md5.digest('hex');
    },

    toJSON: function () {
      var user = this.toObject();
      delete user.password;
      user.gravatarUrl = this.getGravatarUrl();
      return user;
    }
  },

  /**
   * Register a new User with a passport
   */
  register: function (user) {
    return new Promise(function (resolve, reject) {
      sails.services.passport.protocols.local.createUser(user, function (error, created) {
        if (error) return reject(error);

        resolve(created);
      });
    });
  }
};
<|endoftext|>


<commit_before>// @flow

import React from 'react'
import {GoogleCalendarView} from '../../calendar/calendar-google'

export default class KSTOSchedule extends React.PureComponent {
  static navigationOptions = {
    title: 'Show Schedule',
  }

  render() {
    return (
      <GoogleCalendarView
        navigation={this.props.navigation}
        calendarId="kstonarwhal@gmail.com"
      />
    )
  }
}
<commit_msg>update radio scheduler for flow 56<commit_after>// @flow

import React from 'react'
import {GoogleCalendarView} from '../../calendar/calendar-google'
import type {TopLevelViewPropsType} from '../../types'

type Props = TopLevelViewPropsType & {}

export default class KSTOSchedule extends React.PureComponent<Props> {
  static navigationOptions = {
    title: 'Show Schedule',
  }

  render() {
    return (
      <GoogleCalendarView
        navigation={this.props.navigation}
        calendarId="kstonarwhal@gmail.com"
      />
    )
  }
}
<|endoftext|>


<commit_before>/*
Gradebook from Names and Scores
I worked on this challenge [by myself, with:]
This challenge took me [#] hours.
You will work with the following two variables.  The first, students, holds the names of four students.
The second, scores, holds groups of test scores.  The relative positions of elements within the two
variables match (i.e., 'Joseph' is the first element in students; his scores are the first value in scores.).
Do not alter the students and scores code.
*/

var students = ["Joseph", "Susan", "William", "Elizabeth"]

var scores = [ [80, 70, 70, 100],
               [85, 80, 90, 90],
               [75, 70, 80, 75],
               [100, 90, 95, 85] ]

// __________________________________________
// Write your code below.
// var gradebook = {};

// for (var i =0; i <students.length; i++){
//   gradebook[students[i]]= {};
// };

// for(i in scores){
//   gradebook[students[i]].testScores = scores[i];
// };

// gradebook.addScore = function (name, score){
//   gradebook[name].testScores.push(score);
// }

// gradebook.getAverage = function(name){
//   return average(gradebook[name].testScores);
// };

// var average = function(array){
//   var sum = 0;
//   for (i in array){sum = sum + array[i]};
//   return sum / array.length;
// }

// __________________________________________
// Refactored Solution
var gradebook = {};

for (var i =0; i <students.length; i++){
  gradebook[students[i]]= {testScores: scores[i]};
};

gradebook.addScore = function (name, score){
  gradebook[name].testScores.push(score);
}

gradebook.getAverage = function(name){
  return average(gradebook[name].testScores);
};

var average = function(arr) {
  var total = arr.reduce(function add(a, b) {return a + b});
  return total / arr.length;
};

// __________________________________________
// Reflect
// What did you learn about adding functions to objects?
// I learned that adding functions to an object will automatically iterate through my code
// and do the work that I intend to do right away, instead of declaring a variable and then execute the function.
// It seems like it saves more time.

// How did you iterate over nested arrays in JavaScript?
// I iterated through them by using the correct index numbers, which was identical to Ruby's iteration

// Were there any new methods you were able to incorporate? If so, what were they and how did they work?
// I was able to incorporate reduce function.  I learned it from a guy in my group from last week's accountability
// group.  He used reduce function to get the sum of the array of numbers which I was able to use here.

// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (gradebook instanceof Object),
  "The value of gradebook should be an Object.\n",
  "1. "
)

assert(
  (gradebook["Elizabeth"] instanceof Object),
  "gradebook's Elizabeth property should be an object.",
  "2. "
)

assert(
  (gradebook.William.testScores === scores[2]),
  "William's testScores should equal the third element in scores.",
  "3. "
)

assert(
  (gradebook.addScore instanceof Function),
  "The value of gradebook's addScore property should be a Function.",
  "4. "
)

gradebook.addScore("Susan", 80)

assert(
  (gradebook.Susan.testScores.length === 5
   && gradebook.Susan.testScores[4] === 80),
  "Susan's testScores should have a new score of 80 added to the end.",
  "5. "
)

assert(
  (gradebook.getAverage instanceof Function),
  "The value of gradebook's getAverage property should be a Function.",
  "6. "
)

assert(
  (average instanceof Function),
  "The value of average should be a Function.\n",
  "7. "
)
assert(
  average([1, 2, 3]) === 2,
  "average should return the average of the elements in the array argument.\n",
  "8. "
)

assert(
  (gradebook.getAverage("Joseph") === 80),
  "gradebook's getAverage should return 80 if passed 'Joseph'.",
  "9. "
)<commit_msg>add syntax change for refactor<commit_after>/*
Gradebook from Names and Scores
I worked on this challenge [by myself, with:]
This challenge took me [#] hours.
You will work with the following two variables.  The first, students, holds the names of four students.
The second, scores, holds groups of test scores.  The relative positions of elements within the two
variables match (i.e., 'Joseph' is the first element in students; his scores are the first value in scores.).
Do not alter the students and scores code.
*/

var students = ["Joseph", "Susan", "William", "Elizabeth"]

var scores = [ [80, 70, 70, 100],
               [85, 80, 90, 90],
               [75, 70, 80, 75],
               [100, 90, 95, 85] ]

// __________________________________________
// Write your code below.
// var gradebook = {};

// for (var i =0; i <students.length; i++){
//   gradebook[students[i]]= {};
// };

// for(i in scores){
//   gradebook[students[i]].testScores = scores[i];
// };

// gradebook.addScore = function (name, score){
//   gradebook[name].testScores.push(score);
// }

// gradebook.getAverage = function(name){
//   return average(gradebook[name].testScores);
// };

// var average = function(array){
//   var sum = 0;
//   for (i in array){sum = sum + array[i]};
//   return sum / array.length;
// }

// __________________________________________
// Refactored Solution
var gradebook = {};

for (var i =0; i <students.length; i++){
  gradebook[students[i]]= {testScores: scores[i]};
};

gradebook.addScore = function (name, score){
  gradebook[name].testScores.push(score);
}

gradebook.getAverage = function(name){
  return average(gradebook[name].testScores);
};

var average = function(arr) {
 return arr.reduce((a, b) => a + b) / arr.length;
};

// __________________________________________
// Reflect
// What did you learn about adding functions to objects?
// I learned that adding functions to an object will automatically iterate through my code
// and do the work that I intend to do right away, instead of declaring a variable and then execute the function.
// It seems like it saves more time.

// How did you iterate over nested arrays in JavaScript?
// I iterated through them by using the correct index numbers, which was identical to Ruby's iteration

// Were there any new methods you were able to incorporate? If so, what were they and how did they work?
// I was able to incorporate reduce function.  I learned it from a guy in my group from last week's accountability
// group.  He used reduce function to get the sum of the array of numbers which I was able to use here.

// __________________________________________
// Test Code:  Do not alter code below this line.

function assert(test, message, test_number) {
  if (!test) {
    console.log(test_number + "false");
    throw "ERROR: " + message;
  }
  console.log(test_number + "true");
  return true;
}

assert(
  (gradebook instanceof Object),
  "The value of gradebook should be an Object.\n",
  "1. "
)

assert(
  (gradebook["Elizabeth"] instanceof Object),
  "gradebook's Elizabeth property should be an object.",
  "2. "
)

assert(
  (gradebook.William.testScores === scores[2]),
  "William's testScores should equal the third element in scores.",
  "3. "
)

assert(
  (gradebook.addScore instanceof Function),
  "The value of gradebook's addScore property should be a Function.",
  "4. "
)

gradebook.addScore("Susan", 80)

assert(
  (gradebook.Susan.testScores.length === 5
   && gradebook.Susan.testScores[4] === 80),
  "Susan's testScores should have a new score of 80 added to the end.",
  "5. "
)

assert(
  (gradebook.getAverage instanceof Function),
  "The value of gradebook's getAverage property should be a Function.",
  "6. "
)

assert(
  (average instanceof Function),
  "The value of average should be a Function.\n",
  "7. "
)
assert(
  average([1, 2, 3]) === 2,
  "average should return the average of the elements in the array argument.\n",
  "8. "
)

assert(
  (gradebook.getAverage("Joseph") === 80),
  "gradebook's getAverage should return 80 if passed 'Joseph'.",
  "9. "
)<|endoftext|>