<commit_before>module.exports = {
  "plugins": [
    "stylelint-scss",
    "stylelint-selector-no-utility"
  ],
  "rules": {
    "at-rule-blacklist": ["extend"],
    "at-rule-name-case": "lower",
    "at-rule-name-space-after": "always-single-line",
    "at-rule-semicolon-newline-after": "always",
    "block-closing-brace-newline-after": "always",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-closing-brace-space-before": "always-single-line",
    "block-no-empty": true,
    "block-opening-brace-newline-after": "always-multi-line",
    "block-opening-brace-space-after": "always-single-line",
    "block-opening-brace-space-before": "always",
    "color-hex-case": "lower",
    "color-hex-length": "short",
    "color-named": "never",
    "color-no-invalid-hex": true,
    "comment-empty-line-before": [
      "always",
      {
        "except": [
          "first-nested"
        ],
        "ignore": [
          "stylelint-commands"
        ]
      }
    ],
    "comment-whitespace-inside": "always",
    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-no-duplicate-properties": [
      true,
      {
        "ignore": [
          "consecutive-duplicates"
        ]
      }
    ],
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-properties-order": [
      "position",
      "top",
      "right",
      "bottom",
      "left",
      "z-index",
      "display",
      "float",
      "width",
      "min-width",
      "max-width",
      "height",
      "min-height",
      "max-height",
      "box-sizing",
      "padding",
      "padding-top",
      "padding-right",
      "padding-bottom",
      "padding-left",
      "margin",
      "margin-top",
      "margin-right",
      "margin-bottom",
      "margin-left",
      "overflow",
      "overflow-x",
      "overflow-y",
      "clip",
      "clear",
      "font",
      "font-family",
      "font-size",
      "font-style",
      "font-weight",
      "font-variant",
      "font-size-adjust",
      "font-stretch",
      "font-effect",
      "font-emphasize",
      "font-emphasize-position",
      "font-emphasize-style",
      "font-smooth",
      "hyphens",
      "line-height",
      "color",
      "text-align",
      "text-align-last",
      "text-emphasis",
      "text-emphasis-color",
      "text-emphasis-style",
      "text-emphasis-position",
      "text-decoration",
      "text-indent",
      "text-justify",
      "text-outline",
      "text-overflow",
      "text-overflow-ellipsis",
      "text-overflow-mode",
      "text-shadow",
      "text-transform",
      "text-wrap",
      "letter-spacing",
      "word-break",
      "word-spacing",
      "word-wrap",
      "tab-size",
      "white-space",
      "vertical-align",
      "list-style",
      "list-style-position",
      "list-style-type",
      "list-style-image",
      "pointer-events",
      "fill",
      "fill-opacity",
      "stroke",
      "stroke-opacity",
      "stroke-width",
      "shape-rendering",
      "cursor",
      "visibility",
      "zoom",
      "flex-direction",
      "flex-order",
      "flex-pack",
      "flex-align",
      "table-layout",
      "empty-cells",
      "caption-side",
      "border-spacing",
      "border-collapse",
      "content",
      "quotes",
      "counter-reset",
      "counter-increment",
      "resize",
      "user-select",
      "nav-index",
      "nav-up",
      "nav-right",
      "nav-down",
      "nav-left",
      "background",
      "background-color",
      "background-image",
      "filter",
      "background-repeat",
      "background-attachment",
      "background-position",
      "background-position-x",
      "background-position-y",
      "background-clip",
      "background-origin",
      "background-size",
      "border",
      "border-color",
      "border-style",
      "border-width",
      "border-top",
      "border-top-color",
      "border-top-style",
      "border-top-width",
      "border-right",
      "border-right-color",
      "border-right-style",
      "border-right-width",
      "border-bottom",
      "border-bottom-color",
      "border-bottom-style",
      "border-bottom-width",
      "border-left",
      "border-left-color",
      "border-left-style",
      "border-left-width",
      "border-radius",
      "border-top-left-radius",
      "border-top-right-radius",
      "border-bottom-right-radius",
      "border-bottom-left-radius",
      "border-image",
      "border-image-source",
      "border-image-slice",
      "border-image-width",
      "border-image-outset",
      "border-image-repeat",
      "outline",
      "outline-width",
      "outline-style",
      "outline-color",
      "outline-offset",
      "box-shadow",
      "opacity",
      "transition",
      "transition-delay",
      "transition-timing-function",
      "transition-duration",
      "transition-property",
      "transform",
      "transform-origin",
      "animation",
      "animation-name",
      "animation-duration",
      "animation-fill-mode",
      "animation-play-state",
      "animation-timing-function",
      "animation-delay",
      "animation-iteration-count",
      "animation-direction"
    ],
    "declaration-block-semicolon-newline-after": "always",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-newline-after": "always-multi-line",
    "declaration-colon-space-after": "always-single-line",
    "declaration-colon-space-before": "never",
    "declaration-property-value-blacklist": {
      "/^transition/": [
        "/all/"
      ],
      "/^background/": [
        "http:",
        "https:"
      ],
      "/^border/": [
        "none"
      ],
      "/.+/": [
        "initial"
      ]
    },
    "font-family-name-quotes": "always-where-recommended",
    "function-calc-no-unspaced-operator": true,
    "function-comma-newline-after": "always-multi-line",
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-linear-gradient-no-nonstandard-direction": true,
    "function-max-empty-lines": 0,
    "function-name-case": "lower",
    "function-parentheses-newline-inside": "always-multi-line",
    "function-parentheses-space-inside": "never-single-line",
    "function-url-quotes": "always",
    "function-whitespace-after": "always",
    "indentation": 2,
    "max-empty-lines": 1,
    "max-nesting-depth": 3,
    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-no-missing-punctuation": true,
    "media-feature-parentheses-space-inside": "never",
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",
    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",
    "no-duplicate-selectors": true,
    "no-eol-whitespace": true,
    "no-extra-semicolons": true,
    "no-missing-end-of-source-newline": true,
    "no-unsupported-browser-features": [true, {
      "browsers": "> 5%, last 2 firefox versions, last 2 chrome versions, last 2 safari versions, last 2 edge versions, ie 11",
      "severity": "warning"
    }],
    "number-leading-zero": "always",
    "number-no-trailing-zeros": true,
    "primer/selector-no-utility": true,
    "property-case": "lower",
    "property-no-vendor-prefix": true,
    "rule-nested-empty-line-before": [
      "always-multi-line",
      {
        "except": [
          "first-nested"
        ],
        "ignore": [
          "after-comment"
        ]
      }
    ],
    "rule-non-nested-empty-line-before": [
      "always-multi-line",
      {
        "ignore": [
          "after-comment"
        ]
      }
    ],
    "scss/selector-no-redundant-nesting-selector": true,
    "selector-attribute-brackets-space-inside": "never",
    "selector-attribute-operator-space-after": "never",
    "selector-attribute-operator-space-before": "never",
    "selector-class-pattern": [
      "^(?!(js\\-))[a-z\\-0-9]+$",
      {
        "message": "Selector should be written in lowercase with hyphens (selector-class-pattern)"
      }
    ],
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-list-comma-newline-after": "always",
    "selector-list-comma-space-before": "never",
    "selector-max-compound-selectors": 3,
    "selector-max-empty-lines": 0,
    "selector-max-specificity": "0,4,0",
    "selector-no-id": true,
    "selector-no-qualifying-type": true,
    "selector-no-type": true,
    "selector-pseudo-class-case": "lower",
    "selector-pseudo-class-parentheses-space-inside": "never",
    "selector-pseudo-element-case": "lower",
    "selector-pseudo-element-colon-notation": "double",
    "selector-pseudo-element-no-unknown": true,
    "selector-type-case": "lower",
    "shorthand-property-no-redundant-values": true,
    "string-no-newline": true,
    "string-quotes": "double",
    "unit-case": "lower",
    "unit-no-unknown": true,
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
    "value-no-vendor-prefix": true
  }
}
<commit_msg>Prevent units in zero values<commit_after>module.exports = {
  "plugins": [
    "stylelint-scss",
    "stylelint-selector-no-utility"
  ],
  "rules": {
    "at-rule-blacklist": ["extend"],
    "at-rule-name-case": "lower",
    "at-rule-name-space-after": "always-single-line",
    "at-rule-semicolon-newline-after": "always",
    "block-closing-brace-newline-after": "always",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-closing-brace-space-before": "always-single-line",
    "block-no-empty": true,
    "block-opening-brace-newline-after": "always-multi-line",
    "block-opening-brace-space-after": "always-single-line",
    "block-opening-brace-space-before": "always",
    "color-hex-case": "lower",
    "color-hex-length": "short",
    "color-named": "never",
    "color-no-invalid-hex": true,
    "comment-empty-line-before": [
      "always",
      {
        "except": [
          "first-nested"
        ],
        "ignore": [
          "stylelint-commands"
        ]
      }
    ],
    "comment-whitespace-inside": "always",
    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-no-duplicate-properties": [
      true,
      {
        "ignore": [
          "consecutive-duplicates"
        ]
      }
    ],
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-properties-order": [
      "position",
      "top",
      "right",
      "bottom",
      "left",
      "z-index",
      "display",
      "float",
      "width",
      "min-width",
      "max-width",
      "height",
      "min-height",
      "max-height",
      "box-sizing",
      "padding",
      "padding-top",
      "padding-right",
      "padding-bottom",
      "padding-left",
      "margin",
      "margin-top",
      "margin-right",
      "margin-bottom",
      "margin-left",
      "overflow",
      "overflow-x",
      "overflow-y",
      "clip",
      "clear",
      "font",
      "font-family",
      "font-size",
      "font-style",
      "font-weight",
      "font-variant",
      "font-size-adjust",
      "font-stretch",
      "font-effect",
      "font-emphasize",
      "font-emphasize-position",
      "font-emphasize-style",
      "font-smooth",
      "hyphens",
      "line-height",
      "color",
      "text-align",
      "text-align-last",
      "text-emphasis",
      "text-emphasis-color",
      "text-emphasis-style",
      "text-emphasis-position",
      "text-decoration",
      "text-indent",
      "text-justify",
      "text-outline",
      "text-overflow",
      "text-overflow-ellipsis",
      "text-overflow-mode",
      "text-shadow",
      "text-transform",
      "text-wrap",
      "letter-spacing",
      "word-break",
      "word-spacing",
      "word-wrap",
      "tab-size",
      "white-space",
      "vertical-align",
      "list-style",
      "list-style-position",
      "list-style-type",
      "list-style-image",
      "pointer-events",
      "fill",
      "fill-opacity",
      "stroke",
      "stroke-opacity",
      "stroke-width",
      "shape-rendering",
      "cursor",
      "visibility",
      "zoom",
      "flex-direction",
      "flex-order",
      "flex-pack",
      "flex-align",
      "table-layout",
      "empty-cells",
      "caption-side",
      "border-spacing",
      "border-collapse",
      "content",
      "quotes",
      "counter-reset",
      "counter-increment",
      "resize",
      "user-select",
      "nav-index",
      "nav-up",
      "nav-right",
      "nav-down",
      "nav-left",
      "background",
      "background-color",
      "background-image",
      "filter",
      "background-repeat",
      "background-attachment",
      "background-position",
      "background-position-x",
      "background-position-y",
      "background-clip",
      "background-origin",
      "background-size",
      "border",
      "border-color",
      "border-style",
      "border-width",
      "border-top",
      "border-top-color",
      "border-top-style",
      "border-top-width",
      "border-right",
      "border-right-color",
      "border-right-style",
      "border-right-width",
      "border-bottom",
      "border-bottom-color",
      "border-bottom-style",
      "border-bottom-width",
      "border-left",
      "border-left-color",
      "border-left-style",
      "border-left-width",
      "border-radius",
      "border-top-left-radius",
      "border-top-right-radius",
      "border-bottom-right-radius",
      "border-bottom-left-radius",
      "border-image",
      "border-image-source",
      "border-image-slice",
      "border-image-width",
      "border-image-outset",
      "border-image-repeat",
      "outline",
      "outline-width",
      "outline-style",
      "outline-color",
      "outline-offset",
      "box-shadow",
      "opacity",
      "transition",
      "transition-delay",
      "transition-timing-function",
      "transition-duration",
      "transition-property",
      "transform",
      "transform-origin",
      "animation",
      "animation-name",
      "animation-duration",
      "animation-fill-mode",
      "animation-play-state",
      "animation-timing-function",
      "animation-delay",
      "animation-iteration-count",
      "animation-direction"
    ],
    "declaration-block-semicolon-newline-after": "always",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-newline-after": "always-multi-line",
    "declaration-colon-space-after": "always-single-line",
    "declaration-colon-space-before": "never",
    "declaration-property-value-blacklist": {
      "/^transition/": [
        "/all/"
      ],
      "/^background/": [
        "http:",
        "https:"
      ],
      "/^border/": [
        "none"
      ],
      "/.+/": [
        "initial"
      ]
    },
    "font-family-name-quotes": "always-where-recommended",
    "function-calc-no-unspaced-operator": true,
    "function-comma-newline-after": "always-multi-line",
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-linear-gradient-no-nonstandard-direction": true,
    "function-max-empty-lines": 0,
    "function-name-case": "lower",
    "function-parentheses-newline-inside": "always-multi-line",
    "function-parentheses-space-inside": "never-single-line",
    "function-url-quotes": "always",
    "function-whitespace-after": "always",
    "indentation": 2,
    "length-zero-no-unit": true,
    "max-empty-lines": 1,
    "max-nesting-depth": 3,
    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-no-missing-punctuation": true,
    "media-feature-parentheses-space-inside": "never",
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",
    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",
    "no-duplicate-selectors": true,
    "no-eol-whitespace": true,
    "no-extra-semicolons": true,
    "no-missing-end-of-source-newline": true,
    "no-unsupported-browser-features": [true, {
      "browsers": "> 5%, last 2 firefox versions, last 2 chrome versions, last 2 safari versions, last 2 edge versions, ie 11",
      "severity": "warning"
    }],
    "number-leading-zero": "always",
    "number-no-trailing-zeros": true,
    "primer/selector-no-utility": true,
    "property-case": "lower",
    "property-no-vendor-prefix": true,
    "rule-nested-empty-line-before": [
      "always-multi-line",
      {
        "except": [
          "first-nested"
        ],
        "ignore": [
          "after-comment"
        ]
      }
    ],
    "rule-non-nested-empty-line-before": [
      "always-multi-line",
      {
        "ignore": [
          "after-comment"
        ]
      }
    ],
    "scss/selector-no-redundant-nesting-selector": true,
    "selector-attribute-brackets-space-inside": "never",
    "selector-attribute-operator-space-after": "never",
    "selector-attribute-operator-space-before": "never",
    "selector-class-pattern": [
      "^(?!(js\\-))[a-z\\-0-9]+$",
      {
        "message": "Selector should be written in lowercase with hyphens (selector-class-pattern)"
      }
    ],
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-list-comma-newline-after": "always",
    "selector-list-comma-space-before": "never",
    "selector-max-compound-selectors": 3,
    "selector-max-empty-lines": 0,
    "selector-max-specificity": "0,4,0",
    "selector-no-id": true,
    "selector-no-qualifying-type": true,
    "selector-no-type": true,
    "selector-pseudo-class-case": "lower",
    "selector-pseudo-class-parentheses-space-inside": "never",
    "selector-pseudo-element-case": "lower",
    "selector-pseudo-element-colon-notation": "double",
    "selector-pseudo-element-no-unknown": true,
    "selector-type-case": "lower",
    "shorthand-property-no-redundant-values": true,
    "string-no-newline": true,
    "string-quotes": "double",
    "unit-case": "lower",
    "unit-no-unknown": true,
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
    "value-no-vendor-prefix": true
  }
}
<|endoftext|>


<commit_before>/*global URL */

'use strict';
var React = require('react');
var ReactDOM = require('react-dom')
var request = require('superagent-bluebird-promise');

var isFunction = function (fn) {
 var getType = {};
 return fn && getType.toString.call(fn) === '[object Function]';
};

var ReactQiniu = React.createClass({
    // based on https://github.com/paramaggarwal/react-dropzone
    propTypes: {
        onDrop: React.PropTypes.func.isRequired,
        token: React.PropTypes.string.isRequired,
        // called before upload to set callback to files
        onUpload: React.PropTypes.func,
        size: React.PropTypes.number,
        style: React.PropTypes.object,
        supportClick: React.PropTypes.bool,
        accept: React.PropTypes.string,
        multiple: React.PropTypes.bool,
        // Qiniu
        uploadUrl: React.PropTypes.string,
        uploadKey: React.PropTypes.string,
        prefix: React.PropTypes.string
    },

    getDefaultProps: function() {
        return {
            supportClick: true,
            multiple: true,
            uploadUrl: 'https://up.qbox.me/'
        };
    },

    getInitialState: function() {
        return {
            isDragActive: false
        };
    },

    onDragLeave: function(e) {
        this.setState({
            isDragActive: false
        });
    },

    onDragOver: function(e) {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';

        this.setState({
            isDragActive: true
        });
    },

    onDrop: function(e) {
        e.preventDefault();

        this.setState({
            isDragActive: false
        });

        var files;
        if (e.dataTransfer) {
            files = e.dataTransfer.files;
        } else if (e.target) {
            files = e.target.files;
        }

        var maxFiles = (this.props.multiple) ? files.length : 1;

        if (this.props.onUpload) {
            files = Array.prototype.slice.call(files, 0, maxFiles);
            this.props.onUpload(files, e);
        }

        for (var i = 0; i < maxFiles; i++) {
            files[i].preview = URL.createObjectURL(files[i]);
            files[i].request = this.upload(files[i]);
            files[i].uploadPromise = files[i].request.promise();
        }

        if (this.props.onDrop) {
            files = Array.prototype.slice.call(files, 0, maxFiles);
            this.props.onDrop(files, e);
        }
    },

    onClick: function () {
        if (this.props.supportClick) {
            this.open();
        }
    },

    open: function() {
        var fileInput = ReactDOM.findDOMNode(this.refs.fileInput);
        fileInput.value = null;
        fileInput.click();
    },

    upload: function(file) {
        if (!file || file.size === 0) return null;
        var key = file.preview.split('/').pop() + '.' + file.name.split('.').pop();
        if (this.props.prefix) {
            key = this.props.prefix  + key;
        }

        if(this.props.uploadKey){
          key = this.props.uploadKey;
        }

        var r = request
            .post(this.props.uploadUrl)
            .field('key', key)
            .field('token', this.props.token)
            .field('x:filename', file.name)
            .field('x:size', file.size)
            .attach('file', file, file.name)
            .set('Accept', 'application/json');
        if (isFunction(file.onprogress)) { r.on('progress', file.onprogress); }
        return r;
    },

    render: function() {
        var className = this.props.className || 'dropzone';
        if (this.state.isDragActive) {
            className += ' active';
        }

        var style = this.props.style || {
            width: this.props.size || 100,
            height: this.props.size || 100,
            borderStyle: this.state.isDragActive ? 'solid' : 'dashed'
        };

        return (
            React.createElement('div', {className: className, style: style, onClick: this.onClick, onDragLeave: this.onDragLeave, onDragOver: this.onDragOver, onDrop: this.onDrop},
                                React.createElement('input', {style: {display: 'none'}, type: 'file', multiple: this.props.multiple, ref: 'fileInput', onChange: this.onDrop, accept: this.props.accept}),
                                this.props.children
                               )
        );
    }

});

module.exports = ReactQiniu;
<commit_msg>Update uploadUrl based on protocol<commit_after>/*global URL */

'use strict';
var React = require('react');
var ReactDOM = require('react-dom')
var request = require('superagent-bluebird-promise');

var isFunction = function (fn) {
 var getType = {};
 return fn && getType.toString.call(fn) === '[object Function]';
};

var ReactQiniu = React.createClass({
    // based on https://github.com/paramaggarwal/react-dropzone
    propTypes: {
        onDrop: React.PropTypes.func.isRequired,
        token: React.PropTypes.string.isRequired,
        // called before upload to set callback to files
        onUpload: React.PropTypes.func,
        size: React.PropTypes.number,
        style: React.PropTypes.object,
        supportClick: React.PropTypes.bool,
        accept: React.PropTypes.string,
        multiple: React.PropTypes.bool,
        // Qiniu
        uploadUrl: React.PropTypes.string,
        uploadKey: React.PropTypes.string,
        prefix: React.PropTypes.string
    },

    getDefaultProps: function() {
        if (window.location.protocol === 'https:') {
          uploadUrl = 'https://up.qbox.me/'
        } else {
          uploadUrl = 'http://upload.qiniu.com'
        }

        return {
            supportClick: true,
            multiple: true,
            uploadUrl: uploadUrl
        };
    },

    getInitialState: function() {
        return {
            isDragActive: false
        };
    },

    onDragLeave: function(e) {
        this.setState({
            isDragActive: false
        });
    },

    onDragOver: function(e) {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';

        this.setState({
            isDragActive: true
        });
    },

    onDrop: function(e) {
        e.preventDefault();

        this.setState({
            isDragActive: false
        });

        var files;
        if (e.dataTransfer) {
            files = e.dataTransfer.files;
        } else if (e.target) {
            files = e.target.files;
        }

        var maxFiles = (this.props.multiple) ? files.length : 1;

        if (this.props.onUpload) {
            files = Array.prototype.slice.call(files, 0, maxFiles);
            this.props.onUpload(files, e);
        }

        for (var i = 0; i < maxFiles; i++) {
            files[i].preview = URL.createObjectURL(files[i]);
            files[i].request = this.upload(files[i]);
            files[i].uploadPromise = files[i].request.promise();
        }

        if (this.props.onDrop) {
            files = Array.prototype.slice.call(files, 0, maxFiles);
            this.props.onDrop(files, e);
        }
    },

    onClick: function () {
        if (this.props.supportClick) {
            this.open();
        }
    },

    open: function() {
        var fileInput = ReactDOM.findDOMNode(this.refs.fileInput);
        fileInput.value = null;
        fileInput.click();
    },

    upload: function(file) {
        if (!file || file.size === 0) return null;
        var key = file.preview.split('/').pop() + '.' + file.name.split('.').pop();
        if (this.props.prefix) {
            key = this.props.prefix  + key;
        }

        if(this.props.uploadKey){
          key = this.props.uploadKey;
        }

        var r = request
            .post(this.props.uploadUrl)
            .field('key', key)
            .field('token', this.props.token)
            .field('x:filename', file.name)
            .field('x:size', file.size)
            .attach('file', file, file.name)
            .set('Accept', 'application/json');
        if (isFunction(file.onprogress)) { r.on('progress', file.onprogress); }
        return r;
    },

    render: function() {
        var className = this.props.className || 'dropzone';
        if (this.state.isDragActive) {
            className += ' active';
        }

        var style = this.props.style || {
            width: this.props.size || 100,
            height: this.props.size || 100,
            borderStyle: this.state.isDragActive ? 'solid' : 'dashed'
        };

        return (
            React.createElement('div', {className: className, style: style, onClick: this.onClick, onDragLeave: this.onDragLeave, onDragOver: this.onDragOver, onDrop: this.onDrop},
                                React.createElement('input', {style: {display: 'none'}, type: 'file', multiple: this.props.multiple, ref: 'fileInput', onChange: this.onDrop, accept: this.props.accept}),
                                this.props.children
                               )
        );
    }

});

module.exports = ReactQiniu;
<|endoftext|>


<commit_before>const themeSlots = [
    "--AccentLines: #0086f4;",
    "--AccentText: #0078d7;",
    "--BackgroundOverlay: rgba(255, 255, 255, 0.85);",
    "--BodyText: #333333;",
    "--ButtonBackground: #f8f8f8;",
    "--ButtonBorder: #a6a6a6;",
    "--ButtonDisabledBackground: #f8f8f8;",
    "--ButtonDisabledBorder: #eaeaea;",
    "--ButtonDisabledText: #a6a6a6;",
    "--ButtonGlyph: #666666;",
    "--ButtonGlyphActive: #333333;",
    "--ButtonGlyphDisabled: #c8c8c8;",
    "--ButtonHoverBackground: #e1f2ff;",
    "--ButtonHoverBorder: #c4e4ff;",
    "--ButtonPressedBackground: #c4e4ff;",
    "--ButtonPressedBorder: #0086f4;",
    "--ButtonText: #333333;",
    "--CommandLinks: #666666;",
    "--CommandLinksDisabled: #a6a6a6;",
    "--CommandLinksHover: #0078d7;",
    "--CommandLinksPressed: #004176;",
    "--CommandLinksSecondary: #212121;",
    "--ContentAccent1: #0078d7;",
    "--DialogBorder: #f4f4f4;",
    "--DisabledBackground: #f8f8f8;",
    "--DisabledLines: #eaeaea;",
    "--DisabledText: #a6a6a6;",
    "--EmphasisBackground: #0078d7;",
    "--EmphasisBorder: #005296;",
    "--EmphasisHoverBackground: #005296;",
    "--EmphasisHoverBorder: #004176;",
    "--EmphasisText: #ffffff;",
    "--FooterBackground: rgba(255, 255, 255, 0.85);",
    "--HeaderAccentLines: #0086f4;",
    "--HeaderBackground: rgba(255, 255, 255, 0.85);",
    "--HeaderDisableText: #a6a6a6;",
    "--HeaderDisabledBackground: #f8f8f8;",
    "--HeaderDisabledLines: #eaeaea;",
    "--HeaderLines: #a6a6a6;",
    "--HeaderNavigationHoverText: #0078d7;",
    "--HeaderNavigationPressedText: #004176;",
    "--HeaderNavigationSelectedText: #0078d7;",
    "--HeaderNavigationText: #666666;",
    "--HeaderSiteTitle: #212121;",
    "--HeaderStrongLines: #c4e4ff;",
    "--HeaderSubtleLines: #c8c8c8;",
    "--HeaderText: #333333;",
    "--HoverBackground: rgba(225, 242, 255, 0.50);",
    "--Hyperlink: #0078d7;",
    "--HyperlinkActive: #004176;",
    "--Hyperlinkfollowed: #004176;",
    "--Lines: #a6a6a6;",
    "--Navigation: #666666;",
    "--NavigationAccent: #0078d7;",
    "--NavigationHover: #0078d7;",
    "--NavigationHoverBackground: rgba(225, 242, 255, 0.50);",
    "--NavigationPressed: #004176;",
    "--NavigationSelectedBackground: rgba(234, 234, 234, 0.78);",
    "--PageBackground: #ffffff;",
    "--RowAccent: #0078d7;",
    "--SelectionBackground: rgba(196, 228, 255, 0.50);",
    "--SiteTitle: #212121;",
    "--StrongBodyText: #212121;",
    "--StrongLines: #c4e4ff;",
    "--SubtleEmphasisBackground: #f4f4f4;",
    "--SubtleEmphasisCommandLinks: #212121;",
    "--SubtleEmphasisText: #666666;",
    "--SubtleLines: #c8c8c8;",
    "--SuiteBarBackground: #0078d7;",
    "--SuiteBarHoverBackground: #83c7ff;",
    "--SuiteBarHoverText: #c4e4ff;",
    "--SuiteBarText: #ffffff;",
    "--TileBackgroundOverlay: rgba(0, 0, 0, 0.50);",
    "--TileText: #ffffff;",
    "--TopBarBackground: rgba(234, 234, 234, 0.78);",
    "--TopBarHoverText: #333333;",
    "--TopBarPressedText: #004176;",
    "--TopBarText: #666666;",
    "--WebPartHeading: #333333;",
    "--accent: #8764b8;",
    "--backgroundImageUri: none;",
    "--backgroundOverlay: rgba(255, 255, 255, 0.85);",
    "--black: #000000;",
    "--blackTranslucent40: rgba(0,0,0,.4);",
    "--blockingBackground: rgba(234, 67, 0, .2);",
    "--blue: #0078d4;",
    "--blueDark: #002050;",
    "--blueLight: #00bcf2;",
    "--blueMid: #00188f;",
    "--bodyBackground: #ffffff;",
    "--bodyDivider: #c8c8c8;",
    "--bodyFrameBackground: #ffffff;",
    "--bodyFrameDivider: #eaeaea;",
    "--bodySubtext: #666666;",
    "--bodyText: #333333;",
    "--bodyTextChecked: #000000;",
    "--buttonBackground: #f4f4f4;",
    "--buttonBackgroundChecked: #c8c8c8;",
    "--buttonBackgroundCheckedHovered: #eaeaea;",
    "--buttonBackgroundHovered: #eaeaea;",
    "--buttonBorder: transparent;",
    "--buttonText: #333333;",
    "--buttonTextChecked: #212121;",
    "--buttonTextCheckedHovered: #000000;",
    "--buttonTextHovered: #000000;",
    "--dialogBorder: #f4f4f4;",
    "--disabledBackground: #f4f4f4;",
    "--disabledBodyText: #c8c8c8;",
    "--disabledSubtext: #d0d0d0;",
    "--disabledText: #a6a6a6;",
    "--errorBackground: rgba(232, 17, 35, .2);",
    "--errorText: #a80000;",
    "--focusBorder: #000000;",
    "--green: #107c10;",
    "--greenDark: #004b1c;",
    "--greenLight: #bad80a;",
    "--inputBackground: #ffffff;",
    "--inputBackgroundChecked: #0078d7;",
    "--inputBackgroundCheckedHovered: #006ac1;",
    "--inputBorder: #a6a6a6;",
    "--inputBorderHovered: #212121;",
    "--inputFocusBorderAlt: #0078d7;",
    "--inputForegroundChecked: #ffffff;",
    "--inputPlaceholderText: #666666;",
    "--link: #0078d7;",
    "--linkHovered: #004176;",
    "--listBackground: #ffffff;",
    "--listHeaderBackgroundHovered: #f4f4f4;",
    "--listHeaderBackgroundPressed: #eaeaea;",
    "--listItemBackgroundChecked: #eaeaea;",
    "--listItemBackgroundCheckedHovered: #dadada;",
    "--listItemBackgroundHovered: #f4f4f4;",
    "--listText: #333333;",
    "--listTextColor: #333333;",
    "--magenta: #b4009e;",
    "--magentaDark: #5c005c;",
    "--magentaLight: #e3008c;",
    "--menuHeader: #0078d7;",
    "--menuIcon: #0078d7;",
    "--menuItemBackgroundChecked: #eaeaea;",
    "--menuItemBackgroundHovered: #f4f4f4;",
    "--neutralDark: #212121;",
    "--neutralLight: #eaeaea;",
    "--neutralLighter: #f4f4f4;",
    "--neutralLighterAlt: #f8f8f8;",
    "--neutralPrimary: #333333;",
    "--neutralPrimaryAlt: #3c3c3c;",
    "--neutralQuaternary: #d0d0d0;",
    "--neutralQuaternaryAlt: #dadada;",
    "--neutralSecondary: #666666;",
    "--neutralTertiary: #a6a6a6;",
    "--neutralTertiaryAlt: #c8c8c8;",
    "--orange: #d83b01;",
    "--orangeLight: #ea4300;",
    "--orangeLighter: #ff8c00;",
    "--primaryBackground: #ffffff;",
    "--primaryText: #333333;",
    "--purple: #5c2d91;",
    "--purpleDark: #32145a;",
    "--purpleLight: #b4a0ff;",
    "--red: #e81123;",
    "--redDark: #a80000;",
    "--smallInputBorder: #666666;",
    "--successBackground: rgba(186, 216, 10, .2);",
    "--suiteBarBackground: #0078d7;",
    "--suiteBarText: #ffffff;",
    "--teal: #008272;",
    "--tealDark: #004b50;",
    "--tealLight: #00b294;",
    "--themeAccent: #0078d7;",
    "--themeAccentTranslucent10: rgba(0, 120, 215, 0.10);",
    "--themeDark: #005296;",
    "--themeDarkAlt: #006ac1;",
    "--themeDarker: #004176;",
    "--themeLight: #c4e4ff;",
    "--themeLightAlt: #89cbff;",
    "--themeLighter: #e1f2ff;",
    "--themeLighterAlt: #f0f8ff;",
    "--themePrimary: #0078d7;",
    "--themeSecondary: #0086f4;",
    "--themeTertiary: #83c7ff;",
    "--themeTertiaryAlt: #89cbff;",
    "--topBarBackground: rgba(234, 234, 234, 0.78);",
    "--topBarHoverText: #333333;",
    "--topBarText: #666666;",
    "--warningBackground: rgba(255, 185, 0, .2);",
    "--warningHighlight: #ffb900;",
    "--warningText: #333333;",
    "--white: #ffffff;",
    "--whiteTranslucent40: rgba(255, 255, 255, 0.40);",
    "--yellow: #ffb900;",
    "--yellowLight: #fff100;"
]
const cssVarThemeID = "spfxCSSVarsThemeID";
const themeState = "__themeState__";

export default class uiFabricCSS {

    createCSSVariables() {
        let themeCache = null,
            allVariables = [];

        if (document.getElementById(cssVarThemeID)) {
            return;
        }

        if (themeState in window) {

            themeCache = window[themeState];

            let keys = Object.keys(themeCache.theme);

            keys.forEach(element => {
                allVariables.push("    --" + element + ": " + themeCache.theme[element] + ";");
            });

        } else {

            allVariables = themeSlots;

        }

        var includeInRoot = `:root{
        content: 'hello world';
        ${allVariables.sort().join('\r\n')}
    }`;

        let styleSheetFragment = document.createElement('style');
        styleSheetFragment.id = cssVarThemeID;
        styleSheetFragment.innerHTML = includeInRoot;
        document.head.appendChild(styleSheetFragment);

    }

};<commit_msg>Updated theme state check<commit_after>const themeSlots = [
    "--AccentLines: #0086f4;",
    "--AccentText: #0078d7;",
    "--BackgroundOverlay: rgba(255, 255, 255, 0.85);",
    "--BodyText: #333333;",
    "--ButtonBackground: #f8f8f8;",
    "--ButtonBorder: #a6a6a6;",
    "--ButtonDisabledBackground: #f8f8f8;",
    "--ButtonDisabledBorder: #eaeaea;",
    "--ButtonDisabledText: #a6a6a6;",
    "--ButtonGlyph: #666666;",
    "--ButtonGlyphActive: #333333;",
    "--ButtonGlyphDisabled: #c8c8c8;",
    "--ButtonHoverBackground: #e1f2ff;",
    "--ButtonHoverBorder: #c4e4ff;",
    "--ButtonPressedBackground: #c4e4ff;",
    "--ButtonPressedBorder: #0086f4;",
    "--ButtonText: #333333;",
    "--CommandLinks: #666666;",
    "--CommandLinksDisabled: #a6a6a6;",
    "--CommandLinksHover: #0078d7;",
    "--CommandLinksPressed: #004176;",
    "--CommandLinksSecondary: #212121;",
    "--ContentAccent1: #0078d7;",
    "--DialogBorder: #f4f4f4;",
    "--DisabledBackground: #f8f8f8;",
    "--DisabledLines: #eaeaea;",
    "--DisabledText: #a6a6a6;",
    "--EmphasisBackground: #0078d7;",
    "--EmphasisBorder: #005296;",
    "--EmphasisHoverBackground: #005296;",
    "--EmphasisHoverBorder: #004176;",
    "--EmphasisText: #ffffff;",
    "--FooterBackground: rgba(255, 255, 255, 0.85);",
    "--HeaderAccentLines: #0086f4;",
    "--HeaderBackground: rgba(255, 255, 255, 0.85);",
    "--HeaderDisableText: #a6a6a6;",
    "--HeaderDisabledBackground: #f8f8f8;",
    "--HeaderDisabledLines: #eaeaea;",
    "--HeaderLines: #a6a6a6;",
    "--HeaderNavigationHoverText: #0078d7;",
    "--HeaderNavigationPressedText: #004176;",
    "--HeaderNavigationSelectedText: #0078d7;",
    "--HeaderNavigationText: #666666;",
    "--HeaderSiteTitle: #212121;",
    "--HeaderStrongLines: #c4e4ff;",
    "--HeaderSubtleLines: #c8c8c8;",
    "--HeaderText: #333333;",
    "--HoverBackground: rgba(225, 242, 255, 0.50);",
    "--Hyperlink: #0078d7;",
    "--HyperlinkActive: #004176;",
    "--Hyperlinkfollowed: #004176;",
    "--Lines: #a6a6a6;",
    "--Navigation: #666666;",
    "--NavigationAccent: #0078d7;",
    "--NavigationHover: #0078d7;",
    "--NavigationHoverBackground: rgba(225, 242, 255, 0.50);",
    "--NavigationPressed: #004176;",
    "--NavigationSelectedBackground: rgba(234, 234, 234, 0.78);",
    "--PageBackground: #ffffff;",
    "--RowAccent: #0078d7;",
    "--SelectionBackground: rgba(196, 228, 255, 0.50);",
    "--SiteTitle: #212121;",
    "--StrongBodyText: #212121;",
    "--StrongLines: #c4e4ff;",
    "--SubtleEmphasisBackground: #f4f4f4;",
    "--SubtleEmphasisCommandLinks: #212121;",
    "--SubtleEmphasisText: #666666;",
    "--SubtleLines: #c8c8c8;",
    "--SuiteBarBackground: #0078d7;",
    "--SuiteBarHoverBackground: #83c7ff;",
    "--SuiteBarHoverText: #c4e4ff;",
    "--SuiteBarText: #ffffff;",
    "--TileBackgroundOverlay: rgba(0, 0, 0, 0.50);",
    "--TileText: #ffffff;",
    "--TopBarBackground: rgba(234, 234, 234, 0.78);",
    "--TopBarHoverText: #333333;",
    "--TopBarPressedText: #004176;",
    "--TopBarText: #666666;",
    "--WebPartHeading: #333333;",
    "--accent: #8764b8;",
    "--backgroundImageUri: none;",
    "--backgroundOverlay: rgba(255, 255, 255, 0.85);",
    "--black: #000000;",
    "--blackTranslucent40: rgba(0,0,0,.4);",
    "--blockingBackground: rgba(234, 67, 0, .2);",
    "--blue: #0078d4;",
    "--blueDark: #002050;",
    "--blueLight: #00bcf2;",
    "--blueMid: #00188f;",
    "--bodyBackground: #ffffff;",
    "--bodyDivider: #c8c8c8;",
    "--bodyFrameBackground: #ffffff;",
    "--bodyFrameDivider: #eaeaea;",
    "--bodySubtext: #666666;",
    "--bodyText: #333333;",
    "--bodyTextChecked: #000000;",
    "--buttonBackground: #f4f4f4;",
    "--buttonBackgroundChecked: #c8c8c8;",
    "--buttonBackgroundCheckedHovered: #eaeaea;",
    "--buttonBackgroundHovered: #eaeaea;",
    "--buttonBorder: transparent;",
    "--buttonText: #333333;",
    "--buttonTextChecked: #212121;",
    "--buttonTextCheckedHovered: #000000;",
    "--buttonTextHovered: #000000;",
    "--dialogBorder: #f4f4f4;",
    "--disabledBackground: #f4f4f4;",
    "--disabledBodyText: #c8c8c8;",
    "--disabledSubtext: #d0d0d0;",
    "--disabledText: #a6a6a6;",
    "--errorBackground: rgba(232, 17, 35, .2);",
    "--errorText: #a80000;",
    "--focusBorder: #000000;",
    "--green: #107c10;",
    "--greenDark: #004b1c;",
    "--greenLight: #bad80a;",
    "--inputBackground: #ffffff;",
    "--inputBackgroundChecked: #0078d7;",
    "--inputBackgroundCheckedHovered: #006ac1;",
    "--inputBorder: #a6a6a6;",
    "--inputBorderHovered: #212121;",
    "--inputFocusBorderAlt: #0078d7;",
    "--inputForegroundChecked: #ffffff;",
    "--inputPlaceholderText: #666666;",
    "--link: #0078d7;",
    "--linkHovered: #004176;",
    "--listBackground: #ffffff;",
    "--listHeaderBackgroundHovered: #f4f4f4;",
    "--listHeaderBackgroundPressed: #eaeaea;",
    "--listItemBackgroundChecked: #eaeaea;",
    "--listItemBackgroundCheckedHovered: #dadada;",
    "--listItemBackgroundHovered: #f4f4f4;",
    "--listText: #333333;",
    "--listTextColor: #333333;",
    "--magenta: #b4009e;",
    "--magentaDark: #5c005c;",
    "--magentaLight: #e3008c;",
    "--menuHeader: #0078d7;",
    "--menuIcon: #0078d7;",
    "--menuItemBackgroundChecked: #eaeaea;",
    "--menuItemBackgroundHovered: #f4f4f4;",
    "--neutralDark: #212121;",
    "--neutralLight: #eaeaea;",
    "--neutralLighter: #f4f4f4;",
    "--neutralLighterAlt: #f8f8f8;",
    "--neutralPrimary: #333333;",
    "--neutralPrimaryAlt: #3c3c3c;",
    "--neutralQuaternary: #d0d0d0;",
    "--neutralQuaternaryAlt: #dadada;",
    "--neutralSecondary: #666666;",
    "--neutralTertiary: #a6a6a6;",
    "--neutralTertiaryAlt: #c8c8c8;",
    "--orange: #d83b01;",
    "--orangeLight: #ea4300;",
    "--orangeLighter: #ff8c00;",
    "--primaryBackground: #ffffff;",
    "--primaryText: #333333;",
    "--purple: #5c2d91;",
    "--purpleDark: #32145a;",
    "--purpleLight: #b4a0ff;",
    "--red: #e81123;",
    "--redDark: #a80000;",
    "--smallInputBorder: #666666;",
    "--successBackground: rgba(186, 216, 10, .2);",
    "--suiteBarBackground: #0078d7;",
    "--suiteBarText: #ffffff;",
    "--teal: #008272;",
    "--tealDark: #004b50;",
    "--tealLight: #00b294;",
    "--themeAccent: #0078d7;",
    "--themeAccentTranslucent10: rgba(0, 120, 215, 0.10);",
    "--themeDark: #005296;",
    "--themeDarkAlt: #006ac1;",
    "--themeDarker: #004176;",
    "--themeLight: #c4e4ff;",
    "--themeLightAlt: #89cbff;",
    "--themeLighter: #e1f2ff;",
    "--themeLighterAlt: #f0f8ff;",
    "--themePrimary: #0078d7;",
    "--themeSecondary: #0086f4;",
    "--themeTertiary: #83c7ff;",
    "--themeTertiaryAlt: #89cbff;",
    "--topBarBackground: rgba(234, 234, 234, 0.78);",
    "--topBarHoverText: #333333;",
    "--topBarText: #666666;",
    "--warningBackground: rgba(255, 185, 0, .2);",
    "--warningHighlight: #ffb900;",
    "--warningText: #333333;",
    "--white: #ffffff;",
    "--whiteTranslucent40: rgba(255, 255, 255, 0.40);",
    "--yellow: #ffb900;",
    "--yellowLight: #fff100;"
]
const cssVarThemeID = "spfxCSSVarsThemeID";
const themeState = "__themeState__";

export default function uiFabricCSS() {

    // createCSSVariables() {
    let themeCache = null,
        allVariables = [];

    if (document.getElementById(cssVarThemeID)) {
        return;
    }

    if (themeState in window) {

        themeCache = window[themeState];

        if ('theme' in themeCache && themeCache.theme !== undefined) {

            let keys = Object.keys(themeCache.theme);

            keys.forEach(element => {
                allVariables.push('    --' + element + ': ' + themeCache.theme[element] + ';');
            });

        } else {

            allVariables = themeSlots;

        }

    } else {

        allVariables = themeSlots;

    }

    var includeInRoot = `:root{
          ${allVariables.sort().join('\r\n')}
      }`;

    let styleSheetFragment = document.createElement('style');
    styleSheetFragment.id = cssVarThemeID;
    styleSheetFragment.innerHTML = includeInRoot;
    document.head.appendChild(styleSheetFragment);

};<|endoftext|>


<commit_before>var
FilePath = require('filepath').FilePath,
Yargs    = require('yargs'),

Promise = require('./lib/promise'),
Objects = require('./lib/objects'),
Action  = require('./lib/action').Action,
log     = require('./lib/log'),
Plugins = require('./lib/Plugins'),
LOADER  = require('./lib/loader');

exports.main = function () {
  newUpstate().run();
};

var newUpstate = Objects.factory([Action], {

  initialize: function (args) {
    this.q(this.parseArgv);
    this.q(this.setDirectory);
    this.q(this.loadConfigs);
    this.q(this.checkUser);
    this.q(this.loadTasks);
    this.q(this.checkCommand);
    this.q(this.runTask);
    this.q(this.fin);
  },

  parseArgv: function (args) {
    args.argv = Yargs
      .usage('ups <command> <task> [options]')
      .command('help', 'Print out the help text for a particular task')
      .command('run', 'Run a task')
      .command('tasks', 'Print out a list of available tasks')
      .option('h', {
        alias    : 'help',
        describe : 'Print out this help text and exit.'
      })
      .argv;
    return args;
  },

  setDirectory: function (args) {
    args.directory = FilePath.create().append('upstate');
    return args;
  },

  loadConfigs: function (args) {
    var
    confPath = args.directory.append('config.ini');

    return Plugins.PLUGINS.read_ini.api(confPath)
      .then(function (config) {
        config = config || {};
        var
        userDataPath = (config.paths || {}).user_data;
        args.config = config;

        if (userDataPath) {
          userDataPath = userDataPath.replace(/^\~/, FilePath.home().toString());
          return Plugins.PLUGINS.read_ini.api(userDataPath)
            .then(function (userData) {
              var msg;
              if (!userData) {
                msg = 'User data file not found at '+ userDataPath;
                return Promise.reject(new Error(msg));
              }
              args.user_data = userData;
              return args;
            });
        }
        return args;
      });
  },

  checkUser: function (args) {
    var
    argv = args.argv;

    if (!argv._.length && argv.help) {
      printHelpAndExit();
    } else if (!argv._.length) {
      printHelpAndExit('A command is required.');
    } else if (['help', 'run', 'tasks'].indexOf(argv._[0]) === -1) {
      printHelpAndExit('"'+ argv._[0] +'" is not a valid command');
    }
    Yargs.reset();
    return args;
  },

  loadTasks: function (args) {
    return LOADER.loadTasks({
      task_directory: args.directory
    }).then(function (taskRunner) {
      args.taskRunner = taskRunner;
      return args;
    });
  },

  checkCommand: function (args) {
    var
    cmd = args.argv._[0],
    taskId = args.argv._[1];

    if (cmd === 'tasks') {
      printTasksAndExit(args.taskRunner.tasks);
    } else if (cmd === 'help') {
      printTaskHelpAndExit(args.taskRunner.tasks[taskId]);
    }
    args.taskId = taskId;
    return args;
  },

  runTask: function (args) {
    var
    promise;
    try {
      promise = args.taskRunner.run(args.taskId, args)
        .then(function (result) {
          args.result = result;
          return args;
        });
    } catch (err) {
      if (err.code === 'ENOTASK') {
        promise = Promise.reject({
          message: 'The task '+ args.taskId +' does not exist.'
        });
      } else {
        promise = Promise.reject(err);
      }
    }
    return promise;
  },

  fin: function (args) {
    log.stdout(' *** upstate run complete ***');
  },

  onerror: function (err) {
    var
    stack = err.stack || err.message || 'No stack trace';
    log.error('uncaught error - %s', stack);
    log.stderr('Error: uncaught error:');
    log.stderr(stack);
    return null;
  }
});

function printHelpAndExit(msg) {
  if (msg) {
    console.log(Yargs.help() +'\n\n'+ msg);
  } else {
    console.log(Yargs.help());
  }
  process.exit(1);
}

function printTasksAndExit(tasks) {
  var keys = Object.keys(tasks);
  if (keys.length) {
    console.log('Registered tasks:');
    keys.forEach(function (key) {
      var task = tasks[key];
      console.log(' - %s : %s', task.id, task.description);
    });
  } else {
    console.log('No tasks have been registered.');
  }
  process.exit(1);
}

function printTaskHelpAndExit(task) {
  console.log('\n'+ task.id);
  console.log('\n'+ task.description);
  console.log(task.help);
}
<commit_msg>Make sure to exit after printing task help<commit_after>var
FilePath = require('filepath').FilePath,
Yargs    = require('yargs'),

Promise = require('./lib/promise'),
Objects = require('./lib/objects'),
Action  = require('./lib/action').Action,
log     = require('./lib/log'),
Plugins = require('./lib/Plugins'),
LOADER  = require('./lib/loader');

exports.main = function () {
  newUpstate().run();
};

var newUpstate = Objects.factory([Action], {

  initialize: function (args) {
    this.q(this.parseArgv);
    this.q(this.setDirectory);
    this.q(this.loadConfigs);
    this.q(this.checkUser);
    this.q(this.loadTasks);
    this.q(this.checkCommand);
    this.q(this.runTask);
    this.q(this.fin);
  },

  parseArgv: function (args) {
    args.argv = Yargs
      .usage('ups <command> <task> [options]')
      .command('help', 'Print out the help text for a particular task')
      .command('run', 'Run a task')
      .command('tasks', 'Print out a list of available tasks')
      .option('h', {
        alias    : 'help',
        describe : 'Print out this help text and exit.'
      })
      .argv;
    return args;
  },

  setDirectory: function (args) {
    args.directory = FilePath.create().append('upstate');
    return args;
  },

  loadConfigs: function (args) {
    var
    confPath = args.directory.append('config.ini');

    return Plugins.PLUGINS.read_ini.api(confPath)
      .then(function (config) {
        config = config || {};
        var
        userDataPath = (config.paths || {}).user_data;
        args.config = config;

        if (userDataPath) {
          userDataPath = userDataPath.replace(/^\~/, FilePath.home().toString());
          return Plugins.PLUGINS.read_ini.api(userDataPath)
            .then(function (userData) {
              var msg;
              if (!userData) {
                msg = 'User data file not found at '+ userDataPath;
                return Promise.reject(new Error(msg));
              }
              args.user_data = userData;
              return args;
            });
        }
        return args;
      });
  },

  checkUser: function (args) {
    var
    argv = args.argv;

    if (!argv._.length && argv.help) {
      printHelpAndExit();
    } else if (!argv._.length) {
      printHelpAndExit('A command is required.');
    } else if (['help', 'run', 'tasks'].indexOf(argv._[0]) === -1) {
      printHelpAndExit('"'+ argv._[0] +'" is not a valid command');
    }
    Yargs.reset();
    return args;
  },

  loadTasks: function (args) {
    return LOADER.loadTasks({
      task_directory: args.directory
    }).then(function (taskRunner) {
      args.taskRunner = taskRunner;
      return args;
    });
  },

  checkCommand: function (args) {
    var
    cmd = args.argv._[0],
    taskId = args.argv._[1];

    if (cmd === 'tasks') {
      printTasksAndExit(args.taskRunner.tasks);
    } else if (cmd === 'help') {
      printTaskHelpAndExit(args.taskRunner.tasks[taskId]);
    }
    args.taskId = taskId;
    return args;
  },

  runTask: function (args) {
    var
    promise;
    try {
      promise = args.taskRunner.run(args.taskId, args)
        .then(function (result) {
          args.result = result;
          return args;
        });
    } catch (err) {
      if (err.code === 'ENOTASK') {
        promise = Promise.reject({
          message: 'The task '+ args.taskId +' does not exist.'
        });
      } else {
        promise = Promise.reject(err);
      }
    }
    return promise;
  },

  fin: function (args) {
    log.stdout(' *** upstate run complete ***');
  },

  onerror: function (err) {
    var
    stack = err.stack || err.message || 'No stack trace';
    log.error('uncaught error - %s', stack);
    log.stderr('Error: uncaught error:');
    log.stderr(stack);
    return null;
  }
});

function printHelpAndExit(msg) {
  if (msg) {
    console.log(Yargs.help() +'\n\n'+ msg);
  } else {
    console.log(Yargs.help());
  }
  process.exit(1);
}

function printTasksAndExit(tasks) {
  var keys = Object.keys(tasks);
  if (keys.length) {
    console.log('Registered tasks:');
    keys.forEach(function (key) {
      var task = tasks[key];
      console.log(' - %s : %s', task.id, task.description);
    });
  } else {
    console.log('No tasks have been registered.');
  }
  process.exit(1);
}

function printTaskHelpAndExit(task) {
  console.log('\n'+ task.id);
  console.log('\n'+ task.description);
  console.log(task.help);
  process.exit(1);
}
<|endoftext|>


<commit_before>import React from 'react'
import { Platform } from 'react-native-universal'

import makeClassName from '../utils/makeClassName'
import { expandStyle, createCSSDeclarations } from '../utils/expandCSS'

// This plugin assumes its the first plugin run, and makes the
// style tag the rest of the plugins will use
export default element => {
  const { props } = element
  const { css, style } = props

  // If we're on a native platform, copy css to style and be done
  // with it
  if (Platform.OS !== 'web') {
    let newStyle = Object.keys(css).reduce(
      (styleAccumulator, currentProperty) => {
        if (currentProperty.match(/@media/)) return styleAccumulator
        return {
          ...styleAccumulator,
          [currentProperty]: css[currentProperty],
        }
      },
      {}
    )
    // Override css props with style prop
    newStyle = { ...newStyle, ...(style || {}) }
    return React.cloneElement(element, { ...props, style: newStyle })
  }

  // If we're on web, though, copy the css into a stylesheet
  const className = makeClassName(css)

  const cssDeclarations = createCSSDeclarations(expandStyle(css))

  let newChildren = React.createElement(
    'style',
    { key: className },
    `.${className}{${cssDeclarations}}`
  )

  if (typeof props.children === 'function') {
    newChildren = [newChildren, props.children()]
  } else if (!Array.isArray(props.children)) {
    newChildren = [newChildren, props.children]
  } else {
    newChildren = props.children.concat([newChildren])
  }

  const newProps = {
    ...props,
    className: props.className ?
      [...new Set(props.className.split(' ').concat([className]))].join(' ') :
      className,
    children: newChildren,
  }
  return React.cloneElement(element, newProps)
}
<commit_msg>Allow explicitly setting style properties to null to unset them<commit_after>import React from 'react'
import { Platform } from 'react-native-universal'

import makeClassName from '../utils/makeClassName'
import { expandStyle, createCSSDeclarations } from '../utils/expandCSS'

// This plugin assumes its the first plugin run, and makes the
// style tag the rest of the plugins will use
export default element => {
  const { props } = element
  const { css, style } = props

  // If we're on a native platform, copy css to style and be done
  // with it
  if (Platform.OS !== 'web') {
    let newStyle = Object.keys(css).reduce(
      (styleAccumulator, property) => {
        if (property.match(/@media/)) return styleAccumulator
        return {
          ...styleAccumulator,
          [property]: css[property],
        }
      },
      {}
    )
    // Override css props with style prop
    newStyle = { ...newStyle, ...(style || {}) }
    return React.cloneElement(element, { ...props, style: newStyle })
  }

  // If we're on web, though, copy the css into a stylesheet
  const className = makeClassName(css)

  // Weed out properties that were explicitly set to null
  const cssWithoutNullValues = !style ? css : Object.keys(css).reduce((accumulator, property) => {
    if (style[property] === null) return accumulator
    return { ...accumulator, [property]: css[property] }
  }, {})

  const cssDeclarations = createCSSDeclarations(expandStyle(cssWithoutNullValues))

  let newChildren = React.createElement(
    'style',
    { key: className },
    `.${className}{${cssDeclarations}}`
  )

  if (typeof props.children === 'function') {
    newChildren = [newChildren, props.children()]
  } else if (!Array.isArray(props.children)) {
    newChildren = [newChildren, props.children]
  } else {
    newChildren = props.children.concat([newChildren])
  }

  const newProps = {
    ...props,
    className: props.className ?
      [...new Set(props.className.split(' ').concat([className]))].join(' ') :
      className,
    children: newChildren,
  }
  return React.cloneElement(element, newProps)
}
<|endoftext|>


<commit_before>const AWS = require('aws-sdk');
const Q = require('q');
const merge = require('deepmerge');
const unmarshalJson = require('dynamodb-marshaler/unmarshalJson');

class Dynamo {
  constructor(awsRegion, profile) {
    const region = awsRegion || process.env.AWS_DEFAULT_REGION;
    const params = { region };

    const awsProfile = profile || process.env.AWS_PROFILE;

    if (awsProfile) {
      const SharedIniFileCredentials = AWS.SharedIniFileCredentials;
      params.credentials = new SharedIniFileCredentials({ profile });
    }

    this.eventsFn = {
      INSERT: () => Q(),
      MODIFY: () => Q(),
      REMOVE: () => Q()
    };

    this.docClient = new AWS.DynamoDB.DocumentClient(params);
  }

  process(event) {
    const fullRecord = Dynamo._createFullRecord(event);
    const fn = this.eventsFn[event.eventName];
    let chain = Q.defer();
    chain.reject(new Error(`Unexpected event: ${this.eventType}`));
    chain = chain.promise;
    if (fn) {
      chain = fn(fullRecord).catch(err => {
        throw err;
      });
    }
    return chain;
  }

  onInsert(method) {
    this.eventsFn.INSERT = method;
  }

  onUpdate(method) {
    this.eventsFn.MODIFY = method;
  }

  onRemove(method) {
    this.eventsFn.REMOVE = method;
  }

  get(tableName, hashAndRange) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      Key: hashAndRange
    };

    this.docClient.get(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Item);
      }
    });

    return deferred.promise;
  }

  query(tableName, keyExp, filterExp, nameMap, valueMap, scanForward, limit) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      KeyConditionExpression: keyExp,
      FilterExpression: filterExp,
      ExpressionAttributeValues: valueMap,
      ExpressionAttributeNames: nameMap,
      ScanIndexForward: scanForward || false,
      Limit: limit
    };

    this.docClient.query(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Items);
      }
    });

    return deferred.promise;
  }

  update(tableName, hashAndRange, updateExp, expNames, expValues) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      Key: hashAndRange,
      UpdateExpression: updateExp,
      ExpressionAttributeValues: expValues,
      ExpressionAttributeNames: expNames
    };

    this.docClient.update(params, err => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve();
      }
    });

    return deferred.promise;
  }

  delete(tableName, hashAndRange, conditionExp, expNames, expValues) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      ConditionExpression: conditionExp,
      ExpressionAttributeNames: expNames,
      ExpressionAttributeValues: expValues,
      Key: hashAndRange
    };

    this.docClient.delete(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Items);
      }
    });

    return deferred.promise;
  }

  store(tableName, record) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      Item: record
    };

    this.docClient.put(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data);
      }
    });

    return deferred.promise;
  }

  batchPut(tableName, records) {
    const params = { RequestItems: {} };

    params.RequestItems[tableName] = [];
    records.forEach(record => {
      const request = { PutRequest: { Item: record } };
      params.RequestItems[tableName].push(request);
    });

    return this._batchWrite(params);
  }

  static _createFullRecord(event) {
    let fullRecord;
    if (event.dynamodb.OldImage) {
      fullRecord = JSON.parse(unmarshalJson(event.dynamodb.OldImage));
      if (event.dynamodb.NewImage) {
        const updatedFields = JSON.parse(unmarshalJson(event.dynamodb.NewImage));
        fullRecord = merge(fullRecord, updatedFields);
      }
    } else {
      fullRecord = JSON.parse(unmarshalJson(event.dynamodb.NewImage));
    }

    return fullRecord;
  }

  scan(tableName, filterExp, nameMap, valueMap, limit) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      FilterExpression: filterExp,
      ExpressionAttributeValues: valueMap,
      ExpressionAttributeNames: nameMap,
      Limit: limit
    };

    this.docClient.scan(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Items);
      }
    });

    return deferred.promise;
  }

  eraseAll(tableName, keyName, rangeName) {
    return this.scan(tableName)
      .then(items => {
        const deleteRequests = items.map(item => {
          const keyItem = {};
          keyItem[keyName] = item[keyName];
          keyItem[rangeName] = item[rangeName];
          return { DeleteRequest: { Key: keyItem } };
        });

        const params = { RequestItems: {} };
        params.RequestItems[tableName] = deleteRequests;
        params.ReturnConsumedCapacity = 'TOTAL';
        return params;
      })
      .then(params => {
        const deferred = Q.defer();
        const response = {
          deleted: 0,
          unprocessed: 0
        };
        if (params.RequestItems[tableName].length > 0) {
          this.docClient.batchWrite(params, (err, data) => {
            if (err) {
              deferred.reject(err);
            } else {
              response.deleted = data.ConsumedCapacity[0].CapacityUnits;
              response.unprocessed = Object.keys(data.UnprocessedItems).length;
              deferred.resolve(response);
            }
          });
        } else {
          deferred.resolve(response);
        }
        return deferred.promise;
      });
  }

  _batchWrite(params) {
    const deferred = Q.defer();
    this.docClient.batchWrite(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data);
      }
    });

    return deferred.promise;
  }
}

module.exports = Dynamo;
<commit_msg>adding conditional update<commit_after>const AWS = require('aws-sdk');
const Q = require('q');
const merge = require('deepmerge');
const unmarshalJson = require('dynamodb-marshaler/unmarshalJson');

class Dynamo {
  constructor(awsRegion, profile) {
    const region = awsRegion || process.env.AWS_DEFAULT_REGION;
    const params = { region };

    const awsProfile = profile || process.env.AWS_PROFILE;

    if (awsProfile) {
      const SharedIniFileCredentials = AWS.SharedIniFileCredentials;
      params.credentials = new SharedIniFileCredentials({ profile });
    }

    this.eventsFn = {
      INSERT: () => Q(),
      MODIFY: () => Q(),
      REMOVE: () => Q()
    };

    this.docClient = new AWS.DynamoDB.DocumentClient(params);
  }

  process(event) {
    const fullRecord = Dynamo._createFullRecord(event);
    const fn = this.eventsFn[event.eventName];
    let chain = Q.defer();
    chain.reject(new Error(`Unexpected event: ${this.eventType}`));
    chain = chain.promise;
    if (fn) {
      chain = fn(fullRecord).catch(err => {
        throw err;
      });
    }
    return chain;
  }

  onInsert(method) {
    this.eventsFn.INSERT = method;
  }

  onUpdate(method) {
    this.eventsFn.MODIFY = method;
  }

  onRemove(method) {
    this.eventsFn.REMOVE = method;
  }

  get(tableName, hashAndRange) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      Key: hashAndRange
    };

    this.docClient.get(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Item);
      }
    });

    return deferred.promise;
  }

  query(tableName, keyExp, filterExp, nameMap, valueMap, scanForward, limit) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      KeyConditionExpression: keyExp,
      FilterExpression: filterExp,
      ExpressionAttributeValues: valueMap,
      ExpressionAttributeNames: nameMap,
      ScanIndexForward: scanForward || false,
      Limit: limit
    };

    this.docClient.query(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Items);
      }
    });

    return deferred.promise;
  }

  update(tableName, hashAndRange, updateExp, expNames, expValues, conditionExp) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      Key: hashAndRange,
      ConditionExpression: conditionExp,
      UpdateExpression: updateExp,
      ExpressionAttributeValues: expValues,
      ExpressionAttributeNames: expNames
    };

    this.docClient.update(params, err => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve();
      }
    });

    return deferred.promise;
  }

  delete(tableName, hashAndRange, conditionExp, expNames, expValues) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      ConditionExpression: conditionExp,
      ExpressionAttributeNames: expNames,
      ExpressionAttributeValues: expValues,
      Key: hashAndRange
    };

    this.docClient.delete(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Items);
      }
    });

    return deferred.promise;
  }

  store(tableName, record) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      Item: record
    };

    this.docClient.put(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data);
      }
    });

    return deferred.promise;
  }

  batchPut(tableName, records) {
    const params = { RequestItems: {} };

    params.RequestItems[tableName] = [];
    records.forEach(record => {
      const request = { PutRequest: { Item: record } };
      params.RequestItems[tableName].push(request);
    });

    return this._batchWrite(params);
  }

  static _createFullRecord(event) {
    let fullRecord;
    if (event.dynamodb.OldImage) {
      fullRecord = JSON.parse(unmarshalJson(event.dynamodb.OldImage));
      if (event.dynamodb.NewImage) {
        const updatedFields = JSON.parse(unmarshalJson(event.dynamodb.NewImage));
        fullRecord = merge(fullRecord, updatedFields);
      }
    } else {
      fullRecord = JSON.parse(unmarshalJson(event.dynamodb.NewImage));
    }

    return fullRecord;
  }

  scan(tableName, filterExp, nameMap, valueMap, limit) {
    const deferred = Q.defer();
    const params = {
      TableName: tableName,
      FilterExpression: filterExp,
      ExpressionAttributeValues: valueMap,
      ExpressionAttributeNames: nameMap,
      Limit: limit
    };

    this.docClient.scan(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data.Items);
      }
    });

    return deferred.promise;
  }

  eraseAll(tableName, keyName, rangeName) {
    return this.scan(tableName)
      .then(items => {
        const deleteRequests = items.map(item => {
          const keyItem = {};
          keyItem[keyName] = item[keyName];
          keyItem[rangeName] = item[rangeName];
          return { DeleteRequest: { Key: keyItem } };
        });

        const params = { RequestItems: {} };
        params.RequestItems[tableName] = deleteRequests;
        params.ReturnConsumedCapacity = 'TOTAL';
        return params;
      })
      .then(params => {
        const deferred = Q.defer();
        const response = {
          deleted: 0,
          unprocessed: 0
        };
        if (params.RequestItems[tableName].length > 0) {
          this.docClient.batchWrite(params, (err, data) => {
            if (err) {
              deferred.reject(err);
            } else {
              response.deleted = data.ConsumedCapacity[0].CapacityUnits;
              response.unprocessed = Object.keys(data.UnprocessedItems).length;
              deferred.resolve(response);
            }
          });
        } else {
          deferred.resolve(response);
        }
        return deferred.promise;
      });
  }

  _batchWrite(params) {
    const deferred = Q.defer();
    this.docClient.batchWrite(params, (err, data) => {
      if (err) {
        deferred.reject(err);
      } else {
        deferred.resolve(data);
      }
    });

    return deferred.promise;
  }
}

module.exports = Dynamo;
<|endoftext|>


<commit_before>import {List, Map} from 'immutable';
import {expect} from 'chai';
import {setEntries, next, vote} from '../src/core';

describe('application logic', () => {

    describe('setEntries', () => {

        it('adds the entries to the state', () => {
            const state = Map();
            const entries = ['Trainspotting', '28 Days Later'];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of('Trainspotting', '28 Days Later')
            }));
        });
    });

    describe('next', () => {

        it('takes the next two entries under vote', () => {
            const state = Map({
                entries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
            });
            const nextState = next(state);
            console.log(nextState)
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later')
                }),
                entries: List.of('Sunshine')
            }));
        });
        it('puts the winner of the current vote back to the entries', () => {
            const state = Map({
                vote: Map({
                   pair: List.of('Trainspotting', '28 Days Later'),
                   tally: Map({
                       'Trainspotting': 4,
                       '28 Days Later': 2
                   })
               }),
               entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions'),
                }),
                entries: List.of('127 Hours', 'Trainspotting')
            }));
        });
        it('puts both from tied entries', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 3,
                        '28 Days Later': 3
                    })
                }),
                entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions')
                }),
                entries: List.of('127 Hours', 'Trainspotting', '28 Days Later')
            }));
        });
        it('marks winner when just one entry left', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 4,
                        '28 Days Later': 2
                    })
                }),
                entries: List()
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                winner: 'Trainspotting'
            }));
        });

    });

    describe('vote', () => {

        it('creates a tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later')
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 1
                })
            }));
        });
        it('adds to an existing tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 3,
                    '28 Days Later': 2
                })
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 4,
                    '28 Days Later': 2
                })
            }));
        });
    });

});

<commit_msg>added documentation for adding entries to the state<commit_after>import {List, Map} from 'immutable';
import {expect} from 'chai';
import {setEntries, next, vote} from '../src/core';

describe('application logic', () => {

    /* The application allows loading in a collection of entries to be voted on.
     * We should have a function that takes a previous state and produces a state
     * where the entries are included. The test is to check setEntries does that.
    * */
    describe('setEntries', () => {

        it('adds the entries to the state', () => {
            const state = Map();
            const entries = ['Trainspotting', '28 Days Later'];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of('Trainspotting', '28 Days Later')
            }));
        });

    });

    describe('next', () => {

        it('takes the next two entries under vote', () => {
            const state = Map({
                entries: List.of('Trainspotting', '28 Days Later', 'Sunshine')
            });
            const nextState = next(state);
            console.log(nextState)
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later')
                }),
                entries: List.of('Sunshine')
            }));
        });
        it('puts the winner of the current vote back to the entries', () => {
            const state = Map({
                vote: Map({
                   pair: List.of('Trainspotting', '28 Days Later'),
                   tally: Map({
                       'Trainspotting': 4,
                       '28 Days Later': 2
                   })
               }),
               entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions'),
                }),
                entries: List.of('127 Hours', 'Trainspotting')
            }));
        });
        it('puts both from tied entries', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 3,
                        '28 Days Later': 3
                    })
                }),
                entries: List.of('Sunshine', 'Millions', '127 Hours')
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of('Sunshine', 'Millions')
                }),
                entries: List.of('127 Hours', 'Trainspotting', '28 Days Later')
            }));
        });
        it('marks winner when just one entry left', () => {
            const state = Map({
                vote: Map({
                    pair: List.of('Trainspotting', '28 Days Later'),
                    tally: Map({
                        'Trainspotting': 4,
                        '28 Days Later': 2
                    })
                }),
                entries: List()
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                winner: 'Trainspotting'
            }));
        });

    });

    describe('vote', () => {

        it('creates a tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later')
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 1
                })
            }));
        });
        it('adds to an existing tally for the voted entry', () => {
            const state = Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 3,
                    '28 Days Later': 2
                })
            });
            const nextState = vote(state, 'Trainspotting');
            expect(nextState).to.equal(Map({
                pair: List.of('Trainspotting', '28 Days Later'),
                tally: Map({
                    'Trainspotting': 4,
                    '28 Days Later': 2
                })
            }));
        });
    });

});

<|endoftext|>


<commit_before>var mongodb = require('mongodb');
var thunky = require('thunky');
var Readable = require('stream').Readable || require('readable-stream');

var DRIVER_COLLECTION_PROTO = mongodb.Collection.prototype;
var DRIVER_CURSOR_PROTO = mongodb.Cursor.prototype;
var DRIVER_DB_PROTO = mongodb.Db.prototype;

var noop = function() {};

var forEachMethod = function(oldProto, newProto, fn) {
	Object.keys(oldProto).forEach(function(methodName) {
		if (oldProto.__lookupGetter__(methodName) || newProto[methodName]) return;
		if (methodName[0] === '_' || typeof oldProto[methodName] !== 'function') return;
		fn(methodName, oldProto[methodName]);
	});
};

var getCallback = function(args) {
	var callback = args[args.length-1];
	return typeof callback === 'function' ? callback : noop;
};

// Proxy for the native cursor prototype that normalizes method names and
// arguments to fit the mongo shell.

var Cursor = function(oncursor) {
	Readable.call(this, {objectMode:true});
	this._get = oncursor;
};

Cursor.prototype.__proto__ = Readable.prototype;

Cursor.prototype.toArray = function() {
	this._apply(DRIVER_CURSOR_PROTO.toArray, arguments);
};

Cursor.prototype.next = function() {
	this._apply(DRIVER_CURSOR_PROTO.nextObject, arguments);
};

Cursor.prototype.forEach = function() {
	this._apply(DRIVER_CURSOR_PROTO.each, arguments);
};

Cursor.prototype.count = function() {
	this._apply(DRIVER_CURSOR_PROTO.count, arguments);
};

Cursor.prototype.limit = function() {
	return this._config(DRIVER_CURSOR_PROTO.limit, arguments);
};

Cursor.prototype.skip = function() {
	return this._config(DRIVER_CURSOR_PROTO.skip, arguments);
};

Cursor.prototype.batchSize = function() {
	return this._config(DRIVER_CURSOR_PROTO.batchSize, arguments);
};

Cursor.prototype.sort = function() {
	return this._config(DRIVER_CURSOR_PROTO.sort, arguments);
};

Cursor.prototype._apply = function(fn, args) {
	this._get(function(err, cursor) {
		if (err) return getCallback(args)(err);
		fn.apply(cursor, args);
	});

	return this;
};

Cursor.prototype._read = function() { // 0.10 stream support (0.8 compat using readable-stream)
	var self = this;
	this.next(function(err, data) {
		if (err) return self.emit('error', err);
		self.push(data);
	});
};

Cursor.prototype._config = function(fn, args) {
	if (typeof args[args.length-1] !== 'function') return this._apply(fn, args);

	args = Array.prototype.slice.call(args);
	var callback = args.pop();
	return this._apply(fn, args).toArray(callback);
};

// Proxy for the native collection prototype that normalizes method names and
// arguments to fit the mongo shell.

var Collection = function(oncollection) {
	this._get = oncollection;
};

Collection.prototype.find = function() {
	var args = Array.prototype.slice.call(arguments);

	var oncollection = this._get;
	var oncursor = thunky(function(callback) {
		args.push(callback);
		oncollection(function(err, collection) {
			if (err) return callback(err);
			collection.find.apply(collection, args);
		});
	});

	if (typeof args[args.length-1] === 'function') {
		var callback = args.pop();

		oncursor(function(err, cursor) {
			if (err) return callback(err);
			cursor.toArray(callback);
		});
	}

	return new Cursor(oncursor);
};

Collection.prototype.findOne = function() { // see http://www.mongodb.org/display/DOCS/Queries+and+Cursors
	var args = Array.prototype.slice.call(arguments);
	var callback = args.pop();

	this.find.apply(this, args).limit(1).next(callback);
};

Collection.prototype.findAndModify = function(options, callback) {
	this._apply(DRIVER_COLLECTION_PROTO.findAndModify, [options.query, options.sort || [], options.update || {}, {
		new:!!options.new,
		remove:!!options.remove,
		upsert:!!options.upsert,
		fields:options.fields
	}, callback]);
};

Collection.prototype.remove = function() {
	this._apply(DRIVER_COLLECTION_PROTO.remove, arguments.length === 0 ? [{}] : arguments); // driver has a small issue with zero-arguments in remove
};

Collection.prototype.group = function(group, callback) {
	this._apply(DRIVER_COLLECTION_PROTO.group, [group.key ? group.key : group.keyf, group.cond, group.initial, group.reduce, group.finalize, true, callback]);
};

forEachMethod(DRIVER_COLLECTION_PROTO, Collection.prototype, function(methodName, fn) {
	Collection.prototype[methodName] = function() { // we just proxy the rest of the methods directly
		this._apply(fn, arguments);
	};
});

Collection.prototype._apply = function(fn, args) {
	this._get(function(err, collection) {
		if (err) return getCallback(args)(err);
		if (!collection.opts || getCallback(args) === noop) return fn.apply(collection, args);

		var safe = collection.opts.safe;
		collection.opts.safe = true;
		fn.apply(collection, args);
		collection.opts.safe = safe;
	});
};

var toConnectionString = function(conf) { // backwards compat config map (use a connection string instead)
	var options = [];
	var hosts = conf.replSet ? conf.replSet.members || conf.replSet : [conf];
	var auth = conf.username ? (conf.username+':'+conf.password+'@') : '';

	hosts = hosts.map(function(server) {
		if (typeof server === 'string') return server;
		return (server.host || '127.0.0.1') + ':' + (server.port || 27017);
	}).join(',');

	if (conf.slaveOk) options.push('slaveOk=true');

	return 'mongodb://'+auth+hosts+'/'+conf.db+'?'+options.join('&');
};

var parseConfig = function(cs) {
	if (typeof cs === 'object' && cs) return toConnectionString(cs);

	cs = cs.replace(/^\//, '');

	if (cs.indexOf('/') < 0) return parseConfig('127.0.0.1/'+cs);
	if (cs.indexOf('mongodb://') !== 0) return parseConfig('mongodb://'+cs);

	return cs;
};

var connect = function(config, collections) {
	var that = {};
	var connectionString = parseConfig(config);

	var ondb = thunky(function(callback) {
		mongodb.Db.connect(connectionString, function(err, db) {
			if (err) return callback(err);
			that.client = db;
			callback(null, db);
		});
	});

	that.bson = mongodb.BSONPure; // backwards compat
	that.ObjectId = mongodb.ObjectID; // backwards compat

	that.collection = function(name) {
		if (that[name]) return that[name];

		var oncollection = thunky(function(callback) {
			ondb(function(err, db) {
				if (err) return callback(err);
				db.collection(name, callback);
			});
		});

		return that[name] = new Collection(oncollection);
	};

	collections = collections || config.collections || [];
	collections.forEach(that.collection);

	forEachMethod(DRIVER_DB_PROTO, that, function(methodName, fn) {
		that[methodName] = function() {
			var args = arguments;

			ondb(function(err, db) {
				if (err) return getCallback(args)(err);
				fn.apply(db, args);
			});
		};
	});

	return that;
};

connect.connect = connect; // backwards compat
connect.ObjectId = mongodb.ObjectID;
connect.Cursor = Cursor;
connect.Collection = Collection;
module.exports = connect;
<commit_msg>callback should be optional for all mutators<commit_after>var mongodb = require('mongodb');
var thunky = require('thunky');
var Readable = require('stream').Readable || require('readable-stream');

var DRIVER_COLLECTION_PROTO = mongodb.Collection.prototype;
var DRIVER_CURSOR_PROTO = mongodb.Cursor.prototype;
var DRIVER_DB_PROTO = mongodb.Db.prototype;

var noop = function() {};

var forEachMethod = function(oldProto, newProto, fn) {
	Object.keys(oldProto).forEach(function(methodName) {
		if (oldProto.__lookupGetter__(methodName) || newProto[methodName]) return;
		if (methodName[0] === '_' || typeof oldProto[methodName] !== 'function') return;
		fn(methodName, oldProto[methodName]);
	});
};

var ensureCallback = function(args) {
	if (getCallback(args) !== noop) return args;
	args = Array.prototype.slice.call(args);
	args.push(noop);
	return args;
};

var getCallback = function(args) {
	var callback = args[args.length-1];
	return typeof callback === 'function' ? callback : noop;
};

// Proxy for the native cursor prototype that normalizes method names and
// arguments to fit the mongo shell.

var Cursor = function(oncursor) {
	Readable.call(this, {objectMode:true});
	this._get = oncursor;
};

Cursor.prototype.__proto__ = Readable.prototype;

Cursor.prototype.toArray = function() {
	this._apply(DRIVER_CURSOR_PROTO.toArray, arguments);
};

Cursor.prototype.next = function() {
	this._apply(DRIVER_CURSOR_PROTO.nextObject, arguments);
};

Cursor.prototype.forEach = function() {
	this._apply(DRIVER_CURSOR_PROTO.each, arguments);
};

Cursor.prototype.count = function() {
	this._apply(DRIVER_CURSOR_PROTO.count, arguments);
};

Cursor.prototype.limit = function() {
	return this._config(DRIVER_CURSOR_PROTO.limit, arguments);
};

Cursor.prototype.skip = function() {
	return this._config(DRIVER_CURSOR_PROTO.skip, arguments);
};

Cursor.prototype.batchSize = function() {
	return this._config(DRIVER_CURSOR_PROTO.batchSize, arguments);
};

Cursor.prototype.sort = function() {
	return this._config(DRIVER_CURSOR_PROTO.sort, arguments);
};

Cursor.prototype._apply = function(fn, args) {
	this._get(function(err, cursor) {
		if (err) return getCallback(args)(err);
		fn.apply(cursor, args);
	});

	return this;
};

Cursor.prototype._read = function() { // 0.10 stream support (0.8 compat using readable-stream)
	var self = this;
	this.next(function(err, data) {
		if (err) return self.emit('error', err);
		self.push(data);
	});
};

Cursor.prototype._config = function(fn, args) {
	if (typeof args[args.length-1] !== 'function') return this._apply(fn, args);

	args = Array.prototype.slice.call(args);
	var callback = args.pop();
	return this._apply(fn, args).toArray(callback);
};

// Proxy for the native collection prototype that normalizes method names and
// arguments to fit the mongo shell.

var Collection = function(oncollection) {
	this._get = oncollection;
};

Collection.prototype.find = function() {
	var args = Array.prototype.slice.call(arguments);

	var oncollection = this._get;
	var oncursor = thunky(function(callback) {
		args.push(callback);
		oncollection(function(err, collection) {
			if (err) return callback(err);
			collection.find.apply(collection, args);
		});
	});

	if (typeof args[args.length-1] === 'function') {
		var callback = args.pop();

		oncursor(function(err, cursor) {
			if (err) return callback(err);
			cursor.toArray(callback);
		});
	}

	return new Cursor(oncursor);
};

Collection.prototype.findOne = function() { // see http://www.mongodb.org/display/DOCS/Queries+and+Cursors
	var args = Array.prototype.slice.call(arguments);
	var callback = args.pop();

	this.find.apply(this, args).limit(1).next(callback);
};

Collection.prototype.findAndModify = function(options, callback) {
	this._apply(DRIVER_COLLECTION_PROTO.findAndModify, [options.query, options.sort || [], options.update || {}, {
		new:!!options.new,
		remove:!!options.remove,
		upsert:!!options.upsert,
		fields:options.fields
	}, callback || noop]);
};

Collection.prototype.group = function(group, callback) {
	this._apply(DRIVER_COLLECTION_PROTO.group, [group.key ? group.key : group.keyf, group.cond, group.initial, group.reduce, group.finalize, true, callback]);
};

Collection.prototype.remove = function() {
	this._apply(DRIVER_COLLECTION_PROTO.remove, arguments.length === 0 ? [{}, noop] : ensureCallback(arguments));
};

forEachMethod(DRIVER_COLLECTION_PROTO, Collection.prototype, function(methodName, fn) {
	Collection.prototype[methodName] = function() { // we just proxy the rest of the methods directly
		this._apply(fn, ensureCallback(arguments));
	};
});

Collection.prototype._apply = function(fn, args) {
	this._get(function(err, collection) {
		if (err) return getCallback(args)(err);
		if (!collection.opts || getCallback(args) === noop) return fn.apply(collection, args);

		var safe = collection.opts.safe;
		collection.opts.safe = true;
		fn.apply(collection, args);
		collection.opts.safe = safe;
	});
};

var toConnectionString = function(conf) { // backwards compat config map (use a connection string instead)
	var options = [];
	var hosts = conf.replSet ? conf.replSet.members || conf.replSet : [conf];
	var auth = conf.username ? (conf.username+':'+conf.password+'@') : '';

	hosts = hosts.map(function(server) {
		if (typeof server === 'string') return server;
		return (server.host || '127.0.0.1') + ':' + (server.port || 27017);
	}).join(',');

	if (conf.slaveOk) options.push('slaveOk=true');

	return 'mongodb://'+auth+hosts+'/'+conf.db+'?'+options.join('&');
};

var parseConfig = function(cs) {
	if (typeof cs === 'object' && cs) return toConnectionString(cs);

	cs = cs.replace(/^\//, '');

	if (cs.indexOf('/') < 0) return parseConfig('127.0.0.1/'+cs);
	if (cs.indexOf('mongodb://') !== 0) return parseConfig('mongodb://'+cs);

	return cs;
};

var connect = function(config, collections) {
	var that = {};
	var connectionString = parseConfig(config);

	var ondb = thunky(function(callback) {
		mongodb.Db.connect(connectionString, function(err, db) {
			if (err) return callback(err);
			that.client = db;
			callback(null, db);
		});
	});

	that.bson = mongodb.BSONPure; // backwards compat
	that.ObjectId = mongodb.ObjectID; // backwards compat

	that.collection = function(name) {
		if (that[name]) return that[name];

		var oncollection = thunky(function(callback) {
			ondb(function(err, db) {
				if (err) return callback(err);
				db.collection(name, callback);
			});
		});

		return that[name] = new Collection(oncollection);
	};

	collections = collections || config.collections || [];
	collections.forEach(that.collection);

	forEachMethod(DRIVER_DB_PROTO, that, function(methodName, fn) {
		that[methodName] = function() {
			var args = arguments;

			ondb(function(err, db) {
				if (err) return getCallback(args)(err);
				fn.apply(db, args);
			});
		};
	});

	return that;
};

connect.connect = connect; // backwards compat
connect.ObjectId = mongodb.ObjectID;
connect.Cursor = Cursor;
connect.Collection = Collection;
module.exports = connect;
<|endoftext|>


<commit_before>var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));

app.get('/', function (req, res)
{
  res.send('Maggie is working!')
})

app.get('/vehicle-link', function (req, res)
{
  res.send('Success!')
})

app.get('/webhook', function(req, res) {
  if (req.query['hub.mode'] === 'subscribe' &&
      req.query['hub.verify_token'] === 'SECRET') {
    console.log("Validating webhook");
    res.status(200).send(req.query['hub.challenge']);
  } else {
    console.error("Failed validation. Make sure the validation tokens match.");
    res.sendStatus(403);
  }
});
// app.post('/webhook/', funtion(req, res) {
// 	res.send('hello world');
// })

app.listen(app.get('port'), function() {
    console.log("Node app is running at localhost:" + app.get('port'))
});<commit_msg>added basic received messages function<commit_after>var express = require('express');
var app = express();

app.set('port', (process.env.PORT || 5000));

app.get('/', function (req, res)
{
  res.send('Maggie is working!')
})

app.get('/vehicle-link', function (req, res)
{
  res.send('Success!')
})

//
// Facebook Messenger - Verification
//

app.get('/webhook', function(req, res) {
  if (req.query['hub.mode'] === 'subscribe' &&
      req.query['hub.verify_token'] === 'SECRET') {
    console.log("Validating webhook");
    res.status(200).send(req.query['hub.challenge']);
  } else {
    console.error("Failed validation. Make sure the validation tokens match.");
    res.sendStatus(403);
  }
});

//
// Facebook Messenger - Receive Messages
//

app.post('/webhook', function (req, res) {
  var data = req.body;

  // Make sure this is a page subscription
  if (data.object === 'page') {

    // Iterate over each entry - there may be multiple if batched
    data.entry.forEach(function(entry) {
      var pageID = entry.id;
      var timeOfEvent = entry.time;

      // Iterate over each messaging event
      entry.messaging.forEach(function(event) {
        if (event.message) {
          receivedMessage(event);
        } else {
          console.log("Webhook received unknown event: ", event);
        }
      });
    });

    // Assume all went well.
    //
    // You must send back a 200, within 20 seconds, to let us know
    // you've successfully received the callback. Otherwise, the request
    // will time out and we will keep trying to resend.
    res.sendStatus(200);
  }
});

app.listen(app.get('port'), function() {
    console.log("Node app is running at localhost:" + app.get('port'))
});

//
// Functions
//

function receivedMessage(event) {
  // Putting a stub for now, we'll expand it in the following steps
  console.log("Message data: ", event.message);
}<|endoftext|>


<commit_before>'use strict';

var Promise = require('bluebird');
var htmlparser = require("htmlparser2");
var Dom = require('./lib/dom');
var Element = require('./lib/element');
var Attribute = require('./lib/attribute');
var Text = require('./lib/text');

module.exports = function renderHtml(input) {
	return new Promise(function (resolve, reject) {
		if (typeof input !== 'string') throw new TypeError('Input argument must be a string.');

		var DOM = new Dom;
		var context = DOM;

		var parser = new htmlparser.Parser({
			onopentag: function (name, attribs) {
				var element = new Element(name);
				for (var key in attribs) {
					element.appendAttribute(new Attribute(key, attribs[key]));
				}
				context.appendChild(element);
				context = element;
			},
			ontext: function (text) {
				context.appendChild(new Text(text));
			},
			onclosetag: function (name) {
				if (!context.parent) throw new Error('Cannot exit a context which has no parent.');
				if ('' + name !== context.name) throw new Error('Reached a close tag that doesn\'t match the current context.');
				context = context.parent;
			},
			onerror: function (err) {
				throw err;
			},
			onend: function () {
				resolve('' + DOM);
			}
		}, {decodeEntities: false});

		parser.write(input);
		parser.end();
	});
};

var api = [{
		property: 'element',
		constructor: Element,
		current: null,
		original: Element.prototype.toString
	},{
		property: 'attribute',
		constructor: Attribute,
		current: null,
		original: Attribute.prototype.toString
	},{
		property: 'text',
		constructor: Text,
		current: null,
		original: Text.prototype.toString
	}
];

api.forEach(function (node) {
	Object.defineProperty(module.exports, node.property, {
		get: function () {return node.current;},
		set: function (func) {
			if (typeof func !== 'function') throw new TypeError('Expected function, got ' + typeof func + '.');
			node.current = func;
			node.constructor.prototype.toString = function () {
				var str = func.call(this, node.original);
				return typeof str === 'string' ? str : node.original.call(this);
			};
		}
	});
});

module.exports.reset = [].forEach.bind(api,
	function (node) {
		module.exports[node.property] = function (original) {
			return original.call(this);
		};
	}
);

module.exports.reset();
<commit_msg>updated reset functions<commit_after>'use strict';

var Promise = require('bluebird');
var htmlparser = require("htmlparser2");
var Dom = require('./lib/dom');
var Element = require('./lib/element');
var Attribute = require('./lib/attribute');
var Text = require('./lib/text');

module.exports = function renderHtml(input) {
	return new Promise(function (resolve, reject) {
		if (typeof input !== 'string') throw new TypeError('Input argument must be a string.');

		var DOM = new Dom;
		var context = DOM;

		var parser = new htmlparser.Parser({
			onopentag: function (name, attribs) {
				var element = new Element(name);
				for (var key in attribs) {
					element.appendAttribute(new Attribute(key, attribs[key]));
				}
				context.appendChild(element);
				context = element;
			},
			ontext: function (text) {
				context.appendChild(new Text(text));
			},
			onclosetag: function (name) {
				if (!context.parent) throw new Error('Cannot exit a context which has no parent.');
				if ('' + name !== context.name) throw new Error('Reached a close tag that doesn\'t match the current context.');
				context = context.parent;
			},
			onerror: function (err) {
				throw err;
			},
			onend: function () {
				resolve('' + DOM);
			}
		}, {decodeEntities: false});

		parser.write(input);
		parser.end();
	});
};

var api = [{
		property: 'element',
		constructor: Element,
		current: null,
		original: Element.prototype.toString
	},{
		property: 'attribute',
		constructor: Attribute,
		current: null,
		original: Attribute.prototype.toString
	},{
		property: 'text',
		constructor: Text,
		current: null,
		original: Text.prototype.toString
	}
];

api.forEach(function (node) {
	Object.defineProperty(module.exports, node.property, {
		get: function () {return node.current;},
		set: function (func) {
			if (typeof func !== 'function') throw new TypeError('Expected function, got ' + typeof func + '.');
			node.current = func;
			node.constructor.prototype.toString = function () {
				var str = func.call(this, node.original);
				return typeof str === 'string' ? str : node.original.call(this);
			};
		}
	});
});

module.exports.reset = [].forEach.bind(api,
	function (node) {
		module.exports[node.property] = function () {};
	}
);

module.exports.reset();
<|endoftext|>