<commit_before>import React, { PropTypes, Component } from 'react';
import * as UserActionCreators from '../../actions/UserActionCreators';
import TextInput from '../ui/TextInput';
import TextRadios from '../ui/TextRadios';
import TextCheckboxes from '../ui/TextCheckboxes';
import InputCheckbox from '../ui/InputCheckbox';
import TagInput from '../ui/TagInput';
import FullWidthButton from '../ui/FullWidthButton';

export default class CreateContentThread extends Component {
    static propTypes = {
        userId: PropTypes.number.isRequired,
        filters: PropTypes.object.isRequired
        // TODO: tagSuggestions should be a prop
    };

    constructor(props) {
        super(props);

        this.handleClickAddFilter = this.handleClickAddFilter.bind(this);
        this.renderFiltersList = this.renderFiltersList.bind(this);
        this.handleClickFilterOnList = this.handleClickFilterOnList.bind(this);
        this.renderActiveFilters = this.renderActiveFilters.bind(this);
        this.renderMultipleChoicesFilter = this.renderMultipleChoicesFilter.bind(this);
        this.renderTagFilter = this.renderTagFilter.bind(this);
        this.handleClickMultipleChoice = this.handleClickMultipleChoice.bind(this);
        this.handleKeyUpTag = this.handleKeyUpTag.bind(this);
        this.handleClickTagSuggestion = this.handleClickTagSuggestion.bind(this);
        this.handleClickFilter = this.handleClickFilter.bind(this);
        this.handleClickRemoveFilter = this.handleClickRemoveFilter.bind(this);
        this.createThread = this.createThread.bind(this);

        this.state = {
            selectFilter: false,
            selectedFilter: {},
            filters: [],
            tagSuggestions: []
        }
    }

    render() {
        Object.keys(this.props.filters).forEach(key => this.props.filters[key].key = key);
        let content = '';
        if (this.state.selectFilter) {
            content =

Selecciona un filtro

                {this.renderFiltersList()}

;
        } else {
            content =

                {this.renderActiveFilters()}

                            Añadir filtro

                <FullWidthButton onClick={this.createThread}>Crear hilo</FullWidthButton>

;
        }

        return (
            content
        );
    }

    handleClickAddFilter() {
        this.setState({
            selectFilter: true
        })
    }

    renderFiltersList() {
        return(

                    {Object.keys(this.props.filters).map((id) => {
                        let text = this.props.filters[id].label;
                        let checked = this.state.filters.some(filter => filter.key === this.props.filters[id].key);
                        return (

                                <InputCheckbox value={this.props.filters[id].key} name={this.props.filters[id].key} text={text}
                                               checked={checked} defaultChecked={false} onClickHandler={this.handleClickFilterOnList} reverse={true}/>

                        )
                    })}

        );
    }

    handleClickFilterOnList(checked, value) {
        let filters = this.state.filters;
        let filter = this.state.filters.find(key => key === value);
        if (typeof filter == 'undefined') {
            let defaultFilters = JSON.parse(JSON.stringify(this.props.filters));
            filter = Object.keys(defaultFilters).map(key => defaultFilters[key]).find(function (defaultFilter) {
                return defaultFilter.key === value;
            });
        }
        if (checked) {
            this.setState({
                selectFilter: false,
                selectedFilter: filter
            });
        } else {
            let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
            filters.splice(index, 1);
            this.setState({
                filters: filters,
                selectedFilter: {}
            });
        }
    }

    renderActiveFilters() {
        let filters = this.state.filters || [];
        let selectedFilterContent = '';
        if (this.state.selectedFilter.key) {
            let isSelectedFilterActive = filters.some(filter => filter.key === this.state.selectedFilter.key);
            if (!isSelectedFilterActive) {
                filters.push(this.state.selectedFilter);
            }
            switch (this.state.selectedFilter.type) {
                case 'multiple_choices':
                    selectedFilterContent = this.renderMultipleChoicesFilter();
                    break;
                case 'tags':
                    selectedFilterContent = this.renderTagFilter();
                    break;
            }
        }
        let multipleChoicesFilter = filters.filter(filter => filter.type === 'multiple_choices');
        let tagsFilter = filters.filter(filter => filter.type === 'tags');
        let filterCheckboxes = [];

        if (multipleChoicesFilter) {
            multipleChoicesFilter.forEach(filter => {
                let values = filter.values || [];
                let textArray = values.map(value => filter.choices[value]);
                let text = textArray.length > 0 ? filter.label + ' - ' + textArray.join(', ') : filter.label;
                filterCheckboxes.push({
                    label: {key: filter.key, text: text},
                    value: filter.key,
                    selected: this.state.selectedFilter && this.state.selectedFilter.key === filter.key
                });
            });
        }
        if (tagsFilter) {
            tagsFilter.forEach(filter => {
                let tags = filter.values;
                let text = tags && tags.length > 0 ? filter.label + ' - ' + tags.join(', ') : filter.label;
                filterCheckboxes.push({
                    label: {key: filter.key, text: text},
                    value: filter.key,
                    selected: this.state.selectedFilter && this.state.selectedFilter.key === filter.key
                });
            });
        }

        return (
            filterCheckboxes.map((filterCheckbox, index) =>
                filterCheckbox.selected ?
                    selectedFilterContent :

                        <TextCheckboxes labels={[filterCheckbox.label]} onClickHandler={this.handleClickFilter.bind(this, filterCheckbox.label.key)}
                                        values={filters.map(filter => {return filter.value || filter.choice || filter.values && filter.values.length > 0 ? filter.key : null})} />

            )
        );
    }

    renderMultipleChoicesFilter() {
        return (

                {this.renderSelectedFilterBackground()}

                     0 ? "icon-circle active" : "icon-circle"}>

                <TextCheckboxes labels={Object.keys(this.state.selectedFilter.choices).map(key => { return({key: key, text: this.state.selectedFilter.choices[key]}) })}
                            onClickHandler={this.handleClickMultipleChoice} values={this.state.selectedFilter.values || []} className={'multiple-choice-filter'}
                            title={this.state.selectedFilter.label} />
                {this.renderSelectedFilterOppositeBackground()}

        );
    }

    renderTagFilter() {
        return (

                {this.renderSelectedFilterBackground()}

                {/* TODO: tagSuggestions should be set from props instead of state */}
                <TagInput placeholder={'Escribe un tag'} tags={this.state.tagSuggestions}
                          onKeyUpHandler={this.handleKeyUpTag} onClickTagHandler={this.handleClickTagSuggestion}/>
                {this.renderSelectedFilterOppositeBackground()}

        );
    }

    handleClickMultipleChoice(choice) {
        let filters = this.state.filters;
        let filter = this.state.selectedFilter;
        let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
        filter.values = filter.values || [];
        if (index > -1) {
            if (!filter.values.some(value => value === choice)) {
                filter.values.push(choice);
            } else {
                filter.values.splice(choice, 1);
            }
            filters[index] = filter;
        } else {
            filter.values.push(choice);
            filters.push(filter);
        }

        this.setState({
            filters: filters,
            selectedFilter: filter
        });
    }

    handleKeyUpTag(tag = '') {
        if (tag.length > 2) {
            // TODO: Call get tags action and save in store
            // TODO: Replace this example setting the tagSuggestions in getState method as props
            console.log(tag);
            this.setState({
                tagSuggestions: [tag + '1', tag + '2', tag + '3']
            });
            /*window.setTimeout(function () {
             document.getElementsByClassName('view')[0].scrollTop = document.getElementsByClassName('view')[0].scrollHeight;
             }, 500);*/
        } else {
            this.setState({
                tagSuggestions: []
            });
        }
    }

    handleClickTagSuggestion(tagString) {
        let filters = this.state.filters;
        let filter = this.state.selectedFilter;
        let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
        filter.values = filter.values || [];
        if (index > -1) {
            if (!filter.values.some(value => value === tagString)) {
                filter.values.push(tagString);
                filters[index] = filter;
            }
        } else {
            filter.values.push(tagString);
            filters.push(filter);
        }

        this.setState({
            filters: filters,
            selectedFilter: {},
            tagSuggestions: []
        });
    }

    renderSelectedFilterBackground() {
        return (

        );
    }

    handleClickRemoveFilter() {
        let filters = this.state.filters;
        let filter = this.state.selectedFilter;
        let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
        if (index !== -1) {
            filters.splice(index, 1);
        }
        this.setState({
            filters: filters,
            selectedFilter: {}
        })
    }

    renderSelectedFilterOppositeBackground = function() {
        return (

        );
    };

    handleClickFilter(key) {
        let filters = this.state.filters;
        let filter = filters.find(filter => filter.key === key);

        this.setState({
            selectedFilter: filter
        });
    }

    createThread() {
        let data = {
            name: document.querySelector('.list-block input').value,
            filters: {},
            category: 'ThreadContent'
        };

        if (this.state.filters.length > 0){
            data.filters = this.state.filters;
        }

        UserActionCreators.createThread(this.props.userId, data);
    }
}
<commit_msg>QS-964: Create ThreadContent<commit_after>import React, { PropTypes, Component } from 'react';
import * as UserActionCreators from '../../actions/UserActionCreators';
import TextInput from '../ui/TextInput';
import TextRadios from '../ui/TextRadios';
import TextCheckboxes from '../ui/TextCheckboxes';
import InputCheckbox from '../ui/InputCheckbox';
import TagInput from '../ui/TagInput';
import FullWidthButton from '../ui/FullWidthButton';

export default class CreateContentThread extends Component {
    static propTypes = {
        userId: PropTypes.number.isRequired,
        filters: PropTypes.object.isRequired
        // TODO: tagSuggestions should be a prop
    };

    constructor(props) {
        super(props);

        this.handleClickAddFilter = this.handleClickAddFilter.bind(this);
        this.renderFiltersList = this.renderFiltersList.bind(this);
        this.handleClickFilterOnList = this.handleClickFilterOnList.bind(this);
        this.renderActiveFilters = this.renderActiveFilters.bind(this);
        this.renderMultipleChoicesFilter = this.renderMultipleChoicesFilter.bind(this);
        this.renderTagFilter = this.renderTagFilter.bind(this);
        this.handleClickMultipleChoice = this.handleClickMultipleChoice.bind(this);
        this.handleKeyUpTag = this.handleKeyUpTag.bind(this);
        this.handleClickTagSuggestion = this.handleClickTagSuggestion.bind(this);
        this.handleClickFilter = this.handleClickFilter.bind(this);
        this.handleClickRemoveFilter = this.handleClickRemoveFilter.bind(this);
        this.createThread = this.createThread.bind(this);

        this.state = {
            selectFilter: false,
            selectedFilter: {},
            filters: [],
            tagSuggestions: []
        }
    }

    render() {
        Object.keys(this.props.filters).forEach(key => this.props.filters[key].key = key);
        let content = '';
        if (this.state.selectFilter) {
            content =

Selecciona un filtro

                {this.renderFiltersList()}

;
        } else {
            content =

                {this.renderActiveFilters()}

                            Añadir filtro

                <FullWidthButton onClick={this.createThread}>Crear hilo</FullWidthButton>

;
        }

        return (
            content
        );
    }

    handleClickAddFilter() {
        this.setState({
            selectFilter: true
        })
    }

    renderFiltersList() {
        return(

                    {Object.keys(this.props.filters).map((id) => {
                        let text = this.props.filters[id].label;
                        let checked = this.state.filters.some(filter => filter.key === this.props.filters[id].key);
                        return (

                                <InputCheckbox value={this.props.filters[id].key} name={this.props.filters[id].key} text={text}
                                               checked={checked} defaultChecked={false} onClickHandler={this.handleClickFilterOnList} reverse={true}/>

                        )
                    })}

        );
    }

    handleClickFilterOnList(checked, value) {
        let filters = this.state.filters;
        let filter = this.state.filters.find(key => key === value);
        if (typeof filter == 'undefined') {
            let defaultFilters = JSON.parse(JSON.stringify(this.props.filters));
            filter = Object.keys(defaultFilters).map(key => defaultFilters[key]).find(function (defaultFilter) {
                return defaultFilter.key === value;
            });
        }
        if (checked) {
            this.setState({
                selectFilter: false,
                selectedFilter: filter
            });
        } else {
            let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
            filters.splice(index, 1);
            this.setState({
                filters: filters,
                selectedFilter: {}
            });
        }
    }

    renderActiveFilters() {
        let filters = this.state.filters || [];
        let selectedFilterContent = '';
        if (this.state.selectedFilter.key) {
            let isSelectedFilterActive = filters.some(filter => filter.key === this.state.selectedFilter.key);
            if (!isSelectedFilterActive) {
                filters.push(this.state.selectedFilter);
            }
            switch (this.state.selectedFilter.type) {
                case 'multiple_choices':
                    selectedFilterContent = this.renderMultipleChoicesFilter();
                    break;
                case 'tags':
                    selectedFilterContent = this.renderTagFilter();
                    break;
            }
        }
        let multipleChoicesFilter = filters.filter(filter => filter.type === 'multiple_choices');
        let tagsFilter = filters.filter(filter => filter.type === 'tags');
        let filterCheckboxes = [];

        if (multipleChoicesFilter) {
            multipleChoicesFilter.forEach(filter => {
                let values = filter.values || [];
                let textArray = values.map(value => filter.choices[value]);
                let text = textArray.length > 0 ? filter.label + ' - ' + textArray.join(', ') : filter.label;
                filterCheckboxes.push({
                    label: {key: filter.key, text: text},
                    value: filter.key,
                    selected: this.state.selectedFilter && this.state.selectedFilter.key === filter.key
                });
            });
        }
        if (tagsFilter) {
            tagsFilter.forEach(filter => {
                let tags = filter.values;
                let text = tags && tags.length > 0 ? filter.label + ' - ' + tags.join(', ') : filter.label;
                filterCheckboxes.push({
                    label: {key: filter.key, text: text},
                    value: filter.key,
                    selected: this.state.selectedFilter && this.state.selectedFilter.key === filter.key
                });
            });
        }

        return (
            filterCheckboxes.map((filterCheckbox, index) =>
                filterCheckbox.selected ?
                    selectedFilterContent :

                        <TextCheckboxes labels={[filterCheckbox.label]} onClickHandler={this.handleClickFilter.bind(this, filterCheckbox.label.key)}
                                        values={filters.map(filter => {return filter.value || filter.choice || filter.values && filter.values.length > 0 ? filter.key : null})} />

            )
        );
    }

    renderMultipleChoicesFilter() {
        return (

                {this.renderSelectedFilterBackground()}

                     0 ? "icon-circle active" : "icon-circle"}>

                <TextCheckboxes labels={Object.keys(this.state.selectedFilter.choices).map(key => { return({key: key, text: this.state.selectedFilter.choices[key]}) })}
                            onClickHandler={this.handleClickMultipleChoice} values={this.state.selectedFilter.values || []} className={'multiple-choice-filter'}
                            title={this.state.selectedFilter.label} />
                {this.renderSelectedFilterOppositeBackground()}

        );
    }

    renderTagFilter() {
        return (

                {this.renderSelectedFilterBackground()}

                {/* TODO: tagSuggestions should be set from props instead of state */}
                <TagInput placeholder={'Escribe un tag'} tags={this.state.tagSuggestions}
                          onKeyUpHandler={this.handleKeyUpTag} onClickTagHandler={this.handleClickTagSuggestion}/>
                {this.renderSelectedFilterOppositeBackground()}

        );
    }

    handleClickMultipleChoice(choice) {
        let filters = this.state.filters;
        let filter = this.state.selectedFilter;
        let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
        filter.values = filter.values || [];
        if (index > -1) {
            if (!filter.values.some(value => value === choice)) {
                filter.values.push(choice);
            } else {
                filter.values.splice(choice, 1);
            }
            filters[index] = filter;
        } else {
            filter.values.push(choice);
            filters.push(filter);
        }

        this.setState({
            filters: filters,
            selectedFilter: filter
        });
    }

    handleKeyUpTag(tag = '') {
        if (tag.length > 2) {
            // TODO: Call get tags action and save in store
            // TODO: Replace this example setting the tagSuggestions in getState method as props
            console.log(tag);
            this.setState({
                tagSuggestions: [tag + '1', tag + '2', tag + '3']
            });
            /*window.setTimeout(function () {
             document.getElementsByClassName('view')[0].scrollTop = document.getElementsByClassName('view')[0].scrollHeight;
             }, 500);*/
        } else {
            this.setState({
                tagSuggestions: []
            });
        }
    }

    handleClickTagSuggestion(tagString) {
        let filters = this.state.filters;
        let filter = this.state.selectedFilter;
        let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
        filter.values = filter.values || [];
        if (index > -1) {
            if (!filter.values.some(value => value === tagString)) {
                filter.values.push(tagString);
                filters[index] = filter;
            }
        } else {
            filter.values.push(tagString);
            filters.push(filter);
        }

        this.setState({
            filters: filters,
            selectedFilter: {},
            tagSuggestions: []
        });
    }

    renderSelectedFilterBackground() {
        return (

        );
    }

    handleClickRemoveFilter() {
        let filters = this.state.filters;
        let filter = this.state.selectedFilter;
        let index = filters.findIndex(savedFilter => savedFilter.key === filter.key);
        if (index !== -1) {
            filters.splice(index, 1);
        }
        this.setState({
            filters: filters,
            selectedFilter: {}
        })
    }

    renderSelectedFilterOppositeBackground = function() {
        return (

        );
    };

    handleClickFilter(key) {
        let filters = this.state.filters;
        let filter = filters.find(filter => filter.key === key);

        this.setState({
            selectedFilter: filter
        });
    }

    createThread() {
        let data = {
            name: document.querySelector('.list-block input').value,
            filters: {},
            category: 'ThreadContent'
        };

        let stateFilters = this.state.filters;

        for (let stateFilter of stateFilters) {
            switch (stateFilter.type) {
                case 'choice':
                    data.filters[stateFilter.key] = stateFilter.choice;
                    break;
                case 'location':
                    data.filters[stateFilter.key] = {};
                    data.filters[stateFilter.key]['location'] = stateFilter.value;
                    data.filters[stateFilter.key]['distance'] = 50;
                    break;
                case 'tags':
                    data.filters['tag'] = stateFilter.values[0];
                    break;
                case 'double_choice':
                    data.filters[stateFilter.key] = {};
                    data.filters[stateFilter.key]['choice'] = stateFilter.choice;
                    data.filters[stateFilter.key]['detail'] = stateFilter.detail;
                    break;
                case 'multiple_choices':
                    data.filters[stateFilter.key] = stateFilter.values;
                    break;
                default:
                    break;
            }
        }

        UserActionCreators.createThread(this.props.userId, data);
    }
}
<|endoftext|>


<commit_before><commit_msg>Minor update to swarm overlay network settings<commit_after><|endoftext|>


<commit_before>/* Synchronous file helpers */

var grunt = require("grunt"),
    fs = require("fs"),
    extend = require('whet.extend');

module.exports = (function(_, fs, grunt, extend) {
  return _({}).tap(function(exports) {
    exports.copy = function(src, dest) {
      var file = fs.lstatSync(src);

      if(file.isDirectory()) {
        exports.copyDir(src, dest);
      } else {
        grunt.file.copy(src, dest);
        // grunt.log.writeln("Copied image '"+src+"' to '"+dest+"'");
      }
    };

    exports.copyDir = function(src, dest) {
      mkdirIfNecessary(src, dest);

      var paths = fs.readdirSync(src);
      _(paths).each(function(path) {
        exports.copy(src+"/"+path, dest+"/"+path);
      });
    };

    exports.overwritePackageJson = function(src, name) {
      var linemanPackageJson = grunt.file.readJSON(__dirname + "/../package.json"),
          newPackageJson = _(grunt.file.read(src)).template({
            name: _(name).dasherize(),
            versions: {
              lineman: linemanPackageJson["version"],
              grunt: linemanPackageJson["dependencies"]["grunt"],
              gruntContrib: linemanPackageJson["dependencies"]["grunt-contrib"]
            }
          });
      grunt.file.write(src, newPackageJson);
    };

    var mkdirIfNecessary = function(src, dest) {
      var checkDir = fs.statSync(src);
      try {
        fs.mkdirSync(dest, checkDir.mode);
      } catch (e) {
        if (e.code !== 'EEXIST') {
          throw e;
        }
      }
    };
  });
})(grunt.utils._, fs, grunt, extend);<commit_msg>oops, i no need.<commit_after>/* Synchronous file helpers */

var grunt = require("grunt"),
    fs = require("fs");

module.exports = (function(_, fs, grunt) {
  return _({}).tap(function(exports) {
    exports.copy = function(src, dest) {
      var file = fs.lstatSync(src);

      if(file.isDirectory()) {
        exports.copyDir(src, dest);
      } else {
        grunt.file.copy(src, dest);
        // grunt.log.writeln("Copied image '"+src+"' to '"+dest+"'");
      }
    };

    exports.copyDir = function(src, dest) {
      mkdirIfNecessary(src, dest);

      var paths = fs.readdirSync(src);
      _(paths).each(function(path) {
        exports.copy(src+"/"+path, dest+"/"+path);
      });
    };

    exports.overwritePackageJson = function(src, name) {
      var linemanPackageJson = grunt.file.readJSON(__dirname + "/../package.json"),
          newPackageJson = _(grunt.file.read(src)).template({
            name: _(name).dasherize(),
            versions: {
              lineman: linemanPackageJson["version"],
              grunt: linemanPackageJson["dependencies"]["grunt"],
              gruntContrib: linemanPackageJson["dependencies"]["grunt-contrib"]
            }
          });
      grunt.file.write(src, newPackageJson);
    };

    var mkdirIfNecessary = function(src, dest) {
      var checkDir = fs.statSync(src);
      try {
        fs.mkdirSync(dest, checkDir.mode);
      } catch (e) {
        if (e.code !== 'EEXIST') {
          throw e;
        }
      }
    };
  });
})(grunt.utils._, fs, grunt);<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const fs = require('fs');
const http = require('http');

const env = require('../modules/environment');

describe('application', function() {
  this.timeout(10000);

  const serverPort = 8181;
  const testURL = `http://localhost:${serverPort}`

  const config = {
    version: 1,
    teams: [{
      name: 'example_1',
      url: testURL
    }, {
      name: 'example_2',
      url: testURL
    }]
  };

  before(function() {
    this.server = http.createServer(function(req, res) {
      res.writeHead(200, {
        'Content-Type': 'text/html'
      });
      res.end(fs.readFileSync(path.resolve(env.sourceRootDir, 'test/modules/test.html'), 'utf-8'));
    }).listen(serverPort, '127.0.0.1');
  });

  beforeEach(function() {
    fs.writeFileSync(env.configFilePath, JSON.stringify(config));
    this.app = env.getSpectronApp();
    return this.app.start();
  });

  afterEach(function() {
    if (this.app && this.app.isRunning()) {
      return this.app.stop()
    }
  });

  after(function(done) {
    this.server.close(done);
  })

  it('should NOT be able to call Node.js API in webview', function() {
    env.addClientCommands(this.app.client);
    return this.app.client
      .getAttribute('webview', 'nodeintegration').then((nodeintegration) => {
        // nodeintegration is an array of string
        nodeintegration.forEach((n) => {
          n.should.equal('false');
        });
      })
      // webview is handled as a window by chromedriver.
      .windowByIndex(1).isNodeEnabled().should.eventually.be.false
      .windowByIndex(2).isNodeEnabled().should.eventually.be.false;
  });

  it('should NOT be able to call Node.js API in a new window', function() {
    env.addClientCommands(this.app.client);
    const client = this.app.client;
    return this.app.client
      .execute(function() {
        const webview = document.querySelector('webview');
        webview.executeJavaScript('open_window();');
      })
      .waitUntil(function async() {
        return client.windowHandles().then((handles) => {
          return handles.value.length === 4;
        });
      }, 5000, 'expected a new window')
      .windowByIndex(3).isNodeEnabled().should.eventually.be.false;
  })
});
<commit_msg>Execute testing js code directly with webdriverio API<commit_after>'use strict';

const path = require('path');
const fs = require('fs');
const http = require('http');

const env = require('../modules/environment');

describe('application', function() {
  this.timeout(10000);

  const serverPort = 8181;
  const testURL = `http://localhost:${serverPort}`

  const config = {
    version: 1,
    teams: [{
      name: 'example_1',
      url: testURL
    }, {
      name: 'example_2',
      url: testURL
    }]
  };

  before(function() {
    this.server = http.createServer(function(req, res) {
      res.writeHead(200, {
        'Content-Type': 'text/html'
      });
      res.end(fs.readFileSync(path.resolve(env.sourceRootDir, 'test/modules/test.html'), 'utf-8'));
    }).listen(serverPort, '127.0.0.1');
  });

  beforeEach(function() {
    fs.writeFileSync(env.configFilePath, JSON.stringify(config));
    this.app = env.getSpectronApp();
    return this.app.start();
  });

  afterEach(function() {
    if (this.app && this.app.isRunning()) {
      return this.app.stop()
    }
  });

  after(function(done) {
    this.server.close(done);
  })

  it('should NOT be able to call Node.js API in webview', function() {
    env.addClientCommands(this.app.client);
    return this.app.client
      .getAttribute('webview', 'nodeintegration').then((nodeintegration) => {
        // nodeintegration is an array of string
        nodeintegration.forEach((n) => {
          n.should.equal('false');
        });
      })
      // webview is handled as a window by chromedriver.
      .windowByIndex(1).isNodeEnabled().should.eventually.be.false
      .windowByIndex(2).isNodeEnabled().should.eventually.be.false;
  });

  it('should NOT be able to call Node.js API in a new window', function() {
    env.addClientCommands(this.app.client);
    const client = this.app.client;
    return this.app.client
      .windowByIndex(1) // in the first webview
      .execute(function() {
        open_window();
      })
      .waitUntil(function async() {
        return client.windowHandles().then((handles) => {
          return handles.value.length === 4;
        });
      }, 5000, 'expected a new window')
      .windowByIndex(3).isNodeEnabled().should.eventually.be.false;
  })
});
<|endoftext|>


<commit_before>var Base = require('./base');
var Util = require('../controllers/util');

/**
 * Expose `User` Model
 */
module.exports = User;

/**
 * User model constructor.
 * @param {express.app} app Express App instance.
 * @param {Object=} opt_resource Optional resource.
 * @constructor
 * @extends {app.models.base}
 */
function User(app, opt_resource) {
  this.app = app;
  this.resource = opt_resource || null;
  this.db = app.db;
  Base.call(this);
}
require('util').inherits(User, Base);

/**
 * Table name.
 * @const
 * @private {string}
 */
User.TABLE_ = 'user';

/**
 * Columns to retrieve in SELECT statements.
 * @const
 * @private {Array.<string>}
 */
User.SELECT_COLUMNS_ = [
  'user.id',
  'user.displayName',
  'user.slug',
  'user.email',
  'user.created',
  'user.updated'
];

/**
 * MySQL Query Strings.
 * @enum {string}
 * @private
 */
User.QUERIES_ = {
  find: 'SELECT ?? FROM `' + User.TABLE_ + '` WHERE ?',
  findOne: 'SELECT ?? FROM `' + User.TABLE_ + '` WHERE ? LIMIT 1',
  insert: 'INSERT INTO `' + User.TABLE_ + '` SET ?'
};

/**
 * Table strucure. Describes field types and validation properties.
 * Note: Fields that will get generated (i.e. date, markdown formatted content)
 *   should NOT be required - they will always fail validation if they are.
 * @enum {Object.<string, string>}
 * @private
 */
User.STRUCTURE_ = {
  id: {type: 'Number'},
  displayName: {type: 'String', length: 100, required: true},
  slug: {type: 'String', length: 100},
  email: {type: 'String', length: 100, required: true},
  google_id: {type: 'String', length: 100},
  facebook_id: {type: 'Number', length: 100},
  twitter: {type: 'String', length: 100},
  created: {type: 'Number'},
  updated: {type: 'Number'}
};

/**
 * Gets the named query, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
User.prototype.getQuery = function(action) {
  if (action) {
    return User.QUERIES_[action];
  } else {
    return User.QUERIES_;
  }
};

/**
 * Gets the columns to be displayed in a result, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
User.prototype.getColumns = function(action) {
  return User.SELECT_COLUMNS_;
};

/**
 * Gets the current model's structure.
 * @return {Object} structure object.
 */
User.prototype.getStructure = function() {
  return User.STRUCTURE_;
};

/**
 * Gets the table name for the current model.
 * @return {string} table name.
 */
User.prototype.getTable = function() {
  return User.TABLE_;
};

/**
 * Add / Modify fields that are not populated by the form, and that need to be
 * generated.
 * @return {Object.<string, string>} The updated User resource.
 */
User.prototype.prepare = function() {
  var resource = this.resource;
  var date = Util.getDate();
  // TODO: 'created' shouldn't update on edit, only on insert.
  resource.created = date;
  resource.updated = date;
  resource.slug = Util.convertToSlug(resource.displayName);
  return resource;
};
<commit_msg>Added `update` and `remove` queries to the User model.<commit_after>var Base = require('./base');
var Util = require('../controllers/util');

/**
 * Expose `User` Model
 */
module.exports = User;

/**
 * User model constructor.
 * @param {express.app} app Express App instance.
 * @param {Object=} opt_resource Optional resource.
 * @constructor
 * @extends {app.models.base}
 */
function User(app, opt_resource) {
  this.app = app;
  this.resource = opt_resource || null;
  this.db = app.db;
  Base.call(this);
}
require('util').inherits(User, Base);

/**
 * Table name.
 * @const
 * @private {string}
 */
User.TABLE_ = 'user';

/**
 * Columns to retrieve in SELECT statements.
 * @const
 * @private {Array.<string>}
 */
User.SELECT_COLUMNS_ = [
  'user.id',
  'user.displayName',
  'user.slug',
  'user.email',
  'user.created',
  'user.updated'
];

/**
 * MySQL Query Strings.
 * @enum {string}
 * @private
 */
User.QUERIES_ = {
  find: 'SELECT ?? FROM `' + User.TABLE_ + '` WHERE ?',
  findOne: 'SELECT ?? FROM `' + User.TABLE_ + '` WHERE ? LIMIT 1',
  insert: 'INSERT INTO `' + User.TABLE_ + '` SET ?',
  update: 'UPDATE `' + User.TABLE_ + '` SET ? WHERE ?',
  remove: 'DELETE FROM `' + User.TABLE_ + '` WHERE ? LIMIT 1'
};

/**
 * Table strucure. Describes field types and validation properties.
 * Note: Fields that will get generated (i.e. date, markdown formatted content)
 *   should NOT be required - they will always fail validation if they are.
 * @enum {Object.<string, string>}
 * @private
 */
User.STRUCTURE_ = {
  id: {type: 'Number'},
  displayName: {type: 'String', length: 100, required: true},
  slug: {type: 'String', length: 100},
  email: {type: 'String', length: 100, required: true},
  google_id: {type: 'String', length: 100},
  facebook_id: {type: 'Number', length: 100},
  twitter: {type: 'String', length: 100},
  created: {type: 'Number'},
  updated: {type: 'Number'}
};

/**
 * Gets the named query, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
User.prototype.getQuery = function(action) {
  if (action) {
    return User.QUERIES_[action];
  } else {
    return User.QUERIES_;
  }
};

/**
 * Gets the columns to be displayed in a result, or returns them all.
 * @param {?string} action Type of query to get/perform.
 * @return {string|Object} query or queries.
 */
User.prototype.getColumns = function(action) {
  return User.SELECT_COLUMNS_;
};

/**
 * Gets the current model's structure.
 * @return {Object} structure object.
 */
User.prototype.getStructure = function() {
  return User.STRUCTURE_;
};

/**
 * Gets the table name for the current model.
 * @return {string} table name.
 */
User.prototype.getTable = function() {
  return User.TABLE_;
};

/**
 * Add / Modify fields that are not populated by the form, and that need to be
 * generated.
 * @return {Object.<string, string>} The updated User resource.
 */
User.prototype.prepare = function() {
  var resource = this.resource;
  var date = Util.getDate();
  // TODO: 'created' shouldn't update on edit, only on insert.
  resource.created = date;
  resource.updated = date;
  resource.slug = Util.convertToSlug(resource.displayName);
  return resource;
};
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';

export default class Switch extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      offset: null,
      skipAnimation: true,
      dragStart: false,
      focus: false,
      value: props.value != undefined ? props.value : props.defaultValue,
      labelWidth: props.labelWidth,
      handleWidth: props.handleWidth
    };
  }

  componentDidMount() {
    this._recalculateWidth();
  }

  componentWillReceiveProps(nextProps){
    const newValue = nextProps.value !== undefined ? nextProps.value : this.state.value;

    // ensure width is updated
    this.setState({
      labelWidth: nextProps.labelWidth,
      handleWidth: nextProps.handleWidth,
      value: newValue
    }, () => {
      this._recalculateWidth(nextProps.value !== undefined);
    });
  }

  _getValue(){
    if(this.props.value !== undefined)
      return this.props.value;

    return this.state.value;
  }

  value(val){
    if(val === undefined)
      return this.state.value;

    this._setValue(val === null ? null : !!val);
  }

  _wrapperClasses(){
    const {
      baseClass,
      wrapperClass,
      bsSize,
      disabled,
      readonly,
      inverse,
      animate,
      id
    } = this.props;

    const {
      skipAnimation,
      focus,
      dragStart,
    } = this.state;

    const value = this._getValue();

    const classes = [ baseClass, wrapperClass ];
    classes.push(baseClass + (value ? "-on" : "-off"));

    if (bsSize)
      classes.push(baseClass + "-" + bsSize);

    if (disabled)
      classes.push(baseClass + "-disabled");

    if (readonly)
      classes.push(baseClass + "-readonly");

    if (value === null)
      classes.push(baseClass + "-indeterminate");

    if (inverse)
      classes.push(baseClass + "-inverse");

    if (id)
      classes.push(baseClass + "-" + id);

    if (animate && !dragStart & !skipAnimation)
      classes.push(baseClass + "-animate");

    if (focus)
      classes.push(baseClass + "-focused");

    return classes.join(" ");
  }

  _recalculateWidth(animate){
    const onHandle = ReactDOM.findDOMNode(this.elmOnHandle);
    const offHandle = ReactDOM.findDOMNode(this.elmOffHandle);
    const label = ReactDOM.findDOMNode(this.elmLabel);

    // assuming that if the elms need to be resized, the size will be cleared elsewhere first
    const { handleWidth, labelWidth } = this.props;
    const newHandleWidth = handleWidth == "auto"
      ? Math.max(onHandle.offsetWidth, offHandle.offsetWidth)
      : handleWidth;

    const newLabelWidth = labelWidth == "auto"
      ? Math.max(newHandleWidth, label.offsetWidth)
      : labelWidth;

    return this.setState({
      handleWidth: newHandleWidth,
      labelWidth: newLabelWidth
    }, () => {
      this._updateContainerPosition(!animate);
    });
  }

  _updateContainerPosition(noAnimate){
    const { handleWidth, offset } = this.state;
    const { inverse } = this.props;
    const value = this._getValue();

    // skip animating if no offset yet
    const skipAnimation = noAnimate || (offset == null)

    let newOffset = offset;

    if (value === null) {
      newOffset = -(handleWidth / 2);
    } else if (value) {
      newOffset = inverse ? -handleWidth : 0;
    } else {
      newOffset = inverse ? 0 : -handleWidth;
    }

    return this.setState({
      skipAnimation: skipAnimation,
      offset: newOffset
    });
  }

  _disableUserInput(){
    const { disabled, readonly } = this.props;

    return disabled || readonly;
  }

  _handleOnClick(){
    if(this._disableUserInput())
      return;

    this._setValue(false)
    this._setFocus();
  }

  _handleOffClick(){
    if(this._disableUserInput())
      return;

    this._setValue(true)
    this._setFocus();
  }

  _handleKeyPress(e){
    if(!e.which || this._disableUserInput())
      return;

    const { inverse } = this.props;

    switch(e.which){
      case 37:
        return this._setValue(inverse);

      case 39:
        return this._setValue(!inverse);
    }
  }

  _handleLabelMouseDown(e){
    if(this.state.dragStart || this._disableUserInput())
      return;

    this.setState({
      dragStart: (e.pageX || e.touches[0].pageX) - this.state.offset
    });
    this._setFocus();
  }

  _handleLabelMouseMove(e){
    const { dragStart, handleWidth } = this.state;

    if(dragStart === undefined || dragStart === null || dragStart === false)
      return;

    const difference = (e.pageX || e.touches[0].pageX) - dragStart;
    if(difference < -handleWidth || difference > 0)
      return;

    this.setState({
      skipAnimation: false,
      offset: difference,
      dragged: true
    });
  }

  _handleLabelMouseUp(){
    const { dragStart, dragged, offset, handleWidth } = this.state;
    const value = this._getValue();

    if(dragStart === undefined || dragStart === null || dragStart === false)
      return;

    const { inverse } = this.props;

    let val = !value;

    if(dragged){
      val = offset > -(handleWidth / 2);
      val = inverse ? !val : val;
    }

    this.setState({
      dragStart: false,
      dragged: false,
      value: val
    }, () => {
      this._updateContainerPosition();
      this._fireStateChange(val);
    });
  }

  _setFocus(){
    this.setState({
      focus: true
    });
  }

  _setBlur(){
    this.setState({
      focus: false
    });
  }

  _setValue(val){
    const value = this._getValue();
    if(val === value)
      return;

    const newValue = (val === undefined ? !value : val);

    this.setState({
      value: newValue
    }, () => {
      this._updateContainerPosition();
      this._fireStateChange(newValue);
    });
  }

  _fireStateChange(newValue){
    const { onChange } = this.props;
    if (typeof onChange != "function")
      return;

    setTimeout(() => onChange(this, newValue), 0);
  }

  render() {
    const { baseClass, inverse } = this.props;
    const { handleWidth, labelWidth, offset } = this.state;

    const onHandle = this._renderOnHandle();
    const offHandle = this._renderOffHandle();

    let containerWidth = labelWidth + (handleWidth * 2);
    let wrapperWidth = labelWidth + handleWidth;
    if(containerWidth == wrapperWidth)
      containerWidth = wrapperWidth = "auto";

    const wrapperParams = {
      className:  this._wrapperClasses(),
      style:      { width: wrapperWidth },
      tabIndex:   "0",
      onKeyDown:  this._handleKeyPress.bind(this),
      onFocus:    this._setFocus.bind(this),
      onBlur:     this._setBlur.bind(this)
    };

    const containerParams = {
      className:  `${baseClass}-container`,
      style:      { width: containerWidth, marginLeft: offset }
    };

    return (

          { inverse ? offHandle : onHandle}
          { this._renderLabel() }
          { inverse ? onHandle : offHandle}

    );
  }

  _renderOnHandle(){
    const { baseClass, onColor, onText } = this.props;
    const { handleWidth } = this.state;

    const params = {
      ref:        e => this.elmOnHandle = e,
      style:      { width: handleWidth },
      className:  `${baseClass}-handle-on ${baseClass}-${onColor}`,
      onClick:    this._handleOnClick.bind(this)
    };

    return { onText };
  }

  _renderOffHandle(){
    const { baseClass, offColor, offText } = this.props;
    const { handleWidth } = this.state;

    const params = {
      ref:        e => this.elmOffHandle = e,
      style:      { width: handleWidth },
      className:  `${baseClass}-handle-on ${baseClass}-${offColor}`,
      onClick:    this._handleOffClick.bind(this)
    };

    return { offText };
  }

  _renderLabel(){
    const { baseClass, labelText } = this.props;
    const { labelWidth } = this.state;

    const params = {
      ref:          e => this.elmLabel = e,
      style:        { width: labelWidth },
      className:    `${baseClass}-label`,

      onTouchStart: this._handleLabelMouseDown.bind(this),
      onTouchMove:  this._handleLabelMouseMove.bind(this),
      onTouchEnd:   this._handleLabelMouseUp.bind(this),

      onMouseDown:  this._handleLabelMouseDown.bind(this),
      onMouseMove:  this._handleLabelMouseMove.bind(this),
      onMouseUp:    this._handleLabelMouseUp.bind(this),
      onMouseLeave: this._handleLabelMouseUp.bind(this)
    };

    return {labelText};
  }
}

Switch.defaultProps = {
  baseClass:      'bootstrap-switch',
  wrapperClass:   'wrapper',
  bsSize:         null,

  handleWidth:    'auto',
  labelWidth:     'auto',

  onColor:        'primary',
  offColor:       'default',

  onText:         'ON',
  offText:        'OFF',
  labelText:      ' ',

  inverse:        false,
  animate:        true,

  disabled:       false,
  readonly:       false,

  defaultValue:   true,
  value:          undefined
};

Switch.propTypes = {
  baseClass:      React.PropTypes.string,
  wrapperClass:   React.PropTypes.string,
  bsSize:         React.PropTypes.string,

  handleWidth:    React.PropTypes.oneOfType([
                    React.PropTypes.string,
                    React.PropTypes.number
                  ]),
  labelWidth:     React.PropTypes.oneOfType([
                    React.PropTypes.string,
                    React.PropTypes.number
                  ]),

  onColor:        React.PropTypes.string,
  offColor:       React.PropTypes.string,

  onText:         React.PropTypes.string,
  offText:        React.PropTypes.string,
  labelText:      React.PropTypes.string,

  inverse:        React.PropTypes.bool,
  animate:        React.PropTypes.bool,

  disabled:       React.PropTypes.bool,
  readonly:       React.PropTypes.bool,

  defaultValue:   React.PropTypes.bool,
  value:          React.PropTypes.bool,
  onChange:       React.PropTypes.func,
};
<commit_msg>Added a 'tristate' parameter which allows the user to cycle the value through null, on and off.<commit_after>import React from 'react';
import ReactDOM from 'react-dom';

export default class Switch extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      offset: null,
      skipAnimation: true,
      dragStart: false,
      focus: false,
      value: props.value != undefined ? props.value : props.defaultValue,
      labelWidth: props.labelWidth,
      handleWidth: props.handleWidth
    };
  }

  componentDidMount() {
    this._recalculateWidth();
  }

  componentWillReceiveProps(nextProps){
    const newValue = nextProps.value !== undefined ? nextProps.value : this.state.value;

    // ensure width is updated
    this.setState({
      labelWidth: nextProps.labelWidth,
      handleWidth: nextProps.handleWidth,
      value: newValue
    }, () => {
      this._recalculateWidth(nextProps.value !== undefined);
    });
  }

  _getValue(){
    if(this.props.value !== undefined)
      return this.props.value;

    return this.state.value;
  }

  value(val){
    if(val === undefined)
      return this.state.value;

    this._setValue(val === null ? null : !!val);
  }

  _wrapperClasses(){
    const {
      baseClass,
      wrapperClass,
      bsSize,
      disabled,
      readonly,
      inverse,
      tristate,
      animate,
      id
    } = this.props;

    const {
      skipAnimation,
      focus,
      dragStart,
    } = this.state;

    const value = this._getValue();

    const classes = [ baseClass, wrapperClass ];
    classes.push(baseClass + (value ? "-on" : "-off"));

    if (bsSize)
      classes.push(baseClass + "-" + bsSize);

    if (disabled)
      classes.push(baseClass + "-disabled");

    if (readonly)
      classes.push(baseClass + "-readonly");

    if (value === null)
      classes.push(baseClass + "-indeterminate");

    if (inverse)
        classes.push(baseClass + "-inverse");

    if (tristate)
        classes.push(baseClass + "-tristate");

    if (id)
      classes.push(baseClass + "-" + id);

    if (animate && !dragStart & !skipAnimation)
      classes.push(baseClass + "-animate");

    if (focus)
      classes.push(baseClass + "-focused");

    return classes.join(" ");
  }

  _recalculateWidth(animate){
    const onHandle = ReactDOM.findDOMNode(this.elmOnHandle);
    const offHandle = ReactDOM.findDOMNode(this.elmOffHandle);
    const label = ReactDOM.findDOMNode(this.elmLabel);

    // assuming that if the elms need to be resized, the size will be cleared elsewhere first
    const { handleWidth, labelWidth } = this.props;
    const newHandleWidth = handleWidth == "auto"
      ? Math.max(onHandle.offsetWidth, offHandle.offsetWidth)
      : handleWidth;

    const newLabelWidth = labelWidth == "auto"
      ? Math.max(newHandleWidth, label.offsetWidth)
      : labelWidth;

    return this.setState({
      handleWidth: newHandleWidth,
      labelWidth: newLabelWidth
    }, () => {
      this._updateContainerPosition(!animate);
    });
  }

  _updateContainerPosition(noAnimate){
    const { handleWidth, offset } = this.state;
    const { inverse } = this.props;
    const value = this._getValue();

    // skip animating if no offset yet
    const skipAnimation = noAnimate || (offset == null)

    let newOffset = offset;

    if (value === null) {
      newOffset = -(handleWidth / 2);
    } else if (value) {
      newOffset = inverse ? -handleWidth : 0;
    } else {
      newOffset = inverse ? 0 : -handleWidth;
    }

    return this.setState({
      skipAnimation: skipAnimation,
      offset: newOffset
    });
  }

  _disableUserInput(){
    const { disabled, readonly } = this.props;

    return disabled || readonly;
  }

  _handleOnClick(){
    if(this._disableUserInput())
      return;

    this._setValue(false)
    this._setFocus();
  }

  _handleOffClick(){
    if(this._disableUserInput())
      return;

    this._setValue(true)
    this._setFocus();
  }

  _handleKeyPress(e){
    if(!e.which || this._disableUserInput())
      return;

    const { inverse } = this.props;

    switch(e.which){
      case 37:
        return this._setValue(inverse);

      case 39:
        return this._setValue(!inverse);
    }
  }

  _handleLabelMouseDown(e){
    if(this.state.dragStart || this._disableUserInput())
      return;

    this.setState({
      dragStart: (e.pageX || e.touches[0].pageX) - this.state.offset
    });
    this._setFocus();
  }

  _handleLabelMouseMove(e){
    const { dragStart, handleWidth } = this.state;

    if(dragStart === undefined || dragStart === null || dragStart === false)
      return;

    const difference = (e.pageX || e.touches[0].pageX) - dragStart;
    if(difference < -handleWidth || difference > 0)
      return;

    this.setState({
      skipAnimation: false,
      offset: difference,
      dragged: true
    });
  }

  _handleLabelMouseUp(){
    const { dragStart, dragged, offset, handleWidth } = this.state;
    const value = this._getValue();

    if(dragStart === undefined || dragStart === null || dragStart === false)
      return;

    const { inverse, tristate } = this.props;

    let val;

    if(dragged){
    	val = offset > -(handleWidth / 2);
    	val = inverse ? !val : val;
    } else if (tristate) {
    	val = value===null?true:(value?false:null);
    } else {
    	val = !value;
    }

    this.setState({
      dragStart: false,
      dragged: false,
      value: val
    }, () => {
      this._updateContainerPosition();
      this._fireStateChange(val);
    });
  }

  _setFocus(){
    this.setState({
      focus: true
    });
  }

  _setBlur(){
    this.setState({
      focus: false
    });
  }

  _setValue(val){
    const value = this._getValue();
    if(val === value)
      return;

    const newValue = (val === undefined ? !value : val);

    this.setState({
      value: newValue
    }, () => {
      this._updateContainerPosition();
      this._fireStateChange(newValue);
    });
  }

  _fireStateChange(newValue){
    const { onChange } = this.props;
    if (typeof onChange != "function")
      return;

    setTimeout(() => onChange(this, newValue), 0);
  }

  render() {
    const { baseClass, inverse } = this.props;
    const { handleWidth, labelWidth, offset } = this.state;

    const onHandle = this._renderOnHandle();
    const offHandle = this._renderOffHandle();

    let containerWidth = labelWidth + (handleWidth * 2);
    let wrapperWidth = labelWidth + handleWidth;
    if(containerWidth == wrapperWidth)
      containerWidth = wrapperWidth = "auto";

    const wrapperParams = {
      className:  this._wrapperClasses(),
      style:      { width: wrapperWidth },
      tabIndex:   "0",
      onKeyDown:  this._handleKeyPress.bind(this),
      onFocus:    this._setFocus.bind(this),
      onBlur:     this._setBlur.bind(this)
    };

    const containerParams = {
      className:  `${baseClass}-container`,
      style:      { width: containerWidth, marginLeft: offset }
    };

    return (

          { inverse ? offHandle : onHandle}
          { this._renderLabel() }
          { inverse ? onHandle : offHandle}

    );
  }

  _renderOnHandle(){
    const { baseClass, onColor, onText } = this.props;
    const { handleWidth } = this.state;

    const params = {
      ref:        e => this.elmOnHandle = e,
      style:      { width: handleWidth },
      className:  `${baseClass}-handle-on ${baseClass}-${onColor}`,
      onClick:    this._handleOnClick.bind(this)
    };

    return { onText };
  }

  _renderOffHandle(){
    const { baseClass, offColor, offText } = this.props;
    const { handleWidth } = this.state;

    const params = {
      ref:        e => this.elmOffHandle = e,
      style:      { width: handleWidth },
      className:  `${baseClass}-handle-on ${baseClass}-${offColor}`,
      onClick:    this._handleOffClick.bind(this)
    };

    return { offText };
  }

  _renderLabel(){
    const { baseClass, labelText } = this.props;
    const { labelWidth } = this.state;

    const params = {
      ref:          e => this.elmLabel = e,
      style:        { width: labelWidth },
      className:    `${baseClass}-label`,

      onTouchStart: this._handleLabelMouseDown.bind(this),
      onTouchMove:  this._handleLabelMouseMove.bind(this),
      onTouchEnd:   this._handleLabelMouseUp.bind(this),

      onMouseDown:  this._handleLabelMouseDown.bind(this),
      onMouseMove:  this._handleLabelMouseMove.bind(this),
      onMouseUp:    this._handleLabelMouseUp.bind(this),
      onMouseLeave: this._handleLabelMouseUp.bind(this)
    };

    return {labelText};
  }
}

Switch.defaultProps = {
  baseClass:      'bootstrap-switch',
  wrapperClass:   'wrapper',
  bsSize:         null,

  handleWidth:    'auto',
  labelWidth:     'auto',

  onColor:        'primary',
  offColor:       'default',

  onText:         'ON',
  offText:        'OFF',
  labelText:      ' ',

  inverse:        false,
  animate:        true,

  disabled:       false,
  readonly:       false,

  tristate:		  false,
  defaultValue:   true,
  value:          undefined
};

Switch.propTypes = {
  baseClass:      React.PropTypes.string,
  wrapperClass:   React.PropTypes.string,
  bsSize:         React.PropTypes.string,

  handleWidth:    React.PropTypes.oneOfType([
                    React.PropTypes.string,
                    React.PropTypes.number
                  ]),
  labelWidth:     React.PropTypes.oneOfType([
                    React.PropTypes.string,
                    React.PropTypes.number
                  ]),

  onColor:        React.PropTypes.string,
  offColor:       React.PropTypes.string,

  onText:         React.PropTypes.string,
  offText:        React.PropTypes.string,
  labelText:      React.PropTypes.string,

  inverse:        React.PropTypes.bool,
  animate:        React.PropTypes.bool,

  disabled:       React.PropTypes.bool,
  readonly:       React.PropTypes.bool,

  tristate:       React.PropTypes.bool,
  defaultValue:   React.PropTypes.bool,
  value:          React.PropTypes.bool,
  onChange:       React.PropTypes.func,
};
<|endoftext|>


<commit_before>var page = require('webpage').create(),
    system = require('system'),
    args = require('system').args,
    address, isDebug, output, size;

/*phantom settings*/
phantom.cookiesEnabled = true;

//print out console logs on page level
page.onConsoleMessage = function (msg) {
    if (msg.indexOf("Unsafe JavaScript attempt to access frame with URL") > -1){
        return;
    }
    if(isDebug){
        console.log('CONSOLE: ' + msg);
    }
};

page.onAlert = function (msg) {
    //ignore alerts
    //console.log('ALERT: ' + msg);
};

//error tracing
page.onError = function(msg, trace) {
    var msgStack = ['ERROR: ' + msg];
    if (trace) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file||t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    console.error(msgStack.join('\n'));
    phantom.exit();
    return;
};

phantom.onError = function(msg, trace) {
    var msgStack = ['PHANTOM ERROR: ' + msg];
    if (trace) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file||t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    console.error(msgStack.join('\n'));
    phantom.exit();
};

if (system.args.length < 3 || system.args.length > 5) {
    console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
    console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
    phantom.exit(1);
} else {
    address = args[1];
    output = args[2];
    isDebug = args[5] === "true";
    /*render settings*/
    page.zoomFactor = 1;
    page.viewportSize = { width: 600, height: 600 };
    if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
        size = system.args[3].split('*');
        page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
                                           : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
    }
    if (system.args.length > 4) {
        page.zoomFactor = system.args[4];
    }
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
            phantom.exit();
        } else {
            window.setTimeout(function () {
                page.render(output);
                phantom.exit();
            }, 200);
        }
    });
}<commit_msg>don't exit on page errors<commit_after>var page = require('webpage').create(),
    system = require('system'),
    args = require('system').args,
    address, isDebug, output, size;

/*phantom settings*/
phantom.cookiesEnabled = true;

//print out console logs on page level
page.onConsoleMessage = function (msg) {
    if (msg.indexOf("Unsafe JavaScript attempt to access frame with URL") > -1){
        return;
    }
    if(isDebug){
        console.log('CONSOLE: ' + msg);
    }
};

page.onAlert = function (msg) {
    //ignore alerts
    //console.log('ALERT: ' + msg);
};

//error tracing
page.onError = function(msg, trace) {
    // Just log page errors
    var msgStack = ['ERROR: ' + msg];
    if (trace) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file||t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    console.error(msgStack.join('\n'));
    return;
};

phantom.onError = function(msg, trace) {
    var msgStack = ['PHANTOM ERROR: ' + msg];
    if (trace) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file||t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
        });
    }
    console.error(msgStack.join('\n'));
    phantom.exit();
};

if (system.args.length < 3 || system.args.length > 5) {
    console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
    console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
    phantom.exit(1);
} else {
    address = args[1];
    output = args[2];
    isDebug = args[5] === "true";
    /*render settings*/
    page.zoomFactor = 1;
    page.viewportSize = { width: 600, height: 600 };
    if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
        size = system.args[3].split('*');
        page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
                                           : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
    }
    if (system.args.length > 4) {
        page.zoomFactor = system.args[4];
    }
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
            phantom.exit();
        } else {
            window.setTimeout(function () {
                page.render(output);
                phantom.exit();
            }, 200);
        }
    });
}<|endoftext|>


<commit_before>'use strict';
var AbstractStrategy = require('rest-me').Strategy,
    util = require('util'),
    Q = require('q'),
    rest = require('rest'),
    URL = require('url'),
    mime = require('rest/interceptor/mime'),
    client = rest.wrap(mime),
    _ = require('lodash');

function SpotifyStrategy(accessToken, version) {
    this.accessToken = accessToken;
    this.version = version || 'v1'
    this.apiEndpoint = 'api.spotify.com' + '/' + this.version;
    this.protocol = 'https';
}

util.inherits(SpotifyStrategy, AbstractStrategy);

SpotifyStrategy.prototype._get = function(path) {
    var parsedUrl = URL.parse(path, true);
    parsedUrl.protocol = parsedUrl.protocol || this.protocol;
    parsedUrl.host = parsedUrl.host || this.apiEndpoint;
    return client({
        method: 'get',
        path: parsedUrl.format(),
        headers: {
            Authorization: 'Bearer ' + this.accessToken
        }
    })
}

SpotifyStrategy.prototype.get = function(path) {
    return this._get(path);
}

SpotifyStrategy.prototype.getPaginatedList = function(path) {
    var done = Q.defer(),
        promises = [];
    var that = this;
    this._get(path).then(function(response) {
        if (!response.entity.total) {
            throw new Error('Path response does not represent a paginated list');
        }

        if (!response.entity.next) {
            done.resolve(response.entity);
        } else {
            var total = parseInt(response.entity.total);
            var firstResults = response.entity.items;
            var next = response.entity.next;
            var parsedUrl = URL.parse(next, true);
            var limit = parseInt(parsedUrl.query.limit);
            var nextOffset = limit;
            while (nextOffset < total) {
                parsedUrl.search = null;
                parsedUrl.query.offset = nextOffset;
                promises.push(that._get(parsedUrl.format()));
                nextOffset += limit;
            }

            Q.all(promises).then(function(data) {
                var nextResults = data.map(function(item) {
                    return item.entity.items;
                });
                var results = _.flatten([firstResults, nextResults], true);
                done.resolve({
                    items: results
                });
            }, function(err) {
                done.reject(err);
            });
        }
    })

    return done.promise;
}

module.exports = SpotifyStrategy;<commit_msg>Recursive get paginated list<commit_after>'use strict';
var AbstractStrategy = require('rest-me').Strategy,
    util = require('util'),
    Q = require('q'),
    rest = require('rest'),
    URL = require('url'),
    mime = require('rest/interceptor/mime'),
    client = rest.wrap(mime),
    _ = require('lodash');

function SpotifyStrategy(accessToken, version) {
    this.accessToken = accessToken;
    this.version = version || 'v1'
    this.apiEndpoint = 'api.spotify.com' + '/' + this.version;
    this.protocol = 'https';
}

util.inherits(SpotifyStrategy, AbstractStrategy);

SpotifyStrategy.prototype._get = function(path) {
    var parsedUrl = URL.parse(path, true);
    parsedUrl.protocol = parsedUrl.protocol || this.protocol;
    parsedUrl.host = parsedUrl.host || this.apiEndpoint;
    return client({
        method: 'get',
        path: parsedUrl.format(),
        headers: {
            Authorization: 'Bearer ' + this.accessToken
        }
    })
}

SpotifyStrategy.prototype.get = function(path) {
    return this._get(path);
}

SpotifyStrategy.prototype._recursiveGet = function(path, itemsParentNode, results) {
    var that = this;
    //Seriously Spotify, what a bad Restful architecture!
    //For APIs that returns a list, Spotify returns cursor and next url. In some cases it only work when using cursor. For example: Get User’s Followed Artists!!!
    return this._get(path).then(function(response) {
        var rootNode = itemsParentNode ? response.entity[itemsParentNode] : response.entity;

        results = results.concat(rootNode.items);
        if (rootNode.cursors && rootNode.cursors.after) {
            var parsedUrl = URL.parse(path, true);
            parsedUrl.search = null;
            parsedUrl.query.after = rootNode.cursors.after;

            return that._recursiveGet(parsedUrl.format(), itemsParentNode, results);
        } else if (rootNode.next) {
            var parsedUrl = URL.parse(rootNode.next, true);
            parsedUrl.search = null;

            return that._recursiveGet(parsedUrl.format(), itemsParentNode, results);
        } else {
            return results;
        }
    });
}

SpotifyStrategy.prototype.getPaginatedList = function(path, itemsParentNode) {
    var done = Q.defer();

    this._recursiveGet(path, itemsParentNode, []).then(function(results) {
        done.resolve({
            items: results
        })
    }, function(err) {
        done.reject(err);
    });

    return done.promise;
}

module.exports = SpotifyStrategy;<|endoftext|>


<commit_before>'use strict';

var VoteBot = {
	phrases: {
		start: [
			/(start|begin)\s+vot(e|ing)/i
		],
		vote: [
			/(?:i\s+)?vote(?:\s+for)?\s+\@([^\s]+)/i,
			/\@([^\s:]+):?\s*\+\s*\d*/i,
			/\+\s*\d*\s+@([^\s]+)/i
		],
		tally: [
			/tally/i
		],
		confirm: [
			/(yes|yep|sure|ok)/i
		]
	},

	_votes: {},
	_onConfirm: null,
	_bot: null,

	// Bootstrap VoteBot
	bootstrap: function(robot) {
		VoteBot._bot = robot;
		Object.keys(VoteBot.phrases).forEach(function(action) {
			VoteBot.phrases[action].forEach(function(phrase) {
				robot.respond(phrase, VoteBot[action]);
			});
		});
	},

	start: function(message) {
		var startVoting = function(message, done) {
			VoteBot._votes = {};
			message.reply('Got it. New voting started!');
			done && done();
		}

		if (Object.keys(VoteBot._votes).length) {
			VoteBot._onConfirm = startVoting;
			message.reply('Are you sure you want to clear all past votes and start a new poll?');
		} else {
			startVoting(message);
		}
	},

	vote: function(message) {
		var robot = VoteBot._bot;

		var sender = message.message.user.name;
		var username = message.match[1];

		var users = robot.brain.usersForFuzzyName(username);
		switch (users.length) {
			case 0:
				message.reply("I can't find anyone named @" + username);
				return;

			case 1:
				username = users[0].name;

				if (username == sender) {
					message.reply("Bad form, dude.");
					return;
				}

				var votes = VoteBot._votes;
				if (votes[sender] && votes[sender] !== username) {
					message.reply('Changing your vote to @' + username);
				} else {
					message.reply('Got your vote for @' + username);
				}
				votes[sender] = username;
				return;

			default:
				var matchingNames = users.map(function(user) {
					return '@' + user.name;
				});
				message.reply('Could you be a little clearer?  One of: ' + matchingNames.join(', '));
				return;
		}
	},

	tally: function(message) {
		var votes = VoteBot._votes;
		var tally = {};

		// Prepare tally
		Object.keys(votes).forEach(function(voter) {
			var vote = votes[voter];
			if (!tally[vote]) {
				tally[vote] = [];
			}
			tally[vote].push(voter);
		});

		// Sort tally
		var orderedTally = Object.keys(tally);
		orderedTally.sort(function(a, b) {
			return tally[a].length - tally[b].length;
		});

		// Build string
		var winner;
		var results = 'Current results:\n\n';
		orderedTally.forEach(function(username) {
			winner = username;
			var votes = tally[username];
			var count = votes.length;
			results += '   - @' + username + ': ';
			results += count + ' vote' + (1 === count ? '' : 's');
			results += '(voters: ' + votes.join(', ') + ')\n';
		});

		results += '\nWinner: @' + winner;

		message.send(results);
	},

	confirm: function(message) {
		if (VoteBot._onConfirm) {
			return VoteBot._onConfirm(message, function() {
				VoteBot._onConfirm = null;
			});
		}
	}
};

module.exports = function(robot) {
	VoteBot.bootstrap(robot);
};<commit_msg>Made responses easily configurable<commit_after>'use strict';

var util = require('util');

var VoteBot = {
	phrases: {
		start: [
			/(start|begin)\s+vot(e|ing)/i
		],
		vote: [
			/(?:i\s+)?vote(?:\s+for)?\s+\@([^\s]+)/i,
			/\@([^\s:]+):?\s*\+\s*\d*/i,
			/\+\s*\d*\s+@([^\s]+)/i
		],
		tally: [
			/tally/i
		],
		confirm: [
			/(yes|yep|sure|ok)/i
		]
	},
	responses: {
		newVotingStarted: [
			'OK, boss.',
			'Got it. New voting started!'
		],
		confirmClearVotes: [
			'Are you sure you want to clear all past votes and start a new poll?'
		],
		cannotFindUser: [
			'I can\'t find anyone named %s',
			'%s? No one \'round these parts by that name...',
		],
		votingForSelf: [
			'Bad form, dude.'
		],
		changingVoteTo: [
			'Changing your vote to %s!',
			'Fine. %s it is! You sure this time?'
		],
		votingFor: [
			'Got your vote for %s...',
			'Hmm. OK. %s it is...'
		],
		clarifyVote: [
			'Could you be a little clearer?  One of: %s'
		]
	},

	_votes: {},
	_onConfirm: null,
	_bot: null,

	_reply: function(message, key) {
		var args = Array.prototype.slice.call(arguments, 2);
		var format = message.random(VoteBot.responses[key]);
		args.unshift(format);
		var response = util.format.apply(this, args);
		message.reply(response);
	},

	// Bootstrap VoteBot
	bootstrap: function(robot) {
		VoteBot._bot = robot;
		Object.keys(VoteBot.phrases).forEach(function(action) {
			VoteBot.phrases[action].forEach(function(phrase) {
				robot.respond(phrase, VoteBot[action]);
			});
		});
	},

	start: function(message) {
		var startVoting = function(message, done) {
			VoteBot._votes = {};
			VoteBot._reply(message, 'newVotingStarted');
			done && done();
		}

		if (Object.keys(VoteBot._votes).length) {
			VoteBot._onConfirm = startVoting;
			VoteBot._reply(message, 'confirmClearVotes');
		} else {
			startVoting(message);
		}
	},

	vote: function(message) {
		var robot = VoteBot._bot;

		var sender = message.message.user.name;
		var username = message.match[1];

		var users = robot.brain.usersForFuzzyName(username);
		switch (users.length) {
			case 0:
				VoteBot._reply(message, 'cannotFindUser', '@' + username);
				return;

			case 1:
				username = users[0].name;

				if (username == sender) {
					VoteBot._reply(message, 'votingForSelf');
					return;
				}

				var votes = VoteBot._votes;
				if (votes[sender] && votes[sender] !== username) {
					VoteBot._reply(message, 'changingVoteTo', '@' + username);
				} else {
					VoteBot._reply(message, 'votingFor', '@' + username);
				}
				votes[sender] = username;
				return;

			default:
				var matchingNames = users.map(function(user) {
					return '@' + user.name;
				});
				VoteBot._reply(message, 'clarifyVote', matchingNames.join(', '));
				return;
		}
	},

	tally: function(message) {
		var votes = VoteBot._votes;
		var tally = {};

		// Prepare tally
		Object.keys(votes).forEach(function(voter) {
			var vote = votes[voter];
			if (!tally[vote]) {
				tally[vote] = [];
			}
			tally[vote].push(voter);
		});

		// Sort tally
		var orderedTally = Object.keys(tally);
		orderedTally.sort(function(a, b) {
			return tally[a].length - tally[b].length;
		});

		// Build string
		var winner;
		var results = 'Current results:\n\n';
		orderedTally.forEach(function(username) {
			winner = username;
			var votes = tally[username];
			var count = votes.length;
			results += '   - @' + username + ': ';
			results += count + ' vote' + (1 === count ? '' : 's');
			results += '(voters: ' + votes.join(', ') + ')\n';
		});

		results += '\nWinner: @' + winner;

		message.send(results);
	},

	confirm: function(message) {
		if (VoteBot._onConfirm) {
			return VoteBot._onConfirm(message, function() {
				VoteBot._onConfirm = null;
			});
		}
	}
};

module.exports = function(robot) {
	VoteBot.bootstrap(robot);
};<|endoftext|>


<commit_before>module.exports = {
  locale: 'en-US',
  messages: {
    'app.theme.switch.dark': 'Switch default mode',
    'app.theme.switch.default': 'Switch Dark mode',
    'app.header.search': 'Search...',
    'app.header.menu.home': 'Home',
    'app.header.menu.documentation': 'Documentation',
    'app.header.menu.components': 'Components',
    'app.header.menu.spec': 'Guidelines',
    'app.header.menu.resource': 'Resources',
    'app.header.menu.mobile': 'Mobile',
    'app.header.menu.pro.v4': 'Ant Design Pro v4',
    'app.header.menu.ecosystem': 'Ecosystem',
    'app.header.lang': '中文',
    'app.content.edit-page': 'Edit this page on GitHub!',
    'app.content.edit-demo': 'Edit this demo on GitHub!',
    'app.content.contributors': 'contributors',
    'app.component.examples': 'Examples',
    'app.component.examples.expand': 'Expand all code',
    'app.component.examples.collapse': 'Collapse all code',
    'app.component.examples.visible': 'Expand debug examples',
    'app.component.examples.hide': 'Collapse debug examples',
    'app.demo.debug': "Debug only, won't display at online",
    'app.demo.copy': 'Copy code',
    'app.demo.copied': 'Copied!',
    'app.demo.code.show': 'Show code',
    'app.demo.code.hide': 'Hide code',
    'app.demo.codepen': 'Open in CodePen',
    'app.demo.codesandbox': 'Open in CodeSandbox',
    'app.demo.stackblitz': 'Open in Stackblitz',
    'app.demo.riddle': 'Open in Riddle',
    'app.home.slogan': "The world's second most popular React UI framework",
    'app.home.introduce':
      'A design system with values of Nature and Determinacy for better user experience of enterprise applications',
    'app.home.design-language': 'Design Language',
    'app.home.solution': 'Solution',
    'app.home.components-explain':
      'Based on the Ant Design language, we have provided a suite of out-of-the-box with high quality for developing and serving enterprise background applications, including the official React UI library and Angular, Vue implementations',
    'app.home.product-pro-slogan': 'Out-of-the-box front-end / Design solution',
    'app.home.product-mobile-slogan':
      "antd-mobile is the implementation of Ant Design's mobile specification",
    'app.home.product-landing-slogan':
      'Landing Pages templates and specifications based of Ant Design language',
    'app.home.product-antv-slogan':
      'Simple, professional, with unlimited possibilities for data visualization solutions',
    'app.home.tool-title': 'Tools & Resources',
    'app.home.tool-package-title': 'Ant Design Resources',
    'app.home.tool-package-content': 'Ant Design Resources Download',
    'app.home.tool-library-title': 'Axure Library',
    'app.home.tool-library-content': 'Beautifully visual Axure library',
    'app.home.tool-kitchen-title': 'Kitchen',
    'app.home.tool-kitchen-content': 'A Sketch tools for designers',
    'app.home.getting-started': 'Getting Started',
    'app.home.recommend': 'Recommend',
    'app.home.recommend.yuque': 'Yuque, our favorite documentation tool',
    'app.home.recommend.antv.g2plot': 'G2Plot, the new charting library',
    'app.home.more': 'Learn more',
    'app.home.more-mobile-react': 'Ant Design Mobile of React',
    'app.home.more-mobile-angular': 'Ant Design Mobile of Angular',
    'app.footer.repo': 'GitHub Repository',
    'app.footer.awesome': 'Awesome Ant Design',
    'app.footer.course': 'Ant Design Practical Tutorial',
    'app.footer.chinamirror': 'China Mirror 🇨🇳',
    'app.footer.primary-color-changing': 'Changing primary color...',
    'app.footer.primary-color-changed': 'Change primary color successfully!',
    'app.footer.scaffold': 'Scaffold',
    'app.footer.kitchen': 'Sketch Toolkit',
    'app.footer.landing': 'Landing Templates',
    'app.footer.scaffolds': 'Scaffold Market',
    'app.footer.dev-tools': 'Developer Tools',
    'app.footer.umi': 'React Application Framework',
    'app.footer.dva': 'Data Flow Framework',
    'app.footer.remax': 'Mini Program Framework',
    'app.footer.resources': 'Resources',
    'app.footer.data-vis': 'Data Visualization',
    'app.footer.eggjs': 'Enterprise Node Framework',
    'app.footer.motion': 'Motion Solution',
    'app.footer.design-resources': 'Design Resources',
    'app.footer.antd-library': 'Axure library',
    'app.footer.antux': 'Sitemap Template',
    'app.footer.community': 'Community',
    'app.footer.help': 'Help',
    'app.footer.change-log': 'Change Log',
    'app.footer.faq': 'FAQ',
    'app.footer.feedback': 'Feedback',
    'app.footer.stackoverflow': 'StackOverflow',
    'app.footer.segmentfault': 'SegmentFault',
    'app.footer.discuss-en': 'Chat Room 🇺🇸',
    'app.footer.discuss-cn': 'Chat Room 🇨🇳',
    'app.footer.bug-report': 'Bug Report',
    'app.footer.issues': 'Issues',
    'app.footer.version': 'Version: ',
    'app.footer.author': 'Created by XTech',
    'app.footer.work_with_us': 'Work with Us',
    'app.footer.more-product': 'More Products',
    'app.footer.company': 'XTech',
    'app.footer.ant-design': 'UI Design Language',
    'app.footer.yuque': 'YuQue',
    'app.footer.yuque.slogan': 'Write your document as a team',
    'app.footer.fengdie': 'FengDie',
    'app.footer.fengdie.slogan': 'Console Applications Builder',
    'app.footer.antv.slogan': 'Data Visualization',
    'app.footer.egg.slogan': 'Enterprise Node.js Framework',
    'app.footer.zhihu': 'Ant Design Blog',
    'app.footer.zhihu.xtech': 'Experience Cloud Blog',
    'app.footer.seeconf': 'Experience Tech Conference',
    'app.footer.xtech': 'Ant Financial Experience Tech',
    'app.footer.xtech.slogan': 'Experience The Beauty',
    'app.publish.title': 'antd@3.0.0 has been released! 🎉 🎉 🎉',
    'app.publish.greeting': 'Hello, ',
    'app.publish.intro': ' has been released, and please upgrade. ',
    'app.publish.old-version-guide': 'If you need documentation of older version, please visit ',
    'app.publish.old-version-tips': ', or switch version with the select at header navigation.',
    'app.docs.color.pick-primary': 'Pick your primary color',
    'app.docs.components.icon.search.placeholder': 'Search icon here, click icon to copy code',
    'app.docs.components.icon.outlined': 'Outlined',
    'app.docs.components.icon.filled': 'Filled',
    'app.docs.components.icon.two-tone': 'Two Tone',
    'app.docs.components.icon.category.direction': 'Directional Icons',
    'app.docs.components.icon.category.suggestion': 'Suggested Icons',
    'app.docs.components.icon.category.editor': 'Editor Icons',
    'app.docs.components.icon.category.data': 'Data Icons',
    'app.docs.components.icon.category.other': 'Application Icons',
    'app.docs.components.icon.category.logo': 'Brand and Logos',
    'app.docs.components.icon.pic-searcher.intro':
      'AI Search by image is online, welcome to use! 🎉',
    'app.docs.components.icon.pic-searcher.title': 'Search by image',
    'app.docs.components.icon.pic-searcher.upload-text':
      'Click or drag or paste file to this area to upload',
    'app.docs.components.icon.pic-searcher.upload-hint':
      'We will find the most matching icon based on the image',
    'app.docs.components.icon.pic-searcher.server-error':
      'Predict service is temporarily unavailable',
    'app.docs.components.icon.pic-searcher.matching': 'Matching...',
    'app.docs.components.icon.pic-searcher.modelloading': 'Model is loading...',
    'app.docs.components.icon.pic-searcher.result-tip': 'Match the following icons for you:',
    'app.docs.components.icon.pic-searcher.th-icon': 'Icon',
    'app.docs.components.icon.pic-searcher.th-score': 'Probability',
  },
};
<commit_msg>fix: site theme switch text<commit_after>module.exports = {
  locale: 'en-US',
  messages: {
    'app.theme.switch.dark': 'Switch default mode',
    'app.theme.switch.default': 'Switch dark mode',
    'app.header.search': 'Search...',
    'app.header.menu.home': 'Home',
    'app.header.menu.documentation': 'Documentation',
    'app.header.menu.components': 'Components',
    'app.header.menu.spec': 'Guidelines',
    'app.header.menu.resource': 'Resources',
    'app.header.menu.mobile': 'Mobile',
    'app.header.menu.pro.v4': 'Ant Design Pro v4',
    'app.header.menu.ecosystem': 'Ecosystem',
    'app.header.lang': '中文',
    'app.content.edit-page': 'Edit this page on GitHub!',
    'app.content.edit-demo': 'Edit this demo on GitHub!',
    'app.content.contributors': 'contributors',
    'app.component.examples': 'Examples',
    'app.component.examples.expand': 'Expand all code',
    'app.component.examples.collapse': 'Collapse all code',
    'app.component.examples.visible': 'Expand debug examples',
    'app.component.examples.hide': 'Collapse debug examples',
    'app.demo.debug': "Debug only, won't display at online",
    'app.demo.copy': 'Copy code',
    'app.demo.copied': 'Copied!',
    'app.demo.code.show': 'Show code',
    'app.demo.code.hide': 'Hide code',
    'app.demo.codepen': 'Open in CodePen',
    'app.demo.codesandbox': 'Open in CodeSandbox',
    'app.demo.stackblitz': 'Open in Stackblitz',
    'app.demo.riddle': 'Open in Riddle',
    'app.home.slogan': "The world's second most popular React UI framework",
    'app.home.introduce':
      'A design system with values of Nature and Determinacy for better user experience of enterprise applications',
    'app.home.design-language': 'Design Language',
    'app.home.solution': 'Solution',
    'app.home.components-explain':
      'Based on the Ant Design language, we have provided a suite of out-of-the-box with high quality for developing and serving enterprise background applications, including the official React UI library and Angular, Vue implementations',
    'app.home.product-pro-slogan': 'Out-of-the-box front-end / Design solution',
    'app.home.product-mobile-slogan':
      "antd-mobile is the implementation of Ant Design's mobile specification",
    'app.home.product-landing-slogan':
      'Landing Pages templates and specifications based of Ant Design language',
    'app.home.product-antv-slogan':
      'Simple, professional, with unlimited possibilities for data visualization solutions',
    'app.home.tool-title': 'Tools & Resources',
    'app.home.tool-package-title': 'Ant Design Resources',
    'app.home.tool-package-content': 'Ant Design Resources Download',
    'app.home.tool-library-title': 'Axure Library',
    'app.home.tool-library-content': 'Beautifully visual Axure library',
    'app.home.tool-kitchen-title': 'Kitchen',
    'app.home.tool-kitchen-content': 'A Sketch tools for designers',
    'app.home.getting-started': 'Getting Started',
    'app.home.recommend': 'Recommend',
    'app.home.recommend.yuque': 'Yuque, our favorite documentation tool',
    'app.home.recommend.antv.g2plot': 'G2Plot, the new charting library',
    'app.home.more': 'Learn more',
    'app.home.more-mobile-react': 'Ant Design Mobile of React',
    'app.home.more-mobile-angular': 'Ant Design Mobile of Angular',
    'app.footer.repo': 'GitHub Repository',
    'app.footer.awesome': 'Awesome Ant Design',
    'app.footer.course': 'Ant Design Practical Tutorial',
    'app.footer.chinamirror': 'China Mirror 🇨🇳',
    'app.footer.primary-color-changing': 'Changing primary color...',
    'app.footer.primary-color-changed': 'Change primary color successfully!',
    'app.footer.scaffold': 'Scaffold',
    'app.footer.kitchen': 'Sketch Toolkit',
    'app.footer.landing': 'Landing Templates',
    'app.footer.scaffolds': 'Scaffold Market',
    'app.footer.dev-tools': 'Developer Tools',
    'app.footer.umi': 'React Application Framework',
    'app.footer.dva': 'Data Flow Framework',
    'app.footer.remax': 'Mini Program Framework',
    'app.footer.resources': 'Resources',
    'app.footer.data-vis': 'Data Visualization',
    'app.footer.eggjs': 'Enterprise Node Framework',
    'app.footer.motion': 'Motion Solution',
    'app.footer.design-resources': 'Design Resources',
    'app.footer.antd-library': 'Axure library',
    'app.footer.antux': 'Sitemap Template',
    'app.footer.community': 'Community',
    'app.footer.help': 'Help',
    'app.footer.change-log': 'Change Log',
    'app.footer.faq': 'FAQ',
    'app.footer.feedback': 'Feedback',
    'app.footer.stackoverflow': 'StackOverflow',
    'app.footer.segmentfault': 'SegmentFault',
    'app.footer.discuss-en': 'Chat Room 🇺🇸',
    'app.footer.discuss-cn': 'Chat Room 🇨🇳',
    'app.footer.bug-report': 'Bug Report',
    'app.footer.issues': 'Issues',
    'app.footer.version': 'Version: ',
    'app.footer.author': 'Created by XTech',
    'app.footer.work_with_us': 'Work with Us',
    'app.footer.more-product': 'More Products',
    'app.footer.company': 'XTech',
    'app.footer.ant-design': 'UI Design Language',
    'app.footer.yuque': 'YuQue',
    'app.footer.yuque.slogan': 'Write your document as a team',
    'app.footer.fengdie': 'FengDie',
    'app.footer.fengdie.slogan': 'Console Applications Builder',
    'app.footer.antv.slogan': 'Data Visualization',
    'app.footer.egg.slogan': 'Enterprise Node.js Framework',
    'app.footer.zhihu': 'Ant Design Blog',
    'app.footer.zhihu.xtech': 'Experience Cloud Blog',
    'app.footer.seeconf': 'Experience Tech Conference',
    'app.footer.xtech': 'Ant Financial Experience Tech',
    'app.footer.xtech.slogan': 'Experience The Beauty',
    'app.publish.title': 'antd@3.0.0 has been released! 🎉 🎉 🎉',
    'app.publish.greeting': 'Hello, ',
    'app.publish.intro': ' has been released, and please upgrade. ',
    'app.publish.old-version-guide': 'If you need documentation of older version, please visit ',
    'app.publish.old-version-tips': ', or switch version with the select at header navigation.',
    'app.docs.color.pick-primary': 'Pick your primary color',
    'app.docs.components.icon.search.placeholder': 'Search icon here, click icon to copy code',
    'app.docs.components.icon.outlined': 'Outlined',
    'app.docs.components.icon.filled': 'Filled',
    'app.docs.components.icon.two-tone': 'Two Tone',
    'app.docs.components.icon.category.direction': 'Directional Icons',
    'app.docs.components.icon.category.suggestion': 'Suggested Icons',
    'app.docs.components.icon.category.editor': 'Editor Icons',
    'app.docs.components.icon.category.data': 'Data Icons',
    'app.docs.components.icon.category.other': 'Application Icons',
    'app.docs.components.icon.category.logo': 'Brand and Logos',
    'app.docs.components.icon.pic-searcher.intro':
      'AI Search by image is online, welcome to use! 🎉',
    'app.docs.components.icon.pic-searcher.title': 'Search by image',
    'app.docs.components.icon.pic-searcher.upload-text':
      'Click or drag or paste file to this area to upload',
    'app.docs.components.icon.pic-searcher.upload-hint':
      'We will find the most matching icon based on the image',
    'app.docs.components.icon.pic-searcher.server-error':
      'Predict service is temporarily unavailable',
    'app.docs.components.icon.pic-searcher.matching': 'Matching...',
    'app.docs.components.icon.pic-searcher.modelloading': 'Model is loading...',
    'app.docs.components.icon.pic-searcher.result-tip': 'Match the following icons for you:',
    'app.docs.components.icon.pic-searcher.th-icon': 'Icon',
    'app.docs.components.icon.pic-searcher.th-score': 'Probability',
  },
};
<|endoftext|>


<commit_before>/* globals window, $$course_id, DiscussionUtil */
function DiscussionCourseBlock(runtime, element) {
    'use strict';
    var hasPushState = window.history && window.history.pushState ? true : false;
    DiscussionUtil.force_async = true;
    loadDiscussionApp();

    // Restart the Backbone router to use the discussion root when
    // links inside this component are clicked.
    if (Backbone.History.started) {
        Backbone.history.stop();
    }
    Backbone.history.start({
        pushState: hasPushState,
        root: "/courses/" + $$course_id + "/discussion/"
    });
}
<commit_msg>Removes an redundant call to loadDiscussionApp()<commit_after>/* globals window, $$course_id, DiscussionUtil */
function DiscussionCourseBlock(runtime, element) {
    'use strict';
    var hasPushState = window.history && window.history.pushState ? true : false;
    DiscussionUtil.force_async = true;

    // Restart the Backbone router to use the discussion root when
    // links inside this component are clicked.
    if (Backbone.History.started) {
        Backbone.history.stop();
    }
    Backbone.history.start({
        pushState: hasPushState,
        root: "/courses/" + $$course_id + "/discussion/"
    });
}
<|endoftext|>


<commit_before>const test = require('tap').test;
const vm = require('vm');
const spawn = require('child_process').spawn;

const quadPath = require.resolve('./files/quad.js');
const quadPathBuble = require.resolve('./files/quad.buble');
const bubleifyPath = require.resolve('../index.js');
const browserifyCmd = require.resolve('../node_modules/.bin/browserify');

const testContextQuad5 = (b, t) => {
  let out = '';
  let err = '';
  b.stdout.on('data', (buf) => {
    out += buf;
  });
  b.stderr.on('data', (buf) => {
    err += buf;
  });

  b.on('error', (processErr) => {
    throw processErr;
  });

  b.on('exit', () => {
    const sandbox = {};
    const srcStr = typeof out !== 'string' ? out.toString('utf8') : out;
    vm.runInNewContext(srcStr, sandbox);
    const result = sandbox.require('quad')(5);

    t.error(err);
    t.equal(result, 25);
    t.end();
  });
};

test('simple cli', (t) => {
  const bProcess = spawn(browserifyCmd, [
    '-r', `${quadPath}:quad`,
    '-t', '[', bubleifyPath, ']',
  ], { shell: true });

  testContextQuad5(bProcess, t);
});

test('cli with custom extension', (t) => {
  const bProcess = spawn(browserifyCmd, [
    '-r', `${quadPathBuble}:quad`,
    '-t', '[', bubleifyPath, '--extensions .buble ]',
  ], { shell: true });

  testContextQuad5(bProcess, t);
});
<commit_msg>Fix cli test<commit_after>const test = require('tap').test;
const vm = require('vm');
const spawn = require('child_process').spawn;

const quadPath = require.resolve('./files/quad.js');
const quadPathBuble = require.resolve('./files/quad.buble');
const bubleifyPath = require.resolve('../index.js');
const browserifyCmd = require.resolve('../node_modules/.bin/browserify');

const testContextQuad5 = (b, t) => {
  let out = '';
  let err = '';
  b.stdout.on('data', (buf) => {
    out += buf;
  });
  b.stderr.on('data', (buf) => {
    err += buf;
  });

  b.on('error', (processErr) => {
    throw processErr;
  });

  b.on('exit', () => {
    const sandbox = {};
    const srcStr = typeof out !== 'string' ? out.toString('utf8') : out;
    vm.runInNewContext(srcStr, sandbox);
    const result = sandbox.require('quad')(5);

    t.error(err);
    t.equal(result, 25);
    t.end();
  });
};

test('simple cli', (t) => {
  const bProcess = spawn(browserifyCmd, [
    '-r', `${quadPath}:quad`,
    '-t', '[', bubleifyPath, ']',
  ], { shell: true });

  testContextQuad5(bProcess, t);
});

test('cli with custom extension', (t) => {
  const bProcess = spawn(browserifyCmd, [
    '-r', `${quadPathBuble}:quad`,
    '-t', '[', bubleifyPath, '--extensions', '.buble', ']',
  ], { shell: true });

  testContextQuad5(bProcess, t);
});
<|endoftext|>


<commit_before><commit_msg>Fixed browser check<commit_after><|endoftext|>


<commit_before><commit_msg>Fix Resources panel enablement<commit_after><|endoftext|>


<commit_before>var Example = Example || {};

Example.stress3 = function() {
    var Engine = Matter.Engine,
        Render = Matter.Render,
        Runner = Matter.Runner,
        Composites = Matter.Composites,
        Common = Matter.Common,
        MouseConstraint = Matter.MouseConstraint,
        Mouse = Matter.Mouse,
        Composite = Matter.Composite,
        Bodies = Matter.Bodies;

    // create engine
    var engine = Engine.create(),
        world = engine.world;

    // create renderer
    var render = Render.create({
        element: document.body,
        engine: engine,
        options: {
            width: 800,
            height: 600,
            showStats: true,
            showPerformance: true
        }
    });

    Render.run(render);

    // create runner
    var runner = Runner.create({
        isFixed: true
    });
    Runner.run(runner, engine);

    // add bodies
    var scale = 0.3;

    var stack = Composites.stack(40, 40, 38, 18, 0, 0, function(x, y) {
        var sides = Math.round(Common.random(1, 8));

        switch (Math.round(Common.random(0, 1))) {
        case 0:
            if (Common.random() < 0.8) {
                return Bodies.rectangle(x, y, Common.random(25, 50) * scale, Common.random(25, 50) * scale);
            } else {
                return Bodies.rectangle(x, y, Common.random(80, 120) * scale, Common.random(25, 30) * scale);
            }
        case 1:
            return Bodies.polygon(x, y, sides, Common.random(25, 50) * scale);
        }
    });

    Composite.add(world, stack);

    Composite.add(world, [
        // walls
        Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
        Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
        Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
        Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    // add mouse control
    var mouse = Mouse.create(render.canvas),
        mouseConstraint = MouseConstraint.create(engine, {
            mouse: mouse,
            constraint: {
                stiffness: 0.2,
                render: {
                    visible: false
                }
            }
        });

    Composite.add(world, mouseConstraint);

    // keep the mouse in sync with rendering
    render.mouse = mouse;

    // fit the render viewport to the scene
    Render.lookAt(render, {
        min: { x: 0, y: 0 },
        max: { x: 800, y: 600 }
    });

    // context for MatterTools.Demo
    return {
        engine: engine,
        runner: runner,
        render: render,
        canvas: render.canvas,
        stop: function() {
            Matter.Render.stop(render);
            Matter.Runner.stop(runner);
        }
    };
};

Example.stress3.title = 'Stress 3';
Example.stress3.for = '>=0.14.2';

if (typeof module !== 'undefined') {
    module.exports = Example.stress3;
}
<commit_msg>increase iterations on Example.stress3<commit_after>var Example = Example || {};

Example.stress3 = function() {
    var Engine = Matter.Engine,
        Render = Matter.Render,
        Runner = Matter.Runner,
        Composites = Matter.Composites,
        Common = Matter.Common,
        MouseConstraint = Matter.MouseConstraint,
        Mouse = Matter.Mouse,
        Composite = Matter.Composite,
        Bodies = Matter.Bodies;

    // create engine
    var engine = Engine.create({
        positionIterations: 10,
        velocityIterations: 10
    });

    var world = engine.world;

    // create renderer
    var render = Render.create({
        element: document.body,
        engine: engine,
        options: {
            width: 800,
            height: 600,
            showStats: true,
            showPerformance: true
        }
    });

    Render.run(render);

    // create runner
    var runner = Runner.create({
        isFixed: true
    });
    Runner.run(runner, engine);

    // add bodies
    var scale = 0.3;

    var stack = Composites.stack(40, 40, 38, 18, 0, 0, function(x, y) {
        var sides = Math.round(Common.random(1, 8));

        switch (Math.round(Common.random(0, 1))) {
        case 0:
            if (Common.random() < 0.8) {
                return Bodies.rectangle(x, y, Common.random(25, 50) * scale, Common.random(25, 50) * scale);
            } else {
                return Bodies.rectangle(x, y, Common.random(80, 120) * scale, Common.random(25, 30) * scale);
            }
        case 1:
            return Bodies.polygon(x, y, sides, Common.random(25, 50) * scale);
        }
    });

    Composite.add(world, stack);

    Composite.add(world, [
        // walls
        Bodies.rectangle(400, 0, 800, 50, { isStatic: true }),
        Bodies.rectangle(400, 600, 800, 50, { isStatic: true }),
        Bodies.rectangle(800, 300, 50, 600, { isStatic: true }),
        Bodies.rectangle(0, 300, 50, 600, { isStatic: true })
    ]);

    // add mouse control
    var mouse = Mouse.create(render.canvas),
        mouseConstraint = MouseConstraint.create(engine, {
            mouse: mouse,
            constraint: {
                stiffness: 0.2,
                render: {
                    visible: false
                }
            }
        });

    Composite.add(world, mouseConstraint);

    // keep the mouse in sync with rendering
    render.mouse = mouse;

    // fit the render viewport to the scene
    Render.lookAt(render, {
        min: { x: 0, y: 0 },
        max: { x: 800, y: 600 }
    });

    // context for MatterTools.Demo
    return {
        engine: engine,
        runner: runner,
        render: render,
        canvas: render.canvas,
        stop: function() {
            Matter.Render.stop(render);
            Matter.Runner.stop(runner);
        }
    };
};

Example.stress3.title = 'Stress 3';
Example.stress3.for = '>=0.14.2';

if (typeof module !== 'undefined') {
    module.exports = Example.stress3;
}
<|endoftext|>