<commit_before>import React from 'react';
import purebem from 'purebem';
import moment from 'moment';

import isNull from 'lodash.isnull';
import filter from 'lodash.filter';
import pick from 'lodash.pick';
import omitBy from 'lodash.omitby';
import debounce from 'lodash.debounce';
import cloneDeep from 'lodash.clonedeep';
import assign from 'lodash.assign';
import random from 'lodash.random';

import firebaseRef from 'app/firebaseRef';

import ButtonSwitch from 'app/components/ButtonSwitch';
import ContentBox from 'app/components/ContentBox';
import InputField from 'app/components/InputField';
import ProjectMap from 'app/components/ProjectMap';
import ProjectSites from 'app/components/ProjectSites';

const ERROR_TITLE = 'Please fill in a title.';
const ERROR_DATE = 'A valid date follows the pattern YYYYMMDD.';
const ERROR_END = 'A project must start before it can end, silly.';

const defaultState = {
    end: {},
    errors: {},
    isLocked: true,
    isPublic: true,
    isSubmitting: false,
    sites: [],
    start: {},
    title: {},
    toggleMapLock: ['Unlocked', 'Locked'],
    togglePrivacy: ['Private', 'Public']
};

const delayAction = debounce((action) => action(), 300);

const form = purebem.of('form');
const block = purebem.of('create-view');

const CreateView = React.createClass({

    componentWillMount() {
        this.setState(cloneDeep(defaultState));
    },

    isEmpty(str) {
        return !str || !str.trim().length;
    },

    isDate(str) {
        return moment(str, 'YYYYMMDD', true).isValid();
    },

    hasErrors(errors) {
        errors = errors || this.state.errors;
        return Object.keys(omitBy(errors, isNull)).length;
    },

    getSites() {
        return this.state.sites.filter(site => site.name).map(site => pick(site, ['latlng', 'name']));
    },

    validateAll() {
        let errors = {};

        ['title', 'start', 'end'].map(name => {
            assign(errors, this.validateField(name, this.state[name].value));
        });

        return errors;
    },

    validateField(name, value) {
        const error = {};
        const { start, end } = this.state;

        switch (name) {
            case 'title':
                error[name] = this.isEmpty(value) ? ERROR_TITLE : null;
                break;
            default:
                error[name] = !this.isDate(value) ? ERROR_DATE : null;

                if (this.isDate(start.value) && this.isDate(end.value)) {
                    error.order = start.value >= end.value ? ERROR_END : null;
                }
        };

        return error;
    },

    handleChange(evt) {
        const { name, value } = evt.target;
        const { errors } = cloneDeep(this.state);
        this.setState({ [name]: { value } });

        delayAction(() => {
            this.setState({ errors: assign(errors, this.validateField(name, value)) });
        });
    },

    handleReset() {
        this.form.reset();
        this.handleSitesClear();
        this.setState(cloneDeep(defaultState));
    },

    handleSubmit(evt) {
        evt.preventDefault();
        const errors = this.validateAll();

        if (this.hasErrors(errors)) {
            this.setState({ errors });
            return;
        }

        const { title, start, end, sites, isPublic } = this.state;
        const uid = firebaseRef.getAuth().uid;
        const format = 'YYYYMMDD';

        const data = {
            created: moment().format(format),
            title: title.value,
            start: moment(start.value, format).unix(),
            end: moment(end.value, format).unix(),
            public: isPublic,
            ownerId: uid,
            luckyNumber: random(0,360)
        };

        // 1. Add project
        const projectRef = firebaseRef.child('projects').push(data, this.onComplete('projects'));
        const pid = projectRef.key();

        // 2. Add sites
        this.getSites().map(site => {
            const siteRef = firebaseRef.child('sites').push(assign(site, { projectId: pid, ownerId: uid }), this.onComplete('sites'));
            const sid = siteRef.key();

            // 2.1 Update project/sites
            firebaseRef.child(`projects/${pid}/sites/${sid}`).set(true);
        });

        // 3. Update user with ownership
        firebaseRef.child(`users/${uid}/projects/${pid}`).set(true, this.onComplete('users'));

        // 4. Set membership in memberships/project
        firebaseRef.child(`memberships/${pid}/member/${uid}`).set(true, this.onComplete('memberships'));

        console.log('all done…');
    },

    onComplete(store) {
        return (error) => {
            console.log('Saving data to',store, error ? error : 'OK');
        };
    },

    handleSwitch(name) {
        switch (name) {
            case 'privacy':
                this.setState({ isPublic: !this.state.isPublic });
                break;
            case 'maplock':
                this.setState({ isLocked: !this.state.isLocked });
                break;
        };
    },

    handleSiteAdd(marker) {
        const sites = [ ...this.state.sites, marker ];
        this.setState({ sites });
    },

    handleSiteChange(index) {
        return evt => {
            const { sites } = this.state;
            sites[index].name = evt.target.value;
            this.setState({ sites });
        }
    },

    handleSiteRemove(index) {
        let { sites } = this.state;
        sites[index].setMap(null);
        sites.splice(index, 1);
        this.setState({ sites });
    },

    handleSitesClear() {
        const sites = filter(this.state.sites, (item) => item.setMap(null));
        this.setState({ sites });
    },

    renderPrivacyInfo() {
        const info = this.state.isPublic
            ? (
Public projects aim at collaboration. Users can find your project and may request to join.
)
            : (
Private projects aim at privacy. Other users cannot find nor participate in private projects.
);

        return (

{ info }

        );
    },

    renderErrorInfo() {
        if (!this.hasErrors()) {
            return null;
        }

        return (

Please correct any errors to proceed.

        );
    },

    renderForm() {
        const buttonClass = purebem.many(block('button', ['submit']), 'button-primary');
        const { title, start, end, errors, isSubmitting } = this.state;

        return (
            <form className={ block('form') } onSubmit={ this.handleSubmit } ref={ (form) => this.form = form }>

                    Project title
                    <InputField
                        name="title"
                        error={ errors.title }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        value={ title.value } />

                    Start date
                    <InputField
                        name="start"
                        error={ errors.start }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        placeholder="yyyymmdd"
                        value={ start.value } />

                    End date
                    <InputField
                        name="end"
                        error={ errors.end || errors.order }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        placeholder="yyyymmdd"
                        value={ end.value } />

                <ProjectSites
                    sites={ this.state.sites }
                    onChange={ (i) => this.handleSiteChange(i) }
                    onRemove={ (i) => this.handleSiteRemove(i) } />
                <ButtonSwitch
                    className={ block('switch', ['maplock']) }
                    isActive={ this.state.isLocked }
                    onClick={ () => this.handleSwitch('maplock') }
                    options={ this.state.toggleMapLock } />

Unlock the map to locate and mark your ringing sites. Geolocation data may be used for statistics.

                <ButtonSwitch
                    className={ block('switch', ['privacy']) }
                    isActive={ this.state.isPublic }
                    onClick={ () => this.handleSwitch('privacy') }
                    options={ this.state.togglePrivacy } />
                { this.renderPrivacyInfo() }
                { this.renderErrorInfo() }

                    <button type="submit" className={ buttonClass } disabled={ isSubmitting }>Create</button>
                    <button type="button" className={ block('button', ['reset']) } onClick={ this.handleReset }>Reset</button>

            </form>
        );
    },

    render() {
        return (

                    <ProjectMap
                        onClick={ this.handleSiteAdd }
                        sites={ this.state.sites }
                        unlocked={ !this.state.isLocked } />
                    <ContentBox background="white" shadow={ true }>
                        { this.renderForm() }
                    </ContentBox>

        );
    }

});

export default CreateView;
<commit_msg>submission handling and modal/success state<commit_after>import React from 'react';
import purebem from 'purebem';
import moment from 'moment';

import isNull from 'lodash.isnull';
import filter from 'lodash.filter';
import pick from 'lodash.pick';
import omitBy from 'lodash.omitby';
import debounce from 'lodash.debounce';
import cloneDeep from 'lodash.clonedeep';
import assign from 'lodash.assign';
import random from 'lodash.random';

import firebaseRef from 'app/firebaseRef';

import ButtonSwitch from 'app/components/ButtonSwitch';
import ContentBox from 'app/components/ContentBox';
import InputField from 'app/components/InputField';
import Modal from 'app/components/Modal';
import ProjectMap from 'app/components/ProjectMap';
import ProjectSites from 'app/components/ProjectSites';
import ProjectSuccess from 'app/components/ProjectSuccess';

const ERROR_TITLE = 'Please fill in a title.';
const ERROR_DATE = 'A valid date follows the pattern YYYYMMDD.';
const ERROR_END = 'A project must start before it can end, silly.';

const defaultState = {
    end: {},
    errors: {},
    isLocked: true,
    isPublic: true,
    isSubmitting: false,
    // project: {
    //     dateEnd: {},
    //     dateStart: {},
    //     id: '',
    //     sites: [],
    //     title: '',
    // }
    projectId: '',
    sites: [],
    showSuccess: false,
    start: {},
    title: {},
    toggleMapLock: ['Unlocked', 'Locked'],
    togglePrivacy: ['Private', 'Public']
};

const delayAction = debounce((action) => action(), 300);

const form = purebem.of('form');
const block = purebem.of('create-view');

const CreateView = React.createClass({

    componentWillMount() {
        this.setState(cloneDeep(defaultState));
        this.uid = firebaseRef.getAuth().uid;
    },

    isEmpty(str) {
        return !str || !str.trim().length;
    },

    isDate(str) {
        return moment(str, 'YYYYMMDD', true).isValid();
    },

    hasErrors(errors) {
        errors = errors || this.state.errors;
        return Object.keys(omitBy(errors, isNull)).length;
    },

    getSites() {
        return this.state.sites.filter(site => site.name).map(site => pick(site, ['latlng', 'name']));
    },

    validateAll() {
        let errors = {};

        ['title', 'start', 'end'].map(name => {
            assign(errors, this.validateField(name, this.state[name].value));
        });

        return errors;
    },

    validateField(name, value) {
        const error = {};
        const { start, end } = this.state;

        switch (name) {
            case 'title':
                error[name] = this.isEmpty(value) ? ERROR_TITLE : null;
                break;
            default:
                error[name] = !this.isDate(value) ? ERROR_DATE : null;

                if (this.isDate(start.value) && this.isDate(end.value)) {
                    error.order = start.value >= end.value ? ERROR_END : null;
                }
        };

        return error;
    },

    handleChange(evt) {
        const { name, value } = evt.target;
        const { errors } = cloneDeep(this.state);
        this.setState({ [name]: { value } });

        delayAction(() => {
            this.setState({ errors: assign(errors, this.validateField(name, value)) });
        });
    },

    handleReset() {
        this.form.reset();
        this.handleSitesClear();
        this.setState(cloneDeep(defaultState));
    },

    handleSubmit(evt) {
        evt.preventDefault();
        const errors = this.validateAll();

        if (this.hasErrors(errors)) {
            this.setState({ errors });
            return;
        }

        const { title, start, end, sites, isPublic } = this.state;
        const format = 'YYYYMMDD';

        const data = {
            created: moment().unix(),
            title: title.value,
            start: moment(start.value, format).unix(),
            end: moment(end.value, format).unix(),
            public: isPublic,
            ownerId: this.uid,
            luckyNumber: random(0,360)
        };

        // Add project
        this.projectRef = firebaseRef.child('projects').push(data, this.onComplete);
    },

    onComplete(error) {
        if (error) {
            console.log('Oh snap! An error occurred…');
            return;
        }

        // Get project ID
        const pid = this.projectRef.key();

        // Add sites
        this.getSites().map((site, index) => {
            const newSite = assign(site, { projectId: pid, ownerId: this.uid });
            const siteRef = firebaseRef.child('sites').push(newSite);
            const sid = siteRef.key();

            // Update project/sites
            firebaseRef.child(`projects/${pid}/sites/${sid}`).set(true);
        });

        // Update user with ownership
        firebaseRef.child(`users/${this.uid}/projects/${pid}`).set(true);

        // Set membership in memberships/project
        firebaseRef.child(`memberships/${pid}/member/${this.uid}`).set(true);

        // Display Success state
        this.setState({ showSuccess: true, projectId: pid });
    },

    handleSwitch(name) {
        switch (name) {
            case 'privacy':
                this.setState({ isPublic: !this.state.isPublic });
                break;
            case 'maplock':
                this.setState({ isLocked: !this.state.isLocked });
                break;
        };
    },

    handleSiteAdd(marker) {
        const sites = [ ...this.state.sites, marker ];
        this.setState({ sites });
    },

    handleSiteChange(index) {
        return evt => {
            const { sites } = this.state;
            sites[index].name = evt.target.value;
            this.setState({ sites });
        }
    },

    handleSiteRemove(index) {
        let { sites } = this.state;
        sites[index].setMap(null);
        sites.splice(index, 1);
        this.setState({ sites });
    },

    handleSitesClear() {
        const sites = filter(this.state.sites, (item) => item.setMap(null));
        this.setState({ sites });
    },

    handleModalClose() {
        this.handleReset();
        window.scrollTo(0,0);
    },

    renderPrivacyInfo() {
        const info = this.state.isPublic
            ? (
Public projects aim at collaboration. Users can find your project and may request to join.
)
            : (
Private projects aim at privacy. Other users cannot find nor participate in private projects.
);

        return (

{ info }

        );
    },

    renderErrorInfo() {
        if (!this.hasErrors()) {
            return null;
        }

        return (

Please correct any errors to proceed.

        );
    },

    renderForm() {
        const buttonClass = purebem.many(block('button', ['submit']), 'button-primary');
        const { title, start, end, errors, isSubmitting } = this.state;
        const hasErrors = this.hasErrors();

        return (
            <form className={ block('form') } onSubmit={ this.handleSubmit } ref={ (form) => this.form = form }>

                    Project title
                    <InputField
                        name="title"
                        error={ errors.title }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        value={ title.value } />

                    Start date
                    <InputField
                        name="start"
                        error={ errors.start }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        placeholder="yyyymmdd"
                        value={ start.value } />

                    End date
                    <InputField
                        name="end"
                        error={ errors.end || errors.order }
                        onBlur={ this.handleBlur }
                        onChange={ this.handleChange }
                        placeholder="yyyymmdd"
                        value={ end.value } />

                <ProjectSites
                    sites={ this.state.sites }
                    onChange={ (i) => this.handleSiteChange(i) }
                    onRemove={ (i) => this.handleSiteRemove(i) } />
                <ButtonSwitch
                    className={ block('switch', ['maplock']) }
                    isActive={ this.state.isLocked }
                    onClick={ () => this.handleSwitch('maplock') }
                    options={ this.state.toggleMapLock } />

Unlock the map to locate and mark your ringing sites. Geolocation data may be used for statistics.

                <ButtonSwitch
                    className={ block('switch', ['privacy']) }
                    isActive={ this.state.isPublic }
                    onClick={ () => this.handleSwitch('privacy') }
                    options={ this.state.togglePrivacy } />
                { this.renderPrivacyInfo() }
                { this.renderErrorInfo() }

                    <button type="submit" className={ buttonClass } disabled={ hasErrors || isSubmitting }>Create</button>
                    <button type="button" className={ block('button', ['reset']) } onClick={ this.handleReset }>Reset</button>

            </form>
        );
    },

    renderSuccess() {
        if (!this.state.showSuccess) {
            return null;
        }

        return (
            <Modal>
                <ProjectSuccess
                    projectId={ this.state.projectId }
                    onClose={ this.handleModalClose } />
            </Modal>
        );
    },

    render() {
        return (

                    <ProjectMap
                        onClick={ this.handleSiteAdd }
                        sites={ this.state.sites }
                        unlocked={ !this.state.isLocked } />
                    <ContentBox background="white" shadow={ true }>
                        { this.renderForm() }
                    </ContentBox>

                { this.renderSuccess() }

        );
    }

});

export default CreateView;
<|endoftext|>


<commit_before>var ical = require('../../../lib/plugin/in/ical.js'),
    nock = require('nock'),
    here = require('here').here;

describe('input plugin: ical', function(){
  var mockRss = "http://test.com/ics";

  beforeEach(function() {
    var testData = here(/*
      BEGIN:VCALENDAR
      PRODID:-//hideack//evac//EN
      VERSION:2.0
      CALSCALE:GREGORIAN
      METHOD:PUBLISH
      X-WR-CALNAME:evac test sample calendar
      X-WR-TIMEZONE:Asia/Tokyo
      BEGIN:VEVENT
      DTSTART:__testdate__T235500Z
      DTSTAMP:__testdate__T235500Z
      CREATED:__testdate__T235500Z
      LAST-MODIFIED:__testdate__T235500Z
      DTEND:__testdate__T100000Z
      SUMMARY:meeting
      ORGANIZER:hideack
      UID:abc@hideack
      DESCRIPTION:meeting
      LOCATION:
      SEQUENCE:1
      STATUS:CONFIRMED
      TRANSP:OPAQUE
      END:VEVENT
      END:VCALENDAR

    */
    ).unindent();

    var icalData = testData.replace(/__testdate__/g, "20141013");
    nock("http://test.com").get('/ics').reply(200, icalData);
  });

  it('should be able to read from iCal format file.', function(done){
    ical.load({url:"http://test.com/ics", within:24}, function(error, outputs){
      outputs[0].should.be.equal('meeting - Tue Oct 14 2014 08:55:00 GMT+0900 (JST)');
      done();
    });
  });

  it('should be able not much schedule', function(done){
    ical.load({url:"http://test.com/ics", within:1}, function(error, outputs){
      outputs.length.should.be.equal(0);
      done();
    });
  });
});
<commit_msg>Fix test.<commit_after>var ical = require('../../../lib/plugin/in/ical.js'),
    sprintf = require("sprintf-js").sprintf,
    nock = require('nock'),
    here = require('here').here;

describe('input plugin: ical', function(){
  var mockRss = "http://test.com/ics";

  beforeEach(function() {
    var testData = here(/*
      BEGIN:VCALENDAR
      PRODID:-//hideack//evac//EN
      VERSION:2.0
      CALSCALE:GREGORIAN
      METHOD:PUBLISH
      X-WR-CALNAME:evac test sample calendar
      X-WR-TIMEZONE:Asia/Tokyo
      BEGIN:VEVENT
      DTSTART:__testdate__T145500Z
      DTSTAMP:__testdate__T145500Z
      CREATED:__testdate__T145500Z
      LAST-MODIFIED:__testdate__T145500Z
      DTEND:__testdate__T100000Z
      SUMMARY:meeting summary
      ORGANIZER:hideack
      UID:abc@hideack
      DESCRIPTION:meeting
      LOCATION:
      SEQUENCE:1
      STATUS:CONFIRMED
      TRANSP:OPAQUE
      END:VEVENT
      END:VCALENDAR

    */
    ).unindent();

    var date = new Date();
    var formatDate = sprintf("%4d%02d%02d", date.getFullYear(), date.getMonth() + 1, date.getDate());
    var icalData = testData.replace(/__testdate__/g, "" + formatDate);
    nock("http://test.com").get('/ics').reply(200, icalData);
  });

  it('should be able to read from iCal format file.', function(done){
    ical.load({url:"http://test.com/ics", within:24}, function(error, outputs){
      outputs[0].should.match(/meeting summary -/);
      done();
    });
  });

  it('should be able not much schedule', function(done){
    ical.load({url:"http://test.com/ics", within:1}, function(error, outputs){
      outputs.length.should.be.equal(0);
      done();
    });
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import purebem from 'purebem';
import promise from 'promise';
import moment from 'moment';

import filter from 'lodash.filter';
import uniqBy from 'lodash.uniqby';
import forEach from 'lodash.foreach';

import {
    delayAction,
    getStatus,
    isEmpty,
    sortByKey
} from 'app/utils';

import firebaseRef from 'app/firebaseRef';

import ContentBox from 'app/components/ContentBox';
import InputField from 'app/components/InputField';
import ViewHeader from 'app/components/ViewHeader';

const block = purebem.of('search-view');

const SearchView = React.createClass({

    getInitialState() {
        return {
            isLoading: false,
            needle: '',
            results: []
        };
    },

    componentWillMount() {
        this.projectsRef = firebaseRef.child('projects').orderByChild('isPublic').equalTo(true);
    },

    getMatch(sample) {
        const pattern = new RegExp(this.state.needle, 'i');
        return pattern.test(sample);
    },

    getList(snap) {
        let arr = [], obj = {};
        snap.forEach(child => {
            obj = child.val();
            obj.status = getStatus(obj.dateStart, obj.dateEnd);
            obj.projectId = child.key();

            if (this.getMatch(obj.title)) {
                arr.push(obj);
            }

            if (!!obj.sites) {
                forEach(obj.sites, site => {
                    if (this.getMatch(site.name)) {
                        arr.push(obj);
                    }
                });
            }
        });
        return arr;
    },

    handleSearch() {
        let results = [];

        if (isEmpty(this.state.needle)) {
            this.setState({ results, isLoading: false });
            return;
        }

        const a = moment();
        const projects = new promise((resolve, reject) => {
            this.projectsRef.once('value', (snap) => {
                resolve(this.getList(snap));
            });
        });

        projects.then(list => {
            const b = moment();
            const loadTime = b.diff(a, 'seconds', true);
            results = uniqBy(list, 'projectId');
            sortByKey(results, 'status');
            this.setState({ results, loadTime, isLoading: false });
        });
    },

    handleChange(evt) {
        const needle = evt.target.value;
        this.setState({ needle, isLoading: !isEmpty(needle) });
        delayAction(() => this.handleSearch());
    },

    renderResults() {
        const data = this.state.results;
        const headers = ['avatar', 'title', 'ownerId', 'status', 'join'];

        if (data.length === 0) {
            return null;
        }

        return (
            <ContentBox className={ block('results') }>[results]</ContentBox>
        );
    },

    renderMeta() {
        const count = this.state.results.length;
        const match = count > 1 ? 'results' : 'result';

        if (count === 0) {
            return null;
        }

        return (

{ count } { match } ({ this.state.loadTime } seconds).

        );
    },

    renderEmpty() {
        if (this.state.results.length || isEmpty(this.state.needle) || this.state.isLoading) {
            return null;
        }

        return (

Nothing matched: { this.state.needle }

        );
    },

    render() {
        return (

                    <ViewHeader title="Find & Join">

Here you can search for projects to join.

                        <InputField
                            autoFocus={ true }
                            iconClass="icon-search"
                            iconClick={ this.handleSearch }
                            isLoading={ this.state.isLoading }
                            onChange={ this.handleChange }
                            placeholder="Project title, site name, etc."
                            value={ this.state.needle } />
                        { this.renderEmpty() }
                        { this.renderMeta() }
                    </ViewHeader>
                    { this.renderResults() }

        );
    }

});

export default SearchView;
<commit_msg>list results in Table<commit_after>import React from 'react';
import purebem from 'purebem';
import promise from 'promise';
import moment from 'moment';

import filter from 'lodash.filter';
import uniqBy from 'lodash.uniqby';
import forEach from 'lodash.foreach';

import {
    delayAction,
    getStatus,
    isEmpty,
    sortByKey
} from 'app/utils';

import firebaseRef from 'app/firebaseRef';

import ContentBox from 'app/components/ContentBox';
import InputField from 'app/components/InputField';
import ViewHeader from 'app/components/ViewHeader';
import Table from 'app/components/Table';

const block = purebem.of('search-view');

const SearchView = React.createClass({

    getInitialState() {
        return {
            isLoading: false,
            needle: '',
            results: []
        };
    },

    componentWillMount() {
        this.projectsRef = firebaseRef.child('projects').orderByChild('isPublic').equalTo(true);
    },

    getMatch(sample) {
        const pattern = new RegExp(this.state.needle, 'i');
        return pattern.test(sample);
    },

    getList(snap) {
        let arr = [], obj = {};
        snap.forEach(child => {
            obj = child.val();
            obj.status = getStatus(obj.dateStart, obj.dateEnd);
            obj.id = child.key();

            if (this.getMatch(obj.title)) {
                arr.push(obj);
            }

            if (!!obj.sites) {
                forEach(obj.sites, site => {
                    if (this.getMatch(site.name)) {
                        arr.push(obj);
                    }
                });
            }
        });
        return arr;
    },

    handleSearch() {
        let results = [];

        if (isEmpty(this.state.needle)) {
            this.setState({ results, isLoading: false });
            return;
        }

        const a = moment();
        const projects = new promise((resolve, reject) => {
            this.projectsRef.once('value', (snap) => {
                resolve(this.getList(snap));
            });
        });

        projects.then(list => {
            const b = moment();
            const loadTime = b.diff(a, 'seconds', true);
            results = uniqBy(list, 'id');
            sortByKey(results, 'status');
            this.setState({ results, loadTime, isLoading: false });
        });
    },

    handleChange(evt) {
        const needle = evt.target.value;
        this.setState({ needle, isLoading: !isEmpty(needle) });
        delayAction(() => this.handleSearch());
    },

    renderResults() {
        const data = this.state.results;
        const headers = ['avatar', 'title', 'ownerId', 'status', 'join'];

        if (data.length === 0) {
            return null;
        }

        return (
            <ContentBox className={ block('results') }>

            </ContentBox>
        );
    },

    renderMeta() {
        const count = this.state.results.length;
        const match = count > 1 ? 'results' : 'result';

        if (count === 0) {
            return null;
        }

        return (

{ count } { match } ({ this.state.loadTime } seconds).

        );
    },

    renderEmpty() {
        if (this.state.results.length || isEmpty(this.state.needle) || this.state.isLoading) {
            return null;
        }

        return (

Nothing matched: { this.state.needle }

        );
    },

    render() {
        return (

                    <ViewHeader title="Find & Join">

Here you can search for projects to join.

                        <InputField
                            autoFocus={ true }
                            iconClass="icon-search"
                            iconClick={ this.handleSearch }
                            isLoading={ this.state.isLoading }
                            onChange={ this.handleChange }
                            placeholder="Project title, site name, etc."
                            value={ this.state.needle } />
                        { this.renderEmpty() }
                        { this.renderMeta() }
                    </ViewHeader>
                    { this.renderResults() }

        );
    }

});

export default SearchView;
<|endoftext|>


<commit_before>var requirejs = require('requirejs');
var path = require('path');

require('backbone').$ = require('jquery');

requirejs.config({
  baseUrl: path.join(process.cwd(), 'app')
});

requirejs.config(requirejs('config'));
<commit_msg>Add global vars to server-side test helper<commit_after>var requirejs = require('requirejs');
var path = require('path');

require('backbone').$ = require('jquery');

requirejs.config({
  baseUrl: path.join(process.cwd(), 'app')
});

requirejs.config(requirejs('config'));

global._ = require('lodash');
global.isServer = true;
global.config = {};<|endoftext|>


<commit_before>'use strict';

/**
 * A lexical rule.
 */
var LexerRule = {
	/**
	 * The name of the lexical category that this rule matches
	 */
	name: '',

	/**
	 * The regular expression used for matching
	 */
	regex: false,
	/**
	 * A pre-compiled pattern object, kept to save processing time
	 */
	pattern: false,

	/**
	 * Instantiate a new lexical rule with a name and a regex
	 *
	 * @param name
	 *            a name
	 * @param regex
	 *            a regular expression
	 */
	LexerRule: function(name, regex) {
		this.name = name || '';
		this.regex = regex || '';
	},

	/**
	 * Get the category name
	 *
	 * @return the name of rule
	 */
	getName: function() {
		return this.name;
	},

	/**
	 * Get the regex defining the rule
	 *
	 * @return the regex
	 */
	getRegex: function() {
		return this.regex;
	},

	/**
	 * Return the pattern object. Create one if it hasn't been created already.
	 *
	 * @return the pattern object
	 */
	getPattern: function() {
		if (this.pattern == null) {
			this.pattern = new RegExp(this.regex);
		}
		return this.pattern;
	},

	/**
	 * Return a string representation of the rule
	 */
	toString: function() {
		return "[" + this.name + "]";
	}
}

module.exports = LexerRule;<commit_msg>Update lexerRule to js object<commit_after>'use strict';

/**
 * Instantiate a new lexical rule with a name and a regex
 *
 * @param name
 *            a name
 * @param regex
 *            a regular expression
 */
var LexerRule = function (name, regex) {
	/**
	 * The name of the lexical category that this rule matches
	 */
	var name =  name || '';

	/**
	 * The regular expression used for matching
	 */
	var regex = regex || false;
	/**
	 * A pre-compiled pattern object, kept to save processing time
	 */
	var pattern = false;

	/**
	 * Get the category name
	 *
	 * @return the name of rule
	 */
	function getName() {
		return this.name;
	}

	/**
	 * Get the regex defining the rule
	 *
	 * @return the regex
	 */
	function getRegex() {
		return this.regex;
	}

	/**
	 * Return the pattern object. Create one if it hasn't been created already.
	 *
	 * @return the pattern object
	 */
	function getPattern() {
		if (this.pattern == null) {
			this.pattern = new RegExp(this.regex);
		}
		return this.pattern;
	}

	/**
	 * Return a string representation of the rule
	 */
	function toString() {
		return "[" + this.name + "]";
	}
}

module.exports = LexerRule;<|endoftext|>


<commit_before>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.Object}
 * @param {!WebInspector.LayerTreeModel} model
 * @param {!TreeOutline} treeOutline
 */
WebInspector.LayerTree = function(model, treeOutline)
{
    WebInspector.Object.call(this);
    this._model = model;
    this._treeOutline = treeOutline;
    this._treeOutline.childrenListElement.addEventListener("mousemove", this._onMouseMove.bind(this), false);
    this._treeOutline.childrenListElement.addEventListener("mouseout", this._onMouseMove.bind(this), false);
    this._treeOutline.childrenListElement.addEventListener("contextmenu", this._onContextMenu.bind(this), true);
    this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._update.bind(this));
    this._lastHoveredNode = null;
}

/**
 * @enum {string}
 */
WebInspector.LayerTree.Events = {
    LayerHovered: "LayerHovered",
    LayerSelected: "LayerSelected"
}

WebInspector.LayerTree.prototype = {
    /**
     * @param {?WebInspector.Layer} layer
     */
    selectLayer: function(layer)
    {
        this.hoverLayer(null);
        var node = layer && this._treeOutline.getCachedTreeElement(layer);
        if (node)
            node.revealAndSelect(true);
        else if (this._treeOutline.selectedTreeElement)
            this._treeOutline.selectedTreeElement.deselect();
    },

    /**
     * @param {?WebInspector.Layer} layer
     */
    hoverLayer: function(layer)
    {
        var node = layer && this._treeOutline.getCachedTreeElement(layer);
        if (node === this._lastHoveredNode)
            return;
        if (this._lastHoveredNode)
            this._lastHoveredNode.setHovered(false);
        if (node)
            node.setHovered(true);
        this._lastHoveredNode = node;
    },

    _update: function()
    {
        var seenLayers = {};

        /**
         * @param {!WebInspector.Layer} layer
         * @this {WebInspector.LayerTree}
         */
        function updateLayer(layer)
        {
            var id = layer.id();
            if (seenLayers[id])
                console.assert(false, "Duplicate layer id: " + id);
            seenLayers[id] = true;
            var node = this._treeOutline.getCachedTreeElement(layer);
            var parent = layer === this._model.root() ? this._treeOutline : this._treeOutline.getCachedTreeElement(layer.parent());
            if (!parent)
                console.assert(false, "Parent is not in the tree");
            if (!node) {
                node = new WebInspector.LayerTreeElement(this, layer);
                parent.appendChild(node);
            } else {
                if (node.parent !== parent) {
                    node.parent.removeChild(node);
                    parent.appendChild(node);
                }
                node._update();
            }
        }
        if (this._model.root())
            this._model.forEachLayer(updateLayer.bind(this), this._model.root());
        // Cleanup layers that don't exist anymore from tree.
        for (var node = /** @type {!TreeElement|!TreeOutline|null} */(this._treeOutline.children[0]); node && !node.root;) {
            if (seenLayers[node.representedObject.id()]) {
                node = node.traverseNextTreeElement(false);
            } else {
                var nextNode = node.nextSibling || node.parent;
                node.parent.removeChild(node);
                if (node === this._lastHoveredNode)
                    this._lastHoveredNode = null;
                node = nextNode;
            }
        }
    },

    /**
     * @param {?Event} event
     */
    _onMouseMove: function(event)
    {
        var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
        if (node === this._lastHoveredNode)
            return;
        this.dispatchEventToListeners(WebInspector.LayerTree.Events.LayerHovered, node && node.representedObject ? {layer: node.representedObject} : null);
    },

    /**
     * @param {!WebInspector.LayerTreeElement} node
     */
    _selectedNodeChanged: function(node)
    {
        var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
        this.dispatchEventToListeners(WebInspector.LayerTree.Events.LayerSelected, {layer: layer});
    },

    /**
     * @param {?Event} event
     */
    _onContextMenu: function(event)
    {
        var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
        if (!node || !node.representedObject)
            return;
        var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
        if (!layer)
            return;
        var domNode = layer.nodeForSelfOrAncestor();
        if (!domNode)
            return;
        var contextMenu = new WebInspector.ContextMenu(event);
        contextMenu.appendApplicableItems(domNode);
        contextMenu.show();
    },

    __proto__: WebInspector.Object.prototype
}

/**
  * @constructor
  * @param {!WebInspector.LayerTree} tree
  * @param {!WebInspector.Layer} layer
  * @extends {TreeElement}
  */
WebInspector.LayerTreeElement = function(tree, layer)
{
    TreeElement.call(this, "", layer);
    this._layerTree = tree;
    this._update();
}

WebInspector.LayerTreeElement.prototype = {
    onattach: function()
    {
        var selection = document.createElement("div");
        selection.className = "selection";
        this.listItemElement.insertBefore(selection, this.listItemElement.firstChild);
    },

    _update: function()
    {
        var layer = /** @type {!WebInspector.Layer} */ (this.representedObject);
        var node = layer.nodeForSelfOrAncestor();
        var title = document.createDocumentFragment();
        title.createChild("div", "selection");
        title.appendChild(document.createTextNode(node ? WebInspector.DOMPresentationUtils.simpleSelector(node) : "#" + layer.id()));
        var details = title.createChild("span", "dimmed");
        details.textContent = WebInspector.UIString(" (%d × %d)", layer.width(), layer.height());
        this.title = title;
    },

    /**
     * @override
     * @return {boolean}
     */
    onselect: function()
    {
        this._layerTree._selectedNodeChanged(this);
        return false;
    },

    /**
     * @param {boolean} hovered
     */
    setHovered: function(hovered)
    {
        this.listItemElement.classList.toggle("hovered", hovered);
    },

    __proto__: TreeElement.prototype
}
<commit_msg>Remove layers above content root from LayerTree.<commit_after>/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @constructor
 * @extends {WebInspector.Object}
 * @param {!WebInspector.LayerTreeModel} model
 * @param {!TreeOutline} treeOutline
 */
WebInspector.LayerTree = function(model, treeOutline)
{
    WebInspector.Object.call(this);
    this._model = model;
    this._treeOutline = treeOutline;
    this._treeOutline.childrenListElement.addEventListener("mousemove", this._onMouseMove.bind(this), false);
    this._treeOutline.childrenListElement.addEventListener("mouseout", this._onMouseMove.bind(this), false);
    this._treeOutline.childrenListElement.addEventListener("contextmenu", this._onContextMenu.bind(this), true);
    this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeChanged, this._update.bind(this));
    this._lastHoveredNode = null;
}

/**
 * @enum {string}
 */
WebInspector.LayerTree.Events = {
    LayerHovered: "LayerHovered",
    LayerSelected: "LayerSelected"
}

WebInspector.LayerTree.prototype = {
    /**
     * @param {?WebInspector.Layer} layer
     */
    selectLayer: function(layer)
    {
        this.hoverLayer(null);
        var node = layer && this._treeOutline.getCachedTreeElement(layer);
        if (node)
            node.revealAndSelect(true);
        else if (this._treeOutline.selectedTreeElement)
            this._treeOutline.selectedTreeElement.deselect();
    },

    /**
     * @param {?WebInspector.Layer} layer
     */
    hoverLayer: function(layer)
    {
        var node = layer && this._treeOutline.getCachedTreeElement(layer);
        if (node === this._lastHoveredNode)
            return;
        if (this._lastHoveredNode)
            this._lastHoveredNode.setHovered(false);
        if (node)
            node.setHovered(true);
        this._lastHoveredNode = node;
    },

    _update: function()
    {
        var seenLayers = {};

        /**
         * @param {!WebInspector.Layer} layer
         * @this {WebInspector.LayerTree}
         */
        function updateLayer(layer)
        {
            var id = layer.id();
            if (seenLayers[id])
                console.assert(false, "Duplicate layer id: " + id);
            seenLayers[id] = true;
            var node = this._treeOutline.getCachedTreeElement(layer);
            var parent = layer === this._model.contentRoot() ? this._treeOutline : this._treeOutline.getCachedTreeElement(layer.parent());
            if (!parent)
                console.assert(false, "Parent is not in the tree");
            if (!node) {
                node = new WebInspector.LayerTreeElement(this, layer);
                parent.appendChild(node);
            } else {
                if (node.parent !== parent) {
                    node.parent.removeChild(node);
                    parent.appendChild(node);
                }
                node._update();
            }
        }
        if (this._model.contentRoot())
            this._model.forEachLayer(updateLayer.bind(this), this._model.contentRoot());
        // Cleanup layers that don't exist anymore from tree.
        for (var node = /** @type {!TreeElement|!TreeOutline|null} */(this._treeOutline.children[0]); node && !node.root;) {
            if (seenLayers[node.representedObject.id()]) {
                node = node.traverseNextTreeElement(false);
            } else {
                var nextNode = node.nextSibling || node.parent;
                node.parent.removeChild(node);
                if (node === this._lastHoveredNode)
                    this._lastHoveredNode = null;
                node = nextNode;
            }
        }
    },

    /**
     * @param {?Event} event
     */
    _onMouseMove: function(event)
    {
        var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
        if (node === this._lastHoveredNode)
            return;
        this.dispatchEventToListeners(WebInspector.LayerTree.Events.LayerHovered, node && node.representedObject ? {layer: node.representedObject} : null);
    },

    /**
     * @param {!WebInspector.LayerTreeElement} node
     */
    _selectedNodeChanged: function(node)
    {
        var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
        this.dispatchEventToListeners(WebInspector.LayerTree.Events.LayerSelected, {layer: layer});
    },

    /**
     * @param {?Event} event
     */
    _onContextMenu: function(event)
    {
        var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
        if (!node || !node.representedObject)
            return;
        var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
        if (!layer)
            return;
        var domNode = layer.nodeForSelfOrAncestor();
        if (!domNode)
            return;
        var contextMenu = new WebInspector.ContextMenu(event);
        contextMenu.appendApplicableItems(domNode);
        contextMenu.show();
    },

    __proto__: WebInspector.Object.prototype
}

/**
  * @constructor
  * @param {!WebInspector.LayerTree} tree
  * @param {!WebInspector.Layer} layer
  * @extends {TreeElement}
  */
WebInspector.LayerTreeElement = function(tree, layer)
{
    TreeElement.call(this, "", layer);
    this._layerTree = tree;
    this._update();
}

WebInspector.LayerTreeElement.prototype = {
    onattach: function()
    {
        var selection = document.createElement("div");
        selection.className = "selection";
        this.listItemElement.insertBefore(selection, this.listItemElement.firstChild);
    },

    _update: function()
    {
        var layer = /** @type {!WebInspector.Layer} */ (this.representedObject);
        var node = layer.nodeForSelfOrAncestor();
        var title = document.createDocumentFragment();
        title.createChild("div", "selection");
        title.appendChild(document.createTextNode(node ? WebInspector.DOMPresentationUtils.simpleSelector(node) : "#" + layer.id()));
        var details = title.createChild("span", "dimmed");
        details.textContent = WebInspector.UIString(" (%d × %d)", layer.width(), layer.height());
        this.title = title;
    },

    /**
     * @override
     * @return {boolean}
     */
    onselect: function()
    {
        this._layerTree._selectedNodeChanged(this);
        return false;
    },

    /**
     * @param {boolean} hovered
     */
    setHovered: function(hovered)
    {
        this.listItemElement.classList.toggle("hovered", hovered);
    },

    __proto__: TreeElement.prototype
}
<|endoftext|>


<commit_before>var common = require('./common'),
    util = require('util'),
    TrapperKeeper = module.exports = exports,
    Resource = require('./resource');

/**
 * Setup possible `engines`
 */
TrapperKeeper.Engines = require('./engines'),

/**
 * Define methods that are avaliable
 */
TrapperKeeper.Methods = [
  'ALL',
  'GET',
  'FIND',
  'SAVE',
  'CREATE',
  'UPDATE',
  'DESTROY'
];

/**
 * Define a connection
 *
 * @param {String} engine
 * @param {String} uri
 * @param {Number} port
 * @param {Object} options
 * @return {Engine}
 */
TrapperKeeper.Connect = function(/* [engine], [uri], [port], [options] */) {
  var args = Array.prototype.slice.call(arguments),
      options = {},
      engine,
      engineName;

  engine = Array.prototype.shift.call(args);

  if(!engine) {
    throw Error('Must specify an engine');
  }

  args.forEach(function(a) {
    switch (typeof(a)) {
      case 'number': options.port = parseInt(a, 10); break;
      case 'string': options.uri  = a; break;
      case 'object': options      = common.extend(a, options); break;
    }
  });

  engineName = common.capitalize(engine);
  var connection = new TrapperKeeper.Engines[engineName](options);

  return connection;
};<commit_msg>remove unneeded dependencies<commit_after>var common = require('./common'),
    TrapperKeeper = module.exports = exports;

/**
 * Setup possible `engines`
 */
TrapperKeeper.Engines = require('./engines'),

/**
 * Define methods that are avaliable
 */
TrapperKeeper.Methods = [
  'ALL',
  'GET',
  'FIND',
  'SAVE',
  'CREATE',
  'UPDATE',
  'DESTROY'
];

/**
 * Define a connection
 *
 * @param {String} engine
 * @param {String} uri
 * @param {Number} port
 * @param {Object} options
 * @return {Engine}
 */
TrapperKeeper.Connect = function(/* [engine], [uri], [port], [options] */) {
  var args = Array.prototype.slice.call(arguments),
      options = {},
      engine,
      engineName;

  engine = Array.prototype.shift.call(args);

  if(!engine) {
    throw Error('Must specify an engine');
  }

  args.forEach(function(a) {
    switch (typeof(a)) {
      case 'number': options.port = parseInt(a, 10); break;
      case 'string': options.uri  = a; break;
      case 'object': options      = common.extend(a, options); break;
    }
  });

  engineName = common.capitalize(engine);
  var connection = new TrapperKeeper.Engines[engineName](options);

  return connection;
};<|endoftext|>


<commit_before>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/
/*jslint undef: true*/
/*
* Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/

var fs = require("fs");
var path = require("path");
var clone = require("clone");
var childProcess = require("child_process");
var colors = require("colors");
var log4js = require("log4js");
var coverage = require("../util/coverage");

// recursive folder search
function ArrowRecursive(config, args) {
    var k;
    this.logger = log4js.getLogger("ArrowRecursive");
    this.config = config;
    this.args = args;
    this.arrDescriptor = [];
    this.currentDir = process.cwd();
    this.recArgs = clone(this.args.argv.original);
    coverage.configure(config);

    //checking if we need to do colorless reporting.
    if (global.color === false) {
        colors.mode = "none";
    } else {
        if (!process.stdout.isTTY){
            colors.mode = "none";
        }
    }

    if (this.args.dimensions) {
        for (k in this.recArgs) {
            if (this.recArgs[k].indexOf("dimensions") !== -1) {
                this.recArgs[k] = "--dimensions=" + path.resolve(global.workingDirectory, this.args.dimensions);
            }
        }
    }

    if (this.args.routerProxyConfig) {
        for (k in this.recArgs) {
            if (this.recArgs[k].indexOf("routerProxyConfig") !== -1) {
                this.recArgs[k] = "--routerProxyConfig=" + path.resolve(global.workingDirectory, this.args.routerProxyConfig);
            }
        }
    }

    this.descriptorExecutionCount = 0;
    this.descriptorTotalCount = 0;
}

ArrowRecursive.prototype.runAllDescriptors = function (descriptors) {
    this.arrDescriptor = descriptors;
    this.descriptorTotalCount = this.arrDescriptor.length;

    if (this.arrDescriptor.length > 0) {
        this.runSingleDescriptor();
    } else {
        this.logger.error("No descriptors to run.");
    }
};

ArrowRecursive.prototype.runSingleDescriptor = function () {
    var self = this,
        filePath = this.arrDescriptor[this.descriptorExecutionCount],
        fileName,
        testFolder,
        testArgs,
        arrowCmd;

    self.logger.info("Running Test Descriptor Path : " + filePath);
    testFolder = path.dirname(filePath);
    fileName = path.basename(filePath);

    self.logger.info("Switching to path: " + testFolder);
    process.chdir(testFolder);

    testArgs = clone(self.recArgs);

    testArgs.unshift(fileName); // to make sure the first one is the headless param we want
    testArgs.push("--arrowChildProcess=true");

    self.logger.trace("testargs :" + testArgs);
    arrowCmd = childProcess.fork(global.appRoot + "/index.js", testArgs);
    //NOT DOING EXIT, As it does not waits for last browser to close. NEED to revisit this later, as child process's may still linger in system memory
//    arrowCmd.on('exit',function(msg){
//        self.descriptorExecutionCount++;
//        if(self.descriptorExecutionCount < self.descriptorTotalCount){
//            self.runSingleDescriptor(self.descriptorExecutionCount);
//        }else{
//             console.log("All done");
//               console.log("Report Gathering");
//        }
//    });

    arrowCmd.on('message', function (msg) {
        self.logger.trace("Message Received :" + msg);
        if (msg.SessionFactory === "Done") {
            if (msg.covReport) {
                global.coverageMap.push(msg.covReport);
            }

            if (msg.reportFile) {
                global.reportMap.push({"desc" : filePath, "report" : msg.reportFile});
            }

            self.descriptorExecutionCount += 1;
            //revert back to initial working directory
            process.chdir(global.workingDirectory);
            self.logger.trace(self.descriptorExecutionCount + "<" +  self.descriptorTotalCount);
            if (self.descriptorExecutionCount < self.descriptorTotalCount) {
                self.runSingleDescriptor(self.descriptorExecutionCount);
            } else {
                process.chdir(global.workingDirectory);
                if (self.args.report) {
                    self.showRecursiveReport();
                } else {
                    self.tearDown();
                }
            }
        }
    });
};

ArrowRecursive.prototype.showRecursiveReport = function (currentCount) {
    var totalCount = 0,
        passCount = 0,
        failCount = 0,
        skipCount = 0,
        arrFailedDescriptors = {},
        reportPath,
        data,
        desc,
        rep,
        fail,
        i,
        k,
        x,
        ts,
        tmp,
        stats,
        val,
        arrReport,
        testJson,
        results,
        blnFail = false,
        self = this;

    this.logger.trace(this.arrDescriptor);

    for (i = 0; i < global.reportMap.length; i += 1) {
        data = JSON.parse(fs.readFileSync(global.reportMap[i].report.replace("xml", "json"), 'utf-8'));
        fail = 0;
        for (x in data) {
            rep = data[x];
            if (rep.scenario) {
                arrReport = rep.scenario;
            } else {
                arrReport = rep.results;
            }
            if (arrReport) {
                for (j = 0; j < arrReport.length; j = j + 1) {
                    if (rep.scenario) {
                        results = arrReport[j].results;
                        for (k = 0; k < results.length; k = k + 1) {
                            testJson =  results[k];
                            if (testJson.type === "report") {
                                totalCount += testJson.total;
                                fail += testJson.failed;
                                skipCount += testJson.ignored;
                            }
                        }
                    } else {
                        testJson = arrReport[j];
                        if (testJson.type === "report") {
                            totalCount += testJson.total;
                            fail += testJson.failed;
                            skipCount += testJson.ignored;
                        }
                    }
                }
            }
        }

        if (fail > 0) {
            arrFailedDescriptors[global.reportMap[i].desc] = fail;
            failCount += fail;
            blnFail = true;
        }

    }

    passCount = totalCount - failCount - skipCount;
    console.log("********************************************".bold.magenta.toString());
    console.log("Consolidated Test Report Summary".bold.magenta.toString());
    console.log("********************************************".bold.magenta.toString());

    console.log(("Total Number of Executed Tests  :" + totalCount).blue.toString());
    console.log(("Total Number of Passed Tests  : " + passCount).green.toString());
    console.log(("Total Number of Failed Tests  : " + failCount).red.toString());
    console.log(("Total Number of Skipped Tests  : " + skipCount).grey.toString());
    console.log("********************************************".bold.magenta.toString());

    if (blnFail) {
        console.log("List of Failed Test Descriptors".bold.magenta.toString());
        console.log("********************************************".bold.magenta.toString());
        for (k in arrFailedDescriptors) {
            console.log("Failed Descriptor Path : ".grey.toString() +  k.toString().red.toString());
            console.log("Total Number of Failed Tests : ".grey.toString() +  arrFailedDescriptors[k].toString().red.toString());
            console.log("--------------------------------------------".bold.magenta.toString());
        }
    }
    console.log();

    self.tearDown(failCount);
};

ArrowRecursive.prototype.tearDown = function(failCount) {
    var i, testExecutionTime;

    if (this.config.coverage) {
        //console.log(global.coverageMap);
        coverage.writeReportsFor(global.coverageMap, "coverage");

        //now deleting temp coverage files
        for (i = 0; i < global.coverageMap.length; i += 1) {
            fs.unlinkSync(global.coverageMap[i]);
        }
    }
    this.logger.trace("Final TearDown");
    testExecutionTime = (Date.now() - global.startTime);
    console.log(("Total Time of Execution :" + (testExecutionTime / 1000).toFixed(2) + " seconds").black.toString());
    console.log("********************************************".bold.magenta.toString());

    process.exit((this.config.exitCode && failCount) ? 1 : 0);
};

module.exports = ArrowRecursive;

<commit_msg>making report true by default, and changing formatting of total execution time.<commit_after>/*jslint forin:true sub:true anon:true, sloppy:true, stupid:true nomen:true, node:true continue:true*/
/*jslint undef: true*/
/*
* Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
* Copyrights licensed under the New BSD License.
* See the accompanying LICENSE file for terms.
*/

var fs = require("fs");
var path = require("path");
var clone = require("clone");
var childProcess = require("child_process");
var colors = require("colors");
var log4js = require("log4js");
var coverage = require("../util/coverage");

// recursive folder search
function ArrowRecursive(config, args) {
    var k;
    this.logger = log4js.getLogger("ArrowRecursive");
    this.config = config;
    this.args = args;
    this.arrDescriptor = [];
    this.currentDir = process.cwd();
    this.recArgs = clone(this.args.argv.original);

    // Making report param true by default
    if (this.args.report === undefined && this.config.report) {
        this.recArgs.push("--report=true");
    }

    coverage.configure(config);

    //checking if we need to do colorless reporting.
    if (global.color === false) {
        colors.mode = "none";
    } else {
        if (!process.stdout.isTTY){
            colors.mode = "none";
        }
    }

    if (this.args.dimensions) {
        for (k in this.recArgs) {
            if (this.recArgs[k].indexOf("dimensions") !== -1) {
                this.recArgs[k] = "--dimensions=" + path.resolve(global.workingDirectory, this.args.dimensions);
            }
        }
    }

    if (this.args.routerProxyConfig) {
        for (k in this.recArgs) {
            if (this.recArgs[k].indexOf("routerProxyConfig") !== -1) {
                this.recArgs[k] = "--routerProxyConfig=" + path.resolve(global.workingDirectory, this.args.routerProxyConfig);
            }
        }
    }

    this.descriptorExecutionCount = 0;
    this.descriptorTotalCount = 0;
}

ArrowRecursive.prototype.runAllDescriptors = function (descriptors) {
    this.arrDescriptor = descriptors;
    this.descriptorTotalCount = this.arrDescriptor.length;

    if (this.arrDescriptor.length > 0) {
        this.runSingleDescriptor();
    } else {
        this.logger.error("No descriptors to run.");
    }
};

ArrowRecursive.prototype.runSingleDescriptor = function () {
    var self = this,
        filePath = this.arrDescriptor[this.descriptorExecutionCount],
        fileName,
        testFolder,
        testArgs,
        arrowCmd;

    self.logger.info("Running Test Descriptor Path : " + filePath);
    testFolder = path.dirname(filePath);
    fileName = path.basename(filePath);

    self.logger.info("Switching to path: " + testFolder);
    process.chdir(testFolder);

    testArgs = clone(self.recArgs);

    testArgs.unshift(fileName); // to make sure the first one is the headless param we want
    testArgs.push("--arrowChildProcess=true");

    self.logger.trace("testargs :" + testArgs);
    arrowCmd = childProcess.fork(global.appRoot + "/index.js", testArgs);
    //NOT DOING EXIT, As it does not waits for last browser to close. NEED to revisit this later, as child process's may still linger in system memory
//    arrowCmd.on('exit',function(msg){
//        self.descriptorExecutionCount++;
//        if(self.descriptorExecutionCount < self.descriptorTotalCount){
//            self.runSingleDescriptor(self.descriptorExecutionCount);
//        }else{
//             console.log("All done");
//               console.log("Report Gathering");
//        }
//    });

    arrowCmd.on('message', function (msg) {
        self.logger.trace("Message Received :" + msg);
        if (msg.SessionFactory === "Done") {
            if (msg.covReport) {
                global.coverageMap.push(msg.covReport);
            }

            if (msg.reportFile) {
                global.reportMap.push({"desc" : filePath, "report" : msg.reportFile});
            }

            self.descriptorExecutionCount += 1;
            //revert back to initial working directory
            process.chdir(global.workingDirectory);
            self.logger.trace(self.descriptorExecutionCount + "<" +  self.descriptorTotalCount);
            if (self.descriptorExecutionCount < self.descriptorTotalCount) {
                self.runSingleDescriptor(self.descriptorExecutionCount);
            } else {
                process.chdir(global.workingDirectory);
                if (self.args.report) {
                    self.showRecursiveReport();
                } else {
                    self.tearDown();
                }
            }
        }
    });
};

ArrowRecursive.prototype.showRecursiveReport = function (currentCount) {
    var totalCount = 0,
        passCount = 0,
        failCount = 0,
        skipCount = 0,
        arrFailedDescriptors = {},
        reportPath,
        data,
        desc,
        rep,
        fail,
        i,
        k,
        x,
        ts,
        tmp,
        stats,
        val,
        arrReport,
        testJson,
        results,
        blnFail = false,
        self = this;

    this.logger.trace(this.arrDescriptor);

    for (i = 0; i < global.reportMap.length; i += 1) {
        data = JSON.parse(fs.readFileSync(global.reportMap[i].report.replace("xml", "json"), 'utf-8'));
        fail = 0;
        for (x in data) {
            rep = data[x];
            if (rep.scenario) {
                arrReport = rep.scenario;
            } else {
                arrReport = rep.results;
            }
            if (arrReport) {
                for (j = 0; j < arrReport.length; j = j + 1) {
                    if (rep.scenario) {
                        results = arrReport[j].results;
                        for (k = 0; k < results.length; k = k + 1) {
                            testJson =  results[k];
                            if (testJson.type === "report") {
                                totalCount += testJson.total;
                                fail += testJson.failed;
                                skipCount += testJson.ignored;
                            }
                        }
                    } else {
                        testJson = arrReport[j];
                        if (testJson.type === "report") {
                            totalCount += testJson.total;
                            fail += testJson.failed;
                            skipCount += testJson.ignored;
                        }
                    }
                }
            }
        }

        if (fail > 0) {
            arrFailedDescriptors[global.reportMap[i].desc] = fail;
            failCount += fail;
            blnFail = true;
        }

    }

    passCount = totalCount - failCount - skipCount;
    console.log("********************************************".bold.magenta.toString());
    console.log("Consolidated Test Report Summary".bold.magenta.toString());
    console.log("********************************************".bold.magenta.toString());

    console.log(("Total Number of Executed Tests  :" + totalCount).blue.toString());
    console.log(("Total Number of Passed Tests  : " + passCount).green.toString());
    console.log(("Total Number of Failed Tests  : " + failCount).red.toString());
    console.log(("Total Number of Skipped Tests  : " + skipCount).grey.toString());
    console.log("********************************************".bold.magenta.toString());

    if (blnFail) {
        console.log("List of Failed Test Descriptors".bold.magenta.toString());
        console.log("********************************************".bold.magenta.toString());
        for (k in arrFailedDescriptors) {
            console.log("Failed Descriptor Path : ".grey.toString() +  k.toString().red.toString());
            console.log("Total Number of Failed Tests : ".grey.toString() +  arrFailedDescriptors[k].toString().red.toString());
            console.log("--------------------------------------------".bold.magenta.toString());
        }
    }
    console.log();

    self.tearDown(failCount);
};

ArrowRecursive.prototype.tearDown = function(failCount) {
    var i, testExecutionTime;

    if (this.config.coverage) {
        //console.log(global.coverageMap);
        coverage.writeReportsFor(global.coverageMap, "coverage");

        //now deleting temp coverage files
        for (i = 0; i < global.coverageMap.length; i += 1) {
            fs.unlinkSync(global.coverageMap[i]);
        }
    }
    this.logger.trace("Final TearDown");
    testExecutionTime = (Date.now() - global.startTime);
    console.log(("Total Time of Execution :" + (testExecutionTime / 1000).toFixed(2) + " seconds").inverse.toString());
    process.exit((this.config.exitCode && failCount) ? 1 : 0);
};

module.exports = ArrowRecursive;

<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;
var classes = require('../utils/classes');

module.exports = Entity;

/**
 * Base class for entities.
 * @constructor
 * @memberof module:back4app/entity/models
 * @example
 * var entity = new Entity();
 */
function Entity() {}

/**
 * This is a read-only property to get the general Entity Class of the current
 * Entity Class.
 * @type {Class}
 * @example
 * var generalAttributes = SpecificEntity.General.attributes;
 */
Entity.General = null;

Object.defineProperty(Entity, 'General', {
  get: function () {
    return null;
  },
  set: function () {
    throw new Error('General cannot be changed');
  }
});

/**
 * This is a dictionary with the Entity's attributes.
 * @type {Dictionary}
 */
Entity.attributes = {};

/**
 * This is a dictionary with the Entity's methods.
 * @type {Dictionary}
 */
Entity.methods = {};

/**
 * Private function used to get the specify function specific for the current
 * Entity class.
 * @memberof module:back4app/entity/models.Entity
 * @param {Class} CurrentEntity The currentEntity for which the specify function
 * will be got.
 * @returns {Function} The specify function.
 * @private
 */
var _getSpecifyFunction = function (CurrentEntity) {
  return function (specification) {
    function SpecificEntity() {}

    classes.generalize(CurrentEntity, SpecificEntity);

    Object.defineProperty(SpecificEntity, 'General', {
      get: function () {
        return CurrentEntity;
      },
      set: function () {
        throw new Error('General cannot be changed');
      }
    });

    SpecificEntity.attributes = {};
    SpecificEntity.methods = {};

    if (specification) {
      if (specification.attributes) {
        SpecificEntity.attributes = specification.attributes;
      }

      if (specification.methods) {
        SpecificEntity.methods = specification.methods;
      }
    }

    SpecificEntity.specify = _getSpecifyFunction(SpecificEntity);
    SpecificEntity.new = _getNewFunction(SpecificEntity);

    Object.defineProperty(SpecificEntity.prototype, 'Entity', {
      get: function () {
        return SpecificEntity;
      },
      set: function () {
        throw new Error('Entity cannot be changed');
      }
    });

    return SpecificEntity;
  };
};

/**
 * Creates a new Entity Class by specifying a general one.
 * @function
 * @param {Object} specification The new Entity specification.
 * @returns {Class} The new Entity Class.
 */
Entity.specify = _getSpecifyFunction(Entity);

/**
 * Private function used to get the new function specific for the current Entity
 * class.
 * @memberof module:back4app/entity/models.Entity
 * @param {Class} CurrentEntity The current entity class for which the new
 * function will be created.
 * @returns {Function} The new function.
 * @private
 */
var _getNewFunction = function (CurrentEntity) {
  return function (entity) {
    var EntityClass = CurrentEntity;
    if (entity) {
      expect(entity).to.be.a('string');
      try {
        EntityClass = require('../../../tests/unit/back/models/' + entity);
      }
      catch (e) {
        throw new Error('Cannot find Entity \'' + entity + '\'');
      }
    }

    return function () {
      return new EntityClass();
    };
  };
};

/**
 * Returns a function that creates new instances of an Entity Class.
 * @function
 * @param {String} entity The Entity Class of which the new instances will be
 * created. If the parameter is not given, the function will create instances of
 * the current Entity Class.
 * @returns {Function}
 * @example
 * var c1NewFunction = Entity.new('C1');
 * var c1 = c1NewFunction();
 */
Entity.new = _getNewFunction(Entity);

/**
 * This is a read-only property to get the Entity Class of an instance.
 * @type {Class}
 * @example
 * var entity = new Entity();
 * console.log(entity.Entity == Entity) // Logs true
 */
Entity.prototype.Entity = null;

Object.defineProperty(Entity.prototype, 'Entity', {
  get: function () {
    return Entity;
  },
  set: function () {
    throw new Error('Entity cannot be changed');
  }
});

/**
 * This is a read-only property to get the general Entity Class of an instance.
 * This is just an alias to this.Entity.General.
 * @type {Entity}
 */
Entity.prototype.General = null;

Object.defineProperty(Entity.prototype, 'General', {
  get: function () {
    return this.Entity.General;
  },
  set: function () {
    throw new Error('General cannot be changed');
  }
});
<commit_msg>Entity#General example<commit_after>'use strict';

var expect = require('chai').expect;
var classes = require('../utils/classes');

module.exports = Entity;

/**
 * Base class for entities.
 * @constructor
 * @memberof module:back4app/entity/models
 * @example
 * var entity = new Entity();
 */
function Entity() {}

/**
 * This is a read-only property to get the general Entity Class of the current
 * Entity Class.
 * @type {Class}
 * @example
 * var generalAttributes = SpecificEntity.General.attributes;
 */
Entity.General = null;

Object.defineProperty(Entity, 'General', {
  get: function () {
    return null;
  },
  set: function () {
    throw new Error('General cannot be changed');
  }
});

/**
 * This is a dictionary with the Entity's attributes.
 * @type {Dictionary}
 */
Entity.attributes = {};

/**
 * This is a dictionary with the Entity's methods.
 * @type {Dictionary}
 */
Entity.methods = {};

/**
 * Private function used to get the specify function specific for the current
 * Entity class.
 * @memberof module:back4app/entity/models.Entity
 * @param {Class} CurrentEntity The currentEntity for which the specify function
 * will be got.
 * @returns {Function} The specify function.
 * @private
 */
var _getSpecifyFunction = function (CurrentEntity) {
  return function (specification) {
    function SpecificEntity() {}

    classes.generalize(CurrentEntity, SpecificEntity);

    Object.defineProperty(SpecificEntity, 'General', {
      get: function () {
        return CurrentEntity;
      },
      set: function () {
        throw new Error('General cannot be changed');
      }
    });

    SpecificEntity.attributes = {};
    SpecificEntity.methods = {};

    if (specification) {
      if (specification.attributes) {
        SpecificEntity.attributes = specification.attributes;
      }

      if (specification.methods) {
        SpecificEntity.methods = specification.methods;
      }
    }

    SpecificEntity.specify = _getSpecifyFunction(SpecificEntity);
    SpecificEntity.new = _getNewFunction(SpecificEntity);

    Object.defineProperty(SpecificEntity.prototype, 'Entity', {
      get: function () {
        return SpecificEntity;
      },
      set: function () {
        throw new Error('Entity cannot be changed');
      }
    });

    return SpecificEntity;
  };
};

/**
 * Creates a new Entity Class by specifying a general one.
 * @function
 * @param {Object} specification The new Entity specification.
 * @returns {Class} The new Entity Class.
 */
Entity.specify = _getSpecifyFunction(Entity);

/**
 * Private function used to get the new function specific for the current Entity
 * class.
 * @memberof module:back4app/entity/models.Entity
 * @param {Class} CurrentEntity The current entity class for which the new
 * function will be created.
 * @returns {Function} The new function.
 * @private
 */
var _getNewFunction = function (CurrentEntity) {
  return function (entity) {
    var EntityClass = CurrentEntity;
    if (entity) {
      expect(entity).to.be.a('string');
      try {
        EntityClass = require('../../../tests/unit/back/models/' + entity);
      }
      catch (e) {
        throw new Error('Cannot find Entity \'' + entity + '\'');
      }
    }

    return function () {
      return new EntityClass();
    };
  };
};

/**
 * Returns a function that creates new instances of an Entity Class.
 * @function
 * @param {String} entity The Entity Class of which the new instances will be
 * created. If the parameter is not given, the function will create instances of
 * the current Entity Class.
 * @returns {Function}
 * @example
 * var c1NewFunction = Entity.new('C1');
 * var c1 = c1NewFunction();
 */
Entity.new = _getNewFunction(Entity);

/**
 * This is a read-only property to get the Entity Class of an instance.
 * @type {Class}
 * @example
 * var entity = new Entity();
 * console.log(entity.Entity == Entity) // Logs true
 */
Entity.prototype.Entity = null;

Object.defineProperty(Entity.prototype, 'Entity', {
  get: function () {
    return Entity;
  },
  set: function () {
    throw new Error('Entity cannot be changed');
  }
});

/**
 * This is a read-only property to get the general Entity Class of an instance.
 * This is just an alias to this.Entity.General.
 * @type {Entity}
 * @example
 * var MyEntity = Entity.specify();
 * var myEntity = new MyEntity();
 * console.log(myEntity.General == Entity) // Logs true
 */
Entity.prototype.General = null;

Object.defineProperty(Entity.prototype, 'General', {
  get: function () {
    return this.Entity.General;
  },
  set: function () {
    throw new Error('General cannot be changed');
  }
});
<|endoftext|>


<commit_before>import builtins from 'builtins';

const docs = builtins.reduce((result, builtin) => {
  let filename = builtin;
  if (filename === 'module') {
    filename = 'modules';
  }
  result[builtin] = `https://nodejs.org/api/${filename}.html`;
  return result;
}, {});

export default docs;
<commit_msg>javascript: Fix link to Node's `constants` module (#343)<commit_after>import builtins from 'builtins';

const docs = builtins.reduce((result, builtin) => {
  let filename = builtin;
  if (filename === 'module') {
    filename = 'modules';
  }
  result[builtin] = `https://nodejs.org/api/${filename}.html`;
  return result;
}, {});

docs.constants = 'https://github.com/nodejs/node/blob/master/lib/constants.js';

export default docs;
<|endoftext|>


<commit_before>'use strict';

let d3 = require('d3');

export let pieChart = {
  defaultParams: {
    col1: 'green',
    col2: 'red',
    defaultDuration: 500,
    innerRadius: 0,
    cornerRadius: 5
  },

  mainFunction(loc, data, params, reactComp) {
    let self = this;
    this.reactComp = reactComp;

    let par = Object.assign({}, this.defaultParams, params);

    let size = 250;

    let width = size - 20,
      height = size - 20,
      radius = Math.min(width, height) / 2;
    let fullWidth = size;
    let fullHeight = size;

    this.arc = d3.svg.arc()
      .outerRadius(radius - 10);

    this.pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d.value;
      });

    this.svg = loc.append("svg")
      .attr('id', 'd3graphSVG')
      .style('display', 'inline-block')
      .style('position', 'absolute')
      .attr('preserveAspectRatio', 'xMinYMin slice')
      .attr('viewBox', '0 0 ' + fullWidth + ' ' + fullHeight)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    this.updateFunction(data, params);
  },

  tweenFunc(a, context) {
    let i = d3.interpolate(this._current, a);
    this._current = i(0);
    return function(t) {

      return context.arc(i(t));
    };
  },

  updateFunction(data, params) {
    let self = this;
    let par = Object.assign({}, this.defaultParams, params);

    this.arc
      .innerRadius(par.innerRadius)
      .cornerRadius(par.cornerRadius);

    this.join = this.svg.selectAll(".pie")
      .data(this.pie(data), function(d) {
        return d.data.id
      });
    let angMax = d3.max(this.pie(data).map(function(d) {
      return d.endAngle - d.startAngle
    }));

    this.join
      .transition()
      .duration(500)
      .attrTween('d', function(d) {
        return self.tweenFunc.apply(this, [d, self])
      })
      .style('fill', function(d) {
        return d3.interpolateHsl(par.col1, par.col2)
        ((d.endAngle - d.startAngle) / angMax)
      });

    //ENTER
    this.join.enter().append("path")
      .attr('class', 'pie cross-highlight-pie')
      .attr('id', function(d) {
        return 'cross-highlight-pie-sector-' + d.data.id
      })
      .style('stroke', 'white')
      .style('stroke-width', '2px')
      .attr("d", this.arc)
      .each(function(d) {
        this._current = d;
      })
      .style('fill', function(d) {
        return d3.interpolateHsl(par.col1, par.col2)((d.endAngle - d.startAngle) / angMax)
      })
      .on('mouseover', function(d) {
        self.mouseoverSector.call(self, d, this)
      })
      .on('mouseleave', function(d) {
        self.mouseleaveSector.call(self, d, this);
      });

    //EXIT
    this.join.exit().remove();
  },

  mouseoverSector(d, me) {
    // phone mommy
    this.reactComp.handleChartEvent(d.data, 'over');
  },

  mouseleaveSector(d, me) {
    // phone mommy
    this.reactComp.handleChartEvent(d.data, 'leave');
  }
};
<commit_msg>Add colorType and colorArray to pie chart.<commit_after>'use strict';

let d3 = require('d3');

export let pieChart = {
  defaultParams: {
    col1: 'green',
    col2: 'red',
    defaultDuration: 500,
    innerRadius: 0,
    cornerRadius: 5,
    colorType: 'gradient',
    colorArray: d3.scale.category20().range()
  },

  mainFunction(loc, data, params, reactComp) {
    let self = this;
    this.reactComp = reactComp;

    let par = Object.assign({}, this.defaultParams, params);

    let size = 250;

    let width = size - 20,
      height = size - 20,
      radius = Math.min(width, height) / 2;
    let fullWidth = size;
    let fullHeight = size;

    this.arc = d3.svg.arc()
      .outerRadius(radius - 10);

    this.pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d.value;
      });

    this.svg = loc.append("svg")
      .attr('id', 'd3graphSVG')
      .style('display', 'inline-block')
      .style('position', 'absolute')
      .attr('preserveAspectRatio', 'xMinYMin slice')
      .attr('viewBox', '0 0 ' + fullWidth + ' ' + fullHeight)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    this.updateFunction(data, params);
  },

  tweenFunc(a, context) {
    let i = d3.interpolate(this._current, a);
    this._current = i(0);
    return function(t) {

      return context.arc(i(t));
    };
  },

  colorFunction(par) {
    let self = this;
    if (par.colorType === 'gradient') {
      return (
        (d) => {
          return d3.interpolateHsl(par.col1, par.col2)
          ((d.endAngle - d.startAngle) / self.angMax)
        })
    } else if (par.colorType === 'category') {
      let cols = par.colorArray;
      return ((d, i) => {
        return cols[i];
      })
    } else {
      return () => 'gray';
    }
  },

  updateFunction(data, params) {
    let self = this;
    let par = Object.assign({}, this.defaultParams, params);

    let colFunc = this.colorFunction(par);

    this.arc
      .innerRadius(par.innerRadius)
      .cornerRadius(par.cornerRadius);

    this.join = this.svg.selectAll(".pie")
      .data(this.pie(data), function(d) {
        return d.data.id
      });
    this.angMax = d3.max(this.pie(data).map(function(d) {
      return d.endAngle - d.startAngle
    }));

    this.join
      .transition()
      .duration(500)
      .attrTween('d', function(d) {
        return self.tweenFunc.apply(this, [d, self])
      })
      .style('fill', (d, i) => colFunc(d, i));

    //ENTER
    this.join.enter().append("path")
      .attr('class', 'pie cross-highlight-pie')
      .attr('id', function(d) {
        return 'cross-highlight-pie-sector-' + d.data.id
      })
      .style('stroke', 'white')
      .style('stroke-width', '2px')
      .attr("d", this.arc)
      .each(function(d) {
        this._current = d;
      })
      .style('fill', (d, i) => colFunc(d, i))
      .on('mouseover', function(d) {
        self.mouseoverSector.call(self, d, this)
      })
      .on('mouseleave', function(d) {
        self.mouseleaveSector.call(self, d, this);
      });

    //EXIT
    this.join.exit().remove();
  },

  mouseoverSector(d, me) {
    // phone mommy
    this.reactComp.handleChartEvent(d.data, 'over');
  },

  mouseleaveSector(d, me) {
    // phone mommy
    this.reactComp.handleChartEvent(d.data, 'leave');
  }
};
<|endoftext|>


<commit_before>(function($) {
    var setCSS = function() {
        $('.fallzu-scroll-bar').css({
            'position'      : 'fixed',
            'right'         : '30px',
            'bottom'        : '30px'
        });

        $('.fallzu-scroll-btn').css({
            'width'         : '50px',
            'height'        : '50px',
            'background'    : '#333',
            'border-radius' : '25px',
            'text-align'    : 'center',
            'margin-bottom' : '10px'
        });

        $('.fallzu-scroll-btn > a').css({
            'display'       : 'block',
            'color'         : '#FFF'
        });
    };

    $.fn.scrollWhere = function() {
        //Insert HTML
        $(this).html(' \

 \

 \
                     \

 \

 \
                     \

 \

 \

 \
                     \

 \

 \
        ');

        //CSS
        setCSS();

        //Option

        $('.fallzu-scroll-return').hide();
        $(window).scroll(function() {
            var returnTop = $('.fallzu-scroll-return-top').stop(true, true);
            var returnBottom = $('.fallzu-scroll-return-bottom').stop(true, true);
            var windowHeight = $(this).height();
            var documentHeight = $(document).height();
            var scrollHeight = $(this).scrollTop();

            //Top
            if (scrollHeight) {
                returnTop.fadeIn();
            } else {
                returnTop.fadeOut();
            }

            //Bottom
            if (windowHeight + scrollHeight < documentHeight) {
                returnBottom.fadeIn();
            } else {
                returnBottom.fadeOut();
            }
        });

        //Top
        $('.fallzu-scroll-return-top').click(function(e) {
            e.preventDefault();
            $('html, body').animate({scrollTop:0}, 500);
        });

        //Bottom
        $('.fallzu-scroll-return-bottom').click(function(e) {
            e.preventDefault();
            $('html, body').animate({scrollTop:$(document).height() - $(window).height()}, 500);
        });

        //Record
        $('.fallzu-scroll-record').click(function(e) {
            e.preventDefault();
            var windowHeight = $(window).scrollTop();
            $('.fallzu-scroll-area').append('

');
            setCSS();

            //Anchor
            $('.fallzu-scroll-area .fallzu-scroll-btn:last').on('click', function(e) {
                e.preventDefault();
                $('html, body').animate({scrollTop:$(this).data('scroll')}, 500);
            });
        });

        return $(this);
    };
})(jQuery);
<commit_msg>add options<commit_after>(function($) {
    var setCSS = function() {
        $('.fallzu-scroll-bar').css({
            'position'      : 'fixed',
            'right'         : '30px',
            'bottom'        : '30px'
        });

        $('.fallzu-scroll-btn').css({
            'width'         : '50px',
            'height'        : '50px',
            'background'    : '#333',
            'border-radius' : '25px',
            'text-align'    : 'center',
            'margin-bottom' : '10px'
        });

        $('.fallzu-scroll-btn > a').css({
            'display'       : 'block',
            'color'         : '#FFF'
        });
    };

    $.fn.scrollWhere = function(devOptions) {
        //Insert HTML
        $(this).html(' \

 \

 \
                     \

 \

 \
                     \

 \

 \

 \
                     \

 \

 \
        ');

        //CSS
        setCSS();

        //Option
        var defaultOptions = {
            topBtn      : true,
            bottomBtn   : true,
            recordBtn   : true
        };

        var options = $.extend(defaultOptions, devOptions);

        $('.fallzu-scroll-return').hide();
        $(window).scroll(function() {
            var returnTop = $('.fallzu-scroll-return-top').stop(true, true);
            var returnBottom = $('.fallzu-scroll-return-bottom').stop(true, true);
            var windowHeight = $(this).height();
            var documentHeight = $(document).height();
            var scrollHeight = $(this).scrollTop();

            //Top
            if (scrollHeight) {
                returnTop.fadeIn();
            } else {
                returnTop.fadeOut();
            }

            //Bottom
            if (windowHeight + scrollHeight < documentHeight) {
                returnBottom.fadeIn();
            } else {
                returnBottom.fadeOut();
            }
        });

        //Top
        $('.fallzu-scroll-return-top').click(function(e) {
            e.preventDefault();
            $('html, body').animate({scrollTop:0}, 500);
        });

        //Bottom
        $('.fallzu-scroll-return-bottom').click(function(e) {
            e.preventDefault();
            $('html, body').animate({scrollTop:$(document).height() - $(window).height()}, 500);
        });

        //Record
        $('.fallzu-scroll-record').click(function(e) {
            e.preventDefault();
            var windowHeight = $(window).scrollTop();
            $('.fallzu-scroll-area').append('

');
            setCSS();

            //Anchor
            $('.fallzu-scroll-area .fallzu-scroll-btn:last').on('click', function(e) {
                e.preventDefault();
                $('html, body').animate({scrollTop:$(this).data('scroll')}, 500);
            });
        });

        return $(this);
    };
})(jQuery);
<|endoftext|>