<commit_before>// Model for this = _kiwi.model.PanelList
_kiwi.view.Tabs = Backbone.View.extend({
    tagName: 'ul',
    className: 'panellist',

    events: {
        'click li': 'tabClick',
        'click li .part': 'partClick'
    },

    initialize: function () {
        this.model.on("add", this.panelAdded, this);
        this.model.on("remove", this.panelRemoved, this);
        this.model.on("reset", this.render, this);

        this.model.on('active', this.panelActive, this);

        // Network tabs start with a server, so determine what we are now
        this.is_network = false;

        if (this.model.network) {
            this.is_network = true;

            this.model.network.on('change:name', function (network, new_val) {
                $('span', this.model.server.tab).text(new_val);
            }, this);

            this.model.network.on('change:connection_id', function (network, new_val) {
                this.model.forEach(function(panel) {
                    panel.tab.data('connection_id', new_val);
                });
            }, this);
        }
    },

    render: function () {
        var that = this;

        this.$el.empty();

        if (this.is_network) {
            // Add the server tab first
            this.model.server.tab
                .data('panel', this.model.server)
                .data('connection_id', this.model.network.get('connection_id'))
                .appendTo(this.$el);
        }

        // Go through each panel adding its tab
        this.model.forEach(function (panel) {
            // If this is the server panel, ignore as it's already added
            if (this.is_network && panel == that.model.server)
                return;

            panel.tab.data('panel', panel);

            if (this.is_network)
                panel.tab.data('connection_id', this.model.network.get('connection_id'));

            panel.tab.appendTo(that.$el);
        });

        _kiwi.app.view.doLayout();
    },

    updateTabTitle: function (panel, new_title) {
        $('span', panel.tab).text(new_title);
    },

    panelAdded: function (panel) {
        // Add a tab to the panel
        panel.tab = $('
' + (panel.get('title') || panel.get('name')) + '

');

        if (panel.isServer()) {
            panel.tab.addClass('server');
            panel.tab.addClass('fa');
            panel.tab.addClass('fa-nonexistant');
        }

        panel.tab.data('panel', panel);

        if (this.is_network)
            panel.tab.data('connection_id', this.model.network.get('connection_id'));

        this.sortTabs();

        panel.bind('change:title', this.updateTabTitle);
        panel.bind('change:name', this.updateTabTitle);

        _kiwi.app.view.doLayout();
    },
    panelRemoved: function (panel) {
        var connection = _kiwi.app.connections.active_connection;

        panel.tab.remove();
        delete panel.tab;

        _kiwi.app.panels.trigger('remove', panel);

        _kiwi.app.view.doLayout();
    },

    panelActive: function (panel, previously_active_panel) {
        // Remove any existing tabs or part images
        _kiwi.app.view.$el.find('.panellist .part').remove();
        _kiwi.app.view.$el.find('.panellist .active').removeClass('active');

        panel.tab.addClass('active');

        panel.tab.append('');
    },

    tabClick: function (e) {
        var tab = $(e.currentTarget);

        var panel = tab.data('panel');
        if (!panel) {
            // A panel wasn't found for this tab... wadda fuck
            return;
        }

        panel.view.show();
    },

    partClick: function (e) {
        var tab = $(e.currentTarget).parent();
        var panel = tab.data('panel');

        if (!panel) return;

        // If the nicklist is empty, we haven't joined the channel as yet
        // If we part a server, then we need to disconnect from server, close channel tabs,
        // then close server tab
        if (panel.isChannel() && panel.get('members').models.length > 0) {
            this.model.network.gateway.part(panel.get('name'));
        } else if(panel.isServer()) {
            this.model.network.gateway.quit("Leaving");
            _kiwi.app.connections.remove(this.model.network);
        } else {
            panel.close();
        }
    },

    sortTabs: function() {
        var that = this,
            panels = [];

        this.model.forEach(function (panel) {
            // Ignore the server tab, so all others get added after it
            if (that.is_network && panel == that.model.server)
                return;

            panels.push([panel.get('title') || panel.get('name'), panel]);
        });

        // Sort by the panel name..
        panels.sort(function(a, b) {
            if (a[0].toLowerCase() > b[0].toLowerCase()) {
                return 1;
            } else if (a[0].toLowerCase() < b[0].toLowerCase()) {
                return -1;
            } else {
                return 0;
            }
        });

        // And add them all back in order.
        _.each(panels, function(panel) {
            panel[1].tab.appendTo(that.$el);
        });
    }
});<commit_msg>Redirect client to homepage if last connection closed<commit_after>// Model for this = _kiwi.model.PanelList
_kiwi.view.Tabs = Backbone.View.extend({
    tagName: 'ul',
    className: 'panellist',

    events: {
        'click li': 'tabClick',
        'click li .part': 'partClick'
    },

    initialize: function () {
        this.model.on("add", this.panelAdded, this);
        this.model.on("remove", this.panelRemoved, this);
        this.model.on("reset", this.render, this);

        this.model.on('active', this.panelActive, this);

        // Network tabs start with a server, so determine what we are now
        this.is_network = false;

        if (this.model.network) {
            this.is_network = true;

            this.model.network.on('change:name', function (network, new_val) {
                $('span', this.model.server.tab).text(new_val);
            }, this);

            this.model.network.on('change:connection_id', function (network, new_val) {
                this.model.forEach(function(panel) {
                    panel.tab.data('connection_id', new_val);
                });
            }, this);
        }
    },

    render: function () {
        var that = this;

        this.$el.empty();

        if (this.is_network) {
            // Add the server tab first
            this.model.server.tab
                .data('panel', this.model.server)
                .data('connection_id', this.model.network.get('connection_id'))
                .appendTo(this.$el);
        }

        // Go through each panel adding its tab
        this.model.forEach(function (panel) {
            // If this is the server panel, ignore as it's already added
            if (this.is_network && panel == that.model.server)
                return;

            panel.tab.data('panel', panel);

            if (this.is_network)
                panel.tab.data('connection_id', this.model.network.get('connection_id'));

            panel.tab.appendTo(that.$el);
        });

        _kiwi.app.view.doLayout();
    },

    updateTabTitle: function (panel, new_title) {
        $('span', panel.tab).text(new_title);
    },

    panelAdded: function (panel) {
        // Add a tab to the panel
        panel.tab = $('
' + (panel.get('title') || panel.get('name')) + '

');

        if (panel.isServer()) {
            panel.tab.addClass('server');
            panel.tab.addClass('fa');
            panel.tab.addClass('fa-nonexistant');
        }

        panel.tab.data('panel', panel);

        if (this.is_network)
            panel.tab.data('connection_id', this.model.network.get('connection_id'));

        this.sortTabs();

        panel.bind('change:title', this.updateTabTitle);
        panel.bind('change:name', this.updateTabTitle);

        _kiwi.app.view.doLayout();
    },
    panelRemoved: function (panel) {
        var connection = _kiwi.app.connections.active_connection;

        panel.tab.remove();
        delete panel.tab;

        _kiwi.app.panels.trigger('remove', panel);

        _kiwi.app.view.doLayout();
    },

    panelActive: function (panel, previously_active_panel) {
        // Remove any existing tabs or part images
        _kiwi.app.view.$el.find('.panellist .part').remove();
        _kiwi.app.view.$el.find('.panellist .active').removeClass('active');

        panel.tab.addClass('active');

        panel.tab.append('');
    },

    tabClick: function (e) {
        var tab = $(e.currentTarget);

        var panel = tab.data('panel');
        if (!panel) {
            // A panel wasn't found for this tab... wadda fuck
            return;
        }

        panel.view.show();
    },

    partClick: function (e) {
        var tab = $(e.currentTarget).parent();
        var panel = tab.data('panel');

        if (!panel) return;

        // If the nicklist is empty, we haven't joined the channel as yet
        // If we part a server, then we need to disconnect from server, close channel tabs,
        // close server tab, then bring client back to homepage
        if (panel.isChannel() && panel.get('members').models.length > 0) {
            this.model.network.gateway.part(panel.get('name'));
        } else if(panel.isServer()) {
            this.model.network.gateway.quit("Leaving");
            _kiwi.app.connections.remove(this.model.network);
            if(_kiwi.app.connections.length < 1) {
                window.location.reload(true);
            }
        } else {
            panel.close();
        }
    },

    sortTabs: function() {
        var that = this,
            panels = [];

        this.model.forEach(function (panel) {
            // Ignore the server tab, so all others get added after it
            if (that.is_network && panel == that.model.server)
                return;

            panels.push([panel.get('title') || panel.get('name'), panel]);
        });

        // Sort by the panel name..
        panels.sort(function(a, b) {
            if (a[0].toLowerCase() > b[0].toLowerCase()) {
                return 1;
            } else if (a[0].toLowerCase() < b[0].toLowerCase()) {
                return -1;
            } else {
                return 0;
            }
        });

        // And add them all back in order.
        _.each(panels, function(panel) {
            panel[1].tab.appendTo(that.$el);
        });
    }
});<|endoftext|>


<commit_before>var basicScraper = require('./basicScraperController');
var getExternalUrl = require('./urlController').getExternalUrl;
var CronJob = require('cron').CronJob;
var secret = require('../../config.js');
var db = require('../db.js');
var Sequelize = require('sequelize');
var compare = require('../imgCompare.js').compare;
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
    service: 'mailgun',
    auth: secret.auth
});

// var CronJob = require('cron').CronJob;

module.exports = {
  newCron: function(UserUrl) {
    console.log('we have a new cron!', UserUrl)
    var freq = '* * */' + UserUrl.frequency + '* * *';

    var job = new CronJob({
      cronTime: freq,
      onTick: function() {
                  console.log('checking', UserUrl.url, 'for changes');
        //            var oldImg = UserUrl.cropImage;
        //            var email = url[j].UserUrl.email;
        //            var website = url[j].url
        //            var params = {
        //             h: url[j].UserUrl.cropHeight,
        //             w: url[j].UserUrl.cropWidth,
        //             x: url[j].UserUrl.cropOriginX,
        //             y: url[j].UserUrl.cropOriginY
        //           }

        //           // get the server to render the page with params coordinates
        //           basicScraper.getScreenshot(url[j].url, url[j].id, function(img1, email) {
        //             basicScraper.cropImg(img1, params, true, function(newImg) {
        //               console.log('old image path', oldImg);
        //               console.log('new image path', newImg);

        //               compare(oldImg, newImg, function (equal){

        //                 if (!equal){

        //                   console.log('change detected on', website, 'sending email to ', email);

        //                   var mailOptions = {
        //                       from: "The Blank Arrays <postmaster@sandbox72a87403dd654630bfa3c4b021cda08d.mailgun.org>", // sender address
        //                       // currently accessing only one user email
        //                       to: email, // list of receivers
        //                       subject: 'We found some tubular changes!', // Subject line
        //                       text: 'Hi there! It looks like we found a change on '+ website + '!', // plaintext body
        //                       html: "The Scrapinit team found a change on " + website +"!",
        //                           // html: 'Hello world ' // html body
        //                   };

        //                   // Send email function
        //                   transporter.sendMail(mailOptions, function(error, info){
        //                       if(error){
        //                           console.log(error);
        //                       }else{
        //                           console.log('Message sent: ' + info.response);
        //                       } //  else statemenet
        //                   }); //  transporter.sendMail(mailOptions, function(error, info){
        //                 }; // if (!equal){
        //               }) // compare(img1, img2, function (equal){
        //             }); // basicScraper.cropImg(img1, params, true, function(img2) {
        // }, email); // basicScraper.getScreenshot()
      },
      start: false,
      timeZone: "America/Los_Angeles"
    });
    job.start();

  }
}

// for faster testing
// var schedule = '*/30 * * * * *';

//To run every 3 seconds do */3; every 5 min do * */5 *
// var schedule = '*/5 * * * * *';

<commit_msg>[Feat] addCron runs a cronjob when called<commit_after>var basicScraper = require('./basicScraperController');
var getExternalUrl = require('./urlController').getExternalUrl;
var CronJob = require('cron').CronJob;
var secret = require('../../config.js');
var db = require('../db.js');
var Sequelize = require('sequelize');
var compare = require('../imgCompare.js').compare;
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
    service: 'mailgun',
    auth: secret.auth
});

// var CronJob = require('cron').CronJob;

module.exports = {
  addCron: function(UserUrl, url) {
    var userUrl = UserUrl;
    // minutes
    var freq = '* */' + UserUrl.frequency + ' * * * *';
    // seconds
    // var freq = '*/' + UserUrl.frequency + ' * * * * *';
    var job = new CronJob({
      cronTime: freq,
      onTick: function() {
        console.log('checking', url, 'for changes');
         var oldImg = UserUrl.cropImage;
         var email = UserUrl.email;
         var website = url
         var params = {
          h: UserUrl.cropHeight,
          w: UserUrl.cropWidth,
          x: UserUrl.cropOriginX,
          y: UserUrl.cropOriginY
        }

        // get the server to render the page with params coordinates
        basicScraper.getScreenshot(website, UserUrl.user_id, function(img1, email) {
          basicScraper.cropImg(img1, params, true, function(newImg) {
            console.log('old image path', oldImg);
            console.log('new image path', newImg);

            compare(oldImg, newImg, function (equal){

              if (!equal){

                console.log('change detected on', website, 'sending email to ', email);

                var mailOptions = {
                    from: "The Blank Arrays <postmaster@sandbox72a87403dd654630bfa3c4b021cda08d.mailgun.org>", // sender address
                    // currently accessing only one user email
                    to: email, // list of receivers
                    subject: 'We found some tubular changes!', // Subject line
                    text: 'Hi there! It looks like we found a change on '+ website + '!', // plaintext body
                    html: "The Scrapinit team found a change on " + website +"!",
                        // html: 'Hello world ' // html body
                };

                // Send email function
                transporter.sendMail(mailOptions, function(error, info){
                    if(error){
                        console.log(error);
                    }else{
                        console.log('Message sent: ' + info.response);
                    } //  else statemenet
                }); //  transporter.sendMail(mailOptions, function(error, info){
              }; // if (!equal){
            }) // compare(img1, img2, function (equal){
          }); // basicScraper.cropImg(img1, params, true, function(img2) {
        }, email); // basicScraper.getScreenshot()
      },
      start: false,
      timeZone: "America/Los_Angeles"
    });
    job.start(UserUrl);
  }
}

<|endoftext|>


<commit_before>import flow from 'lodash/flow';
import { decodeFcc } from '../../common/utils/encode-decode';

const queryRegex = /^(\?|#\?)/;
export function legacyIsInQuery(query, decode) {
  let decoded;
  try {
    decoded = decode(query);
  } catch (err) {
    return false;
  }
  if (!decoded || typeof decoded.split !== 'function') {
    return false;
  }
  return decoded
    .replace(queryRegex, '')
    .split('&')
    .reduce(function(found, param) {
      var key = param.split('=')[0];
      if (key === 'solution') {
        return true;
      }
      return found;
    }, false);
}

export function getKeyInQuery(query, keyToFind = '') {
  return query
    .split('&')
    .reduce((oldValue, param) => {
      const key = param.split('=')[0];
      const value = param
        .split('=')
        .slice(1)
        .join('=');

      if (key === keyToFind) {
        return value;
      }
      return oldValue;
    }, null);
}

export function getLegacySolutionFromQuery(query = '', decode) {
  return flow(
    getKeyInQuery,
    decode,
    decodeFcc
  )(query, 'solution');
}

export function getCodeUri(location, decodeURIComponent) {
  let query;
  if (
    location.search &&
    legacyIsInQuery(location.search, decodeURIComponent)
  ) {
    query = location.search.replace(/^\?/, '');
  } else {
    return null;
  }

  return getLegacySolutionFromQuery(query, decodeURIComponent);
}

export function removeCodeUri(location, history) {
  if (
    typeof location.search.split !== 'function' ||
    typeof history.replaceState !== 'function'
  ) {
    return false;
  }
  history.replaceState(
    history.state,
    null,
    location.search.split('?')[0]
  );
  return true;
}
<commit_msg>Fix(code-uri): use href instead of search to remove code uri<commit_after>import flow from 'lodash/flow';
import { decodeFcc } from '../../common/utils/encode-decode';

const queryRegex = /^(\?|#\?)/;
export function legacyIsInQuery(query, decode) {
  let decoded;
  try {
    decoded = decode(query);
  } catch (err) {
    return false;
  }
  if (!decoded || typeof decoded.split !== 'function') {
    return false;
  }
  return decoded
    .replace(queryRegex, '')
    .split('&')
    .reduce(function(found, param) {
      var key = param.split('=')[0];
      if (key === 'solution') {
        return true;
      }
      return found;
    }, false);
}

export function getKeyInQuery(query, keyToFind = '') {
  return query
    .split('&')
    .reduce((oldValue, param) => {
      const key = param.split('=')[0];
      const value = param
        .split('=')
        .slice(1)
        .join('=');

      if (key === keyToFind) {
        return value;
      }
      return oldValue;
    }, null);
}

export function getLegacySolutionFromQuery(query = '', decode) {
  return flow(
    getKeyInQuery,
    decode,
    decodeFcc
  )(query, 'solution');
}

export function getCodeUri(location, decodeURIComponent) {
  let query;
  if (
    location.search &&
    legacyIsInQuery(location.search, decodeURIComponent)
  ) {
    query = location.search.replace(/^\?/, '');
  } else {
    return null;
  }

  return getLegacySolutionFromQuery(query, decodeURIComponent);
}

export function removeCodeUri(location, history) {
  if (
    typeof location.href.split !== 'function' ||
    typeof history.replaceState !== 'function'
  ) {
    return false;
  }
  history.replaceState(
    history.state,
    null,
    location.href.split('?')[0]
  );
  return true;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint nomen:true, plusplus:true*/

YUI.add('ShakerPipelineFrameMojit', function (Y, NAME) {
    'use strict';

    var PipelineFrameMojit = Y.mojito.controllers.PipelineFrameMojit;

    // Inherit methods from the PipelineFrameMojit and override
    // to add Shaker specific functionality.
    Y.mojito.controllers[NAME] = Y.merge(PipelineFrameMojit, {
        _init: function (ac) {
            // Serves as a queue, to delay the rendering of postfetch assets
            // until the last flush.
            this.postfetch = {
                js: [],
                css: [],
                blob: []
            };

            PipelineFrameMojit._init.apply(this, arguments);

            if (!ac.pipeline.client.jsEnabled) {
                ac.shaker.set('serveJs', false);
            }

            // Use the shaker htmlData as the view data so that this
            // frame's view data can be manipulated through Shaker's APIs.
            this.view = ac.shaker.data.htmlData;
        },

        _render: function (data, meta, callback) {
            var ac = this.ac;

            // Add top rollups, app resources, and filter assets.
            ac.shaker._addRouteRollups(meta.assets, ['top', 'shakerTop']);
            ac.shaker._addAppResources(meta.assets);
            ac.shaker._filterAndUpdate(meta.assets);

            PipelineFrameMojit._render.apply(this, arguments);
        },

        _processMeta: function (meta) {
            var ac = this.ac,
                postfetch = this.postfetch;

            PipelineFrameMojit._processMeta.apply(this, arguments);

            if (!ac.pipeline.closed) {
                // Queue up postfetch assets such that the are added only on the last flush.
                Y.Object.each(meta.assets.postfetch, function (typeAssets, type) {
                    Array.prototype.push.apply(postfetch[type], typeAssets);
                });

                delete meta.assets.postfetch;
            }
        },

        _addMojitoClient: function (meta) {
            var ac = this.ac,
                binders = this.binders,
                postfetch = this.postfetch;

            if (ac.pipeline.closed) {
                // Add any postfetch assets that has been queued.
                Y.mojito.util.metaMerge(meta.assets, {
                    'postfetch': postfetch
                });

                // Force the mojito client to be place on the bottom.
                ac.shaker.set('serveJs', {
                    position: 'bottom'
                });

                // Add bottom rollups, mojito client runtime, and bootstrap.
                ac.shaker._addRouteRollups(meta.assets, ['bottom']);
                ac.shaker._addYUILoader(meta.assets, binders);
                ac.shaker._addBootstrap(meta.assets);
            }
        },

        _wrapFlushData: function (flushData) {
            // Filter assets before they are wrapped.
            this.ac.shaker._filterAndUpdate(flushData.meta.assets);
            PipelineFrameMojit._wrapFlushData.apply(this, arguments);
        },

        _concatRenderdAssets: function (renderedAsset, renderedAssets, location, type) {
            var ac = this.ac;

            // Add postfetch and assets below shakerTop to the bottom, and the rest to the top
            if (location === 'postfetch' || ac.shaker.PAGE_POSITIONS.indexOf(location) > 2) {
                renderedAssets.bottom  += renderedAsset;
            } else {
                renderedAssets.top += renderedAsset;
            }
        }
    });

}, '0.1.0', {requires: [
    'mojito',
    'mojito-util',
    'mojito-assets-addon',
    'mojito-http-addon',
    'mojito-deploy-addon',
    'mojito-config-addon',
    'mojito-shaker-addon',
    'mojito-pipeline-addon',
    'PipelineFrameMojit'
]});
<commit_msg>Fixed JSLint errors<commit_after>/*
 * Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */

/*jslint nomen:true, plusplus:true */
/*global YUI */

YUI.add('ShakerPipelineFrameMojit', function (Y, NAME) {
    'use strict';

    var PipelineFrameMojit = Y.mojito.controllers.PipelineFrameMojit;

    // Inherit methods from the PipelineFrameMojit and override
    // to add Shaker specific functionality.
    Y.mojito.controllers[NAME] = Y.merge(PipelineFrameMojit, {

        _init: function (ac) {
            // Serves as a queue, to delay the rendering of postfetch assets
            // until the last flush.
            this.postfetch = {
                js: [],
                css: [],
                blob: []
            };

            PipelineFrameMojit._init.apply(this, arguments);

            if (!ac.pipeline.client.jsEnabled) {
                ac.shaker.set('serveJs', false);
            }

            // Use the shaker htmlData as the view data so that this
            // frame's view data can be manipulated through Shaker's APIs.
            this.view = ac.shaker.data.htmlData;
        },

        _render: function (data, meta, callback) {
            var ac = this.ac;

            // Add top rollups, app resources, and filter assets.
            ac.shaker._addRouteRollups(meta.assets, ['top', 'shakerTop']);
            ac.shaker._addAppResources(meta.assets);
            ac.shaker._filterAndUpdate(meta.assets);

            PipelineFrameMojit._render.apply(this, arguments);
        },

        _processMeta: function (meta) {
            var ac = this.ac,
                postfetch = this.postfetch;

            PipelineFrameMojit._processMeta.apply(this, arguments);

            if (!ac.pipeline.closed) {
                // Queue up postfetch assets such that the are added only on the last flush.
                Y.Object.each(meta.assets.postfetch, function (typeAssets, type) {
                    Array.prototype.push.apply(postfetch[type], typeAssets);
                });

                delete meta.assets.postfetch;
            }
        },

        _addMojitoClient: function (meta) {
            var ac = this.ac,
                binders = this.binders,
                postfetch = this.postfetch;

            if (ac.pipeline.closed) {
                // Add any postfetch assets that has been queued.
                Y.mojito.util.metaMerge(meta.assets, {
                    'postfetch': postfetch
                });

                // Force the mojito client to be place on the bottom.
                ac.shaker.set('serveJs', {
                    position: 'bottom'
                });

                // Add bottom rollups, mojito client runtime, and bootstrap.
                ac.shaker._addRouteRollups(meta.assets, ['bottom']);
                ac.shaker._addYUILoader(meta.assets, binders);
                ac.shaker._addBootstrap(meta.assets);
            }
        },

        _wrapFlushData: function (flushData) {
            // Filter assets before they are wrapped.
            this.ac.shaker._filterAndUpdate(flushData.meta.assets);
            PipelineFrameMojit._wrapFlushData.apply(this, arguments);
        },

        _concatRenderdAssets: function (renderedAsset, renderedAssets, location, type) {
            var ac = this.ac;

            // Add postfetch and assets below shakerTop to the bottom, and the rest to the top
            if (location === 'postfetch' || ac.shaker.PAGE_POSITIONS.indexOf(location) > 2) {
                renderedAssets.bottom  += renderedAsset;
            } else {
                renderedAssets.top += renderedAsset;
            }
        }
    });

}, '0.1.0', {
    requires: [
        'mojito',
        'mojito-util',
        'mojito-assets-addon',
        'mojito-http-addon',
        'mojito-deploy-addon',
        'mojito-config-addon',
        'mojito-shaker-addon',
        'mojito-pipeline-addon',
        'PipelineFrameMojit'
    ]
});
<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /!\ DO NOT MODIFY THIS FILE /!\
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// react-native-cli is installed globally on people's computers. This means
// that it is extremely difficult to have them upgrade the version and
// because there's only one global version installed, it is very prone to
// breaking changes.
//
// The only job of react-native-cli is to init the repository and then
// forward all the commands to the local version of react-native.
//
// If you need to add a new command, please add it to local-cli/.
//
// The only reason to modify this file is to add more warnings and
// troubleshooting information for the `react-native init` command.
//
// Do not make breaking changes! We absolutely don't want to have to
// tell people to update their global version of react-native-cli.
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /!\ DO NOT MODIFY THIS FILE /!\
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

'use strict';

var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
var chalk = require('chalk');
var prompt = require('prompt');
var semver = require('semver');

var CLI_MODULE_PATH = function() {
  return path.resolve(
    process.cwd(),
    'node_modules',
    'react-native',
    'cli.js'
  );
};

var REACT_NATIVE_PACKAGE_JSON_PATH = function() {
  return path.resolve(
    process.cwd(),
    'node_modules',
    'react-native',
    'package.json'
  );
};

checkForVersionArgument();

var cli;
var cliPath = CLI_MODULE_PATH();
if (fs.existsSync(cliPath)) {
  cli = require(cliPath);
}

if (cli) {
  cli.run();
} else {
  var args = process.argv.slice(2);
  if (args.length === 0) {
    console.error(
      'You did not pass any commands, did you mean to run `react-native init`?'
    );
    process.exit(1);
  }

  switch (args[0]) {
  case 'init':
    if (args[1]) {
      var verbose = process.argv.indexOf('--verbose') >= 0;
      init(args[1], verbose);
    } else {
      console.error(
        'Usage: react-native init <ProjectName> [--verbose]'
      );
      process.exit(1);
    }
    break;
  default:
    console.error(
      'Command `%s` unrecognized. ' +
      'Did you mean to run this inside a react-native project?',
      args[0]
    );
    process.exit(1);
    break;
  }
}

function validatePackageName(name) {
  if (!name.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
    console.error(
      '"%s" is not a valid name for a project. Please use a valid identifier ' +
        'name (alphanumeric).',
      name
    );
    process.exit(1);
  }

  if (name === 'React') {
    console.error(
      '"%s" is not a valid name for a project. Please do not use the ' +
        'reserved word "React".',
      name
    );
    process.exit(1);
  }
}

function init(name, verbose) {
  validatePackageName(name);

  if (fs.existsSync(name)) {
    createAfterConfirmation(name, verbose);
  } else {
    createProject(name, verbose);
  }
}

function createAfterConfirmation(name, verbose) {
  prompt.start();

  var property = {
    name: 'yesno',
    message: 'Directory ' + name + ' already exist. Continue?',
    validator: /y[es]*|n[o]?/,
    warning: 'Must respond yes or no',
    default: 'no'
  };

  prompt.get(property, function (err, result) {
    if (result.yesno[0] === 'y') {
      createProject(name, verbose);
    } else {
      console.log('Project initialization canceled');
      process.exit();
    }
  });
}

function createProject(name, verbose) {
  var root = path.resolve(name);
  var projectName = path.basename(root);

  console.log(
    'This will walk you through creating a new React Native project in',
    root
  );

  if (!fs.existsSync(root)) {
    fs.mkdirSync(root);
  }

  var packageJson = {
    name: projectName,
    version: '0.0.1',
    private: true,
    scripts: {
      start: 'react-native start'
    }
  };
  fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson));
  process.chdir(root);

  console.log('Installing react-native package from npm...');

  if (verbose) {
    runVerbose(root, projectName);
  } else {
    run(root, projectName);
  }
}

function run(root, projectName) {
  exec('npm install --save react-native', function(e, stdout, stderr) {
    if (e) {
      console.log(stdout);
      console.error(stderr);
      console.error('`npm install --save react-native` failed');
      process.exit(1);
    }

    checkNodeVersion();

    var cli = require(CLI_MODULE_PATH());
    cli.init(root, projectName);
  });
}

function runVerbose(root, projectName) {
  var proc = spawn('npm', ['install', '--verbose', '--save', 'react-native'], {stdio: 'inherit'});
  proc.on('close', function (code) {
    if (code !== 0) {
      console.error('`npm install --save react-native` failed');
      return;
    }

    cli = require(CLI_MODULE_PATH());
    cli.init(root, projectName);
  });
}

function checkNodeVersion() {
  var packageJson = require(REACT_NATIVE_PACKAGE_JSON_PATH());
  if (!packageJson.engines || !packageJson.engines.node) {
    return;
  }
  if (!semver.satisfies(process.version, packageJson.engines.node)) {
    console.error(chalk.red(
        'You are currently running Node %s but React Native requires %s. ' +
        'Please use a supported version of Node.\n' +
        'See https://facebook.github.io/react-native/docs/getting-started.html'
      ),
      process.version,
      packageJson.engines.node);
  }
}

function checkForVersionArgument() {
  if (process.argv.indexOf('-v') >= 0 || process.argv.indexOf('--version') >= 0) {
    var pjson = require('./package.json');
    console.log(pjson.version);
    process.exit();
  }
}
<commit_msg>Fix typo<commit_after>#!/usr/bin/env node

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /!\ DO NOT MODIFY THIS FILE /!\
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// react-native-cli is installed globally on people's computers. This means
// that it is extremely difficult to have them upgrade the version and
// because there's only one global version installed, it is very prone to
// breaking changes.
//
// The only job of react-native-cli is to init the repository and then
// forward all the commands to the local version of react-native.
//
// If you need to add a new command, please add it to local-cli/.
//
// The only reason to modify this file is to add more warnings and
// troubleshooting information for the `react-native init` command.
//
// Do not make breaking changes! We absolutely don't want to have to
// tell people to update their global version of react-native-cli.
//
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// /!\ DO NOT MODIFY THIS FILE /!\
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

'use strict';

var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
var chalk = require('chalk');
var prompt = require('prompt');
var semver = require('semver');

var CLI_MODULE_PATH = function() {
  return path.resolve(
    process.cwd(),
    'node_modules',
    'react-native',
    'cli.js'
  );
};

var REACT_NATIVE_PACKAGE_JSON_PATH = function() {
  return path.resolve(
    process.cwd(),
    'node_modules',
    'react-native',
    'package.json'
  );
};

checkForVersionArgument();

var cli;
var cliPath = CLI_MODULE_PATH();
if (fs.existsSync(cliPath)) {
  cli = require(cliPath);
}

if (cli) {
  cli.run();
} else {
  var args = process.argv.slice(2);
  if (args.length === 0) {
    console.error(
      'You did not pass any commands, did you mean to run `react-native init`?'
    );
    process.exit(1);
  }

  switch (args[0]) {
  case 'init':
    if (args[1]) {
      var verbose = process.argv.indexOf('--verbose') >= 0;
      init(args[1], verbose);
    } else {
      console.error(
        'Usage: react-native init <ProjectName> [--verbose]'
      );
      process.exit(1);
    }
    break;
  default:
    console.error(
      'Command `%s` unrecognized. ' +
      'Did you mean to run this inside a react-native project?',
      args[0]
    );
    process.exit(1);
    break;
  }
}

function validatePackageName(name) {
  if (!name.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
    console.error(
      '"%s" is not a valid name for a project. Please use a valid identifier ' +
        'name (alphanumeric).',
      name
    );
    process.exit(1);
  }

  if (name === 'React') {
    console.error(
      '"%s" is not a valid name for a project. Please do not use the ' +
        'reserved word "React".',
      name
    );
    process.exit(1);
  }
}

function init(name, verbose) {
  validatePackageName(name);

  if (fs.existsSync(name)) {
    createAfterConfirmation(name, verbose);
  } else {
    createProject(name, verbose);
  }
}

function createAfterConfirmation(name, verbose) {
  prompt.start();

  var property = {
    name: 'yesno',
    message: 'Directory ' + name + ' already exists. Continue?',
    validator: /y[es]*|n[o]?/,
    warning: 'Must respond yes or no',
    default: 'no'
  };

  prompt.get(property, function (err, result) {
    if (result.yesno[0] === 'y') {
      createProject(name, verbose);
    } else {
      console.log('Project initialization canceled');
      process.exit();
    }
  });
}

function createProject(name, verbose) {
  var root = path.resolve(name);
  var projectName = path.basename(root);

  console.log(
    'This will walk you through creating a new React Native project in',
    root
  );

  if (!fs.existsSync(root)) {
    fs.mkdirSync(root);
  }

  var packageJson = {
    name: projectName,
    version: '0.0.1',
    private: true,
    scripts: {
      start: 'react-native start'
    }
  };
  fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson));
  process.chdir(root);

  console.log('Installing react-native package from npm...');

  if (verbose) {
    runVerbose(root, projectName);
  } else {
    run(root, projectName);
  }
}

function run(root, projectName) {
  exec('npm install --save react-native', function(e, stdout, stderr) {
    if (e) {
      console.log(stdout);
      console.error(stderr);
      console.error('`npm install --save react-native` failed');
      process.exit(1);
    }

    checkNodeVersion();

    var cli = require(CLI_MODULE_PATH());
    cli.init(root, projectName);
  });
}

function runVerbose(root, projectName) {
  var proc = spawn('npm', ['install', '--verbose', '--save', 'react-native'], {stdio: 'inherit'});
  proc.on('close', function (code) {
    if (code !== 0) {
      console.error('`npm install --save react-native` failed');
      return;
    }

    cli = require(CLI_MODULE_PATH());
    cli.init(root, projectName);
  });
}

function checkNodeVersion() {
  var packageJson = require(REACT_NATIVE_PACKAGE_JSON_PATH());
  if (!packageJson.engines || !packageJson.engines.node) {
    return;
  }
  if (!semver.satisfies(process.version, packageJson.engines.node)) {
    console.error(chalk.red(
        'You are currently running Node %s but React Native requires %s. ' +
        'Please use a supported version of Node.\n' +
        'See https://facebook.github.io/react-native/docs/getting-started.html'
      ),
      process.version,
      packageJson.engines.node);
  }
}

function checkForVersionArgument() {
  if (process.argv.indexOf('-v') >= 0 || process.argv.indexOf('--version') >= 0) {
    var pjson = require('./package.json');
    console.log(pjson.version);
    process.exit();
  }
}
<|endoftext|>


<commit_before>backupApp.directive('notificationArea', function() {
  return {
    restrict: 'E',
    templateUrl: 'templates/notificationarea.html',
    controller: function($scope, $location, $timeout, NotificationService, ServerStatus, AppService, AppUtils, DialogService) {
    	$scope.Notifications = NotificationService.watch($scope);
        $scope.state = ServerStatus.watch($scope);

        $scope.doDismiss = function(id) {
            AppService.delete('/notification/' + id).then(
                function() { }, // Don't care, the message will be removed
                function(resp) {
                    // Most likely there was a sync problem, so attempt to reload
                    NotificationService.refresh_notifications();
                }
            );
        };

        $scope.doShowLog = function(backupid) {
            AppService.get('/backup/' + backupid + '/isactive').then(
                function() {
                    $location.path('/log/' + backupid);
                },

                function(resp) {

                    if (resp.status == 404) {
                        if ((parseInt(backupid) + '') != backupid)
                            DialogService.dialog('Error', 'The backup was temporary and does not exist anymore, so the log data is lost');
                        else
                            DialogService.dialog('Error', 'The backup is missing, has it been delete?');
                    } else {
                        AppUtils.connectionError('Failed to find backup: ', resp);
                    }

                }
            );
        };

        $scope.doInstallUpdate = function(id) {
            AppService.post('/updates/install');
        };

        $scope.doActivateUpdate = function(id) {
            AppService.post('/updates/activate').then(function() { $scope.doDismiss(id); }, AppUtils.connectionError('Activate failed: '));
        };

        $scope.doShowUpdate = function(id) {
            $location.path('/updatechangelog');
        };

        $scope.doDownloadBugreport = function(item) {
            var id = item.Action.substr('bug-report:created:'.length);
            item.DownloadLink = $scope.DownloadLink = AppService.get_bugreport_url(id);
        };
    }
  }
});<commit_msg>Fixed a grammar issue<commit_after>backupApp.directive('notificationArea', function() {
  return {
    restrict: 'E',
    templateUrl: 'templates/notificationarea.html',
    controller: function($scope, $location, $timeout, NotificationService, ServerStatus, AppService, AppUtils, DialogService) {
    	$scope.Notifications = NotificationService.watch($scope);
        $scope.state = ServerStatus.watch($scope);

        $scope.doDismiss = function(id) {
            AppService.delete('/notification/' + id).then(
                function() { }, // Don't care, the message will be removed
                function(resp) {
                    // Most likely there was a sync problem, so attempt to reload
                    NotificationService.refresh_notifications();
                }
            );
        };

        $scope.doShowLog = function(backupid) {
            AppService.get('/backup/' + backupid + '/isactive').then(
                function() {
                    $location.path('/log/' + backupid);
                },

                function(resp) {

                    if (resp.status == 404) {
                        if ((parseInt(backupid) + '') != backupid)
                            DialogService.dialog('Error', 'The backup was temporary and does not exist anymore, so the log data is lost');
                        else
                            DialogService.dialog('Error', 'The backup is missing, has it been deleted?');
                    } else {
                        AppUtils.connectionError('Failed to find backup: ', resp);
                    }

                }
            );
        };

        $scope.doInstallUpdate = function(id) {
            AppService.post('/updates/install');
        };

        $scope.doActivateUpdate = function(id) {
            AppService.post('/updates/activate').then(function() { $scope.doDismiss(id); }, AppUtils.connectionError('Activate failed: '));
        };

        $scope.doShowUpdate = function(id) {
            $location.path('/updatechangelog');
        };

        $scope.doDownloadBugreport = function(item) {
            var id = item.Action.substr('bug-report:created:'.length);
            item.DownloadLink = $scope.DownloadLink = AppService.get_bugreport_url(id);
        };
    }
  }
});<|endoftext|>


<commit_before>const app = require('express')();
const Organization = require('../models/Organization');

app.get('/', (req, res) => {
    Organization.find()
        .then(orgs => {
            res.json(orgs);
        });
});
app.get('/:id', (req, res) => {
    if(!req.params.id) return res.sendStatus(400);
    Organization.findOne({ _id: req.params.id })
        .then((org) => {
            if(!org) return res.sendStatus(200);
            res.json(org.toPlainObject())
        });
});
app.post('/organization', (req, res) => {
    if(!req.body.name) return res.sendStatus(400);

    let organization = new Organization({
        name: req.body.name,
        president: req.body.president,
        logo: req.body.logo
    });

    organization.save()
        .then((org) => { res.json(org.toPlainObject()) });
});

module.exports = app;
<commit_msg>Fix post insertion path for organization, better status codes<commit_after>const app = require('express')();
const Organization = require('../models/Organization');

app.get('/', (req, res) => {
    Organization.find()
        .then(orgs => {
            res.json(orgs);
        });
});
app.get('/:id', (req, res) => {
    if(!req.params.id) return res.sendStatus(400);
    Organization.findOne({ _id: req.params.id })
        .then((org) => {
            if(!org) return res.sendStatus(404);
            res.json(org.toPlainObject())
        })
        .catch((err) => res.sendStatus(500));
});
app.post('/', (req, res) => {
    if(!req.body.name) return res.sendStatus(400);

    let organization = new Organization({
        name: req.body.name,
        president: req.body.president,
        logo: req.body.logo
    });

    organization.save()
        .then((org) => { res.json(org.toPlainObject()) });
});

module.exports = app;
<|endoftext|>


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

/* merethis modification for centreon */
var pickRecentProgID = function (idList){
	// found progID flag
    var bFound = false;
    for(var i=0; i < idList.length && !bFound; i++){
        try{
            var oDoc = new ActiveXObject(idList[i]);
            o2Store = idList[i];
            bFound = true;
        }catch (objException){
            // trap; try next progID
        };
    };
    if (!bFound)
		throw ("Aucun ActiveXObject n'est valide sur votre ordinateur, pensez  mettre  jour votre navigateur");
    idList = null;
    return o2Store;
}

// Retourne un nouvel objet XmlHttpRequest
var GetXmlHttpRequest_AXO=null
var GetXmlHttpRequest=function () {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest()
	}
	else if (window.ActiveXObject) {
		if (!GetXmlHttpRequest_AXO) {
			GetXmlHttpRequest_AXO=pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]);
		}
		return new ActiveXObject(GetXmlHttpRequest_AXO)
	}
	return false;
}

/**
 * Properties of this library.
 *
 * @type String
 * @final
 */
var xslt_js = {
    /**
     * The version of this library
     *
     * @type String
     * @final
     */
    revision: 'xslt.js $Revision: 1.5 $'
};

/**
 * Constructor for client-side XSLT transformations.
 *
 * @author Johann Burkard
 * @version $Id: xslt.js,v 1.5 2007/06/23 19:48:30 jburkard Exp $
 * @constructor
 */

function loadXML(url)

      {

        var xmlDoc;

        /* chargement du fichier XML */

        try {

          // navigateur bas sur Gecko

          if (document.implementation && document.implementation.createDocument)

          {

            xmlDoc = document.implementation.createDocument('', '', null);

            xmlDoc.load(url);

          // ActiveX pour Internet Explorer

          } else if (window.ActiveXObject) {

            try {

              xmlDoc = new ActiveXObject('Msxml2.XMLDOM');

            } catch (e) {

              xmlDoc = new ActiveXObject('Microsoft.XMLDOM');

            }

            xmlDoc.async = false;

            xmlDoc.load(url);

          //  l'aide de lobjet XMLHTTPRequest

          } else if (window.XMLHttpRequest) {

            xmlDoc = new XMLHttpRequest();

            xmlDoc.overrideMimeType('text/xml');

            xmlDoc.open('GET', url, false);

            xmlDoc.send(null);

            if (this.xmlDoc.readyState == 4) xmlDoc = xmlDoc.responseXML;

          }

        } catch (e) {

          return e;

        }

        return xmlDoc;

      }

function Transformation() {
var xsltRequest = GetXmlHttpRequest();

    var xml;

    var xmlDoc;

    var xslt;

    var xsltDoc;

    var callback = function() {};

    /**
     * Sort of like a fix for Opera who doesn't always get readyStates right.
     */
    var transformed = false;

    /**
     * Returns the URL of the XML document.
     *
     * @return the URL of the XML document
     * @type String
     */
    this.getXml = function() {
        return xml;
    }

    /**
     * Returns the XML document.
     *
     * @return the XML document
     */
    this.getXmlDocument = function() {
        return xmlDoc
    }

    /**
     * Sets the URL of the XML document.
     *
     * @param x the URL of the XML document
     * @return this
     * @type Transformation
     */
    this.setXml = function(x) {
        xml = x;
        return this;
    }

    /**
     * Returns the URL of the XSLT document.
     *
     * @return the URL of the XSLT document
     * @type String
     */
    this.getXslt = function() {
        return xslt;
    }

    /**
     * Returns the XSLT document.
     *
     * @return the XSLT document
     */
    this.getXsltDocument = function() {
        return xsltDoc;
    }

    /**
     * Sets the URL of the XSLT document.
     *
     * @param x the URL of the XML document
     * @return this
     * @type Transformation
     */
    this.setXslt = function(x) {
        xslt = x;
        return this;
    }

    /**
     * Returns the callback function.
     *
     * @return the callback function
     */
    this.getCallback = function() {
        return callback;
    }

    /**
     * Sets the callback function
     *
     * @param c the callback function
     * @return this
     * @type Transformation
     */
    this.setCallback = function(c) {
        callback = c;
        return this;
    }

    /**
     * Sets the target element to write the transformed content to and asynchronously
     * starts the transformation process.
     *

     * target can be a Node or the ID of an element. 2DO
     *

     * This method may only be called after {@link #setXml} and {@link #setXslt} have
     * been called.
     *

     * Note that the target element must exist once this method is called. Calling
     * this method before onload was fired will most likely
     * not work.
     *
     * @param target the Node or the ID of an element
     */
    this.transform = function(target) {
        if (!browserSupportsXSLT()) {
           return;
        }
        var t = this;

        if (document.recalc) {
            var xmlID = randomID();
            var xsltID = randomID();

            var change = function() {
                var c = 'complete'; // ?loading ?interactive
                var u = 'undefined';
/*
                if (typeof document.all[xmlID] != u && document.all[xmlID].readyState == c &&
                typeof document.all[xsltID] != u && document.all[xsltID].readyState == c) {

*/
                if (typeof document.all[xmlID] != u && document.all[xmlID].readyState != null &&
                typeof document.all[xsltID] != u && document.all[xsltID].readyState != null) {
/*
viewDebugInfo('---->' + document.all[xmlID].readyState);
viewDebugInfo('---->' + document.all[xsltID].readyState);
*/

document.all[target].innerHTML = '';
                    window.setTimeout(function() {
                        xmlDoc = document.all[xmlID].XMLDocument;
                        xsltDoc = document.all[xsltID].XMLDocument;
                        callback(t);

                       document.all[target].innerHTML = document.all[xmlID].transformNode(document.all[xsltID].XMLDocument);
//                        document.all[target].innerHTML = document.all[xmlID].transformNode(document.all[xsltID].XMLDocument);

                    }, 50);
                }
            }

            var xm = document.createElement('xml');
            xm.onreadystatechange = change;
            xm.id = xmlID;
            xm.src = xml;

            var xs = document.createElement('xml');
            xs.onreadystatechange = change;
            xs.id = xsltID;
            xs.src = xslt;

            document.body.insertBefore(xm);
            document.body.insertBefore(xs);
        }
        else {
			/* tradition
			            var xsltRequest = new XMLHttpRequest();
			            var xmlRequest = new XMLHttpRequest();
			*/

			/* legerement plus rapide avec FF*/
            var xmlRequest = GetXmlHttpRequest();

//console.log(xsltRequest);

            var change = function() {

                if (xmlRequest.readyState == 4 && xmlRequest.responseXML && xsltRequest.status == 200 && xsltRequest.readyState == 4 && xsltRequest.statusText == "OK" && xsltRequest.responseText ) {

                    if (transformed) {
                        return;
                    }
                    xsltDoc = xsltRequest.responseXML;
                    xmlDoc = xmlRequest.responseXML;

// responseText
/*
					var xmlstring = xsltRequest.responseText;
                    xsltDoc = ( new DOMParser() ).parseFromString( xmlstring , "text/xml" );
*/
                    var resultDoc;
                    var processor = new XSLTProcessor();

                        document.getElementById(target).innerHTML = '';

/*
                    if (typeof processor.transformToFragment == 'function') {
                        // obsolete Mozilla interface
                        resultDoc = document.implementation.createDocument("", "", null);
						processor.transformDocument(xmlDoc, xsltDoc, resultDoc, null);
                        var out = new XMLSerializer().serializeToString(resultDoc);
                        callback(t);
                        mk_pagination(xmlDoc);

						if(out)
						 document.getElementById(target).innerHTML = out;
                       	set_header_title();

                    }
                    else {*/
                        processor.importStylesheet(xsltDoc);
                        resultDoc = processor.transformToFragment(xmlDoc, document);
                        callback(t);
                       	mk_pagination(xmlDoc);
                        document.getElementById(target).appendChild(resultDoc);
                       	set_header_title();
//                    }
                    transformed = true;
                }
            }

            xmlRequest.open("GET", xml, true);
            xmlRequest.onreadystatechange = change;
            xmlRequest.send(null);

			if(xsltRequest.readyState != 4){
	            xsltRequest.open("GET", xslt);
	            xsltRequest.overrideMimeType("text/xml");
	            xsltRequest.onreadystatechange = change;
	            xsltRequest.send(null);
			}
        }
    }

    /**
     * Generates a random ID.
     *
     * @return a random ID
     */
    function randomID() {
        var out = 'id' + Math.round(Math.random() * 100000);
        return out;
    }

}

/**
 * Returns whether the browser supports XSLT.
 *
 * @return the browser supports XSLT
 * @type boolean
 */
function browserSupportsXSLT() {
    var support = false;
    if (document.recalc) { // IE 5+
        support = true;
    }
    var u = 'undefined';
    if (typeof XMLHttpRequest != u && typeof XSLTProcessor != u) { // Mozilla 0.9.4+, Opera 9+
       var processor = new XSLTProcessor();
       if (typeof processor.transformDocument == 'function') {
           support = typeof XMLSerializer != u;
       }
       else {
           support = true;
       }
    }
    return support;
}
<commit_msg>Solves bug #53 (missing labels in table on IE)<commit_after>/*
 * xslt.js
 *
 * Copyright (c) 2005-2007 Johann Burkard (<mailto:jb@eaio.com>)
 * <http://eaio.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

/* merethis modification for centreon */
var pickRecentProgID = function (idList){
	// found progID flag
    var bFound = false;
    for(var i=0; i < idList.length && !bFound; i++){
        try{
            var oDoc = new ActiveXObject(idList[i]);
            o2Store = idList[i];
            bFound = true;
        }catch (objException){
            // trap; try next progID
        };
    };
    if (!bFound)
		throw ("Aucun ActiveXObject n'est valide sur votre ordinateur, pensez  mettre  jour votre navigateur");
    idList = null;
    return o2Store;
}

// Retourne un nouvel objet XmlHttpRequest
var GetXmlHttpRequest_AXO=null
var GetXmlHttpRequest=function () {
	if (window.XMLHttpRequest) {
		return new XMLHttpRequest()
	}
	else if (window.ActiveXObject) {
		if (!GetXmlHttpRequest_AXO) {
			GetXmlHttpRequest_AXO=pickRecentProgID(["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]);
		}
		return new ActiveXObject(GetXmlHttpRequest_AXO)
	}
	return false;
}

/**
 * Properties of this library.
 *
 * @type String
 * @final
 */
var xslt_js = {
    /**
     * The version of this library
     *
     * @type String
     * @final
     */
    revision: 'xslt.js $Revision: 1.5 $'
};

/**
 * Constructor for client-side XSLT transformations.
 *
 * @author Johann Burkard
 * @version $Id: xslt.js,v 1.5 2007/06/23 19:48:30 jburkard Exp $
 * @constructor
 */

function loadXML(url)

      {

        var xmlDoc;

        /* chargement du fichier XML */

        try {

          // navigateur bas sur Gecko

          if (document.implementation && document.implementation.createDocument)

          {

            xmlDoc = document.implementation.createDocument('', '', null);

            xmlDoc.load(url);

          // ActiveX pour Internet Explorer

          } else if (window.ActiveXObject) {

            try {

              xmlDoc = new ActiveXObject('Msxml2.XMLDOM');

            } catch (e) {

              xmlDoc = new ActiveXObject('Microsoft.XMLDOM');

            }

            xmlDoc.async = false;

            xmlDoc.load(url);

          //  l'aide de lobjet XMLHTTPRequest

          } else if (window.XMLHttpRequest) {

            xmlDoc = new XMLHttpRequest();

            xmlDoc.overrideMimeType('text/xml');

            xmlDoc.open('GET', url, false);

            xmlDoc.send(null);

            if (this.xmlDoc.readyState == 4) xmlDoc = xmlDoc.responseXML;

          }

        } catch (e) {

          return e;

        }

        return xmlDoc;

      }

function Transformation() {
var xsltRequest = GetXmlHttpRequest();

    var xml;

    var xmlDoc;

    var xslt;

    var xsltDoc;

    var callback = function() {};

    /**
     * Sort of like a fix for Opera who doesn't always get readyStates right.
     */
    var transformed = false;

    /**
     * Returns the URL of the XML document.
     *
     * @return the URL of the XML document
     * @type String
     */
    this.getXml = function() {
        return xml;
    }

    /**
     * Returns the XML document.
     *
     * @return the XML document
     */
    this.getXmlDocument = function() {
        return xmlDoc
    }

    /**
     * Sets the URL of the XML document.
     *
     * @param x the URL of the XML document
     * @return this
     * @type Transformation
     */
    this.setXml = function(x) {
        xml = x;
        return this;
    }

    /**
     * Returns the URL of the XSLT document.
     *
     * @return the URL of the XSLT document
     * @type String
     */
    this.getXslt = function() {
        return xslt;
    }

    /**
     * Returns the XSLT document.
     *
     * @return the XSLT document
     */
    this.getXsltDocument = function() {
        return xsltDoc;
    }

    /**
     * Sets the URL of the XSLT document.
     *
     * @param x the URL of the XML document
     * @return this
     * @type Transformation
     */
    this.setXslt = function(x) {
        xslt = x;
        return this;
    }

    /**
     * Returns the callback function.
     *
     * @return the callback function
     */
    this.getCallback = function() {
        return callback;
    }

    /**
     * Sets the callback function
     *
     * @param c the callback function
     * @return this
     * @type Transformation
     */
    this.setCallback = function(c) {
        callback = c;
        return this;
    }

    /**
     * Sets the target element to write the transformed content to and asynchronously
     * starts the transformation process.
     *

     * target can be a Node or the ID of an element. 2DO
     *

     * This method may only be called after {@link #setXml} and {@link #setXslt} have
     * been called.
     *

     * Note that the target element must exist once this method is called. Calling
     * this method before onload was fired will most likely
     * not work.
     *
     * @param target the Node or the ID of an element
     */
    this.transform = function(target) {
        if (!browserSupportsXSLT()) {
           return;
        }
        var t = this;

        if (document.recalc) {
            var xmlID = randomID();
            var xsltID = randomID();

            var change = function() {
                var c = 'complete'; // ?loading ?interactive
                var u = 'undefined';
/*
                if (typeof document.all[xmlID] != u && document.all[xmlID].readyState == c &&
                typeof document.all[xsltID] != u && document.all[xsltID].readyState == c) {

*/
                if (typeof document.all[xmlID] != u && document.all[xmlID].readyState != null &&
                typeof document.all[xsltID] != u && document.all[xsltID].readyState != null) {
/*
viewDebugInfo('---->' + document.all[xmlID].readyState);
viewDebugInfo('---->' + document.all[xsltID].readyState);
*/

document.all[target].innerHTML = '';
                    window.setTimeout(function() {
                        xmlDoc = document.all[xmlID].XMLDocument;
                        xsltDoc = document.all[xsltID].XMLDocument;
                        callback(t);

                       document.all[target].innerHTML = document.all[xmlID].transformNode(document.all[xsltID].XMLDocument);
//                        document.all[target].innerHTML = document.all[xmlID].transformNode(document.all[xsltID].XMLDocument);
						set_header_title();

                    }, 50);
                }
            }

            var xm = document.createElement('xml');
            xm.onreadystatechange = change;
            xm.id = xmlID;
            xm.src = xml;

            var xs = document.createElement('xml');
            xs.onreadystatechange = change;
            xs.id = xsltID;
            xs.src = xslt;

            document.body.insertBefore(xm);
            document.body.insertBefore(xs);
        }
        else {
			/* tradition
			            var xsltRequest = new XMLHttpRequest();
			            var xmlRequest = new XMLHttpRequest();
			*/

			/* legerement plus rapide avec FF*/
            var xmlRequest = GetXmlHttpRequest();

//console.log(xsltRequest);

            var change = function() {

                if (xmlRequest.readyState == 4 && xmlRequest.responseXML && xsltRequest.status == 200 && xsltRequest.readyState == 4 && xsltRequest.statusText == "OK" && xsltRequest.responseText ) {

                    if (transformed) {
                        return;
                    }
                    xsltDoc = xsltRequest.responseXML;
                    xmlDoc = xmlRequest.responseXML;

// responseText
/*
					var xmlstring = xsltRequest.responseText;
                    xsltDoc = ( new DOMParser() ).parseFromString( xmlstring , "text/xml" );
*/
                    var resultDoc;
                    var processor = new XSLTProcessor();

                        document.getElementById(target).innerHTML = '';

/*
                    if (typeof processor.transformToFragment == 'function') {
                        // obsolete Mozilla interface
                        resultDoc = document.implementation.createDocument("", "", null);
						processor.transformDocument(xmlDoc, xsltDoc, resultDoc, null);
                        var out = new XMLSerializer().serializeToString(resultDoc);
                        callback(t);
                        mk_pagination(xmlDoc);

						if(out)
						 document.getElementById(target).innerHTML = out;
                       	set_header_title();

                    }
                    else {*/
                        processor.importStylesheet(xsltDoc);
                        resultDoc = processor.transformToFragment(xmlDoc, document);
                        callback(t);
                       	mk_pagination(xmlDoc);
                        document.getElementById(target).appendChild(resultDoc);
                       	set_header_title();
//                    }
                    transformed = true;
                }
            }

            xmlRequest.open("GET", xml, true);
            xmlRequest.onreadystatechange = change;
            xmlRequest.send(null);

			if(xsltRequest.readyState != 4){
	            xsltRequest.open("GET", xslt);
	            xsltRequest.overrideMimeType("text/xml");
	            xsltRequest.onreadystatechange = change;
	            xsltRequest.send(null);
			}
        }
    }

    /**
     * Generates a random ID.
     *
     * @return a random ID
     */
    function randomID() {
        var out = 'id' + Math.round(Math.random() * 100000);
        return out;
    }

}

/**
 * Returns whether the browser supports XSLT.
 *
 * @return the browser supports XSLT
 * @type boolean
 */
function browserSupportsXSLT() {
    var support = false;
    if (document.recalc) { // IE 5+
        support = true;
    }
    var u = 'undefined';
    if (typeof XMLHttpRequest != u && typeof XSLTProcessor != u) { // Mozilla 0.9.4+, Opera 9+
       var processor = new XSLTProcessor();
       if (typeof processor.transformDocument == 'function') {
           support = typeof XMLSerializer != u;
       }
       else {
           support = true;
       }
    }
    return support;
}
<|endoftext|>


<commit_before>/**
 * UserController
 *
 * @description :: Server-side logic for managing users
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

'use strict';
var moment = require('moment');
var Promise = require('bluebird');

var emoticonService = require('./../services/emoticonService');
var userService = require('../services/userService');
var User = require('./../models/User');
var UserSettings = require('./../models/UserSettings');
var RoomMember = require('./../models/RoomMember');
var InboxMessage = require('./../models/InboxMessage');
var Room = require('./../models/Room');
var Message = require('./../models/Message');
var RoomController = require('./RoomController');

// A connecting client will call this endpoint. It should subscribe them to all relevant data and
// return all rooms and user data necessary to run the application.
module.exports.init = function (req, res) {

	var localUser, localUserSettings, localMemberships, localInboxMessages;

	var userId = req.session.userId.toObjectId();
	var socket = req.socket;

	// allows sending async messages back to connected client from server
	socket.join('userself_' + userId);

	Promise.join(
		User.findById(userId).lean(),
		UserSettings.findOne({user: userId}),
		RoomMember.find({user: userId}).sort('roomOrder').populate('room'),
		InboxMessage.find({user: req.session.userId}).sort('-createdAt').limit(20).populate('message')
		)
		.spread(function (user, userSettings, memberships, inboxMessages) {

			localUser = user;
			localUserSettings = userSettings;
			localMemberships = memberships;
			localInboxMessages = inboxMessages;
			var rooms = _(memberships).pluck('room').compact().value();
			var inboxUserIds = _(inboxMessages).pluck('message').pluck('author').unique().value();

			// de-associate a room from a membership since we set rooms above
			// and fix bad room order data
			_(localMemberships)
				.reject(function (membership) {
					return !membership.room;
				})
				.each(function (membership, index) {
					membership.room = membership.room._id;
					membership.roomOrder = index;
				})
				.value();

			// Setup subscriptions
			socket.join('user_' + userId);
			socket.join('inboxmessage_' + userId);

			_.each(memberships, function (membership) {
				socket.join('roommember_' + membership._id);
			});
			_.each(rooms, function (room) {
				socket.join('room_' + room._id);
			});

			return Promise.join(
				// Get all room members and 40 initial messages for each room
				Promise.map(rooms, function (room) {
					room = room.toJSON();

					return Promise.join(
						Message.find({room: room._id}).sort('-createdAt').limit(40).populate('author'),
						RoomMember.find({room: room._id}).populate('user')
						)
						.spread(function (messages, members) {

							// Setup subscriptions
							_.each(members, function (member) {
								socket.join('roommember_' + member._id);
							});

							_.each(_.pluck(members, 'user'), function (user) {
								socket.join('user_' + user._id);
							});

							room.$messages = [];
							_.each(messages, function (message) {
								room.$messages.push(message.toJSON());
							});

							room.$members = [];
							_.each(members, function (member) {
								room.$members.push(member.toJSON());
							});

							return room;
						});
				}),

				// Populate authors for inbox messages
				User.find(inboxUserIds)
					.then(function (inboxUsers) {
						return Promise.map(localInboxMessages, function (inboxMessage) {

							var authorData = _.find(inboxUsers, {_id: inboxMessage.message.author});
							if (authorData) {
								inboxMessage.message.author = authorData.toJSON();
							}

							return inboxMessage;
						});
					}),

				// fetch all emoticon counts for emoticon list
				emoticonService.emoticonCounts()
			);
		})
		.spread(function (rooms, inboxMessages, emoticonCounts) {
			return {
				user: localUser,
				userSettings: localUserSettings,
				memberships: localMemberships,
				inbox: inboxMessages,
				rooms: rooms,
				emoticonCounts: emoticonCounts
			};
		})
		.then(res.ok)
		.catch(res.serverError);
};

// Activity update route. This will respond to PUT /user/current/activity
// This route only allows updates to present and typingIn.
// It can only be called by the current user.
// It's sole purpose is to enable away and typing notifications.
module.exports.activity = function (req, res) {
	var userId = req.session.userId;

	// Only allow updates for the following values
	// There's no need for us to save these in the db, this may change in the future
	var typingIn = req.body.typingIn;
	var present = req.body.present;
	var updates = {
		typingIn: typeof typingIn !== 'undefined' ? typingIn : null,
		present: typeof present !== 'undefined' ? present : true,
		lastActivity: new Date().toISOString()
	};

	req.io.to('user_' + userId).emit('user', {_id: userId, verb: 'updated', data: updates});
	res.ok(updates);
};

module.exports.connect = function (req, res) {
	var lastConnected, previouslyConnected;

	User.findById(req.session.userId.toObjectId())
		.then(function (user) {
			lastConnected = user.lastConnected;
			previouslyConnected = user.connected;

			if (!user.sockets) user.sockets = [];
			user.sockets.push(req.socket.id);
			user.connected = true;
			user.lastConnected = new Date().toISOString();
			user.typingIn = null;
			user.present = true;

			return user.save();
		})
		.then(function (user) {

			req.io.to('user_' + user._id).emit('user', {_id: user._id, verb: 'updated', data: user});

			// Clear any disconnect messages that haven't gone out yet
			if (userService.pendingTasks[user._id]) {
				clearTimeout(userService.pendingTasks[user._id]);
				userService.pendingTasks[user._id] = null;
			}

			res.ok({});
		})
		.catch(res.serverError);
};

module.exports.markInboxRead = function (req, res) {
	InboxMessage.update({user: req.session.userId.toObjectId()}, {read: true})
		.then(res.ok)
		.catch(res.serverError);
};

module.exports.clearInbox = function (req, res) {
	InboxMessage.remove({user: req.session.userId.toObjectId()})
		.then(res.ok)
		.catch(res.serverError);
};
<commit_msg>null checking<commit_after>/**
 * UserController
 *
 * @description :: Server-side logic for managing users
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

'use strict';
var moment = require('moment');
var Promise = require('bluebird');

var emoticonService = require('./../services/emoticonService');
var userService = require('../services/userService');
var User = require('./../models/User');
var UserSettings = require('./../models/UserSettings');
var RoomMember = require('./../models/RoomMember');
var InboxMessage = require('./../models/InboxMessage');
var Room = require('./../models/Room');
var Message = require('./../models/Message');
var RoomController = require('./RoomController');

// A connecting client will call this endpoint. It should subscribe them to all relevant data and
// return all rooms and user data necessary to run the application.
module.exports.init = function (req, res) {

	var localUser, localUserSettings, localMemberships, localInboxMessages;

	var userId = req.session.userId.toObjectId();
	var socket = req.socket;

	// allows sending async messages back to connected client from server
	socket.join('userself_' + userId);

	Promise.join(
		User.findById(userId).lean(),
		UserSettings.findOne({user: userId}),
		RoomMember.find({user: userId}).sort('roomOrder').populate('room'),
		InboxMessage.find({user: req.session.userId}).sort('-createdAt').limit(20).populate('message')
		)
		.spread(function (user, userSettings, memberships, inboxMessages) {

			localUser = user;
			localUserSettings = userSettings;
			localMemberships = memberships;
			localInboxMessages = inboxMessages;
			var rooms = _(memberships).pluck('room').compact().value();
			var inboxUserIds = _(inboxMessages).pluck('message').pluck('author').unique().value();

			// de-associate a room from a membership since we set rooms above
			// and fix bad room order data
			_(localMemberships)
				.reject(function (membership) {
					return !membership.room;
				})
				.each(function (membership, index) {
					membership.room = membership.room._id;
					membership.roomOrder = index;
				})
				.value();

			// Setup subscriptions
			socket.join('user_' + userId);
			socket.join('inboxmessage_' + userId);

			_.each(memberships, function (membership) {
				socket.join('roommember_' + membership._id);
			});
			_.each(rooms, function (room) {
				socket.join('room_' + room._id);
			});

			return Promise.join(
				// Get all room members and 40 initial messages for each room
				Promise.map(rooms, function (room) {
					room = room.toJSON();

					return Promise.join(
						Message.find({room: room._id}).sort('-createdAt').limit(40).populate('author'),
						RoomMember.find({room: room._id}).populate('user')
						)
						.spread(function (messages, members) {

							// Setup subscriptions
							_.each(members, function (member) {
								socket.join('roommember_' + member._id);
							});

							_.each(_.pluck(members, 'user'), function (user) {
								socket.join('user_' + user._id);
							});

							room.$messages = [];
							_.each(messages, function (message) {
								room.$messages.push(message.toJSON());
							});

							room.$members = [];
							_.each(members, function (member) {
								room.$members.push(member.toJSON());
							});

							return room;
						});
				}),

				// Populate authors for inbox messages
				User.find(inboxUserIds)
					.then(function (inboxUsers) {
						return Promise.map(localInboxMessages, function (inboxMessage) {

							var authorData = _.find(inboxUsers, {_id: inboxMessage.message.author});
							if (authorData) {
								inboxMessage.message.author = authorData.toJSON();
							}

							return inboxMessage;
						});
					}),

				// fetch all emoticon counts for emoticon list
				emoticonService.emoticonCounts()
			);
		})
		.spread(function (rooms, inboxMessages, emoticonCounts) {
			return {
				user: localUser,
				userSettings: localUserSettings,
				memberships: localMemberships,
				inbox: inboxMessages,
				rooms: rooms,
				emoticonCounts: emoticonCounts
			};
		})
		.then(res.ok)
		.catch(res.serverError);
};

// Activity update route. This will respond to PUT /user/current/activity
// This route only allows updates to present and typingIn.
// It can only be called by the current user.
// It's sole purpose is to enable away and typing notifications.
module.exports.activity = function (req, res) {
	var userId = req.session.userId;

	// Only allow updates for the following values
	// There's no need for us to save these in the db, this may change in the future
	var typingIn = req.body.typingIn;
	var present = req.body.present;
	var updates = {
		typingIn: typeof typingIn !== 'undefined' ? typingIn : null,
		present: typeof present !== 'undefined' ? present : true,
		lastActivity: new Date().toISOString()
	};

	req.io.to('user_' + userId).emit('user', {_id: userId, verb: 'updated', data: updates});
	res.ok(updates);
};

module.exports.connect = function (req, res) {
	var lastConnected, previouslyConnected;

	if(!req.session.userId) return;

	User.findById(req.session.userId.toObjectId())
		.then(function (user) {
			lastConnected = user.lastConnected;
			previouslyConnected = user.connected;

			if (!user.sockets) user.sockets = [];
			user.sockets.push(req.socket.id);
			user.connected = true;
			user.lastConnected = new Date().toISOString();
			user.typingIn = null;
			user.present = true;

			return user.save();
		})
		.then(function (user) {

			req.io.to('user_' + user._id).emit('user', {_id: user._id, verb: 'updated', data: user});

			// Clear any disconnect messages that haven't gone out yet
			if (userService.pendingTasks[user._id]) {
				clearTimeout(userService.pendingTasks[user._id]);
				userService.pendingTasks[user._id] = null;
			}

			res.ok({});
		})
		.catch(res.serverError);
};

module.exports.markInboxRead = function (req, res) {
	InboxMessage.update({user: req.session.userId.toObjectId()}, {read: true})
		.then(res.ok)
		.catch(res.serverError);
};

module.exports.clearInbox = function (req, res) {
	InboxMessage.remove({user: req.session.userId.toObjectId()})
		.then(res.ok)
		.catch(res.serverError);
};
<|endoftext|>


<commit_before>import React from 'react';

import SPELLS from 'common/SPELLS';
import SpellIcon from 'common/SpellIcon';
import SpellLink from 'common/SpellLink';
import ITEMS from 'common/ITEMS';
import { formatPercentage } from 'common/format';

import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';
import StatisticBox, { STATISTIC_ORDER } from 'Main/StatisticBox';

class ColdHeartEfficiency extends Analyzer {
  static dependencies = {
    combatants: Combatants,
  };
  on_initialized() {
    this.active = this.combatants.selected.hasChest(ITEMS.COLD_HEART.id);
  }

  totalColdHeartCasts = 0;
  correctColdHeartCasts = 0;
  buffColdHeart = 0;

  unholyStrengthStart = 0;
  unholyStrengthRemaining = 0;

  concordanceStart = 0;
  concordanceRemaining = 0;

  khazgorothStart = 0;
  khazgorothRemaining = 0;

  timeAtMaxStacksStart = 0;
  timeAtMaxStacks = 0;

  on_byPlayer_applybuff(event) {
    const spellID = event.ability.guid;
    if (spellID === SPELLS.UNHOLY_STRENGTH_BUFF.id) {
      this.unholyStrengthStart = event.timestamp;
    }
	if (spellID === SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id) {
		this.concordanceStart = event.timestamp;
	}
	if (spellID === SPELLS.KHAZGOROTHS_SHAPING.id) {
		this.khazgorothStart = event.timestamp;
	}
  }

  on_byPlayer_refreshbuff(event) {
	const spellID = event.ability.guid;
	if (spellID === SPELLS.UNHOLY_STRENGTH_BUFF.id) {
      this.unholyStrengthStart = event.timestamp;
    }
	if (spellID === SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id) {
		this.concordanceStart = event.timestamp;
	}
	if (spellID === SPELLS.KHAZGOROTHS_SHAPING.id) {
		this.khazgorothStart = event.timestamp;
	}
  }

  on_byPlayer_removebuff(event) {
    const spellID = event.ability.guid;
    if (spellID === SPELLS.UNHOLY_STRENGTH_BUFF.id) {
      this.unholyStrengthStart = 0;
    }
	if (spellID === SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id) {
		this.concordanceStart = 0;
    }
	if (spellID === SPELLS.KHAZGOROTHS_SHAPING.id) {
		this.khazgorothStart = 0;
	}
  }

  on_byPlayer_applybuffstack(event) {
    const spellID = event.ability.guid;
    if (spellID === SPELLS.COLD_HEART_BUFF.id) {
      this.buffColdHeart = event.stack;
	  if (this.buffColdHeart == 20) {
		  this.timeAtMaxStacksStart = event.timestamp;
	  }
    }
  }

  on_byPlayer_cast(event) {
    const spellId = event.ability.guid;

    const unholyStrengthDuration = 15000;
	const concordanceDuration = 10000;
	const khazgorothDuration = 15000;

    const coldHeartMaxStack = 20;
    const coldHeartOptimalMinStack = 14;

    const remainingDurationAllowed = 4000;

	this.timeAtMaxStacks = event.timestamp - this.timeAtMaxStacksStart;

    this.unholyStrengthRemaining = unholyStrengthDuration - (event.timestamp - this.unholyStrengthStart);
	this.concordanceRemaining = concordanceDuration - (event.timestamp - this.concordanceStart);
	this.khazgorothRemaining = khazgorothDuration - (event.timestamp - this.khazgorothStart);

    if (spellId === SPELLS.CHAINS_OF_ICE.id) {
      this.totalColdHeartCasts++;
	  //This checks wether or not any of the three buffs are about to fall off within the next 4 seconds.
      if ((this.unholyStrengthRemaining > 0 & this.unholyStrengthRemaining < remainingDurationAllowed) || (this.concordanceRemaining > 0 & this.concordanceRemaining < remainingDurationAllowed) || (this.khazgorothRemaining > 0 & this.khazgorothRemaining < remainingDurationAllowed) & this.buffColdHeart < coldHeartMaxStack & this.buffColdHeart >= coldHeartOptimalMinStack) {
         this.correctColdHeartCasts++;
      }
      if (this.buffColdHeart === 20 & this.timeAtMaxStacks <= 4000) {
        this.correctColdHeartCasts++;
      }
      //This is only here for double casting Cold Heart. If Cold Heart is casted again before it reaches 2 stacks, the event won't update.
      this.buffColdHeart = 0;
    }

  }

  suggestions(when) {
    const castEfficiency = this.correctColdHeartCasts / this.totalColdHeartCasts;
    when(castEfficiency).isLessThan(0.8)
      .addSuggestion((suggest, actual, recommended) => {
        return suggest(You are casting <SpellLink id={SPELLS.CHAINS_OF_ICE.id} /> at non optimal times. You either want to cast <SpellLink id={SPELLS.CHAINS_OF_ICE.id} /> when at 20 stacks of <SpellLink id={SPELLS.COLD_HEART_BUFF.id} /> or when you are above 16 stacks and your buff <SpellLink id={SPELLS.UNHOLY_STRENGTH_BUFF.id} /> is about to run out.)
          .icon(SPELLS.CHAINS_OF_ICE.icon)
          .actual(`${formatPercentage(actual)}% of Chains of Ice were cast correctly.`)
          .recommended(`>${formatPercentage(recommended)}% is recommended`)
          .regular(recommended - 0.20).major(recommended - 0.40);
      });
  }
  statistic() {
    const castEfficiency = this.correctColdHeartCasts / this.totalColdHeartCasts;
    return (
      <StatisticBox
        icon={<SpellIcon id={SPELLS.CHAINS_OF_ICE.id} />}
        value={`${formatPercentage(castEfficiency)} %`}
        label="Cold Heart Efficiency"
        tooltip={`${this.correctColdHeartCasts} out of ${this.totalColdHeartCasts} casts of Cold Heart were made optimally.`}
      />
    );
  }
  statisticOrder = STATISTIC_ORDER.CORE(5);
}

export default ColdHeartEfficiency;
<commit_msg>Update ColdHeartEfficiency.js<commit_after>import React from 'react';

import SPELLS from 'common/SPELLS';
import SpellIcon from 'common/SpellIcon';
import SpellLink from 'common/SpellLink';
import ITEMS from 'common/ITEMS';
import { formatPercentage } from 'common/format';

import Analyzer from 'Parser/Core/Analyzer';
import Combatants from 'Parser/Core/Modules/Combatants';
import StatisticBox, { STATISTIC_ORDER } from 'Main/StatisticBox';

class ColdHeartEfficiency extends Analyzer {
  static dependencies = {
    combatants: Combatants,
  };
  on_initialized() {
    this.active = this.combatants.selected.hasChest(ITEMS.COLD_HEART.id);
  }

  totalColdHeartCasts = 0;
  correctColdHeartCasts = 0;
  buffColdHeart = 0;

  unholyStrengthStart = 0;
  unholyStrengthRemaining = 0;

  concordanceStart = 0;
  concordanceRemaining = 0;

  khazgorothStart = 0;
  khazgorothRemaining = 0;

  timeAtMaxStacksStart = 0;
  timeAtMaxStacks = 0;

  on_byPlayer_applybuff(event) {
    const spellID = event.ability.guid;
    if (spellID === SPELLS.UNHOLY_STRENGTH_BUFF.id) {
      this.unholyStrengthStart = event.timestamp;
    }
	if (spellID === SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id) {
		this.concordanceStart = event.timestamp;
	}
	if (spellID === SPELLS.KHAZGOROTHS_SHAPING.id) {
		this.khazgorothStart = event.timestamp;
	}
  }

  on_byPlayer_refreshbuff(event) {
	const spellID = event.ability.guid;
	if (spellID === SPELLS.UNHOLY_STRENGTH_BUFF.id) {
      this.unholyStrengthStart = event.timestamp;
    }
	if (spellID === SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id) {
		this.concordanceStart = event.timestamp;
	}
	if (spellID === SPELLS.KHAZGOROTHS_SHAPING.id) {
		this.khazgorothStart = event.timestamp;
	}
  }

  on_byPlayer_removebuff(event) {
    const spellID = event.ability.guid;
    if (spellID === SPELLS.UNHOLY_STRENGTH_BUFF.id) {
      this.unholyStrengthStart = 0;
    }
	if (spellID === SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id) {
		this.concordanceStart = 0;
    }
	if (spellID === SPELLS.KHAZGOROTHS_SHAPING.id) {
		this.khazgorothStart = 0;
	}
  }

  on_byPlayer_applybuffstack(event) {
    const spellID = event.ability.guid;
    if (spellID === SPELLS.COLD_HEART_BUFF.id) {
      this.buffColdHeart = event.stack;
	  if (this.buffColdHeart === 20) {
		  this.timeAtMaxStacksStart = event.timestamp;
	  }
    }
  }

  on_byPlayer_cast(event) {
    const spellId = event.ability.guid;

    const unholyStrengthDuration = 15000;
	const concordanceDuration = 10000;
	const khazgorothDuration = 15000;

    const coldHeartMaxStack = 20;
    const coldHeartOptimalMinStack = 14;

    const remainingDurationAllowed = 4000;

	this.timeAtMaxStacks = event.timestamp - this.timeAtMaxStacksStart;

    this.unholyStrengthRemaining = unholyStrengthDuration - (event.timestamp - this.unholyStrengthStart);
	this.concordanceRemaining = concordanceDuration - (event.timestamp - this.concordanceStart);
	this.khazgorothRemaining = khazgorothDuration - (event.timestamp - this.khazgorothStart);

    if (spellId === SPELLS.CHAINS_OF_ICE.id) {
      this.totalColdHeartCasts++;
	  //This checks wether or not any of the three buffs are about to fall off within the next 4 seconds.
      if ((this.unholyStrengthRemaining > 0 & this.unholyStrengthRemaining < remainingDurationAllowed) || (this.concordanceRemaining > 0 & this.concordanceRemaining < remainingDurationAllowed) || (this.khazgorothRemaining > 0 & this.khazgorothRemaining < remainingDurationAllowed) & this.buffColdHeart < coldHeartMaxStack & this.buffColdHeart >= coldHeartOptimalMinStack) {
         this.correctColdHeartCasts++;
      }
      if (this.buffColdHeart === 20 & this.timeAtMaxStacks <= 4000) {
        this.correctColdHeartCasts++;
      }
      //This is only here for double casting Cold Heart. If Cold Heart is casted again before it reaches 2 stacks, the event won't update.
      this.buffColdHeart = 0;
    }

  }

  suggestions(when) {
    const castEfficiency = this.correctColdHeartCasts / this.totalColdHeartCasts;
    when(castEfficiency).isLessThan(0.8)
      .addSuggestion((suggest, actual, recommended) => {
        return suggest( You are casting <SpellLink id={SPELLS.CHAINS_OF_ICE.id} /> at non optimal times. You either want to cast <SpellLink id={SPELLS.CHAINS_OF_ICE.id} /> when at 20 stacks of <SpellLink id={SPELLS.COLD_HEART_BUFF.id} /> or when you are above 13 stacks and either of your buffs <SpellLink id={SPELLS.UNHOLY_STRENGTH_BUFF.id}/> or <SpellLink id={SPELLS.CONCORDANCE_OF_THE_LEGIONFALL_STRENGTH.id} />  or <SpellLink id={SPELLS.KHAZGOROTHS_SHAPING.id} /> are about to run out. You also don't want to hold <SpellLink id={SPELLS.CHAINS_OF_ICE.id} /> at 20 stacks for too long. )
          .icon(SPELLS.CHAINS_OF_ICE.icon)
          .actual(`${formatPercentage(actual)}% of Chains of Ice were cast correctly.`)
          .recommended(`>${formatPercentage(recommended)}% is recommended`)
          .regular(recommended - 0.20).major(recommended - 0.40);
      });
  }
  statistic() {
    const castEfficiency = this.correctColdHeartCasts / this.totalColdHeartCasts;
    return (
      <StatisticBox
        icon={<SpellIcon id={SPELLS.CHAINS_OF_ICE.id} />}
        value={`${formatPercentage(castEfficiency)} %`}
        label="Cold Heart Efficiency"
        tooltip={`${this.correctColdHeartCasts} out of ${this.totalColdHeartCasts} casts of Cold Heart were made optimally.`}
      />
    );
  }
  statisticOrder = STATISTIC_ORDER.CORE(5);
}

export default ColdHeartEfficiency;
<|endoftext|>