<commit_before>var formfiller = new FormFiller();
formfiller.loadForm();

/**
 * FormFiller
 *
 * Main FormFiller class, which handles all requests
 * @returns {FormFiller}
 */
function FormFiller() {

    var _version = '0.1.1';
    var _context = this;
    this.jsCode = 'javascript:/* Created With FormFiller v'+_version+' */var d=document, e=new Event(\'change\');function i(a){return d.getElementById(a)}function n(a){return d.getElementsByName(a)}';

    this.loadForm = function () {
        _loadJQuery();
    };

    var _loadJQuery = function () {
        if (typeof jQuery === 'undefined') {
            new Loader().script('//code.jquery.com/jquery-1.11.1.min.js', function(context){context.doLoadForm();}, _context);
        } else {
            _context.doLoadForm();
        }
    };

    this.doLoadForm = function () {
        var html = '

Form Filler v'+_version+'

<input id="formfiller-bookmarkletname" style="margin-bottom:18px" value="'+document.title+'"> <input type="button" value="Save" onclick="javascript:formfiller.save();return false;">

 Click and drag this link to the bookmarks bar: My bookmarklet
×

';
        jQuery('body').append(html);
    };

    this.save = function() {
        jQuery('form input:not(:hidden,:radio,:checkbox,:submit), form textarea, form select, form input[type="radio"]:checked, form input[type="checkbox"]:checked').each(function(){
            if(jQuery(this).attr('name') !== undefined){
                var attrName = jQuery(this).attr('name');
                var attrId = jQuery(this).attr('id');

                if((attrName.indexOf('[]') >= 0) || (jQuery.inArray(jQuery(this).attr('type'), ['radio', 'checkbox']) >= 0)){
                    // Handle checkboxes and radio buttons
                    formfiller.jsCode += 'i("'+attrId+'").checked=true;i("'+attrId+'").dispatchEvent(e);';
                } else {
                    // Set field value
                    formfiller.jsCode += 'n("'+attrName+'")[0].value="'+jQuery(this).val()+'";n("'+attrName+'")[0].dispatchEvent(e);';
                }
            }
        });
        this.jsCode += 'console.log("FormFiller: Form Repopulated.");';
        jQuery('#bookmarklet').attr('href', this.jsCode + 'void(0);').html(jQuery('#formfiller-bookmarkletname').val()).parent('p').show();
        jQuery('#formfiller-formwrapper').hide();
    };

}

/**
 * Loader
 *
 * Class for loading external files
 * Supported tags:
 *   - script
 *   - link
 * @returns {Loader}
 */
function Loader() {

    var TYPE = {
        SCRIPT: 'script'
    };

    var _fileLoaded = false;
    var _callback = null;
    var _context = null;

    this.script = function (url, callback, context) {
        _callback = callback;
        _context = context;
        _appendNewElementToBody(
            TYPE.SCRIPT
            , {
                src: url
                , type: 'text/javascript'
            }
        );
        _cleanup();
    };

    var _appendNewElementToBody = function (type, attrs) {
        _getFirstElementByTagName('body').appendChild(_createElement(type, attrs));
    };

    var _getFirstElementByTagName = function (name) {
        return document.getElementsByTagName(name)[0];
    };

    var _createElement = function (type, attrs) {
        var element = document.createElement(type);

        for (var key in attrs) {
            element.setAttribute(key, attrs[key]);
        }

        element.onload = element.onreadystatechage = function () {
            if (!_fileLoaded && (!this.readyState || ['loaded', 'complete'].indexOf(this.readyState) !== -1)) {
                _fileLoaded = true;
                element.onload = element.onreadystatechange = null;
                _getFirstElementByTagName('body').removeChild(element);
                _callback(_context);
            }
        };

        return element;
    };

    var _cleanup = function () {
        _fileLoaded = false;
    };

}
<commit_msg>Version bump<commit_after>var formfiller = new FormFiller();
formfiller.loadForm();

/**
 * FormFiller
 *
 * Main FormFiller class, which handles all requests
 * @returns {FormFiller}
 */
function FormFiller() {

    var _version = '0.1.2';
    var _context = this;
    this.jsCode = 'javascript:/* Created With FormFiller v'+_version+' */var d=document, e=new Event(\'change\');function i(a){return d.getElementById(a)}function n(a){return d.getElementsByName(a)}';

    this.loadForm = function () {
        _loadJQuery();
    };

    var _loadJQuery = function () {
        if (typeof jQuery === 'undefined') {
            new Loader().script('//code.jquery.com/jquery-1.11.1.min.js', function(context){context.doLoadForm();}, _context);
        } else {
            _context.doLoadForm();
        }
    };

    this.doLoadForm = function () {
        var html = '

Form Filler v'+_version+'

<input id="formfiller-bookmarkletname" style="margin-bottom:18px" value="'+document.title+'"> <input type="button" value="Save" onclick="javascript:formfiller.save();return false;">

 Click and drag this link to the bookmarks bar: My bookmarklet
×

';
        jQuery('body').append(html);
    };

    this.save = function() {
        jQuery('form input:not(:hidden,:radio,:checkbox,:submit), form textarea, form select, form input[type="radio"]:checked, form input[type="checkbox"]:checked').each(function(){
            if(jQuery(this).attr('name') !== undefined){
                var attrName = jQuery(this).attr('name');
                var attrId = jQuery(this).attr('id');

                if((attrName.indexOf('[]') >= 0) || (jQuery.inArray(jQuery(this).attr('type'), ['radio', 'checkbox']) >= 0)){
                    // Handle checkboxes and radio buttons
                    formfiller.jsCode += 'i("'+attrId+'").checked=true;i("'+attrId+'").dispatchEvent(e);';
                } else {
                    // Set field value
                    formfiller.jsCode += 'n("'+attrName+'")[0].value="'+jQuery(this).val()+'";n("'+attrName+'")[0].dispatchEvent(e);';
                }
            }
        });
        this.jsCode += 'console.log("FormFiller: Form Repopulated.");';
        jQuery('#bookmarklet').attr('href', this.jsCode + 'void(0);').html(jQuery('#formfiller-bookmarkletname').val()).parent('p').show();
        jQuery('#formfiller-formwrapper').hide();
    };

}

/**
 * Loader
 *
 * Class for loading external files
 * Supported tags:
 *   - script
 *   - link
 * @returns {Loader}
 */
function Loader() {

    var TYPE = {
        SCRIPT: 'script'
    };

    var _fileLoaded = false;
    var _callback = null;
    var _context = null;

    this.script = function (url, callback, context) {
        _callback = callback;
        _context = context;
        _appendNewElementToBody(
            TYPE.SCRIPT
            , {
                src: url
                , type: 'text/javascript'
            }
        );
        _cleanup();
    };

    var _appendNewElementToBody = function (type, attrs) {
        _getFirstElementByTagName('body').appendChild(_createElement(type, attrs));
    };

    var _getFirstElementByTagName = function (name) {
        return document.getElementsByTagName(name)[0];
    };

    var _createElement = function (type, attrs) {
        var element = document.createElement(type);

        for (var key in attrs) {
            element.setAttribute(key, attrs[key]);
        }

        element.onload = element.onreadystatechage = function () {
            if (!_fileLoaded && (!this.readyState || ['loaded', 'complete'].indexOf(this.readyState) !== -1)) {
                _fileLoaded = true;
                element.onload = element.onreadystatechange = null;
                _getFirstElementByTagName('body').removeChild(element);
                _callback(_context);
            }
        };

        return element;
    };

    var _cleanup = function () {
        _fileLoaded = false;
    };

}
<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('torpedo:Game');
var format = require('util').format;

var Grid = require('./Grid');
var Field = require('./Field');

var TURN_MYSELF = 1;
var TURN_ENEMY = 2;

class Game {
    /**
     * @param {Platform} platform
     * @param {StrategyInterface} strategy
     */
    constructor(platform, strategy) {
        this._platform = platform;
        this._strategy = strategy;

        debug('new game created');
    }

    play() {
        this._platform
            .on('turn', this._turn)
            .trigger('ready');
    }

    _turn () {
        var target = null;
        var grid = this._platform.getEnemyGrid();

        debug('finding fields to frag an already hit ship..');
        var finishingFields = this._findFinishingFields(grid);
        if (finishingFields.length) {
            debug('found %d finishing fields', finishingFields.length);
            target = finishingFields.shift();
        } else {
            debug('no finishing fields found, getting target by strategy');
            target = this._strategy.getTargetField(grid);
        }

        if (target) {
            debug('shooting at %d/%d', target.getX(), target.getY());
            this._platform.shootAt(target);
        } else {
            debug('no target found, is the game over?');
        }
    }

    _findFinishingFields (grid) {
        var finishingFields = [];
        var hit = grid.getFieldsByState(Field.STATE.HIT);
        hit.forEach(field => {
            finishingFields = finishingFields.concat(
                grid.getFieldNeighbors(field)
                    .filter(neighbor => {
                        return this._isShootable(grid, neighbor);
                    })
            );
        });

        finishingFields.sort((a, b) => {
            return grid.getFieldNeighborsByState(b, Field.STATE.HIT, 2).length - grid.getFieldNeighborsByState(a, Field.STATE.HIT, 2).length;
        });

        return finishingFields;
    }

    _isShootable(grid, field) {
        return field.getState() === Field.STATE.UNKNOWN && grid.getFieldNeighbors(field).filter(neighbor => {
            return neighbor.getState() >= Field.STATE.SUNK;
        }).length === 0;
    }
}

module.exports = Game;<commit_msg>it's not trigger, it's emit<commit_after>'use strict';

var debug = require('debug')('torpedo:Game');
var format = require('util').format;

var Grid = require('./Grid');
var Field = require('./Field');

var TURN_MYSELF = 1;
var TURN_ENEMY = 2;

class Game {
    /**
     * @param {Platform} platform
     * @param {StrategyInterface} strategy
     */
    constructor(platform, strategy) {
        this._platform = platform;
        this._strategy = strategy;

        debug('new game created');
    }

    play() {
        this._platform
            .on('turn', this._turn)
            .emit('ready');
    }

    _turn () {
        var target = null;
        var grid = this._platform.getEnemyGrid();

        debug('finding fields to frag an already hit ship..');
        var finishingFields = this._findFinishingFields(grid);
        if (finishingFields.length) {
            debug('found %d finishing fields', finishingFields.length);
            target = finishingFields.shift();
        } else {
            debug('no finishing fields found, getting target by strategy');
            target = this._strategy.getTargetField(grid);
        }

        if (target) {
            debug('shooting at %d/%d', target.getX(), target.getY());
            this._platform.shootAt(target);
        } else {
            debug('no target found, is the game over?');
        }
    }

    _findFinishingFields (grid) {
        var finishingFields = [];
        var hit = grid.getFieldsByState(Field.STATE.HIT);
        hit.forEach(field => {
            finishingFields = finishingFields.concat(
                grid.getFieldNeighbors(field)
                    .filter(neighbor => {
                        return this._isShootable(grid, neighbor);
                    })
            );
        });

        finishingFields.sort((a, b) => {
            return grid.getFieldNeighborsByState(b, Field.STATE.HIT, 2).length - grid.getFieldNeighborsByState(a, Field.STATE.HIT, 2).length;
        });

        return finishingFields;
    }

    _isShootable(grid, field) {
        return field.getState() === Field.STATE.UNKNOWN && grid.getFieldNeighbors(field).filter(neighbor => {
            return neighbor.getState() >= Field.STATE.SUNK;
        }).length === 0;
    }
}

module.exports = Game;<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import {
  Animated,
  InteractionManager,
  Platform,
  StyleSheet,
  View,
} from 'react-native';

import ActionSheet from '@exponent/react-native-action-sheet';
import dismissKeyboard from 'react-native-dismiss-keyboard';
import moment from 'moment/min/moment-with-locales.min';

import Actions from './Actions';
import Avatar from './Avatar';
import Bubble from './Bubble';
import MessageImage from './MessageImage';
import MessageText from './MessageText';
import Composer from './Composer';
import Day from './Day';
import InputToolbar from './InputToolbar';
import LoadEarlier from './LoadEarlier';
import Message from './Message';
import MessageContainer from './MessageContainer';
import Send from './Send';
import Time from './Time';

// Min and max heights of ToolbarInput and Composer
// Needed for Composer auto grow and ScrollView animation
// TODO move these values to Constants.js (also with used colors #b2b2b2)
const MIN_COMPOSER_HEIGHT = Platform.select({
  ios: 33,
  android: 41,
});
const MAX_COMPOSER_HEIGHT = 100;
const MIN_INPUT_TOOLBAR_HEIGHT = 44;

class GiftedChat extends Component {
  constructor(props) {
    super(props);

    // default values
    this._isMounted = false;
    this._keyboardHeight = 0;
    this._maxHeight = null;
    this._touchStarted = false;
    this._isTypingDisabled = false;
    this._locale = 'en';
    this._messages = [];

    this.state = {
      isInitialized: false, // initialization will calculate maxHeight before rendering the chat
    };

    this.onTouchStart = this.onTouchStart.bind(this);
    this.onTouchMove = this.onTouchMove.bind(this);
    this.onTouchEnd = this.onTouchEnd.bind(this);
    this.onKeyboardWillShow = this.onKeyboardWillShow.bind(this);
    this.onKeyboardWillHide = this.onKeyboardWillHide.bind(this);
    this.onKeyboardDidShow = this.onKeyboardDidShow.bind(this);
    this.onKeyboardDidHide = this.onKeyboardDidHide.bind(this);
    this.onType = this.onType.bind(this);
    this.onSend = this.onSend.bind(this);
    this.getLocale = this.getLocale.bind(this);

    this.invertibleScrollViewProps={
          inverted: true,
          keyboardShouldPersistTaps: true,
          onTouchStart: this.onTouchStart,
          onTouchMove: this.onTouchMove,
          onTouchEnd: this.onTouchEnd,
          onKeyboardWillShow: this.onKeyboardWillShow,
          onKeyboardWillHide: this.onKeyboardWillHide,
          onKeyboardDidShow: this.onKeyboardDidShow,
          onKeyboardDidHide: this.onKeyboardDidHide,
      };
  }

  static append(currentMessages = [], messages) {
    if (!Array.isArray(messages)) {
      messages = [messages];
    }
    return messages.concat(currentMessages);
  }

  static prepend(currentMessages = [], messages) {
    if (!Array.isArray(messages)) {
      messages = [messages];
    }
    return currentMessages.concat(messages);
  }

  getChildContext() {
    return {
      actionSheet: () => this._actionSheetRef,
      getLocale: this.getLocale,
    };
  }

  componentWillMount() {
    this.setIsMounted(true);
    this.initLocale();
    this.initMessages(this.props.messages);
  }

  componentWillUnmount() {
    this.setIsMounted(false);
  }

  componentWillReceiveProps(nextProps) {
    this.initMessages(nextProps.messages);
  }

  initLocale() {
    if (this.props.locale === null || moment.locales().indexOf(this.props.locale) === -1) {
      this.setLocale('en');
    } else {
      this.setLocale(this.props.locale);
    }
  }

  initMessages(messages = []) {
    this.setMessages(messages);
  }

  setLocale(locale) {
    this._locale = locale;
  }

  getLocale() {
    return this._locale;
  }

  setMessages(messages) {
    this._messages = messages;
  }

  getMessages() {
    return this._messages;
  }

  setMaxHeight(height) {
    this._maxHeight = height;
  }

  getMaxHeight() {
    return this._maxHeight;
  }

  setKeyboardHeight(height) {
    this._keyboardHeight = height;
  }

  getKeyboardHeight() {
    return this._keyboardHeight;
  }

  setIsTypingDisabled(value) {
    this._isTypingDisabled = value;
  }

  getIsTypingDisabled() {
    return this._isTypingDisabled;
  }

  setIsMounted(value) {
    this._isMounted = value;
  }

  getIsMounted() {
    return this._isMounted;
  }

  // TODO
  // setMinInputToolbarHeight
  getMinInputToolbarHeight() {
    if (this.props.renderAccessory) {
      return MIN_INPUT_TOOLBAR_HEIGHT * 2;
    }
    return MIN_INPUT_TOOLBAR_HEIGHT;
  }

  prepareMessagesContainerHeight(value) {
    if (this.props.isAnimated === true) {
      return new Animated.Value(value);
    }
    return value;
  }

  onKeyboardWillShow(e) {
    this.setIsTypingDisabled(true);
    this.setKeyboardHeight(e.endCoordinates.height);
    const newMessagesContainerHeight = (this.getMaxHeight() - (this.state.composerHeight + (this.getMinInputToolbarHeight() - MIN_COMPOSER_HEIGHT))) - this.getKeyboardHeight();
    if (this.props.isAnimated === true) {
      Animated.timing(this.state.messagesContainerHeight, {
        toValue: newMessagesContainerHeight,
        duration: 210,
      }).start();
    } else {
      this.setState((previousState) => {
        return {
          messagesContainerHeight: newMessagesContainerHeight,
        };
      });
    }
  }

  onKeyboardWillHide() {
    this.setIsTypingDisabled(true);
    this.setKeyboardHeight(0);
    const newMessagesContainerHeight = this.getMaxHeight() - (this.state.composerHeight + (this.getMinInputToolbarHeight() - MIN_COMPOSER_HEIGHT));
    if (this.props.isAnimated === true) {
      Animated.timing(this.state.messagesContainerHeight, {
        toValue: newMessagesContainerHeight,
        duration: 210,
      }).start();
    } else {
      this.setState((previousState) => {
        return {
          messagesContainerHeight: newMessagesContainerHeight,
        };
      });
    }
  }

  onKeyboardDidShow(e) {
    if (Platform.OS === 'android') {
      this.onKeyboardWillShow(e);
    }
    this.setIsTypingDisabled(false);
  }

  onKeyboardDidHide(e) {
    if (Platform.OS === 'android') {
      this.onKeyboardWillHide(e);
    }
    this.setIsTypingDisabled(false);
  }

  scrollToBottom(animated = true) {
    this._messageContainerRef.scrollTo({
      y: 0,
      animated,
    });
  }

  onTouchStart() {
    this._touchStarted = true;
  }

  onTouchMove() {
    this._touchStarted = false;
  }

  // handle Tap event to dismiss keyboard
  onTouchEnd() {
    if (this._touchStarted === true) {
      dismissKeyboard();
    }
    this._touchStarted = false;
  }

  renderMessages() {
    const AnimatedView = this.props.isAnimated === true ? Animated.View : View;
    return (
      <AnimatedView style={{
        height: this.state.messagesContainerHeight,
      }}>
        <MessageContainer
          {...this.props}

          invertibleScrollViewProps={this.invertibleScrollViewProps}

          messages={this.getMessages()}

          ref={component => this._messageContainerRef = component}
        />
      </AnimatedView>
    );
  }

  onSend(messages = [], shouldResetInputToolbar = false) {
    if (!Array.isArray(messages)) {
      messages = [messages];
    }

    messages = messages.map((message) => {
      return {
        ...message,
        user: this.props.user,
        createdAt: new Date(),
        _id: 'temp-id-' + Math.round(Math.random() * 1000000),
      };
    });

    if (shouldResetInputToolbar === true) {
      this.setIsTypingDisabled(true);
      this.resetInputToolbar();
    }

    this.props.onSend(messages);
    this.scrollToBottom();

    if (shouldResetInputToolbar === true) {
      setTimeout(() => {
        if (this.getIsMounted() === true) {
          this.setIsTypingDisabled(false);
        }
      }, 200);
    }
  }

  resetInputToolbar() {
    this.setState((previousState) => {
      return {
        text: '',
        composerHeight: MIN_COMPOSER_HEIGHT,
        messagesContainerHeight: this.prepareMessagesContainerHeight(this.getMaxHeight() - this.getMinInputToolbarHeight() - this.getKeyboardHeight()),
      };
    });
  }

  calculateInputToolbarHeight(newComposerHeight) {
    return newComposerHeight + (this.getMinInputToolbarHeight() - MIN_COMPOSER_HEIGHT);
  }

  onType(e) {
    if (this.getIsTypingDisabled() === true) {
      return;
    }
    const newComposerHeight = Math.max(MIN_COMPOSER_HEIGHT, Math.min(MAX_COMPOSER_HEIGHT, e.nativeEvent.contentSize.height));
    const newMessagesContainerHeight = this.getMaxHeight() - this.calculateInputToolbarHeight(newComposerHeight) - this.getKeyboardHeight();
    const newText = e.nativeEvent.text;
    this.setState((previousState) => {
      return {
        text: newText,
        composerHeight: newComposerHeight,
        messagesContainerHeight: this.prepareMessagesContainerHeight(newMessagesContainerHeight),
      };
    });
  }

  renderInputToolbar() {
    const inputToolbarProps = {
      ...this.props,
      text: this.state.text,
      composerHeight: Math.max(MIN_COMPOSER_HEIGHT, this.state.composerHeight),
      onChange: this.onType,
      onSend: this.onSend,
    };

    if (this.props.renderInputToolbar) {
      return this.props.renderInputToolbar(inputToolbarProps);
    }
    return (
      <InputToolbar
        {...inputToolbarProps}
      />
    );
  }

  renderLoading() {
    if (this.props.renderLoading) {
      return this.props.renderLoading();
    }
    return null;
  }

  render() {
    if (this.state.isInitialized === true) {
      return (
        <ActionSheet ref={component => this._actionSheetRef = component}>
          <View style={styles.container}>
            {this.renderMessages()}
            {this.renderInputToolbar()}
          </View>
        </ActionSheet>
      );
    }
    return (
      <View
        style={styles.container}
        onLayout={(e) => {
          const layout = e.nativeEvent.layout;
          this.setMaxHeight(layout.height);
          InteractionManager.runAfterInteractions(() => {
            this.setState({
              isInitialized: true,
              text: '',
              composerHeight: MIN_COMPOSER_HEIGHT,
              messagesContainerHeight: this.prepareMessagesContainerHeight(this.getMaxHeight() - this.getMinInputToolbarHeight()),
            });
          });
        }}
      >
        {this.renderLoading()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

GiftedChat.childContextTypes = {
  actionSheet: PropTypes.func,
  getLocale: PropTypes.func,
};

GiftedChat.defaultProps = {
  messages: [],
  onSend: () => {},
  loadEarlier: false,
  onLoadEarlier: () => {},
  locale: null,
  isAnimated: Platform.select({
    ios: true,
    android: false,
  }),
  footer: null,
  renderAccessory: null,
  renderActions: null,
  renderAvatar: null,
  renderBubble: null,
  renderMessageText: null,
  renderMessageImage: null,
  renderComposer: null,
  renderCustomView: null,
  renderDay: null,
  renderInputToolbar: null,
  renderLoadEarlier: null,
  renderLoading: null,
  renderMessage: null,
  renderSend: null,
  renderTime: null,
  user: {},
};

export {
  GiftedChat,
  Actions,
  Avatar,
  Bubble,
  MessageImage,
  MessageText,
  Composer,
  Day,
  InputToolbar,
  LoadEarlier,
  Message,
  Send,
  Time,
};
<commit_msg>code formatting<commit_after>import React, {Component, PropTypes} from 'react';
import {
  Animated,
  InteractionManager,
  Platform,
  StyleSheet,
  View,
} from 'react-native';

import ActionSheet from '@exponent/react-native-action-sheet';
import dismissKeyboard from 'react-native-dismiss-keyboard';
import moment from 'moment/min/moment-with-locales.min';

import Actions from './Actions';
import Avatar from './Avatar';
import Bubble from './Bubble';
import MessageImage from './MessageImage';
import MessageText from './MessageText';
import Composer from './Composer';
import Day from './Day';
import InputToolbar from './InputToolbar';
import LoadEarlier from './LoadEarlier';
import Message from './Message';
import MessageContainer from './MessageContainer';
import Send from './Send';
import Time from './Time';

// Min and max heights of ToolbarInput and Composer
// Needed for Composer auto grow and ScrollView animation
// TODO move these values to Constants.js (also with used colors #b2b2b2)
const MIN_COMPOSER_HEIGHT = Platform.select({
  ios: 33,
  android: 41,
});
const MAX_COMPOSER_HEIGHT = 100;
const MIN_INPUT_TOOLBAR_HEIGHT = 44;

class GiftedChat extends Component {
  constructor(props) {
    super(props);

    // default values
    this._isMounted = false;
    this._keyboardHeight = 0;
    this._maxHeight = null;
    this._touchStarted = false;
    this._isTypingDisabled = false;
    this._locale = 'en';
    this._messages = [];

    this.state = {
      isInitialized: false, // initialization will calculate maxHeight before rendering the chat
    };

    this.onTouchStart = this.onTouchStart.bind(this);
    this.onTouchMove = this.onTouchMove.bind(this);
    this.onTouchEnd = this.onTouchEnd.bind(this);
    this.onKeyboardWillShow = this.onKeyboardWillShow.bind(this);
    this.onKeyboardWillHide = this.onKeyboardWillHide.bind(this);
    this.onKeyboardDidShow = this.onKeyboardDidShow.bind(this);
    this.onKeyboardDidHide = this.onKeyboardDidHide.bind(this);
    this.onType = this.onType.bind(this);
    this.onSend = this.onSend.bind(this);
    this.getLocale = this.getLocale.bind(this);

    this.invertibleScrollViewProps = {
      inverted: true,
      keyboardShouldPersistTaps: true,
      onTouchStart: this.onTouchStart,
      onTouchMove: this.onTouchMove,
      onTouchEnd: this.onTouchEnd,
      onKeyboardWillShow: this.onKeyboardWillShow,
      onKeyboardWillHide: this.onKeyboardWillHide,
      onKeyboardDidShow: this.onKeyboardDidShow,
      onKeyboardDidHide: this.onKeyboardDidHide,
    };
  }

  static append(currentMessages = [], messages) {
    if (!Array.isArray(messages)) {
      messages = [messages];
    }
    return messages.concat(currentMessages);
  }

  static prepend(currentMessages = [], messages) {
    if (!Array.isArray(messages)) {
      messages = [messages];
    }
    return currentMessages.concat(messages);
  }

  getChildContext() {
    return {
      actionSheet: () => this._actionSheetRef,
      getLocale: this.getLocale,
    };
  }

  componentWillMount() {
    this.setIsMounted(true);
    this.initLocale();
    this.initMessages(this.props.messages);
  }

  componentWillUnmount() {
    this.setIsMounted(false);
  }

  componentWillReceiveProps(nextProps) {
    this.initMessages(nextProps.messages);
  }

  initLocale() {
    if (this.props.locale === null || moment.locales().indexOf(this.props.locale) === -1) {
      this.setLocale('en');
    } else {
      this.setLocale(this.props.locale);
    }
  }

  initMessages(messages = []) {
    this.setMessages(messages);
  }

  setLocale(locale) {
    this._locale = locale;
  }

  getLocale() {
    return this._locale;
  }

  setMessages(messages) {
    this._messages = messages;
  }

  getMessages() {
    return this._messages;
  }

  setMaxHeight(height) {
    this._maxHeight = height;
  }

  getMaxHeight() {
    return this._maxHeight;
  }

  setKeyboardHeight(height) {
    this._keyboardHeight = height;
  }

  getKeyboardHeight() {
    return this._keyboardHeight;
  }

  setIsTypingDisabled(value) {
    this._isTypingDisabled = value;
  }

  getIsTypingDisabled() {
    return this._isTypingDisabled;
  }

  setIsMounted(value) {
    this._isMounted = value;
  }

  getIsMounted() {
    return this._isMounted;
  }

  // TODO
  // setMinInputToolbarHeight
  getMinInputToolbarHeight() {
    if (this.props.renderAccessory) {
      return MIN_INPUT_TOOLBAR_HEIGHT * 2;
    }
    return MIN_INPUT_TOOLBAR_HEIGHT;
  }

  prepareMessagesContainerHeight(value) {
    if (this.props.isAnimated === true) {
      return new Animated.Value(value);
    }
    return value;
  }

  onKeyboardWillShow(e) {
    this.setIsTypingDisabled(true);
    this.setKeyboardHeight(e.endCoordinates.height);
    const newMessagesContainerHeight = (this.getMaxHeight() - (this.state.composerHeight + (this.getMinInputToolbarHeight() - MIN_COMPOSER_HEIGHT))) - this.getKeyboardHeight();
    if (this.props.isAnimated === true) {
      Animated.timing(this.state.messagesContainerHeight, {
        toValue: newMessagesContainerHeight,
        duration: 210,
      }).start();
    } else {
      this.setState((previousState) => {
        return {
          messagesContainerHeight: newMessagesContainerHeight,
        };
      });
    }
  }

  onKeyboardWillHide() {
    this.setIsTypingDisabled(true);
    this.setKeyboardHeight(0);
    const newMessagesContainerHeight = this.getMaxHeight() - (this.state.composerHeight + (this.getMinInputToolbarHeight() - MIN_COMPOSER_HEIGHT));
    if (this.props.isAnimated === true) {
      Animated.timing(this.state.messagesContainerHeight, {
        toValue: newMessagesContainerHeight,
        duration: 210,
      }).start();
    } else {
      this.setState((previousState) => {
        return {
          messagesContainerHeight: newMessagesContainerHeight,
        };
      });
    }
  }

  onKeyboardDidShow(e) {
    if (Platform.OS === 'android') {
      this.onKeyboardWillShow(e);
    }
    this.setIsTypingDisabled(false);
  }

  onKeyboardDidHide(e) {
    if (Platform.OS === 'android') {
      this.onKeyboardWillHide(e);
    }
    this.setIsTypingDisabled(false);
  }

  scrollToBottom(animated = true) {
    this._messageContainerRef.scrollTo({
      y: 0,
      animated,
    });
  }

  onTouchStart() {
    this._touchStarted = true;
  }

  onTouchMove() {
    this._touchStarted = false;
  }

  // handle Tap event to dismiss keyboard
  onTouchEnd() {
    if (this._touchStarted === true) {
      dismissKeyboard();
    }
    this._touchStarted = false;
  }

  renderMessages() {
    const AnimatedView = this.props.isAnimated === true ? Animated.View : View;
    return (
      <AnimatedView style={{
        height: this.state.messagesContainerHeight,
      }}>
        <MessageContainer
          {...this.props}

          invertibleScrollViewProps={this.invertibleScrollViewProps}

          messages={this.getMessages()}

          ref={component => this._messageContainerRef = component}
        />
      </AnimatedView>
    );
  }

  onSend(messages = [], shouldResetInputToolbar = false) {
    if (!Array.isArray(messages)) {
      messages = [messages];
    }

    messages = messages.map((message) => {
      return {
        ...message,
        user: this.props.user,
        createdAt: new Date(),
        _id: 'temp-id-' + Math.round(Math.random() * 1000000),
      };
    });

    if (shouldResetInputToolbar === true) {
      this.setIsTypingDisabled(true);
      this.resetInputToolbar();
    }

    this.props.onSend(messages);
    this.scrollToBottom();

    if (shouldResetInputToolbar === true) {
      setTimeout(() => {
        if (this.getIsMounted() === true) {
          this.setIsTypingDisabled(false);
        }
      }, 200);
    }
  }

  resetInputToolbar() {
    this.setState((previousState) => {
      return {
        text: '',
        composerHeight: MIN_COMPOSER_HEIGHT,
        messagesContainerHeight: this.prepareMessagesContainerHeight(this.getMaxHeight() - this.getMinInputToolbarHeight() - this.getKeyboardHeight()),
      };
    });
  }

  calculateInputToolbarHeight(newComposerHeight) {
    return newComposerHeight + (this.getMinInputToolbarHeight() - MIN_COMPOSER_HEIGHT);
  }

  onType(e) {
    if (this.getIsTypingDisabled() === true) {
      return;
    }
    const newComposerHeight = Math.max(MIN_COMPOSER_HEIGHT, Math.min(MAX_COMPOSER_HEIGHT, e.nativeEvent.contentSize.height));
    const newMessagesContainerHeight = this.getMaxHeight() - this.calculateInputToolbarHeight(newComposerHeight) - this.getKeyboardHeight();
    const newText = e.nativeEvent.text;
    this.setState((previousState) => {
      return {
        text: newText,
        composerHeight: newComposerHeight,
        messagesContainerHeight: this.prepareMessagesContainerHeight(newMessagesContainerHeight),
      };
    });
  }

  renderInputToolbar() {
    const inputToolbarProps = {
      ...this.props,
      text: this.state.text,
      composerHeight: Math.max(MIN_COMPOSER_HEIGHT, this.state.composerHeight),
      onChange: this.onType,
      onSend: this.onSend,
    };

    if (this.props.renderInputToolbar) {
      return this.props.renderInputToolbar(inputToolbarProps);
    }
    return (
      <InputToolbar
        {...inputToolbarProps}
      />
    );
  }

  renderLoading() {
    if (this.props.renderLoading) {
      return this.props.renderLoading();
    }
    return null;
  }

  render() {
    if (this.state.isInitialized === true) {
      return (
        <ActionSheet ref={component => this._actionSheetRef = component}>
          <View style={styles.container}>
            {this.renderMessages()}
            {this.renderInputToolbar()}
          </View>
        </ActionSheet>
      );
    }
    return (
      <View
        style={styles.container}
        onLayout={(e) => {
          const layout = e.nativeEvent.layout;
          this.setMaxHeight(layout.height);
          InteractionManager.runAfterInteractions(() => {
            this.setState({
              isInitialized: true,
              text: '',
              composerHeight: MIN_COMPOSER_HEIGHT,
              messagesContainerHeight: this.prepareMessagesContainerHeight(this.getMaxHeight() - this.getMinInputToolbarHeight()),
            });
          });
        }}
      >
        {this.renderLoading()}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

GiftedChat.childContextTypes = {
  actionSheet: PropTypes.func,
  getLocale: PropTypes.func,
};

GiftedChat.defaultProps = {
  messages: [],
  onSend: () => {
  },
  loadEarlier: false,
  onLoadEarlier: () => {
  },
  locale: null,
  isAnimated: Platform.select({
    ios: true,
    android: false,
  }),
  footer: null,
  renderAccessory: null,
  renderActions: null,
  renderAvatar: null,
  renderBubble: null,
  renderMessageText: null,
  renderMessageImage: null,
  renderComposer: null,
  renderCustomView: null,
  renderDay: null,
  renderInputToolbar: null,
  renderLoadEarlier: null,
  renderLoading: null,
  renderMessage: null,
  renderSend: null,
  renderTime: null,
  user: {},
};

export {
  GiftedChat,
  Actions,
  Avatar,
  Bubble,
  MessageImage,
  MessageText,
  Composer,
  Day,
  InputToolbar,
  LoadEarlier,
  Message,
  Send,
  Time,
};
<|endoftext|>


<commit_before>/**
 * JsonWebKey
 */
class JsonWebKey {}

/**
 * Export
 */
module.exports = JsonWebKey
<commit_msg>feat(JsonWebKey): draft constructor<commit_after>/**
 * JsonWebKey
 */
class JsonWebKey {

  /**
   * Constructor
   */
  constructor (data) {
    Object.assign(this, data)
  }
}

/**
 * Export
 */
module.exports = JsonWebKey
<|endoftext|>


<commit_before>    /**
     * Represents a single media query, manages it's state and registered handlers for this query
     *
     * @constructor
     * @param {string} query the media query string
     * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design
     */
    function MediaQuery(query, isUnconditional) {
        this.query = query;
        this.isUnconditional = isUnconditional;
        this.handlers = [];
        this.mql = matchMedia(query);

        var self = this;
        this.listener = function(mql) {
            self.mql = mql;
            self.assess();
        };
        this.mql.addListener(this.listener);
    }
    MediaQuery.prototype = {

        /**
         * add a handler for this query, triggering if already active
         *
         * @param {object} handler
         * @param {function} handler.match callback for when query is activated
         * @param {function} [handler.unmatch] callback for when query is deactivated
         * @param {function} [handler.setup] callback for immediate execution when a query handler is registered
         * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched?
         */
        addHandler : function(handler) {
            var qh = new QueryHandler(handler);
            this.handlers.push(qh);

            this.matches() && qh.on();
        },

        /**
         * removes the given handler from the collection, and calls it's destroy methods
         *
         * @param {object || function} handler the handler to remove
         */
        removeHandler : function(handler) {
            var handlers = this.handlers;
            each(handlers, function(h, i) {
                if(h.equals(handler)) {
                    h.destroy();
                    return !handlers.splice(i,1); //remove from array and exit each early
                }
            });
        },

        /**
         * Determine whether the media query should be considered a match
         *
         * @return {Boolean} true if media query can be considered a match, false otherwise
         */
        matches : function() {
            return this.mql.matches || this.isUnconditional;
        },

        /**
         * Clears all handlers and unbinds events
         */
        clear : function() {
            each(this.handlers, function(handler) {
                handler.destroy();
            });
            this.mql.removeListener(this.listener);
            this.handlers.length = 0; //clear array
        },

        /*
         * Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match
         */
        assess : function() {
            var action = this.matches() ? 'on' : 'off';

            each(this.handlers, function(handler) {
                handler[action]();
            });
        }
    };<commit_msg>handle MediaQueryListEvent objects. Fixes #124, #154<commit_after>    /**
     * Represents a single media query, manages it's state and registered handlers for this query
     *
     * @constructor
     * @param {string} query the media query string
     * @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design
     */
    function MediaQuery(query, isUnconditional) {
        this.query = query;
        this.isUnconditional = isUnconditional;
        this.handlers = [];
        this.mql = matchMedia(query);

        var self = this;
        this.listener = function(mql) {
            // Chrome passes an MediaQueryListEvent object, while other browsers pass MediaQueryList directly
            self.mql = mql.currentTarget || mql;
            self.assess();
        };
        this.mql.addListener(this.listener);
    }
    MediaQuery.prototype = {

        /**
         * add a handler for this query, triggering if already active
         *
         * @param {object} handler
         * @param {function} handler.match callback for when query is activated
         * @param {function} [handler.unmatch] callback for when query is deactivated
         * @param {function} [handler.setup] callback for immediate execution when a query handler is registered
         * @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched?
         */
        addHandler : function(handler) {
            var qh = new QueryHandler(handler);
            this.handlers.push(qh);

            this.matches() && qh.on();
        },

        /**
         * removes the given handler from the collection, and calls it's destroy methods
         *
         * @param {object || function} handler the handler to remove
         */
        removeHandler : function(handler) {
            var handlers = this.handlers;
            each(handlers, function(h, i) {
                if(h.equals(handler)) {
                    h.destroy();
                    return !handlers.splice(i,1); //remove from array and exit each early
                }
            });
        },

        /**
         * Determine whether the media query should be considered a match
         *
         * @return {Boolean} true if media query can be considered a match, false otherwise
         */
        matches : function() {
            return this.mql.matches || this.isUnconditional;
        },

        /**
         * Clears all handlers and unbinds events
         */
        clear : function() {
            each(this.handlers, function(handler) {
                handler.destroy();
            });
            this.mql.removeListener(this.listener);
            this.handlers.length = 0; //clear array
        },

        /*
         * Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match
         */
        assess : function() {
            var action = this.matches() ? 'on' : 'off';

            each(this.handlers, function(handler) {
                handler[action]();
            });
        }
    };<|endoftext|>


<commit_before>import Pulse from './Pulse';
import {error, inherits, isArray} from 'vega-util';

/**
 * Represents a set of multiple pulses. Used as input for operators
 * that accept multiple pulses at a time. Contained pulses are
 * accessible via the public "pulses" array property. This pulse doe
 * not carry added, removed or modified tuples directly. However,
 * the visit method can be used to traverse all such tuples contained
 * in sub-pulses with a timestamp matching this parent multi-pulse.
 * @constructor
 * @param {Dataflow} dataflow - The backing dataflow instance.
 * @param {number} stamp - The timestamp.
 * @param {Array<Pulse>} pulses - The sub-pulses for this multi-pulse.
 */
export default function MultiPulse(dataflow, stamp, pulses, encode) {
  var p = this,
      c = 0,
      pulse, hash, i, n, f;

  this.dataflow = dataflow;
  this.stamp = stamp;
  this.fields = null;
  this.encode = encode || null;
  this.pulses = pulses;

  for (i=0, n=pulses.length; i<n; ++i) {
    pulse = pulses[i];
    if (pulse.stamp !== stamp) continue;

    if (pulse.fields) {
      hash = p.fields || (p.fields = {});
      for (f in pulse.fields) { hash[f] = 1; }
    }

    if (pulse.changed(p.ADD)) c |= p.ADD;
    if (pulse.changed(p.REM)) c |= p.REM;
    if (pulse.changed(p.MOD)) c |= p.MOD;
  }

  this.changes = c;
}

var prototype = inherits(MultiPulse, Pulse);

/**
 * Creates a new pulse based on the values of this pulse.
 * The dataflow, time stamp and field modification values are copied over.
 * @return {Pulse}
 */
prototype.fork = function() {
  if (arguments.length && (arguments[0] & Pulse.prototype.ALL)) {
    error('MultiPulse fork does not support tuple change sets.');
  }
  return new Pulse(this.dataflow).init(this, 0);
};

prototype.changed = function(flags) {
  return this.changes & flags;
};

prototype.modified = function(_) {
  var p = this, fields = p.fields;
  return !(fields && (p.changes & p.MOD)) ? 0
    : isArray(_) ? _.some(function(f) { return fields[f]; })
    : fields[_];
};

prototype.filter = function() {
  error('MultiPulse does not support filtering.');
};

prototype.materialize = function() {
  error('MultiPulse does not support materialization.');
};

prototype.visit = function(flags, visitor) {
  var pulses = this.pulses, i, n;

  for (i=0, n=pulses.length; i<n; ++i) {
    if (pulses[i].stamp === this.stamp) {
      pulses[i].visit(flags, visitor);
    }
  }

  return this;
};
<commit_msg>Fix MultiPulse visit bug.<commit_after>import Pulse from './Pulse';
import {error, inherits, isArray} from 'vega-util';

/**
 * Represents a set of multiple pulses. Used as input for operators
 * that accept multiple pulses at a time. Contained pulses are
 * accessible via the public "pulses" array property. This pulse doe
 * not carry added, removed or modified tuples directly. However,
 * the visit method can be used to traverse all such tuples contained
 * in sub-pulses with a timestamp matching this parent multi-pulse.
 * @constructor
 * @param {Dataflow} dataflow - The backing dataflow instance.
 * @param {number} stamp - The timestamp.
 * @param {Array<Pulse>} pulses - The sub-pulses for this multi-pulse.
 */
export default function MultiPulse(dataflow, stamp, pulses, encode) {
  var p = this,
      c = 0,
      pulse, hash, i, n, f;

  this.dataflow = dataflow;
  this.stamp = stamp;
  this.fields = null;
  this.encode = encode || null;
  this.pulses = pulses;

  for (i=0, n=pulses.length; i<n; ++i) {
    pulse = pulses[i];
    if (pulse.stamp !== stamp) continue;

    if (pulse.fields) {
      hash = p.fields || (p.fields = {});
      for (f in pulse.fields) { hash[f] = 1; }
    }

    if (pulse.changed(p.ADD)) c |= p.ADD;
    if (pulse.changed(p.REM)) c |= p.REM;
    if (pulse.changed(p.MOD)) c |= p.MOD;
  }

  this.changes = c;
}

var prototype = inherits(MultiPulse, Pulse);

/**
 * Creates a new pulse based on the values of this pulse.
 * The dataflow, time stamp and field modification values are copied over.
 * @return {Pulse}
 */
prototype.fork = function() {
  if (arguments.length && (arguments[0] & Pulse.prototype.ALL)) {
    error('MultiPulse fork does not support tuple change sets.');
  }
  return new Pulse(this.dataflow).init(this, 0);
};

prototype.changed = function(flags) {
  return this.changes & flags;
};

prototype.modified = function(_) {
  var p = this, fields = p.fields;
  return !(fields && (p.changes & p.MOD)) ? 0
    : isArray(_) ? _.some(function(f) { return fields[f]; })
    : fields[_];
};

prototype.filter = function() {
  error('MultiPulse does not support filtering.');
};

prototype.materialize = function() {
  error('MultiPulse does not support materialization.');
};

prototype.visit = function(flags, visitor) {
  var p = this,
      pulses = p.pulses,
      n = pulses.length,
      i = 0;

  if (flags & p.SOURCE) {
    for (; i<n; ++i) {
      pulses[i].visit(flags, visitor);
    }
  } else {
    for (; i<n; ++i) {
      if (pulses[i].stamp === p.stamp) {
        pulses[i].visit(flags, visitor);
      }
    }
  }

  return p;
};
<|endoftext|>


<commit_before>'use strict'

import {VAL, ERR, END} from './Constants'
import * as SideEffects from './SideEffects'

/**
 * An Observable receives and emits events, optionally with transformations.
 */

export default class Observable {
  constructor(transformers, producers) {
    let tforms = transformers || {}
    this.val = tforms.val || this.emitVal
    this.err = tforms.err || this.emitErr
    this.end = tforms.end || this.emitEnd
    this.producers = producers || []
    this.consumers = []
    this.sideEffects = { [VAL]: [], [ERR]: [], [END]: [] }
    this.ended = this.active = false
  }

  // Emitters

  emitVal(d, c) {
    for(let i = 0, l = this.consumers.length; i < l; ++i)
      this.consumers[i].val(d, this)
    return this
  }

  emitErr(d, c) {
    for(let i = 0, l = this.consumers.length; i < l; ++i)
      this.consumers[i].err(d, this)
    return this
  }

  emitEnd() {
    this.ended = true
    this.active = false
    for(let i = 0, l = this.producers.length; i < l; ++i)
      this.producers[i].deactivate(this)
    for(let i = 0, l = this.consumers.length; i < l; ++i)
      this.consumers[i].end(this)
    return this
  }

  // Activation / Deactivation

  activate(that) {
    if(!this.ended) {
      this.consumers.push(that)
      if(!this.active) {
        this.active = true
        for(let i = 0, l = this.producers.length; i < l; ++i)
          this.producers[i].activate(this)
      }
    } else that.end()
  }

  deactivate(that) {
    this.consumers.splice(this.consumers.indexOf(that), 1)
    if(this.consumers.length === 0) {
      for(let i = 0, l = this.producers.length; i < l; ++i)
          this.producers[i].deactivate(this)
      this.active = false
    }
  }

  // Subscription

  on(type, fn) {
    let se
    switch(type) {
      case VAL: se = new SideEffects.OnVal(fn); break
      case ERR: se = new SideEffects.OnErr(fn); break
      case END: se = new SideEffects.OnEnd(fn); break
      case ANY: se = new SideEffects.OnAny(fn); break
      default: throw new Error('Invalid SideEffect type.')
    }

    this.sideEffects[type].push(se)
    this.activate(se, true)
    return this
  }

  off(type, fn) {
    let idx = this.sideEffects[type].findIndex(c => c.fn === fn)

    if(idx > -1) {
      let se = this.sideEffects[type].splice(idx, 1)
      this.deactivate(se)
    }
    return this
  }

  // Fluent interface for applying transformations.

  map(fn) {
    return this.extend({
      val: function(d, p, c) {
        this.emitVal(fn(d), c)
      }
    })
  }

  filter(fn) {
    return this.extend({
      val: function(d, p, c) {
        if(fn(d)) this.emitVal(d, c)
      }
    })
  }

  take(n) {
    return this.extend({
      val: function(d, p, c) {
        if(--n > 0) this.emitVal(d, c)
        else this.emitVal(d, c).emitEnd()
      }
    })
  }

  takeWhile(fn) {
    return this.extend({
      val: function(d, p, c) {
        if(fn(d)) this.emitVal(d, c)
        else this.emitEnd()
      }
    })
  }

  last() {
    let data, curr
    return this.extend({
      val: function(d, p, c) {
        data = d
        curr = c
      },
      end: function(p) {
        if(curr !== undefined)
          this.emitVal(data, curr).emitEnd()
      }
    })
  }

  skip(n) {
    return this.extend({
      val: function(d, p, c) {
        if(--n <= 0) this.emitVal(d, c)
      }
    })
  }

  skipWhile(n) {
    let done = false
    return this.extend({
      val: function(d, p, c) {
        if(done || (done = !fn(d)))
          this.emitVal(d, c)
      }
    })
  }

  skipDuplicates() {
    let data
    return this.extend({
      val: function(d, p, c) {
        if(d !== data) {
          data = d
          this.emitVal(d, c)
        }
      }
    })
  }

  diff(fn, seed) {
    let data = seed
    return this.extend({
      val: function(d, p, c) {
        if(data !== undefined)
          this.emitVal(fn(data, data = d), c)
        else data = d
      }
    })
  }

  scan(fn, seed) {
    let data = seed
    return this.extend({
      val: function(d, p, c) {
        if(data !== undefined)
          this.emitVal(data = fn(data, d), c)
      }
    })
  }

  flatten(fn) {
    return this.extend({
      val: function(d, p, c) {
        for(let i = 0, l = d.length; i < l; ++i)
          this.emitVal(d[i], c)
      }
    })
  }

  onValue(fn) {
    return this.on(VAL, fn)
  }

  onError(fn) {
    return this.on(ERR, fn)
  }

  onEnd(fn) {
    return this.on(END, fn)
  }

  onAny(fn) {
    return this.on(ANY, fn)
  }

  offValue(fn) {
    return this.off(VAL, fn)
  }

  offError(fn) {
    return this.off(ERR, fn)
  }

  offEnd(fn) {
    return this.off(END, fn)
  }

  offAny(fn) {
    return this.off(ANY, fn)
  }
}<commit_msg>Add missing dependency<commit_after>'use strict'

import {VAL, ERR, END, ANY} from './Constants'
import * as SideEffects from './SideEffects'

/**
 * An Observable receives and emits events, optionally with transformations.
 */

export default class Observable {
  constructor(transformers, producers) {
    let tforms = transformers || {}
    this.val = tforms.val || this.emitVal
    this.err = tforms.err || this.emitErr
    this.end = tforms.end || this.emitEnd
    this.producers = producers || []
    this.consumers = []
    this.sideEffects = { [VAL]: [], [ERR]: [], [END]: [] }
    this.ended = this.active = false
  }

  // Emitters

  emitVal(d, c) {
    for(let i = 0, l = this.consumers.length; i < l; ++i)
      this.consumers[i].val(d, this)
    return this
  }

  emitErr(d, c) {
    for(let i = 0, l = this.consumers.length; i < l; ++i)
      this.consumers[i].err(d, this)
    return this
  }

  emitEnd() {
    this.ended = true
    this.active = false
    for(let i = 0, l = this.producers.length; i < l; ++i)
      this.producers[i].deactivate(this)
    for(let i = 0, l = this.consumers.length; i < l; ++i)
      this.consumers[i].end(this)
    return this
  }

  // Activation / Deactivation

  activate(that) {
    if(!this.ended) {
      this.consumers.push(that)
      if(!this.active) {
        this.active = true
        for(let i = 0, l = this.producers.length; i < l; ++i)
          this.producers[i].activate(this)
      }
    } else that.end()
  }

  deactivate(that) {
    this.consumers.splice(this.consumers.indexOf(that), 1)
    if(this.consumers.length === 0) {
      for(let i = 0, l = this.producers.length; i < l; ++i)
          this.producers[i].deactivate(this)
      this.active = false
    }
  }

  // Subscription

  on(type, fn) {
    let se
    switch(type) {
      case VAL: se = new SideEffects.OnVal(fn); break
      case ERR: se = new SideEffects.OnErr(fn); break
      case END: se = new SideEffects.OnEnd(fn); break
      case ANY: se = new SideEffects.OnAny(fn); break
      default: throw new Error('Invalid SideEffect type.')
    }

    this.sideEffects[type].push(se)
    this.activate(se, true)
    return this
  }

  off(type, fn) {
    let idx = this.sideEffects[type].findIndex(c => c.fn === fn)

    if(idx > -1) {
      let se = this.sideEffects[type].splice(idx, 1)
      this.deactivate(se)
    }
    return this
  }

  // Fluent interface for applying transformations.

  map(fn) {
    return this.extend({
      val: function(d, p, c) {
        this.emitVal(fn(d), c)
      }
    })
  }

  filter(fn) {
    return this.extend({
      val: function(d, p, c) {
        if(fn(d)) this.emitVal(d, c)
      }
    })
  }

  take(n) {
    return this.extend({
      val: function(d, p, c) {
        if(--n > 0) this.emitVal(d, c)
        else this.emitVal(d, c).emitEnd()
      }
    })
  }

  takeWhile(fn) {
    return this.extend({
      val: function(d, p, c) {
        if(fn(d)) this.emitVal(d, c)
        else this.emitEnd()
      }
    })
  }

  last() {
    let data, curr
    return this.extend({
      val: function(d, p, c) {
        data = d
        curr = c
      },
      end: function(p) {
        if(curr !== undefined)
          this.emitVal(data, curr).emitEnd()
      }
    })
  }

  skip(n) {
    return this.extend({
      val: function(d, p, c) {
        if(--n <= 0) this.emitVal(d, c)
      }
    })
  }

  skipWhile(n) {
    let done = false
    return this.extend({
      val: function(d, p, c) {
        if(done || (done = !fn(d)))
          this.emitVal(d, c)
      }
    })
  }

  skipDuplicates() {
    let data
    return this.extend({
      val: function(d, p, c) {
        if(d !== data) {
          data = d
          this.emitVal(d, c)
        }
      }
    })
  }

  diff(fn, seed) {
    let data = seed
    return this.extend({
      val: function(d, p, c) {
        if(data !== undefined)
          this.emitVal(fn(data, data = d), c)
        else data = d
      }
    })
  }

  scan(fn, seed) {
    let data = seed
    return this.extend({
      val: function(d, p, c) {
        if(data !== undefined)
          this.emitVal(data = fn(data, d), c)
      }
    })
  }

  flatten(fn) {
    return this.extend({
      val: function(d, p, c) {
        for(let i = 0, l = d.length; i < l; ++i)
          this.emitVal(d[i], c)
      }
    })
  }

  onValue(fn) {
    return this.on(VAL, fn)
  }

  onError(fn) {
    return this.on(ERR, fn)
  }

  onEnd(fn) {
    return this.on(END, fn)
  }

  onAny(fn) {
    return this.on(ANY, fn)
  }

  offValue(fn) {
    return this.off(VAL, fn)
  }

  offError(fn) {
    return this.off(ERR, fn)
  }

  offEnd(fn) {
    return this.off(END, fn)
  }

  offAny(fn) {
    return this.off(ANY, fn)
  }
}<|endoftext|>


<commit_before>import data from './_data';

const splitBySpaceReg = /\s+/;
const splitByDotReg = /\.(.+)/;

// checks an element against a selector
function is(node, selector) {
    return (node.matches
            || node.webkitMatchesSelector
            || node.mozMatchesSelector
            || node.msMatchesSelector
            || node.oMatchesSelector).call(node, selector);
}

// the function is used when a selector is given
function delegateHandler(evt, selector, handler) {
    const randomID = Math.random().toString().replace('0.', 'x');
    const scopeSelector = `[${randomID}="${randomID}"] `;
    const splittedSelector = selector.split(',');

    let matching = '';

    for (let i = 0; i < splittedSelector.length; i++) {
        const sel = splittedSelector[i];
        matching += `${i === 0 ? '' : ','}${scopeSelector}${sel},${scopeSelector}${sel} *`;
    }

    this.setAttribute(randomID, randomID);

    if (is(evt.target, matching)) {
        handler.call(this, evt);
    }

    this.removeAttribute(randomID);
}

// adds event listener to a set of elemnts
export default function on(namesStr, selector, handler) {
    const names = namesStr.split(splitBySpaceReg);
    let delegate;

    if (typeof selector === 'function') {
        handler = selector; // eslint-disable-line no-param-reassign
        selector = null; // eslint-disable-line no-param-reassign
    }

    if (selector) {
        delegate = function uniqueDelegateHandler(evt) {
            delegateHandler.call(this, evt, selector, handler);
        };
    }

    for (let i = 0; i < names.length; i++) {
        const [name, namespace] = names[i].split(splitByDotReg);

        for (let j = 0; j < this.length; j++) {
            const node = this[j];
            const nodeID = node.b$ = node.b$ || ++data.nodeIndex; // eslint-disable-line no-plusplus
            const events = data.allEvents[name + nodeID] = data.allEvents[name + nodeID] || [];

            let exist = false;

            for (let k = 0; k < events.length; k++) {
                const event = events[k];

                if (handler === event.handler && (!selector || selector === event.selector)) {
                    exist = true;
                    break;
                }
            }

            if (!exist) {
                events.push({
                    delegate,
                    handler,
                    namespace,
                    selector,
                    nodeID,
                    name
                });

                node.addEventListener(name, delegate || handler, false);
            }
        }
    }

    return this;
}
<commit_msg>test: End attr with letter (jsdom issue)<commit_after>import data from './_data';

const splitBySpaceReg = /\s+/;
const splitByDotReg = /\.(.+)/;
const randomID = `${Math.random().toString().replace('0.', 'x')}y`; // x12345y

// checks an element against a selector
function is(node, selector) {
    return (node.matches
            || node.webkitMatchesSelector
            || node.mozMatchesSelector
            || node.msMatchesSelector
            || node.oMatchesSelector).call(node, selector);
}

// the function is used when a selector is given
function delegateHandler(evt, selector, handler) {
    const scopeSelector = `[${randomID}="${randomID}"] `;
    const splittedSelector = selector.split(',');

    let matching = '';

    for (let i = 0; i < splittedSelector.length; i++) {
        const sel = splittedSelector[i];
        matching += `${i === 0 ? '' : ','}${scopeSelector}${sel},${scopeSelector}${sel} *`;
    }

    this.setAttribute(randomID, randomID);

    if (is(evt.target, matching)) {
        handler.call(this, evt);
    }

    this.removeAttribute(randomID);
}

// adds event listener to a set of elemnts
export default function on(namesStr, selector, handler) {
    const names = namesStr.split(splitBySpaceReg);
    let delegate;

    if (typeof selector === 'function') {
        handler = selector; // eslint-disable-line no-param-reassign
        selector = null; // eslint-disable-line no-param-reassign
    }

    if (selector) {
        delegate = function uniqueDelegateHandler(evt) {
            delegateHandler.call(this, evt, selector, handler);
        };
    }

    for (let i = 0; i < names.length; i++) {
        const [name, namespace] = names[i].split(splitByDotReg);

        for (let j = 0; j < this.length; j++) {
            const node = this[j];
            const nodeID = node.b$ = node.b$ || ++data.nodeIndex; // eslint-disable-line no-plusplus
            const events = data.allEvents[name + nodeID] = data.allEvents[name + nodeID] || [];

            let exist = false;

            for (let k = 0; k < events.length; k++) {
                const event = events[k];

                if (handler === event.handler && (!selector || selector === event.selector)) {
                    exist = true;
                    break;
                }
            }

            if (!exist) {
                events.push({
                    delegate,
                    handler,
                    namespace,
                    selector,
                    nodeID,
                    name
                });

                node.addEventListener(name, delegate || handler, false);
            }
        }
    }

    return this;
}
<|endoftext|>


<commit_before>let mod = new ActionObj('Put');
module.exports = mod;

//Warning: if you put more than one container near source,
//  hauler will be in infinite loop of withdraw/transfer.

//TODO diff put target to two module
//  one for store energy whose priority is low
//  one for put energy to controller container
//    which is using by upgrader whose priority is normal
const targetInitFunc = function(creep) {
    const role = creep.memory.role;
    const findSuitableContainer = function(o) {
        if(o.structureType == STRUCTURE_CONTAINER || o.structureType == STRUCTURE_STORAGE) {
            if(_.sum(o.store) < o.storeCapacity) {
                return true;
            }
        }
        return false;
    };
    const suitableContainers = creep.room.find(FIND_STRUCTURES, {
        filter: findSuitableContainer
    });

    if(role == 'harvester') {
        const sourceLink = creep.room.sourceLink;
        if(sourceLink && creep.pos.getRangeTo(sourceLink)<=2
           && sourceLink.energy<sourceLink.energyCapacity) {
            return sourceLink;
        } else {
            const markSource = Util.Mark.getMarkSource(creep);
            return markSource ? markSource.container : false;
        }
    } else {
        const sourceContainers = [];
        for(var id in Memory.sources) {
            const source = Game.getObjectById(id);
            if(source && source.container) {
                sourceContainers.push(source.container);
            }
        }
        var targets = suitableContainers;
        if(sourceContainers.length) {
            const sourceContainerIds = _.map(sourceContainers, o => o.id);
            targets = _.filter(targets, o => _.indexOf(sourceContainerIds, o.id) == -1);
        }
        return creep.pos.findClosestByRange(targets);
    }
};

mod.nextTarget = function() {
    return Util.Mark.handleMark(this.creep, targetInitFunc, this.actionName);
}

mod.loop = function(creep) {
    return this.loop0(creep, (creep, target) => {
        //Maintain container first(Only for harvester which is stay still)
        //So result is creep will harvest -> repair util
        // container hits equal to hitsMax.

        if(target.hits < target.hitsMax && creep.getActiveBodyparts(WORK) > 0 && creep.memory.role=='harvester') {
            creep.say('🚧 repair');
            if(creep.repair(target) == ERR_NOT_IN_RANGE) {
                creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        } else {
            const result = creep.transfer(target, RESOURCE_ENERGY);
            if(result == ERR_NOT_IN_RANGE) {
                creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
            } else if(result == OK || result == ERR_FULL) {
                Util.Mark.unmarkTarget(creep, this.actionName);
            }
        }
    });
};
<commit_msg>updated comments<commit_after>let mod = new ActionObj('Put');
module.exports = mod;

//Warning: if you put more than one container near source,
//  hauler will be in infinite loop of withdraw/transfer.
const targetInitFunc = function(creep) {
    const role = creep.memory.role;
    const findSuitableContainer = function(o) {
        if(o.structureType == STRUCTURE_CONTAINER || o.structureType == STRUCTURE_STORAGE) {
            if(_.sum(o.store) < o.storeCapacity) {
                return true;
            }
        }
        return false;
    };
    const suitableContainers = creep.room.find(FIND_STRUCTURES, {
        filter: findSuitableContainer
    });

    if(role == 'harvester') {
        const sourceLink = creep.room.sourceLink;
        if(sourceLink && creep.pos.getRangeTo(sourceLink)<=2
           && sourceLink.energy<sourceLink.energyCapacity) {
            return sourceLink;
        } else {
            const markSource = Util.Mark.getMarkSource(creep);
            return markSource ? markSource.container : false;
        }
    } else {
        const sourceContainers = [];
        for(var id in Memory.sources) {
            const source = Game.getObjectById(id);
            if(source && source.container) {
                sourceContainers.push(source.container);
            }
        }
        var targets = suitableContainers;
        //Other roles shouldn't put energy to source container
        //  which will occupy space for energy from source.
        if(sourceContainers.length) {
            const sourceContainerIds = _.map(sourceContainers, o => o.id);
            targets = _.filter(targets, o => _.indexOf(sourceContainerIds, o.id) == -1);
        }
        return creep.pos.findClosestByRange(targets);
    }
};

mod.nextTarget = function() {
    return Util.Mark.handleMark(this.creep, targetInitFunc, this.actionName);
}

mod.loop = function(creep) {
    return this.loop0(creep, (creep, target) => {
        //Maintain container first(Only for harvester which is stay still)
        //So result is creep will harvest -> repair util
        // container hits equal to hitsMax.

        if(target.hits < target.hitsMax && creep.getActiveBodyparts(WORK) > 0 && creep.memory.role=='harvester') {
            creep.say('🚧 repair');
            if(creep.repair(target) == ERR_NOT_IN_RANGE) {
                creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        } else {
            const result = creep.transfer(target, RESOURCE_ENERGY);
            if(result == ERR_NOT_IN_RANGE) {
                creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
            } else if(result == OK || result == ERR_FULL) {
                Util.Mark.unmarkTarget(creep, this.actionName);
            }
        }
    });
};
<|endoftext|>


<commit_before>/**
 * Created by Abdellatif on 1/9/2017.
 */
var React = require('react');
var ReactDOM = require('react-dom');
var firebase = require('firebase');
import Paper from 'material-ui/Paper'
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
var key = 0;

export default class Events extends React.Component{
    getKey(){
        key++;
        return key;
    }

    handleExpandChange = (expanded) => {
        this.setState({expanded: expanded});
    };

    handleExpand = () => {
        this.setState({expanded: true});
    };

    reverseExpand(expanded){
        return !expanded;
    }
    handleReduce = () => {
        this.setState({expanded: false});
    };

    componentWillMount(){
        var database = firebase.database();
        var eventsRef = database.ref().root;
        eventsRef.on('value', snap => {
            var events = Object.values(snap.val());
            this.setState({
                events: events,
            })
        })
    }
    /*
     const aboutRef = firebase.database().ref('About');
     aboutRef.on('value', snap => {
     this.setState({
     about: snap.val()
     });
     })
     */
    constructor(props) {
        super(props);

        this.state = {
            events: [],
            expanded: false,
        }
    }

    render() {

        const archiveStyle = {
            marginTop: 20,
        };

        const titleStyle = {
            fontSize: '160%',
            textTransform: 'uppercase'
        };

        const titleStyle2 = {
            fontSize: '120%',
        };

        const subtitleStyle = {
            color: '#ababab'
        };

        const imgStyle = {
            width: '100%',
            height: '180%'
        };

        const cardStyle = {
            textAlign: 'left',
        };

        const cardTextStyle = {
            // color: '#000',
        };

        const cardTextExpanded = false;

        var events = this.state.events.map(event =>

                <Card style={cardStyle} expanded={this.state.expanded} onExpandChange={this.handleExpandChange}>
                    <CardHeader
                        title={event.title} titleStyle={titleStyle}
                        subtitle={event.type} subtitleStyle={subtitleStyle}
                        actAsExpander={true}
                        showExpandableButton={true}
                    />

                    <CardText style={cardTextStyle} expandable={true}>
                        {event.description}
                    </CardText>
                    <CardTitle title={event.dayAndTime} subtitle={event.locationAndDate} titleStyle={titleStyle2} subtitleStyle={subtitleStyle} />
                    <CardActions>
                        <FlatButton label="Description" primary={true} onTouchTap={this.handleExpand}/>
                        <FlatButton label="RSVP" secondary={true}/>
                    </CardActions>
                </Card>

        );

        return (
            <Paper className="section" rounded={false} zDepth={1} id="events">

EVENTS

                    {events}

                <FlatButton label="Events Archive" style={archiveStyle}/>
            </Paper>
        );
    }
};

<commit_msg>make RSVP redirect to the RSVP page<commit_after>/**
 * Created by Abdellatif on 1/9/2017.
 */
var React = require('react');
var ReactDOM = require('react-dom');
var firebase = require('firebase');
import Paper from 'material-ui/Paper'
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
var key = 0;

export default class Events extends React.Component{
    getKey(){
        key++;
        return key;
    }

    handleExpandChange = (expanded) => {
    };

    handleExpand = () => {
        this.expandedForm = true;
    };

    reverseExpand(expanded){
        return !expanded;
    }
    handleReduce = () => {
        this.setState({expanded: false});
    };

    componentWillMount(){
        var database = firebase.database();
        var eventsRef = database.ref().root;
        eventsRef.on('value', snap => {
            var events = Object.values(snap.val());
            for (var i = 0; i < events.length; i++){
                events[i].expandedForm = false;
            }
            console.log(events)

            this.setState({
                events: events,
            })
        })
    }

    constructor(props) {
        super(props);

        this.state = {
            events: [],
            expanded: false,
        }
    }

    render() {

        const archiveStyle = {
            marginTop: 20,
        };

        const titleStyle = {
            fontSize: '160%',
            textTransform: 'uppercase'
        };

        const titleStyle2 = {
            fontSize: '120%',
        };

        const subtitleStyle = {
            color: '#ababab'
        };

        const imgStyle = {
            width: '100%',
            height: '180%'
        };

        const cardStyle = {
            textAlign: 'left',
        };

        const cardTextStyle = {
            // color: '#000',
        };

        const cardTextExpanded = false;

        var events = this.state.events.map(event =>

                <Card style={cardStyle} expanded={event.expanded} onExpandChange={this.handleExpandChange}>
                    <CardHeader
                        title={event.title} titleStyle={titleStyle}
                        subtitle={event.type} subtitleStyle={subtitleStyle}
                        actAsExpander={true}
                        showExpandableButton={true}
                    />

                    <CardText style={cardTextStyle} expandable={true}>
                        {event.description}
                    </CardText>
                    <CardTitle title={event.dayAndTime} subtitle={event.locationAndDate} titleStyle={titleStyle2} subtitleStyle={subtitleStyle} />
                    <CardActions>
                        <FlatButton label="Description" primary={true} onTouchTap={this.handleExpand}/>
                        <FlatButton label="RSVP" secondary={true} href={event.RSVP} target="_window"/>
                    </CardActions>
                </Card>

        );

        return (
            <Paper className="section" rounded={false} zDepth={1} id="events">

EVENTS

                    {events}

                <FlatButton label="Events Archive" style={archiveStyle}/>
            </Paper>
        );
    }
};

<|endoftext|>