<commit_before>/**
 *  Point of contact for component modules
 *
 *  ie: import { CounterButton, InfoBar } from 'components';
 *
 */

/*export CounterButton from './CounterButton/CounterButton';
export GithubButton from './GithubButton/GithubButton';*/
export InfoBar from './InfoBar/InfoBar';
export Article from '../containers/Article/Article';
export Kontakt from '../containers/Kontakt/Kontakt';
export MiniInfoBar from './MiniInfoBar/MiniInfoBar';
/*export SurveyForm from './SurveyForm/SurveyForm';
export WidgetForm from './WidgetForm/WidgetForm';*/
<commit_msg>sadasda<commit_after>/**
 *  Point of contact for component modules
 *
 *  ie: import { CounterButton, InfoBar } from 'components';
 *
 */

/*export CounterButton from './CounterButton/CounterButton';
export GithubButton from './GithubButton/GithubButton';*/
export InfoBar from './InfoBar/InfoBar';
export Article from '../containers/Article/Article';
export MiniInfoBar from './MiniInfoBar/MiniInfoBar';
/*export SurveyForm from './SurveyForm/SurveyForm';
export WidgetForm from './WidgetForm/WidgetForm';*/
<|endoftext|>


<commit_before>import { hydrate, state } from '../store';
import Export from './export/export';
import { getSettings } from '../settings';
import MediaTable from './media/media-table';

export default {

    template: `

            <media-table
                :collection="collection"
                :media="media"
                :editor="settings.editor"
            ></media-table>
            <export
                :collection="collection"
                :media="media"
            ></export>

    `,

    props: {
        collection: {
            required: true,
        },
        type: {
            required: true,
        },
        initial: {
            default: [],
        },
    },

    components: {
        Export,
        MediaTable,
    },

    data() {
        return { state };
    },

    computed: {
        media() {
            return this.state.media.filter(m => m.collection === this.collection);
        },
        settings() {
            return getSettings(this.type);
        },
    },

    ready() {
        hydrate({ media: this.initial });
    },

};
<commit_msg>Blender user fix<commit_after>import { hydrate, state } from '../store';
import Dropzone from 'dropzone';
import Export from './export/export';
import { getSettings } from '../settings';
import MediaTable from './media/media-table';

export default {

    template: `

            <media-table
                :collection="collection"
                :media="media"
                :editor="settings.editor"
            ></media-table>
            <export
                :collection="collection"
                :media="media"
            ></export>

    `,

    props: {
        collection: {
            required: true,
        },
        type: {
            required: true,
        },
        uploadUrl: {
            required: true,
        },
        initial: {
            default: [],
        },
    },

    components: {
        Export,
        MediaTable,
    },

    data() {
        return { state };
    },

    computed: {
        media() {
            return this.state.media.filter(m => m.collection === this.collection);
        },
        settings() {
            return getSettings(this.type);
        },
    },

    ready() {
        hydrate({ media: this.initial });

        new Dropzone(this.$els.media, {
            url: this.uploadUrl,
            uploadMultiple: this.settings.multiple,
            acceptedFiles: this.settings.accepts,
            previewTemplate: false,
            addedfile: this.addedFile,
            success: this.success,
            error: this.error,
        });
    },

    methods: {
        addedFile() {

        },
        success() {

        },
        error() {

        },
    },

};
<|endoftext|>


<commit_before>var registerComponent = require('../core/component').registerComponent;
var debug = require('../utils/debug');
var bind = require('../utils/bind');
var THREE = require('../lib/three');

var warn = debug('components:sound:warn');

/**
 * Sound component.
 */
module.exports.Component = registerComponent('sound', {
  schema: {
    autoplay: {default: false},
    distanceModel: {default: 'inverse',
      oneOf: ['linear', 'inverse', 'exponential']},
    loop: {default: false},
    maxDistance: {default: 10000},
    on: {default: ''},
    poolSize: {default: 1},
    positional: {default: true},
    refDistance: {default: 1},
    rolloffFactor: {default: 1},
    src: {type: 'audio'},
    volume: {default: 1}
  },

  multiple: true,

  init: function () {
    this.listener = null;
    this.audioLoader = new THREE.AudioLoader();
    this.pool = new THREE.Group();
    this.loaded = false;
    this.mustPlay = false;
    this.playSound = bind(this.playSound, this);
  },

  update: function (oldData) {
    var data = this.data;
    var srcChanged = data.src !== oldData.src;
    // Create new sound if not yet created or changing `src`.
    if (srcChanged) {
      if (!data.src) {
        warn('Audio source was not specified with `src`');
        return;
      }
      this.setupSound();
    }

    this.pool.children.forEach(function (sound) {
      if (data.positional) {
        sound.setDistanceModel(data.distanceModel);
        sound.setMaxDistance(data.maxDistance);
        sound.setRefDistance(data.refDistance);
        sound.setRolloffFactor(data.rolloffFactor);
      }
      sound.setLoop(data.loop);
      sound.setVolume(data.volume);
      sound.isPaused = false;
    });

    if (data.on !== oldData.on) {
      this.updateEventListener(oldData.on);
    }
    // All sound values set. Load in `src`.
    if (srcChanged) {
      var self = this;

      this.loaded = false;
      this.audioLoader.load(data.src, function (buffer) {
        self.pool.children.forEach(function (sound) {
          sound.setBuffer(buffer);
        });
        self.loaded = true;

        // Remove this key from cache, otherwise we can't play it again
        THREE.Cache.remove(data.src);
        if (self.data.autoplay || self.mustPlay) { self.playSound(); }
        self.el.emit('sound-loaded', {component: self});
      });
    }
  },

  pause: function () {
    this.stopSound();
    this.removeEventListener();
  },

  play: function () {
    if (this.data.autoplay) { this.playSound(); }
    this.updateEventListener();
  },

  remove: function () {
    this.removeEventListener();
    this.el.removeObject3D(this.attrName);
    try {
      this.pool.children.forEach(function (sound) {
        sound.disconnect();
      });
    } catch (e) {
      // disconnect() will throw if it was never connected initially.
      warn('Audio source not properly disconnected');
    }
  },

  /**
  *  Update listener attached to the user defined on event.
  */
  updateEventListener: function (oldEvt) {
    var el = this.el;
    if (oldEvt) { el.removeEventListener(oldEvt, this.playSound); }
    el.addEventListener(this.data.on, this.playSound);
  },

  removeEventListener: function () {
    this.el.removeEventListener(this.data.on, this.playSound);
  },

  /**
   * Removes current sound object, creates new sound object, adds to entity.
   *
   * @returns {object} sound
   */
  setupSound: function () {
    var self = this;
    var el = this.el;
    var sceneEl = el.sceneEl;

    if (this.pool.children.length > 0) {
      this.stopSound();
      el.removeObject3D('sound');
    }

    // Only want one AudioListener. Cache it on the scene.
    var listener = this.listener = sceneEl.audioListener || new THREE.AudioListener();
    sceneEl.audioListener = listener;

    if (sceneEl.camera) {
      sceneEl.camera.add(listener);
    }

    // Wait for camera if necessary.
    sceneEl.addEventListener('camera-set-active', function (evt) {
      evt.detail.cameraEl.getObject3D('camera').add(listener);
    });

    // Create [poolSize] audio instances and attach them to pool
    this.pool = new THREE.Group();
    for (var i = 0; i < this.data.poolSize; i++) {
      var sound = this.data.positional ? new THREE.PositionalAudio(listener) : new THREE.Audio(listener);
      this.pool.add(sound);
    }
    el.setObject3D(this.attrName, this.pool);

    this.pool.children.forEach(function (sound) {
      sound.onEnded = function () {
        sound.isPlaying = false;
        el.emit('sound-ended', {index: i, component: self});
      };
    });
  },

  /**
   * Pause all the sounds in the pool.
   */
  pauseSound: function () {
    this.isPlaying = false;
    this.pool.children.forEach(function (sound) {
      if (!sound.source || !sound.source.buffer || !sound.isPlaying || sound.isPaused) { return; }
      sound.isPaused = true;
      sound.pause();
    });
  },

  /**
   * Look for an unused sound in the pool and play it if found.
   */
  playSound: function () {
    if (!this.loaded) {
      warn('Sound not loaded yet. It will be played once it finished loading');
      this.mustPlay = true;
      return;
    }

    var found = false;
    this.isPlaying = true;
    this.pool.children.forEach(function (sound) {
      if (!sound.isPlaying && sound.buffer && !found) {
        sound.play();
        sound.isPaused = false;
        found = true;
        return;
      }
    });

    if (!found) {
      warn('All the sounds are playing. If you need to play more sounds simultaneously ' +
           'consider increasing the size of pool with the `poolSize` attribute.', this.el);
      return;
    }

    this.mustPlay = false;
  },

  /**
   * Stop all the sounds in the pool.
   */
  stopSound: function () {
    this.isPlaying = false;
    this.pool.children.forEach(function (sound) {
      if (!sound.source || !sound.source.buffer) { return; }
      sound.stop();
    });
  }
});
<commit_msg>Added id and name explicitly to sound-loaded and sound-ended (Fixes #3505)<commit_after>var registerComponent = require('../core/component').registerComponent;
var debug = require('../utils/debug');
var bind = require('../utils/bind');
var THREE = require('../lib/three');

var warn = debug('components:sound:warn');

/**
 * Sound component.
 */
module.exports.Component = registerComponent('sound', {
  schema: {
    autoplay: {default: false},
    distanceModel: {default: 'inverse',
      oneOf: ['linear', 'inverse', 'exponential']},
    loop: {default: false},
    maxDistance: {default: 10000},
    on: {default: ''},
    poolSize: {default: 1},
    positional: {default: true},
    refDistance: {default: 1},
    rolloffFactor: {default: 1},
    src: {type: 'audio'},
    volume: {default: 1}
  },

  multiple: true,

  init: function () {
    this.listener = null;
    this.audioLoader = new THREE.AudioLoader();
    this.pool = new THREE.Group();
    this.loaded = false;
    this.mustPlay = false;
    this.playSound = bind(this.playSound, this);
  },

  update: function (oldData) {
    var data = this.data;
    var srcChanged = data.src !== oldData.src;
    // Create new sound if not yet created or changing `src`.
    if (srcChanged) {
      if (!data.src) {
        warn('Audio source was not specified with `src`');
        return;
      }
      this.setupSound();
    }

    this.pool.children.forEach(function (sound) {
      if (data.positional) {
        sound.setDistanceModel(data.distanceModel);
        sound.setMaxDistance(data.maxDistance);
        sound.setRefDistance(data.refDistance);
        sound.setRolloffFactor(data.rolloffFactor);
      }
      sound.setLoop(data.loop);
      sound.setVolume(data.volume);
      sound.isPaused = false;
    });

    if (data.on !== oldData.on) {
      this.updateEventListener(oldData.on);
    }
    // All sound values set. Load in `src`.
    if (srcChanged) {
      var self = this;

      this.loaded = false;
      this.audioLoader.load(data.src, function (buffer) {
        self.pool.children.forEach(function (sound) {
          sound.setBuffer(buffer);
        });
        self.loaded = true;

        // Remove this key from cache, otherwise we can't play it again
        THREE.Cache.remove(data.src);
        if (self.data.autoplay || self.mustPlay) { self.playSound(); }
        self.el.emit('sound-loaded', {component: self, id: self.evtDetail.id, name: self.evtDetail.name});
      });
    }
  },

  pause: function () {
    this.stopSound();
    this.removeEventListener();
  },

  play: function () {
    if (this.data.autoplay) { this.playSound(); }
    this.updateEventListener();
  },

  remove: function () {
    this.removeEventListener();
    this.el.removeObject3D(this.attrName);
    try {
      this.pool.children.forEach(function (sound) {
        sound.disconnect();
      });
    } catch (e) {
      // disconnect() will throw if it was never connected initially.
      warn('Audio source not properly disconnected');
    }
  },

  /**
  *  Update listener attached to the user defined on event.
  */
  updateEventListener: function (oldEvt) {
    var el = this.el;
    if (oldEvt) { el.removeEventListener(oldEvt, this.playSound); }
    el.addEventListener(this.data.on, this.playSound);
  },

  removeEventListener: function () {
    this.el.removeEventListener(this.data.on, this.playSound);
  },

  /**
   * Removes current sound object, creates new sound object, adds to entity.
   *
   * @returns {object} sound
   */
  setupSound: function () {
    var self = this;
    var el = this.el;
    var sceneEl = el.sceneEl;

    if (this.pool.children.length > 0) {
      this.stopSound();
      el.removeObject3D('sound');
    }

    // Only want one AudioListener. Cache it on the scene.
    var listener = this.listener = sceneEl.audioListener || new THREE.AudioListener();
    sceneEl.audioListener = listener;

    if (sceneEl.camera) {
      sceneEl.camera.add(listener);
    }

    // Wait for camera if necessary.
    sceneEl.addEventListener('camera-set-active', function (evt) {
      evt.detail.cameraEl.getObject3D('camera').add(listener);
    });

    // Create [poolSize] audio instances and attach them to pool
    this.pool = new THREE.Group();
    for (var i = 0; i < this.data.poolSize; i++) {
      var sound = this.data.positional ? new THREE.PositionalAudio(listener) : new THREE.Audio(listener);
      this.pool.add(sound);
    }
    el.setObject3D(this.attrName, this.pool);

    this.pool.children.forEach(function (sound) {
      sound.onEnded = function () {
        sound.isPlaying = false;
        el.emit('sound-ended', {index: i, component: self, sound: sound, id: self.evtDetail.id, name: self.evtDetail.name});
      };
    });
  },

  /**
   * Pause all the sounds in the pool.
   */
  pauseSound: function () {
    this.isPlaying = false;
    this.pool.children.forEach(function (sound) {
      if (!sound.source || !sound.source.buffer || !sound.isPlaying || sound.isPaused) { return; }
      sound.isPaused = true;
      sound.pause();
    });
  },

  /**
   * Look for an unused sound in the pool and play it if found.
   */
  playSound: function () {
    if (!this.loaded) {
      warn('Sound not loaded yet. It will be played once it finished loading');
      this.mustPlay = true;
      return;
    }

    var found = false;
    this.isPlaying = true;
    this.pool.children.forEach(function (sound) {
      if (!sound.isPlaying && sound.buffer && !found) {
        sound.play();
        sound.isPaused = false;
        found = true;
        return;
      }
    });

    if (!found) {
      warn('All the sounds are playing. If you need to play more sounds simultaneously ' +
           'consider increasing the size of pool with the `poolSize` attribute.', this.el);
      return;
    }

    this.mustPlay = false;
  },

  /**
   * Stop all the sounds in the pool.
   */
  stopSound: function () {
    this.isPlaying = false;
    this.pool.children.forEach(function (sound) {
      if (!sound.source || !sound.source.buffer) { return; }
      sound.stop();
    });
  }
});
<|endoftext|>


<commit_before>/*global require, exports, , setInterval, clearInterval*/

var addon = require('./../../erizoAPI/build/Release/addon');
var logger = require('./../common/logger').logger;
var rpc = require('./../common/rpc');

// Logger
var log = logger.getLogger("ErizoJSController");

exports.ErizoJSController = function (spec) {
    "use strict";

    var that = {},
        // {id: {subsId1: wrtc1, subsId2: wrtc2}}
        subscribers = {},
        // {id: {muxer: OneToManyProcessor, wrtc: WebRtcConnection}
        publishers = {},

        // {id: ExternalOutput}
        externalOutputs = {},

        INTERVAL_TIME_SDP = 100,
        INTERVAL_TIME_FIR = 100,
        INTERVAL_TIME_KILL = 30*60*1000, // Timeout to kill itself after a timeout since the publisher leaves room.
        waitForFIR,
        initWebRtcConnection,
        getSdp,
        getRoap;

    var CONN_INITIAL = 101, CONN_STARTED = 102, CONN_READY = 103, CONN_FINISHED = 104, CONN_CANDIDATE = 201, CONN_SDP = 202, CONN_FAILED = 500;

    /*
     * Given a WebRtcConnection waits for the state READY for ask it to send a FIR packet to its publisher.
     */
    waitForFIR = function (wrtc, to) {

        if (publishers[to] !== undefined) {
            var intervarId = setInterval(function () {
              if (publishers[to]!==undefined){
                if (wrtc.getCurrentState() >= CONN_READY && publishers[to].muxer.getPublisherState() >=CONN_READY) {
                    log.info("Sending FIR");
                    publishers[to].muxer.sendFIR();
                    clearInterval(intervarId);
                }
              }

            }, INTERVAL_TIME_FIR);
        }
    };

    /*
     * Given a WebRtcConnection waits for the state CANDIDATES_GATHERED for set remote SDP.
     */
    initWebRtcConnection = function (wrtc, callback, id_pub, id_sub) {

        if (GLOBAL.config.erizoController.sendStats) {
            wrtc.getStats(function (newStats){
                log.info("Received RTCP stats: ", newStats);
                var timeStamp = new Date();
                rpc.callRpc('stats_handler', 'stats', [{pub: id_pub, subs: id_sub, stats: JSON.parse(newStats), timestamp:timeStamp.getTime()}]);
            });
        }

        wrtc.init( function (newStatus, mess){
          log.info("webrtc Addon status", newStatus, mess);

          // if (newStatus === 102 && !sdpDelivered) {
          //   localSdp = wrtc.getLocalSdp();
          //   answer = getRoap(localSdp, roap);
          //   callback('callback', answer);
          //   sdpDelivered = true;

          // }
          // if (newStatus === 103) {
          //   callback('onReady');
          // }

          if (newStatus == CONN_INITIAL) {
            callback('callback', {type: 'started'});

          } else if (newStatus == CONN_SDP) {
            log.debug('Sending SDP', mess);
            callback('callback', {type: 'answer', sdp: mess});

          } else if (newStatus == CONN_CANDIDATE) {
            callback('callback', {type: 'candidate', candidate: mess});
          } else if (newStatus == CONN_STARTED) {
          }

        });
        log.info("initializing");

        callback('callback', {type: 'initializing'});

        // var roap = sdp,
        //     remoteSdp = getSdp(roap);
        // wrtc.setRemoteSdp(remoteSdp);

        // var sdpDelivered = false;
    };

    /*
     * Gets SDP from roap message.
     */
    getSdp = function (roap) {

        var reg1 = new RegExp(/^.*sdp\":\"(.*)\",.*$/),
            sdp = roap.match(reg1)[1],
            reg2 = new RegExp(/\\r\\n/g);

        sdp = sdp.replace(reg2, '\n');

        return sdp;

    };

    /*
     * Gets roap message from SDP.
     */
    getRoap = function (sdp, offerRoap) {

        var reg1 = new RegExp(/\n/g),
            offererSessionId = offerRoap.match(/("offererSessionId":)(.+?)(,)/)[0],
            answererSessionId = "106",
            answer = ('\n{\n \"messageType\":\"ANSWER\",\n');

        sdp = sdp.replace(reg1, '\\r\\n');

        //var reg2 = new RegExp(/^.*offererSessionId\":(...).*$/);
        //var offererSessionId = offerRoap.match(reg2)[1];

        answer += ' \"sdp\":\"' + sdp + '\",\n';
        //answer += ' \"offererSessionId\":' + offererSessionId + ',\n';
        answer += ' ' + offererSessionId + '\n';
        answer += ' \"answererSessionId\":' + answererSessionId + ',\n \"seq\" : 1\n}\n';

        return answer;
    };

    that.addExternalInput = function (from, url, callback) {

        if (publishers[from] === undefined) {

            log.info("Adding external input peer_id ", from);

            var muxer = new addon.OneToManyProcessor(),
                ei = new addon.ExternalInput(url);

            publishers[from] = {muxer: muxer};
            subscribers[from] = {};

            ei.setAudioReceiver(muxer);
            ei.setVideoReceiver(muxer);
            muxer.setExternalPublisher(ei);

            var answer = ei.init();

            if (answer >= 0) {
                callback('callback', 'success');
            } else {
                callback('callback', answer);
            }

        } else {
            log.info("Publisher already set for", from);
        }
    };

    that.addExternalOutput = function (to, url) {
        if (publishers[to] !== undefined) {
            log.info("Adding ExternalOutput to " + to + " url " + url);
            var externalOutput = new addon.ExternalOutput(url);
            externalOutput.init();
            publishers[to].muxer.addExternalOutput(externalOutput, url);
            externalOutputs[url] = externalOutput;
        }
    };

    that.removeExternalOutput = function (to, url) {
      if (externalOutputs[url] !== undefined && publishers[to]!=undefined) {
        log.info("Stopping ExternalOutput: url " + url);
        publishers[to].removeSubscriber(url);
        delete externalOutputs[url];
      }
    };

    that.processSignaling = function (streamId, peerId, msg) {
        log.info("Process Signaling message: ", streamId, peerId, msg);
        if (publishers[streamId] !== undefined) {

            if (subscribers[streamId][peerId]) {
                if (msg.type === 'offer') {
                    subscribers[streamId][peerId].setRemoteSdp(msg.sdp);
                } else if (msg.type === 'candidate') {
                    subscribers[streamId][peerId].addRemoteCandidate(msg.candidate.sdpMid, msg.candidate.candidate);
                }
            } else {
                if (msg.type === 'offer') {
                    publishers[streamId].wrtc.setRemoteSdp(msg.sdp);
                } else if (msg.type === 'candidate') {
                    publishers[streamId].wrtc.addRemoteCandidate(msg.candidate.sdpMid, msg.candidate.candidate);
                }
            }

        }
    };

    /*
     * Adds a publisher to the room. This creates a new OneToManyProcessor
     * and a new WebRtcConnection. This WebRtcConnection will be the publisher
     * of the OneToManyProcessor.
     */
    that.addPublisher = function (from, callback) {

        if (publishers[from] === undefined) {

            log.info("Adding publisher peer_id ", from);

            var muxer = new addon.OneToManyProcessor(),
                wrtc = new addon.WebRtcConnection(true, true, GLOBAL.config.erizo.stunserver, GLOBAL.config.erizo.stunport, GLOBAL.config.erizo.minport, GLOBAL.config.erizo.maxport);

            publishers[from] = {muxer: muxer, wrtc: wrtc};
            subscribers[from] = {};

            wrtc.setAudioReceiver(muxer);
            wrtc.setVideoReceiver(muxer);
            muxer.setPublisher(wrtc);

            initWebRtcConnection(wrtc, callback, from);

            //log.info('Publishers: ', publishers);
            //log.info('Subscribers: ', subscribers);

        } else {
            log.info("Publisher already set for", from);
        }
    };

    /*
     * Adds a subscriber to the room. This creates a new WebRtcConnection.
     * This WebRtcConnection will be added to the subscribers list of the
     * OneToManyProcessor.
     */
    that.addSubscriber = function (from, to, audio, video, callback) {

        if (publishers[to] !== undefined && subscribers[to][from] === undefined) {

            log.info("Adding subscriber from ", from, 'to ', to, 'audio', audio, 'video', video);

            var wrtc = new addon.WebRtcConnection(audio, video, GLOBAL.config.erizo.stunserver, GLOBAL.config.erizo.stunport, GLOBAL.config.erizo.minport, GLOBAL.config.erizo.maxport);

            subscribers[to][from] = wrtc;
            publishers[to].muxer.addSubscriber(wrtc, from);

            initWebRtcConnection(wrtc, callback, to, from);
            waitForFIR(wrtc, to);

            //log.info('Publishers: ', publishers);
            //log.info('Subscribers: ', subscribers);
        }
    };

    /*
     * Removes a publisher from the room. This also deletes the associated OneToManyProcessor.
     */
    that.removePublisher = function (from) {

        if (subscribers[from] !== undefined && publishers[from] !== undefined) {
            log.info('Removing muxer', from);
            publishers[from].muxer.close();
            log.info('Removing subscribers', from);
            delete subscribers[from];
            log.info('Removing publisher', from);
            delete publishers[from];
            var count = 0;
            for (var k in publishers) {
                if (publishers.hasOwnProperty(k)) {
                   ++count;
                }
            }
            log.info("Publishers: ", count);
            if (count === 0)  {
                log.info('Removed all publishers. Killing process.');
                process.exit(0);
            }
        }
    };

    /*
     * Removes a subscriber from the room. This also removes it from the associated OneToManyProcessor.
     */
    that.removeSubscriber = function (from, to) {

        var index = subscribers[to].indexOf(from);
        if (index !== -1) {
            log.info('Removing subscriber ', from, 'to muxer ', to);
            publishers[to].removeSubscriber(from);
            subscribers[to].splice(index, 1);
        }
    };

    /*
     * Removes all the subscribers related with a client.
     */
    that.removeSubscriptions = function (from) {

        var key;

        log.info('Removing subscriptions of ', from);
        for (key in subscribers) {
            if (subscribers.hasOwnProperty(key)) {
                index = subscribers[key].indexOf(from);
                if (index !== -1) {
                    log.info('Removing subscriber ', from, 'to muxer ', key);
                    publishers[key].removeSubscriber(from);
                    subscribers[key].splice(index, 1);
                }
            }
        }
    };

    return that;
};
<commit_msg>Fixed a bug when removing subscribers<commit_after>/*global require, exports, , setInterval, clearInterval*/

var addon = require('./../../erizoAPI/build/Release/addon');
var logger = require('./../common/logger').logger;
var rpc = require('./../common/rpc');

// Logger
var log = logger.getLogger("ErizoJSController");

exports.ErizoJSController = function (spec) {
    "use strict";

    var that = {},
        // {id: {subsId1: wrtc1, subsId2: wrtc2}}
        subscribers = {},
        // {id: {muxer: OneToManyProcessor, wrtc: WebRtcConnection}
        publishers = {},

        // {id: ExternalOutput}
        externalOutputs = {},

        INTERVAL_TIME_SDP = 100,
        INTERVAL_TIME_FIR = 100,
        INTERVAL_TIME_KILL = 30*60*1000, // Timeout to kill itself after a timeout since the publisher leaves room.
        waitForFIR,
        initWebRtcConnection,
        getSdp,
        getRoap;

    var CONN_INITIAL = 101, CONN_STARTED = 102, CONN_READY = 103, CONN_FINISHED = 104, CONN_CANDIDATE = 201, CONN_SDP = 202, CONN_FAILED = 500;

    /*
     * Given a WebRtcConnection waits for the state READY for ask it to send a FIR packet to its publisher.
     */
    waitForFIR = function (wrtc, to) {

        if (publishers[to] !== undefined) {
            var intervarId = setInterval(function () {
              if (publishers[to] !== undefined){
                if (wrtc.getCurrentState() >= CONN_READY && publishers[to].muxer.getPublisherState() >=CONN_READY) {
                    log.info("Sending FIR");
                    publishers[to].muxer.sendFIR();
                    clearInterval(intervarId);
                }
              }

            }, INTERVAL_TIME_FIR);
        }
    };

    /*
     * Given a WebRtcConnection waits for the state CANDIDATES_GATHERED for set remote SDP.
     */
    initWebRtcConnection = function (wrtc, callback, id_pub, id_sub) {

        if (GLOBAL.config.erizoController.sendStats) {
            wrtc.getStats(function (newStats){
                log.info("Received RTCP stats: ", newStats);
                var timeStamp = new Date();
                rpc.callRpc('stats_handler', 'stats', [{pub: id_pub, subs: id_sub, stats: JSON.parse(newStats), timestamp:timeStamp.getTime()}]);
            });
        }

        wrtc.init( function (newStatus, mess){
          log.info("webrtc Addon status", newStatus, mess);

          // if (newStatus === 102 && !sdpDelivered) {
          //   localSdp = wrtc.getLocalSdp();
          //   answer = getRoap(localSdp, roap);
          //   callback('callback', answer);
          //   sdpDelivered = true;

          // }
          // if (newStatus === 103) {
          //   callback('onReady');
          // }

          if (newStatus == CONN_INITIAL) {
            callback('callback', {type: 'started'});

          } else if (newStatus == CONN_SDP) {
            log.debug('Sending SDP', mess);
            callback('callback', {type: 'answer', sdp: mess});

          } else if (newStatus == CONN_CANDIDATE) {
            callback('callback', {type: 'candidate', candidate: mess});
          } else if (newStatus == CONN_STARTED) {
          }

        });
        log.info("initializing");

        callback('callback', {type: 'initializing'});

        // var roap = sdp,
        //     remoteSdp = getSdp(roap);
        // wrtc.setRemoteSdp(remoteSdp);

        // var sdpDelivered = false;
    };

    /*
     * Gets SDP from roap message.
     */
    getSdp = function (roap) {

        var reg1 = new RegExp(/^.*sdp\":\"(.*)\",.*$/),
            sdp = roap.match(reg1)[1],
            reg2 = new RegExp(/\\r\\n/g);

        sdp = sdp.replace(reg2, '\n');

        return sdp;

    };

    /*
     * Gets roap message from SDP.
     */
    getRoap = function (sdp, offerRoap) {

        var reg1 = new RegExp(/\n/g),
            offererSessionId = offerRoap.match(/("offererSessionId":)(.+?)(,)/)[0],
            answererSessionId = "106",
            answer = ('\n{\n \"messageType\":\"ANSWER\",\n');

        sdp = sdp.replace(reg1, '\\r\\n');

        //var reg2 = new RegExp(/^.*offererSessionId\":(...).*$/);
        //var offererSessionId = offerRoap.match(reg2)[1];

        answer += ' \"sdp\":\"' + sdp + '\",\n';
        //answer += ' \"offererSessionId\":' + offererSessionId + ',\n';
        answer += ' ' + offererSessionId + '\n';
        answer += ' \"answererSessionId\":' + answererSessionId + ',\n \"seq\" : 1\n}\n';

        return answer;
    };

    that.addExternalInput = function (from, url, callback) {

        if (publishers[from] === undefined) {

            log.info("Adding external input peer_id ", from);

            var muxer = new addon.OneToManyProcessor(),
                ei = new addon.ExternalInput(url);

            publishers[from] = {muxer: muxer};
            subscribers[from] = {};

            ei.setAudioReceiver(muxer);
            ei.setVideoReceiver(muxer);
            muxer.setExternalPublisher(ei);

            var answer = ei.init();

            if (answer >= 0) {
                callback('callback', 'success');
            } else {
                callback('callback', answer);
            }

        } else {
            log.info("Publisher already set for", from);
        }
    };

    that.addExternalOutput = function (to, url) {
        if (publishers[to] !== undefined) {
            log.info("Adding ExternalOutput to " + to + " url " + url);
            var externalOutput = new addon.ExternalOutput(url);
            externalOutput.init();
            publishers[to].muxer.addExternalOutput(externalOutput, url);
            externalOutputs[url] = externalOutput;
        }
    };

    that.removeExternalOutput = function (to, url) {
      if (externalOutputs[url] !== undefined && publishers[to] !== undefined) {
        log.info("Stopping ExternalOutput: url " + url);
        publishers[to].muxer.removeSubscriber(url);
        delete externalOutputs[url];
      }
    };

    that.processSignaling = function (streamId, peerId, msg) {
        log.info("Process Signaling message: ", streamId, peerId, msg);
        if (publishers[streamId] !== undefined) {

            if (subscribers[streamId][peerId]) {
                if (msg.type === 'offer') {
                    subscribers[streamId][peerId].setRemoteSdp(msg.sdp);
                } else if (msg.type === 'candidate') {
                    subscribers[streamId][peerId].addRemoteCandidate(msg.candidate.sdpMid, msg.candidate.candidate);
                }
            } else {
                if (msg.type === 'offer') {
                    publishers[streamId].wrtc.setRemoteSdp(msg.sdp);
                } else if (msg.type === 'candidate') {
                    publishers[streamId].wrtc.addRemoteCandidate(msg.candidate.sdpMid, msg.candidate.candidate);
                }
            }

        }
    };

    /*
     * Adds a publisher to the room. This creates a new OneToManyProcessor
     * and a new WebRtcConnection. This WebRtcConnection will be the publisher
     * of the OneToManyProcessor.
     */
    that.addPublisher = function (from, callback) {

        if (publishers[from] === undefined) {

            log.info("Adding publisher peer_id ", from);

            var muxer = new addon.OneToManyProcessor(),
                wrtc = new addon.WebRtcConnection(true, true, GLOBAL.config.erizo.stunserver, GLOBAL.config.erizo.stunport, GLOBAL.config.erizo.minport, GLOBAL.config.erizo.maxport);

            publishers[from] = {muxer: muxer, wrtc: wrtc};
            subscribers[from] = {};

            wrtc.setAudioReceiver(muxer);
            wrtc.setVideoReceiver(muxer);
            muxer.setPublisher(wrtc);

            initWebRtcConnection(wrtc, callback, from);

            //log.info('Publishers: ', publishers);
            //log.info('Subscribers: ', subscribers);

        } else {
            log.info("Publisher already set for", from);
        }
    };

    /*
     * Adds a subscriber to the room. This creates a new WebRtcConnection.
     * This WebRtcConnection will be added to the subscribers list of the
     * OneToManyProcessor.
     */
    that.addSubscriber = function (from, to, audio, video, callback) {

        if (publishers[to] !== undefined && subscribers[to][from] === undefined) {

            log.info("Adding subscriber from ", from, 'to ', to, 'audio', audio, 'video', video);

            var wrtc = new addon.WebRtcConnection(audio, video, GLOBAL.config.erizo.stunserver, GLOBAL.config.erizo.stunport, GLOBAL.config.erizo.minport, GLOBAL.config.erizo.maxport);

            subscribers[to][from] = wrtc;
            publishers[to].muxer.addSubscriber(wrtc, from);

            initWebRtcConnection(wrtc, callback, to, from);
            waitForFIR(wrtc, to);

            //log.info('Publishers: ', publishers);
            //log.info('Subscribers: ', subscribers);
        }
    };

    /*
     * Removes a publisher from the room. This also deletes the associated OneToManyProcessor.
     */
    that.removePublisher = function (from) {

        if (subscribers[from] !== undefined && publishers[from] !== undefined) {
            log.info('Removing muxer', from);
            publishers[from].muxer.close();
            log.info('Removing subscribers', from);
            delete subscribers[from];
            log.info('Removing publisher', from);
            delete publishers[from];
            var count = 0;
            for (var k in publishers) {
                if (publishers.hasOwnProperty(k)) {
                   ++count;
                }
            }
            log.info("Publishers: ", count);
            if (count === 0)  {
                log.info('Removed all publishers. Killing process.');
                process.exit(0);
            }
        }
    };

    /*
     * Removes a subscriber from the room. This also removes it from the associated OneToManyProcessor.
     */
    that.removeSubscriber = function (from, to) {

        if (subscribers[to][from]) {
            log.info('Removing subscriber ', from, 'to muxer ', to);
            publishers[to].muxer.removeSubscriber(from);
            delete subscribers[to][from];
        }
    };

    /*
     * Removes all the subscribers related with a client.
     */
    that.removeSubscriptions = function (from) {

        var key;

        log.info('Removing subscriptions of ', from);
        for (key in subscribers) {
            if (subscribers.hasOwnProperty(key)) {
                 if (subscribers[to][from]) {
                    log.info('Removing subscriber ', from, 'to muxer ', key);
                    publishers[key].muxer.removeSubscriber(from);
                    delete subscribers[key][from];
                }
            }
        }
    };

    return that;
};
<|endoftext|>


<commit_before>/*jshint node: true, -W106 */
'use strict';

/*
* Name : mapChartFlowSpec.js
* Module : UnitTest
* Location : /test/businessTier/flow
*
* History :
*
* Version   Date         Programmer         Description
* =========================================================
* 0.0.1     2015-06-02   Matteo Furlan    Initial code
* =========================================================
*/

var LineChartFlow = require('../../../lib/businessTier/flow/lineChartFlow.js');
var assert = require('assert');

describe('LineChartFlow', function() {

    it('returns null when there are no params', function() {
        assert.strictEqual((new LineChartFlow()).hasOwnProperty('_dataLineChartFlow'), false);
    });

    it('returns null when there is no valid graphsocket in params', function() {
        assert.strictEqual((new LineChartFlow(2, 3)).hasOwnProperty('_dataLineChartFlow'), false);
    });

    it('returns null when params are not valid', function() {
        assert.strictEqual((new LineChartFlow(2, {_namespace: 2})).hasOwnProperty('_dataLineChartFlow'), false);
    });

    it('calls the parent constructor with the params specified', function() {
        var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
        assert.strictEqual(flow1._dataLineChartFlow._ID, 'flow1');
        assert.strictEqual(flow1._graphSocket._namespace, 'flow1');
    });

    describe('#addRecord', function() {
        it('returns 123 if record is invalid', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
            assert.strictEqual(flow1.addRecord(), 123);
        });
        it('returns valid norrisRecordID if record is valid', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
            assert.strictEqual(flow1.addRecord({'tempo': 1, 'temperatura': 25}).indexOf('flow1'), 0);
        });
    });

    describe('#updateRecord', function() {
        it('returns 123 if record is invalid', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
            flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord(), 123);
        });
        it('returns 122 if no ID in records', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
            var ID=flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord(ID+'32442',{'tempo': 4, 'temperatura': 33}), 122);
        });
        it('returns 122 if invalid ID', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
            var ID=flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord('sad'+ID,{'tempo': 4, 'temperatura': 33}), 122);
        });
        it('returns true with correct update', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
            var ID=flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord(ID,{'tempo': 4, 'temperatura': 33}), true);
        });
    });

    describe('#getReplaceDataJSON', function() {
        var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
        flow1.addRecord({'tempo': 4, 'temperatura': 4});
        flow1.addRecord({'tempo': 9, 'temperatura': 23});
        flow1.addRecord({'tempo': 6, 'temperatura': 7});
        console.log('getReplaceDataJSONgetReplaceDataJSONgetReplaceDataJSON');
        console.dir(flow1.getReplaceDataJSON());
    });

    describe('#updateProperties', function() {
        var flow1=new LineChartFlow({ID: 'flow1'},{_namespace: 'flow1'});
        flow1.updateProperties({name: 'grafico tempo-temperatura',xKey: 'tempo',yKey: 'temperatura'});
        assert.strictEqual(flow1._dataLineChartFlow._xKey,'tempo');
        assert.strictEqual(flow1._dataLineChartFlow._yKey,'temperatura');
        assert.strictEqual(flow1._dataLineChartFlow._name,'grafico tempo-temperatura');
    });
});<commit_msg>fix socketMock<commit_after>/*jshint node: true, -W106 */
'use strict';

/*
* Name : mapChartFlowSpec.js
* Module : UnitTest
* Location : /test/businessTier/flow
*
* History :
*
* Version   Date         Programmer         Description
* =========================================================
* 0.0.1     2015-06-02   Matteo Furlan    Initial code
* =========================================================
*/

var LineChartFlow = require('../../../lib/businessTier/flow/lineChartFlow.js');
var assert = require('assert');

var socketMock=function(){
    this.p1=null;
    this.p2=null;
    this._namespace='flow1';
    this.sendMessage=function(p1, p2){
        this.p1=p1;
        this.p2=p2;
    };
};

describe('LineChartFlow', function() {

    it('returns null when there are no params', function() {
        assert.strictEqual((new LineChartFlow()).hasOwnProperty('_dataLineChartFlow'), false);
    });

    it('returns null when there is no valid graphsocket in params', function() {
        assert.strictEqual((new LineChartFlow(2, 3)).hasOwnProperty('_dataLineChartFlow'), false);
    });

    it('returns null when params are not valid', function() {
        assert.strictEqual((new LineChartFlow(2, {_namespace: 2})).hasOwnProperty('_dataLineChartFlow'), false);
    });

    it('calls the parent constructor with the params specified', function() {
        var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
        assert.strictEqual(flow1._dataLineChartFlow._ID, 'flow1');
        assert.strictEqual(flow1._graphSocket._namespace, 'flow1');
    });

    describe('#addRecord', function() {
        it('returns 123 if record is invalid', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
            assert.strictEqual(flow1.addRecord(), 123);
        });
        it('returns valid norrisRecordID if record is valid', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
            assert.strictEqual(flow1.addRecord({'tempo': 1, 'temperatura': 25}).indexOf('flow1'), 0);
        });
    });

    describe('#updateRecord', function() {
        it('returns 123 if record is invalid', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
            flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord(), 123);
        });
        it('returns 122 if no ID in records', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
            var ID=flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord(ID+'32442',{'tempo': 4, 'temperatura': 33}), 122);
        });
        it('returns 122 if invalid ID', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
            var ID=flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord('sad'+ID,{'tempo': 4, 'temperatura': 33}), 122);
        });
        it('returns true with correct update', function() {
            var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
            var ID=flow1.addRecord({'tempo': 1, 'temperatura': 25});
            assert.strictEqual(flow1.updateRecord(ID,{'tempo': 4, 'temperatura': 33}), true);
        });
    });

    describe('#getReplaceDataJSON', function() {
        var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
        flow1.addRecord({'tempo': 4, 'temperatura': 4});
        flow1.addRecord({'tempo': 9, 'temperatura': 23});
        flow1.addRecord({'tempo': 6, 'temperatura': 7});
        console.log('getReplaceDataJSONgetReplaceDataJSONgetReplaceDataJSON');
        console.dir(flow1.getReplaceDataJSON());
    });

    describe('#updateProperties', function() {
        var flow1=new LineChartFlow({ID: 'flow1'},socketMock);
        flow1.updateProperties({name: 'grafico tempo-temperatura',xKey: 'tempo',yKey: 'temperatura'});
        assert.strictEqual(flow1._dataLineChartFlow._xKey,'tempo');
        assert.strictEqual(flow1._dataLineChartFlow._yKey,'temperatura');
        assert.strictEqual(flow1._dataLineChartFlow._name,'grafico tempo-temperatura');
    });
});<|endoftext|>


<commit_before>//@todo better coverage
describe('dom.getElementCoordinates', function () {
	'use strict';
	var fixture = document.getElementById('fixture');

	afterEach(function () {
		fixture.innerHTML = '';
	});

	it('should calculate bounding box based on element position', function () {
		var el, coords;

		fixture.innerHTML = '
' +
			'' +
				'Absolute' +
			'
';

		el = document.getElementById('coords0');
		coords = commons.dom.getElementCoordinates(el);
		assert.closeTo(coords.left, -1000, 0.3);
		assert.closeTo(coords.top, -1000, 0.3);
		assert.closeTo(coords.width, 1000, 0.3);
		assert.closeTo(coords.height, 1000, 0.3);
		assert.closeTo(coords.right, 0, 0.3);
		assert.closeTo(coords.bottom, 0, 0.3);

		el = document.getElementById('div');
		coords = commons.dom.getElementCoordinates(el);
		assert.equal(Math.round(coords.left), -1);
		assert.equal(Math.round(coords.top), -1);
	});

	it('should take into account scroll offsets', function () {
		var el, coords,
			offset = commons.dom.getScrollOffset(window.document);

		fixture.innerHTML = '
' +
			'' +
				'Absolute' +
			'
';

		el = document.getElementById('coords0');
		coords = commons.dom.getElementCoordinates(el);
		assert.closeTo(coords.left, -1000, 0.3);
		assert.closeTo(coords.top, -1000, 0.3);
		assert.closeTo(coords.width, 1000, 0.3);
		assert.closeTo(coords.height, 1000, 0.3);
		assert.closeTo(coords.right, 0, 0.3);
		assert.closeTo(coords.bottom, 0, 0.3);

		window.scrollTo(0, 150);
		coords = commons.dom.getElementCoordinates(el);
		assert.closeTo(coords.left, -1000, 0.3);
		assert.closeTo(coords.top, -1000, 0.3);
		assert.closeTo(coords.width, 1000, 0.3);
		assert.closeTo(coords.height, 1000, 0.3);
		assert.closeTo(coords.right, 0, 0.3);
		assert.closeTo(coords.bottom, 0, 0.3);

		window.scrollTo(offset.left, offset.top);

	});
});
<commit_msg>bigger error margin on get-element-coord<commit_after>//@todo better coverage
describe('dom.getElementCoordinates', function () {
	'use strict';
	var fixture = document.getElementById('fixture');

	afterEach(function () {
		fixture.innerHTML = '';
	});

	it('should calculate bounding box based on element position', function () {
		var el, coords;

		fixture.innerHTML = '
' +
			'' +
				'Absolute' +
			'
';

		el = document.getElementById('coords0');
		coords = commons.dom.getElementCoordinates(el);
		assert.closeTo(coords.left, -1000, 0.5);
		assert.closeTo(coords.top, -1000, 0.5);
		assert.closeTo(coords.width, 1000, 0.5);
		assert.closeTo(coords.height, 1000, 0.5);
		assert.closeTo(coords.right, 0, 0.5);
		assert.closeTo(coords.bottom, 0, 0.5);

		el = document.getElementById('div');
		coords = commons.dom.getElementCoordinates(el);
		assert.equal(Math.round(coords.left), -1);
		assert.equal(Math.round(coords.top), -1);
	});

	it('should take into account scroll offsets', function () {
		var el, coords,
			offset = commons.dom.getScrollOffset(window.document);

		fixture.innerHTML = '
' +
			'' +
				'Absolute' +
			'
';

		el = document.getElementById('coords0');
		coords = commons.dom.getElementCoordinates(el);
		assert.closeTo(coords.left, -1000, 0.5);
		assert.closeTo(coords.top, -1000, 0.5);
		assert.closeTo(coords.width, 1000, 0.5);
		assert.closeTo(coords.height, 1000, 0.5);
		assert.closeTo(coords.right, 0, 0.5);
		assert.closeTo(coords.bottom, 0, 0.5);

		window.scrollTo(0, 150);
		coords = commons.dom.getElementCoordinates(el);
		assert.closeTo(coords.left, -1000, 0.5);
		assert.closeTo(coords.top, -1000, 0.5);
		assert.closeTo(coords.width, 1000, 0.5);
		assert.closeTo(coords.height, 1000, 0.5);
		assert.closeTo(coords.right, 0, 0.5);
		assert.closeTo(coords.bottom, 0, 0.5);

		window.scrollTo(offset.left, offset.top);

	});
});
<|endoftext|>


<commit_before>import config from '../config';

export async function main(req, res) {
  res.json({
    status: 'online',
    user: config.user,
    repo: config.repo
  });
}
<commit_msg>Print latest-release info in /<commit_after>import {getLatestRelease} from '../components/github';
import config from '../config';

export async function main(req, res) {
  const latestRelease = await getLatestRelease();
  res.json({
    status: 'online',
    user: config.user,
    repo: config.repo,
    latestRelease
  });
}
<|endoftext|>


<commit_before>var fetchValue = require("./value.js")
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Finds an object's color and returns random if it cannot be found
//------------------------------------------------------------------------------
module.exports = function( vars , id , level ) {

  if ( !level ) {
    var level = vars.id.value
  }

  if (typeof level === "number") {
    level = vars.id.nesting[level]
  }

  function getRandom( c ) {

    if ( d3plus.object.validate( c ) ) {
      c = c[ level ]
    }

    if (c instanceof Array) {
      c = c[0]
    }

    return d3plus.color.random( c, vars.color.scale.value )

  }

  if ( !vars.color.value ) {

    return getRandom( id )

  }
  else {

    for ( var i = vars.id.nesting.indexOf(level) ; i >= 0 ; i-- ) {
      var colorLevel = vars.id.nesting[i]
        , o = d3plus.object.validate(id) && !(vars.color.value in id) && id[level] instanceof Array ? id[level][0] : fetchValue(vars, id, colorLevel)
        , color = fetchValue( vars , o , vars.color.value , colorLevel )
      if ( color ) break
    }

    if ( !color ) {

      if ( vars.color.value || typeof vars.color.valueScale === "function" ) {
        return vars.color.missing
      }
      return getRandom( id )

    }
    else if ( !vars.color.valueScale ) {
      return d3plus.color.validate( color ) ? color : getRandom( color )
    }
    else {
      return vars.color.valueScale( color )
    }

  }

}
<commit_msg>more robust color fetching (support for arrays)<commit_after>var fetchValue = require("./value.js")
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Finds an object's color and returns random if it cannot be found
//------------------------------------------------------------------------------
module.exports = function( vars , id , level ) {

  if ( !level ) {
    var level = vars.id.value
  }

  if (typeof level === "number") {
    level = vars.id.nesting[level]
  }

  function getRandom( c ) {

    if ( d3plus.object.validate( c ) ) {
      c = c[ level ]
    }

    if (c instanceof Array) {
      c = c[0]
    }

    return d3plus.color.random( c, vars.color.scale.value )

  }

  if ( !vars.color.value ) {

    return getRandom( id )

  }
  else {

    function getColor(color) {

      if ( !color ) {

        if ( vars.color.value || typeof vars.color.valueScale === "function" ) {
          return vars.color.missing
        }
        return getRandom( id )

      }
      else if ( !vars.color.valueScale ) {
        return d3plus.color.validate( color ) ? color : getRandom( color )
      }
      else {
        return vars.color.valueScale( color )
      }

    }

    var colors = []
    for ( var i = vars.id.nesting.indexOf(level) ; i >= 0 ; i-- ) {
      var colorLevel = vars.id.nesting[i]
        , value = d3plus.object.validate(id) ? fetchValue( vars , id , vars.color.value , colorLevel ) : id
      if ( value ) {
        var color = getColor(value)
        if (colors.indexOf(color) < 0) colors.push(color)
      }
    }

    return colors.length === 0 ? getColor(undefined) : colors.length === 1 ? colors[0] : vars.color.missing

  }

}
<|endoftext|>


<commit_before>'use strict';

const root = './../../../src/';

var expect = require('chai').expect,
  supertest = require('supertest'),
  rewire = require('rewire'),

  App = require(root + 'app').App,
  config = require(root + 'common/config').getDebugConfig(),
  testUtils = require(root + '../test/test-utils'),
  RewiredSystemStatusHandler = rewire(root + 'handlers/status/systemStatusHandler');

config.api.port = 0;

describe('SystemStatusHandler', function () {
  describe('parseDiskInformation', function () {
    beforeEach(function () {
      this.parseDiskInformation = RewiredSystemStatusHandler.__get__('parseDiskInformation');
    });

    it('should be able to handle invalid data', function () {
      expect(this.parseDiskInformation()).to.be.null;
      expect(this.parseDiskInformation(null)).to.be.null;
      expect(this.parseDiskInformation(123)).to.be.null;
      expect(this.parseDiskInformation('')).to.be.null;
      expect(this.parseDiskInformation('asdf')).to.be.null;
      expect(this.parseDiskInformation('fo o b a r')).to.be.null;
    });

    it('should be able to parse valid data', function () {
      expect(this.parseDiskInformation('type size used avail use% mountpoint')).to.eql(
        {
          mountPoint: 'mountpoint',
          spaceUsed: 'used',
          spaceAvailable: 'avail'
        });
      expect(this.parseDiskInformation('type    size  used   avail    use%   mountpoint')).to.eql(
        {
          mountPoint: 'mountpoint',
          spaceUsed: 'used',
          spaceAvailable: 'avail'
        });
      expect(this.parseDiskInformation('type size used avail use% mount point with spaces')).to.eql(
        {
          mountPoint: 'mount point with spaces',
          spaceUsed: 'used',
          spaceAvailable: 'avail'
        });
    });
  });

  describe('requests', function () {
    describe('GET /system/status/disk', function () {
      beforeEach(function (done) {
        var that = this;

        // prepare data - return sample data on the first call, if the correct command is used
        // throw an exception on the second call
        this.fakeExec = function (command, callback) {
          that.calls = that.calls || 0;
          that.calls++;

          if (that.calls > 2) {
            return callback('This is an error');
          }
          if (that.calls > 1) {
            throw new Error('Fake exec failed!');
          }

          return command === 'df -x tmpfs -x devtmpfs | tail -n +2'
            ? callback(null,  '/dev/sda1       165G  119G   38G  76% /\n\n/dev/sdb2       766G  730G   36G  96% /foo')
            : callback('Unexpected invocation');
        };

        // injec fake exec
        RewiredSystemStatusHandler.__set__('exec', this.fakeExec);

        // create app and replace handler
        this.app = new App(config, testUtils.getFakeLog());
        this.app.systemStatusHandler = new RewiredSystemStatusHandler(testUtils.getFakeLog());

        // start server
        this.app.listen(function () {
          var url = 'http://' + this.address().address + ':' + this.address().port;
          that.server = supertest.agent(url);
          done();
        });
      });

      afterEach(function (done) {
        this.app.close(done);
      });

      it('should correctly return sample data', function (done) {
        this.server
          .get('/status/system/disk')
          .expect('Content-type', 'application/json')
          .expect(200)
          .end(function (err, res) {
            expect(err).to.not.exist;
            expect(res.result).to.not.exist;
            expect(res.body.code).to.equal('Success');
            expect(res.body.data).to.eql([
              {
                mountPoint: "/",
                spaceUsed: "119G",
                spaceAvailable: "38G"
              },
              {
                mountPoint: "/foo",
                spaceUsed: "730G",
                spaceAvailable: "36G"
              },
            ]);
            done();
          });
      });

      it('should be able to deal with a failing command - exception', function (done) {
        this.server
          .get('/status/system/disk')
          .expect('Content-type', 'application/json')
          .expect(500)
          .end(function (err, res) {
            expect(err).to.not.exist;
            expect(res.result).to.not.exist;
            expect(res.body.code).to.equal('InternalServerError');
            done();
          });
      });

      it('should be able to deal with a failing command - error object', function (done) {
        this.server
          .get('/status/system/disk')
          .expect('Content-type', 'application/json')
          .expect(500)
          .end(function (err, res) {
            expect(err).to.not.exist;
            expect(res.result).to.not.exist;
            expect(res.body.code).to.equal('InternalServerError');
            done();
          });
      });
    });
  });
});

<commit_msg>SSH test cleanup<commit_after>'use strict';

const root = './../../../src/';

var expect = require('chai').expect,
  supertest = require('supertest'),
  rewire = require('rewire'),

  App = require(root + 'app').App,
  config = require(root + 'common/config').getDebugConfig(),
  testUtils = require(root + '../test/test-utils'),
  RewiredSystemStatusHandler = rewire(root + 'handlers/status/systemStatusHandler');

config.api.port = 0;

describe('SystemStatusHandler', function () {
  describe('parseDiskInformation', function () {
    var parseDiskInformation = RewiredSystemStatusHandler.__get__('parseDiskInformation');

    it('should be able to handle invalid data', function () {
      expect(parseDiskInformation()).to.be.null;
      expect(parseDiskInformation(null)).to.be.null;
      expect(parseDiskInformation(123)).to.be.null;
      expect(parseDiskInformation('')).to.be.null;
      expect(parseDiskInformation('asdf')).to.be.null;
      expect(parseDiskInformation('fo o b a r')).to.be.null;
    });

    it('should be able to parse valid data', function () {
      expect(parseDiskInformation('type size used avail use% mountpoint')).to.eql(
        {
          mountPoint: 'mountpoint',
          spaceUsed: 'used',
          spaceAvailable: 'avail'
        });
      expect(parseDiskInformation('type    size  used   avail    use%   mountpoint')).to.eql(
        {
          mountPoint: 'mountpoint',
          spaceUsed: 'used',
          spaceAvailable: 'avail'
        });
      expect(parseDiskInformation('type size used avail use% mount point with spaces')).to.eql(
        {
          mountPoint: 'mount point with spaces',
          spaceUsed: 'used',
          spaceAvailable: 'avail'
        });
    });
  });

  describe('requests', function () {
    describe('GET /system/status/disk', function () {
      beforeEach(function (done) {
        var that = this;

        // prepare data - return sample data on the first call, if the correct command is used
        // throw an exception on the second call - there's no way around doing it like that because
        // all calls are exactly the same
        this.fakeExec = function (command, callback) {
          that.calls = that.calls || 0;
          that.calls++;

          if (that.calls > 2) {
            return callback('This is an error');
          }
          if (that.calls > 1) {
            throw new Error('Fake exec failed!');
          }

          return command === 'df -x tmpfs -x devtmpfs | tail -n +2'
            ? callback(null,  '/dev/sda1       165G  119G   38G  76% /\n\n/dev/sdb2       766G  730G   36G  96% /foo')
            : callback('Unexpected invocation');
        };

        // injec fake exec
        RewiredSystemStatusHandler.__set__('exec', this.fakeExec);

        // create app and replace handler
        this.app = new App(config, testUtils.getFakeLog());
        this.app.systemStatusHandler = new RewiredSystemStatusHandler(testUtils.getFakeLog());

        // start server
        this.app.listen(function () {
          var url = 'http://' + this.address().address + ':' + this.address().port;
          that.server = supertest.agent(url);
          done();
        });
      });

      afterEach(function (done) {
        this.app.close(done);
      });

      it('should correctly return sample data', function (done) {
        this.server
          .get('/status/system/disk')
          .expect('Content-type', 'application/json')
          .expect(200)
          .end(function (err, res) {
            expect(err).to.not.exist;
            expect(res.result).to.not.exist;
            expect(res.body.code).to.equal('Success');
            expect(res.body.data).to.eql([
              {
                mountPoint: "/",
                spaceUsed: "119G",
                spaceAvailable: "38G"
              },
              {
                mountPoint: "/foo",
                spaceUsed: "730G",
                spaceAvailable: "36G"
              },
            ]);
            done();
          });
      });

      it('should be able to deal with a failing command - exception', function (done) {
        this.server
          .get('/status/system/disk')
          .expect('Content-type', 'application/json')
          .expect(500)
          .end(function (err, res) {
            expect(err).to.not.exist;
            expect(res.result).to.not.exist;
            expect(res.body.code).to.equal('InternalServerError');
            done();
          });
      });

      it('should be able to deal with a failing command - error object', function (done) {
        this.server
          .get('/status/system/disk')
          .expect('Content-type', 'application/json')
          .expect(500)
          .end(function (err, res) {
            expect(err).to.not.exist;
            expect(res.result).to.not.exist;
            expect(res.body.code).to.equal('InternalServerError');
            done();
          });
      });
    });
  });
});

<|endoftext|>


<commit_before>/**
 * @description
A collection of reusable utility functions.

 *
 * @namespace imageCreator
 * @name utils
 * @version 1.0
 * @author mbaijs
 */
define(
[],
function()
{
    var module = {};

    module.HAS_VML = function()
    {
        var div       = document.body.appendChild( document.createElement( "div" ) );
        div.innerHTML = "<v:shape adj='1' />";

        var shape            = div.firstChild;
        shape.style.behavior = "url(#default#VML)";

        var supportsVml = shape ? typeof shape.adj == "object": true;
        div.parentNode.removeChild( div );

        return supportsVml;
    }();

    module.HAS_SVG            = !!document.createElementNS && !!document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect

    module.HAS_FOREIGN_OBJECT = "function" === typeof SVGForeignObjectElement

    module.HAS_CANVAS         = !!document.createElement( "canvas" ).getContext;

    module.IS_PRE_IE9         = window.attachEvent && !window.addEventListener;

    module.HAS_POINTEREVENTS  = navigator.pointerEnabled || navigator.msPointerEnabled;

    module.HAS_TOUCHEVENTS    = ("ontouchstart" in window);

    module.NO_MOUSEEVENTS     = module.HAS_TOUCHEVENTS && navigator.userAgent.match(/mobile|tablet|ip(ad|hone|od)|android/i);

    return module;
});<commit_msg>Util Detect: Forgot a semicolon at the end of the HAS_FOREIGN_OBJECT constant.<commit_after>/**
 * @description
A collection of reusable utility functions.

 *
 * @namespace imageCreator
 * @name utils
 * @version 1.0
 * @author mbaijs
 */
define(
[],
function()
{
    var module = {};

    module.HAS_VML = function()
    {
        var div       = document.body.appendChild( document.createElement( "div" ) );
        div.innerHTML = "<v:shape adj='1' />";

        var shape            = div.firstChild;
        shape.style.behavior = "url(#default#VML)";

        var supportsVml = shape ? typeof shape.adj == "object": true;
        div.parentNode.removeChild( div );

        return supportsVml;
    }();

    module.HAS_SVG            = !!document.createElementNS && !!document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect

    module.HAS_FOREIGN_OBJECT = "function" === typeof SVGForeignObjectElement;

    module.HAS_CANVAS         = !!document.createElement( "canvas" ).getContext;

    module.IS_PRE_IE9         = window.attachEvent && !window.addEventListener;

    module.HAS_POINTEREVENTS  = navigator.pointerEnabled || navigator.msPointerEnabled;

    module.HAS_TOUCHEVENTS    = ("ontouchstart" in window);

    module.NO_MOUSEEVENTS     = module.HAS_TOUCHEVENTS && navigator.userAgent.match(/mobile|tablet|ip(ad|hone|od)|android/i);

    return module;
});<|endoftext|>


<commit_before>var CONST = require('../const');

/**
 * @namespace PIXI.utils
 */
var utils = module.exports = {
    _uid: 0,
    _saidHello: false,

    Ticker:         require('./Ticker'),
    EventData:      require('./EventData'),
    eventTarget:    require('./eventTarget'),
    pluginTarget:   require('./pluginTarget'),
    PolyK:          require('./PolyK'),

    /**
     * Gets the next uuid
     *
     * @return {number} The next uuid to use.
     */
    uuid: function ()
    {
        return ++utils._uid;
    },

    /**
     * Converts a hex color number to an [R, G, B] array
     *
     * @param hex {number}
     * @return {number[]} An array representing the [R, G, B] of the color.
     */
    hex2rgb: function (hex, out)
    {
        out = out || [];

        out[0] = (hex >> 16 & 0xFF) / 255;
        out[1] = (hex >> 8 & 0xFF) / 255;
        out[2] = (hex & 0xFF) / 255;

        return out;
    },

    /**
     * Converts a hex color number to a string.
     *
     * @param hex {number}
     * @return {string} The string color.
     */
    hex2string: function (hex)
    {
        hex = hex.toString(16);
        hex = '000000'.substr(0, 6 - hex.length) + hex;

        return '#' + hex;
    },

    /**
     * Converts a color as an [R, G, B] array to a hex number
     *
     * @param rgb {number[]}
     * @return {number} The color number
     */
    rgb2hex: function (rgb)
    {
        return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);
    },

    /**
     * Checks whether the Canvas BlendModes are supported by the current browser
     *
     * @return {boolean} whether they are supported
     */
    canUseNewCanvasBlendModes: function ()
    {
        if (typeof document === 'undefined')
        {
            return false;
        }

        var canvas = document.createElement('canvas'),
            context = canvas.getContext('2d');

        canvas.width = 1;
        canvas.height = 1;

        context.fillStyle = '#000';
        context.fillRect(0, 0, 1, 1);

        context.globalCompositeOperation = 'multiply';

        context.fillStyle = '#fff';
        context.fillRect(0, 0, 1, 1);

        return context.getImageData(0,0,1,1).data[0] === 0;
    },

    /**
     * Given a number, this function returns the closest number that is a power of two
     * this function is taken from Starling Framework as its pretty neat ;)
     *
     * @param number {number}
     * @return {number} the closest number that is a power of two
     */
    getNextPowerOfTwo: function (number)
    {
        // see: http://en.wikipedia.org/wiki/Power_of_two#Fast_algorithm_to_check_if_a_positive_number_is_a_power_of_two
        if (number > 0 && (number & (number - 1)) === 0)
        {
            return number;
        }
        else
        {
            var result = 1;

            while (result < number)
            {
                result <<= 1;
            }

            return result;
        }
    },

    /**
     * checks if the given width and height make a power of two rectangle
     *
     * @param width {number}
     * @param height {number}
     * @return {boolean}
     */
    isPowerOfTwo: function (width, height)
    {
        return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0);
    },

    /**
     * get the resolution of an asset by looking for the prefix
     * used by spritesheets and image urls
     * TODO make this smarter!
     *
     * @param url {string} the image path
     * @return {boolean}
     */
    getResolutionOfUrl: function (url)
    {
        var resolution = CONST.RETINA_PREFIX.exec(url);

        if (resolution)
        {
           return parseFloat(resolution[1]);
        }

        return 1;
    },

    /**
     * Logs out the version and renderer information for this running instance of PIXI.
     * If you don't want to see this message you can set `PIXI.utils._saidHello = true;`
     * so the library thinks it already said it. Keep in mind that doing that will forever
     * makes you a jerk face.
     *
     * @param {string} type - The string renderer type to log.
     * @constant
     * @static
     */
    sayHello: function (type)
    {
        if (utils._saidHello)
        {
            return;
        }

        if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
        {
            var args = [
                '%c %c %c Pixi.js ' + CONST.VERSION + ' - ' + type + '  %c ' + ' %c ' + ' http://www.pixijs.com/  %c %c ♥%c♥%c♥ ',
                'background: #ff66a5',
                'background: #ff66a5',
                'color: #ff66a5; background: #030307;',
                'background: #ff66a5',
                'background: #ffc3dc',
                'background: #ff66a5',
                'color: #ff2424; background: #fff',
                'color: #ff2424; background: #fff',
                'color: #ff2424; background: #fff'
            ];

            window.console.log.apply(console, args); //jshint ignore:line
        }
        else if (window.console)
        {
            window.console.log('Pixi.js ' + CONST.VERSION + ' - ' + type + ' - http://www.pixijs.com/'); //jshint ignore:line
        }

        utils._saidHello = true;
    },

    TextureCache: {},
    BaseTextureCache: {}
};
<commit_msg>Fix #1308; use @photonstorm's blend mode test<commit_after>var CONST = require('../const');

/**
 * @namespace PIXI.utils
 */
var utils = module.exports = {
    _uid: 0,
    _saidHello: false,

    Ticker:         require('./Ticker'),
    EventData:      require('./EventData'),
    eventTarget:    require('./eventTarget'),
    pluginTarget:   require('./pluginTarget'),
    PolyK:          require('./PolyK'),

    /**
     * Gets the next uuid
     *
     * @return {number} The next uuid to use.
     */
    uuid: function ()
    {
        return ++utils._uid;
    },

    /**
     * Converts a hex color number to an [R, G, B] array
     *
     * @param hex {number}
     * @return {number[]} An array representing the [R, G, B] of the color.
     */
    hex2rgb: function (hex, out)
    {
        out = out || [];

        out[0] = (hex >> 16 & 0xFF) / 255;
        out[1] = (hex >> 8 & 0xFF) / 255;
        out[2] = (hex & 0xFF) / 255;

        return out;
    },

    /**
     * Converts a hex color number to a string.
     *
     * @param hex {number}
     * @return {string} The string color.
     */
    hex2string: function (hex)
    {
        hex = hex.toString(16);
        hex = '000000'.substr(0, 6 - hex.length) + hex;

        return '#' + hex;
    },

    /**
     * Converts a color as an [R, G, B] array to a hex number
     *
     * @param rgb {number[]}
     * @return {number} The color number
     */
    rgb2hex: function (rgb)
    {
        return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);
    },

    /**
     * Checks whether the Canvas BlendModes are supported by the current browser
     *
     * @return {boolean} whether they are supported
     */
    canUseNewCanvasBlendModes: function ()
    {
        if (typeof document === 'undefined') return false;

        var pngHead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/';
        var pngEnd = 'AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';

        var magenta = new Image();
        magenta.src = pngHead + 'AP804Oa6' + pngEnd;

        var yellow = new Image();
        yellow.src = pngHead + '/wCKxvRF' + pngEnd;

        var canvas = document.createElement('canvas');
        canvas.width = 6;
        canvas.height = 1;

        var context = canvas.getContext('2d');
        context.globalCompositeOperation = 'multiply';
        context.drawImage(magenta, 0, 0);
        context.drawImage(yellow, 2, 0);

        var data = context.getImageData(2,0,1,1).data;

        return (data[0] === 255 && data[1] === 0 && data[2] === 0);
    },

    /**
     * Given a number, this function returns the closest number that is a power of two
     * this function is taken from Starling Framework as its pretty neat ;)
     *
     * @param number {number}
     * @return {number} the closest number that is a power of two
     */
    getNextPowerOfTwo: function (number)
    {
        // see: http://en.wikipedia.org/wiki/Power_of_two#Fast_algorithm_to_check_if_a_positive_number_is_a_power_of_two
        if (number > 0 && (number & (number - 1)) === 0)
        {
            return number;
        }
        else
        {
            var result = 1;

            while (result < number)
            {
                result <<= 1;
            }

            return result;
        }
    },

    /**
     * checks if the given width and height make a power of two rectangle
     *
     * @param width {number}
     * @param height {number}
     * @return {boolean}
     */
    isPowerOfTwo: function (width, height)
    {
        return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0);
    },

    /**
     * get the resolution of an asset by looking for the prefix
     * used by spritesheets and image urls
     * TODO make this smarter!
     *
     * @param url {string} the image path
     * @return {boolean}
     */
    getResolutionOfUrl: function (url)
    {
        var resolution = CONST.RETINA_PREFIX.exec(url);

        if (resolution)
        {
           return parseFloat(resolution[1]);
        }

        return 1;
    },

    /**
     * Logs out the version and renderer information for this running instance of PIXI.
     * If you don't want to see this message you can set `PIXI.utils._saidHello = true;`
     * so the library thinks it already said it. Keep in mind that doing that will forever
     * makes you a jerk face.
     *
     * @param {string} type - The string renderer type to log.
     * @constant
     * @static
     */
    sayHello: function (type)
    {
        if (utils._saidHello)
        {
            return;
        }

        if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1)
        {
            var args = [
                '%c %c %c Pixi.js ' + CONST.VERSION + ' - ' + type + '  %c ' + ' %c ' + ' http://www.pixijs.com/  %c %c ♥%c♥%c♥ ',
                'background: #ff66a5',
                'background: #ff66a5',
                'color: #ff66a5; background: #030307;',
                'background: #ff66a5',
                'background: #ffc3dc',
                'background: #ff66a5',
                'color: #ff2424; background: #fff',
                'color: #ff2424; background: #fff',
                'color: #ff2424; background: #fff'
            ];

            window.console.log.apply(console, args); //jshint ignore:line
        }
        else if (window.console)
        {
            window.console.log('Pixi.js ' + CONST.VERSION + ' - ' + type + ' - http://www.pixijs.com/'); //jshint ignore:line
        }

        utils._saidHello = true;
    },

    TextureCache: {},
    BaseTextureCache: {}
};
<|endoftext|>


<commit_before>var utils = require('./utils.js');

var createStateArg = function (action, model, isAsync, compute) {
  var state = Object.keys(model.accessors || {}).reduce(function (state, accessor) {
    state[accessor] = function () {
      var args = [].slice.call(arguments);
      var path = args[0] ? Array.isArray(args[0]) ? args.shift() : [args.shift()] : [];
      return model.accessors[accessor].apply(null, [path].concat(args));
    };
    return state;
  }, {});
  Object.keys(model.mutators || {}).reduce(function (state, mutator) {
    state[mutator] = function () {
      if (isAsync) {
        throw new Error('Cerebral: You can not mutate state in async actions. Output values and set them with a sync action');
      }
      var path = [];
      var args = [].slice.call(arguments);
      if (Array.isArray(args[0])) {
        path = args.shift();
      } else if (typeof args[0] === 'string') {
        path = [args.shift()];
      }
      action.mutations.push({
        name: mutator,
        path: path.slice(),
        args: args
      });
      return model.mutators[mutator].apply(null, [path.slice()].concat(args));
    };
    return state;
  }, state);

  state.getComputed = compute.getComputedValue;

  return state;
};

module.exports = {
  sync: function (action, signalArgs, model, compute) {
    return [
      signalArgs,
      createStateArg(action, model, false, compute)
    ];

  },
  async: function (action, signalArgs, model, compute) {
    return [
      signalArgs,
      createStateArg(action, model, true, compute)
    ];

  }
};
<commit_msg>Fixed state get accessor with computed<commit_after>var utils = require('./utils.js');

var createStateArg = function (action, model, isAsync, compute) {
  var state = Object.keys(model.accessors || {}).reduce(function (state, accessor) {
    state[accessor] = function () {
      var args = [].slice.call(arguments);
      var path = args[0] ? Array.isArray(args[0]) ? args.shift() : [args.shift()] : [];
      if (accessor === 'get' && typeof arguments[0] === 'function') {
        return compute.getComputedValue(arguments[0]);
      }
      return model.accessors[accessor].apply(null, [path].concat(args));
    };
    return state;
  }, {});
  Object.keys(model.mutators || {}).reduce(function (state, mutator) {
    state[mutator] = function () {
      if (isAsync) {
        throw new Error('Cerebral: You can not mutate state in async actions. Output values and set them with a sync action');
      }
      var path = [];
      var args = [].slice.call(arguments);
      if (Array.isArray(args[0])) {
        path = args.shift();
      } else if (typeof args[0] === 'string') {
        path = [args.shift()];
      }
      action.mutations.push({
        name: mutator,
        path: path.slice(),
        args: args
      });
      return model.mutators[mutator].apply(null, [path.slice()].concat(args));
    };
    return state;
  }, state);

  state.getComputed = compute.getComputedValue;

  return state;
};

module.exports = {
  sync: function (action, signalArgs, model, compute) {
    return [
      signalArgs,
      createStateArg(action, model, false, compute)
    ];

  },
  async: function (action, signalArgs, model, compute) {
    return [
      signalArgs,
      createStateArg(action, model, true, compute)
    ];

  }
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';

class Description extends Component {

  render() {
    return (

Description

    );
  }
}
export default Description;
<commit_msg>description page<commit_after>import React, { Component } from 'react';

class Description extends Component {

  render() {
    return (

          Player Name:
          <input className='textinput' style={{width:'160px'}} ref="playerName" />

          Character Name:
          <input className='textinput' style={{width:'160px'}} ref="characterName" />

          Gender:
          <input className='textinput' style={{width:'160px'}} ref="geder" />

          Age:
          <input className='textinput' style={{width:'160px'}} ref="Age" />

          Height:
          <input className='textinput' style={{width:'160px'}} ref="height" />

          Build:
          <input className='textinput' style={{width:'160px'}} ref="build" />

          Hair:
          <input className='textinput' style={{width:'160px'}} ref="hair" />

          Eyes:
          <input className='textinput' style={{width:'160px'}} ref="eyes" />

      <img src={`/Data/SpeciesImages/default.png`}/>
      <button>Select Image</button>

    );
  }
}
export default Description;
<|endoftext|>


<commit_before>// main user interface
// add on set to parent with path string
function addOnSetInterface(_parent, path, action) {
  return durableOnSet(_parent, path.split('.'), action);
}

// bind two object paths together
function mutualBind(a, aPath, b, bPath) {
  var setA = walkAndSet(a, aPath),
    setB = walkAndSet(b, bPath),
    cleanUp = [ // return cleanUp array
      durableOnSet(a, aPath.split('.'), setB),
      durableOnSet(b, bPath.split('.'), setA)
    ];
  return cleanUp;
}

// core of the logic, wrap a member in get/set to allow on set listener
// should only be invoked by onSet
function actionOnSet(_parent, key, action) {
  // ensure the existance of caches
  _parent.bailingWire = _parent.bailingWire || {};
  _parent.bailingWire.value = _parent.bailingWire.value || {};
  // initalize backing value store ( real value )
  _parent.bailingWire.value[key] = _parent[key];
  // check for existing getter / setter
  let descriptor = Object.getOwnPropertyDescriptor(_parent, key);
  let [oldGet, oldSet] = [descriptor.get, descriptor.set];
  Object.defineProperty(_parent, key, {
    set: function(x) {
      // if value has changed
      if (_parent.bailingWire.value[key] !== x) { // replace != with !deep equal?
        // set real value
        _parent.bailingWire.value[key] = x;
        // call listeners
        action.call(this, x);
        if (oldSet) {
          oldSet.call(this, x);
        }
      }
      return x;
    },
    get: function() {
      // get real value
      if(oldGet){ return oldGet.call(this); }
      return _parent.bailingWire.value[key];
    }
  });
}

// handles binding to single item paths
function addOnSet(_parent, key, action) {
  // debug test: keys, not paths
  if (key.indexOf('.') != -1)
    console.error('bad key ', key);
  // detect and divert for array parent
  if (key == 'length' && Array.isArray(_parent))
    return bindToArray(_parent, {
      length: action
    });
  // ensure the existance of caches
  _parent.bailingWire = _parent.bailingWire || {};
  _parent.bailingWire.onSet = _parent.bailingWire.onSet || {};
  // add an onSet callback for the property if none exists
  if (!_parent.bailingWire.onSet[key]) {
    // add action holder
    _parent.bailingWire.onSet[key] = [];
    // define action callback
    var onSet = function(value) {
      callArray(_parent.bailingWire.onSet[key], [value]);
    };
    // add action callback
    actionOnSet(_parent, key, onSet);
  }
  // add action to onSet callback array
  _parent.bailingWire.onSet[key].push(action);
  return (function() {
    //remove action from list
    _parent.bailingWire.onSet[key].splice(_parent.bailingWire.onSet[key].indexOf(action), 1);
  });
}

// recursively walk path and bind regeneration listiners at each step
// add on set to end of path
function durableOnSet(_parent, path, action, cleanUp) {
  cleanUp = cleanUp || [];
  // this is the end of the path, add the real ( user requested ) binding
  if (path.length == 1) {
    // run the action now, if the target exists
    if (_parent[path[0]] !== undefined) {
      action(_parent[path[0]]);
    }
    cleanUp.push(addOnSet(_parent, path[0], action));
  } else {
    var pathCopy = copyArray(path),
      key = pathCopy.shift();
    // follow path down if the next level currently exists
    if (_parent[key] !== undefined) {
      if (isPrimitive(_parent[key])) {
        // next level of path is a primitive
        //  combine remaining path into compound key
        var combinedPath = path.join('.');
        //  define onSet action to be bound to current parent but take it's value from the primitive's property
        var remoteAction = function(primitiveValue) {
          var value = endOfPath(_parent, path);
          action(value);
        };
        //  attach 'jump down' binding
        cleanUp.push(addOnSet(_parent, key, remoteAction));
      } else {
        // current value is not primitive, recurse as normal
        cleanUp.push(durableOnSet(_parent[key], pathCopy, action, cleanUp));
      }
    }
    // define onset action: regenerative binding
    // regenerative binding: calls durable on set when any member of the path is replaced, and rebuilds the bindings on the new values
    // also allows binding to paths that don't yet exist
    var onSet = function(value) {
      if (value !== undefined && !isPrimitive(value))
        durableOnSet(value, pathCopy, action, cleanUp);
    };
    cleanUp.push(addOnSet(_parent, key, onSet));
  }
  return callArray.bind(null, cleanUp);
}
<commit_msg>fixed bug with previous feature which caused an error if the property does not yet exist<commit_after>// main user interface
// add on set to parent with path string
function addOnSetInterface(_parent, path, action) {
  return durableOnSet(_parent, path.split('.'), action);
}

// bind two object paths together
function mutualBind(a, aPath, b, bPath) {
  var setA = walkAndSet(a, aPath),
    setB = walkAndSet(b, bPath),
    cleanUp = [ // return cleanUp array
      durableOnSet(a, aPath.split('.'), setB),
      durableOnSet(b, bPath.split('.'), setA)
    ];
  return cleanUp;
}

// core of the logic, wrap a member in get/set to allow on set listener
// should only be invoked by onSet
function actionOnSet(_parent, key, action) {
  // ensure the existance of caches
  _parent.bailingWire = _parent.bailingWire || {};
  _parent.bailingWire.value = _parent.bailingWire.value || {};
  // initalize backing value store ( real value )
  _parent.bailingWire.value[key] = _parent[key];
  // check for existing getter / setter
  let descriptor = Object.getOwnPropertyDescriptor(_parent, key), oldGet, oldSet;
  if (descriptor) {
    [oldGet, oldSet] = [descriptor.get, descriptor.set];
  }
  Object.defineProperty(_parent, key, {
    set: function(x) {
      // if value has changed
      if (_parent.bailingWire.value[key] !== x) { // replace != with !deep equal?
        // set real value
        _parent.bailingWire.value[key] = x;
        // call listeners
        action.call(this, x);
        if (oldSet) {
          oldSet.call(this, x);
        }
      }
      return x;
    },
    get: function() {
      // get real value
      if (oldGet) {
        return oldGet.call(this);
      }
      return _parent.bailingWire.value[key];
    }
  });
}

// handles binding to single item paths
function addOnSet(_parent, key, action) {
  // debug test: keys, not paths
  if (key.indexOf('.') != -1)
    console.error('bad key ', key);
  // detect and divert for array parent
  if (key == 'length' && Array.isArray(_parent))
    return bindToArray(_parent, {
      length: action
    });
  // ensure the existance of caches
  _parent.bailingWire = _parent.bailingWire || {};
  _parent.bailingWire.onSet = _parent.bailingWire.onSet || {};
  // add an onSet callback for the property if none exists
  if (!_parent.bailingWire.onSet[key]) {
    // add action holder
    _parent.bailingWire.onSet[key] = [];
    // define action callback
    var onSet = function(value) {
      callArray(_parent.bailingWire.onSet[key], [value]);
    };
    // add action callback
    actionOnSet(_parent, key, onSet);
  }
  // add action to onSet callback array
  _parent.bailingWire.onSet[key].push(action);
  return (function() {
    //remove action from list
    _parent.bailingWire.onSet[key].splice(_parent.bailingWire.onSet[key].indexOf(action), 1);
  });
}

// recursively walk path and bind regeneration listiners at each step
// add on set to end of path
function durableOnSet(_parent, path, action, cleanUp) {
  cleanUp = cleanUp || [];
  // this is the end of the path, add the real ( user requested ) binding
  if (path.length == 1) {
    // run the action now, if the target exists
    if (_parent[path[0]] !== undefined) {
      action(_parent[path[0]]);
    }
    cleanUp.push(addOnSet(_parent, path[0], action));
  } else {
    var pathCopy = copyArray(path),
      key = pathCopy.shift();
    // follow path down if the next level currently exists
    if (_parent[key] !== undefined) {
      if (isPrimitive(_parent[key])) {
        // next level of path is a primitive
        //  combine remaining path into compound key
        var combinedPath = path.join('.');
        //  define onSet action to be bound to current parent but take it's value from the primitive's property
        var remoteAction = function(primitiveValue) {
          var value = endOfPath(_parent, path);
          action(value);
        };
        //  attach 'jump down' binding
        cleanUp.push(addOnSet(_parent, key, remoteAction));
      } else {
        // current value is not primitive, recurse as normal
        cleanUp.push(durableOnSet(_parent[key], pathCopy, action, cleanUp));
      }
    }
    // define onset action: regenerative binding
    // regenerative binding: calls durable on set when any member of the path is replaced, and rebuilds the bindings on the new values
    // also allows binding to paths that don't yet exist
    var onSet = function(value) {
      if (value !== undefined && !isPrimitive(value))
        durableOnSet(value, pathCopy, action, cleanUp);
    };
    cleanUp.push(addOnSet(_parent, key, onSet));
  }
  return callArray.bind(null, cleanUp);
}
<|endoftext|>


<commit_before>import React from 'react';
import Octokit from '@octokit/rest';
import styled, { injectGlobal } from 'styled-components';

injectGlobal`
  * {
    box-sizing: border-box;
  }
`;

const Header = styled.h1`
  text-align: center;
`;

const ListItem = styled.li`
  height: 54px;
  width: 400px;
  margin: 5px auto;
  border: 2px solid red;
  font-size: 1.8rem;
  display: flex;
`;

const Avatar = styled.img`
  height: 40px;
  width: 40px;
  border-radius: 50%;
  margin: 5px;
`;

const Username = styled.span`
  flex-grow: 1;
  padding: 8px;
  text-align: center;
`;

const Commits = styled.span`
  padding: 8px;
  border-left: 2px solid red;
  width: 52px;
  text-align: center;
`;

function addCommit(prevState, user) {
  if (!user) {
    return prevState;
  } else {
    const username = user.login;
    const prevLeaderboard = prevState.leaderboard;
    let index;
    const result = prevLeaderboard.find((user, i) => {
      if (user.username === username) {
        index = i;
        return true;
      }
    });
    if (!result) {
      return {
        leaderboard: [
          ...prevLeaderboard,
          { username, commits: 1, avatar: user.avatar_url, url: user.html_url }
        ]
      };
    } else {
      let newLeaderboard = prevLeaderboard;
      newLeaderboard[index].commits += 1;
      return { leaderboard: newLeaderboard };
    }
  }
}

export default class extends React.Component {
  constructor(props) {
    super(props);
    this.state = { leaderboard: [] };
    this.octokit = new Octokit();
  }

  getLeaderboard() {
    this.octokit.repos.getForOrg({ org: 'osdc' }).then(repos => {
      repos.data.forEach(({ name }) => {
        this.octokit.repos.getCommits({ owner: 'osdc', repo: name }).then(commits => {
          commits.data.forEach(commit => {
            const { committer, author } = commit;
            this.setState(prevState => addCommit(prevState, committer));
            this.setState(prevState => addCommit(prevState, author));
          });
        });
      });
    });
  }

  componentDidMount() {
    this.getLeaderboard();
  }

  render() {
    const sorted = this.state.leaderboard.sort((a, b) => {
      return b.commits - a.commits;
    });
    const commitList = sorted.map((user, i) => (
      <ListItem key={i}>
        <Avatar src={user.avatar} />
        <Username>{user.username}</Username>
        <Commits>{user.commits}</Commits>
      </ListItem>
    ));

    return (

        Leaderboard

{commitList}

    );
  }
}
<commit_msg>Improve looks<commit_after>import React from 'react';
import Octokit from '@octokit/rest';
import styled, { injectGlobal } from 'styled-components';

injectGlobal`
  * {
    box-sizing: border-box;
  }
`;

const Header = styled.h1`
  text-align: center;
`;

const Leaderboard = styled.ol`
  padding: 0;
`;

const ListItem = styled.li`
  height: 54px;
  width: 350px;
  margin: 10px auto;
  font-size: 1.8rem;
  display: flex;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
  transition: all 0.2s ease-in-out;
  border-radius: 3px;
  border: 1px solid rgba(0,0,0,0.16);

  &:hover {
    box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
  }
`;

const Avatar = styled.img`
  height: 40px;
  width: 40px;
  border-radius: 50%;
  margin: 5px;
`;

const Username = styled.span`
  flex-grow: 1;
  padding: 8px;
  text-align: center;
`;

const Commits = styled.span`
  padding: 8px;
  width: 52px;
  text-align: center;
  background: rgba(0,0,0,0.12);
  color: white;
`;

function addCommit(prevState, user) {
  if (!user) {
    return prevState;
  } else {
    const username = user.login;
    const prevLeaderboard = prevState.leaderboard;
    let index;
    const result = prevLeaderboard.find((user, i) => {
      if (user.username === username) {
        index = i;
        return true;
      }
    });
    if (!result) {
      return {
        leaderboard: [
          ...prevLeaderboard,
          { username, commits: 1, avatar: user.avatar_url, url: user.html_url }
        ]
      };
    } else {
      let newLeaderboard = prevLeaderboard;
      newLeaderboard[index].commits += 1;
      return { leaderboard: newLeaderboard };
    }
  }
}

export default class extends React.Component {
  constructor(props) {
    super(props);
    this.state = { leaderboard: [] };
    this.octokit = new Octokit();
  }

  getLeaderboard() {
    this.octokit.repos.getForOrg({ org: 'osdc' }).then(repos => {
      repos.data.forEach(({ name }) => {
        this.octokit.repos.getCommits({ owner: 'osdc', repo: name }).then(commits => {
          commits.data.forEach(commit => {
            const { committer, author } = commit;
            this.setState(prevState => addCommit(prevState, committer));
            this.setState(prevState => addCommit(prevState, author));
          });
        });
      });
    });
  }

  componentDidMount() {
    this.getLeaderboard();
  }

  render() {
    const sorted = this.state.leaderboard.sort((a, b) => {
      return b.commits - a.commits;
    });
    const commitList = sorted.map((user, i) => (
      <ListItem key={i}>
        <Avatar src={user.avatar} />
        <Username>{user.username}</Username>
        <Commits>{user.commits}</Commits>
      </ListItem>
    ));

    return (

        Leaderboard
        <Leaderboard>{commitList}</Leaderboard>

    );
  }
}
<|endoftext|>