<commit_before>const config = require('config');
const _ = require('lodash');

module.exports = [{
  condition: function condition(R) {
    R.when(_.has(this, 'principle') &&
     _.has(this, 'currentAccountValue') &&
     this.currentAccountValue < (this.principle - (config.get('sienaAccount.criticalPoint') * this.principle)));
  },
  consequence: function consequence(R) {
    // Market has crashed and your capital has eroded, Bail out!
    this.actions = ['halt'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'bittrexAccountBalances'));
  },
  consequence: function consequence(R) {
    this.actions = ['compartmentaliseAccount'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'movingAverageShort') &&
      _.has(this, 'movingAverageMid') &&
      _.has(this, 'movingAverageLong'));
  },
  consequence: function consequence(R) {
    this.actions = ['getMarketTrend', 'getAccountValue'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'event') &&
      _.has(this, 'market') &&
      _.has(this, 'lastTrade') &&
      _.has(this, 'currentBidPrice') &&
      this.event === 'crossover' &&
      this.market === 'BULL' &&
      this.lastTrade !== 'BUY');
  },
  consequence: function consequence(R) {
    // Buy security on the lower half of the daily range, and at the start of a bull run
    this.actions = ['buySecurity'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'event') &&
      _.has(this, 'lastTrade') &&
      _.has(this, 'market') &&
      _.has(this, 'lastBuyPrice') &&
      _.has(this, 'currentBidPrice') &&
      _.has(this, 'upperSellPercentage') &&
      this.event === 'crossover' &&
      this.currentBidPrice > (this.lastBuyPrice + (this.upperSellPercentage * this.lastBuyPrice)) &&
      this.lastTrade === 'BUY' &&
      this.market !== 'BULL');
  },
  consequence: function consequence(R) {
    // You've got a profit so cash in!
    this.actions = ['sellSecurity'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'lastTrade') &&
      _.has(this, 'market') &&
      _.has(this, 'lastBuyPrice') &&
      _.has(this, 'currentBidPrice') &&
      this.currentBidPrice < (this.lastBuyPrice - (config.get('strategy.lowerSellPercentage') * this.lastBuyPrice)) &&
      this.lastTrade === 'BUY' &&
      this.market === 'BEAR');
  },
  consequence: function consequence(R) {
    // This is a bear market, sell and wait for better buying opportunity.
    this.actions = ['sellSecurity'];
    R.stop();
  },
}];
<commit_msg>unnecessary caps removed<commit_after>const config = require('config');
const _ = require('lodash');

module.exports = [{
  condition: function condition(R) {
    R.when(_.has(this, 'principle') &&
     _.has(this, 'currentAccountValue') &&
     this.currentAccountValue < (this.principle - (config.get('sienaAccount.criticalPoint') * this.principle)));
  },
  consequence: function consequence(R) {
    // Market has crashed and your capital has eroded, Bail out!
    this.actions = ['halt'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'bittrexAccountBalances'));
  },
  consequence: function consequence(R) {
    this.actions = ['compartmentaliseAccount'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'movingAverageShort') &&
      _.has(this, 'movingAverageMid') &&
      _.has(this, 'movingAverageLong'));
  },
  consequence: function consequence(R) {
    this.actions = ['getMarketTrend', 'getAccountValue'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'event') &&
      _.has(this, 'market') &&
      _.has(this, 'lastTrade') &&
      _.has(this, 'currentBidPrice') &&
      this.event === 'crossover' &&
      this.market === 'bull' &&
      this.lastTrade !== 'buy');
  },
  consequence: function consequence(R) {
    // Buy security on the lower half of the daily range, and at the start of a bull run
    this.actions = ['buySecurity'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'event') &&
      _.has(this, 'lastTrade') &&
      _.has(this, 'market') &&
      _.has(this, 'lastBuyPrice') &&
      _.has(this, 'currentBidPrice') &&
      _.has(this, 'upperSellPercentage') &&
      this.event === 'crossover' &&
      this.currentBidPrice > (this.lastBuyPrice + (this.upperSellPercentage * this.lastBuyPrice)) &&
      this.lastTrade === 'buy' &&
      this.market !== 'bull');
  },
  consequence: function consequence(R) {
    // You've got a profit so cash in!
    this.actions = ['sellSecurity'];
    R.stop();
  },
}, {
  condition: function condition(R) {
    R.when(_.has(this, 'lastTrade') &&
      _.has(this, 'market') &&
      _.has(this, 'lastBuyPrice') &&
      _.has(this, 'currentBidPrice') &&
      this.currentBidPrice < (this.lastBuyPrice - (config.get('strategy.lowerSellPercentage') * this.lastBuyPrice)) &&
      this.lastTrade === 'buy' &&
      this.market === 'bear');
  },
  consequence: function consequence(R) {
    // This is a bear market, sell and wait for better buying opportunity.
    this.actions = ['sellSecurity'];
    R.stop();
  },
}];
<|endoftext|>


<commit_before>'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ForkCheckerPlugin = require(
  'awesome-typescript-loader').ForkCheckerPlugin;

const postcss = require('./postcss');

const sourceMap = process.env.TEST
  ? [new webpack.SourceMapDevToolPlugin({ filename: null, test: /\.ts$/ })]
  : [];

const basePlugins = [
  new webpack.DefinePlugin({
    __DEV__: process.env.NODE_ENV !== 'production',
    __PRODUCTION__: process.env.NODE_ENV === 'production',
    __TEST__: JSON.stringify(process.env.TEST || false),
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
  }),
  new HtmlWebpackPlugin({
    chunksSortMode: 'dependency',
    template: './src/index.html',
    inject: 'body',
    minify: false,
  }),
  new webpack.NoErrorsPlugin(),
  new CopyWebpackPlugin([
    { from: 'src/assets', to: 'assets' },
  ]),
  new webpack.LoaderOptionsPlugin({
    test: /\.css$/,
    options: {
      postcss,
    },
  }),
  new webpack.ContextReplacementPlugin(
    /angular\/core\/(esm\/src|src)\/linker/, __dirname),
  new ForkCheckerPlugin(),
].concat(sourceMap);

const devPlugins = [
  new StyleLintPlugin({
    configFile: './.stylelintrc',
    files: ['src/**/*.css'],
    failOnError: false,
  }),
];

const prodPlugins = [
  new webpack.optimize.CommonsChunkPlugin({
    name: [
      'vendor',
    ],
  }),
  new webpack.optimize.UglifyJsPlugin({
    mangle: {
      keep_fnames: true,
    },
    compress: {
      warnings: false,
    },
  }),
];

module.exports = basePlugins
  .concat(process.env.NODE_ENV === 'production' ? prodPlugins : [])
  .concat(process.env.NODE_ENV === 'development' ? devPlugins : []);
<commit_msg>fix for missing source map<commit_after>'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ForkCheckerPlugin = require(
  'awesome-typescript-loader').ForkCheckerPlugin;

const postcss = require('./postcss');

const sourceMap = process.env.TEST
  ? [new webpack.SourceMapDevToolPlugin({ filename: null, test: /\.ts$/ })]
  : [];

const basePlugins = [
  new webpack.DefinePlugin({
    __DEV__: process.env.NODE_ENV !== 'production',
    __PRODUCTION__: process.env.NODE_ENV === 'production',
    __TEST__: JSON.stringify(process.env.TEST || false),
    'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
  }),
  new HtmlWebpackPlugin({
    chunksSortMode: 'dependency',
    template: './src/index.html',
    inject: 'body',
    minify: false,
  }),
  new webpack.NoErrorsPlugin(),
  new CopyWebpackPlugin([
    { from: 'src/assets', to: 'assets' },
  ]),
  new webpack.LoaderOptionsPlugin({
    test: /\.css$/,
    options: {
      postcss,
    },
  }),
  new webpack.ContextReplacementPlugin(
    /angular\/core\/(esm\/src|src)\/linker/, __dirname),
  new ForkCheckerPlugin(),
].concat(sourceMap);

const devPlugins = [
  new StyleLintPlugin({
    configFile: './.stylelintrc',
    files: ['src/**/*.css'],
    failOnError: false,
  }),
];

const prodPlugins = [
  new webpack.optimize.CommonsChunkPlugin({
    name: [
      'vendor',
    ],
  }),
  new webpack.optimize.UglifyJsPlugin({
    sourceMap: true,
    mangle: {
      keep_fnames: true,
    },
    compress: {
      warnings: false,
    },
  }),
];

module.exports = basePlugins
  .concat(process.env.NODE_ENV === 'production' ? prodPlugins : [])
  .concat(process.env.NODE_ENV === 'development' ? devPlugins : []);
<|endoftext|>


<commit_before>const path = require('path');
const rread = require('readdir-recursive');
const EventEmitter = require('events');
const Collection = require('discord.js').Collection;
const Command = require('./Command');
const Inhibitor = require('./Inhibitor');

/** @extends EventEmitter */
class CommandHandler extends EventEmitter {
    /**
     * Creates a new CommandHandler.
     * @param {Framework} framework - The Akairo framework.
     */
    constructor(framework){
        super();

        /**
         * The Akairo framework.
         * @readonly
         * @type {Framework}
         */
        this.framework = framework;

        /**
         * Directory to commands.
         * @readonly
         * @type {string}
         */
        this.commandDirectory = path.resolve(this.framework.options.commandDirectory);

        /**
         * Directory to inhibitors.
         * @readonly
         * @type {string}
         */
        this.inhibitorDirectory = path.resolve(this.framework.options.inhibitorDirectory);

        /**
         * Commands loaded, mapped by ID to Command.
         * @type {Collection.<string, Command>}
         */
        this.commands = new Collection();

        /**
         * Commands categories mapped by name to array of Commands.
         * @type {Collection.<string, Command[]>}
         */
        this.categories = new Collection();

        /**
         * Inhibitors loaded, mapped by ID to Inhibitor.
         * @type {Collection.<string, Inhibitor>}
         */
        this.inhibitors = new Collection();

        let cmdPaths = rread.fileSync(this.commandDirectory);
        cmdPaths.forEach(filepath => {
            this.loadCommand(filepath);
        });

        let inhibPaths = rread.fileSync(this.inhibitorDirectory);
        inhibPaths.forEach(filepath => {
            this.loadInhibitor(filepath);
        });
    }

    /**
     * Loads a Command.
     * @param {string} filepath - Path to file.
     */
    loadCommand(filepath){
        let command = require(filepath);

        if (!(command instanceof Command)) return;
        if (this.commands.has(command.id)) throw new Error(`Command ${command.id} already loaded.`);

        command.filepath = filepath;
        command.framework = this.framework;
        command.client = this.framework.client;
        command.commandHandler = this;

        this.commands.set(command.id, command);

        if (!this.categories.has(command.options.category)) this.categories.set(command.options.category, []);
        this.categories.get(command.options.category).push(command);
    }

    /**
     * Adds a Command.
     * @param {string} filename - Filename to lookup in the directory. A .js extension is assumed.
     */
    addCommand(filename){
        let files = rread.fileSync(this.commandDirectory);
        let filepath = files.find(file => file.endsWith(`${filename}.js`));

        if (!filepath){
            throw new Error(`File ${filename} not found.`);
        }

        this.loadCommand(filepath);
    }

    /**
     * Removes a Command.
     * @param {string} id - ID of the Command.
     */
    removeCommand(id){
        let command = this.commands.get(id);
        if (!command) throw new Error(`Command ${id} does not exist.`);

        delete require.cache[require.resolve(command.filepath)];
        this.commands.delete(command.id);

        let category = this.categories.get(command.options.category);
        category.splice(category.indexOf(command), 1);
    }

    /**
     * Reloads a Command.
     * @param {string} id - ID of the Command.
     */
    reloadCommand(id){
        let command = this.commands.get(id);
        if (!command) throw new Error(`Command ${id} does not exist.`);

        let filepath = command.filepath;

        delete require.cache[require.resolve(command.filepath)];
        this.commands.delete(command.id);

        let category = this.categories.get(command.options.category);
        category.splice(category.indexOf(command), 1);

        this.loadCommand(filepath);
    }

    /**
     * Finds a command by alias.
     * @param {string} name - Alias to find with.
     * @returns {Command}
     */
    findCommand(name){
        return this.commands.find(command => {
            return command.aliases.some(a => a.toLowerCase() === name.toLowerCase());
        });
    }

    /**
     * Finds a category by name.
     * @param {string} name - Name to find with.
     * @returns {Command[]}
     */
    findCategory(name){
        let key = Array.from(this.categories.keys()).find(k => k.toLowerCase() === name.toLowerCase());
        return this.categories.get(key);
    }

    /**
     * Loads an Inhibitor.
     * @param {string} filepath - Path to file.
     */
    loadInhibitor(filepath){
        let inhibitor = require(filepath);

        if (!(inhibitor instanceof Inhibitor)) return;
        if (this.inhibitors.has(inhibitor.id)) throw new Error(`Inhibitor ${inhibitor.id} already loaded.`);

        inhibitor.filepath = filepath;
        inhibitor.framework = this.framework;
        inhibitor.client = this.framework.client;
        inhibitor.commandHandler = this;

        this.inhibitors.set(inhibitor.id, inhibitor);
    }

    /**
     * Adds an Inhibitor.
     * @param {string} filename - Filename to lookup in the directory. A .js extension is assumed.
     */
    addInhibitor(filename){
        let files = rread.fileSync(this.inhibitorDirectory);
        let filepath = files.find(file => file.endsWith(`${filename}.js`));

        if (!filepath){
            throw new Error(`File ${filename} not found.`);
        }

        this.loadInhibitor(filepath);
    }

    /**
     * Removes an Inhibitor.
     * @param {string} id - ID of the Inhibitor.
     */
    removeInhibitor(id){
        let inhibitor = this.inhibitors.get(id);
        if (!inhibitor) throw new Error(`Inhibitor ${id} does not exist.`);

        delete require.cache[require.resolve(inhibitor.filepath)];
        this.inhibitors.delete(inhibitor.id);
    }

    /**
     * Reloads an Inhibitor.
     * @param {string} id - ID of the Inhibitor.
     */
    reloadInhibitor(id){
        let inhibitor = this.inhibitors.get(id);
        if (!inhibitor) throw new Error(`Inhibitor ${id} does not exist.`);

        let filepath = inhibitor.filepath;

        delete require.cache[require.resolve(inhibitor.filepath)];
        this.inhibitors.delete(inhibitor.id);

        this.loadInhibitor(filepath);
    }

    /**
     * Handles a Message.
     * @param {Message} message - Message to handle.
     * @param {string} prefix - Prefix for command.
     * @param {boolean} allowMention - Allow mentions to the client user as a prefix.
     * @param {boolean} disableBuiltIn - Disables the built-in command inhibitors.
     */
    handle(message, prefix, allowMention, disableBuiltIn){
        let start;
        let mentionRegex = new RegExp(`^<@!?${this.framework.client.user.id}>`);
        let mentioned = message.content.match(mentionRegex);

        if (message.content.startsWith(prefix)){
            start = prefix;
        } else
        if (allowMention && mentioned){
            start = mentioned[0];
        } else {
            return this.emit('commandPrefixInvalid', message);
        }

        let firstWord = message.content.replace(start, '').search(/\S/) + start.length;
        let name = message.content.slice(firstWord).split(' ')[0];
        let command = this.findCommand(name);

        if (!command) return this.emit('commandInvalid', message);

        let block = reason => {
            this.emit('commandBlocked', message, command, reason);
        };

        if (!disableBuiltIn){
            if (message.author.id !== this.framework.client.user.id && this.framework.options.selfbot) return block('notSelf');
            if (message.author.id === this.framework.client.user.id && !this.framework.options.selfbot) return block('client');
            if (message.author.bot) return block('bot');
            if (command.options.ownerOnly && message.author.id !== this.framework.options.ownerID) return block('owner');
            if (command.options.channelRestriction === 'guild' && !message.guild) return block('guild');
            if (command.options.channelRestriction === 'dm' && message.guild) return block('dm');
        }

        let results = [];

        this.inhibitors.forEach(inhibitor => {
            let inhibited = inhibitor.exec(message, command);

            if (inhibited instanceof Promise){
                return results.push(inhibited.catch(() => { throw inhibitor.reason; }));
            }

            if (!inhibited){
                return results.push(Promise.resolve());
            }

            results.push(Promise.reject(inhibitor.reason));
        });

        Promise.all(results).then(() => {
            let content = message.content.slice(message.content.indexOf(name) + name.length + 1);
            let args = command.parse(content);

            this.emit('commandStarted', message, command);
            let end = Promise.resolve(command.exec(message, args));

            end.then(() => {
                this.emit('commandFinished', message, command);
            }).catch(err => {
                this.emit('commandFinished', message, command);
                throw err;
            });
        }).catch(reason => {
            if (reason instanceof Error) throw reason;
            block(reason);
        });
    }
}

module.exports = CommandHandler;

/**
 * Emitted when a message does not start with the prefix.
 * @event CommandHandler#commandPrefixInvalid
 * @param {Message} message Message sent.
 */

/**
 * Emitted when a message does not match a command.
 * @event CommandHandler#commandInvalid
 * @param {Message} message Message sent.
 */

/**
 * Emitted when a command is blocked by an inhibitor.
 * @event CommandHandler#commandBlocked
 * @param {Message} message Message sent.
 * @param {Command} command Command blocked.
 * @param {string} reason Reason for the block.
 */

/**
 * Emitted when a command starts execution.
 * @event CommandHandler#commandStarted
 * @param {Message} message Message sent.
 * @param {Command} command Command executed.
 */

/**
 * Emitted when a command finishes execution.
 * @event CommandHandler#commandFinished
 * @param {Message} message Message sent.
 * @param {Command} command Command executed.
 */<commit_msg>simplify inhibiting code<commit_after>const path = require('path');
const rread = require('readdir-recursive');
const EventEmitter = require('events');
const Collection = require('discord.js').Collection;
const Command = require('./Command');
const Inhibitor = require('./Inhibitor');

/** @extends EventEmitter */
class CommandHandler extends EventEmitter {
    /**
     * Creates a new CommandHandler.
     * @param {Framework} framework - The Akairo framework.
     */
    constructor(framework){
        super();

        /**
         * The Akairo framework.
         * @readonly
         * @type {Framework}
         */
        this.framework = framework;

        /**
         * Directory to commands.
         * @readonly
         * @type {string}
         */
        this.commandDirectory = path.resolve(this.framework.options.commandDirectory);

        /**
         * Directory to inhibitors.
         * @readonly
         * @type {string}
         */
        this.inhibitorDirectory = path.resolve(this.framework.options.inhibitorDirectory);

        /**
         * Commands loaded, mapped by ID to Command.
         * @type {Collection.<string, Command>}
         */
        this.commands = new Collection();

        /**
         * Commands categories mapped by name to array of Commands.
         * @type {Collection.<string, Command[]>}
         */
        this.categories = new Collection();

        /**
         * Inhibitors loaded, mapped by ID to Inhibitor.
         * @type {Collection.<string, Inhibitor>}
         */
        this.inhibitors = new Collection();

        let cmdPaths = rread.fileSync(this.commandDirectory);
        cmdPaths.forEach(filepath => {
            this.loadCommand(filepath);
        });

        let inhibPaths = rread.fileSync(this.inhibitorDirectory);
        inhibPaths.forEach(filepath => {
            this.loadInhibitor(filepath);
        });
    }

    /**
     * Loads a Command.
     * @param {string} filepath - Path to file.
     */
    loadCommand(filepath){
        let command = require(filepath);

        if (!(command instanceof Command)) return;
        if (this.commands.has(command.id)) throw new Error(`Command ${command.id} already loaded.`);

        command.filepath = filepath;
        command.framework = this.framework;
        command.client = this.framework.client;
        command.commandHandler = this;

        this.commands.set(command.id, command);

        if (!this.categories.has(command.options.category)) this.categories.set(command.options.category, []);
        this.categories.get(command.options.category).push(command);
    }

    /**
     * Adds a Command.
     * @param {string} filename - Filename to lookup in the directory. A .js extension is assumed.
     */
    addCommand(filename){
        let files = rread.fileSync(this.commandDirectory);
        let filepath = files.find(file => file.endsWith(`${filename}.js`));

        if (!filepath){
            throw new Error(`File ${filename} not found.`);
        }

        this.loadCommand(filepath);
    }

    /**
     * Removes a Command.
     * @param {string} id - ID of the Command.
     */
    removeCommand(id){
        let command = this.commands.get(id);
        if (!command) throw new Error(`Command ${id} does not exist.`);

        delete require.cache[require.resolve(command.filepath)];
        this.commands.delete(command.id);

        let category = this.categories.get(command.options.category);
        category.splice(category.indexOf(command), 1);
    }

    /**
     * Reloads a Command.
     * @param {string} id - ID of the Command.
     */
    reloadCommand(id){
        let command = this.commands.get(id);
        if (!command) throw new Error(`Command ${id} does not exist.`);

        let filepath = command.filepath;

        delete require.cache[require.resolve(command.filepath)];
        this.commands.delete(command.id);

        let category = this.categories.get(command.options.category);
        category.splice(category.indexOf(command), 1);

        this.loadCommand(filepath);
    }

    /**
     * Finds a command by alias.
     * @param {string} name - Alias to find with.
     * @returns {Command}
     */
    findCommand(name){
        return this.commands.find(command => {
            return command.aliases.some(a => a.toLowerCase() === name.toLowerCase());
        });
    }

    /**
     * Finds a category by name.
     * @param {string} name - Name to find with.
     * @returns {Command[]}
     */
    findCategory(name){
        let key = Array.from(this.categories.keys()).find(k => k.toLowerCase() === name.toLowerCase());
        return this.categories.get(key);
    }

    /**
     * Loads an Inhibitor.
     * @param {string} filepath - Path to file.
     */
    loadInhibitor(filepath){
        let inhibitor = require(filepath);

        if (!(inhibitor instanceof Inhibitor)) return;
        if (this.inhibitors.has(inhibitor.id)) throw new Error(`Inhibitor ${inhibitor.id} already loaded.`);

        inhibitor.filepath = filepath;
        inhibitor.framework = this.framework;
        inhibitor.client = this.framework.client;
        inhibitor.commandHandler = this;

        this.inhibitors.set(inhibitor.id, inhibitor);
    }

    /**
     * Adds an Inhibitor.
     * @param {string} filename - Filename to lookup in the directory. A .js extension is assumed.
     */
    addInhibitor(filename){
        let files = rread.fileSync(this.inhibitorDirectory);
        let filepath = files.find(file => file.endsWith(`${filename}.js`));

        if (!filepath){
            throw new Error(`File ${filename} not found.`);
        }

        this.loadInhibitor(filepath);
    }

    /**
     * Removes an Inhibitor.
     * @param {string} id - ID of the Inhibitor.
     */
    removeInhibitor(id){
        let inhibitor = this.inhibitors.get(id);
        if (!inhibitor) throw new Error(`Inhibitor ${id} does not exist.`);

        delete require.cache[require.resolve(inhibitor.filepath)];
        this.inhibitors.delete(inhibitor.id);
    }

    /**
     * Reloads an Inhibitor.
     * @param {string} id - ID of the Inhibitor.
     */
    reloadInhibitor(id){
        let inhibitor = this.inhibitors.get(id);
        if (!inhibitor) throw new Error(`Inhibitor ${id} does not exist.`);

        let filepath = inhibitor.filepath;

        delete require.cache[require.resolve(inhibitor.filepath)];
        this.inhibitors.delete(inhibitor.id);

        this.loadInhibitor(filepath);
    }

    /**
     * Handles a Message.
     * @param {Message} message - Message to handle.
     * @param {string} prefix - Prefix for command.
     * @param {boolean} allowMention - Allow mentions to the client user as a prefix.
     * @param {boolean} disableBuiltIn - Disables the built-in command inhibitors.
     */
    handle(message, prefix, allowMention, disableBuiltIn){
        let start;
        let mentionRegex = new RegExp(`^<@!?${this.framework.client.user.id}>`);
        let mentioned = message.content.match(mentionRegex);

        if (message.content.startsWith(prefix)){
            start = prefix;
        } else
        if (allowMention && mentioned){
            start = mentioned[0];
        } else {
            return this.emit('commandPrefixInvalid', message);
        }

        let firstWord = message.content.replace(start, '').search(/\S/) + start.length;
        let name = message.content.slice(firstWord).split(' ')[0];
        let command = this.findCommand(name);

        if (!command) return this.emit('commandInvalid', message);

        let block = reason => {
            this.emit('commandBlocked', message, command, reason);
        };

        if (!disableBuiltIn){
            if (message.author.id !== this.framework.client.user.id && this.framework.options.selfbot) return block('notSelf');
            if (message.author.id === this.framework.client.user.id && !this.framework.options.selfbot) return block('client');
            if (message.author.bot) return block('bot');
            if (command.options.ownerOnly && message.author.id !== this.framework.options.ownerID) return block('owner');
            if (command.options.channelRestriction === 'guild' && !message.guild) return block('guild');
            if (command.options.channelRestriction === 'dm' && message.guild) return block('dm');
        }

        let p = this.inhibitors.map(inhibitor => {
            let inhibited = inhibitor.exec(message, command);

            if (inhibited instanceof Promise) return inhibited.catch(() => { throw inhibitor.reason; });
            if (!inhibited) return Promise.resolve();
            return Promise.reject(inhibitor.reason);
        });

        Promise.all(p).then(() => {
            let content = message.content.slice(message.content.indexOf(name) + name.length + 1);
            let args = command.parse(content);

            this.emit('commandStarted', message, command);
            let end = Promise.resolve(command.exec(message, args));

            end.then(() => {
                this.emit('commandFinished', message, command);
            }).catch(err => {
                this.emit('commandFinished', message, command);
                throw err;
            });
        }).catch(reason => {
            if (reason instanceof Error) throw reason;
            block(reason);
        });
    }
}

module.exports = CommandHandler;

/**
 * Emitted when a message does not start with the prefix.
 * @event CommandHandler#commandPrefixInvalid
 * @param {Message} message Message sent.
 */

/**
 * Emitted when a message does not match a command.
 * @event CommandHandler#commandInvalid
 * @param {Message} message Message sent.
 */

/**
 * Emitted when a command is blocked by an inhibitor.
 * @event CommandHandler#commandBlocked
 * @param {Message} message Message sent.
 * @param {Command} command Command blocked.
 * @param {string} reason Reason for the block.
 */

/**
 * Emitted when a command starts execution.
 * @event CommandHandler#commandStarted
 * @param {Message} message Message sent.
 * @param {Command} command Command executed.
 */

/**
 * Emitted when a command finishes execution.
 * @event CommandHandler#commandFinished
 * @param {Message} message Message sent.
 * @param {Command} command Command executed.
 */<|endoftext|>


<commit_before>import Backbone from 'backbone';
import { extend, isString, isArray } from 'underscore';
import { isTaggableNode } from 'utils/mixins';
import { appendAtIndex } from 'utils/dom';
import SectorView from './SectorView';

const helperCls = 'hc-state';

export default Backbone.View.extend({
  initialize(o = {}) {
    const config = o.config || {};
    this.pfx = config.stylePrefix || '';
    this.ppfx = config.pStylePrefix || '';
    this.target = o.target || {};
    this.config = config;

    // The target that will emit events for properties
    const target = {};
    extend(target, Backbone.Events);
    const body = document.body;
    const dummy = document.createElement(`el-${new Date().getTime()}`);
    body.appendChild(dummy);
    target.computedDefault = { ...window.getComputedStyle(dummy) };
    body.removeChild(dummy);
    this.propTarget = target;
    const coll = this.collection;
    const events =
      'component:toggled component:update:classes change:state change:device';
    this.listenTo(coll, 'add', this.addTo);
    this.listenTo(coll, 'reset', this.render);
    this.listenTo(this.target, events, this.targetUpdated);
  },

  /**
   * Add to collection
   * @param {Object} model Model
   * @return {Object}
   * @private
   * */
  addTo(model, coll, opts = {}) {
    this.addToCollection(model, null, opts);
  },

  toggleStateCls(targets = [], enable) {
    targets.forEach(trg => {
      const el = trg.getEl();
      el && el.classList[enable ? 'add' : 'remove'](helperCls);
    });
  },

  /**
   * Fired when target is updated
   * @private
   */
  targetUpdated(trg) {
    const em = this.target;
    const pt = this.propTarget;
    const targets = em.getSelectedAll();
    let model = em.getSelected();
    const mdToClear = trg && !!trg.toHTML ? trg : model;

    // Clean components
    mdToClear && this.toggleStateCls([mdToClear]);
    if (!model) return;

    const config = em.get('Config');
    const state = !config.devicePreviewMode ? em.get('state') : '';
    const { componentFirst } = em.get('SelectorManager').getConfig();
    const el = model.getEl();
    pt.helper = null;

    // Create computed style container
    if (el && isTaggableNode(el)) {
      const stateStr = state ? `:${state}` : null;
      pt.computed = window.getComputedStyle(el, stateStr);
    }

    // Create a new rule for the state as a helper
    const appendStateRule = (style = {}) => {
      const cc = em.get('CssComposer');
      const rules = cc.getAll();
      let helperRule = cc.getClassRule(helperCls);

      if (!helperRule) {
        helperRule = cc.setClassRule(helperCls);
      } else {
        // I will make it last again, otherwise it could be overridden
        rules.remove(helperRule);
        rules.add(helperRule);
      }

      helperRule.set('important', 1);
      helperRule.setStyle(style);
      pt.helper = helperRule;
    };

    model = em.get('StyleManager').getModelToStyle(model);

    if (state) {
      appendStateRule(model.getStyle());
      this.toggleStateCls(targets, 1);
    }

    pt.model = model;
    if (componentFirst) pt.targets = targets;
    pt.trigger('update');
  },

  /**
   * Select different target for the Style Manager.
   * It could be a Component, CSSRule, or a string of any CSS selector
   * @param {Component|CSSRule|String|Array<Component|CSSRule|String>} target
   * @return {Array<Styleable>} Array of Components/CSSRules
   */
  setTarget(target, opts = {}) {
    const em = this.target;
    const trgs = isArray(target) ? target : [target];
    const { targetIsClass, stylable } = opts;
    const models = [];

    trgs.forEach(target => {
      let model = target;

      if (isString(target)) {
        let rule;
        const rules = em.get('CssComposer').getAll();

        if (targetIsClass) {
          rule = rules.filter(
            rule => rule.get('selectors').getFullString() === target
          )[0];
        }

        if (!rule) {
          rule = rules.filter(rule => rule.get('selectorsAdd') === target)[0];
        }

        if (!rule) {
          rule = rules.add({ selectors: [], selectorsAdd: target });
        }

        stylable && rule.set({ stylable });
        model = rule;
      }

      models.push(model);
    });

    const pt = this.propTarget;
    pt.targets = models;
    pt.trigger('update');
    return models;
  },

  /**
   * Add new object to collection
   * @param {Object} model Model
   * @param  {Object} fragmentEl collection
   * @return {Object} Object created
   * @private
   * */
  addToCollection(model, fragmentEl, opts = {}) {
    const { pfx, target, propTarget, config, el } = this;
    const appendTo = fragmentEl || el;
    const rendered = new SectorView({
      model,
      id: `${pfx}${model.get('id')}`,
      name: model.get('name'),
      properties: model.get('properties'),
      target,
      propTarget,
      config
    }).render().el;
    appendAtIndex(appendTo, rendered, opts.at);

    return rendered;
  },

  render() {
    const frag = document.createDocumentFragment();
    const $el = this.$el;
    const pfx = this.pfx;
    const ppfx = this.ppfx;
    $el.empty();
    this.collection.each(model => this.addToCollection(model, frag));
    $el.append(frag);
    $el.addClass(`${pfx}sectors ${ppfx}one-bg ${ppfx}two-color`);
    return this;
  }
});
<commit_msg>Clear targets in SectorsView<commit_after>import Backbone from 'backbone';
import { extend, isString, isArray } from 'underscore';
import { isTaggableNode } from 'utils/mixins';
import { appendAtIndex } from 'utils/dom';
import SectorView from './SectorView';

const helperCls = 'hc-state';

export default Backbone.View.extend({
  initialize(o = {}) {
    const config = o.config || {};
    this.pfx = config.stylePrefix || '';
    this.ppfx = config.pStylePrefix || '';
    this.target = o.target || {};
    this.config = config;

    // The target that will emit events for properties
    const target = {};
    extend(target, Backbone.Events);
    const body = document.body;
    const dummy = document.createElement(`el-${new Date().getTime()}`);
    body.appendChild(dummy);
    target.computedDefault = { ...window.getComputedStyle(dummy) };
    body.removeChild(dummy);
    this.propTarget = target;
    const coll = this.collection;
    const events =
      'component:toggled component:update:classes change:state change:device';
    this.listenTo(coll, 'add', this.addTo);
    this.listenTo(coll, 'reset', this.render);
    this.listenTo(this.target, events, this.targetUpdated);
  },

  /**
   * Add to collection
   * @param {Object} model Model
   * @return {Object}
   * @private
   * */
  addTo(model, coll, opts = {}) {
    this.addToCollection(model, null, opts);
  },

  toggleStateCls(targets = [], enable) {
    targets.forEach(trg => {
      const el = trg.getEl();
      el && el.classList[enable ? 'add' : 'remove'](helperCls);
    });
  },

  /**
   * Fired when target is updated
   * @private
   */
  targetUpdated(trg) {
    const em = this.target;
    const pt = this.propTarget;
    const targets = em.getSelectedAll();
    let model = em.getSelected();
    const mdToClear = trg && !!trg.toHTML ? trg : model;

    // Clean components
    mdToClear && this.toggleStateCls([mdToClear]);
    if (!model) return;

    const config = em.get('Config');
    const state = !config.devicePreviewMode ? em.get('state') : '';
    const { componentFirst } = em.get('SelectorManager').getConfig();
    const el = model.getEl();
    pt.helper = null;
    pt.targets = null;

    // Create computed style container
    if (el && isTaggableNode(el)) {
      const stateStr = state ? `:${state}` : null;
      pt.computed = window.getComputedStyle(el, stateStr);
    }

    // Create a new rule for the state as a helper
    const appendStateRule = (style = {}) => {
      const cc = em.get('CssComposer');
      const rules = cc.getAll();
      let helperRule = cc.getClassRule(helperCls);

      if (!helperRule) {
        helperRule = cc.setClassRule(helperCls);
      } else {
        // I will make it last again, otherwise it could be overridden
        rules.remove(helperRule);
        rules.add(helperRule);
      }

      helperRule.set('important', 1);
      helperRule.setStyle(style);
      pt.helper = helperRule;
    };

    model = em.get('StyleManager').getModelToStyle(model);

    if (state) {
      appendStateRule(model.getStyle());
      this.toggleStateCls(targets, 1);
    }

    pt.model = model;
    if (componentFirst) pt.targets = targets;
    pt.trigger('update');
  },

  /**
   * Select different target for the Style Manager.
   * It could be a Component, CSSRule, or a string of any CSS selector
   * @param {Component|CSSRule|String|Array<Component|CSSRule|String>} target
   * @return {Array<Styleable>} Array of Components/CSSRules
   */
  setTarget(target, opts = {}) {
    const em = this.target;
    const trgs = isArray(target) ? target : [target];
    const { targetIsClass, stylable } = opts;
    const models = [];

    trgs.forEach(target => {
      let model = target;

      if (isString(target)) {
        let rule;
        const rules = em.get('CssComposer').getAll();

        if (targetIsClass) {
          rule = rules.filter(
            rule => rule.get('selectors').getFullString() === target
          )[0];
        }

        if (!rule) {
          rule = rules.filter(rule => rule.get('selectorsAdd') === target)[0];
        }

        if (!rule) {
          rule = rules.add({ selectors: [], selectorsAdd: target });
        }

        stylable && rule.set({ stylable });
        model = rule;
      }

      models.push(model);
    });

    const pt = this.propTarget;
    pt.targets = models;
    pt.trigger('update');
    return models;
  },

  /**
   * Add new object to collection
   * @param {Object} model Model
   * @param  {Object} fragmentEl collection
   * @return {Object} Object created
   * @private
   * */
  addToCollection(model, fragmentEl, opts = {}) {
    const { pfx, target, propTarget, config, el } = this;
    const appendTo = fragmentEl || el;
    const rendered = new SectorView({
      model,
      id: `${pfx}${model.get('id')}`,
      name: model.get('name'),
      properties: model.get('properties'),
      target,
      propTarget,
      config
    }).render().el;
    appendAtIndex(appendTo, rendered, opts.at);

    return rendered;
  },

  render() {
    const frag = document.createDocumentFragment();
    const $el = this.$el;
    const pfx = this.pfx;
    const ppfx = this.ppfx;
    $el.empty();
    this.collection.each(model => this.addToCollection(model, frag));
    $el.append(frag);
    $el.addClass(`${pfx}sectors ${ppfx}one-bg ${ppfx}two-color`);
    return this;
  }
});
<|endoftext|>


<commit_before>define(['component/eventBus', 'sinon'], function(eventBus, sinon) {

    describe("EventBus", function() {

        it("triggers event", function() {
            var spy = sinon.spy();

            eventBus.on("test", spy);
            eventBus.trigger("test");
            expect(spy).toHaveBeenCalledOnce();
        });

        it("turn off event", function() {
            var spy = sinon.spy();

            eventBus.on("test", spy);
            eventBus.off("test");
            eventBus.trigger("test");

            expect(spy).not.toHaveBeenCalled();
        });

        it("turn off all events", function() {
            var spy1 = sinon.spy();
            var spy2 = sinon.spy();

            eventBus.on("test1", spy1);
            eventBus.on("test2", spy2);

            eventBus.reset();
            eventBus.trigger("test1");
            eventBus.trigger("test2");

            expect(spy1).not.toHaveBeenCalled();
            expect(spy2).not.toHaveBeenCalled();
        })
    });
});<commit_msg>added missing semi<commit_after>define(['component/eventBus', 'sinon'], function(eventBus, sinon) {

    describe("EventBus", function() {

        it("triggers event", function() {
            var spy = sinon.spy();

            eventBus.on("test", spy);
            eventBus.trigger("test");
            expect(spy).toHaveBeenCalledOnce();
        });

        it("turn off event", function() {
            var spy = sinon.spy();

            eventBus.on("test", spy);
            eventBus.off("test");
            eventBus.trigger("test");

            expect(spy).not.toHaveBeenCalled();
        });

        it("turn off all events", function() {
            var spy1 = sinon.spy();
            var spy2 = sinon.spy();

            eventBus.on("test1", spy1);
            eventBus.on("test2", spy2);

            eventBus.reset();
            eventBus.trigger("test1");
            eventBus.trigger("test2");

            expect(spy1).not.toHaveBeenCalled();
            expect(spy2).not.toHaveBeenCalled();
        });
    });
});<|endoftext|>


<commit_before>/**
 *
 */
var events = require('events');

function WebsocketServer(options){

	var me=this;
	// Simple websocket server
	events.EventEmitter.call(me);
	me.clients = [];

	me._handlers={};

	var config={
			port:8080
	};

	Object.keys(options).forEach(function (key) {
		config[key]=options[key];
	});

	me.server=(new (require('ws').Server)({
		port: config.port
	})).on('connection', function(wsclient){

		me.clients.push(wsclient);
		console.log('client connected: '+wsclient);

		wsclient.on('message',function(data){

			var request=JSON.parse(data);
			//console.log([data, request]);
			var id=request.id;
			var task=request.task;
			var arguments=request.json;
			arguments.request_id=id;
			arguments.client=wsclient;

			if((typeof me._handlers[task])=='function'){

				me._handlers[task](arguments, function(response){

					if((typeof response)=='object'){
						wsclient.send(id+':'+JSON.stringify(response));
					}

					if((['string', 'number']).indexOf(typeof response)>=0){
						wsclient.send(id+':'+response);
					}

				});

			}

		}).on('close',function(code, message){
			var i = me.clients.indexOf(wsclient);
			console.log('ws:'+i+' client closed: '+code+' '+message);
			me.clients.splice(i, 1);
		});

	}).on('error', function(error){

		console.log('error: '+error);

	});

	//gpio.on('change', function(pin, value) {
	//   console.log('notify device: '+pin+' state change: '+value);
	//
	//});

	console.log('websocket listening on: '+config.port);

}

WebsocketServer.prototype.__proto__ = events.EventEmitter.prototype;
WebsocketServer.prototype.stop=function(){
	var me=this;
	console.log('websocker server stopped');
	me.server.close();
}

WebsocketServer.prototype.broadcast=function(name, message, filterClient){
	var me=this;

	me.clients.forEach(function(wsclient){

		if((typeof filterClient)=='function'){
			if(filterClient(wsclient)){
				console.log('broadcast client');
				wsclient.send(name+':'+message);
			}else{
				console.log('skip client');
			}
		}else{
			wsclient.send(name+':'+message);
		}

	});
}

WebsocketServer.prototype.addTask=function(name, callback){
	var me=this;
	if(!me._handlers){
		me._handlers={};
	}
	me._handlers[name]=callback;
	return me;
}

module.exports=WebsocketServer;<commit_msg>client<commit_after>/**
 *
 */
var events = require('events');

function WebsocketServer(options){

	var me=this;
	// Simple websocket server
	events.EventEmitter.call(me);
	me.clients = [];

	me._handlers={};

	var config={
			port:8080
	};

	Object.keys(options).forEach(function (key) {
		config[key]=options[key];
	});

	me.server=(new (require('ws').Server)({
		port: config.port
	})).on('connection', function(wsclient){

		me.clients.push(wsclient);
		console.log('client connected: '+wsclient);

		wsclient.on('message',function(data){

			var request=JSON.parse(data);
			//console.log([data, request]);
			var id=request.id;
			var task=request.task;
			var arguments=request.json;
			arguments.request_id=id;
			arguments.client=wsclient;

			if((typeof me._handlers[task])=='function'){

				me._handlers[task](arguments, function(response){

					if((typeof response)=='object'){
						wsclient.send(id+':'+JSON.stringify(response));
					}

					if((['string', 'number']).indexOf(typeof response)>=0){
						wsclient.send(id+':'+response);
					}

				});

			}

		}).on('close',function(code, message){
			var i = me.clients.indexOf(wsclient);
			console.log('ws:'+i+' client closed: '+code+' '+message);
			me.clients.splice(i, 1);
		});

	}).on('error', function(error){

		console.log('error: '+error);

	});

	//gpio.on('change', function(pin, value) {
	//   console.log('notify device: '+pin+' state change: '+value);
	//
	//});

	console.log('websocket listening on: '+config.port);

}

WebsocketServer.prototype.__proto__ = events.EventEmitter.prototype;
WebsocketServer.prototype.stop=function(){
	var me=this;
	console.log('websocker server stopped');
	me.server.close();
}

WebsocketServer.prototype.broadcast=function(name, message, filterClient){
	var me=this;

	me.clients.forEach(function(client){

		if((typeof filterClient)=='function'){
			if(filterClient(client)){
				console.log('broadcast client');
				client.send(name+':'+message);
			}else{
				console.log('skip client');
			}
		}else{
			client.send(name+':'+message);
		}

	});
}

WebsocketServer.prototype.addTask=function(name, callback){
	var me=this;
	if(!me._handlers){
		me._handlers={};
	}
	me._handlers[name]=callback;
	return me;
}

module.exports=WebsocketServer;<|endoftext|>


<commit_before>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.
var myVar = "The time is ";
console.log(myVar + "3:00.");

//Favorite food
prompt("What's your favorite food?", "");
alert("Hey! That's my favorite too!");

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board
Looping a Triangle
var triangle = ""
while (triangle.length < 7) {
  console.log(triangle += "#");
}
//FizzBuzz
for (var n = 1; n <= 100; n++) {
  if (n % 3 == 0 && n % 5 == 0)
    console.log("FizzBuzz");
  else if (n % 3 == 0)
    console.log("Fizz");
  else if (n % 5 == 0)
    console.log("Buzz");
  else
    console.log(n);
// }
//Chess Board
var size = 8;
var board = "";
for (var row = 0; row < size; row++) {
  for (var line = 0; line < size; line++) {
    if ((row + line) % 2 == 0)
      board += " ";
    else
      board += "#";
  }
  board += "\n"
}
console.log(board);

// Functions

// Complete the `minimum` exercise.

function min(num1, num2) {
  if(num1 < num2)
    return num1;
  else
    return num2;
}

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

var me = {
  name: "Daniel",
  age: 26,
  favoriteFoods: ["Abura Soba", "Bulgogi", "Shio Tsukemen"],
  quirk: "I love leopard geckos."
};
console.log(me.name)<commit_msg>Fix error<commit_after>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.
var myVar = "The time is ";
console.log(myVar + "3:00.");

//Favorite food
prompt("What's your favorite food?", "");
alert("Hey! That's my favorite too!");

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board
Looping a Triangle
var triangle = ""
while (triangle.length < 7) {
  console.log(triangle += "#");
}
//FizzBuzz
for (var n = 1; n <= 100; n++) {
  if (n % 3 == 0 && n % 5 == 0)
    console.log("FizzBuzz");
  else if (n % 3 == 0)
    console.log("Fizz");
  else if (n % 5 == 0)
    console.log("Buzz");
  else
    console.log(n);
}
//Chess Board
var size = 8;
var board = "";
for (var row = 0; row < size; row++) {
  for (var line = 0; line < size; line++) {
    if ((row + line) % 2 == 0)
      board += " ";
    else
      board += "#";
  }
  board += "\n"
}
console.log(board);

// Functions

// Complete the `minimum` exercise.

function min(num1, num2) {
  if(num1 < num2)
    return num1;
  else
    return num2;
}

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

var me = {
  name: "Daniel",
  age: 26,
  favoriteFoods: ["Abura Soba", "Bulgogi", "Shio Tsukemen"],
  quirk: "I love leopard geckos."
};
console.log(me.name)<|endoftext|>


<commit_before>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.
var cat_name = "Finn"
console.log(cat_name, "is a great cat.")

// prompt("What's your favorite food?")
// alert("That's my favorite food too!")

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

// Introduction
// Did you learn anything new about JavaScript or programming in general?
// I don'y know much about JavaScript, so there were definitely some new things here. One of the most interesting things was the fact that JavaScript is very "forgiving" in terms of what it will allow. It does seem like that will be difficult at first, but I'm interested to see how that will also give you the ability to be more flexible later on.

// Are there any concepts you feel uncomfortable with?
// Not in particular. As I said, I don't really have experience with this language, but nothing in the introduction seemed too crazy.

// Chapter 1
// Identify two similarities and two differences between JavaScript and Ruby syntax with regard to numbers, arithmetic, strings, booleans, and various operators.
//Similarities:
  // 1. The arithmetic operators are the same.
  // 2. Strings are handled in the same way.
// Differences
  // 1. In JavaScript you have to include the keyword "var" to declare a variable.
  // 2. The automatic type conversion in JavaScript seems very different from Ruby. I believe Ruby will raise an error any time you try to apply mathematical operations on dissimilar object types (except in a few cases).

// Chapter 2
// What is an expression?
// Anything that produces a value.

// What is the purpose of semicolons in JavaScript? Are they always required?
// It markes the end of an expression. They are not always required, but the rules regarding when they are not required are complicated.

// What causes a variable to return undefined?
// Undefined is returned when an operation doesn't yield a meaningful value.

// Write your own variable and do something to it in the eloquent.js file.
// See above.

// What does console.log do and when would you use it? What Ruby method(s) is this similar to?
// It prints something to the console. This is similar to p, print, and puts in Ruby.

// Write a short program that asks for a user to input their favorite food. After they hit return, have the program respond with "Hey! That's my favorite too!" (You will probably need to run this in the Chrome console (Links to an external site.) rather than node since node does not support prompt or alert). Paste your program into the eloquent.js file.
// See above.

// Describe while and for loops
// While and for loops do the same thing. They will continue to loop until a specified condition is met. For is a shorter version of while, but they function the same.

// What other similarities or differences between Ruby and JavaScript did you notice in this section?
// The main thing for me is that most of the concepts are essentially the same. While loops, if/else statements, etc. For the most part, it's just the syntax that is different.

// Complete at least one of the exercises (Looping a Triangle, FizzBuzz, of Chess Board) in the eloquent.js file.

// Looping a triangle

var counter = 1
while (counter <= 7) {
  console.log("#".repeat(counter ++));
}

// for (var i = 1; i < 101; console.log(i++)) {
//   if (i % 3 == 0 && i % 5 == 0) { console.log("FizzBuzz")};
//     else if (i % 3 == 0 ) { console.log("Fizz") };
//       else if (i % 5 == 0) { console.log("Buzz")};
//         else if (i % 3 != 0 || i % 5 != 0) { console.log(i) };
// }

switch
<commit_msg>Update eloquent.js through chapter 2<commit_after>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.
var cat_name = "Finn"
console.log(cat_name, "is a great cat.")

// prompt("What's your favorite food?")
// alert("That's my favorite food too!")

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

// Introduction
// Did you learn anything new about JavaScript or programming in general?
// I don'y know much about JavaScript, so there were definitely some new things here. One of the most interesting things was the fact that JavaScript is very "forgiving" in terms of what it will allow. It does seem like that will be difficult at first, but I'm interested to see how that will also give you the ability to be more flexible later on.

// Are there any concepts you feel uncomfortable with?
// Not in particular. As I said, I don't really have experience with this language, but nothing in the introduction seemed too crazy.

// Chapter 1
// Identify two similarities and two differences between JavaScript and Ruby syntax with regard to numbers, arithmetic, strings, booleans, and various operators.
//Similarities:
  // 1. The arithmetic operators are the same.
  // 2. Strings are handled in the same way.
// Differences
  // 1. In JavaScript you have to include the keyword "var" to declare a variable.
  // 2. The automatic type conversion in JavaScript seems very different from Ruby. I believe Ruby will raise an error any time you try to apply mathematical operations on dissimilar object types (except in a few cases).

// Chapter 2
// What is an expression?
// Anything that produces a value.

// What is the purpose of semicolons in JavaScript? Are they always required?
// It markes the end of an expression. They are not always required, but the rules regarding when they are not required are complicated.

// What causes a variable to return undefined?
// Undefined is returned when an operation doesn't yield a meaningful value.

// Write your own variable and do something to it in the eloquent.js file.
// See above.

// What does console.log do and when would you use it? What Ruby method(s) is this similar to?
// It prints something to the console. This is similar to p, print, and puts in Ruby.

// Write a short program that asks for a user to input their favorite food. After they hit return, have the program respond with "Hey! That's my favorite too!" (You will probably need to run this in the Chrome console (Links to an external site.) rather than node since node does not support prompt or alert). Paste your program into the eloquent.js file.
// See above.

// Describe while and for loops
// While and for loops do the same thing. They will continue to loop until a specified condition is met. For is a shorter version of while, but they function the same.

// What other similarities or differences between Ruby and JavaScript did you notice in this section?
// The main thing for me is that most of the concepts are essentially the same. While loops, if/else statements, etc. For the most part, it's just the syntax that is different.

// Complete at least one of the exercises (Looping a Triangle, FizzBuzz, of Chess Board) in the eloquent.js file.

// Looping a triangle

var counter = 1
while (counter <= 7) {
  console.log("#".repeat(counter ++));
}

<|endoftext|>


<commit_before>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.

var number = 5
number *= 2
console.log(number)

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

// Did you learn anything new about JavaScript or programming in general?
//
// JavaScript is entirely new to me, so learning about the history of how it came to be and what it is used for.
// A lot of the fundamental concepts behind programming read similar to what was presented in the Ruby material,
// so I think that learning JavaScript will mainly be about learning the new syntax and flow to achieve the same
// results we've been working towards with Ruby.

// Are there any concepts you feel uncomfortable with?
//
// I'm a little nervous to start working in a new language as I'm still getting the hang of Ruby, but I think
// there should be enough similarities to help make this understandable.

// Identify two similarities and two differences between JavaScript and Ruby syntax with regard to numbers,
// arithmetic, strings, booleans, and various operators.
//
// After reading this chapter, I feel pretty good about the similarities between JavaScript and Ruby operators.
// There are quite a few similarities. First off, all of the basic arithmetic and boolean operators between JS
// and Ruby are the same - && always means "and", % means modulus, != means not equal to, etc. Strings also operate
// in the same manner in both languages. You can concatenate strings together using addition in JS, just like in
// Ruby. However, there are also a few key differences to keep in mind. If we tried to add a string and a number
// together in Ruby, we would receive a type error that would let us know we used the wrong type of variable in our
// code. In JS, it will automatically try to convert the "wrong" variable to the "right" type, giving us a possibly
// unexpected result while not displaying an error. Therefore, type errors can be much harder to diagnose in JS than
// in Ruby. The other major difference is that we receive an extra set of operators to check for true equivalencies
// without any type conversion. We can use === and !== (note the extra equal signs) to check to see if the precise
// values on both sides of the equation are truly equal.

// What is an expression?
//
// An expression is simply a fragment of code that produces a value. This value does not need to be stored or
// used anywhere else - an expression simply generates a value.

// What is the purpose of semicolons in JavaScript? Are they always required?
//
// A semicolon signifies the end of a statement at the end of the line, so the next line is treated as a new
// statement. Semicolons are not always required, but the cases in which you can safely omit them is not
// readily apparent. It is safer to end a statement with a semicolon to acheive the desired result.

// What causes a variable to return undefined?
//
// A variable will return undefined if you first define a variable without assigning an expression to it.
// Calling the variable will work because it exists, but will then return undefined because it is empty.
// This is different than calling a variable that has not been defined yet - in this case, the program
// will throw an error because you are referring to a variable that doesn't actually exist.

// Write your own variable and do something to it in the eloquent.js file.
//
var number = 5
number *= 2
console.log(number)

// What does console.log do and when would you use it? What Ruby method(s) is this similar to?
//
// console.log provides a value for some form of text output. When running node.js from the command
// line, that text output will occur in the shell. In a browser, though, that output will occur within
// the browser itself and can be viewed through the developer tools. Console.log is for when you need to
// display a value in readable format. In this way, it is similar to the puts or print command in Ruby.

// Write a short program that asks for a user to input their favorite food. After they hit return,
// have the program respond with "Hey! That's my favorite too!" (You will probably need to run this
// in the Chrome console (Links to an external site.) rather than node since node does not support
// prompt or alert). Paste your program into the eloquent.js file.

// prompt("What's your favorite food?")
// console.log("Hey, that's my favorite too!")

// Describe while and for loops
//
// A while loop allows a loop to iterate until a given condition is met. A for loop will iterate
// for as many times as specified in a for statement. This allows two different type of break conditions.
// The for loop will run for specified set of iterations, and the while loop will run for some
// unspecified time until the condition is met. Both types are useful depending on the function
// of the loop.

// What other similarities or differences between Ruby and JavaScript did you notice in this section?
//
// JavaScript has a new special number, NaN, that stands for Not a Number. This can be generated by running
// a mathematical equation such as x / 0 or Infinity - Infinity, where the answer isn't precise or meaninful.
// In Ruby, this would normally generate an error instead. JavaScript has a function isNaN to check for this
// and return true if NaN is found. This means there is a specific function to handle Nan errors inside the code
// rather than rewriting the structure within Ruby to avoid NaN errors altogether.

// Complete at least one of the exercises (Looping a Triangle, FizzBuzz, of Chess Board) in the eloquent.js file.
//
// Looping Triangle
// row = "#";
// while(row.length <= 7) {
// 	console.log(row);
// 	row += "#";
// }

// // FizzBuzz
// for (var counter = 1; counter <= 100; counter++)
// 	if (counter % 3 == 0 && counter % 5 == 0)
// 		console.log("FizzBuzz");
// 	else if (counter % 3 == 0)
// 		console.log("Fizz");
// 	else if (counter % 5 == 0)
// 		console.log("Buzz");
// 	else
// 		console.log(counter);

// Chessboard

var board = "";
var size = 8;
for (var row = 1; row <= size; row++) {
	for (var counter = 1; counter <= 8; counter ++) {
		if (board.length % 2 == 0)
			board = board + "#";
		else
			board = board + "_";
	}
	board = board + "\n";
}

console.log(board)

// What are the differences between local and global variables in JavaScript?
//
// Local variables are variables that are declared within functions, while global variables
// are declared outside of functions. Global variables can be used anywhere within the program.
// For instance, if you declared the variable "number" outside a function, you could refer to it
// within a function by calling "number" itself. However, you could also declare a local variable
// within the function also called number using the var "number" syntax. This local variable will
// only be used within the function and will not overwrite the global variable.

// When should you use functions?
//
// Functions work very similarly to methods in Ruby. You should use a function to create a block of
// code that can be executed multiple times without having to type out that block each and every
// time you want to call it.

// What is a function declaration?
//
// A function declaration is declaring a variable and assigning a function expression to it. The function
// expression is specified by starting with a function keyword followed by the expression that generates
// the value of the function. This can be written shorthand by leading with the function keyword, removing
// the need for a variable declaration.

// Complete the minimum exercise in the eloquent.js file.

function min(number1, number2) {
	if (number1 <= number2)
		return number1;
	else
		return number2;
}

console.log(min(0,-10))
console.log(min(6,3))
console.log(min(10,10))

// What is the difference between using a dot and a bracket to look up a property? Ex. array.max vs array["max"]
//
// While each of these approaches allow you to look up a property, they will not necessary return the same property.
// The difference is that using array.max will specifically return the .max property as long as it is a valid property.
// When using brackets, the variable "max" will be evaluated first and a different property will be returned. In this
// example, what this means is the .max variable will return the maximum value in an array, while the ["max"] variable
// will evaluate the value in the array stored under the "max" index and return that instead.

// Create an object called me that stores your name, age, three favorite foods, and a quirk in your eloquent.js file.
var me = {
	name: "Zach Barton",
	age: 32,
	fav_foods: ["Pork Belly Ramen", "Pie", "Sausage Pizza"],
	quirk: "I design board games."
}

console.log(me.fav_foods)

// What is a JavaScript object with a name and value property similar to in Ruby?
//
// The above object we defined is very similar to a hash in Ruby. We've created a data structure with
// key-value pairs, where the values can be any type of value, including strings, integers, and arrays.
<commit_msg>Remove Comment from Code Blocks<commit_after>// Eloquent JavaScript

// Run this file in your terminal using `node my_solution.js`. Make sure it works before moving on!

// Program Structure
// Write your own variable and do something to it.

var number = 5
number *= 2
console.log(number)

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods, and a quirk below.

// Did you learn anything new about JavaScript or programming in general?
//
// JavaScript is entirely new to me, so learning about the history of how it came to be and what it is used for.
// A lot of the fundamental concepts behind programming read similar to what was presented in the Ruby material,
// so I think that learning JavaScript will mainly be about learning the new syntax and flow to achieve the same
// results we've been working towards with Ruby.

// Are there any concepts you feel uncomfortable with?
//
// I'm a little nervous to start working in a new language as I'm still getting the hang of Ruby, but I think
// there should be enough similarities to help make this understandable.

// Identify two similarities and two differences between JavaScript and Ruby syntax with regard to numbers,
// arithmetic, strings, booleans, and various operators.
//
// After reading this chapter, I feel pretty good about the similarities between JavaScript and Ruby operators.
// There are quite a few similarities. First off, all of the basic arithmetic and boolean operators between JS
// and Ruby are the same - && always means "and", % means modulus, != means not equal to, etc. Strings also operate
// in the same manner in both languages. You can concatenate strings together using addition in JS, just like in
// Ruby. However, there are also a few key differences to keep in mind. If we tried to add a string and a number
// together in Ruby, we would receive a type error that would let us know we used the wrong type of variable in our
// code. In JS, it will automatically try to convert the "wrong" variable to the "right" type, giving us a possibly
// unexpected result while not displaying an error. Therefore, type errors can be much harder to diagnose in JS than
// in Ruby. The other major difference is that we receive an extra set of operators to check for true equivalencies
// without any type conversion. We can use === and !== (note the extra equal signs) to check to see if the precise
// values on both sides of the equation are truly equal.

// What is an expression?
//
// An expression is simply a fragment of code that produces a value. This value does not need to be stored or
// used anywhere else - an expression simply generates a value.

// What is the purpose of semicolons in JavaScript? Are they always required?
//
// A semicolon signifies the end of a statement at the end of the line, so the next line is treated as a new
// statement. Semicolons are not always required, but the cases in which you can safely omit them is not
// readily apparent. It is safer to end a statement with a semicolon to acheive the desired result.

// What causes a variable to return undefined?
//
// A variable will return undefined if you first define a variable without assigning an expression to it.
// Calling the variable will work because it exists, but will then return undefined because it is empty.
// This is different than calling a variable that has not been defined yet - in this case, the program
// will throw an error because you are referring to a variable that doesn't actually exist.

// Write your own variable and do something to it in the eloquent.js file.

var number = 5
number *= 2
console.log(number)

// What does console.log do and when would you use it? What Ruby method(s) is this similar to?
//
// console.log provides a value for some form of text output. When running node.js from the command
// line, that text output will occur in the shell. In a browser, though, that output will occur within
// the browser itself and can be viewed through the developer tools. Console.log is for when you need to
// display a value in readable format. In this way, it is similar to the puts or print command in Ruby.

// Write a short program that asks for a user to input their favorite food. After they hit return,
// have the program respond with "Hey! That's my favorite too!" (You will probably need to run this
// in the Chrome console (Links to an external site.) rather than node since node does not support
// prompt or alert). Paste your program into the eloquent.js file.

prompt("What's your favorite food?")
console.log("Hey, that's my favorite too!")

// Describe while and for loops
//
// A while loop allows a loop to iterate until a given condition is met. A for loop will iterate
// for as many times as specified in a for statement. This allows two different type of break conditions.
// The for loop will run for specified set of iterations, and the while loop will run for some
// unspecified time until the condition is met. Both types are useful depending on the function
// of the loop.

// What other similarities or differences between Ruby and JavaScript did you notice in this section?
//
// JavaScript has a new special number, NaN, that stands for Not a Number. This can be generated by running
// a mathematical equation such as x / 0 or Infinity - Infinity, where the answer isn't precise or meaninful.
// In Ruby, this would normally generate an error instead. JavaScript has a function isNaN to check for this
// and return true if NaN is found. This means there is a specific function to handle Nan errors inside the code
// rather than rewriting the structure within Ruby to avoid NaN errors altogether.

// Complete at least one of the exercises (Looping a Triangle, FizzBuzz, of Chess Board) in the eloquent.js file.
//
// Looping Triangle
row = "#";
while(row.length <= 7) {
	console.log(row);
	row += "#";
}

// FizzBuzz
for (var counter = 1; counter <= 100; counter++)
	if (counter % 3 == 0 && counter % 5 == 0)
		console.log("FizzBuzz");
	else if (counter % 3 == 0)
		console.log("Fizz");
	else if (counter % 5 == 0)
		console.log("Buzz");
	else
		console.log(counter);

// Chessboard

var board = "";
var size = 8;
for (var row = 1; row <= size; row++) {
	for (var counter = 1; counter <= 8; counter ++) {
		if (board.length % 2 == 0)
			board = board + "#";
		else
			board = board + "_";
	}
	board = board + "\n";
}

console.log(board)

// What are the differences between local and global variables in JavaScript?
//
// Local variables are variables that are declared within functions, while global variables
// are declared outside of functions. Global variables can be used anywhere within the program.
// For instance, if you declared the variable "number" outside a function, you could refer to it
// within a function by calling "number" itself. However, you could also declare a local variable
// within the function also called number using the var "number" syntax. This local variable will
// only be used within the function and will not overwrite the global variable.

// When should you use functions?
//
// Functions work very similarly to methods in Ruby. You should use a function to create a block of
// code that can be executed multiple times without having to type out that block each and every
// time you want to call it.

// What is a function declaration?
//
// A function declaration is declaring a variable and assigning a function expression to it. The function
// expression is specified by starting with a function keyword followed by the expression that generates
// the value of the function. This can be written shorthand by leading with the function keyword, removing
// the need for a variable declaration.

// Complete the minimum exercise in the eloquent.js file.

function min(number1, number2) {
	if (number1 <= number2)
		return number1;
	else
		return number2;
}

console.log(min(0,-10))
console.log(min(6,3))
console.log(min(10,10))

// What is the difference between using a dot and a bracket to look up a property? Ex. array.max vs array["max"]
//
// While each of these approaches allow you to look up a property, they will not necessary return the same property.
// The difference is that using array.max will specifically return the .max property as long as it is a valid property.
// When using brackets, the variable "max" will be evaluated first and a different property will be returned. In this
// example, what this means is the .max variable will return the maximum value in an array, while the ["max"] variable
// will evaluate the value in the array stored under the "max" index and return that instead.

// Create an object called me that stores your name, age, three favorite foods, and a quirk in your eloquent.js file.
var me = {
	name: "Zach Barton",
	age: 32,
	fav_foods: ["Pork Belly Ramen", "Pie", "Sausage Pizza"],
	quirk: "I design board games."
}

console.log(me.fav_foods)

// What is a JavaScript object with a name and value property similar to in Ruby?
//
// The above object we defined is very similar to a hash in Ruby. We've created a data structure with
// key-value pairs, where the values can be any type of value, including strings, integers, and arrays.
<|endoftext|>


<commit_before>// Eloquent JavaScript
/*
Introduction

	Did you learn anything new about JavaScript or programming in general?
		Not really. It was a good refresher to see how far we've come
		in programming, but overall, I am familiar with the concepts presented.

	Are there any concepts you feel uncomfortable with?
		Nope, I'm good so far. This book is fairly well written and I hope it is
		just as informative in future chapters.

Ch. 1: Values, Types, and Operators
	Identify two similarities and two differences between JavaScript and Ruby
	syntax with regard to numbers, arithmetic, strings, booleans, and
	various operators.

		Similarities:
			Unary, Binary, and Ternary operators work in the same way
			and have the same syntax.

			Conditionals work in the same way most of the time.

		Differences:
			While Ruby has some added functionality on its binary operators,
			Javascript has a lot more automatic type conversion and will return
			a result no matter what.

			Javascript has some interesting use cases for && and || determining
			what to return when values are not a simple true/false comparison.
			Ruby, as I know it, does not support this.

Ch. 2: Program Structure
	What is an expression?
		An expression is some code piece that creates some value.

	What is the purpose of semicolons in JavaScript? Are they always required?
		The purpose of semicolons is to separate statements from one another. They
		aren't always required, but it is suggested that you do for sake of
		starting and just-in-case.

	What causes a variable to return undefined?
		If a variable has not been assigned a value beforehand, aka empty, it
		will return the value undefined.

	Write your own variable and do something to it in the eloquent.js file.
		var name = "Kevin"
		name += " Serrano"
		fullname = name

	What does console.log do and when would you use it? What Ruby method(s) is
	this similar to?
		console.log prints out the output of a statement to the browser's
		developer console. This is similar to Ruby's "puts" method.

	Write a short program that asks for a user to input their favorite food.
	After they hit return, have the program respond with "Hey! That's my
	favorite too!" (You will probably need to run this in the Chrome console
	rather than node since node does not support
	prompt or alert). Paste your program into the eloquent.js file.

		food = prompt("What's your favorite food?")
		console.log("Hey, " + food +  " is/are my favorite food too!")

	Describe while and for loops
		While loops run a specified code block repeatedly until a certain condition
		is met. For loops are similar except that the iteration logic is handled
		within the for-loop delcaration itself.

	What other similarities or differences between Ruby and JavaScript did you
	notice in this section?
		While loops seem to be the same, as are the basic structure of if/else if/
		else statements. Breaks seem the same, and some incrementation syntax
		is similar too. Some differences are that Javascript has a nicer single
		increment/decrement operator and that the structure of declaring a for
		loop is different. Comments are similar too, though block comments seem
		to be different.

	Complete at least one of the exercises (Looping a Triangle, FizzBuzz,
	of Chess Board) in the eloquent.js file.

	Looping a Triangle:
	-------------------
	var step = "";
	for (var i = 0; i < 7; i++) {
	  step += "#";
	  console.log(step);
	};

	FizzBuzz:
	---------
	for (var i = 1; i <= 100; i++) {
		if i % 3 == 0 && i % 5 == 0
			console.log("FizzBuzz");
		else if i % 3 == 0
			console.log("Fizz");
		else if i % 5 == 0
			console.log("Buzz");
		else
			console.log(i);
	};

	Chess Board:
	------------
	var size = 8;
	var string = ""
	var start = true
	for (y = 0; y < size; y++) {
		begin = start
		for (var x = 0; x < size; x++) {
			begin ? (string += "O") : (string += "X")
			begin = !begin
		}
		string += "\n"
		start = !start
	}
	console.log(string)

Ch. 3: Functions (Skip the sections on closure and recursion)
	What are the differences between local and global variables in JavaScript?
		The differences between local and global variables:
			-Local variables are only usable within a function and only exist
			when a function is executing. Every time a function executes,
			that local variable will be instantiated anew.
			-Global variables are variables defined outside of a function,
			which can be accessed and modified by any other function within
			the scope of that program.

	When should you use functions?
		You should use functions when you need to use a certain block of code
		over and over, especially for different inputs. They help to keep your
		code concise and follows DRY principals.

	What is a function declaration?
		A function decalration is a statement that defines a variable to point
		at a given function. Function declrations are outside of the top-down
		execution of a normal program.

	Complete the minimum exercise in the eloquent.js file.

	MINIMUM:
	--------
	function min(x,y) {
		if (x <= y) {
	    	return x
	    }; return y;
	}

	RECURSION:
	---------
	function isEven(number) {
	  if (number < 0) {
	    number = -number
	  }
	  if (number == 0) {
	    return true;
	  } else if (number == 1) {
	    return false;
	  } else return isEven(number-2);
	};

	BEAN COUNTING:
	--------------
	  function countBs(string) {
	    return countChar(string,"B");
	  };

	  function countChar(string,char) {
	    var count = 0;
	    for (var i = 0; i < string.length; i++) {
	      if (string.charAt(i) == char) {
	          count++;
	      };
	    };
	    return count;
	  };

Ch. 4: Data Structures: Objects and Arrays
	Skip the sections on the Lycanthrope's log, Computing Correlations, and
	sections from Further Arrayology to the Global Object, but read the
	chapter summary.

	What is the difference between using a dot and a bracket to look up a
	property? Ex. array.max vs array["max"]

	Create an object called me that stores your name, age, three favorite foods,
	and a quirk in your eloquent.js file.

	What is a JavaScript object with a name and value property similar to in
	Ruby?

*/
// Program Structure
// Write your own variable and do something to it.

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

// Functions

// Complete the `minimum` exercise.

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods,
// and a quirk below.<commit_msg>"Finish eloquent, finally."<commit_after>// Eloquent JavaScript
/*
Introduction

	Did you learn anything new about JavaScript or programming in general?
		Not really. It was a good refresher to see how far we've come
		in programming, but overall, I am familiar with the concepts presented.

	Are there any concepts you feel uncomfortable with?
		Nope, I'm good so far. This book is fairly well written and I hope it is
		just as informative in future chapters.

Ch. 1: Values, Types, and Operators
	Identify two similarities and two differences between JavaScript and Ruby
	syntax with regard to numbers, arithmetic, strings, booleans, and
	various operators.

		Similarities:
			Unary, Binary, and Ternary operators work in the same way
			and have the same syntax.

			Conditionals work in the same way most of the time.

		Differences:
			While Ruby has some added functionality on its binary operators,
			Javascript has a lot more automatic type conversion and will return
			a result no matter what.

			Javascript has some interesting use cases for && and || determining
			what to return when values are not a simple true/false comparison.
			Ruby, as I know it, does not support this.

Ch. 2: Program Structure
	What is an expression?
		An expression is some code piece that creates some value.

	What is the purpose of semicolons in JavaScript? Are they always required?
		The purpose of semicolons is to separate statements from one another. They
		aren't always required, but it is suggested that you do for sake of
		starting and just-in-case.

	What causes a variable to return undefined?
		If a variable has not been assigned a value beforehand, aka empty, it
		will return the value undefined.

	Write your own variable and do something to it in the eloquent.js file.
		var name = "Kevin"
		name += " Serrano"
		fullname = name

	What does console.log do and when would you use it? What Ruby method(s) is
	this similar to?
		console.log prints out the output of a statement to the browser's
		developer console. This is similar to Ruby's "puts" method.

	Write a short program that asks for a user to input their favorite food.
	After they hit return, have the program respond with "Hey! That's my
	favorite too!" (You will probably need to run this in the Chrome console
	rather than node since node does not support
	prompt or alert). Paste your program into the eloquent.js file.

		food = prompt("What's your favorite food?")
		console.log("Hey, " + food +  " is/are my favorite food too!")

	Describe while and for loops
		While loops run a specified code block repeatedly until a certain condition
		is met. For loops are similar except that the iteration logic is handled
		within the for-loop delcaration itself.

	What other similarities or differences between Ruby and JavaScript did you
	notice in this section?
		While loops seem to be the same, as are the basic structure of if/else if/
		else statements. Breaks seem the same, and some incrementation syntax
		is similar too. Some differences are that Javascript has a nicer single
		increment/decrement operator and that the structure of declaring a for
		loop is different. Comments are similar too, though block comments seem
		to be different.

	Complete at least one of the exercises (Looping a Triangle, FizzBuzz,
	of Chess Board) in the eloquent.js file.

	Looping a Triangle:
	-------------------
	var step = "";
	for (var i = 0; i < 7; i++) {
	  step += "#";
	  console.log(step);
	};

	FizzBuzz:
	---------
	for (var i = 1; i <= 100; i++) {
		if i % 3 == 0 && i % 5 == 0
			console.log("FizzBuzz");
		else if i % 3 == 0
			console.log("Fizz");
		else if i % 5 == 0
			console.log("Buzz");
		else
			console.log(i);
	};

	Chess Board:
	------------
	var size = 8;
	var string = ""
	var start = true
	for (y = 0; y < size; y++) {
		begin = start
		for (var x = 0; x < size; x++) {
			begin ? (string += "O") : (string += "X")
			begin = !begin
		}
		string += "\n"
		start = !start
	}
	console.log(string)

Ch. 3: Functions (Skip the sections on closure and recursion)
	What are the differences between local and global variables in JavaScript?
		The differences between local and global variables:
			-Local variables are only usable within a function and only exist
			when a function is executing. Every time a function executes,
			that local variable will be instantiated anew.
			-Global variables are variables defined outside of a function,
			which can be accessed and modified by any other function within
			the scope of that program.

	When should you use functions?
		You should use functions when you need to use a certain block of code
		over and over, especially for different inputs. They help to keep your
		code concise and follows DRY principals.

	What is a function declaration?
		A function decalration is a statement that defines a variable to point
		at a given function. Function declrations are outside of the top-down
		execution of a normal program.

	Complete the minimum exercise in the eloquent.js file.

	MINIMUM:
	--------
	function min(x,y) {
		if (x <= y) {
	    	return x
	    }; return y;
	}

	RECURSION:
	---------
	function isEven(number) {
	  if (number < 0) {
	    number = -number
	  }
	  if (number == 0) {
	    return true;
	  } else if (number == 1) {
	    return false;
	  } else return isEven(number-2);
	};

	BEAN COUNTING:
	--------------
	  function countBs(string) {
	    return countChar(string,"B");
	  };

	  function countChar(string,char) {
	    var count = 0;
	    for (var i = 0; i < string.length; i++) {
	      if (string.charAt(i) == char) {
	          count++;
	      };
	    };
	    return count;
	  };

Ch. 4: Data Structures: Objects and Arrays
	What is the difference between using a dot and a bracket to look up a
	property? Ex. array.max vs array["max"]
		Calling properties using dot notation requires that the attribute being
		called must be a valid variable name for the property. However, using
		bracket notation first evaluates the expression within the square
		brackets, and then proceeds to use that result as the lookup.

	Create an object called me that stores your name, age, three favorite foods,
	and a quirk in your eloquent.js file.
		var me = {
			name: "Kevin Serrano",
			age: "22",
			favorite_foods: ["carbonara","tea","toffee scones"]
			quirk: "I went to Dev Bootcamp in person for my online interview."
		}

	What is a JavaScript object with a name and value property similar to in
	Ruby?
		A hash.

*/
// Program Structure
// Write your own variable and do something to it.

var name = "Kevin"
name += " Serrano"
fullname = name

// Complete one of the exercises: Looping a Triangle, FizzBuzz, or Chess Board

var step = "";
for (var i = 0; i < 7; i++) {
  step += "#";
  console.log(step);
};

for (var i = 1; i <= 100; i++) {
	if i % 3 == 0 && i % 5 == 0
		console.log("FizzBuzz");
	else if i % 3 == 0
		console.log("Fizz");
	else if i % 5 == 0
		console.log("Buzz");
	else
		console.log(i);
};

var size = 8;
var string = ""
var start = true
for (y = 0; y < size; y++) {
	begin = start
	for (var x = 0; x < size; x++) {
		begin ? (string += "O") : (string += "X")
		begin = !begin
	}
	string += "\n"
	start = !start
}
console.log(string)

// Functions

// Complete the `minimum` exercise.
function min(x,y) {
	if (x <= y) {
    	return x
    }; return y;
}

// Data Structures: Objects and Arrays
// Create an object called "me" that stores your name, age, 3 favorite foods,
// and a quirk below.
var me = {
	name: "Kevin Serrano",
	age: "22",
	favorite_foods: ["carbonara","tea","toffee scones"]
	quirk: "I went to Dev Bootcamp in person for my online interview."
}<|endoftext|>


<commit_before>sb.include('Element.prototype.makeDraggable');
sb.include('Element.prototype.getPosition');
sb.include('Element.prototype.mv');
sb.include('Element.prototype.wh');
sb.include('Element.prototype.hide');
sb.include('Element.prototype.show');
sb.include('Element.prototype.isWithin');

sb.widget.floatWin = function(params){
	sb.objects.infuse(params, this);
	this.createBox();
};

sb.widget.floatWin.prototype = {
	createBox : function(){

		var self = this;
		this.win = new sb.element({
			tag : 'div',
			className : 'sb_floatWin '+this.className || ''
		});

		this.titleBar = new sb.element({
			tag : 'div',
			className : 'sb_floatWinTitleBar dragHandle',
			onselectstart : function() {
				return false;
			},
			unselectable : "on",
			styles : {
				MozUserSelect : 'none'
			}
		});

		this.titleIcons = new sb.element({
			tag : 'div',
			className : 'sb_floatWinTitleIcons',
			styles : {
				cssFloat : 'right',
				styleFloat : 'right',
				textAlign : 'right'
			}
		});

		this.titleText = new sb.element({
			tag : 'div',
			className : 'sb_floatWinTitleText dragHandle',
			innerHTML : 'title',
			shaded : 0
		});

		this.content = new sb.element({
			tag : 'div',
			className : 'sb_floatWinContent'
		});

		this.win.events({
			click : function(e){
				var target = e.target;

				if(target.isWithin(self.content)){
					self.onContentClick(e);
				} else {
					if(target.isWithin(self.titleBar)){
						self.onTitleBarClick(e);
					}

					if(target.nodeName == 'IMG' && target.isWithin(self.titleIcons)){
						self.onIconClick(e);
					}
				}

			},
			dblclick : function(e){

				if(e.target == self.titleText || e.target.isWithin(self.titleText)){
					if(this.shaded){

						this.style.height = '';
						this.style.overflow = 'auto';
						this.shaded=0;

					} else {

						this.oldHeight = this.style.height;
						this.style.height = self.titleBar.offsetHeight+'px';
						this.style.overflow ='hidden';
						this.shaded=1;
					}
				}

			}
		});

		this.win.mv(sb.browser.w/2,sb.browser.h/2,999);

		this.titleBar.appendTo(this.win);
		this.titleIcons.appendTo(this.titleBar);
		this.titleText.appendTo(this.titleBar);
		this.content.appendTo(this.win);
		this.win.makeDraggable();

		if(this.closeButton){
			this.addIcon(new sb.element({
				tag : 'img',
				src : sb.base+'_media/close.png',
				onclick : function(){
					self.close();
				}
			}));
		}

		if(typeof this.title =='string'){
			this.setTitle(this.title);
		}

	},

	closeButton : true,

	addContent : function(content){
		var typ = sb.typeOf(content);
		if(typ == 'string'){
			this.content.innerHTML = content;
		} else if(typ =='sb.element'){
			content.appendTo(this.content);
		}
	},

	addIcon : function(el){

		if(sb.typeOf(el)=='sb.element'){
			el.win=this;
			el.style.cursor = 'pointer';
			return el.appendToTop(this.titleIcons);
		} else if(sb.typeOf(el) == 'string'){
			return new sb.element({tag : 'img', src : el}).appendToTop(this.titleIcons);
		}
	},

	clearContent : function(){
		this.content.innerHTML ='';
	},

	close : function(){
		this.onClose();
		this.win.hide();
	},

	show : function(){
		this.win.show();
		this.titleText.style.backgroundColor = this.titleBar.getStyle('backgroundColor');

	},

	maximize : function(){
		this.win.origW = this.win.offsetWidth;
		this.win.origH = this.win.offsetHeight;
		this.win.origX = this.win.offsetLeft;
		this.win.origY = this.win.offsetTop;

		this.win.mv(0,0,999);
		this.win.wh(sb.browser.w, sb.browser.h);
	},

	minimize : function(){
		this.win.origW = this.win.offsetWidth;
		this.win.origH = this.win.offsetHeight;
		this.win.origX = this.win.offsetLeft;
		this.win.origY = this.win.offsetTop;

		var titleHeight=this.titleBar.offsetHeight;
		titleHeight += parseInt(this.titleBar.getStyle('margin'), 10);
		titleHeight += parseInt(this.titleBar.getStyle('padding'), 10);

		this.win.mv(0,sb.browser.h-(titleHeight+18),999);
		this.win.wh(this.offsetWidth, titleHeight);
		this.win.style.overflow='hidden';
	},

	mv : function(x,y,z){
		this.win.mv(x,y,z);
	},

	wh : function(w,h){
		this.win.wh(w,h);
	},

	restore : function(){

		this.win.wh(this.win.origW, this.win.origH);
		this.win.mv(this.win.origX, this.win.origY, 999);
		this.win.style.overflow='';
	},

	setTitle : function(txt){

		this.titleText.innerHTML=txt;
	},
	onTitleBarClick : function(e){},
	onContentClick : function(e){},
	onIconClick : function(e){},
	onClose : function(e){}
};

<commit_msg>added onClick event to floatWin<commit_after>sb.include('Element.prototype.makeDraggable');
sb.include('Element.prototype.getPosition');
sb.include('Element.prototype.mv');
sb.include('Element.prototype.wh');
sb.include('Element.prototype.hide');
sb.include('Element.prototype.show');
sb.include('Element.prototype.isWithin');

sb.widget.floatWin = function(params){
	sb.objects.infuse(params, this);
	this.createBox();
};

sb.widget.floatWin.prototype = {
	createBox : function(){

		var self = this;
		this.win = new sb.element({
			tag : 'div',
			className : 'sb_floatWin '+this.className || ''
		});

		this.titleBar = new sb.element({
			tag : 'div',
			className : 'sb_floatWinTitleBar dragHandle',
			onselectstart : function() {
				return false;
			},
			unselectable : "on",
			styles : {
				MozUserSelect : 'none'
			}
		});

		this.titleIcons = new sb.element({
			tag : 'div',
			className : 'sb_floatWinTitleIcons',
			styles : {
				cssFloat : 'right',
				styleFloat : 'right',
				textAlign : 'right'
			}
		});

		this.titleText = new sb.element({
			tag : 'div',
			className : 'sb_floatWinTitleText dragHandle',
			innerHTML : 'title',
			shaded : 0
		});

		this.content = new sb.element({
			tag : 'div',
			className : 'sb_floatWinContent'
		});

		this.win.events({
			click : function(e){
				var target = e.target;
				self.onClick(e);
				if(target.isWithin(self.content)){
					self.onContentClick(e);
				} else {

					if(target.isWithin(self.titleBar)){
						self.onTitleBarClick(e);
					}
					if(target.nodeName == 'IMG' && target.isWithin(self.titleIcons)){
						self.onIconClick(e);
					}

				}

			},
			dblclick : function(e){

				if(e.target == self.titleText || e.target.isWithin(self.titleText)){
					if(this.shaded){

						this.style.height = '';
						this.style.overflow = 'auto';
						this.shaded=0;

					} else {

						this.oldHeight = this.style.height;
						this.style.height = self.titleBar.offsetHeight+'px';
						this.style.overflow ='hidden';
						this.shaded=1;
					}
				}

			}
		});

		this.win.mv(sb.browser.w/2,sb.browser.h/2,999);

		this.titleBar.appendTo(this.win);
		this.titleIcons.appendTo(this.titleBar);
		this.titleText.appendTo(this.titleBar);
		this.content.appendTo(this.win);
		this.win.makeDraggable();

		if(this.closeButton){
			this.addIcon(new sb.element({
				tag : 'img',
				src : sb.base+'_media/close.png',
				onclick : function(){
					self.close();
				}
			}));
		}

		if(typeof this.title =='string'){
			this.setTitle(this.title);
		}

	},

	closeButton : true,

	addContent : function(content){
		var typ = sb.typeOf(content);
		if(typ == 'string'){
			this.content.innerHTML = content;
		} else if(typ =='sb.element'){
			content.appendTo(this.content);
		}
	},

	addIcon : function(el){

		if(sb.typeOf(el)=='sb.element'){
			el.win=this;
			el.style.cursor = 'pointer';
			return el.appendToTop(this.titleIcons);
		} else if(sb.typeOf(el) == 'string'){
			return new sb.element({tag : 'img', src : el}).appendToTop(this.titleIcons);
		}
	},

	clearContent : function(){
		this.content.innerHTML ='';
	},

	close : function(){
		this.onClose();
		this.win.hide();
	},

	show : function(){
		this.win.show();
		this.titleText.style.backgroundColor = this.titleBar.getStyle('backgroundColor');

	},

	maximize : function(){
		this.win.origW = this.win.offsetWidth;
		this.win.origH = this.win.offsetHeight;
		this.win.origX = this.win.offsetLeft;
		this.win.origY = this.win.offsetTop;

		this.win.mv(0,0,999);
		this.win.wh(sb.browser.w, sb.browser.h);
	},

	minimize : function(){
		this.win.origW = this.win.offsetWidth;
		this.win.origH = this.win.offsetHeight;
		this.win.origX = this.win.offsetLeft;
		this.win.origY = this.win.offsetTop;

		var titleHeight=this.titleBar.offsetHeight;
		titleHeight += parseInt(this.titleBar.getStyle('margin'), 10);
		titleHeight += parseInt(this.titleBar.getStyle('padding'), 10);

		this.win.mv(0,sb.browser.h-(titleHeight+18),999);
		this.win.wh(this.offsetWidth, titleHeight);
		this.win.style.overflow='hidden';
	},

	mv : function(x,y,z){
		this.win.mv(x,y,z);
	},

	wh : function(w,h){
		this.win.wh(w,h);
	},

	restore : function(){

		this.win.wh(this.win.origW, this.win.origH);
		this.win.mv(this.win.origX, this.win.origY, 999);
		this.win.style.overflow='';
	},

	setTitle : function(txt){

		this.titleText.innerHTML=txt;
	},
	onTitleBarClick : function(e){},
	onContentClick : function(e){},
	onIconClick : function(e){},
	onClose : function(e){}
};

<|endoftext|>