<commit_before>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
           \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
            \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/

This is a sample Cisco Spark bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Cisco Spark's APIs
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# EXTEND THE BOT:

  Botkit has many features for building cool and useful bots!

  Read all about it here:

    -> http://botkit.ai

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

var Botkit = require('./lib/Botkit.js');

var controller = Botkit.sparkbot({
    debug: false,
    log: false,
    public_address: process.env.public_address,
    ciscospark_access_token: process.env.access_token,
    studio_token: process.env.studio_token, // get one from studio.botkit.ai to enable content management, stats, message console and more
    secret: process.env.secret, // this is an RECOMMENDED but optional setting that enables validation of incoming webhooks
    webhook_name: 'Cisco Spark bot created with Botkit, override me before going to production',
//    limit_to_domain: ['mycompany.com'],
//    limit_to_org: 'my_cisco_org_id',
});

var bot = controller.spawn({});

controller.setupWebserver(process.env.PORT || 3000, function(err, webserver) {
    controller.createWebhookEndpoints(webserver, bot, function() {
        console.log("Cisco Spark: Webhooks set up!");
    });
});

controller.middleware.receive.use(function(bot, message, next) {

  console.log(message);
  next();
});

controller.hears(['^markdown'], 'direct_message,direct_mention', function(bot, message) {

    bot.reply(message, {text: '*this is cool*', markdown: '*this is super cool*'});

});

controller.on('user_space_join', function(bot, message) {
    bot.reply(message, 'Welcome, ' + message.original_message.data.personDisplayName);
});

controller.on('user_space_leave', function(bot, message) {
    bot.reply(message, 'Bye, ' + message.original_message.data.personDisplayName);
});

controller.on('bot_space_join', function(bot, message) {

    bot.reply(message, 'This trusty bot is here to help.');

});

controller.hears([new RegExp('^\\d{5}$')], 'direct_message,direct_mention', function(bot, message) {
  bot.reply(message,'d5');
});

controller.on('direct_mention', function(bot, message) {
    bot.reply(message, 'You mentioned me and said, "' + message.text + '"');
});

controller.on('direct_message', function(bot, message) {
    bot.reply(message, 'I got your private message. You said, "' + message.text + '"');
    if (message.original_message.files) {
        bot.retrieveFileInfo(message.original_message.files[0], function(err, file) {
            bot.reply(message,'I also got an attached file called ' + file.filename);
        });
    }
});

if (process.env.studio_token) {
    controller.on('direct_message,direct_mention', function(bot, message) {
        controller.studio.runTrigger(bot, message.text, message.user, message.channel).then(function(convo) {
            if (!convo) {
                // console.log('NO STUDIO MATCH');
            }
        }).catch(function(err) {
            console.error('Error with Botkit Studio: ', err);
        });
    });
}
<commit_msg>remove sparkbot change<commit_after>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
           \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
            \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/

This is a sample Cisco Spark bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Cisco Spark's APIs
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# EXTEND THE BOT:

  Botkit has many features for building cool and useful bots!

  Read all about it here:

    -> http://botkit.ai

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

var Botkit = require('./lib/Botkit.js');

var controller = Botkit.sparkbot({
    debug: false,
    log: false,
    public_address: process.env.public_address,
    ciscospark_access_token: process.env.access_token,
    studio_token: process.env.studio_token, // get one from studio.botkit.ai to enable content management, stats, message console and more
    secret: process.env.secret, // this is an RECOMMENDED but optional setting that enables validation of incoming webhooks
    webhook_name: 'Cisco Spark bot created with Botkit, override me before going to production',
//    limit_to_domain: ['mycompany.com'],
//    limit_to_org: 'my_cisco_org_id',
});

var bot = controller.spawn({});

controller.setupWebserver(process.env.PORT || 3000, function(err, webserver) {
    controller.createWebhookEndpoints(webserver, bot, function() {
        console.log("Cisco Spark: Webhooks set up!");
    });
});

controller.middleware.receive.use(function(bot, message, next) {

  console.log(message);
  next();
});

controller.hears(['^markdown'], 'direct_message,direct_mention', function(bot, message) {

    bot.reply(message, {text: '*this is cool*', markdown: '*this is super cool*'});

});

controller.on('user_space_join', function(bot, message) {
    bot.reply(message, 'Welcome, ' + message.original_message.data.personDisplayName);
});

controller.on('user_space_leave', function(bot, message) {
    bot.reply(message, 'Bye, ' + message.original_message.data.personDisplayName);
});

controller.on('bot_space_join', function(bot, message) {

    bot.reply(message, 'This trusty bot is here to help.');

});

controller.on('direct_mention', function(bot, message) {
    bot.reply(message, 'You mentioned me and said, "' + message.text + '"');
});

controller.on('direct_message', function(bot, message) {
    bot.reply(message, 'I got your private message. You said, "' + message.text + '"');
    if (message.original_message.files) {
        bot.retrieveFileInfo(message.original_message.files[0], function(err, file) {
            bot.reply(message,'I also got an attached file called ' + file.filename);
        });
    }
});

if (process.env.studio_token) {
    controller.on('direct_message,direct_mention', function(bot, message) {
        controller.studio.runTrigger(bot, message.text, message.user, message.channel).then(function(convo) {
            if (!convo) {
                // console.log('NO STUDIO MATCH');
            }
        }).catch(function(err) {
            console.error('Error with Botkit Studio: ', err);
        });
    });
}
<|endoftext|>


<commit_before>'use babel';

/** @jsx etch.dom */
/* @flow*/
import etch from 'etch';
import { Emitter, CompositeDisposable, Disposable } from 'atom';
import { normalizeString } from '../helpers';
import type { Message } from '../types';

// TODO
// - sort data by column head
// - resize column
// - only current file filter
// - soft wrap table
export default class ResultView {
  properties: {
    messages: Array<Message>;
    ansiToHtml: boolean;
    softWrap: boolean;
 }
  refs: any;
  element: any;
  panel: any;
  emitter: Emitter;
  disposables: CompositeDisposable;

  constructor(properties:Object) {
    this.properties = properties;
    this.emitter = new Emitter();
    this.disposables = new CompositeDisposable();
    etch.initialize(this);

    const softWrapHandler = () => {
      this.update(this.properties);
    };
    this.refs.softWrap.addEventListener('click', softWrapHandler);
    this.disposables.add(new Disposable(() => { this.refs.softWrap.removeEventListener('click', softWrapHandler()); }));
  }

  render() {
    return (

            Failed: {this.properties.messages.filter(result => result.state === 'failed').length}
            Skipped: {this.properties.messages.filter(result => result.state === 'skipped').length}
            Passed: {this.properties.messages.filter(result => result.state === 'passed').length}

            <input class='input-checkbox' ref='softWrap' type='checkbox'/> Soft Wrap
            <input class='input-checkbox' type='checkbox'/> Current file only
            <button class="inline-block-tight btn btn-sm" title="Test Project"
              onclick={this.handleTestButtonClick.bind(this, true)}>Test Project</button>

State

Duration

Title

Error

Location

 0 ? 'display: none;' : ''}>No tester messages

          {this.properties.messages.map((message, index) =>

                      {message.state || 'unknown'}

{message.duration || 0}ms

{message.title || ''}

                      {atom.project.relativizePath(message.filePath)[1] || message.filePath || ''}:{message.lineNumber.toString() || ''}

)}

    );
  }

  update(newProperties:Object) {
    if (this.properties.messages !== newProperties.messages) {
      this.properties.messages = newProperties.messages;
      return etch.update(this);
    }
    return Promise.resolve();
  }

  async destroy() {
    await etch.destroy(this);
  }

  getTitle() {
    return 'Tester results';
  }

  getIconName() {
    return 'law';
  }

  getDefaultLocation() {
    return 'bottom';
  }

  getAllowedLocations() {
    return ['left', 'right', 'bottom'];
  }

  getURI() {
    return 'atom://tester-result-view';
  }

  getPath() {
    return 'atom://tester-result-view';
  }

  getElement() {
    return this.element;
  }

  onTestButtonClick(callback : Function) : Disposable {
    return this.emitter.on('test-button-click', callback);
  }

  handleRowClick(selectedIndex: number): void {
    const message = this.properties.messages[selectedIndex];
    atom.workspace.open(message.filePath, { initialLine: message.lineNumber });
  }

  handleTestButtonClick(shouldTestCurrentProject :boolean):void {
    console.log('handleTestButtonClick', shouldTestCurrentProject);
    this.emitter.emit('test-button-click', shouldTestCurrentProject);
  }
}
<commit_msg>fix wrap<commit_after>'use babel';

/** @jsx etch.dom */
/* @flow*/
import etch from 'etch';
import { Emitter, CompositeDisposable, Disposable } from 'atom';
import { normalizeString } from '../helpers';
import type { Message } from '../types';

// TODO
// - sort data by column head
// - resize column
// - only current file filter
// - soft wrap table
export default class ResultView {
  properties: {
    messages: Array<Message>;
    ansiToHtml: boolean;
    softWrap: boolean;
 }
  refs: any;
  element: any;
  panel: any;
  emitter: Emitter;
  disposables: CompositeDisposable;

  constructor(properties:Object) {
    this.properties = properties;
    this.emitter = new Emitter();
    this.disposables = new CompositeDisposable();
    etch.initialize(this);

    const softWrapHandler = () => {
      this.update({ softWrap: this.refs.softWrap.checked });
    };
    this.refs.softWrap.addEventListener('click', softWrapHandler);
    this.disposables.add(new Disposable(() => { this.refs.softWrap.removeEventListener('click', softWrapHandler()); }));
  }

  render() {
    return (

            Failed: {this.properties.messages.filter(result => result.state === 'failed').length}
            Skipped: {this.properties.messages.filter(result => result.state === 'skipped').length}
            Passed: {this.properties.messages.filter(result => result.state === 'passed').length}

            <input class='input-checkbox' ref='softWrap' type='checkbox'/> Soft Wrap
            <input class='input-checkbox' type='checkbox'/> Current file only
            <button class="inline-block-tight btn btn-sm" title="Test Project"
              onclick={this.handleTestButtonClick.bind(this, true)}>Test Project</button>

State

Duration

Title

Error

Location

 0 ? 'display: none;' : ''}>No tester messages

          {this.properties.messages.map((message, index) =>

                      {message.state || 'unknown'}

{message.duration || 0}ms

{message.title || ''}

                      {atom.project.relativizePath(message.filePath)[1] || message.filePath || ''}:{message.lineNumber.toString() || ''}

)}

    );
  }

  update(newProperties:Object) {
    if (this.properties.messages !== newProperties.messages ||
      this.properties.softWrap !== newProperties.softWrap) {
      if (newProperties.messages) {
        this.properties.messages = newProperties.messages;
      }
      if (newProperties.softWrap) {
        this.properties.softWrap = newProperties.softWrap;
      }
      return etch.update(this);
    }
    return Promise.resolve();
  }

  async destroy() {
    await etch.destroy(this);
  }

  getTitle() {
    return 'Tester results';
  }

  getIconName() {
    return 'law';
  }

  getDefaultLocation() {
    return 'bottom';
  }

  getAllowedLocations() {
    return ['left', 'right', 'bottom'];
  }

  getURI() {
    return 'atom://tester-result-view';
  }

  getPath() {
    return 'atom://tester-result-view';
  }

  getElement() {
    return this.element;
  }

  onTestButtonClick(callback : Function) : Disposable {
    return this.emitter.on('test-button-click', callback);
  }

  handleRowClick(selectedIndex: number): void {
    const message = this.properties.messages[selectedIndex];
    atom.workspace.open(message.filePath, { initialLine: message.lineNumber });
  }

  handleTestButtonClick(shouldTestCurrentProject :boolean):void {
    console.log('handleTestButtonClick', shouldTestCurrentProject);
    this.emitter.emit('test-button-click', shouldTestCurrentProject);
  }
}
<|endoftext|>


<commit_before>'use babel';

/** @jsx etch.dom */
/* @flow*/
import etch from 'etch';
import { Emitter, CompositeDisposable } from 'atom';
import { normalizeString } from '../helpers';
import type { Message } from '../types';

// TODO
// - add serialization
// - sort data by column head
// - resize column
export default class ResultView {
  properties: {
    messages: Array<Message>;
  }
  refs: any;
  element: any;
  panel: any;
  emitter: Emitter;
  disposables: CompositeDisposable;

  constructor(properties:Object) {
    this.properties = properties;
    this.emitter = new Emitter();
    this.disposables = new CompositeDisposable();
    etch.initialize(this);
  }

  render() {
    return (

            Failed: {this.properties.messages.filter(result => result.state === 'failed').length}
            Skipped: {this.properties.messages.filter(result => result.state === 'skipped').length}
            Passed: {this.properties.messages.filter(result => result.state === 'passed').length}

            <input class='input-checkbox' type='checkbox'/> Soft Wrap
            <input class='input-checkbox' type='checkbox'/> Current file only

State

Duration

Title

Error

Location

 0 ? 'display: none;' : ''}>No tester messages

          {this.properties.messages.map((message, index) =>

                      {message.state || 'unknown'}

{message.duration || 0}ms

{message.title || ''}

                      {atom.project.relativizePath(message.filePath)[1] || message.filePath || ''}:{message.lineNumber.toString() || ''}

)}

    );
  }

  update(newProperties:Object) {
    if (this.properties.messages !== newProperties.messages) {
      this.properties.messages = newProperties.messages;
      return etch.update(this);
    }
    return Promise.resolve();
  }

  async destroy() {
    await etch.destroy(this);
  }

  getTitle() {
    return 'Tester results';
  }

  getIconName() {
    return 'law';
  }

  getDefaultLocation() {
    return 'bottom';
  }

  getAllowedLocations() {
    return ['left', 'right', 'bottom'];
  }

  getURI() {
    return 'atom://tester-result-view';
  }

  serialize() {
    return {
      deserializer: 'tester-result-view/ResultView',
    };
  }

  getElement() {
    return this.element;
  }

  handleRowClick(selectedIndex: number): void {
    const message = this.properties.messages[selectedIndex];
    atom.workspace.open(message.filePath, { initialLine: message.lineNumber });
  }
}
<commit_msg>logging<commit_after>'use babel';

/** @jsx etch.dom */
/* @flow*/
import etch from 'etch';
import { Emitter, CompositeDisposable } from 'atom';
import { normalizeString } from '../helpers';
import type { Message } from '../types';

// TODO
// - add serialization
// - sort data by column head
// - resize column
export default class ResultView {
  properties: {
    messages: Array<Message>;
  }
  refs: any;
  element: any;
  panel: any;
  emitter: Emitter;
  disposables: CompositeDisposable;

  constructor(properties:Object) {
    this.properties = properties;
    this.emitter = new Emitter();
    this.disposables = new CompositeDisposable();
    console.log('properties', properties);
    etch.initialize(this);
  }

  render() {
    return (

            Failed: {this.properties.messages.filter(result => result.state === 'failed').length}
            Skipped: {this.properties.messages.filter(result => result.state === 'skipped').length}
            Passed: {this.properties.messages.filter(result => result.state === 'passed').length}

            <input class='input-checkbox' type='checkbox'/> Soft Wrap
            <input class='input-checkbox' type='checkbox'/> Current file only

State

Duration

Title

Error

Location

 0 ? 'display: none;' : ''}>No tester messages

          {this.properties.messages.map((message, index) =>

                      {message.state || 'unknown'}

{message.duration || 0}ms

{message.title || ''}

                      {atom.project.relativizePath(message.filePath)[1] || message.filePath || ''}:{message.lineNumber.toString() || ''}

)}

    );
  }

  update(newProperties:Object) {
    if (this.properties.messages !== newProperties.messages) {
      this.properties.messages = newProperties.messages;
      return etch.update(this);
    }
    return Promise.resolve();
  }

  async destroy() {
    await etch.destroy(this);
  }

  getTitle() {
    return 'Tester results';
  }

  getIconName() {
    return 'law';
  }

  getDefaultLocation() {
    return 'bottom';
  }

  getAllowedLocations() {
    return ['left', 'right', 'bottom'];
  }

  getURI() {
    return 'atom://tester-result-view';
  }

  serialize() {
    return {
      deserializer: 'tester-result-view/ResultView',
    };
  }

  getElement() {
    return this.element;
  }

  handleRowClick(selectedIndex: number): void {
    const message = this.properties.messages[selectedIndex];
    atom.workspace.open(message.filePath, { initialLine: message.lineNumber });
  }
}
<|endoftext|>


<commit_before>'use strict';

module.exports = {

  types: [
    {value: 'feat',     name: 'feat:     A new feature'},
    {value: 'fix',      name: 'fix:      A bug fix'},
    {value: 'docs',     name: 'docs:     Documentation only changes'},
    {value: 'style',    name: 'style:    Changes that do not affect the meaning of the code\n            (white-space, formatting, missing semi-colons, etc)'},
    {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'},
    {value: 'perf',     name: 'perf:     A code change that improves performance'},
    {value: 'test',     name: 'test:     Adding missing tests'},
    {value: 'chore',    name: 'chore:    Changes to the build process or auxiliary tools\n            and libraries such as documentation generation'},
    {value: 'revert',   name: 'revert:   Revert to a commit'},
    {value: 'WIP',      name: 'WIP:      Work in progress'}
  ],

  scopes: [
/*
    {name: 'accounts'},
    {name: 'admin'},
    {name: 'app'},
    {name: 'build'},
    {name: 'others'}
*/
  ],

  //it needs to match the value for field type. Eg.: 'fix'
  scopeOverrides: {
    fix: [
/*
      {name: 'merge'},
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
*/
    ]
  },

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix']

};
<commit_msg>docs: update example config<commit_after>'use strict';

module.exports = {

  types: [
    {value: 'feat',     name: 'feat:     A new feature'},
    {value: 'fix',      name: 'fix:      A bug fix'},
    {value: 'docs',     name: 'docs:     Documentation only changes'},
    {value: 'style',    name: 'style:    Changes that do not affect the meaning of the code\n            (white-space, formatting, missing semi-colons, etc)'},
    {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'},
    {value: 'perf',     name: 'perf:     A code change that improves performance'},
    {value: 'test',     name: 'test:     Adding missing tests'},
    {value: 'chore',    name: 'chore:    Changes to the build process or auxiliary tools\n            and libraries such as documentation generation'},
    {value: 'revert',   name: 'revert:   Revert to a commit'},
    {value: 'WIP',      name: 'WIP:      Work in progress'}
  ],

  scopes: [
    {name: 'accounts'},
    {name: 'admin'},
    {name: 'exampleScope'},
    {name: 'changeMe'}
  ],

  // it needs to match the value for field type. Eg.: 'fix'
  /*
  scopeOverrides: {
    fix: [

      {name: 'merge'},
      {name: 'style'},
      {name: 'e2eTest'},
      {name: 'unitTest'}
    ]
  },
  */

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix']

};
<|endoftext|>


<commit_before><commit_msg>Debug: typed variable with no change event is set to 'true' instead of correct value.<commit_after><|endoftext|>


<commit_before>
$(function(){

    var viewProperties = {
        height: 420,
        padding: 20,
        xvalues: 100
    };

    var container = $('#graph');
    var svg = null;

    var nodenetMonitors = {};
    var currentMonitors = [];

    var currentSimulationStep = 0;
    var currentNodenet = null;

    var capturedLoggers = {
        'system': false,
        'world': false,
        'nodenet': false
    };

    var logs = [];

    if($.cookie('capturedLoggers')){
        capturedLoggers = JSON.parse($.cookie('capturedLoggers'));
    }
    if($.cookie('currentMonitors')){
        currentMonitors = JSON.parse($.cookie('currentMonitors'));
    }

    var last_logger_call = 0;

    var log_container = $('#logs');

    init();

    $('.layoutbtn').on('click', function(event){
        event.preventDefault();
        var target = $(event.target);
        if(!target.hasClass('active')){
            var layout = target.attr('data');
            if(layout == 'vertical'){
                $('.layout_field').addClass('span6');
            } else if(layout == 'horizontal'){
                $('.layout_field').removeClass('span6');
            }
            refreshMonitors();
            $('.layoutbtn').removeClass('active');
            target.addClass('active');
        }
    })

    $('#monitor_x_axis').on('change', function(){
        viewProperties.xvalues = parseInt($('#monitor_x_axis').val());
        refreshMonitors();
    });

    var filter_timeout=null;
    $('#monitor_filter_logs').on('keydown', function(event){
        if(event.keyCode == 13){
            event.preventDefault();
        }
        clearTimeout(filter_timeout);
        filter_timeout = setTimeout(refreshLoggerView, 400);
    })

    $(document).on('monitorsChanged', function(evt, new_monitor){
        currentMonitors.push(new_monitor)
        refreshMonitors();
    });
    $(document).on('nodenetChanged', function(data, newNodenet){
        refreshMonitors(newNodenet);
    });

    function init() {
        bindEvents();
        if (currentNodenet = $.cookie('selected_nodenet')) {
            api.call('load_nodenet', {
                nodenet_uid: currentNodenet,
                include_links: false
            }, function(data) {
                refreshMonitors();
            },
            function(data) {
                if(data.status == 500){
                    api.defaultErrorCallback(data);
                } else {
                    currentNodenet = null;
                    $.cookie('selected_nodenet', '', { expires: -1, path: '/' });
                    dialogs.notification(data.data, "Info");
                }
            });
        }
    }

    function getPollParams(){
        var poll = [];
        for(var logger in capturedLoggers){
            if(capturedLoggers[logger]){
                poll.push(logger);
            }
        }
        return {
            logger: poll,
            after: last_logger_call
        }
    }

    function setData(data){
        setMonitorData(data);
        setLoggingData(data);
        currentSimulationStep = data.current_step;
    }

    register_stepping_function('monitors', getPollParams, setData);

    function refreshMonitors(newNodenet){
        params = getPollParams();
        if(newNodenet || currentNodenet){
            params.nodenet_uid = newNodenet || currentNodenet;
            api.call('get_monitoring_info', params, setData);
        }
    }

    function setMonitorData(data){
        updateMonitorList(data.monitors);
        nodenetMonitors = data.monitors;
        var m = {};
        for (var uid in nodenetMonitors) {
            if (currentMonitors.indexOf(uid) >= 0) {
                m[uid] = nodenetMonitors[uid];
            }
        }
        drawGraph(m);
    }

    function setLoggingData(data){
        last_logger_call = data.logs.servertime;
        for(var idx in data.logs.logs){
            var item = data.logs.logs[idx];
            logs.push(item);
            var filter = $('#monitor_filter_logs').val();
            if(filter){
                var check = item.logger + item.msg + item.module + item.function + item.level
                if(check.indexOf(filter) > -1){
                    log_container.append(''+("          " + item.logger).slice(-10)+' | ' + item.msg +'');
                }
            } else {
                log_container.append($(''+("          " + item.logger).slice(-10)+' | ' + item.msg +''));
            }
        }
        var height = log_container.height();
        var scrollHeight = log_container[0].scrollHeight;
        var st = log_container.scrollTop();
        var doscroll = (st >= (scrollHeight - height));
        if(doscroll){
            log_container.scrollTop(log_container[0].scrollHeight);
        }
    }

    function refreshLoggerView(){
        var html = '';
        var filter = $('#monitor_filter_logs').val();
        for(var idx in logs){
            item = logs[idx];
            if(filter){
                var check = item.logger + item.msg + item.module+ item.function + item.level
                if(check.indexOf(filter) > -1){
                    html += ''+("          " + item.logger).slice(-10)+' | ' + item.msg +'';
                }
            } else {
                html += ''+("          " + item.logger).slice(-10)+' | ' + item.msg +'';
            }
        }
        log_container.html(html);
        var height = log_container.height();
        var scrollHeight = log_container[0].scrollHeight;
        var st = log_container.scrollTop();
        var doscroll = (st >= (scrollHeight - height));
        if(doscroll){
            log_container.scrollTop(log_container[0].scrollHeight);
        }
    }

    function bindEvents(){
        $('.log_switch').on('change', function(event){
            var el = $(event.target);
            capturedLoggers[el.attr('data')] = el.attr('checked')
            $.cookie('capturedLoggers', JSON.stringify(capturedLoggers), {path:'/', expires:7})
        });
        $('.log_level_switch').on('change', function(event){
            var el = $(event.target);
            var data = {}
            data[el.attr('data')] = el.val();
            api.call('set_logging_levels', data);
        });
        $('.log_switch').each(function(idx, el){
            if(capturedLoggers[$(el).attr('data')]){
                el.checked=true;
            }
        });
    }

    function updateMonitorList(monitors){
        var list = $('#monitor_selector');
        var html = '';
        for(var uid in monitors){
            html += '
<input type="checkbox" class="monitor_checkbox" value="'+uid+'" id="'+uid+'"';
            if(currentMonitors.indexOf(uid) > -1){
                html += ' checked="checked"';
            }
            html += ' /> ' + monitors[uid].name + '
';
        }
        list.html(html);
        $('.monitor_checkbox', list).on('change', updateMonitorSelection);
        $('.delete_monitor', list).on('click', function(event){
            event.preventDefault();
            api.call(
                'remove_monitor',
                {nodenet_uid: currentNodenet, monitor_uid: $(event.delegateTarget).attr('data')},
                function(){
                    delete monitors[uid];
                    refreshMonitors();
                }
            );
        });
    }

    function updateMonitorSelection() {
        currentMonitors = [];
        $.each($('.monitor_checkbox'), function(idx, el) {
            if (el.checked) {
                currentMonitors.push(el.value);
            }
        });
        $.cookie('currentMonitors', JSON.stringify(currentMonitors), {path:'/', expires:7})
        drawGraph(currentMonitors);
    }

    function drawGraph(currentMonitors) {

        var customMonitors = false;
        container.html(''); // TODO: come up with a way to redraw
        var margin = {
                top: 20,
                right: 50,
                bottom: 30,
                left: 50
            },
            width = container.width() - margin.left - margin.right - viewProperties.padding,
            height = viewProperties.height - margin.top - margin.bottom - viewProperties.padding;

        var xmax = Math.max(viewProperties.xvalues, currentSimulationStep);
        if(viewProperties.xvalues < 0){
            viewProperties.xvalues = xmax;
        }
        var x = d3.scale.linear()
            .domain([xmax - viewProperties.xvalues, xmax])
            .range([0, width]);
        var xstart = xmax - viewProperties.xvalues;

        var y1values = [];
        var y2values = [];
        var y1max = 1.0;
        var y1min = 0;
        var y2max = 1.0;
        var y2min = 0;
        for (var uid in currentMonitors) {
            for (var step in currentMonitors[uid].values) {
                if(currentMonitors[uid].classname == 'CustomMonitor'){
                    customMonitors = true;
                    y2values.push(currentMonitors[uid].values[step]);
                    if (step >= xstart) {
                        y2max = Math.max(y2max, currentMonitors[uid].values[step]);
                        y2min = Math.min(y2min, currentMonitors[uid].values[step]);
                    }
                } else {
                    y1values.push(currentMonitors[uid].values[step]);
                    if (step >= xstart) {
                        y1max = Math.max(y1max, currentMonitors[uid].values[step]);
                        y1min = Math.min(y1min, currentMonitors[uid].values[step]);
                    }
                }
            }
        }

        var y1 = d3.scale.linear().domain([y1min, y1max]).range([height, 0]);
        var y2 = d3.scale.linear().domain([y2min, y2max]).range([height, 0]);

        var x_axis_pos = (y1max / (y1max - y1min)) * height;

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

        var y1Axis = d3.svg.axis()
            .scale(y1)
            .orient("left");
        var y2Axis = d3.svg.axis()
            .scale(y2)
            .orient("right");

        svg = d3.select("#graph").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + x_axis_pos + ")")
            .call(xAxis)
            .append("text")
            .attr("dx", width - 100)
            .attr("dy", -5)
            .style("text-anchor", "start")
            .text("Nodenet step");
        svg.append("g")
            .attr("class", "y axis")
            .call(y1Axis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Activation");
        if(customMonitors){
            svg.append("g")
                .attr("class", "y axis")
                .call(y2Axis)
                .attr("transform", "translate(" + width + " ,0)")
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Value");
        }

        for (var uid in currentMonitors) {
            var data = [];
            if(currentMonitors[uid].classname == 'CustomMonitor'){
                var line = d3.svg.line()
                    .x(function(d) {
                        return x(d[0]);
                    })
                    .y(function(d) {
                        return y2(d[1]);
                    })
                    .defined(function(d){ return d[1] == 0 || Boolean(d[1])});
                for (var step in currentMonitors[uid].values) {
                    data.push([parseInt(step, 10), parseFloat(currentMonitors[uid].values[step])]);
                }
                var points = svg.selectAll(".point")
                    .data(data)
                    .enter().append("svg:circle")
                     .attr("stroke", "black")
                     .attr("fill", function(d, i) { return '#' + uid.substr(2, 6); })
                     .attr("cx", function(d, i) { return x(d[0]); })
                     .attr("cy", function(d, i) { return y2(d[1]); })
                     .attr("r", function(d, i) { return 2 });

            } else {
                var line = d3.svg.line()
                    .x(function(d) {
                        return x(d[0]);
                    })
                    .y(function(d) {
                        return y1(d[1]);
                    })
                    .defined(function(d){ return d[1] == 0 || Boolean(d[1])});
                for (var step in currentMonitors[uid].values) {
                    data.push([parseInt(step, 10), parseFloat(currentMonitors[uid].values[step])]);
                }
                var points = svg.selectAll(".point")
                    .data(data)
                    .enter().append("svg:circle")
                     .attr("fill", function(d, i) { return '#' + uid.substr(2, 6); })
                     .attr("cx", function(d, i) { return x(d[0]); })
                     .attr("cy", function(d, i) { return y1(d[1]); })
                     .attr("r", function(d, i) { return 2 });

            }

            var len = data.length;
            data.splice(0, len - viewProperties.xvalues - 1);
            var color = '#' + uid.substr(2, 6);
            svg.append("path")
                .datum(data)
                .attr("class", "line")
                .attr("stroke", color)
                .attr("d", line);
        }
    }

});
<commit_msg>frontend, fix monitors for the everything-case<commit_after>
$(function(){

    var viewProperties = {
        height: 420,
        padding: 20,
        xvalues: 100
    };

    var container = $('#graph');
    var svg = null;

    var nodenetMonitors = {};
    var currentMonitors = [];

    var currentSimulationStep = 0;
    var currentNodenet = null;

    var capturedLoggers = {
        'system': false,
        'world': false,
        'nodenet': false
    };

    var logs = [];

    if($.cookie('capturedLoggers')){
        capturedLoggers = JSON.parse($.cookie('capturedLoggers'));
    }
    if($.cookie('currentMonitors')){
        currentMonitors = JSON.parse($.cookie('currentMonitors'));
    }

    var last_logger_call = 0;

    var log_container = $('#logs');

    init();

    $('.layoutbtn').on('click', function(event){
        event.preventDefault();
        var target = $(event.target);
        if(!target.hasClass('active')){
            var layout = target.attr('data');
            if(layout == 'vertical'){
                $('.layout_field').addClass('span6');
            } else if(layout == 'horizontal'){
                $('.layout_field').removeClass('span6');
            }
            refreshMonitors();
            $('.layoutbtn').removeClass('active');
            target.addClass('active');
        }
    })

    $('#monitor_x_axis').on('change', function(){
        viewProperties.xvalues = parseInt($('#monitor_x_axis').val());
        refreshMonitors();
    });

    var filter_timeout=null;
    $('#monitor_filter_logs').on('keydown', function(event){
        if(event.keyCode == 13){
            event.preventDefault();
        }
        clearTimeout(filter_timeout);
        filter_timeout = setTimeout(refreshLoggerView, 400);
    })

    $(document).on('monitorsChanged', function(evt, new_monitor){
        currentMonitors.push(new_monitor)
        refreshMonitors();
    });
    $(document).on('nodenetChanged', function(data, newNodenet){
        refreshMonitors(newNodenet);
    });

    function init() {
        bindEvents();
        if (currentNodenet = $.cookie('selected_nodenet')) {
            api.call('load_nodenet', {
                nodenet_uid: currentNodenet,
                include_links: false
            }, function(data) {
                refreshMonitors();
            },
            function(data) {
                if(data.status == 500){
                    api.defaultErrorCallback(data);
                } else {
                    currentNodenet = null;
                    $.cookie('selected_nodenet', '', { expires: -1, path: '/' });
                    dialogs.notification(data.data, "Info");
                }
            });
        }
    }

    function getPollParams(){
        var poll = [];
        for(var logger in capturedLoggers){
            if(capturedLoggers[logger]){
                poll.push(logger);
            }
        }
        return {
            logger: poll,
            after: last_logger_call
        }
    }

    function setData(data){
        setMonitorData(data);
        setLoggingData(data);
        currentSimulationStep = data.current_step;
    }

    register_stepping_function('monitors', getPollParams, setData);

    function refreshMonitors(newNodenet){
        params = getPollParams();
        if(newNodenet || currentNodenet){
            params.nodenet_uid = newNodenet || currentNodenet;
            api.call('get_monitoring_info', params, setData);
        }
    }

    function setMonitorData(data){
        updateMonitorList(data.monitors);
        nodenetMonitors = data.monitors;
        var m = {};
        for (var uid in nodenetMonitors) {
            if (currentMonitors.indexOf(uid) >= 0) {
                m[uid] = nodenetMonitors[uid];
            }
        }
        drawGraph(m);
    }

    function setLoggingData(data){
        last_logger_call = data.logs.servertime;
        for(var idx in data.logs.logs){
            var item = data.logs.logs[idx];
            logs.push(item);
            var filter = $('#monitor_filter_logs').val();
            if(filter){
                var check = item.logger + item.msg + item.module + item.function + item.level
                if(check.indexOf(filter) > -1){
                    log_container.append(''+("          " + item.logger).slice(-10)+' | ' + item.msg +'');
                }
            } else {
                log_container.append($(''+("          " + item.logger).slice(-10)+' | ' + item.msg +''));
            }
        }
        var height = log_container.height();
        var scrollHeight = log_container[0].scrollHeight;
        var st = log_container.scrollTop();
        var doscroll = (st >= (scrollHeight - height));
        if(doscroll){
            log_container.scrollTop(log_container[0].scrollHeight);
        }
    }

    function refreshLoggerView(){
        var html = '';
        var filter = $('#monitor_filter_logs').val();
        for(var idx in logs){
            item = logs[idx];
            if(filter){
                var check = item.logger + item.msg + item.module+ item.function + item.level
                if(check.indexOf(filter) > -1){
                    html += ''+("          " + item.logger).slice(-10)+' | ' + item.msg +'';
                }
            } else {
                html += ''+("          " + item.logger).slice(-10)+' | ' + item.msg +'';
            }
        }
        log_container.html(html);
        var height = log_container.height();
        var scrollHeight = log_container[0].scrollHeight;
        var st = log_container.scrollTop();
        var doscroll = (st >= (scrollHeight - height));
        if(doscroll){
            log_container.scrollTop(log_container[0].scrollHeight);
        }
    }

    function bindEvents(){
        $('.log_switch').on('change', function(event){
            var el = $(event.target);
            capturedLoggers[el.attr('data')] = el.attr('checked')
            $.cookie('capturedLoggers', JSON.stringify(capturedLoggers), {path:'/', expires:7})
        });
        $('.log_level_switch').on('change', function(event){
            var el = $(event.target);
            var data = {}
            data[el.attr('data')] = el.val();
            api.call('set_logging_levels', data);
        });
        $('.log_switch').each(function(idx, el){
            if(capturedLoggers[$(el).attr('data')]){
                el.checked=true;
            }
        });
    }

    function updateMonitorList(monitors){
        var list = $('#monitor_selector');
        var html = '';
        for(var uid in monitors){
            html += '
<input type="checkbox" class="monitor_checkbox" value="'+uid+'" id="'+uid+'"';
            if(currentMonitors.indexOf(uid) > -1){
                html += ' checked="checked"';
            }
            html += ' /> ' + monitors[uid].name + '
';
        }
        list.html(html);
        $('.monitor_checkbox', list).on('change', updateMonitorSelection);
        $('.delete_monitor', list).on('click', function(event){
            event.preventDefault();
            api.call(
                'remove_monitor',
                {nodenet_uid: currentNodenet, monitor_uid: $(event.delegateTarget).attr('data')},
                function(){
                    delete monitors[uid];
                    refreshMonitors();
                }
            );
        });
    }

    function updateMonitorSelection() {
        currentMonitors = [];
        $.each($('.monitor_checkbox'), function(idx, el) {
            if (el.checked) {
                currentMonitors.push(el.value);
            }
        });
        $.cookie('currentMonitors', JSON.stringify(currentMonitors), {path:'/', expires:7})
        drawGraph(currentMonitors);
    }

    function drawGraph(currentMonitors) {

        var customMonitors = false;
        container.html(''); // TODO: come up with a way to redraw
        var margin = {
                top: 20,
                right: 50,
                bottom: 30,
                left: 50
            },
            width = container.width() - margin.left - margin.right - viewProperties.padding,
            height = viewProperties.height - margin.top - margin.bottom - viewProperties.padding;

        var xmax = Math.max(viewProperties.xvalues, currentSimulationStep);

        var xvalues = viewProperties.xvalues;
        if(viewProperties.xvalues < 0){
            xvalues = xmax;
        }
        var x = d3.scale.linear()
            .domain([xmax - xvalues, xmax])
            .range([0, width]);
        var xstart = xmax - xvalues;

        var y1values = [];
        var y2values = [];
        var y1max = 1.0;
        var y1min = 0;
        var y2max = 1.0;
        var y2min = 0;
        for (var uid in currentMonitors) {
            for (var step in currentMonitors[uid].values) {
                if(currentMonitors[uid].classname == 'CustomMonitor'){
                    customMonitors = true;
                    y2values.push(currentMonitors[uid].values[step]);
                    if (step >= xstart) {
                        y2max = Math.max(y2max, currentMonitors[uid].values[step]);
                        y2min = Math.min(y2min, currentMonitors[uid].values[step]);
                    }
                } else {
                    y1values.push(currentMonitors[uid].values[step]);
                    if (step >= xstart) {
                        y1max = Math.max(y1max, currentMonitors[uid].values[step]);
                        y1min = Math.min(y1min, currentMonitors[uid].values[step]);
                    }
                }
            }
        }

        var y1 = d3.scale.linear().domain([y1min, y1max]).range([height, 0]);
        var y2 = d3.scale.linear().domain([y2min, y2max]).range([height, 0]);

        var x_axis_pos = (y1max / (y1max - y1min)) * height;

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

        var y1Axis = d3.svg.axis()
            .scale(y1)
            .orient("left");
        var y2Axis = d3.svg.axis()
            .scale(y2)
            .orient("right");

        svg = d3.select("#graph").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + x_axis_pos + ")")
            .call(xAxis)
            .append("text")
            .attr("dx", width - 100)
            .attr("dy", -5)
            .style("text-anchor", "start")
            .text("Nodenet step");
        svg.append("g")
            .attr("class", "y axis")
            .call(y1Axis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Activation");
        if(customMonitors){
            svg.append("g")
                .attr("class", "y axis")
                .call(y2Axis)
                .attr("transform", "translate(" + width + " ,0)")
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Value");
        }

        for (var uid in currentMonitors) {
            var data = [];
            if(currentMonitors[uid].classname == 'CustomMonitor'){
                var line = d3.svg.line()
                    .x(function(d) {
                        return x(d[0]);
                    })
                    .y(function(d) {
                        return y2(d[1]);
                    })
                    .defined(function(d){ return d[1] == 0 || Boolean(d[1])});
                for (var step in currentMonitors[uid].values) {
                    data.push([parseInt(step, 10), parseFloat(currentMonitors[uid].values[step])]);
                }
                var points = svg.selectAll(".point")
                    .data(data)
                    .enter().append("svg:circle")
                     .attr("stroke", "black")
                     .attr("fill", function(d, i) { return '#' + uid.substr(2, 6); })
                     .attr("cx", function(d, i) { return x(d[0]); })
                     .attr("cy", function(d, i) { return y2(d[1]); })
                     .attr("r", function(d, i) { return 2 });

            } else {
                var line = d3.svg.line()
                    .x(function(d) {
                        return x(d[0]);
                    })
                    .y(function(d) {
                        return y1(d[1]);
                    })
                    .defined(function(d){ return d[1] == 0 || Boolean(d[1])});
                for (var step in currentMonitors[uid].values) {
                    data.push([parseInt(step, 10), parseFloat(currentMonitors[uid].values[step])]);
                }
                var points = svg.selectAll(".point")
                    .data(data)
                    .enter().append("svg:circle")
                     .attr("fill", function(d, i) { return '#' + uid.substr(2, 6); })
                     .attr("cx", function(d, i) { return x(d[0]); })
                     .attr("cy", function(d, i) { return y1(d[1]); })
                     .attr("r", function(d, i) { return 2 });

            }

            var len = data.length;
            data.splice(0, len - xvalues - 1);
            var color = '#' + uid.substr(2, 6);
            svg.append("path")
                .datum(data)
                .attr("class", "line")
                .attr("stroke", color)
                .attr("d", line);
        }
    }

});
<|endoftext|>


<commit_before>/*
 *    Copyright (C) 2017    IC Manage Inc.
 *
 *    See the file 'COPYING' for license information.
 */

function restHost() {
  //
  //  Give the URL priority
  //
  const params = new URLSearchParams(window.location.search.substring(1));
  const rest = params.get('rest');
  if (rest) {
    return rest;
  }
  //
  //  Otherwise, if the URL is the Slingshot BrowserSync default, use the
  //  pre-configured product default. This is where a developer's
  //  vcnc-rest would be listening.
  //
  if (window.location.host === 'localhost:3000') {
    return 'localhost:6130';
  }
  //
  //  Otherwise, use the offset convention programmed into vcnc-rest.
  //
  const port = parseInt(window.location.port, 10) + 10;
  return `${window.location.hostname}:${port}`;
}

export default restHost;

<commit_msg>vcnc-web: Infrastructure for changing the REST host from the URL.  Not yet wired in.<commit_after>/*
 *    Copyright (C) 2017    IC Manage Inc.
 *
 *    See the file 'COPYING' for license information.
 */

function restHost() {
  //
  //  Give the URL priority
  //  ... the substring(1) idiom drops the initial '?' See
  //      https://stackoverflow.com/a/14395123/7702839
  //
  const params = new URLSearchParams(window.location.search.substring(1));
  if (params.has('rest')) {
    return params.get('rest');
  }
  //
  //  Otherwise, if the URL is the Slingshot BrowserSync default, use the
  //  pre-configured product default. This is where a developer's
  //  vcnc-rest would be listening.
  //
  if (window.location.host === 'localhost:3000') {
    return 'localhost:6130';
  }
  //
  //  Otherwise, use the offset convention programmed into vcnc-rest.
  //
  const port = parseInt(window.location.port, 10) + 10;
  return `${window.location.hostname}:${port}`;
}

export default restHost;

<|endoftext|>


<commit_before>/* jshint browser:true */
/* globals PIXI, requestAnimationFrame */
(function() {

    document.addEventListener('DOMContentLoaded', function() {

        // define EDGE
        var LEFT = "left",
            RIGHT = "right",
            TOP = "top",
            BOTTOM = "bottom";

        // define default velocity value
        var DEFAULT_VELOCITY = 5;

        // define PIXI libraries
        var Graphics = PIXI.Graphics,
            Text = PIXI.Text,
            Container = PIXI.Container,
            autoDetectRenderer = PIXI.autoDetectRenderer;

        // define Game Objects
        var circle,
            roundBox;

        // define parameters
        var isStopGame;
        var isPlayGame;

        // create an new instance of a pixi stage
        var stage = new Container();

        // create an new instance of a gameOverScene
        var gameOverScene = new Container();
        gameOverScene.visible = false;

        stage.addChild(gameOverScene);

        // register backgound listener
        stage.interactive = true;
        stage.mousedown = stage.touchstart = onMouseDown;
        stage.mousemove = stage.touchmove = onMouseMove;
        stage.mouseup = stage.touchend = onMouseUp;

        // create a renderer instance
        var width = window.innerWidth//screen.availWidth;
        var height = window.innerHeight//screen.availHeight;
        var renderer = new autoDetectRenderer(width, height, {backgroundColor : 0x000000});

        // add the renderer view element to the DOM
        document.body.appendChild(renderer.view);

        requestAnimationFrame(onStart);

        var scores = 0;
        var message = new Text(
          "0",
          {font: "32px sans-serif", fill: "white"}
        );

        message.position.set(20, 20);
        message.visible = false;
        stage.addChild(message);

        function onStart() {
            if(!isPlayGame){
                initPlayButton();
            }else{
                message.visible = true;

                initCircleObject();
                initRoundBoxObject();
                initGameOverScene();

                circle.vx = DEFAULT_VELOCITY;
                circle.vy = DEFAULT_VELOCITY;

                requestAnimationFrame(onUpdate);
            }

        }

        function onUpdate(){

            // Stop game
            if(isStopGame) return;

            requestAnimationFrame(onUpdate);

            circle.y += circle.vy;
            circle.x += circle.vx;

            var edge,
                isHit;

            //check for a collision between the 'circle' and the 'roundBox'
            isHited = hitObjects(circle, roundBox);

            var frameHeight;
            if (isHited) {
//                frameHeight = height;
                // plus scores
                        scores++;

                        // show user's scores
                        message.text = scores;

                        circle.vy = (-1.1) * circle.vy;
                        circle.vx = (1.1) * circle.vx;
            }else{
                frameHeight = height + roundBox.height;

                 edge = contain(circle, {x: 0, y: 0, width: width, height: frameHeight});

            // check position hited of 'circle'
            switch(edge){
                case LEFT:{
                    circle.vx = (-1) * circle.vx;
                    break;
                }
                case RIGHT:{
                     circle.vx = (-1) * circle.vx;

                    break;
                }
                case TOP:{
                    circle.vy = (-1) * circle.vy;

                    break;
                }
                 case BOTTOM:{
                    if(!isHited){
                        // lose game
                        lose();

                    }else{
                        // plus scores
                        scores++;

                        // show user's scores
                        message.text = scores;

                        circle.vy = (-1.1) * circle.vy;
                        circle.vx = (1.1) * circle.vx;
                    }

                    break;
                }

                default:{
                    break;
                }
            }
            }

            // render the stage
            renderer.render(stage);
        }

        // lose game
        function lose(){
            isStopGame = true;

            circle.vy = 0;
            circle.vx = 0;

            gameOverScene.visible = true;
        }

        // reset game
        function reset(){
            isStopGame = false;

            scores = 0;
            message.text = scores;

            circle.vy = DEFAULT_VELOCITY;
            circle.vx = DEFAULT_VELOCITY;

            circle.x = Math.floor((Math.random() * width) + 0);
            circle.y = 130;

            gameOverScene.visible = false;

            onUpdate();
        }

        /***** ACTIONS ******/
        function onMouseDown(mouseData){
            console.log("onMouseDown");

            if(isStopGame){
               reset();
            }
        }

        function onMouseMove(mouseData){
//             console.log("onMouseMoved");

            if(isStopGame) return;

             var mouse = mouseData.data.originalEvent;
            _mouseY = mouse.y;
            _mouseX = mouse.x;

            if(_mouseX > (width - roundBox.width)){

                _mouseX = width - roundBox.width;

            }

            // update roundBox position
            roundBox.x = _mouseX;
        }

        function onMouseUp(mouseData){
            console.log("onMouseUp");

        }

        /***** EXTERNAL FUNCTION *****/
        function contain(sprite, container) {

          var collision = undefined;

          //Left
          if (sprite.x < container.x) {
            sprite.x = container.x;
            collision = LEFT;
          }

          //Top
          if (sprite.y < container.y) {
            sprite.y = container.y;
            collision = TOP;
          }

          //Right
          if (sprite.x + sprite.width > container.width) {
            sprite.x = container.width - sprite.width;
            collision = RIGHT;
          }

          //Bottom
          if (sprite.y + sprite.height > container.height) {
            sprite.y = container.height - sprite.height;
            collision = BOTTOM;
          }

          //Return the `collision` value
          return collision;
        }

        //The `hitObjects` function
        function hitObjects(r1, r2) {

          //Define the variables we'll need to calculate
          var hit, combinedHalfWidths, combinedHalfHeights, vx, vy;

          //hit will determine whether there's a collision
          hit = false;

          //Find the center points of each sprite
          r1.centerX = r1.x + r1.width / 2;
          r1.centerY = r1.y + r1.height / 2;
          r2.centerX = r2.x + r2.width / 2;
          r2.centerY = r2.y + r2.height / 2;

          //Find the half-widths and half-heights of each sprite
          r1.halfWidth = r1.width / 2;
          r1.halfHeight = r1.height / 2;
          r2.halfWidth = r2.width / 2;
          r2.halfHeight = r2.height / 2;

          //Calculate the distance vector between the sprites
          vx = r1.centerX - r2.centerX;
          vy = r1.centerY - r2.centerY;

          //Figure out the combined half-widths and half-heights
          combinedHalfWidths = r1.halfWidth + r2.halfWidth;
          combinedHalfHeights = r1.halfHeight + r2.halfHeight;

          //Check for a collision on the x axis
          if (Math.abs(vx) < combinedHalfWidths) {

            //A collision might be occuring. Check for a collision on the y axis
            if (Math.abs(vy) < combinedHalfHeights) {

              //There's definitely a collision happening
              hit = true;
            } else {

              //There's no collision on the y axis
              hit = false;
            }
          } else {

            //There's no collision on the x axis
            hit = false;
          }

          //`hit` will be either `true` or `false`
          return hit;
        }

        function initCircleObject(){
            //Circle
            circle = new Graphics();
            circle.beginFill(0x9966FF);
            circle.drawCircle(0, 0, 15);
            circle.endFill();
            circle.x = 64;
            circle.y = 130;

            stage.addChild(circle);
        }

        function initRoundBoxObject(){

            var roundBoxHeight = 20;
            var roundBoxWidth = width/4;

            //Rounded rectangle
            roundBox = new Graphics();
            roundBox.lineStyle(4, 0x9966FF, 1);
            roundBox.beginFill(0xFF9933);
            roundBox.drawRoundedRect(0, 0, roundBoxWidth, roundBoxHeight, 10)
            roundBox.endFill();
            roundBox.x = 5;
            roundBox.y = height - roundBoxHeight;
            stage.addChild(roundBox);
        }

        function initGameOverScene(){
            var loseMessage = new Text(
                  "YOU LOSE :(\n\nTAP ME TO RETRY",
                  {font: "32px sans-serif", fill: "white", align: "center"}
                 );
            loseMessage.anchor.x = 0.5;
            loseMessage.anchor.y= 0.5;

            loseMessage.x = width/2;
            loseMessage.y = height/2;

            gameOverScene.addChild(loseMessage);
        }

        function initPlayButton(){
            var playButton = new Text(
                  "PLAY",
                  {font: "32px sans-serif", fill: "white", align: "center"}
                 );
            playButton.anchor.x = 0.5;
            playButton.anchor.y= 0.5;

            playButton.x = width/2;
            playButton.y = height/2;

            stage.addChild(playButton);
            renderer.render(stage);

            // turn on interactive
            playButton.interactive = true;
            playButton.click = playButton.tap = function play(){
                playButton.visible = false;
                isPlayGame = true;

                onStart();
            }
        }

    }, false);

}());
<commit_msg>! Fix wrong roundBox height<commit_after>/* jshint browser:true */
/* globals PIXI, requestAnimationFrame */
(function() {

    document.addEventListener('DOMContentLoaded', function() {

        // define EDGE
        var LEFT = "left",
            RIGHT = "right",
            TOP = "top",
            BOTTOM = "bottom";

        // define default velocity value
        var DEFAULT_VELOCITY = 5;

        // define PIXI libraries
        var Graphics = PIXI.Graphics,
            Text = PIXI.Text,
            Container = PIXI.Container,
            autoDetectRenderer = PIXI.autoDetectRenderer;

        // define Game Objects
        var circle,
            roundBox;

        // define parameters
        var isStopGame;
        var isPlayGame;

        // create an new instance of a pixi stage
        var stage = new Container();

        // create an new instance of a gameOverScene
        var gameOverScene = new Container();
        gameOverScene.visible = false;

        stage.addChild(gameOverScene);

        // register backgound listener
        stage.interactive = true;
        stage.mousedown = stage.touchstart = onMouseDown;
        stage.mousemove = stage.touchmove = onMouseMove;
        stage.mouseup = stage.touchend = onMouseUp;

        // create a renderer instance
        var width = window.innerWidth//screen.availWidth;
        var height = window.innerHeight//screen.availHeight;
        var renderer = new autoDetectRenderer(width, height);

        // add the renderer view element to the DOM
        document.body.appendChild(renderer.view);

        requestAnimationFrame(onStart);

        var scores = 0;
        var message = new Text(
          "0",
          {font: "32px sans-serif", fill: "white"}
        );

        message.position.set(20, 20);
        message.visible = false;
        stage.addChild(message);

        function onStart() {
            if(!isPlayGame){
                initPlayButton();
            }else{
                message.visible = true;

                initCircleObject();
                initRoundBoxObject();
                initGameOverScene();

                circle.vx = DEFAULT_VELOCITY;
                circle.vy = DEFAULT_VELOCITY;

                requestAnimationFrame(onUpdate);
            }

        }

        function onUpdate(){

            // Stop game
            if(isStopGame) return;

            requestAnimationFrame(onUpdate);

            circle.y += circle.vy;
            circle.x += circle.vx;

            var edge,
                isHit;

            //check for a collision between the 'circle' and the 'roundBox'
            isHited = hitObjects(circle, roundBox);

            var frameHeight;
            if (isHited) {
//                frameHeight = height;
                // plus scores
                        scores++;

                        // show user's scores
                        message.text = scores;

                        circle.vy = (-1.1) * circle.vy;
                        circle.vx = (1.1) * circle.vx;
            }else{
                frameHeight = height + roundBox.height;

                 edge = contain(circle, {x: 0, y: 0, width: width, height: frameHeight});

            // check position hited of 'circle'
            switch(edge){
                case LEFT:{
                    circle.vx = (-1) * circle.vx;
                    break;
                }
                case RIGHT:{
                     circle.vx = (-1) * circle.vx;

                    break;
                }
                case TOP:{
                    circle.vy = (-1) * circle.vy;

                    break;
                }
                 case BOTTOM:{
                    if(!isHited){
                        // lose game
                        lose();

                    }else{
                        // plus scores
                        scores++;

                        // show user's scores
                        message.text = scores;

                        circle.vy = (-1.1) * circle.vy;
                        circle.vx = (1.1) * circle.vx;
                    }

                    break;
                }

                default:{
                    break;
                }
            }
            }

            // render the stage
            renderer.render(stage);
        }

        // lose game
        function lose(){
            isStopGame = true;

            circle.vy = 0;
            circle.vx = 0;

            gameOverScene.visible = true;
        }

        // reset game
        function reset(){
            isStopGame = false;

            scores = 0;
            message.text = scores;

            circle.vy = DEFAULT_VELOCITY;
            circle.vx = DEFAULT_VELOCITY;

            circle.x = Math.floor((Math.random() * width) + 0);
            circle.y = 130;

            gameOverScene.visible = false;

            onUpdate();
        }

        /***** ACTIONS ******/
        function onMouseDown(mouseData){
            console.log("onMouseDown");

            if(isStopGame){
               reset();
            }
        }

        function onMouseMove(mouseData){
//             console.log("onMouseMoved");

            if(isStopGame) return;

             var mouse = mouseData.data.originalEvent;
            _mouseY = mouse.y;
            _mouseX = mouse.x;

            if(_mouseX > (width - roundBox.width)){

                _mouseX = width - roundBox.width;

            }

            // update roundBox position
            roundBox.x = _mouseX;
            roundBox.y = height - 20;
        }

        function onMouseUp(mouseData){
            console.log("onMouseUp");

        }

        /***** EXTERNAL FUNCTION *****/
        function contain(sprite, container) {

          var collision = undefined;

          //Left
          if (sprite.x < container.x) {
            sprite.x = container.x;
            collision = LEFT;
          }

          //Top
          if (sprite.y < container.y) {
            sprite.y = container.y;
            collision = TOP;
          }

          //Right
          if (sprite.x + sprite.width > container.width) {
            sprite.x = container.width - sprite.width;
            collision = RIGHT;
          }

          //Bottom
          if (sprite.y + sprite.height > container.height) {
            sprite.y = container.height - sprite.height;
            collision = BOTTOM;
          }

          //Return the `collision` value
          return collision;
        }

        //The `hitObjects` function
        function hitObjects(r1, r2) {

          //Define the variables we'll need to calculate
          var hit, combinedHalfWidths, combinedHalfHeights, vx, vy;

          //hit will determine whether there's a collision
          hit = false;

          //Find the center points of each sprite
          r1.centerX = r1.x + r1.width / 2;
          r1.centerY = r1.y + r1.height / 2;
          r2.centerX = r2.x + r2.width / 2;
          r2.centerY = r2.y + r2.height / 2;

          //Find the half-widths and half-heights of each sprite
          r1.halfWidth = r1.width / 2;
          r1.halfHeight = r1.height / 2;
          r2.halfWidth = r2.width / 2;
          r2.halfHeight = r2.height / 2;

          //Calculate the distance vector between the sprites
          vx = r1.centerX - r2.centerX;
          vy = r1.centerY - r2.centerY;

          //Figure out the combined half-widths and half-heights
          combinedHalfWidths = r1.halfWidth + r2.halfWidth;
          combinedHalfHeights = r1.halfHeight + r2.halfHeight;

          //Check for a collision on the x axis
          if (Math.abs(vx) < combinedHalfWidths) {

            //A collision might be occuring. Check for a collision on the y axis
            if (Math.abs(vy) < combinedHalfHeights) {

              //There's definitely a collision happening
              hit = true;
            } else {

              //There's no collision on the y axis
              hit = false;
            }
          } else {

            //There's no collision on the x axis
            hit = false;
          }

          //`hit` will be either `true` or `false`
          return hit;
        }

        function initCircleObject(){
            //Circle
            circle = new Graphics();
            circle.beginFill(0x9966FF);
            circle.drawCircle(0, 0, 15);
            circle.endFill();
            circle.x = 64;
            circle.y = 130;

            stage.addChild(circle);
        }

        function initRoundBoxObject(){

            var roundBoxHeight = 20;
            var roundBoxWidth = width/4;

            //Rounded rectangle
            roundBox = new Graphics();
            roundBox.lineStyle(4, 0x9966FF, 1);
            roundBox.beginFill(0xFF9933);
            roundBox.drawRoundedRect(0, 0, roundBoxWidth, roundBoxHeight, 10)
            roundBox.endFill();
            roundBox.x = 5;
            roundBox.y = height - roundBoxHeight;
            stage.addChild(roundBox);
        }

        function initGameOverScene(){
            var loseMessage = new Text(
                  "YOU LOSE :(\n\nTAP ME TO RETRY",
                  {font: "32px sans-serif", fill: "white", align: "center"}
                 );
            loseMessage.anchor.x = 0.5;
            loseMessage.anchor.y= 0.5;

            loseMessage.x = width/2;
            loseMessage.y = height/2;

            gameOverScene.addChild(loseMessage);
        }

        function initPlayButton(){
            var playButton = new Text(
                  "PLAY",
                  {font: "32px sans-serif", fill: "white", align: "center"}
                 );
            playButton.anchor.x = 0.5;
            playButton.anchor.y= 0.5;

            playButton.x = width/2;
            playButton.y = height/2;

            stage.addChild(playButton);
            renderer.render(stage);

            // turn on interactive
            playButton.interactive = true;
            playButton.click = playButton.tap = function play(){
                playButton.visible = false;
                isPlayGame = true;

                onStart();
            }
        }

    }, false);

}());

<|endoftext|>


<commit_before>var sock;

var curEvent, users, messages;

var app;

var curSession = null;

// handle IE not having console.log
if (typeof console === "undefined" || typeof console.log === "undefined") {
     console = {};
     console.log = function() {};
}

$(document).ready(function() {
	if($("#main").length!=1) {
		console.log("Code running on a page that does not have an #app div.");
		return;
	}

	console.log("Starting app!");

	curEvent = new models.ClientEvent(EVENT_ATTRS);

	users = new models.UserList(EVENT_ATTRS.connectedUsers);

	curEvent.get("sessions").add(EVENT_ATTRS.sessions);

	if(SINGLE_SESSION_RSVP) {
		curEvent.get("sessions").each(function(session) {
			if(session.isAttending(USER_ID)) {
				console.log("SETTING CUR SESSION: " + session.id);
				curSession = session.id;
			}
		})
	}

	$("#sessions-nav").find("a").text("Sessions (" + curEvent.get("sessions").length + ")");

	messages = new models.ChatMessageList();

	console.log("Inflated models.");

	app = new Backbone.Marionette.Application();

	app.addRegions({
		// top: '#top',
		right: '#main-right',
		main: '#main-left',
		top: '#top-left',
		global: '#global',
		dialogs: '#dialogs',
		admin: '#admin-region',
		bar:'#bar'
	});

	app.addInitializer(function(options) {

		// include the youtube JS api per docs:
	    // https://developers.google.com/youtube/iframe_api_reference
	    var tag = document.createElement('script');
	    tag.src = "//www.youtube.com/iframe_api";
	    var firstScriptTag = document.getElementsByTagName('script')[0];
	    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

	    window.onYouTubeIframeAPIReady = _.bind(function(playerId) {
			this.vent.trigger("youtube-ready");
	    }, this);

	    this.paginatedSessions = new models.PaginatedSessionList(curEvent.get("sessions").models);
	    this.paginatedSessions.bootstrap();

		this.sessionListView = new SessionListView({collection: this.paginatedSessions});
		this.chatView = new ChatLayout({messages:messages, users:users});
		this.youtubeEmbedView = new VideoEmbedView({model:curEvent});
		this.dialogView = new DialogView();

		// this.top.show(this.sessionListView);
		this.right.show(this.chatView);
		this.main.show(this.sessionListView);
		this.dialogs.show(this.dialogView);

		// this is a little unorthodox, but not sure how else
		// to do it.
		$(this.bar.el).hide();

		if(IS_ADMIN) {
			this.adminButtonView = new AdminButtonView();
			this.admin.show(this.adminButtonView);
		}

		console.log("Initialized app.");
	});

	var isIntervalRunning = false;
	var interval = 0;

	app.vent.on("new-chat-message", _.bind(function() {
		isIntervalRunning = true;

		if(isIntervalRunning)
			interval = window.setTimeout(showFlashTitle, 1000);
	}, app));

	function showFlashTitle() {
		if(window.document.title == 'Unhangout')
			window.document.title = 'New Message ...';
		else
			window.document.title = 'Unhangout';

		interval = window.setTimeout(showFlashTitle, 1000);
	}

	app.vent.on("sessions-nav", _.bind(function() {
		this.main.show(this.sessionListView);
	}, app));

	var videoShown = false;
	app.vent.on("video-nav", _.bind(function() {
		console.log("handling video-nav event");

		// regardless of whether there's a current embed, hide the video if
		// it's currently showon.
		if(videoShown) {
			this.top.$el.css("z-index", -10);

			this.top.reset();
			videoShown = false;

			this.main.$el.css("top", 0);
			this.sessionListView.updateDisplay();
			$("#video-nav").removeClass("active");
		} else if(curEvent.hasEmbed()) {
			$(".nav .active").removeClass("active");

			if(!videoShown) {
				this.top.show(this.youtubeEmbedView);
				videoShown = true;

				var mainHeight = this.youtubeEmbedView.$el.outerHeight()-5;

				if(this.main.$el.hasClass("bar")) {
					mainHeight += 40;
				}

				this.main.$el.css("top", mainHeight);
				this.sessionListView.updateDisplay();
				this.top.$el.css("z-index", 50);
				$("#video-nav").addClass("active");
			}
		} else {
			console.log("Ignoring video click; no video available.");
		}

	}, app));

	app.vent.on("youtube-ready", _.bind(function() {
		console.log("YOUTUBE READY");

		if(curEvent.hasEmbed()) {
			app.vent.trigger("video-nav");
		}
	}, app));

	app.vent.on("video-live", _.bind(function() {
		$("#video-nav .label").removeClass("hide");
	}, app));

	app.vent.on("video-off", _.bind(function() {
		$("#video-nav .label").addClass("hide");
	}, app));

	app.vent.on("show-bar", _.bind(function(sessionKey) {

		this.bar.show(new SessionLiveView());
		$(this.bar.el).show();

		$("#top-left, #main-right, #main-left").addClass("bar");

		// set the hangout link.
		this.bar.$el.find("a").attr("href", "/session/" + sessionKey);

		// 30 minutes later hide the bar(?)
		setTimeout(function() {
			app.vent.trigger("hide-bar");
		}, 60*1000*30);
	}, app));

	app.vent.on("hide-bar", _.bind(function() {
		this.bar.close();
		this.bar.$el.hide();

		$("#top-left, #main-right, #main-left").removeClass("bar");

		// we need to do a special check for main-left, which has custom
		// style adjustement on it.
		if(videoShown) {
			this.main.$el.css("top", this.youtubeEmbedView.$el.outerHeight()-5);
		} else {
			this.main.$el.css("top", "");
		}

	}, app));

	var queuedAttend = false;

	app.vent.on("attend", _.bind(function(sessionId) {
		console.log("VENT ATTEND: " + sessionId);
		// we have to manage attend logic here in the single_session_rsvp case so
		// we can send unattend messages first, and then attend messages.

		// if they're the same, just ignore it.
		if(curSession && curSession!=sessionId) {

			queuedAttend = function() {
				var message = {type:"attend", args:{id:sessionId}};
				sock.send(JSON.stringify(message));
			}

			var message = {type:"unattend", args:{id:curSession}};
			sock.send(JSON.stringify(message));
		} else if(!curSession) {
			var message = {type:"attend", args:{id:sessionId}};
			sock.send(JSON.stringify(message));
		}
	}));

	app.start();

	if(curSession) {
		var curSessionObj = curEvent.get("sessions").get(curSession);

		if(curSessionObj.isLive()) {
			app.vent.trigger("show-bar", curSessionObj.get("session-key"));
		}
	}

	if(curEvent.hasEmbed()) {
		app.vent.trigger("video-live");
		// app.vent.trigger("video-nav");
	}

	$("#video-nav").click(function() {
		app.vent.trigger($(this).attr("id"));
	})

	console.log("Setup regions.");

	sock = new SockJS(document.location.protocol + "//" + document.location.hostname + ":" + document.location.port + "/sock");
	sock.onopen = function() {
		console.log('open');

		var AUTH = {type:"auth", args:{key:SOCK_KEY, id:USER_ID}};

		sock.send(JSON.stringify(AUTH));
	};
	sock.onmessage = function(message) {
		console.log(message);
		var msg = JSON.parse(message.data);

		if(msg.type.indexOf("-err")!=-1) {
			console.log("Got an error from the server!");
		}

		switch(msg.type) {
			case "attend":
				curEvent.get("sessions").get(msg.args.id).addAttendee(msg.args.user);
				console.log("added attendee to a session");

				if(SINGLE_SESSION_RSVP && msg.args.user.id==USER_ID) {

					if(!_.isNull(curSession)) {
						var message = {type:"unattend", args:{id:curSession}};
						sock.send(JSON.stringify(message));
					}

					curSession = msg.args.id;
				}
				break;

			case "first-attendee":
				curEvent.get("sessions").get(msg.args.id).setFirstAttendee(msg.args.user);
				console.log("set first attendee");
				break;

			case "unattend"	:
				curEvent.get("sessions").get(msg.args.id).removeAttendee(msg.args.user);
				console.log("removed attendee from a session");

				curSession = null;

				if(queuedAttend) {
					queuedAttend.call();
					queuedAttend = false;
				}

				break;

			case "join":
				console.log("join: " + JSON.stringify(msg.args));
				users.add(new models.User(msg.args.user));
				break;

			case "leave":
				users.remove(users.get(msg.args.user.id));
				break;

			case "chat":
				messages.add(new models.ChatMessage(msg.args));
				app.vent.trigger("new-chat-message");
				break;

			case "embed":
				var originalYoutubeId = curEvent.get("youtubeEmbed") || "";

				curEvent.setEmbed(msg.args.ytId);
				console.log("added yt embed id: " + JSON.stringify(msg.args));

				if(msg.args.ytId.length > 0) {
					// if it's a non-empty yt embed, show the live tag.
					app.vent.trigger("video-live");

					if(originalYoutubeId.length==0) {
						app.vent.trigger("video-nav");
					}
				} else {
					// if it's empty, hide the live tag.
					app.vent.trigger("video-off");
					app.vent.trigger("video-nav");
				}

				break;

			case "start":
				// this is a little wacky, but we want to give people who RSVP'd a chance to join first.
				// so we're going to do two things here:
				// 1) if not rsvp, delay triggering start and setting the session key.
				// 2) if not rsvp, supress the dialog popup
				var session = curEvent.get("sessions").get(msg.args.id);

				var timeout = 0;

				if(!(session.isAttending(USER_ID))) {
					timeout = 60*1000;
				}

				setTimeout(function() {
					session.set("session-key", msg.args.key);
					session.start();
				}, timeout);

				app.vent.trigger("show-bar", msg.args.key);

				break;
			case "stop":
				var session = curEvent.get("sessions").get(msg.args.id);
				session.stop();

				if(session.id==curSession) {
					app.vent.trigger("hide-bar");
				}

				break;
			case "auth-ack":
				sock.send(JSON.stringify({type:"join", args:{id:curEvent.id}}));
				break;

			case "embed-ack":
				$("#embed-modal").modal('hide');
				break;

			case "join-ack":
				console.log("joined!");
				break;

			case "attend-ack":
				console.log("attend-ack");
				break;
		}
	};

	sock.onclose = function() {
		$('#disconnected-modal').modal('show');
		messages.add(new models.ChatMessage({text:"You have been disconnected from the server. Please reload the page to reconnect!", user:{displayName:"SERVER"}}));
		console.log('close');
	};
});
<commit_msg>Modified app.js file and added blur / focus functions. Now whenever there is a new message pop up and the window is out of focus the window title will flash<commit_after>var sock;

var curEvent, users, messages;

var app;

var curSession = null;

// handle IE not having console.log
if (typeof console === "undefined" || typeof console.log === "undefined") {
     console = {};
     console.log = function() {};
}

$(document).ready(function() {
	if($("#main").length!=1) {
		console.log("Code running on a page that does not have an #app div.");
		return;
	}

	console.log("Starting app!");

	curEvent = new models.ClientEvent(EVENT_ATTRS);

	users = new models.UserList(EVENT_ATTRS.connectedUsers);

	curEvent.get("sessions").add(EVENT_ATTRS.sessions);

	if(SINGLE_SESSION_RSVP) {
		curEvent.get("sessions").each(function(session) {
			if(session.isAttending(USER_ID)) {
				console.log("SETTING CUR SESSION: " + session.id);
				curSession = session.id;
			}
		})
	}

	$("#sessions-nav").find("a").text("Sessions (" + curEvent.get("sessions").length + ")");

	messages = new models.ChatMessageList();

	console.log("Inflated models.");

	app = new Backbone.Marionette.Application();

	app.addRegions({
		// top: '#top',
		right: '#main-right',
		main: '#main-left',
		top: '#top-left',
		global: '#global',
		dialogs: '#dialogs',
		admin: '#admin-region',
		bar:'#bar'
	});

	app.addInitializer(function(options) {

		// include the youtube JS api per docs:
	    // https://developers.google.com/youtube/iframe_api_reference
	    var tag = document.createElement('script');
	    tag.src = "//www.youtube.com/iframe_api";
	    var firstScriptTag = document.getElementsByTagName('script')[0];
	    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

	    window.onYouTubeIframeAPIReady = _.bind(function(playerId) {
			this.vent.trigger("youtube-ready");
	    }, this);

	    this.paginatedSessions = new models.PaginatedSessionList(curEvent.get("sessions").models);
	    this.paginatedSessions.bootstrap();

		this.sessionListView = new SessionListView({collection: this.paginatedSessions});
		this.chatView = new ChatLayout({messages:messages, users:users});
		this.youtubeEmbedView = new VideoEmbedView({model:curEvent});
		this.dialogView = new DialogView();

		// this.top.show(this.sessionListView);
		this.right.show(this.chatView);
		this.main.show(this.sessionListView);
		this.dialogs.show(this.dialogView);

		// this is a little unorthodox, but not sure how else
		// to do it.
		$(this.bar.el).hide();

		if(IS_ADMIN) {
			this.adminButtonView = new AdminButtonView();
			this.admin.show(this.adminButtonView);
		}

		console.log("Initialized app.");
	});

	var interval = 0;
	var messageShown = false ;
	var windowBlurred = false ;
	var isIntervalRunning = false;

	app.vent.on("new-chat-message", _.bind(function() {
		if(windowBlurred)
			messageShown = false ;
		else
			messageShown = true ;

		if(!messageShown && isIntervalRunning && windowBlurred)
			interval = window.setTimeout(showFlashTitle, 1000);

	}, app));

	window.onblur = _.bind(function() {
		isIntervalRunning = true ;
		windowBlurred = true ;
		messageShown = true ;
	} , app);

	window.onfocus = _.bind(function() {
		isIntervalRunning = false;
		windowBlurred = false;
		messageShown = false ;
		clearInterval(interval);
		window.document.title = 'Unhangout';
	} , app);

	function showFlashTitle() {
		if(isIntervalRunning && !messageShown) {
			if(window.document.title == 'Unhangout')
				window.document.title = 'New Message ...';
			else
				window.document.title = 'Unhangout';

			interval = window.setTimeout(showFlashTitle, 1000);
		}
	}

	app.vent.on("sessions-nav", _.bind(function() {
		this.main.show(this.sessionListView);
	}, app));

	var videoShown = false;
	app.vent.on("video-nav", _.bind(function() {
		console.log("handling video-nav event");

		// regardless of whether there's a current embed, hide the video if
		// it's currently showon.
		if(videoShown) {
			this.top.$el.css("z-index", -10);

			this.top.reset();
			videoShown = false;

			this.main.$el.css("top", 0);
			this.sessionListView.updateDisplay();
			$("#video-nav").removeClass("active");
		} else if(curEvent.hasEmbed()) {
			$(".nav .active").removeClass("active");

			if(!videoShown) {
				this.top.show(this.youtubeEmbedView);
				videoShown = true;

				var mainHeight = this.youtubeEmbedView.$el.outerHeight()-5;

				if(this.main.$el.hasClass("bar")) {
					mainHeight += 40;
				}

				this.main.$el.css("top", mainHeight);
				this.sessionListView.updateDisplay();
				this.top.$el.css("z-index", 50);
				$("#video-nav").addClass("active");
			}
		} else {
			console.log("Ignoring video click; no video available.");
		}

	}, app));

	app.vent.on("youtube-ready", _.bind(function() {
		console.log("YOUTUBE READY");

		if(curEvent.hasEmbed()) {
			app.vent.trigger("video-nav");
		}
	}, app));

	app.vent.on("video-live", _.bind(function() {
		$("#video-nav .label").removeClass("hide");
	}, app));

	app.vent.on("video-off", _.bind(function() {
		$("#video-nav .label").addClass("hide");
	}, app));

	app.vent.on("show-bar", _.bind(function(sessionKey) {

		this.bar.show(new SessionLiveView());
		$(this.bar.el).show();

		$("#top-left, #main-right, #main-left").addClass("bar");

		// set the hangout link.
		this.bar.$el.find("a").attr("href", "/session/" + sessionKey);

		// 30 minutes later hide the bar(?)
		setTimeout(function() {
			app.vent.trigger("hide-bar");
		}, 60*1000*30);
	}, app));

	app.vent.on("hide-bar", _.bind(function() {
		this.bar.close();
		this.bar.$el.hide();

		$("#top-left, #main-right, #main-left").removeClass("bar");

		// we need to do a special check for main-left, which has custom
		// style adjustement on it.
		if(videoShown) {
			this.main.$el.css("top", this.youtubeEmbedView.$el.outerHeight()-5);
		} else {
			this.main.$el.css("top", "");
		}

	}, app));

	var queuedAttend = false;

	app.vent.on("attend", _.bind(function(sessionId) {
		console.log("VENT ATTEND: " + sessionId);
		// we have to manage attend logic here in the single_session_rsvp case so
		// we can send unattend messages first, and then attend messages.

		// if they're the same, just ignore it.
		if(curSession && curSession!=sessionId) {

			queuedAttend = function() {
				var message = {type:"attend", args:{id:sessionId}};
				sock.send(JSON.stringify(message));
			}

			var message = {type:"unattend", args:{id:curSession}};
			sock.send(JSON.stringify(message));
		} else if(!curSession) {
			var message = {type:"attend", args:{id:sessionId}};
			sock.send(JSON.stringify(message));
		}
	}));

	app.start();

	if(curSession) {
		var curSessionObj = curEvent.get("sessions").get(curSession);

		if(curSessionObj.isLive()) {
			app.vent.trigger("show-bar", curSessionObj.get("session-key"));
		}
	}

	if(curEvent.hasEmbed()) {
		app.vent.trigger("video-live");
		// app.vent.trigger("video-nav");
	}

	$("#video-nav").click(function() {
		app.vent.trigger($(this).attr("id"));
	})

	console.log("Setup regions.");

	sock = new SockJS(document.location.protocol + "//" + document.location.hostname + ":" + document.location.port + "/sock");
	sock.onopen = function() {
		console.log('open');

		var AUTH = {type:"auth", args:{key:SOCK_KEY, id:USER_ID}};

		sock.send(JSON.stringify(AUTH));
	};
	sock.onmessage = function(message) {
		console.log(message);
		var msg = JSON.parse(message.data);

		if(msg.type.indexOf("-err")!=-1) {
			console.log("Got an error from the server!");
		}

		switch(msg.type) {
			case "attend":
				curEvent.get("sessions").get(msg.args.id).addAttendee(msg.args.user);
				console.log("added attendee to a session");

				if(SINGLE_SESSION_RSVP && msg.args.user.id==USER_ID) {

					if(!_.isNull(curSession)) {
						var message = {type:"unattend", args:{id:curSession}};
						sock.send(JSON.stringify(message));
					}

					curSession = msg.args.id;
				}
				break;

			case "first-attendee":
				curEvent.get("sessions").get(msg.args.id).setFirstAttendee(msg.args.user);
				console.log("set first attendee");
				break;

			case "unattend"	:
				curEvent.get("sessions").get(msg.args.id).removeAttendee(msg.args.user);
				console.log("removed attendee from a session");

				curSession = null;

				if(queuedAttend) {
					queuedAttend.call();
					queuedAttend = false;
				}

				break;

			case "join":
				console.log("join: " + JSON.stringify(msg.args));
				users.add(new models.User(msg.args.user));
				break;

			case "leave":
				users.remove(users.get(msg.args.user.id));
				break;

			case "chat":
				messages.add(new models.ChatMessage(msg.args));
				app.vent.trigger("new-chat-message");

				break;

			case "embed":
				var originalYoutubeId = curEvent.get("youtubeEmbed") || "";

				curEvent.setEmbed(msg.args.ytId);
				console.log("added yt embed id: " + JSON.stringify(msg.args));

				if(msg.args.ytId.length > 0) {
					// if it's a non-empty yt embed, show the live tag.
					app.vent.trigger("video-live");

					if(originalYoutubeId.length==0) {
						app.vent.trigger("video-nav");
					}
				} else {
					// if it's empty, hide the live tag.
					app.vent.trigger("video-off");
					app.vent.trigger("video-nav");
				}

				break;

			case "start":
				// this is a little wacky, but we want to give people who RSVP'd a chance to join first.
				// so we're going to do two things here:
				// 1) if not rsvp, delay triggering start and setting the session key.
				// 2) if not rsvp, supress the dialog popup
				var session = curEvent.get("sessions").get(msg.args.id);

				var timeout = 0;

				if(!(session.isAttending(USER_ID))) {
					timeout = 60*1000;
				}

				setTimeout(function() {
					session.set("session-key", msg.args.key);
					session.start();
				}, timeout);

				app.vent.trigger("show-bar", msg.args.key);

				break;
			case "stop":
				var session = curEvent.get("sessions").get(msg.args.id);
				session.stop();

				if(session.id==curSession) {
					app.vent.trigger("hide-bar");
				}

				break;
			case "auth-ack":
				sock.send(JSON.stringify({type:"join", args:{id:curEvent.id}}));
				break;

			case "embed-ack":
				$("#embed-modal").modal('hide');
				break;

			case "join-ack":
				console.log("joined!");
				break;

			case "attend-ack":
				console.log("attend-ack");
				break;
		}
	};

	sock.onclose = function() {
		$('#disconnected-modal').modal('show');
		messages.add(new models.ChatMessage({text:"You have been disconnected from the server. Please reload the page to reconnect!", user:{displayName:"SERVER"}}));
		console.log('close');
	};
});
<|endoftext|>