<commit_before>/**
 * Created by kamalnrf
 */
'use strict';

const redis = require('../services/redis');
const userModel = require('../app/model/userModel');

const msgMe = {
    /**
     * Creates and user and returns true if succesfuly created
     * @param fbID
     * @param userName
     * @returns {boolean}
     */
    createUser(fbID, userName) {
        try{
            redis.setKey(userName, fbID);
            const userRedis = {
                userName: userName,
                isTexting: false,
                Texting: -1,
                isOnline: true
            };
            redis.setHash(fbID, JSON.stringify(userRedis));

            const user = new userModel({
                userName: userName,
                fbID: fbID,
                blockedUsers: []
            });

            user.save((error, user) => {
                if (error) return console.error(error);

                console.log("User has been successfully saved to mongodb");
            });

            return true;
        }catch (error){
            console.log(error);
        }
    },

    /**
     * Returns a promise which has the facbook id of the userName
     * @param userName
     * @return {Promise}
     */
    findUser(userName) {
        return redis.getKey(userName);
    },

    /**
     * Returns a promise which has userName existence boolean.
     * @param userName
     * @returns {Promise}
     */
    isExiting(userName) {
        return new Promise((resolve, reject) => {
            redis.getKey(userName)
                .then(fbID => resolve((fbID !== null)))
                .catch(error => reject(error));
        })
    },

    /**
     * Connects both sender and reciver
     * @param senderID
     * @param recieverID
     * @returns {boolean}
     */
    connect(senderID, recieverID) {
        try {
            redis.setKey(senderID + "isTexting", true);
            redis.setKey(recieverID + "isTexting", true);
            redis.setKey(senderID + "Texting", recieverID);
            redis.setKey(recieverID + "Texting", senderID);

            return true;
        } catch (error) {
            console.log(error);
            return false;
        }
    },

    /**
     * Removes the connection between sender and reciever.
     * @param senderID
     * @param recieverID
     * @returns {boolean}
     */
    disconnect(senderID, recieverID) {
        try {
            redis.setKey(senderID + "isTexting", false);
            redis.setKey(recieverID + "isTexting", false);
            redis.setKey(senderID + "Texting", -1);
            redis.setKey(recieverID + "Texting", -1);

            return true;
        } catch (error) {
            console.log(error);
            return false;
        }
    },

    /**
     * Returns true if fbID is texting
     * @param fbID
     */
    isConnected(fbID) {
        return redis.getKey(fbID + "isTexting");
    },

    /**
     * Returns recieverID
     * @param senderID
     */
    conectedTo(senderID) {
        return redis.getKey(senderID + "Texting");
    },

    /**
     * Returns whether the user is online or not.
     * @param fbId
     */
    isOnline(fbId){
        return redis.getKey(fbId + "isOnline");
    },

    /**
     * Turns the user offline.
     * @param fbId
     * @returns {boolean}
     */
    turnOffline(fbId){
        redis.setKey(fbId + "isOnline", false);

        return true;
    },

    /**
     * Turns the user online.
     * @param fbID
     * @returns {boolean}
     */
    turnOnline(fbID){
        redis.setKey(fbID + "isOnline", true);

        return true;
    },

    /**
     * Returns the username of the facebook ID
     * @param fbID
     */
    getMyName (fbID){
        return redis.getKey(fbID);
    },

    blockUser (blockerID, userName, userFbID){
        userModel.findOne({fbID: blockerID}, (errors, user) => {
            user.blockedUsers.push({
                userName: userName,
                fbID: userFbID
            });
        })
    }
};

module.exports = msgMe;<commit_msg>db changes patch<commit_after>/**
 * Created by kamalnrf
 */
'use strict';

const redis = require('../services/redis');
const userModel = require('../app/model/userModel');

const msgMe = {
    /**
     * Creates and user and returns true if succesfuly created
     * @param fbID
     * @param userName
     * @returns {boolean}
     */
    createUser(fbID, userName) {
        try{
            redis.setKey(userName, fbID);
            const userRedis = {
                userName: userName,
                isTexting: false,
                Texting: -1,
                isOnline: true
            };
            redis.setHash(fbID, userRedis);

            const user = new userModel({
                userName: userName,
                fbID: fbID,
                blockedUsers: []
            });

            user.save((error, user) => {
                if (error) return console.error(error);

                console.log("User has been successfully saved to mongodb");
            });

            return true;
        }catch (error){
            console.log(error);
        }
    },

    /**
     * Returns a promise which has the facbook id of the userName
     * @param userName
     * @return {Promise}
     */
    findUser(userName) {
        return redis.getKey(userName);
    },

    /**
     * Returns a promise which has userName existence boolean.
     * @param userName
     * @returns {Promise}
     */
    isExiting(userName) {
        return new Promise((resolve, reject) => {
            redis.getKey(userName)
                .then(fbID => resolve((fbID !== null)))
                .catch(error => reject(error));
        })
    },

    /**
     * Connects both sender and reciver
     * @param senderID
     * @param recieverID
     * @returns {boolean}
     */
    connect(senderID, recieverID) {
        try {
            redis.setKey(senderID + "isTexting", true);
            redis.setKey(recieverID + "isTexting", true);
            redis.setKey(senderID + "Texting", recieverID);
            redis.setKey(recieverID + "Texting", senderID);

            return true;
        } catch (error) {
            console.log(error);
            return false;
        }
    },

    /**
     * Removes the connection between sender and reciever.
     * @param senderID
     * @param recieverID
     * @returns {boolean}
     */
    disconnect(senderID, recieverID) {
        try {
            redis.setKey(senderID + "isTexting", false);
            redis.setKey(recieverID + "isTexting", false);
            redis.setKey(senderID + "Texting", -1);
            redis.setKey(recieverID + "Texting", -1);

            return true;
        } catch (error) {
            console.log(error);
            return false;
        }
    },

    /**
     * Returns true if fbID is texting
     * @param fbID
     */
    isConnected(fbID) {
        return redis.getKey(fbID + "isTexting");
    },

    /**
     * Returns recieverID
     * @param senderID
     */
    conectedTo(senderID) {
        return redis.getKey(senderID + "Texting");
    },

    /**
     * Returns whether the user is online or not.
     * @param fbId
     */
    isOnline(fbId){
        return redis.getKey(fbId + "isOnline");
    },

    /**
     * Turns the user offline.
     * @param fbId
     * @returns {boolean}
     */
    turnOffline(fbId){
        redis.setKey(fbId + "isOnline", false);

        return true;
    },

    /**
     * Turns the user online.
     * @param fbID
     * @returns {boolean}
     */
    turnOnline(fbID){
        redis.setKey(fbID + "isOnline", true);

        return true;
    },

    /**
     * Returns the username of the facebook ID
     * @param fbID
     */
    getMyName (fbID){
        return redis.getKey(fbID);
    },

    blockUser (blockerID, userName, userFbID){
        userModel.findOne({fbID: blockerID}, (errors, user) => {
            user.blockedUsers.push({
                userName: userName,
                fbID: userFbID
            });
        })
    }
};

module.exports = msgMe;<|endoftext|>


<commit_before>'use strict';

const MetaPlayer = require('../meta/player');

module.exports = class Player {
  /**
   * Initializes all the necessary elements for audio analysis.
   * These ones should be instantiated just once.
   *
   * @return {null}
   */
  static initialize() {
    this.context  = new AudioContext();
    this.analyser = this.context.createAnalyser();

    this.video_source = this.context.createMediaElementSource(MetaPlayer.video);
    this.audio_source = this.context.createMediaElementSource(MetaPlayer.audio);

    this.video_source.connect(this.analyser);
    this.audio_source.connect(this.analyser);

    this.analyser.connect(this.context.destination);

    this.analyser.fftSize = 128;
  }

  /**
   * Finds the record to play in the cache. Once the record
   * is found, delegates to the `start` method.
   *
   * @param  {String}     id          - The record to play's id.
   * @param  {$=|Record=} playlist    - Optionally the current
   *                                    playlist.
   * @param  {Boolean=}   keep_action - Whether to keep the
   *                                    playing action or not.
   * @return {null}
   */
  static preload(id, playlist, keep_action) {
    // Pause the player if the user clicked on
    // the currently playing item, resume if
    // the player is paused.
    if (this.record && id == this.record.id && !this.paused)
      return this.pause();
    else if (this.record && id == this.record.id && this.paused)
      return this.play();

    // Pretty special feature (TM); hides the search bar when the
    // user starts a new media and the search bar is visible. We
    // assume that they found what they want.
    if ($('.sidebar .search-form').is(':visible'))
      Ui.toggleSearchBar();

    var module = Cache.current.module;
    var action = Cache.current.action;

    MetaModel.findById(id, module, action, playlist).then((record) => {
      if (!keep_action) {
        Cache.playing.module = module;
        Cache.playing.action = action;

        // Reset the current queue's mode
        Queue.setMode(null);
      }

      // Start the playing queue and the media itself.
      Queue.start(record, record.set);
      this.start(record);
    });
  }

  /**
   * Starts the player for a given record.
   *
   * @param  {Media} media - The record to play.
   * @return {null}
   */
  static start(media) {
    this.record = media;

    if (media.service != 'local')
      Ui.Player.showLoader();

    if (!media.set)
      Ui.Player.hideCurrentSet();
    else if (media.set)
      Ui.Player.showCurrentSet();

    // Display as soon as possible the correct interface to
    // tell the user that its media is processed.
    Ui.Player.setupInterface();

    MetaPlayer.start(media).then(() => {
      this.play();
    });
  }

  /**
   * Facility to play the current media instance. It just
   * delegates to the instance's `play` method and change
   * the class of the pause button.
   *
   * @return {null}
   */
  static play() {
    MetaPlayer.play();

    Ui.Player.pauseButton();
  }

  /**
   * Plays the next media unless the repeat mode is enabled;
   * in this case, just go to the beginning of the current
   * media.
   *
   * @return {null}
   */
  static playNext() {
    if (this.repeat) {
      this.goTo(0);
      this.play();
    } else {
      Queue.shift().then((set) => {
        this.start(set[0], set[1]);
      });
    }
  }

  /**
   * Plays the previous media unless the current media's time
   * is greater than 5 seconds; in this case, we just rewind
   * it.
   *
   * @return {null}
   */
  static playPrevious() {
    MetaPlayer.currentTime().then((current_time) => {
      if (current_time > 5)
        this.goTo(0);
      else
        Queue.pop().then((set) => {
          this.start(set[0], set[1]);
        });
    })
  }

  /**
   * Ditto `play` but for pausing.
   *
   * @return {null}
   */
  static pause() {
    MetaPlayer.pause();

    Ui.Player.pauseEqualizer();
    Ui.Player.playButton();
  }

  /**
   * Seeks the current media to the given percentage of time
   * and update the position of the progress bar accordingly.
   *
   * @param  {Number} seconds - The duration to go to.
   * @return {null}
   */
  static goTo(seconds) {
    this.auto_progression = true;
    Ui.Player.progression(seconds);
    MetaPlayer.goTo(seconds);
  }

  /**
   * Delegates to the instance's `setVolume` method and
   * updates the volume bar. Also stores the current
   * volume in the user's configuration.
   *
   * @param  {Number}   volume      - The volume between 0 and 1.
   * @param  {Boolean=} skip_config - Whether to save the volume
   *                                  in the configuration or not.
   * @return {null}
   */
  static setVolume(volume, skip_config) {
    Ui.Player.setVolume(volume);

    MetaPlayer.setVolume(volume);

    if (!skip_config)
      Config.store(this.record.service, 'volume', volume);
  }

  /**
   * Mutes or unmutes the current volume.
   *
   * @return {null}
   */
  static toggleMute() {
    var volume = Config.read(this.record.service, 'volume');
    var circle = Ui.Player.volume_circle;

    if (Ui.Player.volume_icon.hasClass('glyphicon-volume-up')) {
      this.setVolume(0, true);
      circle.val(1);
    } else {
      this.setVolume(volume, true);
      circle.val(1 - volume);
    }
  }

  /**
   * Returns whether the player is paused or not.
   *
   * @return {Boolean}
   */
  static get paused() {
    return MetaPlayer.isPaused();
  }

  /**
   * Toggles the repeat mode for the current playing media.
   *
   * @return {null}
   */
  static toggleRepeat() {
    Ui.Player.toggleRepeat();

    this.repeat = !this.repeat;
  }

  /**
   * Changes the playing mode for the current set.
   *
   * @return {null}
   */
  static currentSetMode(mode) {
    Ui.Player.currentSetMode(Queue.mode, mode);

    Queue.mode == mode ? Queue.setMode(null) : Queue.setMode(mode);
  }

  /**
   * Returns a random value from the array returned by the
   * audio context's `getByteFrequencyData` method.
   *
   * This method is used to give an idea of the height of
   * the equalizer bars.
   *
   * @return {Float}
   */
  static sample() {
    var dataArray = new Uint8Array(this.analyser.frequencyBinCount);

    this.analyser.getByteFrequencyData(dataArray);

    return dataArray[Math.floor(Math.random() * (dataArray.length / 2))] / 256;
  }
}
<commit_msg>Allow the `.music.bar` elements to be played<commit_after>'use strict';

const MetaPlayer = require('../meta/player');

module.exports = class Player {
  /**
   * Initializes all the necessary elements for audio analysis.
   * These ones should be instantiated just once.
   *
   * @return {null}
   */
  static initialize() {
    this.context  = new AudioContext();
    this.analyser = this.context.createAnalyser();

    this.video_source = this.context.createMediaElementSource(MetaPlayer.video);
    this.audio_source = this.context.createMediaElementSource(MetaPlayer.audio);

    this.video_source.connect(this.analyser);
    this.audio_source.connect(this.analyser);

    this.analyser.connect(this.context.destination);

    this.analyser.fftSize = 128;
  }

  /**
   * Finds the record to play in the cache. Once the record
   * is found, delegates to the `start` method.
   *
   * @param  {String}     id          - The record to play's id.
   * @param  {$=|Record=} playlist    - Optionally the current
   *                                    playlist.
   * @param  {Boolean=}   keep_action - Whether to keep the
   *                                    playing action or not.
   * @return {null}
   */
  static preload(id, playlist, keep_action) {
    // Pause the player if the user clicked on
    // the currently playing item, resume if
    // the player is paused.
    if (this.record && id == this.record.id && !this.paused)
      return this.pause();
    else if (this.record && id == this.record.id && this.paused)
      return this.play();

    // Pretty special feature (TM); hides the search bar when the
    // user starts a new media and the search bar is visible. We
    // assume that they found what they want.
    if ($('.sidebar .search-form').is(':visible'))
      Ui.toggleSearchBar();

    var module = Cache.current.module;
    var action = Cache.current.action;

    MetaModel.findById(id, module, action, playlist).then((record) => {
      if (!keep_action) {
        Cache.playing.module = module;
        Cache.playing.action = action;

        // Reset the current queue's mode
        Queue.setMode(null);
      }

      // Start the playing queue and the media itself.
      Queue.start(record, record.set);
      this.start(record);
    });
  }

  /**
   * Starts the player for a given record.
   *
   * @param  {Media} media - The record to play.
   * @return {null}
   */
  static start(media) {
    if (media instanceof Activity)
      media = media.item;

    this.record = media;

    if (media.service != 'local')
      Ui.Player.showLoader();

    if (!media.set)
      Ui.Player.hideCurrentSet();
    else if (media.set)
      Ui.Player.showCurrentSet();

    // Display as soon as possible the correct interface to
    // tell the user that its media is processed.
    Ui.Player.setupInterface();

    MetaPlayer.start(media).then(() => {
      this.play();
    });
  }

  /**
   * Facility to play the current media instance. It just
   * delegates to the instance's `play` method and change
   * the class of the pause button.
   *
   * @return {null}
   */
  static play() {
    MetaPlayer.play();

    Ui.Player.pauseButton();
  }

  /**
   * Plays the next media unless the repeat mode is enabled;
   * in this case, just go to the beginning of the current
   * media.
   *
   * @return {null}
   */
  static playNext() {
    if (this.repeat) {
      this.goTo(0);
      this.play();
    } else {
      Queue.shift().then((set) => {
        this.start(set[0], set[1]);
      });
    }
  }

  /**
   * Plays the previous media unless the current media's time
   * is greater than 5 seconds; in this case, we just rewind
   * it.
   *
   * @return {null}
   */
  static playPrevious() {
    MetaPlayer.currentTime().then((current_time) => {
      if (current_time > 5)
        this.goTo(0);
      else
        Queue.pop().then((set) => {
          this.start(set[0], set[1]);
        });
    })
  }

  /**
   * Ditto `play` but for pausing.
   *
   * @return {null}
   */
  static pause() {
    MetaPlayer.pause();

    Ui.Player.pauseEqualizer();
    Ui.Player.playButton();
  }

  /**
   * Seeks the current media to the given percentage of time
   * and update the position of the progress bar accordingly.
   *
   * @param  {Number} seconds - The duration to go to.
   * @return {null}
   */
  static goTo(seconds) {
    this.auto_progression = true;
    Ui.Player.progression(seconds);
    MetaPlayer.goTo(seconds);
  }

  /**
   * Delegates to the instance's `setVolume` method and
   * updates the volume bar. Also stores the current
   * volume in the user's configuration.
   *
   * @param  {Number}   volume      - The volume between 0 and 1.
   * @param  {Boolean=} skip_config - Whether to save the volume
   *                                  in the configuration or not.
   * @return {null}
   */
  static setVolume(volume, skip_config) {
    Ui.Player.setVolume(volume);

    MetaPlayer.setVolume(volume);

    if (!skip_config)
      Config.store(this.record.service, 'volume', volume);
  }

  /**
   * Mutes or unmutes the current volume.
   *
   * @return {null}
   */
  static toggleMute() {
    var volume = Config.read(this.record.service, 'volume');
    var circle = Ui.Player.volume_circle;

    if (Ui.Player.volume_icon.hasClass('glyphicon-volume-up')) {
      this.setVolume(0, true);
      circle.val(1);
    } else {
      this.setVolume(volume, true);
      circle.val(1 - volume);
    }
  }

  /**
   * Returns whether the player is paused or not.
   *
   * @return {Boolean}
   */
  static get paused() {
    return MetaPlayer.isPaused();
  }

  /**
   * Toggles the repeat mode for the current playing media.
   *
   * @return {null}
   */
  static toggleRepeat() {
    Ui.Player.toggleRepeat();

    this.repeat = !this.repeat;
  }

  /**
   * Changes the playing mode for the current set.
   *
   * @return {null}
   */
  static currentSetMode(mode) {
    Ui.Player.currentSetMode(Queue.mode, mode);

    Queue.mode == mode ? Queue.setMode(null) : Queue.setMode(mode);
  }

  /**
   * Returns a random value from the array returned by the
   * audio context's `getByteFrequencyData` method.
   *
   * This method is used to give an idea of the height of
   * the equalizer bars.
   *
   * @return {Float}
   */
  static sample() {
    var dataArray = new Uint8Array(this.analyser.frequencyBinCount);

    this.analyser.getByteFrequencyData(dataArray);

    return dataArray[Math.floor(Math.random() * (dataArray.length / 2))] / 256;
  }
}
<|endoftext|>


<commit_before>"use strict";

var _ = require('underscore');
var xmlshim = require('ltx-dom-shim');

var helpers = require('./helpers');
var types = require('./types');
var find = helpers.find;

var LOOKUP = {};
var LOOKUP_EXT = {};
var TOP_LEVEL_LOOKUP = {};

function topLevel(JXT) {
    var name = JXT.prototype._NS + '|' + JXT.prototype._EL;
    LOOKUP[name] = JXT;
    TOP_LEVEL_LOOKUP[name] = JXT;
}

function toString(xml) {
    return xmlshim.serializeToString(xml);
}

function toJSON(jxt) {
    var prop;
    var result = {};
    var exclude = {
        constructor: true,
        _EL: true,
        _NS: true,
        _extensions: true,
        _name: true,
        parent: true,
        prototype: true,
        toJSON: true,
        toString: true,
        xml: true
    };

    for (prop in jxt._extensions) {
        if (jxt._extensions[prop].toJSON && prop[0] !== '_') {
            result[prop] = jxt._extensions[prop].toJSON();
        }
    }

    for (prop in jxt) {
        if (!exclude[prop] && !((LOOKUP_EXT[jxt._NS + '|' + jxt._EL] || {})[prop]) && !jxt._extensions[prop] && prop[0] !== '_') {
            var val = jxt[prop];
            if (typeof val == 'function') continue;
            var type = Object.prototype.toString.call(val);
            if (type.indexOf('Object') >= 0) {
                if (Object.keys(val).length > 0) {
                    result[prop] = val;
                }
            } else if (type.indexOf('Array') >= 0) {
                if (val.length > 0) {
                    result[prop] = val;
                }
            } else if (!!val) {
                result[prop] = val;
            }
        }
    }

    return result;
}

exports.build = function (xml) {
    var JXT = TOP_LEVEL_LOOKUP[xml.namespaceURI + '|' + xml.localName];
    if (JXT) {
        return new JXT(null, xml);
    }
};

exports.extend = function (ParentJXT, ChildJXT, multiName) {
    var parentName = ParentJXT.prototype._NS + '|' + ParentJXT.prototype._EL;
    var name = ChildJXT.prototype._name;
    var qName = ChildJXT.prototype._NS + '|' + ChildJXT.prototype._EL;

    LOOKUP[qName] = ChildJXT;
    if (!LOOKUP_EXT[qName]) {
        LOOKUP_EXT[qName] = {};
    }
    if (!LOOKUP_EXT[parentName]) {
        LOOKUP_EXT[parentName] = {};
    }
    LOOKUP_EXT[parentName][name] = ChildJXT;

    exports.add(ParentJXT, name, types.extension(ChildJXT));
    if (multiName) {
        exports.add(ParentJXT, multiName, types.multiExtension(ChildJXT));
    }
};

exports.add = function (ParentJXT, fieldName, field) {
    field.enumerable = true;
    Object.defineProperty(ParentJXT.prototype, fieldName, field);
};

exports.define = function (opts) {
    var StanzaConstructor = function (data, xml, parent) {
        var self = this;

        var parentNode = (xml || {}).parentNode || (parent || {}).xml;
        var parentNS = (parentNode || {}).namespaceURI;

        self.xml = xml || helpers.createElement(self._NS, self._EL, parentNS);

        var prefixes = opts.prefixes || {};
        _.each(opts.prefixes || {}, function (namespace, prefix) {
            self.xml.setAttribute('xmlns:' + prefix, namespace);
        });

        self._extensions = {};

        _.each(self.xml.childNodes, function (child) {
            var childName = child.namespaceURI + '|' + child.localName;
            var ChildJXT = LOOKUP[childName];
            if (ChildJXT !== undefined) {
                var name = ChildJXT.prototype._name;
                self._extensions[name] = new ChildJXT(null, child);
                self._extensions[name].parent = self;
            }
        });

        _.extend(self, data);

        if (opts.init) {
            var init = opts.init.bind(self);
            init(data);
        }

        return self;
    };

    StanzaConstructor.prototype = {
        constructor: {
            value: StanzaConstructor
        },
        _name: opts.name,
        _eventname: opts.eventName,
        _NS: opts.namespace,
        _EL: opts.element,
        toString: function () { return toString(this.xml); },
        toJSON: function () { return toJSON(this); }
    };

    var fieldNames = Object.keys(opts.fields || {});
    fieldNames.forEach(function (fieldName) {
        exports.add(StanzaConstructor, fieldName, opts.fields[fieldName]);
    });

    if (opts.topLevel) {
        topLevel(StanzaConstructor);
    }

    return StanzaConstructor;
};
<commit_msg>Use apply() to make things cleaner<commit_after>"use strict";

var _ = require('underscore');
var xmlshim = require('ltx-dom-shim');

var helpers = require('./helpers');
var types = require('./types');
var find = helpers.find;

var LOOKUP = {};
var LOOKUP_EXT = {};
var TOP_LEVEL_LOOKUP = {};

function topLevel(JXT) {
    var name = JXT.prototype._NS + '|' + JXT.prototype._EL;
    LOOKUP[name] = JXT;
    TOP_LEVEL_LOOKUP[name] = JXT;
}

function toString(xml) {
    return xmlshim.serializeToString(xml);
}

function toJSON(jxt) {
    var prop;
    var result = {};
    var exclude = {
        constructor: true,
        _EL: true,
        _NS: true,
        _extensions: true,
        _name: true,
        parent: true,
        prototype: true,
        toJSON: true,
        toString: true,
        xml: true
    };

    for (prop in jxt._extensions) {
        if (jxt._extensions[prop].toJSON && prop[0] !== '_') {
            result[prop] = jxt._extensions[prop].toJSON();
        }
    }

    for (prop in jxt) {
        if (!exclude[prop] && !((LOOKUP_EXT[jxt._NS + '|' + jxt._EL] || {})[prop]) && !jxt._extensions[prop] && prop[0] !== '_') {
            var val = jxt[prop];
            if (typeof val == 'function') continue;
            var type = Object.prototype.toString.call(val);
            if (type.indexOf('Object') >= 0) {
                if (Object.keys(val).length > 0) {
                    result[prop] = val;
                }
            } else if (type.indexOf('Array') >= 0) {
                if (val.length > 0) {
                    result[prop] = val;
                }
            } else if (!!val) {
                result[prop] = val;
            }
        }
    }

    return result;
}

exports.build = function (xml) {
    var JXT = TOP_LEVEL_LOOKUP[xml.namespaceURI + '|' + xml.localName];
    if (JXT) {
        return new JXT(null, xml);
    }
};

exports.extend = function (ParentJXT, ChildJXT, multiName) {
    var parentName = ParentJXT.prototype._NS + '|' + ParentJXT.prototype._EL;
    var name = ChildJXT.prototype._name;
    var qName = ChildJXT.prototype._NS + '|' + ChildJXT.prototype._EL;

    LOOKUP[qName] = ChildJXT;
    if (!LOOKUP_EXT[qName]) {
        LOOKUP_EXT[qName] = {};
    }
    if (!LOOKUP_EXT[parentName]) {
        LOOKUP_EXT[parentName] = {};
    }
    LOOKUP_EXT[parentName][name] = ChildJXT;

    exports.add(ParentJXT, name, types.extension(ChildJXT));
    if (multiName) {
        exports.add(ParentJXT, multiName, types.multiExtension(ChildJXT));
    }
};

exports.add = function (ParentJXT, fieldName, field) {
    field.enumerable = true;
    Object.defineProperty(ParentJXT.prototype, fieldName, field);
};

exports.define = function (opts) {
    var StanzaConstructor = function (data, xml, parent) {
        var self = this;

        var parentNode = (xml || {}).parentNode || (parent || {}).xml;
        var parentNS = (parentNode || {}).namespaceURI;

        self.xml = xml || helpers.createElement(self._NS, self._EL, parentNS);

        var prefixes = opts.prefixes || {};
        _.each(opts.prefixes || {}, function (namespace, prefix) {
            self.xml.setAttribute('xmlns:' + prefix, namespace);
        });

        self._extensions = {};

        _.each(self.xml.childNodes, function (child) {
            var childName = child.namespaceURI + '|' + child.localName;
            var ChildJXT = LOOKUP[childName];
            if (ChildJXT !== undefined) {
                var name = ChildJXT.prototype._name;
                self._extensions[name] = new ChildJXT(null, child);
                self._extensions[name].parent = self;
            }
        });

        _.extend(self, data);

        if (opts.init) {
            opts.init.apply(self, [data]);
        }

        return self;
    };

    StanzaConstructor.prototype = {
        constructor: {
            value: StanzaConstructor
        },
        _name: opts.name,
        _eventname: opts.eventName,
        _NS: opts.namespace,
        _EL: opts.element,
        toString: function () { return toString(this.xml); },
        toJSON: function () { return toJSON(this); }
    };

    var fieldNames = Object.keys(opts.fields || {});
    fieldNames.forEach(function (fieldName) {
        exports.add(StanzaConstructor, fieldName, opts.fields[fieldName]);
    });

    if (opts.topLevel) {
        topLevel(StanzaConstructor);
    }

    return StanzaConstructor;
};
<|endoftext|>


<commit_before>//= require "meta"
//= require "lib/jquery-1.3.2.min"
//= require "lib/quicksilver"
//= require "lib/json2.min.js"
//= require "repo_search"
//= require "analyze"
//= require "repo_info"
//= require "user_info"
//= require "info"<commit_msg>Removing quicksilver from the sprockets includes<commit_after>//= require "meta"
//= require "lib/jquery-1.3.2.min"
//= require "lib/json2.min.js"
//= require "lib/json_search.0.9.0.js"
//= require "repo_search"
//= require "analyze"
//= require "repo_info"
//= require "user_info"
//= require "info"<|endoftext|>


<commit_before>import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
    this.route("login", {path: "/login"});
    this.route("about", {path: "/about"});
    this.resource("add-to-home-screen", {path: "/add-to-home-screen"});
    this.resource("mobile-tasks", {path: "/mobile-tasks"});
    this.route("create-task", {path: "/create-task"});
    this.route("edit-task", {path: "/edit-task/:uuid"});
    this.resource("tasks", function(){
        this.resource("task", {path: "/:uuid"});
    });
    this.resource("activity-log", {path: "/activity-log"});
    this.route("configure", {path: "/configure"});
    this.route("getting-started", {path: "/getting-started"});
    this.route("terms-of-Service", {path: "/terms-of-service"});
    this.route("four-oh-four", {path: "*path"});
});

export default Router;
<commit_msg>Fixing bug in router w/r/t TOS acceptance.<commit_after>import Ember from 'ember';
import config from './config/environment';

var Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
    this.route("login", {path: "/login"});
    this.route("about", {path: "/about"});
    this.resource("add-to-home-screen", {path: "/add-to-home-screen"});
    this.resource("mobile-tasks", {path: "/mobile-tasks"});
    this.route("create-task", {path: "/create-task"});
    this.route("edit-task", {path: "/edit-task/:uuid"});
    this.resource("tasks", function(){
        this.resource("task", {path: "/:uuid"});
    });
    this.resource("activity-log", {path: "/activity-log"});
    this.route("configure", {path: "/configure"});
    this.route("getting-started", {path: "/getting-started"});
    this.route("terms-of-service", {path: "/terms-of-service"});
    this.route("four-oh-four", {path: "*path"});
});

export default Router;
<|endoftext|>


<commit_before>/* -*- mode: espresso; espresso-indent-level: 8; indent-tabs-mode: t -*- */
/**
 * tilelayer.js
 *
 * requirements:
 *	 tools.js
 *	 ui.js
 *	 slider.js
 *
 * @todo redo all public interfaces to use physical coordinates instead of pixel coordinates
 */

/**
 * Get the part of the tile name that consists of dimensions z, t, ...
 * For a 3D stack this will return "z/", for a 4D stack "t/z/", etc.
 *
 * @param pixelPos pixel position of the stack [x, y, z, t, ...]
 */
function getTileBaseName( pixelPos )
{
	var n = pixelPos.length;
	var dir = ""
	for ( var i = n - 1; i > 1; --i )
	{
		dir += pixelPos[ i ] + "/";
	}
	return dir;
}

function getTileBaseName3D( stack, pixelPos, adjacent )
{
  if(!adjacent) {
    adjacent = 0;
  }
  var z = pixelPos[ 2 ] + adjacent;
  if( z < 0 ) {
    z = 0;
  }
  if( z > stack.slices[stack.slices.length-1] ) {
    z = stack.slices[stack.slices.length-1];
  }
  if( $.inArray(z, stack.slices) === -1 ) {
    return null;
  }
  return z + "/";
}

/**
 *
 */
function TileLayer(
		stack,						//!< reference to the parent stack
		baseURL,					//!< base URL for image tiles
		tileWidth,
		tileHeight,
		fileExtension,
		tileSourceType
		)
{
	/**
	 * initialise the tiles array
	 */
	var initTiles = function( rows, cols )
	{
		while ( tilesContainer.firstChild )
			tilesContainer.removeChild( tilesContainer.firstChild );

		delete tiles;
		tiles = new Array();

		for ( var i = 0; i < rows; ++i )
		{
			tiles[ i ] = new Array();
			for ( var j = 0; j < cols; ++j )
			{
				tiles[ i ][ j ] = document.createElement( "img" );
				tiles[ i ][ j ].alt = "empty";
				tiles[ i ][ j ].src = "widgets/empty256.gif";

				tilesContainer.appendChild( tiles[ i ][ j ] );
			}
		}
		return;
	}

	/**
	 * align and update the tiles to be ( x, y ) in the image center
	 */
	this.redraw = function(completionCallback)
	{
		var pixelPos = [ stack.x, stack.y, stack.z ];
		var tileBaseName = getTileBaseName( pixelPos );

		var zoom = stack.s;
		var mag = 1.0;
		var artificialZoom = false;
		/* If the zoom is negative we zoom in digitally. For this
		 * we take the zero zoom level and adjust the tile properties.
		 * This way we let the browser do the zooming work.
		 */
		if (zoom < 0) {
			artificialZoom = true;
			mag = Math.pow(2, -zoom);
			zoom = 0;
		}

		effectiveTileWidth = tileWidth * mag;
		effectiveTileHeight = tileHeight * mag;

		var fr = Math.floor( stack.yc / effectiveTileHeight );
		var fc = Math.floor( stack.xc / effectiveTileWidth );

		var xd = 0;
		var yd = 0;

		if ( stack.z == stack.old_z && stack.s == stack.old_s )
		{
			var old_fr = Math.floor( stack.old_yc / effectiveTileHeight );
			var old_fc = Math.floor( stack.old_xc / effectiveTileWidth );

			xd = fc - old_fc;
			yd = fr - old_fr;

			// re-order the tiles array on demand
			if ( xd < 0 )
			{
				for ( var i = 0; i < tiles.length; ++i )
				{
					tilesContainer.removeChild( tiles[ i ].pop() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					tiles[ i ].unshift( img );
				}
			}
			else if ( xd > 0 )
			{
				for ( var i = 0; i < tiles.length; ++i )
				{
					tilesContainer.removeChild( tiles[ i ].shift() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					tiles[ i ].push( img );
				}
			}
			else if ( yd < 0 )
			{
				var old_row = tiles.pop();
				var new_row = new Array();
				for ( var i = 0; i < tiles[ 0 ].length; ++i )
				{
					tilesContainer.removeChild( old_row.pop() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					new_row.push( img );
				}
				tiles.unshift( new_row );
			}
			else if ( yd > 0 )
			{
				var old_row = tiles.shift();
				var new_row = new Array();
				for ( var i = 0; i < tiles[ 0 ].length; ++i )
				{
					tilesContainer.removeChild( old_row.pop() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					new_row.push( img );
				}
				tiles.push( new_row );
			}
		}

		if ( stack.s != stack.old_s)
		{
			if (artificialZoom)
			{
				LAST_XT = Math.floor( ( stack.dimension.x - 1 ) / tileWidth );
				LAST_YT = Math.floor( ( stack.dimension.y - 1 ) / tileHeight );
			}
			else
			{
				LAST_XT = Math.floor( ( stack.dimension.x * stack.scale - 1 ) / tileWidth );
				LAST_YT = Math.floor( ( stack.dimension.y * stack.scale - 1 ) / tileHeight );
			}
		}

		var top;
		var left;

		if ( stack.yc >= 0 )
			top  = -( stack.yc % effectiveTileHeight );
		else
			top  = -( ( stack.yc + 1 ) % effectiveTileHeight ) - effectiveTileHeight + 1;
		if ( stack.xc >= 0 )
			left = -( stack.xc % effectiveTileWidth );
		else
			left = -( ( stack.xc + 1 ) % effectiveTileWidth ) - effectiveTileWidth + 1;

		var t = top;
		var l = left;

		// update the images sources
		for ( var i = 0; i < tiles.length; ++i )
		{
			var r = fr + i;
			for ( var j = 0; j < tiles[ 0 ].length; ++j )
			{
				var c = fc + j;

				/**
				 * TODO Test if updating the URLs always was required to
				 * guarantee homogeneous update speed for modulo-changing steps
				 * and non-modulo changing steps.  Write more comments in
				 * general.
				 */
				if ( r < 0 || c < 0 || r > LAST_YT || c > LAST_XT )
				{
					tiles[ i ][ j ].alt = "";
					tiles[ i ][ j ].src = "widgets/black.gif";
				}
				else
				{
					// TODO: use this for the new tile naming scheme:
					// tiles[ i ][ j ].alt = tileBaseName + stack.s + "/" + ( fr + i ) + "/" + ( fc + j );
					if( tileSourceType === 1 ) {
					    tiles[ i ][ j ].alt = tileBaseName + r + "_" + c + "_" + zoom;
					    tiles[ i ][ j ].src = self.getTileURL( tiles[ i ][ j ].alt );
          } else if ( tileSourceType === 2 ) {
					    tiles[ i ][ j ].alt = tileBaseName + r + "_" + c + "_" + zoom;
					    tiles[ i ][ j ].src = self.getTileURLRequest( c * tileWidth, r * tileHeight, tileWidth, tileHeight, stack.scale, stack.z );
          } else if ( tileSourceType === 3 ) {
					    tiles[ i ][ j ].alt = tileBaseName + r + "_" + c + "_" + zoom;
					    tiles[ i ][ j ].src = self.getTileHDF5Request( c * tileWidth, r * tileHeight, tileWidth, tileHeight, stack.scale, stack.z );
					}

          // prefetch tiles
            // TODO: fetch information in stack table: -2, -1, 1, 2
            var adj = [], tmpimg = new Image(), tmptileBaseName;
          for( var jj in adj ) {
            tmptileBaseName = getTileBaseName3D( stack, pixelPos, adj[jj] );
            // only prefetch for type 1
            if( tileSourceType === 1 ) {
              tmpimg.src = self.getTileURL( tmptileBaseName + r + "_" + c + "_" + zoom );
            }
          }

				}
				tiles[ i ][ j ].style.top = t + "px";
				tiles[ i ][ j ].style.left = l + "px";
				tiles[ i ][ j ].style.visibility = "visible";

				tiles[ i ][ j ].style.width = effectiveTileWidth + "px";
				tiles[ i ][ j ].style.height = effectiveTileHeight + "px";

				l += effectiveTileWidth;

			}
			l = left;
			t += effectiveTileHeight;
		}

		if (typeof completionCallback !== "undefined") {
			completionCallback();
		}

		return 2;
	}

	/**
	 * Creates the URL for a tile in a generic way.
     * To be used for instance for Volumina served datasources
	 */
    this.getTileURLRequest = function( x, y, dx, dy, scale, z ) {
    return baseURL + "?" + $.param({
        x: x,
        y: y,
        width : tileWidth,
        height : tileHeight,
        row : 'y',
        col : 'x',
        scale : scale, // defined as 1/2**zoomlevel
        z : z});
    }

  /*
   * Get Tile from HDF5 through Django (tiles_source_type == 3)
   */
  this.getTileHDF5Request = function( x, y, dx, dy, scale, z ) {
    return django_url + project.id + '/stack/' + stack.id + '/tile?' + $.param({
        x: x,
        y: y,
        width : tileWidth,
        height : tileHeight,
        row : 'y',
        col : 'x',
        scale : stack.s, // defined as 1/2**zoomlevel
        z : z,
        file_extension: fileExtension,
        hdf5_path: baseURL // image_base refers to path within HDF5 to dataset
    });
  }

	/**
	 * Creates the URL for a tile.
	 */
	this.getTileURL = function(tileId) {
		return baseURL + tileId + "." + fileExtension;
	}

	this.resize = function( width, height )
	{
//		alert( "resize tileLayer of stack" + stack.getId() );

		/* TODO 2 more?  Should be 1---not?! */
		var rows = Math.floor( height / tileHeight ) + 2;
		var cols = Math.floor( width / tileWidth ) + 2;
		initTiles( rows, cols );
		self.redraw();
		return;
	}

	/**
	 * Get the width of an image tile.
	 */
	this.getTileWidth = function(){ return tileWidth; }

	/**
	 * Get the height of an image tile.
	 */
	this.getTileHeight = function(){ return tileHeight; }

	/**
	 * Get the number of tile columns.
	 */
	this.numTileColumns = function()
	{
		if ( tiles.length == 0 )
			return 0;
		else
			return tiles[ 0 ].length;
	}

	/**
	 * Get the number of tile rows.
	 */
	this.numTileColumns = function(){ return tiles.length; }

	/**
	 * Get the stack.
	 */
	this.getStack = function(){ return stack; }

	var OverviewLayer = function()
	{
		this.redraw = function()
		{
            if( tileSourceType === 1 ) {
                img.src = baseURL + stack.z + "/small." + fileExtension;
            }
			return;
		}

		this.unregister = function()
		{
			if ( img.parentNode )
				img.parentNode.removeChild( img );
		}

		var self = this;

		var img = document.createElement( "img" );
		img.className = "smallMapMap";
		img.src = baseURL + stack.z + "/small." + fileExtension;

		stack.overview.getView().appendChild( img );
		stack.overview.addLayer( "tilelayer", this );
	}

	this.setOpacity = function( val )
	{
		tilesContainer.style.opacity = val+"";
		opacity = val;
	}

	this.getOpacity = function()
	{
		return opacity;
	}

	// initialise
	var self = this;

	// internal opacity variable
	var opacity = 100;

	/* Contains all tiles in a 2d-array */
	var tiles = new Array();

	var tilesContainer = document.createElement( "div" );
	tilesContainer.className = "sliceTiles";
	stack.getView().appendChild( tilesContainer );

    var overviewLayer = new OverviewLayer();

	var LAST_XT = Math.floor( ( stack.dimension.x * stack.scale - 1 ) / tileWidth );
	var LAST_YT = Math.floor( ( stack.dimension.y * stack.scale - 1 ) / tileHeight );

	self.baseURL = baseURL;
}
<commit_msg>Refactor creation of tile URL in tile layer<commit_after>/* -*- mode: espresso; espresso-indent-level: 8; indent-tabs-mode: t -*- */
/**
 * tilelayer.js
 *
 * requirements:
 *	 tools.js
 *	 ui.js
 *	 slider.js
 *
 * @todo redo all public interfaces to use physical coordinates instead of pixel coordinates
 */

/**
 * Get the part of the tile name that consists of dimensions z, t, ...
 * For a 3D stack this will return "z/", for a 4D stack "t/z/", etc.
 *
 * @param pixelPos pixel position of the stack [x, y, z, t, ...]
 */
function getTileBaseName( pixelPos )
{
	var n = pixelPos.length;
	var dir = ""
	for ( var i = n - 1; i > 1; --i )
	{
		dir += pixelPos[ i ] + "/";
	}
	return dir;
}

function getTileBaseName3D( stack, pixelPos, adjacent )
{
  if(!adjacent) {
    adjacent = 0;
  }
  var z = pixelPos[ 2 ] + adjacent;
  if( z < 0 ) {
    z = 0;
  }
  if( z > stack.slices[stack.slices.length-1] ) {
    z = stack.slices[stack.slices.length-1];
  }
  if( $.inArray(z, stack.slices) === -1 ) {
    return null;
  }
  return z + "/";
}

/**
 *
 */
function TileLayer(
		stack,						//!< reference to the parent stack
		baseURL,					//!< base URL for image tiles
		tileWidth,
		tileHeight,
		fileExtension,
		tileSourceType
		)
{
	/**
	 * initialise the tiles array
	 */
	var initTiles = function( rows, cols )
	{
		while ( tilesContainer.firstChild )
			tilesContainer.removeChild( tilesContainer.firstChild );

		delete tiles;
		tiles = new Array();

		for ( var i = 0; i < rows; ++i )
		{
			tiles[ i ] = new Array();
			for ( var j = 0; j < cols; ++j )
			{
				tiles[ i ][ j ] = document.createElement( "img" );
				tiles[ i ][ j ].alt = "empty";
				tiles[ i ][ j ].src = "widgets/empty256.gif";

				tilesContainer.appendChild( tiles[ i ][ j ] );
			}
		}
		return;
	}

	/**
	 * align and update the tiles to be ( x, y ) in the image center
	 */
	this.redraw = function(completionCallback)
	{
		var pixelPos = [ stack.x, stack.y, stack.z ];
		var tileBaseName = getTileBaseName( pixelPos );

		var zoom = stack.s;
		var mag = 1.0;
		var artificialZoom = false;
		/* If the zoom is negative we zoom in digitally. For this
		 * we take the zero zoom level and adjust the tile properties.
		 * This way we let the browser do the zooming work.
		 */
		if (zoom < 0) {
			artificialZoom = true;
			mag = Math.pow(2, -zoom);
			zoom = 0;
		}

		effectiveTileWidth = tileWidth * mag;
		effectiveTileHeight = tileHeight * mag;

		var fr = Math.floor( stack.yc / effectiveTileHeight );
		var fc = Math.floor( stack.xc / effectiveTileWidth );

		var xd = 0;
		var yd = 0;

		if ( stack.z == stack.old_z && stack.s == stack.old_s )
		{
			var old_fr = Math.floor( stack.old_yc / effectiveTileHeight );
			var old_fc = Math.floor( stack.old_xc / effectiveTileWidth );

			xd = fc - old_fc;
			yd = fr - old_fr;

			// re-order the tiles array on demand
			if ( xd < 0 )
			{
				for ( var i = 0; i < tiles.length; ++i )
				{
					tilesContainer.removeChild( tiles[ i ].pop() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					tiles[ i ].unshift( img );
				}
			}
			else if ( xd > 0 )
			{
				for ( var i = 0; i < tiles.length; ++i )
				{
					tilesContainer.removeChild( tiles[ i ].shift() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					tiles[ i ].push( img );
				}
			}
			else if ( yd < 0 )
			{
				var old_row = tiles.pop();
				var new_row = new Array();
				for ( var i = 0; i < tiles[ 0 ].length; ++i )
				{
					tilesContainer.removeChild( old_row.pop() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					new_row.push( img );
				}
				tiles.unshift( new_row );
			}
			else if ( yd > 0 )
			{
				var old_row = tiles.shift();
				var new_row = new Array();
				for ( var i = 0; i < tiles[ 0 ].length; ++i )
				{
					tilesContainer.removeChild( old_row.pop() );
					var img = document.createElement( "img" );
					img.alt = "empty";
					img.src = "widgets/empty256.gif";
					img.style.visibility = "hidden";
					tilesContainer.appendChild( img );
					new_row.push( img );
				}
				tiles.push( new_row );
			}
		}

		if ( stack.s != stack.old_s)
		{
			if (artificialZoom)
			{
				LAST_XT = Math.floor( ( stack.dimension.x - 1 ) / tileWidth );
				LAST_YT = Math.floor( ( stack.dimension.y - 1 ) / tileHeight );
			}
			else
			{
				LAST_XT = Math.floor( ( stack.dimension.x * stack.scale - 1 ) / tileWidth );
				LAST_YT = Math.floor( ( stack.dimension.y * stack.scale - 1 ) / tileHeight );
			}
		}

		var top;
		var left;

		if ( stack.yc >= 0 )
			top  = -( stack.yc % effectiveTileHeight );
		else
			top  = -( ( stack.yc + 1 ) % effectiveTileHeight ) - effectiveTileHeight + 1;
		if ( stack.xc >= 0 )
			left = -( stack.xc % effectiveTileWidth );
		else
			left = -( ( stack.xc + 1 ) % effectiveTileWidth ) - effectiveTileWidth + 1;

		var t = top;
		var l = left;

		// update the images sources
		for ( var i = 0; i < tiles.length; ++i )
		{
			var r = fr + i;
			for ( var j = 0; j < tiles[ 0 ].length; ++j )
			{
				var c = fc + j;

				/**
				 * TODO Test if updating the URLs always was required to
				 * guarantee homogeneous update speed for modulo-changing steps
				 * and non-modulo changing steps.  Write more comments in
				 * general.
				 */
				if ( r < 0 || c < 0 || r > LAST_YT || c > LAST_XT )
				{
					tiles[ i ][ j ].alt = "";
					tiles[ i ][ j ].src = "widgets/black.gif";
				}
				else
				{
					// TODO: use this for the new tile naming scheme:
					// tiles[ i ][ j ].alt = tileBaseName + stack.s + "/" + ( fr + i ) + "/" + ( fc + j );
					if( tileSourceType === 1 ) {
					    tiles[ i ][ j ].alt = tileBaseName + r + "_" + c + "_" + zoom;
					    tiles[ i ][ j ].src = self.getTileURL( tileBaseName, stack.z, c, r, zoom );
                    } else if ( tileSourceType === 2 ) {
					    tiles[ i ][ j ].alt = tileBaseName + r + "_" + c + "_" + zoom;
					    tiles[ i ][ j ].src = self.getTileURLRequest( c * tileWidth, r * tileHeight, tileWidth, tileHeight, stack.scale, stack.z );
          } else if ( tileSourceType === 3 ) {
					    tiles[ i ][ j ].alt = tileBaseName + r + "_" + c + "_" + zoom;
					    tiles[ i ][ j ].src = self.getTileHDF5Request( c * tileWidth, r * tileHeight, tileWidth, tileHeight, stack.scale, stack.z );
					}

          // prefetch tiles
            // TODO: fetch information in stack table: -2, -1, 1, 2
            var adj = [], tmpimg = new Image(), tmptileBaseName;
          for( var jj in adj ) {
            tmptileBaseName = getTileBaseName3D( stack, pixelPos, adj[jj] );
            // only prefetch for type 1
            if( tileSourceType === 1 ) {
              tmpimg.src = self.getTileURL( tmptileBaseName + r + "_" + c + "_" + zoom );
            }
          }

				}
				tiles[ i ][ j ].style.top = t + "px";
				tiles[ i ][ j ].style.left = l + "px";
				tiles[ i ][ j ].style.visibility = "visible";

				tiles[ i ][ j ].style.width = effectiveTileWidth + "px";
				tiles[ i ][ j ].style.height = effectiveTileHeight + "px";

				l += effectiveTileWidth;

			}
			l = left;
			t += effectiveTileHeight;
		}

		if (typeof completionCallback !== "undefined") {
			completionCallback();
		}

		return 2;
	}

	/**
	 * Creates the URL for a tile in a generic way.
     * To be used for instance for Volumina served datasources
	 */
    this.getTileURLRequest = function( x, y, dx, dy, scale, z ) {
    return baseURL + "?" + $.param({
        x: x,
        y: y,
        width : tileWidth,
        height : tileHeight,
        row : 'y',
        col : 'x',
        scale : scale, // defined as 1/2**zoomlevel
        z : z});
    }

  /*
   * Get Tile from HDF5 through Django (tiles_source_type == 3)
   */
  this.getTileHDF5Request = function( x, y, dx, dy, scale, z ) {
    return django_url + project.id + '/stack/' + stack.id + '/tile?' + $.param({
        x: x,
        y: y,
        width : tileWidth,
        height : tileHeight,
        row : 'y',
        col : 'x',
        scale : stack.s, // defined as 1/2**zoomlevel
        z : z,
        file_extension: fileExtension,
        hdf5_path: baseURL // image_base refers to path within HDF5 to dataset
    });
  }

	/**
	 * Creates the URL for a tile.
	 */
	this.getTileURL = function( tileBaseName, slice, x_tile, y_tile, zoom_level )
	{
		return baseURL + tileBaseName + y_tile + "_" + x_tile + "_" + zoom_level + "." + fileExtension;
	}

	this.resize = function( width, height )
	{
//		alert( "resize tileLayer of stack" + stack.getId() );

		/* TODO 2 more?  Should be 1---not?! */
		var rows = Math.floor( height / tileHeight ) + 2;
		var cols = Math.floor( width / tileWidth ) + 2;
		initTiles( rows, cols );
		self.redraw();
		return;
	}

	/**
	 * Get the width of an image tile.
	 */
	this.getTileWidth = function(){ return tileWidth; }

	/**
	 * Get the height of an image tile.
	 */
	this.getTileHeight = function(){ return tileHeight; }

	/**
	 * Get the number of tile columns.
	 */
	this.numTileColumns = function()
	{
		if ( tiles.length == 0 )
			return 0;
		else
			return tiles[ 0 ].length;
	}

	/**
	 * Get the number of tile rows.
	 */
	this.numTileColumns = function(){ return tiles.length; }

	/**
	 * Get the stack.
	 */
	this.getStack = function(){ return stack; }

	var OverviewLayer = function()
	{
		this.redraw = function()
		{
            if( tileSourceType === 1 ) {
                img.src = baseURL + stack.z + "/small." + fileExtension;
            }
			return;
		}

		this.unregister = function()
		{
			if ( img.parentNode )
				img.parentNode.removeChild( img );
		}

		var self = this;

		var img = document.createElement( "img" );
		img.className = "smallMapMap";
		img.src = baseURL + stack.z + "/small." + fileExtension;

		stack.overview.getView().appendChild( img );
		stack.overview.addLayer( "tilelayer", this );
	}

	this.setOpacity = function( val )
	{
		tilesContainer.style.opacity = val+"";
		opacity = val;
	}

	this.getOpacity = function()
	{
		return opacity;
	}

	// initialise
	var self = this;

	// internal opacity variable
	var opacity = 100;

	/* Contains all tiles in a 2d-array */
	var tiles = new Array();

	var tilesContainer = document.createElement( "div" );
	tilesContainer.className = "sliceTiles";
	stack.getView().appendChild( tilesContainer );

    var overviewLayer = new OverviewLayer();

	var LAST_XT = Math.floor( ( stack.dimension.x * stack.scale - 1 ) / tileWidth );
	var LAST_YT = Math.floor( ( stack.dimension.y * stack.scale - 1 ) / tileHeight );

	self.baseURL = baseURL;
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import React from 'react';
import PropTypes from 'prop-types';

import AbstractSeries from './abstract-series';
import Animation from 'animation';
import {ANIMATED_SERIES_PROPS} from 'utils/series-utils';

const predefinedClassName =
  'rv-xy-plot__series rv-xy-plot__series--custom-svg-wrapper';

const DEFAULT_STYLE = {
  stroke: 'blue',
  fill: 'blue'
};

function predefinedComponents(type, size = 2, style = DEFAULT_STYLE) {
  switch (type) {
    case 'diamond':
      return (
        <polygon
          style={style}
          points={`0 0 ${size / 2} ${size / 2} 0 ${size} ${-size / 2} ${size /
            2} 0 0`}
        />
      );
    case 'star':
      const starPoints = [...new Array(5)]
        .map((c, index) => {
          const angle = index / 5 * Math.PI * 2;
          const innerAngle = angle + Math.PI / 10;
          const outerAngle = angle - Math.PI / 10;
          // ratio of inner polygon to outer polgyon
          const innerRadius = size / 2.61;
          return `
        ${Math.cos(outerAngle) * size} ${Math.sin(outerAngle) * size}
        ${Math.cos(innerAngle) * innerRadius} ${Math.sin(innerAngle) *
            innerRadius}
      `;
        })
        .join(' ');
      return (
        <polygon
          points={starPoints}
          x="0"
          y="0"
          height={size}
          width={size}
          style={style}
        />
      );
    case 'square':
      return (
        <rect
          x={`${-size / 2}`}
          y={`${-size / 2}`}
          height={size}
          width={size}
          style={style}
        />
      );
    default:
    case 'circle':
      return <circle cx="0" cy="0" r={size / 2} style={style} />;
  }
}

function getInnerComponent({
  customComponent,
  defaultType,
  positionInPixels,
  positionFunctions,
  style,
  propsSize
}) {
  const {size} = customComponent;
  const aggStyle = {...style, ...(customComponent.style || {})};
  const innerComponent = customComponent.customComponent;
  if (!innerComponent && typeof defaultType === 'string') {
    return predefinedComponents(defaultType, size || propsSize, aggStyle);
  }
  // if default component is a function
  if (!innerComponent) {
    return defaultType(customComponent, positionInPixels, aggStyle);
  }
  if (typeof innerComponent === 'string') {
    return predefinedComponents(innerComponent || defaultType, size, aggStyle);
  }
  // if inner component is a function
  return innerComponent(customComponent, positionInPixels, aggStyle);
}

class CustomSVGSeries extends AbstractSeries {
  render() {
    const {
      animation,
      className,
      customComponent,
      data,
      innerHeight,
      innerWidth,
      marginLeft,
      marginTop,
      style,
      size
    } = this.props;

    if (!data || !innerWidth || !innerHeight) {
      return null;
    }

    if (animation) {
      return (
        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>
          <CustomSVGSeries {...this.props} animation={false} />
        </Animation>
      );
    }

    const x = this._getAttributeFunctor('x');
    const y = this._getAttributeFunctor('y');
    const contents = data.map((seriesComponent, index) => {
      const positionInPixels = {
        x: x(seriesComponent),
        y: y(seriesComponent)
      };
      const innerComponent = getInnerComponent({
        customComponent: seriesComponent,
        positionInPixels,
        defaultType: customComponent,
        positionFunctions: {x, y},
        style,
        propsSize: size
      });
      return (
        <g
          className="rv-xy-plot__series--custom-svg"
          key={`rv-xy-plot__series--custom-svg-${index}`}
          transform={`translate(${positionInPixels.x},${positionInPixels.y})`}
          onMouseEnter={e => this._valueMouseOverHandler(seriesComponent, e)}
          onMouseLeave={e => this._valueMouseOutHandler(seriesComponent, e)}
        >
          {innerComponent}
        </g>
      );
    });
    return (
      <g
        className={`${predefinedClassName} ${className}`}
        transform={`translate(${marginLeft},${marginTop})`}
      >
        {contents}
      </g>
    );
  }
}

CustomSVGSeries.propTypes = {
  animation: PropTypes.bool,
  className: PropTypes.string,
  customComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
  data: PropTypes.arrayOf(
    PropTypes.shape({
      x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
      y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
    })
  ).isRequired,
  marginLeft: PropTypes.number,
  marginTop: PropTypes.number,
  style: PropTypes.object,
  size: PropTypes.number,
  onValueMouseOver: PropTypes.func,
  onValueMouseOut: PropTypes.func
};

CustomSVGSeries.defaultProps = {
  ...AbstractSeries.defaultProps,
  animation: false,
  customComponent: 'circle',
  style: {},
  size: 2
};

export default CustomSVGSeries;
<commit_msg>Fixed #1085 (#1197)<commit_after>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import React from 'react';
import PropTypes from 'prop-types';

import AbstractSeries from './abstract-series';
import Animation from 'animation';
import {ANIMATED_SERIES_PROPS} from 'utils/series-utils';

const predefinedClassName =
  'rv-xy-plot__series rv-xy-plot__series--custom-svg-wrapper';

const DEFAULT_STYLE = {
  stroke: 'blue',
  fill: 'blue'
};

function predefinedComponents(type, size = 2, style = DEFAULT_STYLE) {
  switch (type) {
    case 'diamond':
      return (
        <polygon
          style={style}
          points={`0 0 ${size / 2} ${size / 2} 0 ${size} ${-size / 2} ${size /
            2} 0 0`}
        />
      );
    case 'star':
      const starPoints = [...new Array(5)]
        .map((c, index) => {
          const angle = index / 5 * Math.PI * 2;
          const innerAngle = angle + Math.PI / 10;
          const outerAngle = angle - Math.PI / 10;
          // ratio of inner polygon to outer polgyon
          const innerRadius = size / 2.61;
          return `
        ${Math.cos(outerAngle) * size} ${Math.sin(outerAngle) * size}
        ${Math.cos(innerAngle) * innerRadius} ${Math.sin(innerAngle) *
            innerRadius}
      `;
        })
        .join(' ');
      return (
        <polygon
          points={starPoints}
          x="0"
          y="0"
          height={size}
          width={size}
          style={style}
        />
      );
    case 'square':
      return (
        <rect
          x={`${-size / 2}`}
          y={`${-size / 2}`}
          height={size}
          width={size}
          style={style}
        />
      );
    default:
    case 'circle':
      return <circle cx="0" cy="0" r={size / 2} style={style} />;
  }
}

function getInnerComponent({
  customComponent,
  defaultType,
  positionInPixels,
  positionFunctions,
  style,
  propsSize
}) {
  const {size} = customComponent;
  const aggStyle = {...style, ...(customComponent.style || {})};
  const innerComponent = customComponent.customComponent;
  if (!innerComponent && typeof defaultType === 'string') {
    return predefinedComponents(defaultType, size || propsSize, aggStyle);
  }
  // if default component is a function
  if (!innerComponent) {
    return defaultType(customComponent, positionInPixels, aggStyle, positionFunctions);
  }
  if (typeof innerComponent === 'string') {
    return predefinedComponents(innerComponent || defaultType, size, aggStyle);
  }
  // if inner component is a function
  return innerComponent(customComponent, positionInPixels, aggStyle, positionFunctions);
}

class CustomSVGSeries extends AbstractSeries {
  render() {
    const {
      animation,
      className,
      customComponent,
      data,
      innerHeight,
      innerWidth,
      marginLeft,
      marginTop,
      style,
      size
    } = this.props;

    if (!data || !innerWidth || !innerHeight) {
      return null;
    }

    if (animation) {
      return (
        <Animation {...this.props} animatedProps={ANIMATED_SERIES_PROPS}>
          <CustomSVGSeries {...this.props} animation={false} />
        </Animation>
      );
    }

    const x = this._getAttributeFunctor('x');
    const y = this._getAttributeFunctor('y');
    const contents = data.map((seriesComponent, index) => {
      const positionInPixels = {
        x: x(seriesComponent),
        y: y(seriesComponent)
      };
      const innerComponent = getInnerComponent({
        customComponent: seriesComponent,
        positionInPixels,
        defaultType: customComponent,
        positionFunctions: {x, y},
        style,
        propsSize: size
      });
      return (
        <g
          className="rv-xy-plot__series--custom-svg"
          key={`rv-xy-plot__series--custom-svg-${index}`}
          transform={`translate(${positionInPixels.x},${positionInPixels.y})`}
          onMouseEnter={e => this._valueMouseOverHandler(seriesComponent, e)}
          onMouseLeave={e => this._valueMouseOutHandler(seriesComponent, e)}
        >
          {innerComponent}
        </g>
      );
    });
    return (
      <g
        className={`${predefinedClassName} ${className}`}
        transform={`translate(${marginLeft},${marginTop})`}
      >
        {contents}
      </g>
    );
  }
}

CustomSVGSeries.propTypes = {
  animation: PropTypes.bool,
  className: PropTypes.string,
  customComponent: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
  data: PropTypes.arrayOf(
    PropTypes.shape({
      x: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
      y: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired
    })
  ).isRequired,
  marginLeft: PropTypes.number,
  marginTop: PropTypes.number,
  style: PropTypes.object,
  size: PropTypes.number,
  onValueMouseOver: PropTypes.func,
  onValueMouseOut: PropTypes.func
};

CustomSVGSeries.defaultProps = {
  ...AbstractSeries.defaultProps,
  animation: false,
  customComponent: 'circle',
  style: {},
  size: 2
};

export default CustomSVGSeries;
<|endoftext|>


<commit_before>$.uce.widget("file_sharing", {
    options: {
        ucemeeting : null,
        upload     : true,
        title      : "File sharing"
    },

    // ucengine events
    meetingsEvents: {
        'internal.file.add'        : '_handleFileAddEvent',
        'document.conversion.done' : '_handleFileDocumentEvent',
        'document.share.start'     : '_handleShareStartEvent',
        'document.share.goto'      : '_handleShareGotoEvent',
        'document.share.stop'      : '_handleShareStopEvent'
    },

    _create: function() {
        this.element.addClass('ui-widget ui-filesharing');
        $("<div>").addClass("ui-widget-header").append($("<span>").text(this.options.title)).appendTo(this.element);
        var that = this;
        var all = $('<div>').attr('class', 'ui-filesharing-all');
        var preview = $('<div>').attr('class', 'ui-filesharing-preview');
        // init preview content
        $('<div>').attr('class', 'ui-filesharing-preview-title').appendTo(preview);
        var toolbar = $('<div>').attr('class', 'ui-corner-all ui-preview-toolbar');

        var previous = $('<span>')
            .attr('class', 'ui-filesharing ui-toolbar-button ui-button-previous')
            .attr('href', '#')
            .button({
                text: false,
                icons: {
                    primary: "ui-icon-arrowthick-1-n"
                }
            });

        var next = $('<span>')
            .attr('class', 'ui-filesharing ui-toolbar-button ui-button-next')
            .attr('href', '#')
            .button({
                text: false,
                icons: {
                    primary: "ui-icon-arrowthick-1-s"
                }
            });

        previous.appendTo(toolbar);
        next.appendTo(toolbar);

	var pageSelector = $('<span>').attr('class', 'ui-filesharing ui-toolbar-selector');
        $('<span>').attr('class', 'ui-filesharing ui-selector-current')
            .appendTo(pageSelector);
        $('<span>').attr('class', 'ui-filesharing ui-selector-separator').text('/')
	    .appendTo(pageSelector);
        $('<span>').attr('class', 'ui-filesharing ui-selector-total')
	    .appendTo(pageSelector);
	pageSelector.appendTo(toolbar);

        var stop = $('<span>')
            .attr('class', 'ui-filesharing ui-toolbar-button ui-button-stop')
            .attr('href', '#')
            .button({
                text: false,
                icons: {
                    primary: "ui-icon-circle-close"
                }
            });

        stop.appendTo(toolbar);

        toolbar.appendTo(preview);
        var pageContainer = $('<div>').attr('class', 'ui-filesharing-preview-page').appendTo(preview);
        $('<img>').appendTo(pageContainer);

        previous.bind('click', function() {
            var page = that._shared.page - 1;
            if (page < 0) {
                return false;
            }
            that.options.ucemeeting.push('document.share.goto', {id: that._shared.file.id,
                                                                 page: page});

            return false;
        });
        next.bind('click', function() {
            var page = that._shared.page + 1;
            if (page >= that._shared.file.pages.length) {
                return false;
            }
            that.options.ucemeeting.push('document.share.goto', {id: that._shared.file.id,
                                                                 page: page});

            return false;
        });
        stop.bind('click', function() {
            that.options.ucemeeting.push('document.share.stop', {id: that._shared.file.id});
            return false;
        });

        //
        all.appendTo(this.element);
        preview.appendTo(this.element);
        this.viewAll();
        $('<ul>').attr('class', 'ui-filesharing-list').appendTo(all);
        this._listFiles = [];
        this._shared = null;
        if (this.options.ucemeeting) {
            if (this.options.upload) {
                var uploadButton = $('<a>').attr('href', '#')
                    .button({label: "Upload New File"})

                var uploadContainer = $('<div>').append($('<p>').attr('class', 'ui-filesharing-add')
                                                        .append(uploadButton)).appendTo(all);
                new AjaxUpload(uploadContainer.find('a'), {
                    action: this.options.ucemeeting.getFileUploadUrl(),
                    name: 'content',
                    onComplete : function(file, response){
                           return true;
                    }
                });
            }
        }
    },

    clear: function() {
        this.element.find('.ui-filesharing-new').text(this._nbNewFiles);
        this._listFiles = [];
        this._refreshListFiles();
    },

    viewAll: function() {
        this.element.find('.ui-filesharing-all').show();
        this.element.find('.ui-filesharing-preview').hide();
    },

    viewPreview: function() {
        this.element.find('.ui-filesharing-all').hide();
        this.element.find('.ui-filesharing-preview').show();
    },

    _setOption: function(key, value) {
        $.Widget.prototype._setOption.apply(this, arguments);
        switch (key) {
            case 'upload':
            this.element.find('.ui-filesharing-add').toggle();
            break;
        }
    },

    _handleFileAddEvent: function(event) {
        if (event.from == "document") {
            return;
        }

        this._listFiles.push($.extend({}, event, {pages: []}));
        this._refreshListFiles();
    },

    _handleFileDocumentEvent: function(event) {
        $(this._listFiles).each(
            function(index, file) {
                if (file.id == event.parent) {
                    for (var key in event.metadata) {
                        var value = event.metadata[key];
                        file.pages.push(value);
                    };
                }
            }
        );
        this._refreshListFiles();
    },

    _refreshListFiles: function() {
        var ul = $();
        var ucemeeting = this.options.ucemeeting;
        var that = this;
        $(this._listFiles).each(
            function(index, file) {
                var id = file.metadata.id;
                var mime = (file.metadata.mime == "application/pdf") ? "pdf" : "default";
                var filename = $('<p>').text(file.metadata.name);
                if (file.pages.length != 0) {
                    var sharelink = $('<a>');
                    sharelink.attr('href', '#');
		    sharelink.attr('class', 'ui-filesharing ui-preview-link');
                    sharelink.text(' (preview)');
                    sharelink.bind('click', function() {
                        that.options.ucemeeting.push("document.share.start", {id: file.metadata.id});
                        return false;
                    });
                    filename.append(sharelink);
                }
		var fileowner = $('<p>').attr('class', 'ui-file-owner').text("From: " + file.from);
		var li = $('<li>').attr('class', 'mime ' + mime).append(filename).append(fileowner);
                ul = ul.add(li);
            }
        );
        this.element.find('.ui-filesharing-list').empty().append(ul);
    },

    _refreshPreview: function() {
        var preview = this.element.find('.ui-filesharing-preview');
        this.element.find('.ui-filesharing-preview-title')
            .text(this._shared.file.name);
        this.element.find('.ui-selector-current')
            .text(this._shared.page + 1);
        this.element.find('.ui-selector-total')
            .text(this._shared.file.pages.length);
        var pageImg = this.element.find('.ui-filesharing-preview-page img')
        var src = this.options.ucemeeting
            .getFileDownloadUrl(this._shared.file.pages[this._shared.page]);
        pageImg.attr('src', src);
    },

    _handleShareStartEvent: function(event) {
        var that = this;
        $(this._listFiles).each(
            function(i, file) {
                if (file.metadata.id == event.metadata.id) {
                    that._shared = {
                        master : event.from,
                        page   : 0,
                        file   : file
                    };
                    that._refreshPreview();
                    that.viewPreview();
                }
            }
        );

    },

    _handleShareGotoEvent: function(event) {
        if (this._shared.master != event.from) {
            return;
        }
        this._shared.page = parseInt(event.metadata.page);
        this._refreshPreview();
    },

    _handleShareStopEvent: function(event) {
        if (this._shared.master != event.from) {
            return;
        }
        this.viewAll();
    },

    destroy: function() {
        this.element.find('*').remove();
        this.element.removeClass('ui-widget ui-filesharing');
        $.Widget.prototype.destroy.apply(this, arguments); // default destroy
    }
});
<commit_msg>[bugfix] sort img when receive document.conversion.done event<commit_after>$.uce.widget("file_sharing", {
    options: {
        ucemeeting : null,
        upload     : true,
        title      : "File sharing"
    },

    // ucengine events
    meetingsEvents: {
        'internal.file.add'        : '_handleFileAddEvent',
        'document.conversion.done' : '_handleFileDocumentEvent',
        'document.share.start'     : '_handleShareStartEvent',
        'document.share.goto'      : '_handleShareGotoEvent',
        'document.share.stop'      : '_handleShareStopEvent'
    },

    _create: function() {
        this.element.addClass('ui-widget ui-filesharing');
        $("<div>").addClass("ui-widget-header").append($("<span>").text(this.options.title)).appendTo(this.element);
        var that = this;
        var all = $('<div>').attr('class', 'ui-filesharing-all');
        var preview = $('<div>').attr('class', 'ui-filesharing-preview');
        // init preview content
        $('<div>').attr('class', 'ui-filesharing-preview-title').appendTo(preview);
        var toolbar = $('<div>').attr('class', 'ui-corner-all ui-preview-toolbar');

        var previous = $('<span>')
            .attr('class', 'ui-filesharing ui-toolbar-button ui-button-previous')
            .attr('href', '#')
            .button({
                text: false,
                icons: {
                    primary: "ui-icon-arrowthick-1-n"
                }
            });

        var next = $('<span>')
            .attr('class', 'ui-filesharing ui-toolbar-button ui-button-next')
            .attr('href', '#')
            .button({
                text: false,
                icons: {
                    primary: "ui-icon-arrowthick-1-s"
                }
            });

        previous.appendTo(toolbar);
        next.appendTo(toolbar);

	var pageSelector = $('<span>').attr('class', 'ui-filesharing ui-toolbar-selector');
        $('<span>').attr('class', 'ui-filesharing ui-selector-current')
            .appendTo(pageSelector);
        $('<span>').attr('class', 'ui-filesharing ui-selector-separator').text('/')
	    .appendTo(pageSelector);
        $('<span>').attr('class', 'ui-filesharing ui-selector-total')
	    .appendTo(pageSelector);
	pageSelector.appendTo(toolbar);

        var stop = $('<span>')
            .attr('class', 'ui-filesharing ui-toolbar-button ui-button-stop')
            .attr('href', '#')
            .button({
                text: false,
                icons: {
                    primary: "ui-icon-circle-close"
                }
            });

        stop.appendTo(toolbar);

        toolbar.appendTo(preview);
        var pageContainer = $('<div>').attr('class', 'ui-filesharing-preview-page').appendTo(preview);
        $('<img>').appendTo(pageContainer);

        previous.bind('click', function() {
            var page = that._shared.page - 1;
            if (page < 0) {
                return false;
            }
            that.options.ucemeeting.push('document.share.goto', {id: that._shared.file.id,
                                                                 page: page});

            return false;
        });
        next.bind('click', function() {
            var page = that._shared.page + 1;
            if (page >= that._shared.file.pages.length) {
                return false;
            }
            that.options.ucemeeting.push('document.share.goto', {id: that._shared.file.id,
                                                                 page: page});

            return false;
        });
        stop.bind('click', function() {
            that.options.ucemeeting.push('document.share.stop', {id: that._shared.file.id});
            return false;
        });

        //
        all.appendTo(this.element);
        preview.appendTo(this.element);
        this.viewAll();
        $('<ul>').attr('class', 'ui-filesharing-list').appendTo(all);
        this._listFiles = [];
        this._shared = null;
        if (this.options.ucemeeting) {
            if (this.options.upload) {
                var uploadButton = $('<a>').attr('href', '#')
                    .button({label: "Upload New File"})

                var uploadContainer = $('<div>').append($('<p>').attr('class', 'ui-filesharing-add')
                                                        .append(uploadButton)).appendTo(all);
                new AjaxUpload(uploadContainer.find('a'), {
                    action: this.options.ucemeeting.getFileUploadUrl(),
                    name: 'content',
                    onComplete : function(file, response){
                           return true;
                    }
                });
            }
        }
    },

    clear: function() {
        this.element.find('.ui-filesharing-new').text(this._nbNewFiles);
        this._listFiles = [];
        this._refreshListFiles();
    },

    viewAll: function() {
        this.element.find('.ui-filesharing-all').show();
        this.element.find('.ui-filesharing-preview').hide();
    },

    viewPreview: function() {
        this.element.find('.ui-filesharing-all').hide();
        this.element.find('.ui-filesharing-preview').show();
    },

    _setOption: function(key, value) {
        $.Widget.prototype._setOption.apply(this, arguments);
        switch (key) {
            case 'upload':
            this.element.find('.ui-filesharing-add').toggle();
            break;
        }
    },

    _handleFileAddEvent: function(event) {
        if (event.from == "document") {
            return;
        }

        this._listFiles.push($.extend({}, event, {pages: []}));
        this._refreshListFiles();
    },

    _handleFileDocumentEvent: function(event) {
        $(this._listFiles).each(
            function(index, file) {
                if (file.id == event.parent) {
                    for (var key in event.metadata) {
                        var value = event.metadata[key];
                      file.pages[key] = value;
                    };
                }
            }
        );
        this._refreshListFiles();
    },

    _refreshListFiles: function() {
        var ul = $();
        var ucemeeting = this.options.ucemeeting;
        var that = this;
        $(this._listFiles).each(
            function(index, file) {
                var id = file.metadata.id;
                var mime = (file.metadata.mime == "application/pdf") ? "pdf" : "default";
                var filename = $('<p>').text(file.metadata.name);
                if (file.pages.length != 0) {
                    var sharelink = $('<a>');
                    sharelink.attr('href', '#');
		    sharelink.attr('class', 'ui-filesharing ui-preview-link');
                    sharelink.text(' (preview)');
                    sharelink.bind('click', function() {
                        that.options.ucemeeting.push("document.share.start", {id: file.metadata.id});
                        return false;
                    });
                    filename.append(sharelink);
                }
		var fileowner = $('<p>').attr('class', 'ui-file-owner').text("From: " + file.from);
		var li = $('<li>').attr('class', 'mime ' + mime).append(filename).append(fileowner);
                ul = ul.add(li);
            }
        );
        this.element.find('.ui-filesharing-list').empty().append(ul);
    },

    _refreshPreview: function() {
        var preview = this.element.find('.ui-filesharing-preview');
        this.element.find('.ui-filesharing-preview-title')
            .text(this._shared.file.name);
        this.element.find('.ui-selector-current')
            .text(this._shared.page + 1);
        this.element.find('.ui-selector-total')
            .text(this._shared.file.pages.length);
        var pageImg = this.element.find('.ui-filesharing-preview-page img');
        var src = this.options.ucemeeting
            .getFileDownloadUrl(this._shared.file.pages[this._shared.page]);
        pageImg.attr('src', src);
    },

    _handleShareStartEvent: function(event) {
        var that = this;
        $(this._listFiles).each(
            function(i, file) {
                if (file.metadata.id == event.metadata.id) {
                    that._shared = {
                        master : event.from,
                        page   : 0,
                        file   : file
                    };
                    that._refreshPreview();
                    that.viewPreview();
                }
            }
        );

    },

    _handleShareGotoEvent: function(event) {
        if (this._shared.master != event.from) {
            return;
        }
        this._shared.page = parseInt(event.metadata.page);
        this._refreshPreview();
    },

    _handleShareStopEvent: function(event) {
        if (this._shared.master != event.from) {
            return;
        }
        this.viewAll();
    },

    destroy: function() {
        this.element.find('*').remove();
        this.element.removeClass('ui-widget ui-filesharing');
        $.Widget.prototype.destroy.apply(this, arguments); // default destroy
    }
});
<|endoftext|>


<commit_before>var Todo = require('./models/todo');

if ('dev' == process.env.DEPLOY_ENV){
    Todo.remove({})
}

function getTodos(res) {
    Todo.find(function (err, todos) {

        // if there is an error retrieving, send the error. nothing after res.send(err) will execute
        if (err) {
            res.send(err);
        }

        res.json(todos); // return all todos in JSON format
    });
};

module.exports = function (app) {

    // api ---------------------------------------------------------------------
    // get all todos
    app.get('/api/todos', function (req, res) {
        // use mongoose to get all todos in the database
        getTodos(res);
    });

    // create todo and send back all todos after creation
    app.post('/api/todos', function (req, res) {

        // create a todo, information comes from AJAX request from Angular
        Todo.create({
            text: req.body.text,
            done: false
        }, function (err, todo) {
            if (err)
                res.send(err);

            // get and return all the todos after you create another
            getTodos(res);
        });

    });

    // delete a todo
    app.delete('/api/todos/:todo_id', function (req, res) {
        Todo.remove({
            _id: req.params.todo_id
        }, function (err, todo) {
            if (err)
                res.send(err);

            getTodos(res);
        });
    });

    // application -------------------------------------------------------------
    app.get('*', function (req, res) {
        res.sendFile(__dirname + '/public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
    });
};
<commit_msg>Update routes.js<commit_after>var Todo = require('./models/todo');

function getTodos(res) {
    Todo.find(function (err, todos) {

        // if there is an error retrieving, send the error. nothing after res.send(err) will execute
        if (err) {
            res.send(err);
        }

        res.json(todos); // return all todos in JSON format
    });
};

module.exports = function (app) {

    // api ---------------------------------------------------------------------
    // get all todos
    app.get('/api/todos', function (req, res) {
        // use mongoose to get all todos in the database
        getTodos(res);
    });

    // create todo and send back all todos after creation
    app.post('/api/todos', function (req, res) {

        // create a todo, information comes from AJAX request from Angular
        Todo.create({
            text: req.body.text,
            done: false
        }, function (err, todo) {
            if (err)
                res.send(err);

            // get and return all the todos after you create another
            getTodos(res);
        });

    });

    // delete a todo
    app.delete('/api/todos/:todo_id', function (req, res) {
        Todo.remove({
            _id: req.params.todo_id
        }, function (err, todo) {
            if (err)
                res.send(err);

            getTodos(res);
        });
    });

    // application -------------------------------------------------------------
    app.get('*', function (req, res) {
        res.sendFile(__dirname + '/public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
    });
};
<|endoftext|>