<commit_before>/*
 *  timer.js
 *
 *  David Janes
 *  IOTDB.org
 *  2014-12-03
 *
 *  Base class for timers
 *
 *  Copyright [2013-2014] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var moment = require('moment');
var util = require('util');
var events = require('events');

var _ = require("./helpers");
var DateTime = require("./datetime").DateTime;

var logger = _.make_logger({
    name: 'iotdb-timer',
    module: 'timer',
});

var event_sorter = function(a, b) {
    return a.compare(b);
}

var format2 = function(d) {
    d = Math.abs(d) % 100
    if (d < 10) {
        return "0" + d
    } else {
        return "" + d
    }
}

/**
 *  Internal for package ... mainly
 */
var defaults = {
    latitude: 43.7,
    longitude: -79.4,
    max_delta: 60,
};

/**
 */
var setLocation = function(latitude, longitude) {
    defaults.latitude = latitude;
    defaults.longitude = longitude;
};

var unique_id = 0;

/**
 */
var Timer = function () {
    var self = this;

    self.events = [];
    self.when = null;
    self._timer_id = null;
    self.__unique_id = unique_id++;

    // console.log("EVENTS", self._events);
    self._events = undefined
    events.EventEmitter.call(this);
    self._events.__unique_id = self.__unique_id;
};

util.inherits(Timer, events.EventEmitter);

/**
 */
Timer.prototype.schedule = function(event) {
    this._schedule(event);
}

Timer.prototype.getWhen = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self._scrub(self.when);
}

Timer.prototype.getDate = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self.when.getDate();
}

Timer.prototype.isBefore = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self.when.compare() > 0;
}

Timer.prototype.isAfter = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self.when.compare() <= 0;
}

/**
 *  Reschedule the event to the next interval. If
 *  not rescheduable, return false
 */
Timer.prototype._reschedule = function(event) {
    var self = this;

    var dd = event.get()
    var dt_old = event.getDate();
    var dt_new = null;

    if (dd.year_repeat) {
        dt_new = moment(dt_old).add(dd.year_repeat, 'hours').toDate();
    } else if (dd.month_repeat) {
        dt_new = moment(dt_old).add(dd.month_repeat, 'months').toDate();
    } else if (dd.day_repeat) {
        dt_new = moment(dt_old).add(dd.day_repeat, 'days').toDate();
    } else if (dd.hour_repeat) {
        dt_new = moment(dt_old).add(dd.hour_repeat, 'hours').toDate();
    } else if (dd.minute_repeat) {
        dt_new = moment(dt_old).add(dd.minute_repeat, 'minutes').toDate();
    } else if (dd.second_repeat) {
        dt_new = moment(dt_old).add(dd.second_repeat, 'seconds').toDate();
    } else {
        return false;
    }

    event.set(dt_new);

    return true;
};

/**
 *  Add an event to the queue
 *

 *  Lots of rules built into the code need to be documented
 */
Timer.prototype._schedule = function(paramd) {
    var self = this;

    var event = new DateTime(paramd);

    if ((event.compare() < 0) && !self._reschedule(event)) {
        logger.error({
            method: "_schedule",
            cause: "likely the programmer or data, often not serious",
            event: event.get(),
            unique_id: self.__unique_id,
            initd: paramd.initd,
            driverd: paramd.driverd
        }, "date is in the past any this does not repeat -- not scheduling");
        return
    }

    if (paramd.id) {
        for (var ei in self.events) {
            var e = self.events[ei];
            var id = e.get().id;
            if (e.get().id === paramd.id) {
                self.events.splice(ei, 1);
                break;
            }
        }

        if (paramd.id === "timer") {
            self.when = event;
        }
    }

    self.events.push(event);
    self._scheduler();
};

/**
 */
Timer.prototype._scrub = function(event) {
    var dd = event.get()

    for (var key in dd) {
        if (key.indexOf('_') > -1) {
            delete dd[key];
        }
    }

    return dd;
}

/**
 *  Run the event
 */
Timer.prototype._execute = function(event) {
    var self = this;

    var dd = self._scrub(event);

    // dd.__unique_id = self.__unique_id;
    self.emit(dd.id ? dd.id : 'timer', dd);

    logger.info({
        method: "_execute",
        event: dd,
        unique_id: self.__unique_id,
    }, "timer change")
};

/**
 *  This will run any events that are ready AND
 *  it will set the timer to wakeup at the next event
 */
Timer.prototype._scheduler = function() {
    var self = this;

    if (self.timer_id) {
        clearTimeout(self.timer_id);
    }

    if (self.events.length === 0) {
        return;
    }

    self.events.sort(event_sorter);

    while (true) {
        var event = self.events[0]
        if (event.compare() > 0) {
            break;
        }

        self._execute(event);

        if (!self._reschedule(event)) {
            self.events.shift();
        }
    }

    if (self.events.length === 0) {
        return;
    }

    self.events.sort(event_sorter);

    var delta = self.events[0].compare()
    logger.info({
        method: "_scheduler",
        next_run: delta,
        unique_id: self.__unique_id,
    }, "schedule updated");

    /*
     *  Because the computer can sleep, the process can be stopped,
     *  &c, we don't let sleeps go to long. It might be worth
     *  investigating setting up SIGTSTP handlers too, or listenable (?)
     *  events about the computer going to sleep and waking up
     */
    if (self._timer_id) {
        clearTimeout(self._timer_id);
        self._timer_id = null;
    }

    var again = function() {
        var delta = self.events[0].compare()
        if (delta > defaults.max_delta) {
            self._timer_id = setTimeout(again, defaults.max_delta * 1000);
        } else {
            self._timer_id = setTimeout(function() {
                self._scheduler();
            }, delta * 1000);
        }
    };
    again();
};

/*
 *  API
 */
exports.Timer = Timer;
exports.defaults = defaults;
exports.setLocation = setLocation;
<commit_msg>Support custom logger, adjust logging levels<commit_after>/*
 *  timer.js
 *
 *  David Janes
 *  IOTDB.org
 *  2014-12-03
 *
 *  Base class for timers
 *
 *  Copyright [2013-2014] [David P. Janes]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

"use strict";

var moment = require('moment');
var util = require('util');
var events = require('events');

var _ = require("./helpers");
var DateTime = require("./datetime").DateTime;

var logger = _.make_logger({
    name: 'iotdb-timer',
    module: 'timer',
});

var event_sorter = function(a, b) {
    return a.compare(b);
}

var format2 = function(d) {
    d = Math.abs(d) % 100
    if (d < 10) {
        return "0" + d
    } else {
        return "" + d
    }
}

/**
 *  Internal for package ... mainly
 */
var defaults = {
    latitude: 43.7,
    longitude: -79.4,
    max_delta: 60,
};

/**
 */
var setLocation = function(latitude, longitude) {
    defaults.latitude = latitude;
    defaults.longitude = longitude;
};

/**
 *  Accept a custom bunyan instance
 */
var setLogger = function(l) {
    logger = l;
};

var unique_id = 0;

/**
 */
var Timer = function () {
    var self = this;

    self.events = [];
    self.when = null;
    self._timer_id = null;
    self.__unique_id = unique_id++;

    // console.log("EVENTS", self._events);
    self._events = undefined
    events.EventEmitter.call(this);
    self._events.__unique_id = self.__unique_id;
};

util.inherits(Timer, events.EventEmitter);

/**
 */
Timer.prototype.schedule = function(event) {
    this._schedule(event);
}

Timer.prototype.getWhen = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self._scrub(self.when);
}

Timer.prototype.getDate = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self.when.getDate();
}

Timer.prototype.isBefore = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self.when.compare() > 0;
}

Timer.prototype.isAfter = function() {
    var self = this;

    if (!self.when) {
        return null;
    }

    return self.when.compare() <= 0;
}

/**
 *  Reschedule the event to the next interval. If
 *  not rescheduable, return false
 */
Timer.prototype._reschedule = function(event) {
    var self = this;

    var dd = event.get()
    var dt_old = event.getDate();
    var dt_new = null;

    if (dd.year_repeat) {
        dt_new = moment(dt_old).add(dd.year_repeat, 'hours').toDate();
    } else if (dd.month_repeat) {
        dt_new = moment(dt_old).add(dd.month_repeat, 'months').toDate();
    } else if (dd.day_repeat) {
        dt_new = moment(dt_old).add(dd.day_repeat, 'days').toDate();
    } else if (dd.hour_repeat) {
        dt_new = moment(dt_old).add(dd.hour_repeat, 'hours').toDate();
    } else if (dd.minute_repeat) {
        dt_new = moment(dt_old).add(dd.minute_repeat, 'minutes').toDate();
    } else if (dd.second_repeat) {
        dt_new = moment(dt_old).add(dd.second_repeat, 'seconds').toDate();
    } else {
        return false;
    }

    event.set(dt_new);

    return true;
};

/**
 *  Add an event to the queue
 *

 *  Lots of rules built into the code need to be documented
 */
Timer.prototype._schedule = function(paramd) {
    var self = this;

    var event = new DateTime(paramd);

    if ((event.compare() < 0) && !self._reschedule(event)) {
        logger.debug({
            method: "_schedule",
            cause: "likely the programmer or data, often not serious",
            event: event.get(),
            unique_id: self.__unique_id,
            initd: paramd.initd,
            driverd: paramd.driverd
        }, "date is in the past any this does not repeat -- not scheduling");
        return
    }

    if (paramd.id) {
        for (var ei in self.events) {
            var e = self.events[ei];
            var id = e.get().id;
            if (e.get().id === paramd.id) {
                self.events.splice(ei, 1);
                break;
            }
        }

        if (paramd.id === "timer") {
            self.when = event;
        }
    }

    self.events.push(event);
    self._scheduler();
};

/**
 */
Timer.prototype._scrub = function(event) {
    var dd = event.get()

    for (var key in dd) {
        if (key.indexOf('_') > -1) {
            delete dd[key];
        }
    }

    return dd;
}

/**
 *  Run the event
 */
Timer.prototype._execute = function(event) {
    var self = this;

    var dd = self._scrub(event);

    // dd.__unique_id = self.__unique_id;
    self.emit(dd.id ? dd.id : 'timer', dd);

    logger.debug({
        method: "_execute",
        event: dd,
        unique_id: self.__unique_id,
    }, "timer change")
};

/**
 *  This will run any events that are ready AND
 *  it will set the timer to wakeup at the next event
 */
Timer.prototype._scheduler = function() {
    var self = this;

    if (self.timer_id) {
        clearTimeout(self.timer_id);
    }

    if (self.events.length === 0) {
        return;
    }

    self.events.sort(event_sorter);

    while (true) {
        var event = self.events[0]
        if (event.compare() > 0) {
            break;
        }

        self._execute(event);

        if (!self._reschedule(event)) {
            self.events.shift();
        }
    }

    if (self.events.length === 0) {
        return;
    }

    self.events.sort(event_sorter);

    var delta = self.events[0].compare()
    logger.debug({
        method: "_scheduler",
        next_run: delta,
        unique_id: self.__unique_id,
    }, "schedule updated");

    /*
     *  Because the computer can sleep, the process can be stopped,
     *  &c, we don't let sleeps go to long. It might be worth
     *  investigating setting up SIGTSTP handlers too, or listenable (?)
     *  events about the computer going to sleep and waking up
     */
    if (self._timer_id) {
        clearTimeout(self._timer_id);
        self._timer_id = null;
    }

    var again = function() {
        var delta = self.events[0].compare()
        if (delta > defaults.max_delta) {
            self._timer_id = setTimeout(again, defaults.max_delta * 1000);
        } else {
            self._timer_id = setTimeout(function() {
                self._scheduler();
            }, delta * 1000);
        }
    };
    again();
};

/*
 *  API
 */
exports.Timer = Timer;
exports.defaults = defaults;
exports.setLocation = setLocation;
exports.setLogger = setLogger;
<|endoftext|>


<commit_before>/*global screen:true*/
var uuid = require("node-uuid")
var World = require("./world")
var Login = require("./login")

// Hackish name
var NAME = require("../name")

module.exports = UI

function UI(doc) {
    var login = Login()
    var world = World(doc)

    var player = {
        id: "human:" + NAME.name
        , name: NAME.name
        , type: "human"
        , dead: false
    }

    if (NAME.newPlayer) {
        player.x = 300
        player.y = 240
    }

    var playerRow = doc.add(player)

    document.body.appendChild(login.root)

    var ta = document.createElement('textarea')
    ta.style.position = 'absolute'
    ta.style.left = '600px'
    ta.style.width = '400px'
    ta.style.height = '480px'
    document.body.appendChild(ta)

    world.on('examine', function (entity) {
      console.log(entity)
      ta.innerText = JSON.stringify(entity.toJSON())
    })

    login.on("name", function (name) {
        console.log("name", name)
        playerRow.set("displayName", name)
    })
}
<commit_msg>fix textarea<commit_after>/*global screen:true*/
var uuid = require("node-uuid")
var World = require("./world")
var Login = require("./login")

// Hackish name
var NAME = require("../name")

module.exports = UI

function UI(doc) {
    var login = Login()
    var world = World(doc)

    var player = {
        id: "human:" + NAME.name
        , name: NAME.name
        , type: "human"
        , dead: false
    }

    if (NAME.newPlayer) {
        player.x = 300
        player.y = 240
    }

    var playerRow = doc.add(player)

    document.body.appendChild(login.root)

    var ta = document.createElement('textarea')
    ta.style.position = 'absolute'
    ta.style.top = '40px'
    ta.style.left = '620px'
    ta.style.width = '400px'
    ta.style.height = '480px'
    document.body.appendChild(ta)

    world.on('examine', function (entity) {
      console.log(entity)
      ta.innerText = JSON.stringify(entity.toJSON())
    })

    login.on("name", function (name) {
        console.log("name", name)
        playerRow.set("displayName", name)
    })
}
<|endoftext|>


<commit_before>import Ember from 'ember'
const {$} = Ember

const ctx = $('<canvas />').get(0).getContext('2d')

/**
 * Get width of text for a specific font
 *
 * @param {String} text - text to measure width of
 * @param {String} [font] - font to measure text in
 * @returns {Number} width of text using font
 */
export function getTextWidth (text, font) {
  if (font) {
    ctx.font = font
  }

  return Math.ceil(ctx.measureText(text).width)
}

/**
 * Trim text to fit within a specified width by removing characters from the center out and replacing with an ellipsis
 * Note: Replaces just enough characters from the center so that the text fills the width to the best of its ability
 *
 * @param {String} text - text to trim
 * @param {Number} width - width trimmed text needs to fit within in pixels
 * @param {String} [font] - font to measure text in
 * @returns {String} trimmed text
 */
export function trimDataToFit (text, width, font) {
  if (!text) {
    return text
  }

  // Start at two end characters
  let leftIndex = 0
  let rightIndex = text.length - 1

  if (getTextWidth(text, font) <= width) {
    return text
  }

  // Start total width as width of ellipsis since it will be added to the middle of the text
  let total = getTextWidth('…', font)

  while (leftIndex < rightIndex) {
    // Determine width of next two characters inward
    let current = getTextWidth(text[leftIndex]) + getTextWidth(text[rightIndex], font)

    // Determine total width including next two characters inward
    let newTotal = total + current

    // If adding next two characters makes string too long let's go ahead and stop
    if (newTotal > width) {
      leftIndex -= 1
      rightIndex += 1
      break
    }

    total = newTotal
    leftIndex += 1
    rightIndex -= 1
  }

  // Get trimmed text
  return text.slice(0, leftIndex + 1) + '…' + text.slice(rightIndex, text.length)
}

/**
 * If data is too long for element without wrapping trim with ellipsis in middle
 * Note: expects data-text attribute to be on element with full text
 *
 * @param {HTMLElement} element - HTML element to trim data within
 * @returns {Object} updated text and tooltip
 */
export function trimLongDataInElement (element) {
  const $element = $(element)
  const fullText = $(element).data('text')
  const width = $element.width()

  const fontFamily = $element.css('font-family')
  const fontSize = $element.css('font-size')
  ctx.font = `${fontSize} ${fontFamily}`

  const text = trimDataToFit(fullText, width)
  const tooltip = text === fullText ? '' : fullText

  // If rendered text has changed, update it
  if (element.textContent.trim() !== text) {
    return {text, tooltip}
  }

  return null
}
<commit_msg>Change from Jquery create canvas element to document.create JQuery create behaves strangley in Firefox sometimes where it seems like the canvas doesn't have a surface<commit_after>import Ember from 'ember'
const {$} = Ember

const ctx = document.createElement('canvas').getContext('2d')

/**
 * Get width of text for a specific font
 *
 * @param {String} text - text to measure width of
 * @param {String} [font] - font to measure text in
 * @returns {Number} width of text using font
 */
export function getTextWidth (text, font) {
  if (font) {
    ctx.font = font
  }

  return Math.ceil(ctx.measureText(text).width)
}

/**
 * Trim text to fit within a specified width by removing characters from the center out and replacing with an ellipsis
 * Note: Replaces just enough characters from the center so that the text fills the width to the best of its ability
 *
 * @param {String} text - text to trim
 * @param {Number} width - width trimmed text needs to fit within in pixels
 * @param {String} [font] - font to measure text in
 * @returns {String} trimmed text
 */
export function trimDataToFit (text, width, font) {
  if (!text) {
    return text
  }

  // Start at two end characters
  let leftIndex = 0
  let rightIndex = text.length - 1

  if (getTextWidth(text, font) <= width) {
    return text
  }

  // Start total width as width of ellipsis since it will be added to the middle of the text
  let total = getTextWidth('…', font)

  while (leftIndex < rightIndex) {
    // Determine width of next two characters inward
    let current = getTextWidth(text[leftIndex]) + getTextWidth(text[rightIndex], font)

    // Determine total width including next two characters inward
    let newTotal = total + current

    // If adding next two characters makes string too long let's go ahead and stop
    if (newTotal > width) {
      leftIndex -= 1
      rightIndex += 1
      break
    }

    total = newTotal
    leftIndex += 1
    rightIndex -= 1
  }

  // Get trimmed text
  return text.slice(0, leftIndex + 1) + '…' + text.slice(rightIndex, text.length)
}

/**
 * If data is too long for element without wrapping trim with ellipsis in middle
 * Note: expects data-text attribute to be on element with full text
 *
 * @param {HTMLElement} element - HTML element to trim data within
 * @returns {Object} updated text and tooltip
 */
export function trimLongDataInElement (element) {
  const $element = $(element)
  const fullText = $(element).data('text')
  const width = $element.width()

  const fontFamily = $element.css('font-family')
  const fontSize = $element.css('font-size')
  ctx.font = `${fontSize} ${fontFamily}`

  const text = trimDataToFit(fullText, width)
  const tooltip = text === fullText ? '' : fullText

  // If rendered text has changed, update it
  if (element.textContent.trim() !== text) {
    return {text, tooltip}
  }

  return null
}
<|endoftext|>


<commit_before>const EventEmitter = require('events').EventEmitter
const levelup = require('levelup')
const concatStream = require('concat-stream')
const assert = require('assert')

function getKey(value) {
  const info = value.info
  return info.room + ':' + info.handid
}

class LevelUp extends EventEmitter {
  constructor({ location, leveldown, encoding }) {
    super()

    assert.equal(typeof leveldown, 'function', 'need to specify leveldown function')
    assert.equal(typeof location, 'string', 'need to specify location string')

    this._location = location
    this._leveldown = leveldown
    this._db = levelup(location, { db: leveldown, valueEncoding: encoding })
  }

  append(value, opts, cb) {
    this._db.put(getKey(value), value, opts, cb)
  }

  createReadStream({ live, since, encoding } = {}) {
    // TODO: https://github.com/dominictarr/level-live-stream
    if (live) throw new Error('live stream not supported ATM')
    return this._db.createValueStream({ gte: since, valueEncoding: encoding })
  }

  range({ gt, gte, limit, reverse }, cb) {
    this._db
      .createReadStream({ gt, gte, limit, reverse })
      .on('error', cb)
      .pipe(concatStream(ondone))

    function ondone(res) {
      const first = res[0]
      const last = res[res.length - 1]
      const values = res.map(x => x.value)
      cb(null, { firstKey: first.key, lastKey: last.key, hands: values })
    }
  }

  get(key, { encoding } = {}, cb) {
    return this._db.get(key, { valueEncoding: encoding }, cb)
  }

  getHand(data) {
    return data
  }

  destroy(cb) {
    this._leveldown.destroy(this._location, cb)
  }
}

module.exports = LevelUp
<commit_msg>store: returning key/value stream for levelup readStream<commit_after>const EventEmitter = require('events').EventEmitter
const levelup = require('levelup')
const concatStream = require('concat-stream')
const assert = require('assert')

function getKey(value) {
  const info = value.info
  return info.room + ':' + info.handid
}

class LevelUp extends EventEmitter {
  constructor({ location, leveldown, encoding }) {
    super()

    assert.equal(typeof leveldown, 'function', 'need to specify leveldown function')
    assert.equal(typeof location, 'string', 'need to specify location string')

    this._location = location
    this._leveldown = leveldown
    this._db = levelup(location, { db: leveldown, valueEncoding: encoding })
  }

  append(value, opts, cb) {
    this._db.put(getKey(value), value, opts, cb)
  }

  createReadStream({ live, since, encoding } = {}) {
    // TODO: https://github.com/dominictarr/level-live-stream
    if (live) throw new Error('live stream not supported ATM')
    return this._db.createReadStream({ gte: since, valueEncoding: encoding })
  }

  range({ gt, gte, limit, reverse }, cb) {
    this._db
      .createReadStream({ gt, gte, limit, reverse })
      .on('error', cb)
      .pipe(concatStream(ondone))

    function ondone(res) {
      const first = res[0]
      const last = res[res.length - 1]
      const values = res.map(x => x.value)
      cb(null, { firstKey: first.key, lastKey: last.key, hands: values })
    }
  }

  get(key, { encoding } = {}, cb) {
    return this._db.get(key, { valueEncoding: encoding }, cb)
  }

  getHand(data) {
    return data
  }

  destroy(cb) {
    this._leveldown.destroy(this._location, cb)
  }
}

module.exports = LevelUp
<|endoftext|>


<commit_before>function updateTime(){
    var activeSong = document.getElementById('song');
    var currentSeconds = (Math.floor(activeSong.currentTime % 60) < 10 ? '0' : '') + Math.floor(activeSong.currentTime % 60);
    var currentMinutes = Math.floor(activeSong.currentTime / 60);
    var radial = $('.loader');

    document.getElementById('songTime').innerHTML = currentMinutes + ":" + currentSeconds + ' / ' + Math.floor(activeSong.duration / 60) + ":" + (Math.floor(activeSong.duration % 60) < 10 ? '0' : '') + Math.floor(activeSong.duration % 60);

    var percentageOfSong = (activeSong.currentTime/activeSong.duration);
    var percentageOfSlider = (percentageOfSong)*180;

    var transformStyles = ['-webkit-transform', '-ms-transform', 'transform'];
    window.rotate = function() {
      var fillRotation = percentageOfSlider;
      var fixRotation = percentageOfSlider * 2;
      for(i in transformStyles) {
        $('.circle .fill, .circle .mask.full').css(transformStyles[i], 'rotate(' + fillRotation + 'deg)');
        $('.circle .fill.fix').css(transformStyles[i], 'rotate(' + fixRotation + 'deg)');
      }
    }
    setTimeout(window.rotate, 200);
    radial.click(window.rotate);
}

jQuery(document).ready(function() {

  var song;
  var i;
  var album1List = $('ul.album1_inner_list > li');
  var album2List = $('ul.album2_inner_list > li');
  var album3List = $('ul.album3_inner_list > li');
  var songPlayPause = $('.songPlayPause');
  var fill = $('.fill');
  var radial = $('.loader');

  var activeSong;

  activeSong = document.getElementById('song');

    activeSong.addEventListener("paused", function(e) {
      songPlayPause.removeClass('pauseButton').addClass('playButton');
    }, false);

    album1List.click(function () {

      activeSong.pause();

      initalbum(album1List.index( $(this) ), "audio/album1/");
      activeSong.load();
      activeSong.play();
      songPlayPause.removeClass('playButton').addClass('pauseButton');
    });

    album2List.click(function () {
      activeSong.pause();

      initalbum(album2List.index( $(this) ), "audio/album2/");
      activeSong.load();
      activeSong.play();
      songPlayPause.removeClass('playButton').addClass('pauseButton');

    });

    album3List.click(function () {
      activeSong.pause();

      initalbum(album3List.index( $(this) ), "audio/album3/");
      activeSong.load();
      activeSong.play();
      songPlayPause.removeClass('playButton').addClass('pauseButton');

    });

    songPlayPause.click(function() {
      //Sets the active song since one of the functions could be play.
      activeSong = document.getElementById('song');
      playPause('song');
    })

    radial.click(function() {
      //Sets the active song since one of the functions could be play.
      activeSong = document.getElementById('song');
      setSongPosition(this,event);
    })

  function initalbum(i, folder) {

    $('#songmp3').attr("src", ""+folder+""+(i+1)+".mp3");
    $('#songogg').attr("src", ""+folder+""+(i+1)+".ogg");
    $('#song').load();
  }

      //Does a switch of the play/pause with one button.
  function playPause(id) {
      //Checks to see if the song is paused, if it is, play it from where it left off otherwise pause it.
      if (activeSong.paused){
           activeSong.play();
           songPlayPause.removeClass('playButton').addClass('pauseButton');
      }else{
           activeSong.pause();
           songPlayPause.removeClass('pauseButton').addClass('playButton');
      }
  }

  function pause() {
    activeSong.pause();
  }

  function setLocation(percentage) {
    activeSong.currentTime = activeSong.duration * percentage;
  }

  function setSongPosition(obj,e) {
    // If the player is circle, its width = height, so height is skipped
    var playerWidth = radial.width(); // width of circle player
    var centerX = playerWidth/2; // horisontal coordinate of center
    var centerY = playerWidth/2; // vertical coordinate of center
    var playWidth = songPlayPause.width(); //width of play button
    var minClickCoord = centerX - (playWidth/2); // minimum coordinate where clicking will trigger play/pause
    var maxClickCoord = centerX + (playWidth/2);

    var evtobj=window.event? event : e;
    var posX = evtobj.pageX - obj.offsetLeft;
    var posY = evtobj.pageY - obj.offsetTop;
    var sideCsq = centerY*centerY;
    var sideBsq = (posX-centerX)*(posX-centerX)+(posY-centerY)*(posY-centerY);
    var sideAsq = (posX-centerX)*(posX-centerX)+(posY)*(posY);

    var squares = (sideBsq + sideCsq - sideAsq);

    var bc2 = Math.sqrt(sideBsq*sideCsq)*2;

    var cos = squares/bc2;

    var acosA = Math.acos(cos);

    var grad;

    if (posX >= centerX) {grad = (acosA*180)/Math.PI;}
    else {grad = (360-(acosA*180)/Math.PI);}

    var percentage = grad/360;

    // Set postion in song manually
    if ((minClickCoord > posX || posX > maxClickCoord) || (minClickCoord > posY || posY > maxClickCoord)) {
      setLocation(percentage); }
  }

  activeSong.addEventListener("ended", function() {
    activeSong.currentTime = 0;
    $('.songPlayPause').removeClass('pauseButton').addClass('playButton');
  });
});<commit_msg>Fixed offset() issue, caused by offsetLeft propery with relative position of parent container<commit_after>function updateTime(){
    var activeSong = document.getElementById('song');
    var currentSeconds = (Math.floor(activeSong.currentTime % 60) < 10 ? '0' : '') + Math.floor(activeSong.currentTime % 60);
    var currentMinutes = Math.floor(activeSong.currentTime / 60);
    var radial = $('.loader');

    document.getElementById('songTime').innerHTML = currentMinutes + ":" + currentSeconds + ' / ' + Math.floor(activeSong.duration / 60) + ":" + (Math.floor(activeSong.duration % 60) < 10 ? '0' : '') + Math.floor(activeSong.duration % 60);

    var percentageOfSong = (activeSong.currentTime/activeSong.duration);
    var percentageOfSlider = (percentageOfSong)*180;

    var transformStyles = ['-webkit-transform', '-ms-transform', 'transform'];
    window.rotate = function() {
      var fillRotation = percentageOfSlider;
      var fixRotation = percentageOfSlider * 2;
      for(i in transformStyles) {
        $('.circle .fill, .circle .mask.full').css(transformStyles[i], 'rotate(' + fillRotation + 'deg)');
        $('.circle .fill.fix').css(transformStyles[i], 'rotate(' + fixRotation + 'deg)');
      }
    }
    setTimeout(window.rotate, 200);
    radial.click(window.rotate);
}

jQuery(document).ready(function() {

  var song;
  var i;
  var album1List = $('ul.album1_inner_list > li');
  var album2List = $('ul.album2_inner_list > li');
  var album3List = $('ul.album3_inner_list > li');
  var songPlayPause = $('.songPlayPause');
  var fill = $('.fill');
  var radial = $('.loader');

  var activeSong;

  activeSong = document.getElementById('song');

    activeSong.addEventListener("paused", function(e) {
      songPlayPause.removeClass('pauseButton').addClass('playButton');
    }, false);

    album1List.click(function () {

      activeSong.pause();

      initalbum(album1List.index( $(this) ), "audio/album1/");
      activeSong.load();
      activeSong.play();
      songPlayPause.removeClass('playButton').addClass('pauseButton');
    });

    album2List.click(function () {
      activeSong.pause();

      initalbum(album2List.index( $(this) ), "audio/album2/");
      activeSong.load();
      activeSong.play();
      songPlayPause.removeClass('playButton').addClass('pauseButton');

    });

    album3List.click(function () {
      activeSong.pause();

      initalbum(album3List.index( $(this) ), "audio/album3/");
      activeSong.load();
      activeSong.play();
      songPlayPause.removeClass('playButton').addClass('pauseButton');

    });

    songPlayPause.click(function() {
      //Sets the active song since one of the functions could be play.
      activeSong = document.getElementById('song');
      playPause('song');
    })

    radial.click(function() {
      //Sets the active song since one of the functions could be play.
      activeSong = document.getElementById('song');
      setSongPosition(this,event);
    })

  function initalbum(i, folder) {

    $('#songmp3').attr("src", ""+folder+""+(i+1)+".mp3");
    $('#songogg').attr("src", ""+folder+""+(i+1)+".ogg");
    $('#song').load();
  }

      //Does a switch of the play/pause with one button.
  function playPause(id) {
      //Checks to see if the song is paused, if it is, play it from where it left off otherwise pause it.
      if (activeSong.paused){
           activeSong.play();
           songPlayPause.removeClass('playButton').addClass('pauseButton');
      }else{
           activeSong.pause();
           songPlayPause.removeClass('pauseButton').addClass('playButton');
      }
  }

  function pause() {
    activeSong.pause();
  }

  function setLocation(percentage) {
    activeSong.currentTime = activeSong.duration * percentage;
  }

  function setSongPosition(obj,e) {
    // If the player is circle, its width = height, so height is skipped
    var playerWidth = radial.width(); // width of circle player
    var centerX = playerWidth/2; // horisontal coordinate of center
    var centerY = playerWidth/2; // vertical coordinate of center
    var playWidth = songPlayPause.width(); //width of play button
    var minClickCoord = centerX - (playWidth/2); // minimum coordinate where clicking will trigger play/pause
    var maxClickCoord = centerX + (playWidth/2);
    var offset = radial.offset();

    var evtobj=window.event? event : e;
    var posX = evtobj.pageX - offset.left;
    var posY = evtobj.pageY - offset.top;
    var sideCsq = centerY*centerY;
    var sideBsq = (posX-centerX)*(posX-centerX)+(posY-centerY)*(posY-centerY);
    var sideAsq = (posX-centerX)*(posX-centerX)+(posY)*(posY);

    var squares = (sideBsq + sideCsq - sideAsq);

    var bc2 = Math.sqrt(sideBsq*sideCsq)*2;

    var cos = squares/bc2;

    var acosA = Math.acos(cos);

    var grad;

    if (posX >= centerX) {grad = (acosA*180)/Math.PI;}
    else {grad = (360-(acosA*180)/Math.PI);}

    var percentage = grad/360;

    // Set postion in song manually
    if ((minClickCoord > posX || posX > maxClickCoord) || (minClickCoord > posY || posY > maxClickCoord)) {
      setLocation(percentage); }
  }

  activeSong.addEventListener("ended", function() {
    activeSong.currentTime = 0;
    $('.songPlayPause').removeClass('pauseButton').addClass('playButton');
  });
});<|endoftext|>


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

import { connect } from "react-redux";
import { push } from "redux-router";

import FiltersToolBar from "../FiltersToolBar";
import { CardOverlay } from "../CardOverlay";
import { Card, CardText } from 'material-ui/Card';

import { Actions } from "./redux/actions";
import {
    Actions as ServiceActions,
    ActionKeyStore as ServiceActionKeyStore
} from "../../services/servicemanager/redux/actions";
import {
    Actions as ConfigurationsActions,
    ActionKeyStore as ConfigurationsActionKeyStore
} from "../../services/configurations/redux/actions";

import { resizeVisualization } from "../../utils/resize"
import { contextualize } from "../../utils/configurations"

import { GraphManager } from "../Graphs/index";
import { ServiceManager } from "../../services/servicemanager/index";

import style from "./styles"

import FontAwesome from "react-fontawesome";

class VisualizationView extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            parameterizable: true,
            hasResults: false,
            showDescription: false,
        }
    }

    componentWillMount() {
        this.initialize(this.props.id);
    }

    componentDidMount() {
        this.updateSize();

        // If present, register the resize callback
        // to respond to interactive resizes from react-grid-layout.
        if (this.props.registerResize) {
            this.props.registerResize(this.updateSize.bind(this))
        }
    }

    componentWillReceiveProps(nextProps) {
        this.initialize(nextProps.id);
    }

    componentDidUpdate() {
        this.updateSize();
    }

    updateSize() {
        if (this._element) {
            const { width, height } = resizeVisualization(this._element);

            if (width !== this.state.width || height !== this.state.height) {
                this.setState({ width, height });
            }
        }
    }

    initialize(id) {

        this.props.fetchConfigurationIfNeeded(id).then((c) => {
            const { configuration } = this.props

            if (!configuration)
                return;

            const queryName  = configuration.get("query"),
                  scriptName = configuration.get("script");

            if (scriptName) {
                const { executeScriptIfNeeded, context } = this.props;
                executeScriptIfNeeded(scriptName, context);
            }

            if (queryName) {
                this.props.fetchQueryIfNeeded(queryName).then(() => {
                    const { queryConfiguration, executeQueryIfNeeded, context } = this.props;

                    if (!queryConfiguration)
                        return;

                    executeQueryIfNeeded(queryConfiguration.toJS(), context).then(
                        () => {
                            this.setState({
                                parameterizable: true,
                            });
                        },
                        (error) => {
                            this.setState({
                                parameterizable: false,
                            });
                        }
                    );
                });
            }

            // Handle configured listeners (e.g. navigate when clicking on a bar).
            if(configuration.get("listeners")) {
                // Use this.state.listeners to store the listeners that will be
                // passed into the visualization components.
                this.setState({

                    // This will be an object whose keys are event names,
                    // and whose values are functions that accept the data object
                    // corresponding to the clicked visual element.
                    listeners: configuration.get("listeners").reduce((listeners, listener) => {
                        // Use ES6 destructuring with defaults.
                        const {

                            // By default, use the "onMarkClick" event.
                            event = "onMarkClick",

                            // By default, stay on the current route.
                            redirect = window.location.pathname,

                            // By default, specify no additional query params.
                            params = {}
                        } = listener.toJS();

                        // Each listener expects the data object `d`,
                        // which corresponds to a row of data visualized.
                        listeners[event] = (d) => {

                            // Compute the query params from the data object.
                            let queryParams = Object.keys(params)
                                .reduce((queryParams, destinationParam) => {
                                    const sourceColumn = params[destinationParam];
                                    queryParams[destinationParam] = d[sourceColumn];
                                    return queryParams;
                                }, {});

                            // Override the existing context with the new params.
                            queryParams = Object.assign({}, this.props.context, queryParams);

                            // Perform the navigation via react-router.
                            this.props.goTo(redirect, queryParams);
                        };

                        return listeners;
                    }, {})
                });
            }
        });
    }

    shouldShowVisualization() {
        const { configuration, response } = this.props;

        return configuration && response && !response.get("isFetching");
    }

    renderCardWithInfo(message, iconName, spin = false) {
        return (
            <CardOverlay
                overlayStyle={style.overlayContainer}
                textStyle={style.overlayText}
                text={(

                        <FontAwesome
                            name={iconName}
                            size="2x"
                            spin={spin}
                            />

                        {message}

                )}
                />
        )
    }

    renderVisualization() {
        const { configuration,
                queryConfiguration,
                response
        } = this.props;

        const graphName      = configuration.get("graph"),
              GraphComponent = GraphManager.getGraphComponent(graphName);

        const currentResponse = response.toJS();

        if (currentResponse.error) {
            return this.renderCardWithInfo("Oops, " + currentResponse.error, "meh-o");
        }

        const data = ServiceManager.tabify(queryConfiguration, currentResponse.results);

        if (!data || !data.length) {
            return this.renderCardWithInfo("No data to visualize", "bar-chart");
        }

        let description;

        if (this.state.showDescription) {
            description = <CardOverlay
                                overlayStyle={style.descriptionContainer}
                                textStyle={style.descriptionText}
                                text={configuration.get("description")}
                                onTouchTapOverlay={() => { this.setState({showDescription: false}); }}
                                />
        }

        const timeout = configuration.get("refreshInterval") || 30000;

        return (

                <ReactInterval
                    enabled={true}
                    timeout={timeout}
                    callback={() => { this.initialize(this.props.id) }}
                    />
                <GraphComponent
                  data={data}
                  configuration={configuration.toJS()}
                  width={this.state.width}
                  height={this.state.height}
                  {...this.state.listeners}
                />
                {description}

        )
    }

    renderVisualizationIfNeeded() {
        if (this.shouldShowVisualization()) {
            return this.renderVisualization();
        }

        return this.renderCardWithInfo("Please wait while loading", "circle-o-notch", true);
    }

    shouldShowTitleBar() {
        const { configuration } = this.props;

        return configuration && this.currentTitle() && this.state.parameterizable && configuration.get("showTitleBar") !== false;
    }

    currentTitle() {
        const { configuration, context } = this.props;
        const title = configuration.get("title");

        if (!title)
            return ;

        return contextualize(title, context);
    }

    renderDescriptionIcon() {
        const { configuration } = this.props;

        if (!configuration.get("description"))
            return;

        return (
            <FontAwesome
                name="info-circle"
                style={style.cardIconMenu}
                onTouchTap={() => { this.setState({showDescription: !!configuration.get("description")}); }}
                />
        )
    }

    renderTitleBarIfNeeded() {
        if (!this.shouldShowTitleBar())
            return;

        return (

                {this.currentTitle()}

                    {this.renderDescriptionIcon()}

        )
    }

    renderFiltersToolBar() {
        const { configuration, context } = this.props;

        if (!configuration || !configuration.get("filterOptions"))
            return;

        return (
            <FiltersToolBar filterOptions={configuration.get("filterOptions")} context={context} />
        )
    }

    cardTextReference = (c) => {
        if (this._element)
            return;

        this._element = ReactDOM.findDOMNode(c).parentElement;
    }

    render() {
        if (!this.state.parameterizable)
            return (

);

        return (
            <Card
              style={style.card}
              containerStyle={style.cardContainer}
              ref={this.cardTextReference}
            >
                { this.renderTitleBarIfNeeded() }
                { this.renderFiltersToolBar() }
                <CardText style={style.cardText}>
                    { this.renderVisualizationIfNeeded() }
                </CardText>
            </Card>
        );
    }
}

const mapStateToProps = (state, ownProps) => {

    const configurationID = ownProps.id || ownProps.params.id,
          context         = ownProps.context || ownProps.location.query;

    const props = {
        id: configurationID,
        context: context,

        configuration: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.DATA
        ]),

        error: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.ERROR
        ])

    };

    // Expose the query template as a JS object if it is available.
    if (props.configuration) {
        const queryConfiguration = state.configurations.getIn([
            ConfigurationsActionKeyStore.QUERIES,
            props.configuration.get("query")
        ]);

        if (queryConfiguration && !queryConfiguration.get(
            ConfigurationsActionKeyStore.IS_FETCHING
        )) {
            props.queryConfiguration = queryConfiguration.get(
                ConfigurationsActionKeyStore.DATA
            );
        }

        const scriptName = props.configuration.get("script");

        // Expose received response if it is available
        if (props.queryConfiguration || scriptName) {
            const query = props.queryConfiguration ? props.queryConfiguration.toJS() : scriptName;
            const requestID = ServiceManager.getRequestID(query, context);

            let response = state.services.getIn([
                ServiceActionKeyStore.REQUESTS,
                requestID
            ]);
            if (response && !response.get(ServiceActionKeyStore.IS_FETCHING))
                props.response = response;
        }
    }

    return props;
};

const actionCreators = (dispatch) => ({

    setPageTitle: function(aTitle) {
        dispatch(Actions.updateTitle(aTitle));
    },

    goTo: function(link, filters) {
        dispatch(push({pathname:link, query:filters}));
    },

    fetchConfigurationIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.VISUALIZATIONS
        ));
    },

    fetchQueryIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.QUERIES
        ));
    },

    executeQueryIfNeeded: function(queryConfiguration, context) {
        return dispatch(ServiceActions.fetchIfNeeded(queryConfiguration, context));
    },

    executeScriptIfNeeded: function(scriptName, context) {
        return dispatch(ServiceActions.fetchIfNeeded(scriptName, context));
    }

 });

export default connect(mapStateToProps, actionCreators)(VisualizationView);
<commit_msg>Added PUBLIC_URL in listeners links<commit_after>import React from "react";
import ReactDOM from "react-dom";
import ReactInterval from 'react-interval';

import { connect } from "react-redux";
import { push } from "redux-router";

import FiltersToolBar from "../FiltersToolBar";
import { CardOverlay } from "../CardOverlay";
import { Card, CardText } from 'material-ui/Card';

import { Actions } from "./redux/actions";
import {
    Actions as ServiceActions,
    ActionKeyStore as ServiceActionKeyStore
} from "../../services/servicemanager/redux/actions";
import {
    Actions as ConfigurationsActions,
    ActionKeyStore as ConfigurationsActionKeyStore
} from "../../services/configurations/redux/actions";

import { resizeVisualization } from "../../utils/resize"
import { contextualize } from "../../utils/configurations"

import { GraphManager } from "../Graphs/index";
import { ServiceManager } from "../../services/servicemanager/index";

import style from "./styles"

import FontAwesome from "react-fontawesome";

class VisualizationView extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            parameterizable: true,
            hasResults: false,
            showDescription: false,
        }
    }

    componentWillMount() {
        this.initialize(this.props.id);
    }

    componentDidMount() {
        this.updateSize();

        // If present, register the resize callback
        // to respond to interactive resizes from react-grid-layout.
        if (this.props.registerResize) {
            this.props.registerResize(this.updateSize.bind(this))
        }
    }

    componentWillReceiveProps(nextProps) {
        this.initialize(nextProps.id);
    }

    componentDidUpdate() {
        this.updateSize();
    }

    updateSize() {
        if (this._element) {
            const { width, height } = resizeVisualization(this._element);

            if (width !== this.state.width || height !== this.state.height) {
                this.setState({ width, height });
            }
        }
    }

    initialize(id) {

        this.props.fetchConfigurationIfNeeded(id).then((c) => {
            const { configuration } = this.props

            if (!configuration)
                return;

            const queryName  = configuration.get("query"),
                  scriptName = configuration.get("script");

            if (scriptName) {
                const { executeScriptIfNeeded, context } = this.props;
                executeScriptIfNeeded(scriptName, context);
            }

            if (queryName) {
                this.props.fetchQueryIfNeeded(queryName).then(() => {
                    const { queryConfiguration, executeQueryIfNeeded, context } = this.props;

                    if (!queryConfiguration)
                        return;

                    executeQueryIfNeeded(queryConfiguration.toJS(), context).then(
                        () => {
                            this.setState({
                                parameterizable: true,
                            });
                        },
                        (error) => {
                            this.setState({
                                parameterizable: false,
                            });
                        }
                    );
                });
            }

            // Handle configured listeners (e.g. navigate when clicking on a bar).
            if(configuration.get("listeners")) {
                // Use this.state.listeners to store the listeners that will be
                // passed into the visualization components.
                this.setState({

                    // This will be an object whose keys are event names,
                    // and whose values are functions that accept the data object
                    // corresponding to the clicked visual element.
                    listeners: configuration.get("listeners").reduce((listeners, listener) => {
                        // Use ES6 destructuring with defaults.
                        const {

                            // By default, use the "onMarkClick" event.
                            event = "onMarkClick",

                            // By default, stay on the current route.
                            redirect = window.location.pathname,

                            // By default, specify no additional query params.
                            params = {}
                        } = listener.toJS();

                        // Each listener expects the data object `d`,
                        // which corresponds to a row of data visualized.
                        listeners[event] = (d) => {

                            // Compute the query params from the data object.
                            let queryParams = Object.keys(params)
                                .reduce((queryParams, destinationParam) => {
                                    const sourceColumn = params[destinationParam];
                                    queryParams[destinationParam] = d[sourceColumn];
                                    return queryParams;
                                }, {});

                            // Override the existing context with the new params.
                            queryParams = Object.assign({}, this.props.context, queryParams);

                            // Perform the navigation via react-router.
                            this.props.goTo(process.env.PUBLIC_URL + redirect, queryParams);
                        };

                        return listeners;
                    }, {})
                });
            }
        });
    }

    shouldShowVisualization() {
        const { configuration, response } = this.props;

        return configuration && response && !response.get("isFetching");
    }

    renderCardWithInfo(message, iconName, spin = false) {
        return (
            <CardOverlay
                overlayStyle={style.overlayContainer}
                textStyle={style.overlayText}
                text={(

                        <FontAwesome
                            name={iconName}
                            size="2x"
                            spin={spin}
                            />

                        {message}

                )}
                />
        )
    }

    renderVisualization() {
        const { configuration,
                queryConfiguration,
                response
        } = this.props;

        const graphName      = configuration.get("graph"),
              GraphComponent = GraphManager.getGraphComponent(graphName);

        const currentResponse = response.toJS();

        if (currentResponse.error) {
            return this.renderCardWithInfo("Oops, " + currentResponse.error, "meh-o");
        }

        const data = ServiceManager.tabify(queryConfiguration, currentResponse.results);

        if (!data || !data.length) {
            return this.renderCardWithInfo("No data to visualize", "bar-chart");
        }

        let description;

        if (this.state.showDescription) {
            description = <CardOverlay
                                overlayStyle={style.descriptionContainer}
                                textStyle={style.descriptionText}
                                text={configuration.get("description")}
                                onTouchTapOverlay={() => { this.setState({showDescription: false}); }}
                                />
        }

        const timeout = configuration.get("refreshInterval") || 30000;

        return (

                <ReactInterval
                    enabled={true}
                    timeout={timeout}
                    callback={() => { this.initialize(this.props.id) }}
                    />
                <GraphComponent
                  data={data}
                  configuration={configuration.toJS()}
                  width={this.state.width}
                  height={this.state.height}
                  {...this.state.listeners}
                />
                {description}

        )
    }

    renderVisualizationIfNeeded() {
        if (this.shouldShowVisualization()) {
            return this.renderVisualization();
        }

        return this.renderCardWithInfo("Please wait while loading", "circle-o-notch", true);
    }

    shouldShowTitleBar() {
        const { configuration } = this.props;

        return configuration && this.currentTitle() && this.state.parameterizable && configuration.get("showTitleBar") !== false;
    }

    currentTitle() {
        const { configuration, context } = this.props;
        const title = configuration.get("title");

        if (!title)
            return ;

        return contextualize(title, context);
    }

    renderDescriptionIcon() {
        const { configuration } = this.props;

        if (!configuration.get("description"))
            return;

        return (
            <FontAwesome
                name="info-circle"
                style={style.cardIconMenu}
                onTouchTap={() => { this.setState({showDescription: !!configuration.get("description")}); }}
                />
        )
    }

    renderTitleBarIfNeeded() {
        if (!this.shouldShowTitleBar())
            return;

        return (

                {this.currentTitle()}

                    {this.renderDescriptionIcon()}

        )
    }

    renderFiltersToolBar() {
        const { configuration, context } = this.props;

        if (!configuration || !configuration.get("filterOptions"))
            return;

        return (
            <FiltersToolBar filterOptions={configuration.get("filterOptions")} context={context} />
        )
    }

    cardTextReference = (c) => {
        if (this._element)
            return;

        this._element = ReactDOM.findDOMNode(c).parentElement;
    }

    render() {
        if (!this.state.parameterizable)
            return (

);

        return (
            <Card
              style={style.card}
              containerStyle={style.cardContainer}
              ref={this.cardTextReference}
            >
                { this.renderTitleBarIfNeeded() }
                { this.renderFiltersToolBar() }
                <CardText style={style.cardText}>
                    { this.renderVisualizationIfNeeded() }
                </CardText>
            </Card>
        );
    }
}

const mapStateToProps = (state, ownProps) => {

    const configurationID = ownProps.id || ownProps.params.id,
          context         = ownProps.context || ownProps.location.query;

    const props = {
        id: configurationID,
        context: context,

        configuration: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.DATA
        ]),

        error: state.configurations.getIn([
            ConfigurationsActionKeyStore.VISUALIZATIONS,
            configurationID,
            ConfigurationsActionKeyStore.ERROR
        ])

    };

    // Expose the query template as a JS object if it is available.
    if (props.configuration) {
        const queryConfiguration = state.configurations.getIn([
            ConfigurationsActionKeyStore.QUERIES,
            props.configuration.get("query")
        ]);

        if (queryConfiguration && !queryConfiguration.get(
            ConfigurationsActionKeyStore.IS_FETCHING
        )) {
            props.queryConfiguration = queryConfiguration.get(
                ConfigurationsActionKeyStore.DATA
            );
        }

        const scriptName = props.configuration.get("script");

        // Expose received response if it is available
        if (props.queryConfiguration || scriptName) {
            const query = props.queryConfiguration ? props.queryConfiguration.toJS() : scriptName;
            const requestID = ServiceManager.getRequestID(query, context);

            let response = state.services.getIn([
                ServiceActionKeyStore.REQUESTS,
                requestID
            ]);
            if (response && !response.get(ServiceActionKeyStore.IS_FETCHING))
                props.response = response;
        }
    }

    return props;
};

const actionCreators = (dispatch) => ({

    setPageTitle: function(aTitle) {
        dispatch(Actions.updateTitle(aTitle));
    },

    goTo: function(link, filters) {
        dispatch(push({pathname:link, query:filters}));
    },

    fetchConfigurationIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.VISUALIZATIONS
        ));
    },

    fetchQueryIfNeeded: function(id) {
        return dispatch(ConfigurationsActions.fetchIfNeeded(
            id,
            ConfigurationsActionKeyStore.QUERIES
        ));
    },

    executeQueryIfNeeded: function(queryConfiguration, context) {
        return dispatch(ServiceActions.fetchIfNeeded(queryConfiguration, context));
    },

    executeScriptIfNeeded: function(scriptName, context) {
        return dispatch(ServiceActions.fetchIfNeeded(scriptName, context));
    }

 });

export default connect(mapStateToProps, actionCreators)(VisualizationView);
<|endoftext|>


<commit_before>/**
 * @license Copyright (c) 2015, goreutils.com
 * For licensing, see LICENSE
 */

"use strict";

var mocha = require("gulp-mocha"),
    gulp = require("gulp"),
    path = require("path");

module.exports = function (baseDir) {
    var pckg = require(path.join(baseDir, "package.json")),
        globPattern = path.join(baseDir, pckg.directories.lib, "**", "*.test.js");

    return function () {
        return gulp.src(globPattern)
            .pipe(mocha({
                "bail": true,
                "reporter": "dot"
            }));
    };
};
<commit_msg>include jsx files in tests glob pattern<commit_after>/**
 * @license Copyright (c) 2015, goreutils.com
 * For licensing, see LICENSE
 */

"use strict";

var mocha = require("gulp-mocha"),
    gulp = require("gulp"),
    path = require("path");

module.exports = function (baseDir) {
    var pckg = require(path.join(baseDir, "package.json")),
        globPattern = path.join(baseDir, pckg.directories.lib, "**", "*.test.{js,jsx}");

    return function () {
        return gulp.src(globPattern)
            .pipe(mocha({
                "bail": true,
                "reporter": "dot"
            }));
    };
};
<|endoftext|>


<commit_before>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/
var et = require('elementtree'),
    xml= require('./xml-helpers'),
    fs = require('fs');

function config_parser(path) {
    this.path = path;
    this.doc = xml.parseElementtreeSync(path);
    this.access = new access(this);
    this.preference = new preference(this);
}

config_parser.prototype = {
    packageName:function(id) {
        if (id) {
            this.doc.getroot().attrib.id = id;
            this.update();
        } else return this.doc.getroot().attrib.id;
    },
    name:function(name) {
        if (name) {
            this.doc.find('name').text = name;
            this.update();
        } else return this.doc.find('name').text;
    },
    version:function(version) {
        if (version) {
            this.doc.getroot().attrib.version = version;
            this.update();
        } else return this.doc.getroot().attrib.version;
    },
    content: function(src) {
        var content = this.doc.find('content');
        if (src) {
            content = content || new et.Element('content');
            content.attrib.src = src;
            this.update();
        } else {
            if (!content) {
                content = new et.Element('content');
                content.attrib.src = 'index.html';
                this.doc.getroot().append(content);
                this.update();
            }
            return content.attrib.src;
        }
    },
    author: function (name) {
        if (name) {
            var author = this.doc.find('author');
            if (!author) {
                author = new et.Element('author');
                this.doc.getroot().append(author);
            }

            author.text = name;
            this.update();
        }
        else {
            var author = this.doc.find('author');
            return author ? author.text.trim() : '';
        }
    },
    update:function() {
        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
    },
    merge_with: function (cfg, platform, clobber) {
        var BLACKLIST = ["platform"],
            SINGLETONS = ["content", "author"];
        mergeXml(cfg.doc.getroot(), this.doc.getroot(), platform, clobber);
        this.update();

        function mergeXml(src, dest, platform, clobber) {
            if (BLACKLIST.indexOf(src.tag) === -1) {
                //Handle attributes
                Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
                    if (clobber || !dest.attrib[attribute]) {
                        dest.attrib[attribute] = src.attrib[attribute];
                    }
                });
                //Handle text
                if (src.text && (clobber || !dest.text)) {
                    dest.text = src.text;
                }
                //Handle platform
                if (platform) {
                    src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
                        platformElement.getchildren().forEach(mergeChild);
                    });
                }

                //Handle children
                src.getchildren().forEach(mergeChild);

                function mergeChild (srcChild) {
                    var srcTag = srcChild.tag,
                        destChild = new et.Element(srcTag),
                        foundChild,
                        query = srcTag + "",
                        shouldMerge = true;

                    if (BLACKLIST.indexOf(srcTag) === -1) {
                        if (SINGLETONS.indexOf(srcTag) !== -1) {
                            foundChild = dest.find(query);
                            if (foundChild) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                            }
                        } else {
                            //Check for an exact match and if you find one don't add
                            Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
                                query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
                            });
                            foundChild = dest.find(query);
                            if (foundChild && textMatch(srcChild, foundChild)) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                                shouldMerge = false;
                            }
                        }

                        mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
                        dest.append(destChild);
                    }
                }

                function textMatch(elm1, elm2) {
                    var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
                        text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
                    return (text1 === "" || text1 === text2);
                }
            }
        }
    }
};

function access(cfg) {
    this.config = cfg;
};

access.prototype = {
    add:function(uri, subdomain) {
        var el = new et.Element('access');
        el.attrib.origin = uri;
        if (typeof subdomain !== "undefined") el.attrib.subdomains = subdomain;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(uri) {
        var self = this;
        var els = [];
        if (uri) els = this.config.doc.findall('access[@origin="' + uri + '"]');
        else els = this.config.doc.findall('access');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib.origin || a.attrib.uri; });
    },
    getAttributes:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib; });
    }
};

function preference(cfg) {
    this.config = cfg;
};

preference.prototype = {
    add:function(pref) {
        var el = new et.Element('preference');
        el.attrib.name = pref.name;
        el.attrib.value = pref.value;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(name) {
        var self = this;
        var els = [];
        if (name) els = this.config.doc.findall('preference[@name="' + name + '"]');
        else els = this.config.doc.findall('preference');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('preference').map(function(a) {
            return {
                name:a.attrib.name,
                value:a.attrib.value
            };
        });
    }
};

module.exports = config_parser;
<commit_msg>CB-5614 Include path to file when config.xml fails to parse<commit_after>/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/
var et = require('elementtree'),
    xml= require('./xml-helpers'),
    fs = require('fs');

function config_parser(path) {
    this.path = path;
    try {
        this.doc = xml.parseElementtreeSync(path);
    } catch (e) {
        throw new Error("Parsing "+path+" failed:\n"+e.message);
    }
    this.access = new access(this);
    this.preference = new preference(this);
}

config_parser.prototype = {
    packageName:function(id) {
        if (id) {
            this.doc.getroot().attrib.id = id;
            this.update();
        } else return this.doc.getroot().attrib.id;
    },
    name:function(name) {
        if (name) {
            this.doc.find('name').text = name;
            this.update();
        } else return this.doc.find('name').text;
    },
    version:function(version) {
        if (version) {
            this.doc.getroot().attrib.version = version;
            this.update();
        } else return this.doc.getroot().attrib.version;
    },
    content: function(src) {
        var content = this.doc.find('content');
        if (src) {
            content = content || new et.Element('content');
            content.attrib.src = src;
            this.update();
        } else {
            if (!content) {
                content = new et.Element('content');
                content.attrib.src = 'index.html';
                this.doc.getroot().append(content);
                this.update();
            }
            return content.attrib.src;
        }
    },
    author: function (name) {
        if (name) {
            var author = this.doc.find('author');
            if (!author) {
                author = new et.Element('author');
                this.doc.getroot().append(author);
            }

            author.text = name;
            this.update();
        }
        else {
            var author = this.doc.find('author');
            return author ? author.text.trim() : '';
        }
    },
    update:function() {
        fs.writeFileSync(this.path, this.doc.write({indent: 4}), 'utf-8');
    },
    merge_with: function (cfg, platform, clobber) {
        var BLACKLIST = ["platform"],
            SINGLETONS = ["content", "author"];
        mergeXml(cfg.doc.getroot(), this.doc.getroot(), platform, clobber);
        this.update();

        function mergeXml(src, dest, platform, clobber) {
            if (BLACKLIST.indexOf(src.tag) === -1) {
                //Handle attributes
                Object.getOwnPropertyNames(src.attrib).forEach(function (attribute) {
                    if (clobber || !dest.attrib[attribute]) {
                        dest.attrib[attribute] = src.attrib[attribute];
                    }
                });
                //Handle text
                if (src.text && (clobber || !dest.text)) {
                    dest.text = src.text;
                }
                //Handle platform
                if (platform) {
                    src.findall('platform[@name="' + platform + '"]').forEach(function (platformElement) {
                        platformElement.getchildren().forEach(mergeChild);
                    });
                }

                //Handle children
                src.getchildren().forEach(mergeChild);

                function mergeChild (srcChild) {
                    var srcTag = srcChild.tag,
                        destChild = new et.Element(srcTag),
                        foundChild,
                        query = srcTag + "",
                        shouldMerge = true;

                    if (BLACKLIST.indexOf(srcTag) === -1) {
                        if (SINGLETONS.indexOf(srcTag) !== -1) {
                            foundChild = dest.find(query);
                            if (foundChild) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                            }
                        } else {
                            //Check for an exact match and if you find one don't add
                            Object.getOwnPropertyNames(srcChild.attrib).forEach(function (attribute) {
                                query += "[@" + attribute + '="' + srcChild.attrib[attribute] + '"]';
                            });
                            foundChild = dest.find(query);
                            if (foundChild && textMatch(srcChild, foundChild)) {
                                destChild = foundChild;
                                dest.remove(0, destChild);
                                shouldMerge = false;
                            }
                        }

                        mergeXml(srcChild, destChild, platform, clobber && shouldMerge);
                        dest.append(destChild);
                    }
                }

                function textMatch(elm1, elm2) {
                    var text1 = elm1.text ? elm1.text.replace(/\s+/, "") : "",
                        text2 = elm2.text ? elm2.text.replace(/\s+/, "") : "";
                    return (text1 === "" || text1 === text2);
                }
            }
        }
    }
};

function access(cfg) {
    this.config = cfg;
};

access.prototype = {
    add:function(uri, subdomain) {
        var el = new et.Element('access');
        el.attrib.origin = uri;
        if (typeof subdomain !== "undefined") el.attrib.subdomains = subdomain;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(uri) {
        var self = this;
        var els = [];
        if (uri) els = this.config.doc.findall('access[@origin="' + uri + '"]');
        else els = this.config.doc.findall('access');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib.origin || a.attrib.uri; });
    },
    getAttributes:function() {
        return this.config.doc.findall('access').map(function(a) { return a.attrib; });
    }
};

function preference(cfg) {
    this.config = cfg;
};

preference.prototype = {
    add:function(pref) {
        var el = new et.Element('preference');
        el.attrib.name = pref.name;
        el.attrib.value = pref.value;
        this.config.doc.getroot().append(el);
        this.config.update();
    },
    remove:function(name) {
        var self = this;
        var els = [];
        if (name) els = this.config.doc.findall('preference[@name="' + name + '"]');
        else els = this.config.doc.findall('preference');
        els.forEach(function(a) {
            self.config.doc.getroot().remove(0, a);
        });
        this.config.update();
    },
    get:function() {
        return this.config.doc.findall('preference').map(function(a) {
            return {
                name:a.attrib.name,
                value:a.attrib.value
            };
        });
    }
};

module.exports = config_parser;
<|endoftext|>


<commit_before><commit_msg>Begin implementing logic for Edit Task screen<commit_after><|endoftext|>


<commit_before>// @license
// Copyright (c) 2017 Google Inc. All rights reserved.
// This code may only be used under the BSD style license found at
// http://polymer.github.io/LICENSE.txt
// Code distributed by Google as part of this project is also
// subject to an additional IP rights grant found at
// http://polymer.github.io/PATENTS.txt

const gulp = require('gulp');

gulp.task('build', function() {
  const browserify = require('browserify');
  const source = require('vinyl-source-stream');
  const buffer = require('vinyl-buffer');
  const sourcemaps = require('gulp-sourcemaps');

  function build(file) {
  }

  for (let file of [
    'browser-test/browser-test.js',
    'browser-demo/browser-demo.js',
  ]) {
    browserify({
      entries: file,
      debug: true,
    }).bundle()
        .pipe(source(file))
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('./build/'));
  }
});

gulp.task('test', function() {
  const mocha = require('gulp-mocha');
  return gulp.src(['test/*.js'], {read: false})
    .pipe(mocha({reporter: 'list'}));
});

gulp.task('watch', function() {
  // TODO: Move all src to src/ so we can glob recursively here.
  gulp.watch(['*.js', 'test/**'], ['build', 'test']);
});

gulp.task('default', ['build', 'test']);
<commit_msg>Better globbing for watch<commit_after>// @license
// Copyright (c) 2017 Google Inc. All rights reserved.
// This code may only be used under the BSD style license found at
// http://polymer.github.io/LICENSE.txt
// Code distributed by Google as part of this project is also
// subject to an additional IP rights grant found at
// http://polymer.github.io/PATENTS.txt

const gulp = require('gulp');

gulp.task('build', function() {
  const browserify = require('browserify');
  const source = require('vinyl-source-stream');
  const buffer = require('vinyl-buffer');
  const sourcemaps = require('gulp-sourcemaps');

  for (let file of [
    'browser-test/browser-test.js',
    'browser-demo/browser-demo.js',
  ]) {
    browserify({
      entries: file,
      debug: true,
    }).bundle()
        .pipe(source(file))
        .pipe(buffer())
        .pipe(sourcemaps.init({loadMaps: true}))
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('./build/'));
  }
});

gulp.task('test', function() {
  const mocha = require('gulp-mocha');
  return gulp.src(['test/*.js'], {read: false})
    .pipe(mocha({reporter: 'list'}));
});

gulp.task('watch', function() {
  gulp.watch(['**', '!build/**'], ['build', 'test']);
});

gulp.task('default', ['build', 'test']);
<|endoftext|>


<commit_before><commit_msg>[docs] add hr style to match h2 border-bottom<commit_after><|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var request = require('request');
var config = require('config.json');

router.get('/', function (req, res) {
    res.render('contact');
});

router.get('/contact', function (req, res) {
    res.render('contact');
});
module.exports = router;

<commit_msg>Addded 1.controller for contact page<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');
var config = require('config.json');

router.get('/', function (req, res) {
    res.render('contact');
});

router.get('/contact', function (req, res) {
    res.render('contact');
});
module.exports = router;

<|endoftext|>


<commit_before>var Ajv = require('ajv')
var ajv = Ajv();
var schema = {
  "type": "object",
  "properties": {
    "foo": { "type": "number" },
    "bar": { "type": "string" }
  },
  "required": [ "foo", "bar" ]
};

var data = { "foo": 1 };

var valid = ajv.validate(schema, data);

if (!valid) {
  return res.send(400, ajv.errorsText(), ajv.errors);
}
<commit_msg>Update contract.js<commit_after>var Ajv = require('ajv')
var ajv =  new Ajv({ coerceTypes: true, useDefaults: true, removeAdditional: true })
var schema = {
  "type": "object",
  "properties": {
    "foo": { "type": "number" },
    "bar": { "type": "string" }
  },
  "required": [ "foo", "bar" ]
};

var data = { "foo": 1 };

var valid = ajv.validate(schema, data);

if (!valid) {
  return res.send(400, ajv.errorsText(), ajv.errors);
}
// Fastest
var Ajv = require('ajv');
var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true}
var validate = ajv.compile(schema);
var valid = validate(data);
if (!valid) console.log(validate.errors);
<|endoftext|>


<commit_before>function define(name, value) {
    Object.defineProperty(exports, name, {
        value     : value,
        enumerable: true
    });
}

define('NAMESPACE', 'ns:points');
define('SOCKETS', 'ns-points');<commit_msg>user object freeze for constants<commit_after>module.exports = Object.freeze({
    NAMESPACE: 'ns:points',
    SOCKETS  : 'ns-points'
});
<|endoftext|>