<commit_before>var React = require('react');

var Sticky = React.createClass({

  getDefaultProps: function() {
    return {
      type: React.DOM.div,
      className: '',
      style: {},
      stickyClass: 'sticky',
      stickyStyle: {
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0
      },
      topOffset: 0,
      onStickyStateChange: function () {}
    };
  },

  getInitialState: function() {
    return {
      events: ['scroll', 'resize', 'touchmove', 'touchend']
    };
  },

  top: function() {
    return this.domNode.getBoundingClientRect().top;
  },

  shouldBeSticky: function() {
    var position = this.domNode.style.position;
    this.domNode.style.position = 'relative';
    var shouldBeSticky = this.top() <= -this.props.topOffset;
    this.domNode.style.position = position;
    return shouldBeSticky;
  },

  handleTick: function() {
    if (this.hasUnhandledEvent || this.hasTouchEvent) {
      var isSticky = this.state.isSticky;
      var shouldBeSticky = this.shouldBeSticky();
      if (isSticky !== shouldBeSticky) {
        this.nextState(shouldBeSticky);
      }
      this.hasUnhandledEvent = false;
    }
    this.tick();
  },

  handleEvent: function(event) {
    switch (event.type) {
      case 'touchmove':
        this.hasTouchEvent = true;
        break;
      case 'touchend':
        this.hasTouchEvent = false;
        break;
      default:
        this.hasUnhandledEvent = true;
    }
  },

  componentDidMount: function() {
    this.state.events.forEach(function(type) {
      if (window.addEventListener) {
        window.addEventListener(type, this.handleEvent);
      } else {
        window.attachEvent('on' + type, this.handleEvent);
      }
    }, this);
    this.domNode = React.findDOMNode ? React.findDOMNode(this) : this.getDOMNode();
    this.hasUnhandledEvent = true;
    this.tick();
  },

  componentWillUnmount: function() {
    this.state.events.forEach(function(type) {
      if (window.removeEventListener) {
        window.removeEventListener(type, this.handleEvent);
      } else {
        window.detachEvent('on' + type, this.handleEvent)
      }
    }, this);
    this.domNode = null;
    this.cancel();
  },

  isModernBrowser: function() {
    return window && window.requestAnimationFrame && window.cancelAnimationFrame;
  },

  cancel: function() {
    var cancel = this.isModernBrowser() ? cancelAnimationFrame : clearTimeout;
    cancel(this.currentTick);
  },

  tick: function () {
    var next = this.isModernBrowser() ? requestAnimationFrame : setTimeout;
    this.currentTick = next(this.handleTick, 1000 / 60);
  },

  nextStyle: function(shouldBeSticky) {
    if (shouldBeSticky) {
      var copyStyles = function(dest, source) {
        for (var rule in source) {
          dest[rule] = source[rule];
        };
        return dest;
      }
      return copyStyles(copyStyles({}, this.props.style), this.props.stickyStyle)
    } else {
      return this.props.style;
    }
  },

  nextClassName: function(shouldBeSticky) {
    return [this.props.className]
      .concat(shouldBeSticky ? this.props.stickyClass : undefined)
      .join(' ');
  },

  nextState: function(shouldBeSticky) {
    this.setState({
      isSticky: shouldBeSticky,
      style: this.nextStyle(shouldBeSticky),
      className: this.nextClassName(shouldBeSticky)
    });
    this.props.onStickyStateChange(shouldBeSticky);
  },

  render: function() {
    return this.props.type({
      style: this.state.style,
      className: this.state.className
    }, this.props.children);
  }
});

module.exports = Sticky;
<commit_msg>zIndex defaults to 1<commit_after>var React = require('react');

var Sticky = React.createClass({

  getDefaultProps: function() {
    return {
      type: React.DOM.div,
      className: '',
      style: {},
      stickyClass: 'sticky',
      stickyStyle: {
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        zIndex: 1
      },
      topOffset: 0,
      onStickyStateChange: function () {}
    };
  },

  getInitialState: function() {
    return {
      events: ['scroll', 'resize', 'touchmove', 'touchend']
    };
  },

  top: function() {
    return this.domNode.getBoundingClientRect().top;
  },

  shouldBeSticky: function() {
    var position = this.domNode.style.position;
    this.domNode.style.position = 'relative';
    var shouldBeSticky = this.top() <= -this.props.topOffset;
    this.domNode.style.position = position;
    return shouldBeSticky;
  },

  handleTick: function() {
    if (this.hasUnhandledEvent || this.hasTouchEvent) {
      var isSticky = this.state.isSticky;
      var shouldBeSticky = this.shouldBeSticky();
      if (isSticky !== shouldBeSticky) {
        this.nextState(shouldBeSticky);
      }
      this.hasUnhandledEvent = false;
    }
    this.tick();
  },

  handleEvent: function(event) {
    switch (event.type) {
      case 'touchmove':
        this.hasTouchEvent = true;
        break;
      case 'touchend':
        this.hasTouchEvent = false;
        break;
      default:
        this.hasUnhandledEvent = true;
    }
  },

  componentDidMount: function() {
    this.state.events.forEach(function(type) {
      if (window.addEventListener) {
        window.addEventListener(type, this.handleEvent);
      } else {
        window.attachEvent('on' + type, this.handleEvent);
      }
    }, this);
    this.domNode = React.findDOMNode ? React.findDOMNode(this) : this.getDOMNode();
    this.hasUnhandledEvent = true;
    this.tick();
  },

  componentWillUnmount: function() {
    this.state.events.forEach(function(type) {
      if (window.removeEventListener) {
        window.removeEventListener(type, this.handleEvent);
      } else {
        window.detachEvent('on' + type, this.handleEvent)
      }
    }, this);
    this.domNode = null;
    this.cancel();
  },

  isModernBrowser: function() {
    return window && window.requestAnimationFrame && window.cancelAnimationFrame;
  },

  cancel: function() {
    var cancel = this.isModernBrowser() ? cancelAnimationFrame : clearTimeout;
    cancel(this.currentTick);
  },

  tick: function () {
    var next = this.isModernBrowser() ? requestAnimationFrame : setTimeout;
    this.currentTick = next(this.handleTick, 1000 / 60);
  },

  nextStyle: function(shouldBeSticky) {
    if (shouldBeSticky) {
      var copyStyles = function(dest, source) {
        for (var rule in source) {
          dest[rule] = source[rule];
        };
        return dest;
      }
      return copyStyles(copyStyles({}, this.props.style), this.props.stickyStyle)
    } else {
      return this.props.style;
    }
  },

  nextClassName: function(shouldBeSticky) {
    return [this.props.className]
      .concat(shouldBeSticky ? this.props.stickyClass : undefined)
      .join(' ');
  },

  nextState: function(shouldBeSticky) {
    this.setState({
      isSticky: shouldBeSticky,
      style: this.nextStyle(shouldBeSticky),
      className: this.nextClassName(shouldBeSticky)
    });
    this.props.onStickyStateChange(shouldBeSticky);
  },

  render: function() {
    return this.props.type({
      style: this.state.style,
      className: this.state.className
    }, this.props.children);
  }
});

module.exports = Sticky;
<|endoftext|>


<commit_before>var React = require('react');

var Sticky = React.createClass({

  statics: {
    __frame: null,
    __instances: [],
    register: function(instance) {
      Sticky.__instances.push(instance);
      Sticky.__instances.sort(function(a, b) {
        if (a.top() > b.top()) return 1;
        if (b.top() > a.top()) return -1;
        return 0;
      });
      if (Sticky.__frame === null) Sticky.resumeLoop();
    },
    unregister: function(instance) {
      var index = Sticky.__instances.indexOf(instance);
      if (index > -1) Sticky.__instances.splice(index, 1);
      if (Sticky.__instances.length === 0) Sticky.cancelLoop();
    },
    instancesAbove: function(instance) {
      return Sticky.__instances.slice(0, Sticky.__instances.indexOf(instance));
    },
    isModernBrowser: function() {
      return window && window.requestAnimationFrame && window.cancelAnimationFrame;
    },
    resumeLoop: function() {
      var nextFrame = Sticky.isModernBrowser() ? requestAnimationFrame : setTimeout;
      Sticky.__frame = nextFrame(Sticky.onFrame, 1000 / 60);
    },
    cancelLoop: function() {
      var cancel = Sticky.isModernBrowser() ? cancelAnimationFrame : clearTimeout;
      cancel(Sticky.__frame);
      Sticky.__frame = null;
    },
    onFrame: function() {
      for (var i = 0; i < Sticky.__instances.length; i++) {
        var sticky = Sticky.__instances[i];
        if (sticky.isMounted()) sticky.handleFrame();
        else Sticky.unregister(sticky);
      }
      Sticky.resumeLoop();
    }
  },

  getDefaultProps: function() {
    return {
      type: React.DOM.div,
      className: '',
      style: {},
      stickyClass: 'sticky',
      stickyStyle: {
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        zIndex: 1
      },
      topOffset: 0,
      onStickyStateChange: function () {}
    };
  },

  getInitialState: function() {
    return {
      events: ['scroll', 'resize', 'touchmove', 'touchend']
    };
  },

  pageOffset: function() {
    var otherStickies = Sticky.instancesAbove(this);
    var otherStickyOffsets = 0;
    for (var i = 0; i < otherStickies.length; i++) {
      var otherSticky = otherStickies[i];
      if (otherSticky.state.isSticky) {
        otherStickyOffsets += otherSticky.domNode.getBoundingClientRect().height;
      }
    }
    return (window.pageYOffset || document.documentElement.scrollTop) + otherStickyOffsets;
  },

  top: function() {
    return this.domNode.getBoundingClientRect().top;
  },

  shouldBeSticky: function() {
    return this.pageOffset() > this.origin + this.props.topOffset;
  },

  handleFrame: function() {
    if (this.hasUnhandledEvent || this.hasTouchEvent) {
      var shouldBeSticky = this.shouldBeSticky();
      this.nextState(shouldBeSticky);
      this.hasUnhandledEvent = false;
    }
  },

  handleEvent: function(event) {
    switch (event.type) {
      case 'touchmove':
        this.hasTouchEvent = true;
        break;
      case 'touchend':
        this.hasTouchEvent = false;
        break;
      default:
        this.hasUnhandledEvent = true;
    }
  },

  componentDidMount: function() {
    this.state.events.forEach(function(type) {
      if (window.addEventListener) {
        window.addEventListener(type, this.handleEvent);
      } else {
        window.attachEvent('on' + type, this.handleEvent);
      }
    }, this);
    this.domNode = React.findDOMNode ? React.findDOMNode(this) : this.getDOMNode();
    this.origin = this.top() + this.pageOffset();
    this.hasUnhandledEvent = true;
    Sticky.register(this);
  },

  componentWillUnmount: function() {
    this.state.events.forEach(function(type) {
      if (window.removeEventListener) {
        window.removeEventListener(type, this.handleEvent);
      } else {
        window.detachEvent('on' + type, this.handleEvent)
      }
    }, this);
    this.domNode = null;
    Sticky.unregister(this);
  },

  nextStyle: function(shouldBeSticky) {
    if (shouldBeSticky) {
      var copyStyles = function(dest, source) {
        for (var rule in source) {
          dest[rule] = source[rule];
        };
        return dest;
      }
      return copyStyles(copyStyles({}, this.props.style), this.props.stickyStyle)
    } else {
      return this.props.style;
    }
  },

  nextClassName: function(shouldBeSticky) {
    var className = this.props.className;
    if (shouldBeSticky) {
      className += ' ' + this.props.stickyClass;
    }
    return className;
  },

  nextState: function(shouldBeSticky) {
    var hasChanged = this.state.isSticky !== shouldBeSticky;
    this.setState({
      isSticky: shouldBeSticky,
      style: this.nextStyle(shouldBeSticky),
      className: this.nextClassName(shouldBeSticky)
    });
    if (hasChanged) this.props.onStickyStateChange(shouldBeSticky);
  },

  render: function() {
    return this.props.type({
      style: this.state.style,
      className: this.state.className
    }, this.props.children);
  }
});

module.exports = Sticky;
<commit_msg>minor corrections<commit_after>var React = require('react');

var Sticky = React.createClass({

  statics: {
    __frame: null,
    __instances: [],
    register: function(instance) {
      Sticky.__instances.push(instance);
      Sticky.__instances.sort(function(a, b) {
        if (a.top() > b.top()) return 1;
        if (b.top() > a.top()) return -1;
        return 0;
      });
      if (Sticky.__frame === null) Sticky.resumeLoop();
    },
    unregister: function(instance) {
      var index = Sticky.__instances.indexOf(instance);
      if (index > -1) Sticky.__instances.splice(index, 1);
      if (Sticky.__instances.length === 0) Sticky.cancelLoop();
    },
    instancesAbove: function(instance) {
      return Sticky.__instances.slice(0, Sticky.__instances.indexOf(instance));
    },
    isModernBrowser: function() {
      return window && window.requestAnimationFrame && window.cancelAnimationFrame;
    },
    resumeLoop: function() {
      var nextFrame = Sticky.isModernBrowser() ? requestAnimationFrame : setTimeout;
      Sticky.__frame = nextFrame(Sticky.onFrame, 1000 / 60);
    },
    cancelLoop: function() {
      var cancel = Sticky.isModernBrowser() ? cancelAnimationFrame : clearTimeout;
      cancel(Sticky.__frame);
      Sticky.__frame = null;
    },
    onFrame: function() {
      for (var i = 0; i < Sticky.__instances.length; i++) {
        var sticky = Sticky.__instances[i];
        sticky.handleFrame();
      }
      Sticky.resumeLoop();
    }
  },

  getDefaultProps: function() {
    return {
      type: React.DOM.div,
      className: '',
      style: {},
      stickyClass: 'sticky',
      stickyStyle: {
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        zIndex: 1
      },
      topOffset: 0,
      onStickyStateChange: function () {}
    };
  },

  getInitialState: function() {
    return {
      events: ['scroll', 'resize', 'touchmove', 'touchend']
    };
  },

  pageOffset: function() {
    var otherStickies = Sticky.instancesAbove(this);
    var otherStickyOffsets = 0;
    for (var i = 0; i < otherStickies.length; i++) {
      var otherSticky = otherStickies[i];
      if (otherSticky.state.isSticky) {
        otherStickyOffsets += otherSticky.domNode.getBoundingClientRect().height;
      }
    }
    return (window.pageYOffset || document.documentElement.scrollTop) + otherStickyOffsets;
  },

  top: function() {
    return this.domNode.getBoundingClientRect().top;
  },

  shouldBeSticky: function() {
    return this.pageOffset() >= this.origin + this.props.topOffset;
  },

  handleFrame: function() {
    if (this.hasUnhandledEvent || this.hasTouchEvent) {
      var shouldBeSticky = this.shouldBeSticky();
      this.nextState(shouldBeSticky);
      this.hasUnhandledEvent = false;
    }
  },

  handleEvent: function(event) {
    switch (event.type) {
      case 'touchmove':
        this.hasTouchEvent = true;
        break;
      case 'touchend':
        this.hasTouchEvent = false;
        break;
      default:
        this.hasUnhandledEvent = true;
    }
  },

  componentDidMount: function() {
    this.state.events.forEach(function(type) {
      if (window.addEventListener) {
        window.addEventListener(type, this.handleEvent);
      } else {
        window.attachEvent('on' + type, this.handleEvent);
      }
    }, this);
    this.domNode = React.findDOMNode ? React.findDOMNode(this) : this.getDOMNode();
    this.origin = this.top() + this.pageOffset();
    this.hasUnhandledEvent = true;
    Sticky.register(this);
  },

  componentWillUnmount: function() {
    this.state.events.forEach(function(type) {
      if (window.removeEventListener) {
        window.removeEventListener(type, this.handleEvent);
      } else {
        window.detachEvent('on' + type, this.handleEvent)
      }
    }, this);
    this.domNode = null;
    Sticky.unregister(this);
  },

  nextStyle: function(shouldBeSticky) {
    if (shouldBeSticky) {
      var copyStyles = function(dest, source) {
        for (var rule in source) {
          dest[rule] = source[rule];
        };
        return dest;
      }
      return copyStyles(copyStyles({}, this.props.style), this.props.stickyStyle)
    } else {
      return this.props.style;
    }
  },

  nextClassName: function(shouldBeSticky) {
    var className = this.props.className;
    if (shouldBeSticky) {
      className += ' ' + this.props.stickyClass;
    }
    return className;
  },

  nextState: function(shouldBeSticky) {
    var hasChanged = this.state.isSticky !== shouldBeSticky;
    this.setState({
      isSticky: shouldBeSticky,
      style: this.nextStyle(shouldBeSticky),
      className: this.nextClassName(shouldBeSticky)
    });
    if (hasChanged) this.props.onStickyStateChange(shouldBeSticky);
  },

  render: function() {
    return this.props.type({
      style: this.state.style,
      className: this.state.className
    }, this.props.children);
  }
});

module.exports = Sticky;
<|endoftext|>


<commit_before>import urlRegex from 'url-regex';

export function createPostbackAction(label, input, issuedAt) {
  return {
    type: 'postback',
    label,
    data: JSON.stringify({
      input,
      issuedAt,
    }),
  };
}

/**
 * @param {number} positive - Count of positive feedbacks
 * @param {number} negative - Count of negative feedbacks
 * @return {string} Description of feedback counts
 */
export function createFeedbackWords(positive, negative) {
  if (positive + negative === 0) return '[還沒有人針對此回應評價]';
  let result = '';
  if (positive) result += `有 ${positive} 人覺得此回應有幫助\n`;
  if (negative) result += `有 ${negative} 人覺得此回應沒幫助\n`;
  return `[${result.trim()}]`;
}

export function createTypeWords(type) {
  switch (type) {
    case 'RUMOR':
      return '❌ 含有不實訊息';
    case 'NOT_RUMOR':
      return '⭕ 含有真實訊息';
    case 'OPINIONATED':
      return '💬 含有個人意見';
    case 'NOT_ARTICLE':
      return '⚠ 不在查證範圍';
  }
  return '回應的狀態未定義！';
}

/**
 * @param {object} reply The reply object
 * @param {string} reply.reference
 * @param {string} reply.type
 * @returns {string} The reference message to send
 */
export function createReferenceWords({ reference, type }) {
  const prompt = type === 'OPINIONATED' ? '不同觀點請見' : '出處';

  if (reference) return `${prompt}：${reference}`;
  return `\uDBC0\uDC85 ⚠ 此回應沒有${prompt}，請自行斟酌回應真實。⚠  \uDBC0\uDC85`;
}

export function createAskArticleSubmissionReply(issuedAt) {
  return {
    type: 'template',
    altText: '【送出訊息到公開資料庫？】\n' +
      '若這是「轉傳訊息」，而且您覺得這很可能是一則「謠言」，請將這則訊息送進公開資料庫建檔，讓好心人查證與回覆。\n' +
      '雖然您不會立刻收到查證結果，但可以幫助到未來同樣收到這份訊息的人。\n' +
      '\n' +
      '「送出」請輸入「y」，「放棄」則請輸入「n」或其他單一字母。',
    template: {
      type: 'buttons',
      text: '【送出訊息到公開資料庫？】\n' +
        '若這是「轉傳訊息」，而且您覺得這很可能是一則「謠言」，請將這則訊息送進公開資料庫建檔，讓好心人查證與回覆。\n' +
        '雖然您不會立刻收到查證結果，但可以幫助到未來同樣收到這份訊息的人。\n',
      actions: [
        createPostbackAction('我要送出', 'y', issuedAt),
        createPostbackAction('放棄', 'n', issuedAt),
      ],
    },
  };
}

export function isNonsenseText(text) {
  let urls = text.match(urlRegex()) || [];
  let sum = urls.reduce((sum, url) => sum + url.length, 0);
  return text.length - sum < 15;
}

const ELLIPSIS = '⋯⋯';

/**
 * @param {string} text
 * @param {number} limit
 * @return {string} if the text length is lower than limit, return text; else, return
 *                  text with ellipsis.
 */
export function ellipsis(text, limit) {
  if (text.length < limit) return text;

  return text.slice(0, limit - ELLIPSIS.length) + ELLIPSIS;
}

const SITE_URL = process.env.SITE_URL || 'https://cofacts.g0v.tw';

/**
 * @param {string} articleId
 * @returns {string} The article's full URL
 */
export function getArticleURL(articleId) {
  return `${SITE_URL}/article/${articleId}`;
}
<commit_msg>Add jsdoc for createAskArticleSubmissionReply<commit_after>import urlRegex from 'url-regex';

export function createPostbackAction(label, input, issuedAt) {
  return {
    type: 'postback',
    label,
    data: JSON.stringify({
      input,
      issuedAt,
    }),
  };
}

/**
 * @param {number} positive - Count of positive feedbacks
 * @param {number} negative - Count of negative feedbacks
 * @return {string} Description of feedback counts
 */
export function createFeedbackWords(positive, negative) {
  if (positive + negative === 0) return '[還沒有人針對此回應評價]';
  let result = '';
  if (positive) result += `有 ${positive} 人覺得此回應有幫助\n`;
  if (negative) result += `有 ${negative} 人覺得此回應沒幫助\n`;
  return `[${result.trim()}]`;
}

export function createTypeWords(type) {
  switch (type) {
    case 'RUMOR':
      return '❌ 含有不實訊息';
    case 'NOT_RUMOR':
      return '⭕ 含有真實訊息';
    case 'OPINIONATED':
      return '💬 含有個人意見';
    case 'NOT_ARTICLE':
      return '⚠ 不在查證範圍';
  }
  return '回應的狀態未定義！';
}

/**
 * @param {object} reply The reply object
 * @param {string} reply.reference
 * @param {string} reply.type
 * @returns {string} The reference message to send
 */
export function createReferenceWords({ reference, type }) {
  const prompt = type === 'OPINIONATED' ? '不同觀點請見' : '出處';

  if (reference) return `${prompt}：${reference}`;
  return `\uDBC0\uDC85 ⚠ 此回應沒有${prompt}，請自行斟酌回應真實。⚠  \uDBC0\uDC85`;
}

/**
 * @param {number} issuedAt The "issuedAt" to put in postback action
 * @returns {object} a reply message instance
 */
export function createAskArticleSubmissionReply(issuedAt) {
  return {
    type: 'template',
    altText: '【送出訊息到公開資料庫？】\n' +
      '若這是「轉傳訊息」，而且您覺得這很可能是一則「謠言」，請將這則訊息送進公開資料庫建檔，讓好心人查證與回覆。\n' +
      '雖然您不會立刻收到查證結果，但可以幫助到未來同樣收到這份訊息的人。\n' +
      '\n' +
      '「送出」請輸入「y」，「放棄」則請輸入「n」或其他單一字母。',
    template: {
      type: 'buttons',
      text: '【送出訊息到公開資料庫？】\n' +
        '若這是「轉傳訊息」，而且您覺得這很可能是一則「謠言」，請將這則訊息送進公開資料庫建檔，讓好心人查證與回覆。\n' +
        '雖然您不會立刻收到查證結果，但可以幫助到未來同樣收到這份訊息的人。\n',
      actions: [
        createPostbackAction('我要送出', 'y', issuedAt),
        createPostbackAction('放棄', 'n', issuedAt),
      ],
    },
  };
}

export function isNonsenseText(text) {
  let urls = text.match(urlRegex()) || [];
  let sum = urls.reduce((sum, url) => sum + url.length, 0);
  return text.length - sum < 15;
}

const ELLIPSIS = '⋯⋯';

/**
 * @param {string} text
 * @param {number} limit
 * @return {string} if the text length is lower than limit, return text; else, return
 *                  text with ellipsis.
 */
export function ellipsis(text, limit) {
  if (text.length < limit) return text;

  return text.slice(0, limit - ELLIPSIS.length) + ELLIPSIS;
}

const SITE_URL = process.env.SITE_URL || 'https://cofacts.g0v.tw';

/**
 * @param {string} articleId
 * @returns {string} The article's full URL
 */
export function getArticleURL(articleId) {
  return `${SITE_URL}/article/${articleId}`;
}
<|endoftext|>


<commit_before>import React from 'react';
import { array, string, object, objectOf, func } from 'prop-types';
import { Container, Header, Left, Title } from 'native-base';
import bindActionCreators from 'redux/lib/bindActionCreators';
import connect from 'react-redux/lib/connect/connect';
import compose from 'recompose/compose';
import pure from 'recompose/pure';

import FloatingButton from '../components/common/FloatingButton';
import TodoList from '../components/list/TodoList';
import Footer from '../components/list/Footer';

import withBackButton from '../components/common/hoc/withBackButton';

import * as TodoActions from '../redux/todo/actions';
import * as TodoSelectors from '../redux/todo/selector';

const mapStateToProps = state => ({
    items: TodoSelectors.getVisibleTodos(state),
    filter: state.todo.filter
});

const mapDispatchToProps = dispatch => ({
    actions: bindActionCreators(TodoActions, dispatch)
});

const enhance = compose(
    connect(mapStateToProps, mapDispatchToProps),
    withBackButton(),
    pure
);

@enhance
export default class Todos extends React.Component {
    static displayName = 'Todo App';

    static propTypes = {
        items: array.isRequired,
        filter: string.isRequired,
        navigation: object.isRequired,
        actions: objectOf(func).isRequired
    };

    render() {
        const styles = this.getStyles(this.props);

        return (
            <Container>
                <Header style={styles.header}>
                    <Left>
                        <Title style={styles.title}>
                            {Todos.displayName}
                        </Title>
                    </Left>
                </Header>
                <TodoList
                    items={this.props.items}
                    filter={this.props.filter}
                    toggleTodo={this.props.actions.toggleTodo}
                    removeTodo={this.props.actions.removeTodo}
                />
                <FloatingButton onPress={this.addTodo}/>
                <Footer
                    currentFilter={this.props.filter}
                    changeFilter={this.props.actions.visibilityFilter}
                />
            </Container>
        );
    }

    getStyles = (props) => ({
        header: {
            backgroundColor: '#673AB7'
        },
        title: {
            color: '#FFFFFF'
        }
    });

    addTodo = () => {
        this.props.navigation.navigate('AddTodo');
        this.props.actions.visibilityFilter('all');
    };
}<commit_msg>Removing FloatingActionButton from IOS to give more consistence<commit_after>import React from 'react';
import { Platform } from 'react-native';
import { array, string, object, objectOf, func } from 'prop-types';
import { Container, Header, Left, Right, Title, Button, Body } from 'native-base';
import Icon from 'react-native-vector-icons/MaterialIcons';
import bindActionCreators from 'redux/lib/bindActionCreators';
import connect from 'react-redux/lib/connect/connect';
import compose from 'recompose/compose';
import pure from 'recompose/pure';

import FloatingActionButton from '../components/common/FloatingButton';
import TodoList from '../components/list/TodoList';
import Footer from '../components/list/Footer';

import withBackButton from '../components/common/hoc/withBackButton';

import * as TodoActions from '../redux/todo/actions';
import * as TodoSelectors from '../redux/todo/selector';

const mapStateToProps = state => ({
    items: TodoSelectors.getVisibleTodos(state),
    filter: state.todo.filter
});

const mapDispatchToProps = dispatch => ({
    actions: bindActionCreators(TodoActions, dispatch)
});

const enhance = compose(
    connect(mapStateToProps, mapDispatchToProps),
    withBackButton(),
    pure
);

@enhance
export default class Todos extends React.Component {
    static displayName = 'Todo App';

    static propTypes = {
        items: array.isRequired,
        filter: string.isRequired,
        navigation: object.isRequired,
        actions: objectOf(func).isRequired
    };

    render() {
        const styles = this.getStyles(this.props);

        const addTodoButton = (
            <Right>
                <Button
                    onPress={this.addTodo}
                    transparent
                >
                    <Icon
                        name='add'
                        size={30}
                        color='#FFFFFF'
                    />
                </Button>
            </Right>
        );

        const title = (
            <Title style={styles.title}>
                {Todos.displayName}
            </Title>
        );

        return (
            <Container>
                <Header style={styles.header}>
                    {Platform.OS === 'ios' && <Left/>}
                    {Platform.OS === 'ios' && <Body>{title}</Body>}
                    {Platform.OS === 'ios' && addTodoButton}
                    {Platform.OS === 'android' && <Left>{title}</Left>}
                </Header>
                <TodoList
                    items={this.props.items}
                    filter={this.props.filter}
                    toggleTodo={this.props.actions.toggleTodo}
                    removeTodo={this.props.actions.removeTodo}
                />
                {Platform.OS === 'android' && <FloatingActionButton onPress={this.addTodo}/>}
                <Footer
                    currentFilter={this.props.filter}
                    changeFilter={this.props.actions.visibilityFilter}
                />
            </Container>
        );
    }

    getStyles = (props) => ({
        header: {
            backgroundColor: '#673AB7'
        },
        title: {
            color: '#FFFFFF'
        }
    });

    addTodo = () => {
        this.props.navigation.navigate('AddTodo');
        this.props.actions.visibilityFilter('all');
    };
}<|endoftext|>


<commit_before>/*
 Extensions Compatibility Library

 Usage:
   Asynchronus:
     var extensions = window['piro.sakura.ne.jp'].extensions;
     extensions.isAvailable('my.extension.id@example.com', {
       ok : function() { extensions.goToOptions('my.extension.id@example.com'); },
       ng : function() { alert('NOT INSTALLED'); }
     });
     // just same to:
     // extensions.isInstalled('my.extension.id@example.com', {
     //   ok : function() {
     //     extensions.isEnabled('my.extension.id@example.com', {
     //       ok : function() { extensions.goToOptions('my.extension.id@example.com'); }
     //     });
     //   }
     // });
     extensions.isInstalled('my.extension.id@example.com', {
       ok : function(aDir) {
         var dir = aDir; // nsILocalFile
       }
     });

   Synchronus: (DEPRECATED)
     if (extensions.isAvailable('my.extension.id@example.com'))
         extensions.goToOptions('my.extension.id@example.com');
     // just same to:
     // if (extensions.isInstalled('my.extension.id@example.com') &&
     //     extensions.isEnabled('my.extension.id@example.com'))
     //     extensions.goToOptions('my.extension.id@example.com');
     var dir = extensions.getInstalledLocation('my.extension.id@example.com'); // nsILocalFile

 lisence: The MIT License, Copyright (c) 2009-2010 SHIMODA "Piro" Hiroshi
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/license.txt
 original:
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/extensions.js
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/extensions.test.js
*/

/* To work as a JS Code Module */
if (typeof window == 'undefined') {
	this.EXPORTED_SYMBOLS = ['extensions'];

	// If namespace.jsm is available, export symbols to the shared namespace.
	// See: http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/namespace.jsm
	try {
		let ns = {};
		Components.utils.import('resource://my-modules/namespace.jsm', ns);
		/* var */ window = ns.getNamespaceFor('piro.sakura.ne.jp');
	}
	catch(e) {
		window = {};
	}
}

(function() {
	const currentRevision = 9;

	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};

	var loadedRevision = 'extensions' in window['piro.sakura.ne.jp'] ?
			window['piro.sakura.ne.jp'].extensions.revision :
			0 ;
	if (loadedRevision && loadedRevision > currentRevision) {
		return;
	}

	const Cc = Components.classes;
	const Ci = Components.interfaces;

	// Firefox 3.7 or later
	var AM = {};
	if ('@mozilla.org/addons/integration;1' in Cc)
		Components.utils.import('resource://gre/modules/AddonManager.jsm', AM);

	window['piro.sakura.ne.jp'].extensions = {
		revision : currentRevision,

		// Firefox 3.7 or later
		_getInstalledAddonNow : function(aId)
		{
			var addon;
			AM.AddonManager.getAddonByID(aId, function(aAddon) {
				addon = aAddon;
			});
			var thread = Cc['@mozilla.org/thread-manager;1']
							.getService()
							.mainThread;
			while (addon === void(0)) {
				thread.processNextEvent(true);
			}
			return addon;
		},

		_formatCallbacks : function(aOKCallback, aNGCallback)
		{
			var callbacks = {
					ok : aOKCallback,
					ng : aNGCallback
				};
			if (typeof aOKCallback != 'function')
				callbacks = aOKCallback;

			if (!('ok' in callbacks) || typeof callbacks.ok != 'function')
				callbacks.ok = function() {};
			if (!('ng' in callbacks) || typeof callbacks.ng != 'function')
				callbacks.ng = function() {};

			return callbacks;
		},

		// Firefox 3.6 or older
		_ExtensionManager : ('@mozilla.org/extensions/manager;1' in Cc) ?
			Cc['@mozilla.org/extensions/manager;1']
				.getService(Ci.nsIExtensionManager) :
			null,
		_RDF : Cc['@mozilla.org/rdf/rdf-service;1']
			.getService(Ci.nsIRDFService),
		_WindowMediator : Cc['@mozilla.org/appshell/window-mediator;1']
			.getService(Ci.nsIWindowMediator),
		_Prefs : Cc['@mozilla.org/preferences;1']
			.getService(Ci.nsIPrefBranch),

		isAvailable : function(aId, aOKCallback, aNGCallback)
		{
			if (!aOKCallback)
				return this._ExtensionManager ? this._isAvailable_EM(aId) : this._isAvailable_AM(aId) ;

			var callbacks = this._formatCallbacks(aOKCallback, aNGCallback);
			if (this._ExtensionManager) {
				callbacks[this._isAvailable_EM(aId) ? 'ok' : 'ng']();
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					callbacks[aAddon && aAddon.isActive ? 'ok' : 'ng']();
				});
			}
		},
		_isAvailable_EM : function(aId)
		{
			return (this._isInstalled_EM(aId) && this._isEnabled_EM(aId)) ? true : false ;
		},
		_isAvailable_AM : function(aId)
		{
			var addon = this._getInstalledAddonNow(aId);
			return addon ? addon.isActive : false ;
		},

		isInstalled : function(aId, aOKCallback, aNGCallback)
		{
			if (!aOKCallback)
				return this._ExtensionManager ? this._isInstalled_EM(aId) : this._isInstalled_AM(aId) ;

			var callbacks = this._formatCallbacks(aOKCallback, aNGCallback);
			if (this._ExtensionManager) {
				callbacks[this._isInstalled_EM(aId) ? 'ok' : 'ng']();
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					callbacks[aAddon ? 'ok' : 'ng']();
				});
			}
		},
		_isInstalled_EM : function(aId)
		{
			return this._ExtensionManager.getInstallLocation(aId) ? true : false ;
		},
		_isInstalled_AM : function(aId)
		{
			return this._getInstalledAddonNow(aId) ? true : false ;
		},

		isEnabled : function(aId, aOKCallback, aNGCallback)
		{
			if (!aOKCallback)
				return this._ExtensionManager ? this._isEnabled_EM(aId) : this._isAvailable_AM(aId) ;

			var callbacks = this._formatCallbacks(aOKCallback, aNGCallback);
			if (this._ExtensionManager)
				callbacks[this._isEnabled_EM(aId) ? 'ok' : 'ng']();
			else
				this.isAvailable(aId, callbacks);
		},
		_isEnabled_EM : function(aId)
		{
			if (!this._isInstalled_EM(aId))
				return false;

			var res  = this._RDF.GetResource('urn:mozilla:item:'+aId);
			var appDisabled = false;
			try {
				appDisabled = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#appDisabled'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value == 'true';
			}
			catch(e) {
			}
			var userDisabled = false;
			try {
				userDisabled = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#userDisabled'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value == 'true';
			}
			catch(e) {
			}

			return !appDisabled && !userDisabled;
		},

		getInstalledLocation : function(aId, aCallback)
		{
			if (!aCallback)
				return this._ExtensionManager ? this._getInstalledLocation_EM(aId) : this._getInstalledLocation_AM(aId) ;

			if (this._ExtensionManager) {
				aCallback(this._getInstalledLocation_EM(aId));
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					var location = null;
					if (aAddon && aAddon.isActive)
						location = aAddon.getResourceURI('/').QueryInterface(Ci.nsIFileURL).file.clone();
					aCallback(location);
				});
			}
		},
		_getInstalledLocation_EM : function(aId)
		{
			var addon = this._ExtensionManager.getInstallLocation(aId);
			if (!addon) return null;
			var dir = addon.location.clone();
			dir.append(aId);
			return dir;
		},
		_getInstalledLocation_AM : function(aId)
		{
			var addon = this._getInstalledAddonNow(aId);
			if (!addon || !addon.isActive) return null;
			return addon.getResourceURI('/').QueryInterface(Ci.nsIFileURL).file.clone();
		},

		getVersion : function(aId, aCallback)
		{
			if (!aCallback)
				return this._ExtensionManager ? this._getVersion_EM(aId) : this._getVersion_AM(aId) ;

			if (this._ExtensionManager) {
				aCallback(this._getVersion_EM(aId));
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					aCallback(aAddon ? aAddon.version : null );
				});
			}
		},
		_getVersion_EM : function(aId)
		{
			if (!this._isInstalled_EM(aId))
				return null;

			var res  = this._RDF.GetResource('urn:mozilla:item:'+aId);
			var version = null;
			try {
				version = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#version'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value;
			}
			catch(e) {
			}
			return version;
		},
		_getVersion_AM : function(aId)
		{
			var addon = this._getInstalledAddonNow(aId);
			return addon ? addon.version : null ;
		},

		goToOptions : function(aId, aOwnerWindow)
		{
			var self = this;
			var callback = function(aURI) {
					self.goToOptionsInternal(aURI, aOwnerWindow);
				};
			return this._ExtensionManager ? this._getOptionsURI_EM(aId, callback) : this._getOptionsURI_AM(aId, callback);
		},
		_getOptionsURI_EM : function(aId, aCallback)
		{
			var res  = this._RDF.GetResource('urn:mozilla:item:'+aId);
			var uri = null;
			try {
				uri = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#optionsURL'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value;
			}
			catch(e) {
			}
			return aCallback ? aCallback(uri) : uri ;
		},
		_getOptionsURI_AM : function(aId, aCallback)
		{
			if (aCallback) {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					aCallback(aAddon && aAddon.isActive ? aAddon.optionsURL : null );
				});
				return null;
			}
			else {
				var addon = this._getInstalledAddonNow(aId);
				return (addon && addon.isActive) ? addon.optionsURL : null ;
			}
		},

		goToOptionsNow : function(aId, aOwnerWindow)
		{
			this.goToOptionsInternal(
				(this._ExtensionManager ? this._getOptionsURI_EM(aId) : this._getOptionsURI_AM(aId) ),
				aOwnerWindow
			);
		},

		goToOptionsInternal : function(aURI, aOwnerWindow)
		{
			if (!aURI) return;

			var windows = this._WindowMediator.getEnumerator(null);
			while (windows.hasMoreElements())
			{
				let win = windows.getNext();
				if (win.location.href == uri) {
					win.focus();
					return;
				}
			}
			var instantApply = false;
			try {
				instantApply = this._Prefs.getBoolPref('browser.preferences.instantApply');
			}
			catch(e) {
			}
			(aOwnerWindow || window).openDialog(
				uri,
				'',
				'chrome,titlebar,toolbar,centerscreen,' + (instantApply ? 'dialog=no' : 'modal' )
			);
		}
	};
})();

if (window != this) { // work as a JS Code Module
	this.extensions = window['piro.sakura.ne.jp'].extensions;
}
<commit_msg>isEnabledとisAvailableで同じ値を返すように<commit_after>/*
 Extensions Compatibility Library

 Usage:
   Asynchronus:
     var extensions = window['piro.sakura.ne.jp'].extensions;
     extensions.isAvailable('my.extension.id@example.com', {
       ok : function() { extensions.goToOptions('my.extension.id@example.com'); },
       ng : function() { alert('NOT INSTALLED'); }
     });
     extensions.isInstalled('my.extension.id@example.com', {
       ok : function(aDir) {
         var dir = aDir; // nsILocalFile
       }
     });

   Synchronus: (DEPRECATED)
     if (extensions.isAvailable('my.extension.id@example.com'))
         extensions.goToOptions('my.extension.id@example.com');
     var dir = extensions.getInstalledLocation('my.extension.id@example.com'); // nsILocalFile

 lisence: The MIT License, Copyright (c) 2009-2010 SHIMODA "Piro" Hiroshi
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/license.txt
 original:
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/extensions.js
   http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/extensions.test.js
*/

/* To work as a JS Code Module */
if (typeof window == 'undefined') {
	this.EXPORTED_SYMBOLS = ['extensions'];

	// If namespace.jsm is available, export symbols to the shared namespace.
	// See: http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/namespace.jsm
	try {
		let ns = {};
		Components.utils.import('resource://my-modules/namespace.jsm', ns);
		/* var */ window = ns.getNamespaceFor('piro.sakura.ne.jp');
	}
	catch(e) {
		window = {};
	}
}

(function() {
	const currentRevision = 9;

	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};

	var loadedRevision = 'extensions' in window['piro.sakura.ne.jp'] ?
			window['piro.sakura.ne.jp'].extensions.revision :
			0 ;
	if (loadedRevision && loadedRevision > currentRevision) {
		return;
	}

	const Cc = Components.classes;
	const Ci = Components.interfaces;

	// Firefox 3.7 or later
	var AM = {};
	if ('@mozilla.org/addons/integration;1' in Cc)
		Components.utils.import('resource://gre/modules/AddonManager.jsm', AM);

	window['piro.sakura.ne.jp'].extensions = {
		revision : currentRevision,

		// Firefox 3.7 or later
		_getInstalledAddonNow : function(aId)
		{
			var addon;
			AM.AddonManager.getAddonByID(aId, function(aAddon) {
				addon = aAddon;
			});
			var thread = Cc['@mozilla.org/thread-manager;1']
							.getService()
							.mainThread;
			while (addon === void(0)) {
				thread.processNextEvent(true);
			}
			return addon;
		},

		_formatCallbacks : function(aOKCallback, aNGCallback)
		{
			var callbacks = {
					ok : aOKCallback,
					ng : aNGCallback
				};
			if (typeof aOKCallback != 'function')
				callbacks = aOKCallback;

			if (!('ok' in callbacks) || typeof callbacks.ok != 'function')
				callbacks.ok = function() {};
			if (!('ng' in callbacks) || typeof callbacks.ng != 'function')
				callbacks.ng = function() {};

			return callbacks;
		},

		// Firefox 3.6 or older
		_ExtensionManager : ('@mozilla.org/extensions/manager;1' in Cc) ?
			Cc['@mozilla.org/extensions/manager;1']
				.getService(Ci.nsIExtensionManager) :
			null,
		_RDF : Cc['@mozilla.org/rdf/rdf-service;1']
			.getService(Ci.nsIRDFService),
		_WindowMediator : Cc['@mozilla.org/appshell/window-mediator;1']
			.getService(Ci.nsIWindowMediator),
		_Prefs : Cc['@mozilla.org/preferences;1']
			.getService(Ci.nsIPrefBranch),

		isAvailable : function(aId, aOKCallback, aNGCallback)
		{
			return this.isEnabled(aId, aOKCallback, aNGCallback);
		},

		isInstalled : function(aId, aOKCallback, aNGCallback)
		{
			if (!aOKCallback)
				return this._ExtensionManager ? this._isInstalled_EM(aId) : this._isInstalled_AM(aId) ;

			var callbacks = this._formatCallbacks(aOKCallback, aNGCallback);
			if (this._ExtensionManager) {
				callbacks[this._isInstalled_EM(aId) ? 'ok' : 'ng']();
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					callbacks[aAddon ? 'ok' : 'ng']();
				});
			}
		},
		_isInstalled_EM : function(aId)
		{
			return this._ExtensionManager.getInstallLocation(aId) ? true : false ;
		},
		_isInstalled_AM : function(aId)
		{
			return this._getInstalledAddonNow(aId) ? true : false ;
		},

		isEnabled : function(aId, aOKCallback, aNGCallback)
		{
			if (!aOKCallback)
				return this._ExtensionManager ? this._isEnabled_EM(aId) : this._isEnabled_AM(aId) ;

			var callbacks = this._formatCallbacks(aOKCallback, aNGCallback);
			if (this._ExtensionManager) {
				callbacks[this._isEnabled_EM(aId) ? 'ok' : 'ng']();
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					callbacks[aAddon && aAddon.isActive ? 'ok' : 'ng']();
				});
			}
		},
		_isEnabled_EM : function(aId)
		{
			if (!this._isInstalled_EM(aId))
				return false;

			var res  = this._RDF.GetResource('urn:mozilla:item:'+aId);
			var appDisabled = false;
			try {
				appDisabled = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#appDisabled'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value == 'true';
			}
			catch(e) {
			}
			var userDisabled = false;
			try {
				userDisabled = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#userDisabled'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value == 'true';
			}
			catch(e) {
			}

			return !appDisabled && !userDisabled;
		},
		_isEnabled_AM : function(aId)
		{
			var addon = this._getInstalledAddonNow(aId);
			return addon ? addon.isActive : false ;
		},

		getInstalledLocation : function(aId, aCallback)
		{
			if (!aCallback)
				return this._ExtensionManager ? this._getInstalledLocation_EM(aId) : this._getInstalledLocation_AM(aId) ;

			if (this._ExtensionManager) {
				aCallback(this._getInstalledLocation_EM(aId));
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					var location = null;
					if (aAddon && aAddon.isActive)
						location = aAddon.getResourceURI('/').QueryInterface(Ci.nsIFileURL).file.clone();
					aCallback(location);
				});
			}
		},
		_getInstalledLocation_EM : function(aId)
		{
			var addon = this._ExtensionManager.getInstallLocation(aId);
			if (!addon) return null;
			var dir = addon.location.clone();
			dir.append(aId);
			return dir;
		},
		_getInstalledLocation_AM : function(aId)
		{
			var addon = this._getInstalledAddonNow(aId);
			if (!addon || !addon.isActive) return null;
			return addon.getResourceURI('/').QueryInterface(Ci.nsIFileURL).file.clone();
		},

		getVersion : function(aId, aCallback)
		{
			if (!aCallback)
				return this._ExtensionManager ? this._getVersion_EM(aId) : this._getVersion_AM(aId) ;

			if (this._ExtensionManager) {
				aCallback(this._getVersion_EM(aId));
			}
			else {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					aCallback(aAddon ? aAddon.version : null );
				});
			}
		},
		_getVersion_EM : function(aId)
		{
			if (!this._isInstalled_EM(aId))
				return null;

			var res  = this._RDF.GetResource('urn:mozilla:item:'+aId);
			var version = null;
			try {
				version = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#version'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value;
			}
			catch(e) {
			}
			return version;
		},
		_getVersion_AM : function(aId)
		{
			var addon = this._getInstalledAddonNow(aId);
			return addon ? addon.version : null ;
		},

		goToOptions : function(aId, aOwnerWindow)
		{
			var self = this;
			var callback = function(aURI) {
					self.goToOptionsInternal(aURI, aOwnerWindow);
				};
			return this._ExtensionManager ? this._getOptionsURI_EM(aId, callback) : this._getOptionsURI_AM(aId, callback);
		},
		_getOptionsURI_EM : function(aId, aCallback)
		{
			var res  = this._RDF.GetResource('urn:mozilla:item:'+aId);
			var uri = null;
			try {
				uri = this._ExtensionManager.datasource.GetTarget(
						res,
						this._RDF.GetResource('http://www.mozilla.org/2004/em-rdf#optionsURL'),
						true
					).QueryInterface(Ci.nsIRDFLiteral)
					.Value;
			}
			catch(e) {
			}
			return aCallback ? aCallback(uri) : uri ;
		},
		_getOptionsURI_AM : function(aId, aCallback)
		{
			if (aCallback) {
				AM.AddonManager.getAddonByID(aId, function(aAddon) {
					aCallback(aAddon && aAddon.isActive ? aAddon.optionsURL : null );
				});
				return null;
			}
			else {
				var addon = this._getInstalledAddonNow(aId);
				return (addon && addon.isActive) ? addon.optionsURL : null ;
			}
		},

		goToOptionsNow : function(aId, aOwnerWindow)
		{
			this.goToOptionsInternal(
				(this._ExtensionManager ? this._getOptionsURI_EM(aId) : this._getOptionsURI_AM(aId) ),
				aOwnerWindow
			);
		},

		goToOptionsInternal : function(aURI, aOwnerWindow)
		{
			if (!aURI) return;

			var windows = this._WindowMediator.getEnumerator(null);
			while (windows.hasMoreElements())
			{
				let win = windows.getNext();
				if (win.location.href == uri) {
					win.focus();
					return;
				}
			}
			var instantApply = false;
			try {
				instantApply = this._Prefs.getBoolPref('browser.preferences.instantApply');
			}
			catch(e) {
			}
			(aOwnerWindow || window).openDialog(
				uri,
				'',
				'chrome,titlebar,toolbar,centerscreen,' + (instantApply ? 'dialog=no' : 'modal' )
			);
		}
	};
})();

if (window != this) { // work as a JS Code Module
	this.extensions = window['piro.sakura.ne.jp'].extensions;
}
<|endoftext|>


<commit_before>"use strict";

// dependencies

const I = require("../I");

/**
 * @name Tuple
 * @note combined namespace/constructor
 * @type product type
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  const triple = Tuple(1, "a", true);

  Tuple.toArray(triple); // [1, "a", true]

 */

// (*) -> ((*) -> r) -> r
const Tuple = (...args) => f => f(...args);

/**
 * @name bimap
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));

  const inc = x => x + 1
  const toUC = x => x.toUpperCase();
  const pair = Tuple.bimap(inc) (toUC) (Tuple(1, "a"));

  Tuple.toArray(pair); // [2, "A"]

 */

// (a -> b) -> (c -> d) -> ((a, c) -> r) -> ((b, d) -> r)
Tuple.bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));

/**
 * @name concat
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.concat = tx => ty => tx((...argsx) => ty((...argsy) => Tuple(...argsx, ...argsy)));

  const tuple = Tuple.concat(Tuple(1, "a")) (Tuple(true));
  Tuple.toArray(tuple); // [1, "a", true]

 */

// ((*) -> r) -> ((*) -> r) -> ((*) -> r)
Tuple.concat = tx => ty => tx((...argsx) => ty((...argsy) => Tuple(...argsx, ...argsy)));

/**
 * @name concat by
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.concatBy2 = concat1 => concat2 => tx => ty => tx((w, x) => ty((y, z) => Tuple(concat1(w) (y), concat(x) (z))));

  const add = x => y => x + y;
  const concat = x => y => x.concat(y);
  const pair = Tuple.concatBy2(add) (concat) (Tuple(1, "a")) (Tuple(2, "b"));

  Tuple.toArray(pair); // [3, "ab"]

 */

// (a -> a -> a) -> (a -> r) -> (a -> r) -> (a -> r)
Tuple.concatBy = concat => tx => ty => tx(x => ty(y => Tuple(concat(x) (y))));

// (a -> a -> a) -> (b -> b -> b) -> ((a, b) -> r) -> ((a, b) -> r) -> ((a, b) -> r)
Tuple.concatBy2 = concat1 => concat2 => tx => ty => tx((x1, y1) => ty((x2, y2) => Tuple(concat1(x1) (x2), concat2(y1) (y2))));

// (a -> a -> a) -> (b -> b -> b) -> (c -> c -> c) -> ((a, b, c) -> r) -> ((a, b, c) -> r) -> ((a, b, c) -> r)
Tuple.concatBy3 = concat1 => concat2 => concat3 => tx => ty => tx((x1, y1, z1) => ty((x2, y2, z2) => Tuple(concat1(x1) (x2), concat2(y1) (y2), concat3(z1) (z2))));

/**
 * @name empty
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.empty = Tuple();

  Tuple.toArray(Tuple.empty); // []

 */

// (() -> )
Tuple.empty = Tuple();

/**
 * @name from Array
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.get1 = tx => tx(I);
  Tuple.get2 = tx => tx((x, y) => y);
  Tuple.fromArray = args => Tuple(...args);

  const I = x => x;
  const pair = Tuple.fromArray([1, "a"]);

  Tuple.get1(pair); // 1
  Tuple.get2(pair); // "a"

 */

// [*] -> ((*) -> r)
Tuple.fromArray = args => Tuple(...args);

/**
 * @name get
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.get2 = tx => tx((x, y) => y);

  Tuple.get2(Tuple(1, "a", true)); // "a"

 */

// ((*) -> r) -> r
Tuple.get1 = tx => tx(I);

// ((*) -> r) -> r
Tuple.get2 = tx => tx((x, y) => y);

// ((*) -> r) -> r
Tuple.get3 = tx => tx((x, y, z) => z);

/**
 * @name get nth
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.getn = n => tx => tx((...args) => args[n - 1]);

  Tuple.getn(2) (Tuple(1, "a", true)); // "a"

 */

// Number -> ((*) -> r) -> r
Tuple.getn = n => tx => tx((...args) => args[n - 1]);

/**
 * @name has
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.has = x => tx => tx((...args) => args.includes(x));

  const triple = Tuple(1, "a", true);

  Tuple.has("a") (triple); // true
  Tuple.has(2) (triple); // false

 */

// a -> ((*) -> Boolean) -> Boolean
Tuple.has = x => tx => tx((...args) => args.includes(x));

/**
 * @name last
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.last = tx => tx((...args) => args[args.length - 1]);

  const tuple5 = Tuple(1, "a", true, {foo: true}, ["bar"]);
  Tuple.last(tuple5); // ["bar"]

 */

// ((*) -> r) -> r
Tuple.last = tx => tx((...args) => args[args.length - 1]);

/**
 * @name length
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.len = tx => tx((...args) => args.length);

  Tuple.len(Tuple(1, "a", true)); // 3

 */

// ((*) -> Number) -> Number
Tuple.len = tx => tx((...args) => args.length);

/**
 * @name map
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.map2 = f => tx => tx((x, y, ...args) => Tuple(x, f(y), ...args));

  const toUC = x => x.toUpperCase();

  const triple = Tuple.map2(toUC) (Tuple(1, "a", true));
  Tuple.toArray(triple); // [1, "A", true]

 */

// (a -> b) -> ((*) -> r) -> ((*) -> r)
Tuple.map1 = f => tx => tx((x, ...args) => Tuple(f(x), ...args));

// (a -> b) -> ((*) -> r) -> ((*) -> r)
Tuple.map2 = f => tx => tx((x, y, ...args) => Tuple(x, f(y), ...args));

// (a -> b) -> ((*) -> r) -> ((*) -> r)
Tuple.map3 = f => tx => tx((x, y, z, ...args) => Tuple(x, y, f(z), ...args));

/**
 * @name rotate left
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.rotatel = tx => tx((x, y, z) => Tuple(y, z, x));

  const triple = Tuple.rotatel(Tuple(1, "a", true));
  Tuple.toArray(triple); // ["a", true, 1]

 */

// ((a, b, c) -> r) -> ((b, c, a) -> r)
Tuple.rotatel = tx => tx((x, y, z) => Tuple(y, z, x));

/**
 * @name rotate right
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.rotater = tx => tx((x, y, z) => Tuple(z, x, y));

  const triple = Tuple.rotater(Tuple(1, "a", true));
  Tuple.toArray(triple); // [true, 1, "a"]

 */

// ((a, b, c) -> r) -> ((c, a, b) -> r)
Tuple.rotater = tx => tx((x, y, z) => Tuple(z, x, y));

/**
 * @name set
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.set2 = y => tx => tx((x, _, ...args) => Tuple(x, y, ...args));

  const triple = Tuple.set2("b") (Tuple(1, "a", true));
  Tuple.toArray(triple); // [1, "b", true]

 */

// a -> ((*) -> r) -> ((*) -> r)
Tuple.set1 = x => tx => tx((_, ...args) => Tuple(x, ...args));

// a -> ((*) -> r) -> ((*) -> r)
Tuple.set2 = y => tx => tx((x, _, ...args) => Tuple(x, y, ...args));

// a -> ((*) -> r) -> ((*) -> r)
Tuple.set3 = z => tx => tx((x, y, _, ...args) => Tuple(x, y, z, ...args));

/**
 * @name set nth
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.setn = n => x => tx => tx((...args) => (args[n - 1] = x, Tuple(...args)));

  const triple = Tuple.setn(2) ("b") (Tuple(1, "a", true));
  Tuple.toArray(triple); // [1, "b", true]

 */

// Number -> ((*) -> r) -> r
Tuple.setn = n => x => tx => tx((...args) => (args[n - 1] = x, Tuple(...args)));

/**
 * @name swap
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.swap = tx => tx((x, y) => Tuple(y, x));

  const pair = Tuple.swap(Tuple(1, "a"));
  Tuple.toArray(pair); // ["a", 1]

 */

// ((a, b) -> r) -> ((b, a) -> r)
Tuple.swap = tx => tx((x, y) => Tuple(y, x));

/**
 * @name to array
 * @type first order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);

  Tuple.toArray(Tuple(1, "a", true)); // [1, "a", true]

 */

// ((*) -> r) -> [*]
Tuple.toArray = tx => tx((...args) => args);

/**
 * @name uncurry
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.uncurry = f => tx => tx((...args) => f(args[0]) (args[1]));

  const add = y => x => x + y;
  const pair = Tuple(2, 3);

  Tuple.uncurry(add) (pair); // 5

 */

// (a -> b -> c) -> ((a, b) -> c) -> c
Tuple.uncurry = f => tx => tx((...args) => f(args[0]) (args[1]));

// (a -> b -> c -> d) -> ((a, b, c) -> d) -> d
Tuple.uncurry3 = f => tx => tx((...args) => f(args[0]) (args[1]) (args[2]));

// API

module.exports = Tuple;<commit_msg>Version 0.2.5<commit_after>"use strict";

// dependencies

const I = require("../I");

/**
 * @name Tuple
 * @note combined namespace/constructor
 * @type product type
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  const triple = Tuple(1, "a", true);

  Tuple.toArray(triple); // [1, "a", true]

 */

// (*) -> ((*) -> r) -> r
const Tuple = (...args) => f => f(...args);

/**
 * @name bimap
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));

  const inc = x => x + 1
  const toUC = x => x.toUpperCase();
  const pair = Tuple.bimap(inc) (toUC) (Tuple(1, "a"));

  Tuple.toArray(pair); // [2, "A"]

 */

// (a -> b) -> (c -> d) -> ((a, c) -> r) -> ((b, d) -> r)
Tuple.bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));

/**
 * @name concat
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.concat = tx => ty => tx((...argsx) => ty((...argsy) => Tuple(...argsx, ...argsy)));

  const tuple = Tuple.concat(Tuple(1, "a")) (Tuple(true));
  Tuple.toArray(tuple); // [1, "a", true]

 */

// ((*) -> r) -> ((*) -> r) -> ((*) -> r)
Tuple.concat = tx => ty => tx((...argsx) => ty((...argsy) => Tuple(...argsx, ...argsy)));

/**
 * @name concat by
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.concatBy2 = concat1 => concat2 => tx => ty => tx((w, x) => ty((y, z) => Tuple(concat1(w) (y), concat(x) (z))));

  const add = x => y => x + y;
  const concat = x => y => x.concat(y);
  const pair = Tuple.concatBy2(add) (concat) (Tuple(1, "a")) (Tuple(2, "b"));

  Tuple.toArray(pair); // [3, "ab"]

 */

// (a -> a -> a) -> (a -> r) -> (a -> r) -> (a -> r)
Tuple.concatBy = concat => tx => ty => tx(x => ty(y => Tuple(concat(x) (y))));

// (a -> a -> a) -> (b -> b -> b) -> ((a, b) -> r) -> ((a, b) -> r) -> ((a, b) -> r)
Tuple.concatBy2 = concat1 => concat2 => tx => ty => tx((x1, y1) => ty((x2, y2) => Tuple(concat1(x1) (x2), concat2(y1) (y2))));

// (a -> a -> a) -> (b -> b -> b) -> (c -> c -> c) -> ((a, b, c) -> r) -> ((a, b, c) -> r) -> ((a, b, c) -> r)
Tuple.concatBy3 = concat1 => concat2 => concat3 => tx => ty =>
 tx((x1, y1, z1) => ty((x2, y2, z2) => Tuple(concat1(x1) (x2), concat2(y1) (y2), concat3(z1) (z2))));

/**
 * @name empty
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.empty = Tuple();

  Tuple.toArray(Tuple.empty); // []

 */

// (() -> )
Tuple.empty = Tuple();

/**
 * @name from Array
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.get1 = tx => tx(I);
  Tuple.get2 = tx => tx((x, y) => y);
  Tuple.fromArray = args => Tuple(...args);

  const I = x => x;
  const pair = Tuple.fromArray([1, "a"]);

  Tuple.get1(pair); // 1
  Tuple.get2(pair); // "a"

 */

// [*] -> ((*) -> r)
Tuple.fromArray = args => Tuple(...args);

/**
 * @name get
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.get2 = tx => tx((x, y) => y);

  Tuple.get2(Tuple(1, "a", true)); // "a"

 */

// ((*) -> r) -> r
Tuple.get1 = tx => tx(I);

// ((*) -> r) -> r
Tuple.get2 = tx => tx((x, y) => y);

// ((*) -> r) -> r
Tuple.get3 = tx => tx((x, y, z) => z);

/**
 * @name get nth
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.getn = n => tx => tx((...args) => args[n - 1]);

  Tuple.getn(2) (Tuple(1, "a", true)); // "a"

 */

// Number -> ((*) -> r) -> r
Tuple.getn = n => tx => tx((...args) => args[n - 1]);

/**
 * @name has
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.has = x => tx => tx((...args) => args.includes(x));

  const triple = Tuple(1, "a", true);

  Tuple.has("a") (triple); // true
  Tuple.has(2) (triple); // false

 */

// a -> ((*) -> Boolean) -> Boolean
Tuple.has = x => tx => tx((...args) => args.includes(x));

/**
 * @name last
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.last = tx => tx((...args) => args[args.length - 1]);

  const tuple5 = Tuple(1, "a", true, {foo: true}, ["bar"]);
  Tuple.last(tuple5); // ["bar"]

 */

// ((*) -> r) -> r
Tuple.last = tx => tx((...args) => args[args.length - 1]);

/**
 * @name length
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.len = tx => tx((...args) => args.length);

  Tuple.len(Tuple(1, "a", true)); // 3

 */

// ((*) -> Number) -> Number
Tuple.len = tx => tx((...args) => args.length);

/**
 * @name map
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.map2 = f => tx => tx((x, y, ...args) => Tuple(x, f(y), ...args));

  const toUC = x => x.toUpperCase();

  const triple = Tuple.map2(toUC) (Tuple(1, "a", true));
  Tuple.toArray(triple); // [1, "A", true]

 */

// (a -> b) -> ((*) -> r) -> ((*) -> r)
Tuple.map1 = f => tx => tx((x, ...args) => Tuple(f(x), ...args));

// (a -> b) -> ((*) -> r) -> ((*) -> r)
Tuple.map2 = f => tx => tx((x, y, ...args) => Tuple(x, f(y), ...args));

// (a -> b) -> ((*) -> r) -> ((*) -> r)
Tuple.map3 = f => tx => tx((x, y, z, ...args) => Tuple(x, y, f(z), ...args));

/**
 * @name rotate left
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.rotatel = tx => tx((x, y, z) => Tuple(y, z, x));

  const triple = Tuple.rotatel(Tuple(1, "a", true));
  Tuple.toArray(triple); // ["a", true, 1]

 */

// ((a, b, c) -> r) -> ((b, c, a) -> r)
Tuple.rotatel = tx => tx((x, y, z) => Tuple(y, z, x));

/**
 * @name rotate right
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.rotater = tx => tx((x, y, z) => Tuple(z, x, y));

  const triple = Tuple.rotater(Tuple(1, "a", true));
  Tuple.toArray(triple); // [true, 1, "a"]

 */

// ((a, b, c) -> r) -> ((c, a, b) -> r)
Tuple.rotater = tx => tx((x, y, z) => Tuple(z, x, y));

/**
 * @name set
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.set2 = y => tx => tx((x, _, ...args) => Tuple(x, y, ...args));

  const triple = Tuple.set2("b") (Tuple(1, "a", true));
  Tuple.toArray(triple); // [1, "b", true]

 */

// a -> ((*) -> r) -> ((*) -> r)
Tuple.set1 = x => tx => tx((_, ...args) => Tuple(x, ...args));

// a -> ((*) -> r) -> ((*) -> r)
Tuple.set2 = y => tx => tx((x, _, ...args) => Tuple(x, y, ...args));

// a -> ((*) -> r) -> ((*) -> r)
Tuple.set3 = z => tx => tx((x, y, _, ...args) => Tuple(x, y, z, ...args));

/**
 * @name set nth
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.setn = n => x => tx => tx((...args) => (args[n - 1] = x, Tuple(...args)));

  const triple = Tuple.setn(2) ("b") (Tuple(1, "a", true));
  Tuple.toArray(triple); // [1, "b", true]

 */

// Number -> ((*) -> r) -> r
Tuple.setn = n => x => tx => tx((...args) => (args[n - 1] = x, Tuple(...args)));

/**
 * @name swap
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);
  Tuple.swap = tx => tx((x, y) => Tuple(y, x));

  const pair = Tuple.swap(Tuple(1, "a"));
  Tuple.toArray(pair); // ["a", 1]

 */

// ((a, b) -> r) -> ((b, a) -> r)
Tuple.swap = tx => tx((x, y) => Tuple(y, x));

/**
 * @name to array
 * @type first order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.toArray = tx => tx((...args) => args);

  Tuple.toArray(Tuple(1, "a", true)); // [1, "a", true]

 */

// ((*) -> r) -> [*]
Tuple.toArray = tx => tx((...args) => args);

/**
 * @name uncurry
 * @type higher order function
 * @status stable
 * @example

  const Tuple = (...args) => f => f(...args);
  Tuple.uncurry = f => tx => tx((...args) => f(args[0]) (args[1]));

  const add = y => x => x + y;
  const pair = Tuple(2, 3);

  Tuple.uncurry(add) (pair); // 5

 */

// (a -> b -> c) -> ((a, b) -> c) -> c
Tuple.uncurry = f => tx => tx((...args) => f(args[0]) (args[1]));

// (a -> b -> c -> d) -> ((a, b, c) -> d) -> d
Tuple.uncurry3 = f => tx => tx((...args) => f(args[0]) (args[1]) (args[2]));

// API

module.exports = Tuple;<|endoftext|>


<commit_before>'use strict';

module.exports = function (t, a) {
	var x = {}, y = [0, 1, "", null, NaN, x, false, true], z;

	a(t(y), y, "Same object");
	a.deep(y, [1, x, true], "Content");
};
<commit_msg>Simplier tests for functional version<commit_after>'use strict';

module.exports = function (t, a) {
	var x = [0, 1];

	a(t(x), x, "Same object");
	a.deep(x, [1], "Content");
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
var through2 = require('through2');
var clc = require('cli-color');
var program = require('commander');
var cssPurge = require('./lib/css-purge');

var error = clc.red.bold;
var info = clc.xterm(123);
var warn = clc.yellow;
var logoRed = clc.xterm(197);

program
	.version('3.0.14')
	.option('-c, --cssinput - CSS <the css>', 'The CSS to purge')
	.option('-i, --input - CSS file(s) <input filenames, foldernames or url>', 'The CSS file(s) to parse')
	.option('-m, --inputhtml - HTML file(s) <input html filenames, foldernames or url>', 'The HTML file(s) to parse for CSS')
	.option('-o, --output - CSS file <output filename>', 'The new css filename to output as')
	.option('-f, --customconfig - <config filename> - run with custom config filename', 'Global Workflow - All options must be defined in a json file')
	.option('-d, --defaultconfig - run with default config file', 'Local Workflow - All options are defined in a config_css.json')
	.option('-v, --verbose - displays internal messages', 'Outputs CSS-PURGE activity')
	.parse(process.argv);

var options = {};

if (program.cssinput) {

	if (program.output) {

		options = {
			css_output: program.output,
			verbose : (program.verbose) ? true : false
		};

		if (program.customconfig === undefined) {
			options.trim = true;
			options.shorten = true;
		}

		cssPurge.purgeCSS(program.cssinput, options, function(error, result){
			if (error)
				console.log(error)
			else
				console.log(result);
		});
	} else {

		options = {
			verbose : (program.verbose) ? true : false
		};

		if (program.customconfig === undefined) {
			options.trim = true;
			options.shorten = true;
		}

		cssPurge.purgeCSS(program.cssinput, options, function(error, result){
			if (error)
				console.log(error)
			else
				console.log(result);
		});
	}

} else if (program.input && program.inputhtml && program.output) {

	options = {
		css: program.input,
		css_output: program.output,
		special_reduce_with_html: true,
		html: program.inputhtml,
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);

} else if (program.input && program.inputhtml) {

	options = {
		css: program.input,
		css_output: program.input.substr(0, program.input.lastIndexOf('.')) + '.min.css',
		special_reduce_with_html: true,
		html: program.inputhtml,
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);

} else if (program.input && program.output) {

	options = {
		css: program.input,
		css_output: program.output,
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);
} else if (program.input) {

	options = {
		css: program.input,
		css_output: program.input.substr(0, program.input.lastIndexOf('.')) + '.min.css',
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);
} else if (program.customconfig) {
	cssPurge.purgeCSSFiles(null, '' + program.customconfig);
} else if (program.defaultconfig) {
	cssPurge.purgeCSSFiles();
} else {
	program.help();
}<commit_msg>fix: Get the current version from package.json<commit_after>#!/usr/bin/env node
var through2 = require('through2');
var clc = require('cli-color');
var program = require('commander');
var pkg = require('./package.json');
var cssPurge = require('./lib/css-purge');

var error = clc.red.bold;
var info = clc.xterm(123);
var warn = clc.yellow;
var logoRed = clc.xterm(197);

program
	.version(pkg.version)
	.option('-c, --cssinput - CSS <the css>', 'The CSS to purge')
	.option('-i, --input - CSS file(s) <input filenames, foldernames or url>', 'The CSS file(s) to parse')
	.option('-m, --inputhtml - HTML file(s) <input html filenames, foldernames or url>', 'The HTML file(s) to parse for CSS')
	.option('-o, --output - CSS file <output filename>', 'The new css filename to output as')
	.option('-f, --customconfig - <config filename> - run with custom config filename', 'Global Workflow - All options must be defined in a json file')
	.option('-d, --defaultconfig - run with default config file', 'Local Workflow - All options are defined in a config_css.json')
	.option('-v, --verbose - displays internal messages', 'Outputs CSS-PURGE activity')
	.parse(process.argv);

var options = {};

if (program.cssinput) {

	if (program.output) {

		options = {
			css_output: program.output,
			verbose : (program.verbose) ? true : false
		};

		if (program.customconfig === undefined) {
			options.trim = true;
			options.shorten = true;
		}

		cssPurge.purgeCSS(program.cssinput, options, function(error, result){
			if (error)
				console.log(error)
			else
				console.log(result);
		});
	} else {

		options = {
			verbose : (program.verbose) ? true : false
		};

		if (program.customconfig === undefined) {
			options.trim = true;
			options.shorten = true;
		}

		cssPurge.purgeCSS(program.cssinput, options, function(error, result){
			if (error)
				console.log(error)
			else
				console.log(result);
		});
	}

} else if (program.input && program.inputhtml && program.output) {

	options = {
		css: program.input,
		css_output: program.output,
		special_reduce_with_html: true,
		html: program.inputhtml,
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);

} else if (program.input && program.inputhtml) {

	options = {
		css: program.input,
		css_output: program.input.substr(0, program.input.lastIndexOf('.')) + '.min.css',
		special_reduce_with_html: true,
		html: program.inputhtml,
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);

} else if (program.input && program.output) {

	options = {
		css: program.input,
		css_output: program.output,
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);
} else if (program.input) {

	options = {
		css: program.input,
		css_output: program.input.substr(0, program.input.lastIndexOf('.')) + '.min.css',
		verbose : (program.verbose) ? true : false
	};

	if (program.customconfig === undefined) {
		options.trim = true;
		options.shorten = true;
	}

	cssPurge.purgeCSSFiles(
		options,
		(program.customconfig !== undefined) ? program.customconfig : 'cmd_default'
	);
} else if (program.customconfig) {
	cssPurge.purgeCSSFiles(null, '' + program.customconfig);
} else if (program.defaultconfig) {
	cssPurge.purgeCSSFiles();
} else {
	program.help();
}
<|endoftext|>


<commit_before>/* eslint-env es6 */
/* eslint no-global-assign: 0 */
"use strict";

const stubBrowserFeatures = M => {
  const noop = () => ({ collisionFilter: {}, mouse: {} });
  M.Common._requireGlobal = name => global[name];
  M.Render.create = () => ({ options: {}, bounds: { min: { x: 0, y: 0 }, max: { x: 800, y: 600 }}});
  M.Render.run = M.Render.lookAt = noop;
  M.Runner.create = M.Runner.run = noop;
  M.MouseConstraint.create = M.Mouse.create = noop;
  M.Common.log = M.Common.info = M.Common.warn = noop;
  return M;
};

const reset = M => {
  M.Common._nextId = M.Common._seed = 0;
  M.Body._nextCollidingGroupId = 1;
  M.Body._nextNonCollidingGroupId = -1;
  M.Body._nextCategory = 0x0001;
};

const { engineCapture } = require('./TestTools');
const MatterDev = stubBrowserFeatures(require('../src/module/main'));
const MatterBuild = stubBrowserFeatures(require('../build/matter'));
const Example = require('../examples/index');
const decomp = require('../demo/lib/decomp');

const runExample = options => {
  const Matter = options.useDev ? MatterDev : MatterBuild;
  const consoleOriginal = global.console;

  global.console = { log: () => {} };
  global.document = global.window = { addEventListener: () => {} };
  global.decomp = decomp;
  global.Matter = Matter;

  reset(Matter);

  const example = Example[options.name]();
  const engine = example.engine;

  let totalDuration = 0;
  let overlapTotal = 0;
  let overlapCount = 0;

  const bodies = Matter.Composite.allBodies(engine.world);

  if (options.jitter) {
    for (let i = 0; i < bodies.length; i += 1) {
      const body = bodies[i];

      Matter.Body.applyForce(body, body.position, {
        x: Math.cos(i * i) * options.jitter * body.mass,
        y: Math.sin(i * i) * options.jitter * body.mass
      });
    }
  }

  for (let i = 0; i < options.totalUpdates; i += 1) {
      const startTime = process.hrtime();

      Matter.Engine.update(engine, 1000 / 60);

      const duration = process.hrtime(startTime);
      totalDuration += duration[0] * 1e9 + duration[1];

      for (let p = 0; p < engine.pairs.list.length; p += 1) {
        const pair = engine.pairs.list[p];
        const separation = pair.separation - pair.slop;

        if (pair.isActive && !pair.isSensor) {
          overlapTotal += separation > 0 ? separation : 0;
          overlapCount += 1;
        }
      }
  }

  global.console = consoleOriginal;
  global.window = undefined;
  global.document = undefined;
  global.decomp = undefined;
  global.Matter = undefined;

  return {
    name: options.name,
    duration: totalDuration,
    overlap: overlapTotal / (overlapCount || 1),
    ...engineCapture(engine)
  };
};

module.exports = { runExample };<commit_msg>change test worker decomp require<commit_after>/* eslint-env es6 */
/* eslint no-global-assign: 0 */
"use strict";

const stubBrowserFeatures = M => {
  const noop = () => ({ collisionFilter: {}, mouse: {} });
  M.Common._requireGlobal = name => global[name];
  M.Render.create = () => ({ options: {}, bounds: { min: { x: 0, y: 0 }, max: { x: 800, y: 600 }}});
  M.Render.run = M.Render.lookAt = noop;
  M.Runner.create = M.Runner.run = noop;
  M.MouseConstraint.create = M.Mouse.create = noop;
  M.Common.log = M.Common.info = M.Common.warn = noop;
  return M;
};

const reset = M => {
  M.Common._nextId = M.Common._seed = 0;
  M.Body._nextCollidingGroupId = 1;
  M.Body._nextNonCollidingGroupId = -1;
  M.Body._nextCategory = 0x0001;
};

const { engineCapture } = require('./TestTools');
const MatterDev = stubBrowserFeatures(require('../src/module/main'));
const MatterBuild = stubBrowserFeatures(require('../build/matter'));
const Example = require('../examples/index');
const decomp = require('poly-decomp');

const runExample = options => {
  const Matter = options.useDev ? MatterDev : MatterBuild;
  const consoleOriginal = global.console;

  global.console = { log: () => {} };
  global.document = global.window = { addEventListener: () => {} };
  global.decomp = decomp;
  global.Matter = Matter;

  reset(Matter);

  const example = Example[options.name]();
  const engine = example.engine;

  let totalDuration = 0;
  let overlapTotal = 0;
  let overlapCount = 0;

  const bodies = Matter.Composite.allBodies(engine.world);

  if (options.jitter) {
    for (let i = 0; i < bodies.length; i += 1) {
      const body = bodies[i];

      Matter.Body.applyForce(body, body.position, {
        x: Math.cos(i * i) * options.jitter * body.mass,
        y: Math.sin(i * i) * options.jitter * body.mass
      });
    }
  }

  for (let i = 0; i < options.totalUpdates; i += 1) {
      const startTime = process.hrtime();

      Matter.Engine.update(engine, 1000 / 60);

      const duration = process.hrtime(startTime);
      totalDuration += duration[0] * 1e9 + duration[1];

      for (let p = 0; p < engine.pairs.list.length; p += 1) {
        const pair = engine.pairs.list[p];
        const separation = pair.separation - pair.slop;

        if (pair.isActive && !pair.isSensor) {
          overlapTotal += separation > 0 ? separation : 0;
          overlapCount += 1;
        }
      }
  }

  global.console = consoleOriginal;
  global.window = undefined;
  global.document = undefined;
  global.decomp = undefined;
  global.Matter = undefined;

  return {
    name: options.name,
    duration: totalDuration,
    overlap: overlapTotal / (overlapCount || 1),
    ...engineCapture(engine)
  };
};

module.exports = { runExample };<|endoftext|>


<commit_before>var MainTestLayer = cc.Layer.extend({
    ctor:function () {
        var winSize;
        var toastLabel, toastMenuItem, menu, title;
        var pixelLabel, pixelMenuItem;

        this._super();

        winSize = cc.director.getWinSize();

        title = cc.LabelTTF.create("Cocostyle Test List", "Arial", 20);
        title.setPosition(winSize.width / 2, winSize.height - 40);
        title.setColor(cc.color(255, 255, 0, 255));
        this.addChild(title);

        toastLabel = cc.LabelTTF.create("[ csToast ]", "Arial", 18);
        toastMenuItem = cc.MenuItemLabel.create(toastLabel, function() {
            var scene = new csToastTestLayer();
            cc.director.runScene(scene);
        }, this);

        pixelLabel = cc.LabelTTF.create("[ csPixelCollision ]", "Arial", 18);
        pixelMenuItem = cc.MenuItemLabel.create(pixelLabel, function() {
            var scene = new csPixelCollisionTestLayer();
            cc.director.runScene(scene);
        }, this);

        menu = cc.Menu.create(toastMenuItem, pixelMenuItem);
        menu.alignItemsVerticallyWithPadding(15);
        menu.setPosition(winSize.width / 2, winSize.height / 2);
        this.addChild(menu);

        return true;
    }
});

var MainTestScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new MainTestLayer();
        this.addChild(layer);
    }
});
<commit_msg>Update MainTestScene.js<commit_after>var MainTestLayer = cc.Layer.extend({
    ctor:function () {
        var winSize;
        var toastLabel, toastMenuItem, menu, title;
        var pixelLabel, pixelMenuItem;
        var typingLabel, typingMenuItem;

        this._super();

        winSize = cc.director.getWinSize();

        title = cc.LabelTTF.create("Cocostyle Test List", "Arial", 20);
        title.setPosition(winSize.width / 2, winSize.height - 40);
        title.setColor(cc.color(255, 255, 0, 255));
        this.addChild(title);

        toastLabel = cc.LabelTTF.create("[ csToast ]", "Arial", 18);
        toastMenuItem = cc.MenuItemLabel.create(toastLabel, function() {
            var scene = new csToastTestLayer();
            cc.director.runScene(scene);
        }, this);

        pixelLabel = cc.LabelTTF.create("[ csPixelCollision ]", "Arial", 18);
        pixelMenuItem = cc.MenuItemLabel.create(pixelLabel, function() {
            var scene = new csPixelCollisionTestLayer();
            cc.director.runScene(scene);
        }, this);

        typingLabel = cc.LabelTTF.create("[ csTypingLabel ]", "Arial", 18);
        typingMenuItem = cc.MenuItemLabel.create(typingLabel, function() {
            var scene = new csTypingLabelTestLayer();
            cc.director.runScene(scene);
        }, this);

        menu = cc.Menu.create(toastMenuItem, pixelMenuItem, typingMenuItem);
        menu.alignItemsVerticallyWithPadding(15);
        menu.setPosition(winSize.width / 2, winSize.height / 2);
        this.addChild(menu);

        return true;
    }
});

var MainTestScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new MainTestLayer();
        this.addChild(layer);
    }
});

<|endoftext|>


<commit_before>"use strict";

// Stages
var nextStage = false;
var minionTime = true;
var bossTime = false;
var round = 1;

var test = false;

var update = function (game, CatEnemy, Bullet, audio, Explosion) {

	[game.world.platforms,
	game.world.enemies,
	game.world.bullets,
	game.world.explosions
	].forEach (
		function(gameElementArray) {
			gameElementArray.forEach(function(gameElement) {
				gameElement.update();
			});
		}
	);

	game.world.players.forEach(
		function(player) {
			game.world.boss.forEach (
				function(boss) {
					if (boss.lives < 1) {
						round++;
						minionTime = true;
						player.kills = 20;
						nextStage = false;
					}
					boss.update(player);
				}

			);

			game.world.addOn.forEach (
				function(arm) {
					arm.update(player);
				}
			);

			player.update();
			if (player.kills > 22) {
				nextStage = true;
			}
		}
	);

    game.world.players = game.world.players.filter(function(player) {
        return player.active;
    });

	game.world.enemies = game.world.enemies.filter(function(enemy) {
		return enemy.active;
	});

	game.world.bullets = game.world.bullets.filter(function(bullet) {
		return bullet.active;
	});

	game.world.boss = game.world.boss.filter(function(boss) {
		return boss.active;
	});

	game.world.addOn = game.world.addOn.filter(function(arm) {
		return arm.active;
	});

	game.world.platforms = game.world.platforms.filter(function(platform) {
		return platform.active;
	});

	game.world.explosions = game.world.explosions.filter(function(explosion) {
		return explosion.active;
	});

	if (game.world.players.length < 1) {
       game.world.died = true;
    } else if (test) {

	} else if (minionTime && round == 0) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new CatEnemy(game.world, "right"));
				} else {
					game.world.enemies.push(new CatEnemy(game.world, "left"));
				}
			}
		}
		if (nextStage) {
			nextStage = false;
			bossTime = true;
			minionTime = false;
		}
	} else if (bossTime && round == 0) {
		game.world.boss.push(new CatBoss(game.world, Bullet, audio));

		audio.casanova.stop();
		audio.pokemonRuby.loop();
		audio.pokemonRuby.setVolume(20);
		audio.pokemonRuby.play();
		bossTime = false;
	} else if (minionTime && round == 1) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
                                        game.world.enemies.push(new QuadrapusEnemy(game.world, {
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		audio.pokemonRuby.stop();
		audio.underTheSea.loop();
		audio.underTheSea.play();

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}
	} else if (bossTime && round == 1) {
		game.world.boss.push(new QuadrapusBoss(game.world, Bullet, audio, Explosion));
		game.world.platforms.push(new Platform(game.world, {
			x: 75,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 475,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 50,
			y: 191,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 500,
			y: 191,
		}));

		audio.underTheSea.stop();
		audio.itsPossible.setVolume(100);
		audio.itsPossible.loop();
		audio.itsPossible.play();

		bossTime = false;
	} else if (minionTime && round == 2) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}
	} else if (bossTime && round == 2) {
		game.world.boss.push(new FrogBoss(game.world, Bullet, audio));

		bossTime = false;
	} else if (minionTime && round == 3) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}
	} else if (bossTime && round == 3) {
		game.world.boss.push(new StarfishBoss(game.world, Bullet, audio));

		bossTime = false;
	} else if (minionTime && round == 4) {
       	if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}

    } else if (bossTime && round == 4) {
        game.world.boss.push( new TimelordBoss(game.world, Bullet, audio, Explosion));

        game.world.platforms.push(new Platform(game.world, {
			x: 175,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 375,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 130,
			y: 196,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 420,
			y: 196,
		}));
        game.world.platforms.push(new Platform(game.world, {
            x: 130,
            y: 140
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 420,
            y: 140
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 175,
            y: 83
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 375,
            y: 83
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 275,
            y: 83
        }));

        bossTime = false;
    } else if (minionTime && round == 5) {
		game.world.end = true;
	}
};
<commit_msg>Update update.js<commit_after>"use strict";

// Stages
var nextStage = false;
var minionTime = true;
var bossTime = false;
var round = 0;

var test = false;

var update = function (game, CatEnemy, Bullet, audio, Explosion) {

	[game.world.platforms,
	game.world.enemies,
	game.world.bullets,
	game.world.explosions
	].forEach (
		function(gameElementArray) {
			gameElementArray.forEach(function(gameElement) {
				gameElement.update();
			});
		}
	);

	game.world.players.forEach(
		function(player) {
			game.world.boss.forEach (
				function(boss) {
					if (boss.lives < 1) {
						round++;
						minionTime = true;
						player.kills = 20;
						nextStage = false;
					}
					boss.update(player);
				}

			);

			game.world.addOn.forEach (
				function(arm) {
					arm.update(player);
				}
			);

			player.update();
			if (player.kills > 22) {
				nextStage = true;
			}
		}
	);

    game.world.players = game.world.players.filter(function(player) {
        return player.active;
    });

	game.world.enemies = game.world.enemies.filter(function(enemy) {
		return enemy.active;
	});

	game.world.bullets = game.world.bullets.filter(function(bullet) {
		return bullet.active;
	});

	game.world.boss = game.world.boss.filter(function(boss) {
		return boss.active;
	});

	game.world.addOn = game.world.addOn.filter(function(arm) {
		return arm.active;
	});

	game.world.platforms = game.world.platforms.filter(function(platform) {
		return platform.active;
	});

	game.world.explosions = game.world.explosions.filter(function(explosion) {
		return explosion.active;
	});

	if (game.world.players.length < 1) {
       game.world.died = true;
    } else if (test) {

	} else if (minionTime && round == 0) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new CatEnemy(game.world, "right"));
				} else {
					game.world.enemies.push(new CatEnemy(game.world, "left"));
				}
			}
		}
		if (nextStage) {
			nextStage = false;
			bossTime = true;
			minionTime = false;
		}
	} else if (bossTime && round == 0) {
		game.world.boss.push(new CatBoss(game.world, Bullet, audio));

		audio.casanova.stop();
		audio.pokemonRuby.loop();
		audio.pokemonRuby.setVolume(20);
		audio.pokemonRuby.play();
		bossTime = false;
	} else if (minionTime && round == 1) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
                                        game.world.enemies.push(new QuadrapusEnemy(game.world, {
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		audio.pokemonRuby.stop();
		audio.underTheSea.loop();
		audio.underTheSea.play();

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}
	} else if (bossTime && round == 1) {
		game.world.boss.push(new QuadrapusBoss(game.world, Bullet, audio, Explosion));
		game.world.platforms.push(new Platform(game.world, {
			x: 75,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 475,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 50,
			y: 191,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 500,
			y: 191,
		}));

		audio.underTheSea.stop();
		audio.itsPossible.setVolume(100);
		audio.itsPossible.loop();
		audio.itsPossible.play();

		bossTime = false;
	} else if (minionTime && round == 2) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}
	} else if (bossTime && round == 2) {
		game.world.boss.push(new FrogBoss(game.world, Bullet, audio));

		bossTime = false;
	} else if (minionTime && round == 3) {
		if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}
	} else if (bossTime && round == 3) {
		game.world.boss.push(new StarfishBoss(game.world, Bullet, audio));

		bossTime = false;
	} else if (minionTime && round == 4) {
       	if (Math.random() < 0.02) {
			if (Math.random() < 0.1) {
			} else {
				if (Math.random() < 0.8) {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "left"
					}));
				} else {
					game.world.enemies.push(new QuadrapusEnemy(game.world, {
						//spriteName: "enemyQuadrapus",
						side: "right"
					}));
				}
			}
		}

		if (nextStage) {
			bossTime = true;
			minionTime = false;
			nextStage = false;
		}

    } else if (bossTime && round == 4) {
        game.world.boss.push( new TimelordBoss(game.world, Bullet, audio, Explosion));

        game.world.platforms.push(new Platform(game.world, {
			x: 175,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 375,
			y: 250,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 130,
			y: 196,
		}));
		game.world.platforms.push(new Platform(game.world, {
			x: 420,
			y: 196,
		}));
        game.world.platforms.push(new Platform(game.world, {
            x: 130,
            y: 140
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 420,
            y: 140
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 175,
            y: 83
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 375,
            y: 83
        }));
        game.world.platforms.push(new Platform(game.world, {
            x: 275,
            y: 83
        }));

        bossTime = false;
    } else if (minionTime && round == 5) {
		game.world.end = true;
	}
};
<|endoftext|>