<commit_before>'use strict';

var React = require('react');
var t = require('tcomb-validation');
var shouldComponentUpdate = require('./shouldComponentUpdate');
var getComponent = require('../getComponent');
var api = require('../api');
var skin = require('../skin');
var getError = require('../util/getError');
var merge = require('../util/merge');
var move = require('../util/move');
var uuid = require('../util/uuid');
var getReport = require('../util/getReport');
var compile = require('uvdom/react').compile;
var debug = require('debug')('component:List');

function justify(value, keys) {
  if (value.length === keys.length) { return keys; }
  var ret = [];
  for (var i = 0, len = value.length ; i < len ; i++ ) {
    ret[i] = keys[i] || uuid();
  }
  return ret;
}

function normalize(value) {
  t.maybe(t.Arr)(value);
  return value || [];
}

var List = React.createClass({

  displayName: 'List',

  getInitialState: function () {
    var value = normalize(this.props.value);
    return {
      hasError: false,
      value: value,
      keys: value.map(uuid)
    };
  },

  componentWillReceiveProps: function (props) {
    var value = normalize(props.value);
    this.setState({
      value: value,
      keys: justify(value, this.state.keys)
    });
  },

  shouldComponentUpdate: shouldComponentUpdate,

  onChange: function (value, keys) {
    this.props.onChange(value);
    this.setState({value: value, keys: keys});
  },

  getValue: function () {
    var report = this.props.ctx.report;
    var value = [];
    var errors = [];
    var hasError = false;
    var result;

    for (var i = 0, len = this.state.value.length ; i < len ; i++ ) {
      result = this.refs[i].getValue();
      errors = errors.concat(result.errors);
      value.push(result.value);
    }

    // handle subtype
    if (report.subtype && errors.length === 0) {
      result = t.validate(value, report.type);
      hasError = !result.isValid();
      errors = errors.concat(result.errors);
    }

    this.setState({hasError: hasError});
    return new t.ValidationResult({errors: errors, value: value});
  },

  addItem: function (evt) {
    evt.preventDefault();
    var value = this.state.value.concat(null);
    var keys = this.state.keys.concat(uuid());
    this.onChange(value, keys);
  },

  onItemChange: function (itemIndex, itemValue) {
    var value = this.state.value.slice();
    value[itemIndex] = itemValue;
    this.onChange(value, this.state.keys);
  },

  removeItem: function (i, evt) {
    evt.preventDefault();
    var value = this.state.value.slice();
    value.splice(i, 1);
    var keys = this.state.keys.slice();
    keys.splice(i, 1);
    this.onChange(value, keys);
  },

  moveUpItem: function (i, evt) {
    evt.preventDefault();
    if (i > 0) {
      this.onChange(
        move(this.state.value.slice(), i, i - 1),
        move(this.state.keys.slice(), i, i - 1)
      );
    }
  },

  moveDownItem: function (i, evt) {
    evt.preventDefault();
    if (i < this.state.value.length - 1) {
      this.onChange(
        move(this.state.value.slice(), i, i + 1),
        move(this.state.keys.slice(), i, i + 1)
      );
    }
  },

  getLocals: function () {
    var opts = new api.List(this.props.options || {});
    var ctx = this.props.ctx;
    debug('render() called for `%s` field', ctx.name);
    t.assert(!ctx.report.maybe, 'maybe lists are not supported');
    var auto = opts.auto || ctx.auto;
    var i18n = opts.i18n || ctx.i18n;
    var value = t.Arr(this.state.value || []);

    // handle legend
    var legend = opts.legend; // always use the option value if is manually set
    if (!legend && ctx.auto === 'labels') {
      // add automatically a legend only if there is not a legend
      // and the 'labels' auto option is turned on
      legend = ctx.getDefaultLabel();
    }

    var config = merge(ctx.config, opts.config);
    var templates = merge(ctx.templates, opts.templates);
    var itemType = ctx.report.innerType.meta.type;
    var factory = React.createFactory(getComponent(itemType, opts.item));
    var items = value.map(function (value, i) {
      var buttons = [];
      if (!opts.disabledRemove) { buttons.push({ label: i18n.remove, click: this.removeItem.bind(this, i) }); }
      if (!opts.disableOrder)   { buttons.push({ label: i18n.up, click: this.moveUpItem.bind(this, i) }); }
      if (!opts.disableOrder)   { buttons.push({ label: i18n.down, click: this.moveDownItem.bind(this, i) }); }
      return {
        input: factory({
          ref: i,
          type: itemType,
          options: opts.item,
          value: value,
          onChange: this.onItemChange.bind(this, i),
          ctx: new api.Context({
            auto:       auto,
            config:     config,
            i18n:       i18n,
            label:      null,
            name:       ctx.name + '[' + i + ']',
            report:     new getReport(itemType),
            templates:  templates
          })
        }),
        key: this.state.keys[i],
        buttons: buttons
      };
    }.bind(this));
    return {
      add: opts.disableAdd ? null : {
        label: i18n.add,
        click: this.addItem
      },
      config: config,
      disabled: opts.disabled,
      error: getError(opts.error, value),
      hasError: opts.hasError || this.state.hasError,
      help: opts.help,
      items: items,
      legend: legend,
      value: value,
      templates: templates
    };
  },

  render: function () {
    var locals = this.getLocals();
    return compile(locals.templates.list(new skin.List(locals)));
  }

});

module.exports = List;<commit_msg>Update List.js<commit_after>'use strict';

var React = require('react');
var t = require('tcomb-validation');
var shouldComponentUpdate = require('./shouldComponentUpdate');
var getComponent = require('../getComponent');
var api = require('../api');
var skin = require('../skin');
var getError = require('../util/getError');
var merge = require('../util/merge');
var move = require('../util/move');
var uuid = require('../util/uuid');
var getReport = require('../util/getReport');
var compile = require('uvdom/react').compile;
var debug = require('debug')('component:List');

function justify(value, keys) {
  if (value.length === keys.length) { return keys; }
  var ret = [];
  for (var i = 0, len = value.length ; i < len ; i++ ) {
    ret[i] = keys[i] || uuid();
  }
  return ret;
}

function normalize(value) {
  t.maybe(t.Arr)(value);
  return value || [];
}

var List = React.createClass({

  displayName: 'List',

  getInitialState: function () {
    var value = normalize(this.props.value);
    return {
      hasError: false,
      value: value,
      keys: value.map(uuid)
    };
  },

  componentWillReceiveProps: function (props) {
    var value = normalize(props.value);
    this.setState({
      value: value,
      keys: justify(value, this.state.keys)
    });
  },

  shouldComponentUpdate: shouldComponentUpdate,

  onChange: function (value, keys) {
    this.props.onChange(value);
    this.setState({value: value, keys: keys});
  },

  getValue: function () {
    var report = this.props.ctx.report;
    var value = [];
    var errors = [];
    var hasError = false;
    var result;

    for (var i = 0, len = this.state.value.length ; i < len ; i++ ) {
      result = this.refs[i].getValue();
      errors = errors.concat(result.errors);
      value.push(result.value);
    }

    // handle subtype
    if (report.subtype && errors.length === 0) {
      result = t.validate(value, report.type);
      hasError = !result.isValid();
      errors = errors.concat(result.errors);
    }

    this.setState({hasError: hasError});
    return new t.ValidationResult({errors: errors, value: value});
  },

  addItem: function (evt) {
    evt.preventDefault();
    var value = this.state.value.concat(null);
    var keys = this.state.keys.concat(uuid());
    this.onChange(value, keys);
  },

  onItemChange: function (itemIndex, itemValue) {
    var value = this.state.value.slice();
    value[itemIndex] = itemValue;
    this.onChange(value, this.state.keys);
  },

  removeItem: function (i, evt) {
    evt.preventDefault();
    var value = this.state.value.slice();
    value.splice(i, 1);
    var keys = this.state.keys.slice();
    keys.splice(i, 1);
    this.onChange(value, keys);
  },

  moveUpItem: function (i, evt) {
    evt.preventDefault();
    if (i > 0) {
      this.onChange(
        move(this.state.value.slice(), i, i - 1),
        move(this.state.keys.slice(), i, i - 1)
      );
    }
  },

  moveDownItem: function (i, evt) {
    evt.preventDefault();
    if (i < this.state.value.length - 1) {
      this.onChange(
        move(this.state.value.slice(), i, i + 1),
        move(this.state.keys.slice(), i, i + 1)
      );
    }
  },

  getLocals: function () {
    var opts = new api.List(this.props.options || {});
    var ctx = this.props.ctx;
    debug('render() called for `%s` field', ctx.name);
    t.assert(!ctx.report.maybe, 'maybe lists are not supported');
    var auto = opts.auto || ctx.auto;
    var i18n = opts.i18n || ctx.i18n;
    var value = t.Arr(this.state.value || []);

    // handle legend
    var legend = opts.legend; // always use the option value if is manually set
    if (!legend && ctx.auto === 'labels') {
      // add automatically a legend only if there is not a legend
      // and the 'labels' auto option is turned on
      legend = ctx.getDefaultLabel();
    }

    var config = merge(ctx.config, opts.config);
    var templates = merge(ctx.templates, opts.templates);
    var itemType = ctx.report.innerType.meta.type;
    var factory = React.createFactory(getComponent(itemType, opts.item));
    var items = value.map(function (value, i) {
      var buttons = [];
      if (!opts.disableRemove) { buttons.push({ label: i18n.remove, click: this.removeItem.bind(this, i) }); }
      if (!opts.disableOrder)   { buttons.push({ label: i18n.up, click: this.moveUpItem.bind(this, i) }); }
      if (!opts.disableOrder)   { buttons.push({ label: i18n.down, click: this.moveDownItem.bind(this, i) }); }
      return {
        input: factory({
          ref: i,
          type: itemType,
          options: opts.item,
          value: value,
          onChange: this.onItemChange.bind(this, i),
          ctx: new api.Context({
            auto:       auto,
            config:     config,
            i18n:       i18n,
            label:      null,
            name:       ctx.name + '[' + i + ']',
            report:     new getReport(itemType),
            templates:  templates
          })
        }),
        key: this.state.keys[i],
        buttons: buttons
      };
    }.bind(this));
    return {
      add: opts.disableAdd ? null : {
        label: i18n.add,
        click: this.addItem
      },
      config: config,
      disabled: opts.disabled,
      error: getError(opts.error, value),
      hasError: opts.hasError || this.state.hasError,
      help: opts.help,
      items: items,
      legend: legend,
      value: value,
      templates: templates
    };
  },

  render: function () {
    var locals = this.getLocals();
    return compile(locals.templates.list(new skin.List(locals)));
  }

});

module.exports = List;
<|endoftext|>


<commit_before>var Genfors;

Genfors = (function () {

    var DEBUG = false

    var ACTIVE_QUESTION = null

    return {
        vote: (function () {
            return {
                bind_buttons: function () {
                    $('#verify_vote').on('click', function (e) {
                        e.preventDefault();
                        $('.voteverification').slideDown(200);
                        $('#verify_vote').addClass('disabled');
                    });
                    $('#cancel_vote').on('click', function (e) {
                        e.preventDefault();
                        $('.voteverification').slideUp(200);
                        $('#verify_vote').removeClass('disabled');
                    });
                    $('#toggle_vote_code').on('click', function (e) {
                        var self = $(this);
                        var span = $('#vote_code');
                        if(!span.is(':visible')) {
                            span.show();
                            self.text('Skjul stemmekode');
                        }
                        else {
                            span.hide();
                            self.text('Vis stemmekode');
                        }
                    });
                    $('input[name=choice]:radio').change(function (e) {
                        e.preventDefault();
                        $('.voteverification').slideUp(200);
                        $('#verify_vote').removeClass('disabled');
                    });
                },
            }
        }()),

        update: function () {
            $.getJSON("/genfors/api/user", function (data) {
                if (DEBUG) console.log("Update cycle...")
                // Is this the first run after page load?
                if (ACTIVE_QUESTION === null) {
                    if (DEBUG) console.log("First run after pageload.")
                    // Is there an active question?
                    if (data.question !== null) {
                        // Set the flag to true
                        ACTIVE_QUESTION = true
                        if (DEBUG) console.log("We have an active question, updating flag.")
                    }
                    else {
                        // We do not have an active question, set flag and return
                        ACTIVE_QUESTION = false
                        if (DEBUG) console.log("We do not have an active question, updating flag.")
                        return
                    }
                // Do we have an active question?
                } else if (ACTIVE_QUESTION === true) {
                    // If we have an active question, but it has now been closed, reload
                    if (DEBUG) console.log("We have an active question.")
                    if (data.question === null) {
                        if (DEBUG) console.log("Question close detected, reloading page.")
                        window.location.reload()
                        return
                    }
                // We do not have an active question
                } else if (ACTIVE_QUESTION === false) {
                    if (DEBUG) console.log("We do not have an active question.")
                    // We did not have an active question, but now have one, reload
                    if (data.question !== null) {
                        if (DEBUG) console.log("New question detected, reloading page.")
                        window.location.reload()
                    }
                    // Else just return
                    else return
                }

                if ('total_voter' in data.question) {
                    $('#total_voters').text(data.question.total_voters);
                }
                if ('current_votes' in data.question) {
                    $('#current_vote_count').text(data.question.current_votes);
                }
                var votes_html = "";
                if ('votes' in data.question) {
                    for (var x = 0; x < data.question.votes.length; x++) {
                        votes_html += '
' + data.question.votes[x][0];
                        var v = data.question.votes[x][1];
                        if (v === true || v === false || v === null) {
                            if (v) {
                                votes_html += 'Ja
';
                            }
                            else if (v == false) {
                                votes_html += 'Nei
';
                            }
                            else {
                                votes_html += 'Blankt
';
                            }
                        }
                        else {
                            if (v == 'Blankt') {
                                votes_html += '' + v + '
';
                            }
                            else {
                                votes_html += ''+ v.substring(0,20);
                                if (v.length > 20) votes_html += '…';
                                votes_html += '
';
                            }
                        }
                    }
                    $('#votes').html(votes_html);
                }
                if ('results' in data.question) {
                    var r = data.question.results.data;
                    var blank = r['Blankt'];
                    var votes_for_alternative = data.question.current_votes - blank;
                    if ('Ja' in r || 'Nei' in r) {
                        var yes = r['Ja']
                        var no = r['Nei']
                        var current_votes = data.question.current_votes;
                        var options = Object.keys(r);
                        options.sort(function(a,b) {return r[b]-r[a]});
                        var html = "";
                        for (var x = 0; x < options.length; x++) {
                            var key = options[x];
                            var value = r[key];
                            var percent;
                            if (key == 'Blankt') {
                                percent = Genfors.get_percent(value, current_votes);
                            }
                            else{
                                percent = Genfors.get_percent(value, votes_for_alternative);
                            }
                            html += '' + key + ': ' + value + ' stemme' + ((value>1)?'r':'');
                            type = "";
                            if (key == 'Blankt') {
                                type = 'warning';
                                html += '

' + value + ' av ' + current_votes +
                                    ' stemme' + ((current_votes>1)?'r':'') + '

';
                            }
                            else {
                                if (key == 'Ja') {
                                    type = 'success';
                                }
                                else if (key == 'Nei') {
                                    type = 'danger';
                                }
                                html += '

' + percent + '%

';
                            }
                        }
                        $('#bool_progress').html(html);
                    }
                    else {
                        var alternatives = Object.keys(r);
                        alternatives.sort(function(a,b){return r[b]-r[a]});
                        alternatives = Genfors.blank_at_top(alternatives);
                        var current_votes = data.question.current_votes;
                        var html = "";
                        for (var x = 0; x < alternatives.length; x++) {
                            var key = alternatives[x];
                            var value = r[key];
                            var percent;
                            html += '' + key + ': ' + value + ' stemme' + ((value>1)?'r':'');
                            if (key == 'Blankt') {
                                percent = Genfors.get_percent(value, current_votes);
                                type = "warning";
                                html += '

' + value + ' av ' + current_votes + ' stemme' + ((current_votes>1)?'r':'') +
                                    '

';
                            }
                            else {
                                percent = Genfors.get_percent(value, votes_for_alternative);
                                type = "primary";
                                html += '

' + percent + '%

';
                            }
                        }
                        $('#mc_progress').html(html);
                    }
                }
                //console.log(new Date() + ': Fetched stats from genfors API.');
            });
        },

        get_percent: function (votes, total) {
            return Math.floor(votes * 100 / total);
        },

        blank_at_top: function (alternatives) {
            for (var i = 0; i < alternatives.length; i++) {
                if (alternatives[i] == 'Blankt') {
                    var blank = alternatives[i];
                    alternatives.splice(i, 1);
                    alternatives.unshift(blank);
                    return alternatives;
                }
            }
            return null;
        }
    }
}());

$(document).ready(function () {
    Genfors.vote.bind_buttons();
    setInterval(Genfors.update, 10000);
});
<commit_msg>removed empty
 tags<commit_after>var Genfors;

Genfors = (function () {

    var DEBUG = false

    var ACTIVE_QUESTION = null

    return {
        vote: (function () {
            return {
                bind_buttons: function () {
                    $('#verify_vote').on('click', function (e) {
                        e.preventDefault();
                        $('.voteverification').slideDown(200);
                        $('#verify_vote').addClass('disabled');
                    });
                    $('#cancel_vote').on('click', function (e) {
                        e.preventDefault();
                        $('.voteverification').slideUp(200);
                        $('#verify_vote').removeClass('disabled');
                    });
                    $('#toggle_vote_code').on('click', function (e) {
                        var self = $(this);
                        var span = $('#vote_code');
                        if(!span.is(':visible')) {
                            span.show();
                            self.text('Skjul stemmekode');
                        }
                        else {
                            span.hide();
                            self.text('Vis stemmekode');
                        }
                    });
                    $('input[name=choice]:radio').change(function (e) {
                        e.preventDefault();
                        $('.voteverification').slideUp(200);
                        $('#verify_vote').removeClass('disabled');
                    });
                },
            }
        }()),

        update: function () {
            $.getJSON("/genfors/api/user", function (data) {
                if (DEBUG) console.log("Update cycle...")
                // Is this the first run after page load?
                if (ACTIVE_QUESTION === null) {
                    if (DEBUG) console.log("First run after pageload.")
                    // Is there an active question?
                    if (data.question !== null) {
                        // Set the flag to true
                        ACTIVE_QUESTION = true
                        if (DEBUG) console.log("We have an active question, updating flag.")
                    }
                    else {
                        // We do not have an active question, set flag and return
                        ACTIVE_QUESTION = false
                        if (DEBUG) console.log("We do not have an active question, updating flag.")
                        return
                    }
                // Do we have an active question?
                } else if (ACTIVE_QUESTION === true) {
                    // If we have an active question, but it has now been closed, reload
                    if (DEBUG) console.log("We have an active question.")
                    if (data.question === null) {
                        if (DEBUG) console.log("Question close detected, reloading page.")
                        window.location.reload()
                        return
                    }
                // We do not have an active question
                } else if (ACTIVE_QUESTION === false) {
                    if (DEBUG) console.log("We do not have an active question.")
                    // We did not have an active question, but now have one, reload
                    if (data.question !== null) {
                        if (DEBUG) console.log("New question detected, reloading page.")
                        window.location.reload()
                    }
                    // Else just return
                    else return
                }

                if ('total_voter' in data.question) {
                    $('#total_voters').text(data.question.total_voters);
                }
                if ('current_votes' in data.question) {
                    $('#current_vote_count').text(data.question.current_votes);
                }
                var votes_html = "";
                if ('votes' in data.question) {
                    for (var x = 0; x < data.question.votes.length; x++) {
                        votes_html += '
' + data.question.votes[x][0];
                        var v = data.question.votes[x][1];
                        if (v === true || v === false || v === null) {
                            if (v) {
                                votes_html += 'Ja
';
                            }
                            else if (v == false) {
                                votes_html += 'Nei
';
                            }
                            else {
                                votes_html += 'Blankt
';
                            }
                        }
                        else {
                            if (v == 'Blankt') {
                                votes_html += '' + v + '
';
                            }
                            else {
                                votes_html += ''+ v.substring(0,20);
                                if (v.length > 20) votes_html += '…';
                                votes_html += '
';
                            }
                        }
                    }
                    $('#votes').html(votes_html);
                }
                if ('results' in data.question) {
                    var r = data.question.results.data;
                    var blank = r['Blankt'];
                    var votes_for_alternative = data.question.current_votes - blank;
                    if ('Ja' in r || 'Nei' in r) {
                        var yes = r['Ja']
                        var no = r['Nei']
                        var current_votes = data.question.current_votes;
                        var options = Object.keys(r);
                        options.sort(function(a,b) {return r[b]-r[a]});
                        var html = "";
                        for (var x = 0; x < options.length; x++) {
                            var key = options[x];
                            var value = r[key];
                            var percent;
                            if (key == 'Blankt') {
                                percent = Genfors.get_percent(value, current_votes);
                            }
                            else{
                                percent = Genfors.get_percent(value, votes_for_alternative);
                            }
                            html += '
' + key + ': ' + value + ' stemme' + ((value>1)?'r':'') + '
';
                            type = "";
                            if (key == 'Blankt') {
                                type = 'warning';
                                html += '

' + value + ' av ' + current_votes +
                                    ' stemme' + ((current_votes>1)?'r':'') + '

';
                            }
                            else {
                                if (key == 'Ja') {
                                    type = 'success';
                                }
                                else if (key == 'Nei') {
                                    type = 'danger';
                                }
                                html += '

' + percent + '%

';
                            }
                        }
                        $('#bool_progress').html(html);
                    }
                    else {
                        var alternatives = Object.keys(r);
                        alternatives.sort(function(a,b){return r[b]-r[a]});
                        alternatives = Genfors.blank_at_top(alternatives);
                        var current_votes = data.question.current_votes;
                        var html = "";
                        for (var x = 0; x < alternatives.length; x++) {
                            var key = alternatives[x];
                            var value = r[key];
                            var percent;
                            html += '
' + key + ': ' + value + ' stemme' + ((value>1)?'r':'') + '
';
                            if (key == 'Blankt') {
                                percent = Genfors.get_percent(value, current_votes);
                                type = "warning";
                                html += '

' + value + ' av ' + current_votes + ' stemme' + ((current_votes>1)?'r':'') +
                                    '

';
                            }
                            else {
                                percent = Genfors.get_percent(value, votes_for_alternative);
                                type = "primary";
                                html += '

' + percent + '%

';
                            }
                        }
                        $('#mc_progress').html(html);
                    }
                }
                //console.log(new Date() + ': Fetched stats from genfors API.');
            });
        },

        get_percent: function (votes, total) {
            return Math.floor(votes * 100 / total);
        },

        blank_at_top: function (alternatives) {
            for (var i = 0; i < alternatives.length; i++) {
                if (alternatives[i] == 'Blankt') {
                    var blank = alternatives[i];
                    alternatives.splice(i, 1);
                    alternatives.unshift(blank);
                    return alternatives;
                }
            }
            return null;
        }
    }
}());

$(document).ready(function () {
    Genfors.vote.bind_buttons();
    setInterval(Genfors.update, 10000);
});
<|endoftext|>


<commit_before>PROTOTYPE._createPosClass = function(my) {
	return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev();
};

PROTOTYPE.reposition = function(event, effect) {
	if(!this.rendered || this.positioning || this.destroyed) { return this; }

	// Set positioning flag
	this.positioning = TRUE;

	var cache = this.cache,
		tooltip = this.tooltip,
		posOptions = this.options.position,
		target = posOptions.target,
		my = posOptions.my,
		at = posOptions.at,
		viewport = posOptions.viewport,
		container = posOptions.container,
		adjust = posOptions.adjust,
		method = adjust.method.split(' '),
		tooltipWidth = tooltip.outerWidth(FALSE),
		tooltipHeight = tooltip.outerHeight(FALSE),
		targetWidth = 0,
		targetHeight = 0,
		type = tooltip.css('position'),
		position = { left: 0, top: 0 },
		visible = tooltip[0].offsetWidth > 0,
		isScroll = event && event.type === 'scroll',
		win = $(window),
		doc = container[0].ownerDocument,
		mouse = this.mouse,
		pluginCalculations, offset;

	// Check if absolute position was passed
	if($.isArray(target) && target.length === 2) {
		// Force left top and set position
		at = { x: LEFT, y: TOP };
		position = { left: target[0], top: target[1] };
	}

	// Check if mouse was the target
	else if(target === 'mouse') {
		// Force left top to allow flipping
		at = { x: LEFT, y: TOP };

		// Use the cached mouse coordinates if available, or passed event has no coordinates
		if(mouse && mouse.pageX && (adjust.mouse || !event || !event.pageX) ) {
			event = mouse;
		}

		// If the passed event has no coordinates (such as a scroll event)
		else if(!event || !event.pageX) {
			// Use the mouse origin that caused the show event, if distance hiding is enabled
			if((!adjust.mouse || this.options.show.distance) && cache.origin && cache.origin.pageX) {
				event =  cache.origin;
			}

			// Use cached event for resize/scroll events
			else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) {
				event = cache.event;
			}
		}

		// Calculate body and container offset and take them into account below
		if(type !== 'static') { position = container.offset(); }
		if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) {
			offset = $(document.body).offset();
		}

		// Use event coordinates for position
		position = {
			left: event.pageX - position.left + (offset && offset.left || 0),
			top: event.pageY - position.top + (offset && offset.top || 0)
		};

		// Scroll events are a pain, some browsers
		if(adjust.mouse && isScroll && mouse) {
			position.left -= (mouse.scrollX || 0) - win.scrollLeft();
			position.top -= (mouse.scrollY || 0) - win.scrollTop();
		}
	}

	// Target wasn't mouse or absolute...
	else {
		// Check if event targetting is being used
		if(target === 'event') {
			if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
				cache.target = $(event.target);
			}
			else if(!event.target) {
				cache.target = this.elements.target;
			}
		}
		else if(target !== 'event'){
			cache.target = $(target.jquery ? target : this.elements.target);
		}
		target = cache.target;

		// Parse the target into a jQuery object and make sure there's an element present
		target = $(target).eq(0);
		if(target.length === 0) { return this; }

		// Check if window or document is the target
		else if(target[0] === document || target[0] === window) {
			targetWidth = BROWSER.iOS ? window.innerWidth : target.width();
			targetHeight = BROWSER.iOS ? window.innerHeight : target.height();

			if(target[0] === window) {
				position = {
					top: (viewport || target).scrollTop(),
					left: (viewport || target).scrollLeft()
				};
			}
		}

		// Check if the target is an <AREA> element
		else if(PLUGINS.imagemap && target.is('area')) {
			pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE);
		}

		// Check if the target is an SVG element
		else if(PLUGINS.svg && target && target[0].ownerSVGElement) {
			pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE);
		}

		// Otherwise use regular jQuery methods
		else {
			targetWidth = target.outerWidth(FALSE);
			targetHeight = target.outerHeight(FALSE);
			position = target.offset();
		}

		// Parse returned plugin values into proper variables
		if(pluginCalculations) {
			targetWidth = pluginCalculations.width;
			targetHeight = pluginCalculations.height;
			offset = pluginCalculations.offset;
			position = pluginCalculations.position;
		}

		// Adjust position to take into account offset parents
		position = this.reposition.offset(target, position, container);

		// Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
		if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
			(BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) ||
			(!BROWSER.iOS && type === 'fixed')
		){
			position.left -= win.scrollLeft();
			position.top -= win.scrollTop();
		}

		// Adjust position relative to target
		if(!pluginCalculations || (pluginCalculations && pluginCalculations.adjustable !== FALSE)) {
			position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0;
			position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0;
		}
	}

	// Adjust position relative to tooltip
	position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0);
	position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0);

	// Use viewport adjustment plugin if enabled
	if(PLUGINS.viewport) {
		position.adjusted = PLUGINS.viewport(
			this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight
		);

		// Apply offsets supplied by positioning plugin (if used)
		if(offset && position.adjusted.left) { position.left += offset.left; }
		if(offset && position.adjusted.top) {  position.top += offset.top; }
	}

	// Viewport adjustment is disabled, set values to zero
	else { position.adjusted = { left: 0, top: 0 }; }

	// tooltipmove event
	if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; }
	delete position.adjusted;

	// If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
	if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
		tooltip.css(position);
	}

	// Use custom function if provided
	else if($.isFunction(posOptions.effect)) {
		posOptions.effect.call(tooltip, this, $.extend({}, position));
		tooltip.queue(function(next) {
			// Reset attributes to avoid cross-browser rendering bugs
			$(this).css({ opacity: '', height: '' });
			if(BROWSER.ie) { this.style.removeAttribute('filter'); }

			next();
		});
	}

	// Set positioning flag
	this.positioning = FALSE;

	return this;
};

// Custom (more correct for qTip!) offset calculator
PROTOTYPE.reposition.offset = function(elem, pos, container) {
	if(!container[0]) { return pos; }

	var ownerDocument = $(elem[0].ownerDocument),
		quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat',
		parent = container[0],
		scrolled, position, parentOffset, overflow;

	function scroll(e, i) {
		pos.left += i * e.scrollLeft();
		pos.top += i * e.scrollTop();
	}

	// Compensate for non-static containers offset
	do {
		if((position = $.css(parent, 'position')) !== 'static') {
			if(position === 'fixed') {
				parentOffset = parent.getBoundingClientRect();
				scroll(ownerDocument, -1);
			}
			else {
				parentOffset = $(parent).position();
				parentOffset.left += (parseFloat($.css(parent, 'borderLeftWidth')) || 0);
				parentOffset.top += (parseFloat($.css(parent, 'borderTopWidth')) || 0);
			}

			pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0);
			pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0);

			// If this is the first parent element with an overflow of "scroll" or "auto", store it
			if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); }
		}
	}
	while((parent = parent.offsetParent));

	// Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode)
	if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) {
		scroll(scrolled, 1);
	}

	return pos;
};

// Corner class
var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) {
	corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase();
	this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
	this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();
	this.forceY = !!forceY;

	var f = corner.charAt(0);
	this.precedance = (f === 't' || f === 'b' ? Y : X);
}).prototype;

C.invert = function(z, center) {
	this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z];
};

C.string = function() {
	var x = this.x, y = this.y;
	return x === y ? x : this.precedance === Y || (this.forceY && y !== 'center') ? y+' '+x : x+' '+y;
};

C.abbrev = function() {
	var result = this.string().split(' ');
	return result[0].charAt(0) + (result[1] && result[1].charAt(0) || '');
};

C.clone = function() {
	return new CORNER( this.string(), this.forceY );
};<commit_msg>Fixes to mouse positioning<commit_after>PROTOTYPE._createPosClass = function(my) {
	return NAMESPACE + '-pos-' + (my || this.options.position.my).abbrev();
};

PROTOTYPE.reposition = function(event, effect) {
	if(!this.rendered || this.positioning || this.destroyed) { return this; }

	// Set positioning flag
	this.positioning = TRUE;

	var cache = this.cache,
		tooltip = this.tooltip,
		posOptions = this.options.position,
		target = posOptions.target,
		my = posOptions.my,
		at = posOptions.at,
		viewport = posOptions.viewport,
		container = posOptions.container,
		adjust = posOptions.adjust,
		method = adjust.method.split(' '),
		tooltipWidth = tooltip.outerWidth(FALSE),
		tooltipHeight = tooltip.outerHeight(FALSE),
		targetWidth = 0,
		targetHeight = 0,
		type = tooltip.css('position'),
		position = { left: 0, top: 0 },
		visible = tooltip[0].offsetWidth > 0,
		isScroll = event && event.type === 'scroll',
		win = $(window),
		doc = container[0].ownerDocument,
		mouse = this.mouse,
		pluginCalculations, offset;

	// Check if absolute position was passed
	if($.isArray(target) && target.length === 2) {
		// Force left top and set position
		at = { x: LEFT, y: TOP };
		position = { left: target[0], top: target[1] };
	}

	// Check if mouse was the target
	else if(target === 'mouse') {
		// Force left top to allow flipping
		at = { x: LEFT, y: TOP };

		// Use the mouse origin that caused the show event, if distance hiding is enabled
		if((!adjust.mouse || this.options.hide.distance) && cache.origin && cache.origin.pageX) {
			event =  cache.origin;
		}

		// Use cached event for resize/scroll events
		else if(!event || (event && (event.type === 'resize' || event.type === 'scroll'))) {
			event = cache.event;
		}

		// Otherwise, use the cached mouse coordinates if available
		else if(mouse && mouse.pageX) {
			event = mouse;
		}

		// Calculate body and container offset and take them into account below
		if(type !== 'static') { position = container.offset(); }
		if(doc.body.offsetWidth !== (window.innerWidth || doc.documentElement.clientWidth)) {
			offset = $(document.body).offset();
		}

		// Use event coordinates for position
		position = {
			left: event.pageX - position.left + (offset && offset.left || 0),
			top: event.pageY - position.top + (offset && offset.top || 0)
		};

		// Scroll events are a pain, some browsers
		if(adjust.mouse && isScroll && mouse) {
			position.left -= (mouse.scrollX || 0) - win.scrollLeft();
			position.top -= (mouse.scrollY || 0) - win.scrollTop();
		}
	}

	// Target wasn't mouse or absolute...
	else {
		// Check if event targetting is being used
		if(target === 'event') {
			if(event && event.target && event.type !== 'scroll' && event.type !== 'resize') {
				cache.target = $(event.target);
			}
			else if(!event.target) {
				cache.target = this.elements.target;
			}
		}
		else if(target !== 'event'){
			cache.target = $(target.jquery ? target : this.elements.target);
		}
		target = cache.target;

		// Parse the target into a jQuery object and make sure there's an element present
		target = $(target).eq(0);
		if(target.length === 0) { return this; }

		// Check if window or document is the target
		else if(target[0] === document || target[0] === window) {
			targetWidth = BROWSER.iOS ? window.innerWidth : target.width();
			targetHeight = BROWSER.iOS ? window.innerHeight : target.height();

			if(target[0] === window) {
				position = {
					top: (viewport || target).scrollTop(),
					left: (viewport || target).scrollLeft()
				};
			}
		}

		// Check if the target is an <AREA> element
		else if(PLUGINS.imagemap && target.is('area')) {
			pluginCalculations = PLUGINS.imagemap(this, target, at, PLUGINS.viewport ? method : FALSE);
		}

		// Check if the target is an SVG element
		else if(PLUGINS.svg && target && target[0].ownerSVGElement) {
			pluginCalculations = PLUGINS.svg(this, target, at, PLUGINS.viewport ? method : FALSE);
		}

		// Otherwise use regular jQuery methods
		else {
			targetWidth = target.outerWidth(FALSE);
			targetHeight = target.outerHeight(FALSE);
			position = target.offset();
		}

		// Parse returned plugin values into proper variables
		if(pluginCalculations) {
			targetWidth = pluginCalculations.width;
			targetHeight = pluginCalculations.height;
			offset = pluginCalculations.offset;
			position = pluginCalculations.position;
		}

		// Adjust position to take into account offset parents
		position = this.reposition.offset(target, position, container);

		// Adjust for position.fixed tooltips (and also iOS scroll bug in v3.2-4.0 & v4.3-4.3.2)
		if((BROWSER.iOS > 3.1 && BROWSER.iOS < 4.1) ||
			(BROWSER.iOS >= 4.3 && BROWSER.iOS < 4.33) ||
			(!BROWSER.iOS && type === 'fixed')
		){
			position.left -= win.scrollLeft();
			position.top -= win.scrollTop();
		}

		// Adjust position relative to target
		if(!pluginCalculations || (pluginCalculations && pluginCalculations.adjustable !== FALSE)) {
			position.left += at.x === RIGHT ? targetWidth : at.x === CENTER ? targetWidth / 2 : 0;
			position.top += at.y === BOTTOM ? targetHeight : at.y === CENTER ? targetHeight / 2 : 0;
		}
	}

	// Adjust position relative to tooltip
	position.left += adjust.x + (my.x === RIGHT ? -tooltipWidth : my.x === CENTER ? -tooltipWidth / 2 : 0);
	position.top += adjust.y + (my.y === BOTTOM ? -tooltipHeight : my.y === CENTER ? -tooltipHeight / 2 : 0);

	// Use viewport adjustment plugin if enabled
	if(PLUGINS.viewport) {
		position.adjusted = PLUGINS.viewport(
			this, position, posOptions, targetWidth, targetHeight, tooltipWidth, tooltipHeight
		);

		// Apply offsets supplied by positioning plugin (if used)
		if(offset && position.adjusted.left) { position.left += offset.left; }
		if(offset && position.adjusted.top) {  position.top += offset.top; }
	}

	// Viewport adjustment is disabled, set values to zero
	else { position.adjusted = { left: 0, top: 0 }; }

	// tooltipmove event
	if(!this._trigger('move', [position, viewport.elem || viewport], event)) { return this; }
	delete position.adjusted;

	// If effect is disabled, target it mouse, no animation is defined or positioning gives NaN out, set CSS directly
	if(effect === FALSE || !visible || isNaN(position.left) || isNaN(position.top) || target === 'mouse' || !$.isFunction(posOptions.effect)) {
		tooltip.css(position);
	}

	// Use custom function if provided
	else if($.isFunction(posOptions.effect)) {
		posOptions.effect.call(tooltip, this, $.extend({}, position));
		tooltip.queue(function(next) {
			// Reset attributes to avoid cross-browser rendering bugs
			$(this).css({ opacity: '', height: '' });
			if(BROWSER.ie) { this.style.removeAttribute('filter'); }

			next();
		});
	}

	// Set positioning flag
	this.positioning = FALSE;

	return this;
};

// Custom (more correct for qTip!) offset calculator
PROTOTYPE.reposition.offset = function(elem, pos, container) {
	if(!container[0]) { return pos; }

	var ownerDocument = $(elem[0].ownerDocument),
		quirks = !!BROWSER.ie && document.compatMode !== 'CSS1Compat',
		parent = container[0],
		scrolled, position, parentOffset, overflow;

	function scroll(e, i) {
		pos.left += i * e.scrollLeft();
		pos.top += i * e.scrollTop();
	}

	// Compensate for non-static containers offset
	do {
		if((position = $.css(parent, 'position')) !== 'static') {
			if(position === 'fixed') {
				parentOffset = parent.getBoundingClientRect();
				scroll(ownerDocument, -1);
			}
			else {
				parentOffset = $(parent).position();
				parentOffset.left += (parseFloat($.css(parent, 'borderLeftWidth')) || 0);
				parentOffset.top += (parseFloat($.css(parent, 'borderTopWidth')) || 0);
			}

			pos.left -= parentOffset.left + (parseFloat($.css(parent, 'marginLeft')) || 0);
			pos.top -= parentOffset.top + (parseFloat($.css(parent, 'marginTop')) || 0);

			// If this is the first parent element with an overflow of "scroll" or "auto", store it
			if(!scrolled && (overflow = $.css(parent, 'overflow')) !== 'hidden' && overflow !== 'visible') { scrolled = $(parent); }
		}
	}
	while((parent = parent.offsetParent));

	// Compensate for containers scroll if it also has an offsetParent (or in IE quirks mode)
	if(scrolled && (scrolled[0] !== ownerDocument[0] || quirks)) {
		scroll(scrolled, 1);
	}

	return pos;
};

// Corner class
var C = (CORNER = PROTOTYPE.reposition.Corner = function(corner, forceY) {
	corner = ('' + corner).replace(/([A-Z])/, ' $1').replace(/middle/gi, CENTER).toLowerCase();
	this.x = (corner.match(/left|right/i) || corner.match(/center/) || ['inherit'])[0].toLowerCase();
	this.y = (corner.match(/top|bottom|center/i) || ['inherit'])[0].toLowerCase();
	this.forceY = !!forceY;

	var f = corner.charAt(0);
	this.precedance = (f === 't' || f === 'b' ? Y : X);
}).prototype;

C.invert = function(z, center) {
	this[z] = this[z] === LEFT ? RIGHT : this[z] === RIGHT ? LEFT : center || this[z];
};

C.string = function() {
	var x = this.x, y = this.y;
	return x === y ? x : this.precedance === Y || (this.forceY && y !== 'center') ? y+' '+x : x+' '+y;
};

C.abbrev = function() {
	var result = this.string().split(' ');
	return result[0].charAt(0) + (result[1] && result[1].charAt(0) || '');
};

C.clone = function() {
	return new CORNER( this.string(), this.forceY );
};<|endoftext|>


<commit_before>var hostname = window.location.hostname;
var wsaddr = "wss://".concat(hostname, ":1234/api");
console.log("Connecting to " + wsaddr);

var paladinws = new PaladinWebSocket(wsaddr);

var width = $(document).width();
var height = $(document).height();

// Disable the scroll bar
document.documentElement.style.overflow = 'hidden';
// Only for IE
document.body.scroll = 'no';

var zoom = d3.zoom()
    .scaleExtent([1, 8])
    .on("zoom", zoomed);

var svg = d3.select("svg")
    .attr("width", width)
    .attr("height", height)

g = svg.append("g");

function zoomed () {
    g.attr("transform", d3.event.transform);
}

svg.call(zoom);

g.append("svg:image")
    .attr("xlink:href", "images/US.svg")
<commit_msg>Add alerts for web sockets<commit_after>var hostname = window.location.hostname;
var wsaddr = "wss://".concat(hostname, ":1234/api");

/*
 * Useful functions
 */
function map_alert(message) {
    $('body').prepend('

<button type="button" class="close" data-dismiss="alert" aria-label="Close"> ×</button>' + message + '

');
    $(".alert-dismissible").delay(3000).fadeOut("slow", function () { $(this).remove(); });
}

function message_handler(event) {
    map_alert(event.data);
}

/*
 * Initialize the page SVG and controls
 */
var width = $(document).width();
var height = $(document).height();

// Disable the scroll bar
document.documentElement.style.overflow = 'hidden';
// Only for IE
document.body.scroll = 'no';

var zoom = d3.zoom()
    .scaleExtent([1, 8])
    .on("zoom", zoomed);

var svg = d3.select("svg")
    .attr("width", width)
    .attr("height", height)

g = svg.append("g");

function zoomed () {
    g.attr("transform", d3.event.transform);
}

svg.call(zoom);

g.append("svg:image")
    .attr("xlink:href", "images/US.svg")

/*
 * Connect to the web socket
 */
var paladinws = new PaladinWebSocket(wsaddr);
paladinws.ws.onmessage = message_handler;

map_alert("Connected to " + wsaddr);
<|endoftext|>


<commit_before>/* global MessageChannel, performance, Promise */

var registerElement = require('../vr-register-element');

var THREE = require('../../lib/three');
var TWEEN = require('tween.js');
var VRNode = require('./vr-node');

var VRScene = module.exports = registerElement(
  'vr-scene',
  {
    prototype: Object.create(
      VRNode.prototype, {
        defaults: {
          value: {
            lights: {
              // Default directional light.
              0: {
                color: new THREE.Vector3(1.0, 1.0, 1.0),
                direction: new THREE.Vector3(-0.5, 1.0, 0.5),
                position: new THREE.Vector3(0, 0, 0),
                intensity: 5.0
              }
            }
          }
        },

        attachedCallback: {
          value: function () {
            this.insideIframe = window.top !== window.self;
            this.insideLoader = false;
            this.lights = {};
            this.materials = {};
            this.vrButton = null;
            document.addEventListener('vr-markup-ready',
                                      this.attachEventListeners.bind(this));
            this.attachFullscreenListeners();
            this.setupScene();
          }
        },

        detachedCallback: {
          value: function () {
            this.shutdown();
          }
        },

        shutdown: {
          value: function () {
            window.cancelAnimationFrame(this.animationFrameID);
          }
        },

        attachEventListeners: {
          value: function () {
            var self = this;
            var elementLoaded = this.elementLoaded.bind(this);
            this.pendingElements = 0;
            var assets = document.querySelector('vr-assets');
            if (assets && !assets.hasLoaded) {
              this.pendingElements++;
              assets.addEventListener('loaded', elementLoaded);
            }

            var children = this.querySelectorAll('*');
            Array.prototype.slice.call(children).forEach(countElement);
            if (!this.pendingElements) {
              elementLoaded();
            }

            function countElement (node) {
              // We wait for all the elements inside the scene to load.
              if (!node.isVRNode) { return; }
              var isCamera = node.components && node.components.camera;
              if (isCamera) { self.cameraEl = node; }
              if (!node.hasLoaded) {
                attachEventListener(node);
                self.pendingElements++;
              }
            }

            function attachEventListener (node) {
              node.addEventListener('loaded', elementLoaded);
            }
          }
        },

        attachMessageListeners: {
          value: function () {
            var self = this;
            window.addEventListener('message', function (e) {
              if (e.data) {
                switch (e.data.type) {
                  case 'loaderReady':
                    self.insideLoader = true;
                    self.removeEnterVrButton();
                    break;
                  case 'fullscreen':
                    switch (e.data.data) {
                      // Set renderer with fullscreen VR enter and exit.
                      case 'enter':
                        self.setStereoRenderer();
                        break;
                      case 'exit':
                        self.setMonoRenderer();
                        break;
                    }
                }
              }
            });
          }
        },

        attachFullscreenListeners: {
          value: function () {
            // handle fullscreen changes
            document.addEventListener('mozfullscreenchange', this.fullscreenChange.bind(this));
            document.addEventListener('webkitfullscreenchange', this.fullscreenChange.bind(this));
          }
        },

        fullscreenChange: {
          value: function (e) {
            // switch back to the mono renderer if we have dropped out of fullscreen VR mode.
            var fsElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
            if (!fsElement) {
              this.renderer = this.monoRenderer;
            }
          }
        },

        elementLoaded: {
          value: function () {
            this.pendingElements--;
            // If we still need to wait for more elements.
            if (this.pendingElements > 0) { return; }
            // If the render loop is already running.
            if (this.renderLoopStarted) { return; }
            // If somehow there's not a camera.
            if (!this.cameraEl) { return console.error('Expected a camera element'); }

            this.setupLoader();
            // three.js camera setup.
            this.setupCamera();
            // TODO: initialize lights somewhere else.
            this.updateMaterials();
            this.resizeCanvas();
            // Kick off the render loop.
            this.render(performance.now());
            this.renderLoopStarted = true;
            this.load();
          }
        },

        createEnterVrButton: {
          value: function () {
            var vrButton = this.vrButton = document.createElement('button');
            vrButton.textContent = 'Enter VR';
            vrButton.className = 'vr-button';
            document.body.appendChild(vrButton);
            vrButton.addEventListener('click', this.enterVR.bind(this));
          }
        },

        removeEnterVrButton: {
          value: function () {
            if (this.vrButton) {
              this.vrButton.parentNode.removeChild(this.vrButton);
            }
          }
        },

        // returns a promise that resolves to true if loader is in VR mode.
        vrLoaderMode: {
          value: function () {
            return new Promise(function (resolve) {
              var channel = new MessageChannel();
              window.top.postMessage({type: 'checkVr'}, '*', [channel.port2]);
              channel.port1.onmessage = function (message) {
                resolve(!!message.data.data.isVr);
              };
            });
          }
        },

        setupLoader: {
          value: function () {
            var self = this;

            // Inside loader, check for VR mode before kicking off render loop.
            if (self.insideIframe) {
              self.attachMessageListeners();
              self.vrLoaderMode().then(function (isVr) {
                if (isVr) {
                  self.setStereoRenderer();
                } else {
                  self.setMonoRenderer();
                }
                window.top.postMessage({type: 'ready'}, '*');
              });
            }

            if (!self.insideLoader) {
              self.createEnterVrButton();
            }
          }
        },

        setStereoRenderer: {
          value: function () {
            this.renderer = this.stereoRenderer;
            this.resizeCanvas();
          }
        },

        setMonoRenderer: {
          value: function () {
            this.renderer = this.monoRenderer;
            this.resizeCanvas();
          }
        },

        setupScene: {
          value: function () {
            // Three.js setup
            // We reuse the scene if there's already one
            this.object3D = (VRScene && VRScene.scene) || new THREE.Scene();
            VRScene.scene = this.object3D;
            this.behaviors = [];
            // The canvas where the WebGL context will be painted
            this.setupCanvas();
            // The three.js renderer setup
            this.setupRenderer();
            // cursor camera setup
            this.setupCursor();
          }
        },

        setupCanvas: {
          value: function () {
            var canvas = this.canvas = document.createElement('canvas');
            canvas.classList.add('vr-canvas');
            document.body.appendChild(canvas);
            window.addEventListener('resize', this.resizeCanvas.bind(this), false);
          }
        },

        setupCamera: {
          value: function () {
            var cameraEl;
            // If there's a user defined camera
            if (this.cameraEl) { return; }
            // We create a default camera
            cameraEl = document.createElement('vr-object');
            this.cameraEl = cameraEl;
            cameraEl.setAttribute('camera', 'fov: 45');
            this.appendChild(cameraEl);
          }
        },

        setupCursor: {
          value: function () {
            var cursor = this.querySelector('vr-cursor');
            if (cursor) {
              this.cursor = cursor;
            }
          }
        },

        enterVR: {
          value: function () {
            this.renderer = this.stereoRenderer;
            this.stereoRenderer.setFullScreen(true);
          }
        },

        setupRenderer: {
          value: function () {
            var canvas = this.canvas;
            var renderer = this.renderer = this.monoRenderer =
              (VRScene && VRScene.renderer) || // To prevent creating multiple rendering contexts
              new THREE.WebGLRenderer({canvas: canvas, antialias: true, alpha: true});
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.sortObjects = false;
            VRScene.renderer = renderer;
            this.stereoRenderer = new THREE.VREffect(renderer);
          }
        },

        resizeCanvas: {
          value: function () {
            var canvas = this.canvas;
            var camera = this.cameraEl.components.camera.camera;
            // Make it visually fill the positioned parent
            canvas.style.width = '100%';
            canvas.style.height = '100%';
            // Set the internal size to match
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            // Updates camera
            camera.aspect = canvas.offsetWidth / canvas.offsetHeight;
            camera.updateProjectionMatrix();
            // Notify the renderer of the size change
            this.renderer.setSize(canvas.width, canvas.height);
          }
        },

        add: {
          value: function (el) {
            if (!el.object3D) { return; }
            this.object3D.add(el.object3D);
          }
        },

        addBehavior: {
          value: function (behavior) {
            this.behaviors.push(behavior);
          }
        },

        remove: {
          value: function (el) {
            if (!el.object3D) { return; }
            this.object3D.remove(el.object3D);
          }
        },

        render: {
          value: function (t) {
            var camera = this.cameraEl.components.camera.camera;
            TWEEN.update(t);
            // Updates behaviors
            this.behaviors.forEach(function (behavior) {
              behavior.update(t);
            });
            this.renderer.render(this.object3D, camera);
            this.animationFrameID = window.requestAnimationFrame(this.render.bind(this));
          }
        },

        /**
         * Registers light to the scene for the scene to keep track.
         * Light is kept track in a map such that it can be looked up and
         * updated in place if necessary.
         * Doing so will update all materials in the scene.
         *
         * @param light {object} light attributes (e.g., color, intensity).
         */
        registerLight: {
          value: function (light) {
            this.lights[light.id] = light;
            this.updateMaterials();
          }
        },

        /**
         * Registers material component for the scene to keep track.
         * Scene keeps track of materials in case of needed updates.
         *
         * @param id {number} ID of the material to keep track.
         * @param material {object} material component instance.
         */
        registerMaterial: {
          value: function (id, material) {
            this.materials[id] = material;
          }
        },

        /**
         * Updates all materials in the scene with the scene's lights.
         * Prescribes a default light if no lights are set.
         */
        updateMaterials: {
          value: function () {
            var self = this;
            // Default lights prescribed if no lights set.
            var lights = Object.keys(self.lights).length
                         ? self.lights : this.defaults.lights;
            // Convert this.lights to array.
            var lightsArr = Object.keys(lights).map(function (id) {
              return lights[id];
            });
            // Iterate through all materials to update lights.
            Object.keys(self.materials).forEach(function (id) {
              self.materials[id].updateLights(lightsArr);
            });
          }
        }
      }
    )
  }
);
<commit_msg>apply lights to newly registered materials (#273)<commit_after>/* global MessageChannel, performance, Promise */

var registerElement = require('../vr-register-element');

var THREE = require('../../lib/three');
var TWEEN = require('tween.js');
var VRNode = require('./vr-node');

var VRScene = module.exports = registerElement(
  'vr-scene',
  {
    prototype: Object.create(
      VRNode.prototype, {
        defaults: {
          value: {
            lights: {
              // Default directional light.
              0: {
                color: new THREE.Vector3(1.0, 1.0, 1.0),
                direction: new THREE.Vector3(-0.5, 1.0, 0.5),
                position: new THREE.Vector3(0, 0, 0),
                intensity: 5.0
              }
            }
          }
        },

        attachedCallback: {
          value: function () {
            this.insideIframe = window.top !== window.self;
            this.insideLoader = false;
            this.lights = {};
            this.materials = {};
            this.vrButton = null;
            document.addEventListener('vr-markup-ready',
                                      this.attachEventListeners.bind(this));
            this.attachFullscreenListeners();
            this.setupScene();
          }
        },

        detachedCallback: {
          value: function () {
            this.shutdown();
          }
        },

        shutdown: {
          value: function () {
            window.cancelAnimationFrame(this.animationFrameID);
          }
        },

        attachEventListeners: {
          value: function () {
            var self = this;
            var elementLoaded = this.elementLoaded.bind(this);
            this.pendingElements = 0;
            var assets = document.querySelector('vr-assets');
            if (assets && !assets.hasLoaded) {
              this.pendingElements++;
              assets.addEventListener('loaded', elementLoaded);
            }

            var children = this.querySelectorAll('*');
            Array.prototype.slice.call(children).forEach(countElement);
            if (!this.pendingElements) {
              elementLoaded();
            }

            function countElement (node) {
              // We wait for all the elements inside the scene to load.
              if (!node.isVRNode) { return; }
              var isCamera = node.components && node.components.camera;
              if (isCamera) { self.cameraEl = node; }
              if (!node.hasLoaded) {
                attachEventListener(node);
                self.pendingElements++;
              }
            }

            function attachEventListener (node) {
              node.addEventListener('loaded', elementLoaded);
            }
          }
        },

        attachMessageListeners: {
          value: function () {
            var self = this;
            window.addEventListener('message', function (e) {
              if (e.data) {
                switch (e.data.type) {
                  case 'loaderReady':
                    self.insideLoader = true;
                    self.removeEnterVrButton();
                    break;
                  case 'fullscreen':
                    switch (e.data.data) {
                      // Set renderer with fullscreen VR enter and exit.
                      case 'enter':
                        self.setStereoRenderer();
                        break;
                      case 'exit':
                        self.setMonoRenderer();
                        break;
                    }
                }
              }
            });
          }
        },

        attachFullscreenListeners: {
          value: function () {
            // handle fullscreen changes
            document.addEventListener('mozfullscreenchange', this.fullscreenChange.bind(this));
            document.addEventListener('webkitfullscreenchange', this.fullscreenChange.bind(this));
          }
        },

        fullscreenChange: {
          value: function (e) {
            // switch back to the mono renderer if we have dropped out of fullscreen VR mode.
            var fsElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
            if (!fsElement) {
              this.renderer = this.monoRenderer;
            }
          }
        },

        elementLoaded: {
          value: function () {
            this.pendingElements--;
            // If we still need to wait for more elements.
            if (this.pendingElements > 0) { return; }
            // If the render loop is already running.
            if (this.renderLoopStarted) { return; }
            // If somehow there's not a camera.
            if (!this.cameraEl) { return console.error('Expected a camera element'); }

            this.setupLoader();
            // three.js camera setup.
            this.setupCamera();
            // TODO: initialize lights somewhere else.
            this.updateMaterials();
            this.resizeCanvas();
            // Kick off the render loop.
            this.render(performance.now());
            this.renderLoopStarted = true;
            this.load();
          }
        },

        createEnterVrButton: {
          value: function () {
            var vrButton = this.vrButton = document.createElement('button');
            vrButton.textContent = 'Enter VR';
            vrButton.className = 'vr-button';
            document.body.appendChild(vrButton);
            vrButton.addEventListener('click', this.enterVR.bind(this));
          }
        },

        removeEnterVrButton: {
          value: function () {
            if (this.vrButton) {
              this.vrButton.parentNode.removeChild(this.vrButton);
            }
          }
        },

        // returns a promise that resolves to true if loader is in VR mode.
        vrLoaderMode: {
          value: function () {
            return new Promise(function (resolve) {
              var channel = new MessageChannel();
              window.top.postMessage({type: 'checkVr'}, '*', [channel.port2]);
              channel.port1.onmessage = function (message) {
                resolve(!!message.data.data.isVr);
              };
            });
          }
        },

        setupLoader: {
          value: function () {
            var self = this;

            // Inside loader, check for VR mode before kicking off render loop.
            if (self.insideIframe) {
              self.attachMessageListeners();
              self.vrLoaderMode().then(function (isVr) {
                if (isVr) {
                  self.setStereoRenderer();
                } else {
                  self.setMonoRenderer();
                }
                window.top.postMessage({type: 'ready'}, '*');
              });
            }

            if (!self.insideLoader) {
              self.createEnterVrButton();
            }
          }
        },

        setStereoRenderer: {
          value: function () {
            this.renderer = this.stereoRenderer;
            this.resizeCanvas();
          }
        },

        setMonoRenderer: {
          value: function () {
            this.renderer = this.monoRenderer;
            this.resizeCanvas();
          }
        },

        setupScene: {
          value: function () {
            // Three.js setup
            // We reuse the scene if there's already one
            this.object3D = (VRScene && VRScene.scene) || new THREE.Scene();
            VRScene.scene = this.object3D;
            this.behaviors = [];
            // The canvas where the WebGL context will be painted
            this.setupCanvas();
            // The three.js renderer setup
            this.setupRenderer();
            // cursor camera setup
            this.setupCursor();
          }
        },

        setupCanvas: {
          value: function () {
            var canvas = this.canvas = document.createElement('canvas');
            canvas.classList.add('vr-canvas');
            document.body.appendChild(canvas);
            window.addEventListener('resize', this.resizeCanvas.bind(this), false);
          }
        },

        setupCamera: {
          value: function () {
            var cameraEl;
            // If there's a user defined camera
            if (this.cameraEl) { return; }
            // We create a default camera
            cameraEl = document.createElement('vr-object');
            this.cameraEl = cameraEl;
            cameraEl.setAttribute('camera', 'fov: 45');
            this.appendChild(cameraEl);
          }
        },

        setupCursor: {
          value: function () {
            var cursor = this.querySelector('vr-cursor');
            if (cursor) {
              this.cursor = cursor;
            }
          }
        },

        enterVR: {
          value: function () {
            this.renderer = this.stereoRenderer;
            this.stereoRenderer.setFullScreen(true);
          }
        },

        setupRenderer: {
          value: function () {
            var canvas = this.canvas;
            var renderer = this.renderer = this.monoRenderer =
              (VRScene && VRScene.renderer) || // To prevent creating multiple rendering contexts
              new THREE.WebGLRenderer({canvas: canvas, antialias: true, alpha: true});
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.sortObjects = false;
            VRScene.renderer = renderer;
            this.stereoRenderer = new THREE.VREffect(renderer);
          }
        },

        resizeCanvas: {
          value: function () {
            var canvas = this.canvas;
            var camera = this.cameraEl.components.camera.camera;
            // Make it visually fill the positioned parent
            canvas.style.width = '100%';
            canvas.style.height = '100%';
            // Set the internal size to match
            canvas.width = canvas.offsetWidth;
            canvas.height = canvas.offsetHeight;
            // Updates camera
            camera.aspect = canvas.offsetWidth / canvas.offsetHeight;
            camera.updateProjectionMatrix();
            // Notify the renderer of the size change
            this.renderer.setSize(canvas.width, canvas.height);
          }
        },

        add: {
          value: function (el) {
            if (!el.object3D) { return; }
            this.object3D.add(el.object3D);
          }
        },

        addBehavior: {
          value: function (behavior) {
            this.behaviors.push(behavior);
          }
        },

        remove: {
          value: function (el) {
            if (!el.object3D) { return; }
            this.object3D.remove(el.object3D);
          }
        },

        render: {
          value: function (t) {
            var camera = this.cameraEl.components.camera.camera;
            TWEEN.update(t);
            // Updates behaviors
            this.behaviors.forEach(function (behavior) {
              behavior.update(t);
            });
            this.renderer.render(this.object3D, camera);
            this.animationFrameID = window.requestAnimationFrame(this.render.bind(this));
          }
        },

        /**
         * Registers light to the scene for the scene to keep track.
         * Light is kept track in a map such that it can be looked up and
         * updated in place if necessary.
         * Doing so will update all materials in the scene.
         *
         * @param light {object} light attributes (e.g., color, intensity).
         */
        registerLight: {
          value: function (light) {
            this.lights[light.id] = light;
            this.updateMaterials();
          }
        },

        /**
         * Transforms this.lights into an array. Uses default lights if no
         * lights have been registered.
         *
         * @param light {array} - array of lights.
         */
        getLightsAsArray: {
          value: function () {
            // Default lights prescribed if no lights set.
            var lights = Object.keys(this.lights).length
                         ? this.lights : this.defaults.lights;
            // Convert this.lights to array.
            return Object.keys(lights).map(function (id) {
              return lights[id];
            });
          }
        },

        /**
         * Registers material component for the scene to keep track.
         * Scene keeps track of materials in case of needed updates.
         *
         * @param id {number} ID of the material to keep track.
         * @param material {object} material component instance.
         */
        registerMaterial: {
          value: function (id, material) {
            this.materials[id] = material;
            material.updateLights(this.getLightsAsArray());
          }
        },

        /**
         * Updates all materials in the scene with the scene's lights.
         * Prescribes a default light if no lights are set.
         */
        updateMaterials: {
          value: function () {
            var self = this;
            // Convert this.lights to array.
            var lightsArr = self.getLightsAsArray();
            // Iterate through all materials to update lights.
            Object.keys(self.materials).forEach(function (id) {
              self.materials[id].updateLights(lightsArr);
            });
          }
        }
      }
    )
  }
);
<|endoftext|>


<commit_before>'use strict';

/* This declares to JSHint that 'settings' is a global variable: */
/*global settings:false */

angular.module('offers').controller('ViewOffersController', ['$scope', '$state', '$location', '$timeout', 'OffersBy', 'Authentication',
  function($scope, $state, $location, $timeout, OffersBy, Authentication) {

    // If user is not signed in then redirect to sign in form
    if (!Authentication.user) $location.path('signin');

    $scope.offer = false;

    // Leaflet
    angular.extend($scope, {
      center: {
        // Default to Europe, we set center to Offer once it loads
        lat: 48.6908333333,
        lng: 9.14055555556,
        zoom: 0
      },
      layers: {
        baselayers: {
          default: {
            name: 'Streets',
            type: 'xyz',
            url: '//{s}.tiles.mapbox.com/v4/{user}.{map}/{z}/{x}/{y}.png?access_token=' + settings.mapbox.access_token + ( settings.https ? '&secure=1' : ''),
            layerParams: {
              user: settings.mapbox.user,
              map: settings.mapbox.map[0]
            },
            options: {
              attribution: 'OSM',
              continuousWorld: true
            }
          }
        }
      },
      paths: {
        offer: {
          weight: 2,
          color: '#12b591',
          fillColor: '#12b591',
          fillOpacity: 0.5,
          latlngs: {
            // Somehow this needs to be here although we set it later again (BTW it's, Center of Europe)
            lat: 48.6908333333,
            lng: 9.14055555556
          },
          radius: 500,
          type: 'circle'
        }
      },
      defaults: {
        scrollWheelZoom: false
      }
    });

    // Fetch that offer for us...
    if(!$scope.offer) {

      // Wait for profile from parent Controller (probably ProfileController)
      $scope.$parent.profile.$promise.then(function(profile) {

        $scope.offer = OffersBy.get({
          userId: profile._id
        }, function(offer){
            // Update also the map
            if(offer.location) {
              $scope.center.lat = parseFloat(offer.location[0]);
              $scope.center.lng = parseFloat(offer.location[1]);
              $scope.center.zoom = 12;

              $scope.paths.offer.latlngs.lat = parseFloat(offer.location[0]);
              $scope.paths.offer.latlngs.lng = parseFloat(offer.location[1]);

            }

        });

      });

    }//if !offer

    $scope.hostingDropdown = false;

    $scope.hostingStatusLabel = function() {
      var status = ($scope.offer) ? $scope.offer.status : false;
        switch(status) {
          case 'yes':
            return 'Can host';
          case 'maybe':
            return 'Might be able to host';
          default:
            return 'Cannot host currently';
        }
    };

    $scope.hostingStatus = function(status) {
      $scope.offer.status = status;
      $scope.hostingDropdown = false;
      $state.go('offer-status', {'status': status});
    };

  }
]);
<commit_msg>Turn location bubble un-clickable at profile<commit_after>'use strict';

/* This declares to JSHint that 'settings' is a global variable: */
/*global settings:false */

angular.module('offers').controller('ViewOffersController', ['$scope', '$state', '$location', '$timeout', 'OffersBy', 'Authentication',
  function($scope, $state, $location, $timeout, OffersBy, Authentication) {

    // If user is not signed in then redirect to sign in form
    if (!Authentication.user) $location.path('signin');

    $scope.offer = false;

    // Leaflet
    angular.extend($scope, {
      center: {
        // Default to Europe, we set center to Offer once it loads
        lat: 48.6908333333,
        lng: 9.14055555556,
        zoom: 0
      },
      layers: {
        baselayers: {
          default: {
            name: 'Streets',
            type: 'xyz',
            url: '//{s}.tiles.mapbox.com/v4/{user}.{map}/{z}/{x}/{y}.png?access_token=' + settings.mapbox.access_token + ( settings.https ? '&secure=1' : ''),
            layerParams: {
              user: settings.mapbox.user,
              map: settings.mapbox.map[0]
            },
            options: {
              attribution: 'OSM',
              continuousWorld: true
            }
          }
        }
      },
      paths: {
        offer: {
          weight: 2,
          color: '#12b591',
          fillColor: '#12b591',
          fillOpacity: 0.5,
          clickable: false,
          latlngs: {
            // Somehow this needs to be here although we set it later again (BTW it's, Center of Europe)
            lat: 48.6908333333,
            lng: 9.14055555556
          },
          radius: 500,
          type: 'circle'
        }
      },
      defaults: {
        scrollWheelZoom: false
      }
    });

    // Fetch that offer for us...
    if(!$scope.offer) {

      // Wait for profile from parent Controller (probably ProfileController)
      $scope.$parent.profile.$promise.then(function(profile) {

        $scope.offer = OffersBy.get({
          userId: profile._id
        }, function(offer){
            // Update also the map
            if(offer.location) {
              $scope.center.lat = parseFloat(offer.location[0]);
              $scope.center.lng = parseFloat(offer.location[1]);
              $scope.center.zoom = 12;

              $scope.paths.offer.latlngs.lat = parseFloat(offer.location[0]);
              $scope.paths.offer.latlngs.lng = parseFloat(offer.location[1]);

            }

        });

      });

    }//if !offer

    $scope.hostingDropdown = false;

    $scope.hostingStatusLabel = function() {
      var status = ($scope.offer) ? $scope.offer.status : false;
        switch(status) {
          case 'yes':
            return 'Can host';
          case 'maybe':
            return 'Might be able to host';
          default:
            return 'Cannot host currently';
        }
    };

    $scope.hostingStatus = function(status) {
      $scope.offer.status = status;
      $scope.hostingDropdown = false;
      $state.go('offer-status', {'status': status});
    };

  }
]);
<|endoftext|>


<commit_before>new GMaps({
  div: '#map',
  lat: 51.517686,
  lng: -0.073767
});<commit_msg>added marker with info window<commit_after>map = new GMaps({
        div: '#map',
        lat: 51.517686,
  		lng: -0.073767
      });

map.addMarker({
        lat: 51.515173,
		lng: -0.077128,
        infoWindow: {
          content: '
Hello, I am a charity
'
        }
      });
<|endoftext|>