<commit_before>/**
 * @file tvShow command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license MIT
 */

const string = require('../../handlers/languageHandler');
const request = require('request');

exports.run = (Bastion, message, args) => {
  if (!args.tvshow) {
    /**
     * The command was ran with invalid parameters.
     * @fires commandUsage
     */
    return Bastion.emit('commandUsage', message, this.help);
  }

  let options = {
    method: 'GET',
    url: `https://api.themoviedb.org/3/search/tv?api_key=&query=${encodeURIComponent(args.tvshow)}`,
    qs: {
      api_key: Bastion.credentials.theMovieDBApiKey
    },
    body: '{}'
  };

  request(options, (error, response, body) => {
    if (error) {
      /**
       * Error condition is encountered.
       * @fires error
       */
      return Bastion.emit('error', string('connection', 'errors'), string('connection', 'errorMessage'), message.channel);
    }
    if (response) {
      if (response.statusCode === 200) {
        let tvShow = JSON.parse(body);
        tvShow = tvShow.results[0];

        if (!tvShow) {
          /**
           * Error condition is encountered.
           * @fires error
           */
          Bastion.emit('error', string('notFound', 'errors'), string('notFound', 'errorMessage', 'TV show'), message.channel);
        }

        message.channel.send({
          embed: {
            color: Bastion.colors.BLUE,
            title: tvShow.name,
            url: `https://themoviedb.org/tv/${tvShow.id}`,
            description: tvShow.overview,
            fields: [
              {
                name: 'Language',
                value: tvShow.original_language.toUpperCase(),
                inline: true
              },
              {
                name: 'First Air Date',
                value: tvShow.first_air_date,
                inline: true
              }
            ],
            image: {
              url: tvShow.poster_path ? `https://image.tmdb.org/t/p/original${tvShow.poster_path}` : `https://image.tmdb.org/t/p/original${tvShow.backdrop_path}`
            },
            footer: {
              text: 'Powered by The Movie Database'
            }
          }
        }).catch(e => {
          Bastion.log.error(e);
        });
      }
      else {
        /**
         * Error condition is encountered.
         * @fires error
         */
        return Bastion.emit('error', string(response.statusCode), string(response.statusMessage), message.channel);
      }
    }
  });
};

exports.config = {
  aliases: [ 'tv' ],
  enabled: true,
  argsDefinitions: [
    { name: 'tvshow', type: String, multiple: true, defaultOption: true }
  ]
};

exports.help = {
  name: 'tvshow',
  description: string('tvShow', 'commandDescription'),
  botPermission: '',
  userPermission: '',
  usage: 'tvShow <TV Show Name>',
  example: [ 'tvShow The Flash' ]
};
<commit_msg>Fixed tvShow command crashes * Fixed crashes when tv show was not found * Fixed crashes for unknown errors<commit_after>/**
 * @file tvShow command
 * @author Sankarsan Kampa (a.k.a k3rn31p4nic)
 * @license MIT
 */

const string = require('../../handlers/languageHandler');
const request = require('request');

exports.run = (Bastion, message, args) => {
  if (!args.tvshow) {
    /**
     * The command was ran with invalid parameters.
     * @fires commandUsage
     */
    return Bastion.emit('commandUsage', message, this.help);
  }

  let options = {
    method: 'GET',
    url: `https://api.themoviedb.org/3/search/tv?api_key=&query=${encodeURIComponent(args.tvshow)}`,
    qs: {
      api_key: Bastion.credentials.theMovieDBApiKey
    },
    body: '{}'
  };

  request(options, (error, response, body) => {
    if (error) {
      /**
       * Error condition is encountered.
       * @fires error
       */
      return Bastion.emit('error', string('connection', 'errors'), string('connection', 'errorMessage'), message.channel);
    }
    if (response) {
      if (response.statusCode === 200) {
        let tvShow = JSON.parse(body);
        tvShow = tvShow.results[0];

        if (!tvShow) {
          /**
           * Error condition is encountered.
           * @fires error
           */
          return Bastion.emit('error', string('notFound', 'errors'), string('notFound', 'errorMessage', 'TV show'), message.channel);
        }

        message.channel.send({
          embed: {
            color: Bastion.colors.BLUE,
            title: tvShow.name,
            url: `https://themoviedb.org/tv/${tvShow.id}`,
            description: tvShow.overview,
            fields: [
              {
                name: 'Language',
                value: tvShow.original_language.toUpperCase(),
                inline: true
              },
              {
                name: 'First Air Date',
                value: tvShow.first_air_date,
                inline: true
              }
            ],
            image: {
              url: tvShow.poster_path ? `https://image.tmdb.org/t/p/original${tvShow.poster_path}` : `https://image.tmdb.org/t/p/original${tvShow.backdrop_path}`
            },
            footer: {
              text: 'Powered by The Movie Database'
            }
          }
        }).catch(e => {
          Bastion.log.error(e);
        });
      }
      else {
        /**
         * Error condition is encountered.
         * @fires error
         */
        return Bastion.emit('error', response.statusCode, response.statusMessage, message.channel);
      }
    }
  });
};

exports.config = {
  aliases: [ 'tv' ],
  enabled: true,
  argsDefinitions: [
    { name: 'tvshow', type: String, multiple: true, defaultOption: true }
  ]
};

exports.help = {
  name: 'tvshow',
  description: string('tvShow', 'commandDescription'),
  botPermission: '',
  userPermission: '',
  usage: 'tvShow <TV Show Name>',
  example: [ 'tvShow The Flash' ]
};
<|endoftext|>


<commit_before>const AbstractModule = require('./AbstractModule');
const Pg = require('pg');
const {Permissions} = require('discord.js');
const later = require('later');
const async = require('async');

var draft = /Name: ([[\w \(\)]+)\s*Teams: ([^\n]+)\s*Rounds: (\d+)\s*Date: ([^\n]+)/im;
var insertDraft = 'INSERT INTO Drafts (Name, Teams, Rounds, Date, Guild, oChannel, Msg, Drafter) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING Draft_Key;';
var selectDrafts = 'SELECT Draft_Key, Name, Teams, Rounds, Date, Guild, oChannel, Msg FROM Drafts WHERE COALESCE(Channel, \'\') = \'\' AND Date BETWEEN $1 AND $2;';
var selectDraftsKey = 'SELECT Name, Teams, Rounds, Date FROM Drafts WHERE Draft_Key = $1';
var setDraftChannel = 'UPDATE Drafts SET Channel = $1, Role = $2 WHERE Draft_Key = $3;';
var updateDraft = 'UPDATE Drafts SET Name = $1, Teams = $2, Rounds = $3, Date = $4 WHERE Draft_Key = $5 RETURNING Draft_Key;';
var userDrafts = 'SELECT Guild, oChannel, Msg, Draft_Key FROM Drafts WHERE Drafter = $1 AND COALESCE(Channel, \'\') = \'\';';
var resetDraft_1 = `SELECT Drafter, Role FROM Drafts WHERE Channel = $1;`;
var resetDraft_2 = `UPDATE Drafts SET Channel = '', Role = '' WHERE Channel = $1;`;
var getDraft = 'SELECT Guild, oChannel, Msg, Draft_Key FROM Drafts WHERE Name = $1 AND Drafter = $2;';

class DraftScheduler extends AbstractModule {
  constructor() {
    super();

    var sched = later.parse.recur().on(12).hour();
    this.job = later.setInterval(this.updateDrafts, sched);
  }

  updateDrafts() {
    var today;
    var tomorrow;
    today = new Date();
    today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
    tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
    this.pgClient.query(selectDrafts, [today, tomorrow], (err, res) => {
      if (err) {
        console.log(err, res); return;
      }

      res.rows.reduce((acc, row) => {
        var chName = `draft-${row.name.replace(/\s+/g, '-')}`;
        var roleId;

        this.dClient.guilds.get(row.guild)
          .channels.get(row.ochannel)
          .messages.fetch(row.msg)
          .then(msg => {
            var ready = false;

            msg.guild.createRole({
              'data': {
                'name': `${row.name} Drafters`,
                'color': Math.floor(Math.random() * 256 * 256 * 256),
                'hoist': false,
                'position': 1,
                'permissions': 0,
                'mentionable': true
              },
              'reason': `People drafting ${row.name}`
            })
              .then(role => {

                async.parallel(
                  msg.reactions.map((acc, key, rxns) => {
                    return (callback) => {
                      rxns.get(key).fetchUsers().then(users => callback(null, users.array()));
                    };
                  }),
                  (err, results) => {
                    var drafters = results.reduce((acc, users) => {
                      users.reduce((l, user) => {
                        l.push(user);
                        return l;
                      }, acc);

                      return acc;
                    }, []);

                    async.parallel(
                      drafters.map(drafter => callback => {
                        var gm = msg.guild.member(drafter);
                        gm.addRole(role, `You're drafting ${row.name}`);
                        callback(null, gm.nickname);
                      }),
                      (err, results) => {
                        msg.guild.createChannel(chName, 'text', {
                          'nsfw': false,
                          'parent': msg.channel.parent.id,
                          'reason': `Drafting channel for ${row.name}`
                        })
                          .then(ch => {
                            ch.send(`Hello <@&${role.id}>! This channel has been setup to draft ${row.name} today at ${row.date.toTimeString()}.
Teams competing can be found at the following link: ${row.teams}
Here are the drafters:
${results.join('\n')}`);
                            console.log(row.draft_key);
                            this.pgClient.query(setDraftChannel, [ch.id, role.id, row.draft_key]);
                          });
                      });
                  });
              });
          });
      }, 0);
    });
  }

  saveDraft(msg, draft_key, cb) {
    var r = draft.exec(msg.content);
    if (!r) {
      return false;
    }

    var name;
    var teams;
    var rounds;
    var date;
    var msgId;
    var chId;
    var guildId;
    var drafter;
    name = r[1];
    teams = r[2];
    rounds = parseInt(r[3]);
    date = new Date(new Date().getFullYear() + " " + r[4]);
    guildId = msg.channel.guild.id;
    chId = msg.channel.id;
    msgId = msg.id;
    drafter = msg.author.id;

    if (date.getHours() < 12) {
      date.setHours(date.getHours() + 12);
    }

    var query;
    var values;

    if (draft_key) {
      query = updateDraft;
      values = [name, teams, rounds, date, draft_key];
    } else {
      query = insertDraft;
      values = [name, teams, rounds, date, guildId, chId, msgId, drafter];
    }

    async.parallel(
      [callback => this.pgClient.query(query, values, (err, res) => {
        callback(err, res);
      })],
      (err, res) => {
        if (err) {
          console.log(err);
          return;
        }
        cb(res[0].rows[0].draft_key);
      });
  }

  getEvents() {
    return [
      {
        'key': 'message',
        'callback': message => {
          this.saveDraft(message, null, (key) => {
            this.pgClient.query(selectDraftsKey, [key], (err, res) => {
              message.channel.send(`Hey ${message.author.username}, I have you setup to run **${res.rows[0].name}** on **${res.rows[0].date}**.
It will be **${res.rows[0].rounds} rounds** of these teams: ${res.rows[0].teams}
I'll setup your channel and roles the day of.`);
            });
          });
        }
      },
      {
        'key': 'message',
        'callback': message => {
          var r = /^!updateMyDrafts$/i.exec(message.content);
          if (!r) {
            return;
          }

          this.pgClient.query(userDrafts, [message.author.id], (err, res) => {
            if (err) {
              console.log(err, res);
            }

            var msgs = res.rows.map(row => callback => {
              this.dClient.guilds.get(row.guild).channels.get(row.ochannel).messages.fetch(row.msg).then(msg => callback(null, {
                'key': row.draft_key,
                'message': msg
              }));
            });

            async.parallel(
              msgs,
              (err, drafts) => drafts.map(draft => {
                this.saveDraft(draft.message, draft.key, (key) => {
                  this.pgClient.query(selectDraftsKey, [key], (err, res) => {
                    message.channel.send(`Hey ${message.author.username}, I've updated your draft of **${res.rows[0].name}** on **${res.rows[0].date}**.
It will be **${res.rows[0].rounds} rounds** of these teams: ${res.rows[0].teams}`);
                  });
                });
              }));
          });
        }
      },
      {
        'key': 'message',
        'callback': message => {
          var r = /!reset/i.exec(message.content);
          if (!r) return;

          this.pgClient.query(resetDraft_1, [message.channel.id], (err, res) => {
            var drafter = res.rows[0].drafter;
            var role = res.rows[0].role;

            var author = message.guild.members.get(message.author.id);
            if (author.permissions.bitfield & Permissions.FLAGS.ADMINISTRATOR || message.author.id == drafter) {
              return;
              this.pgClient.query(resetDraft_2, [message.channel.id], console.log);
              message.guild.roles.get(role).delete('Cleaning up draft');
              message.channel.delete('Cleaning Up Draft');
            }
          });
        }
      },
      {
        'key': 'messageUpdate',
        'callback': (oldMessage, newMessage) => {
          var o = draft.exec(oldMessage.content);
          if (!o || oldMessage.content == newMessage.content || oldMessage.content == '') return;

          this.pgClient.query(getDraft, [o[1], oldMessage.author.id], (err, res) => {
            if (err) {
              console.log(err, res);
            }

            var msgs = res.rows.map(row => callback => {
              this.dClient.guilds.get(row.guild).channels.get(row.ochannel).messages.fetch(row.msg).then(msg => callback(null, {
                'key': row.draft_key,
                'message': msg
              }));
            });

            async.parallel(
              msgs,
              (err, drafts) => drafts.map(draft => {
                this.saveDraft(draft.message, draft.key, (key) => {
                  this.pgClient.query(selectDraftsKey, [key], (err, res) => {
                    oldMessage.channel.send(`Hey ${oldMessage.author.username}, I've updated your draft of **${res.rows[0].name}** on **${res.rows[0].date}**.
It will be **${res.rows[0].rounds} rounds** of these teams: ${res.rows[0].teams}`);
                  });
                });
              }));
          });
        }
      },];
  }

  getEndpoints() {
    return {
      '/getDrafts': (request, response) => {
        this.updateDrafts(); response.send('Checking if there\'s drafts to make...');
      }
    };
  }
}

module.exports = DraftScheduler;<commit_msg>Removed clutter from draft proposal responses<commit_after>const AbstractModule = require('./AbstractModule');
const Pg = require('pg');
const {Permissions} = require('discord.js');
const later = require('later');
const async = require('async');

var draft = /Name: ([[\w \(\)]+)\s*Teams: ([^\n]+)\s*Rounds: (\d+)\s*Date: ([^\n]+)/im;
var insertDraft = 'INSERT INTO Drafts (Name, Teams, Rounds, Date, Guild, oChannel, Msg, Drafter) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING Draft_Key;';
var selectDrafts = 'SELECT Draft_Key, Name, Teams, Rounds, Date, Guild, oChannel, Msg FROM Drafts WHERE COALESCE(Channel, \'\') = \'\' AND Date BETWEEN $1 AND $2;';
var selectDraftsKey = 'SELECT Name, Teams, Rounds, Date FROM Drafts WHERE Draft_Key = $1';
var setDraftChannel = 'UPDATE Drafts SET Channel = $1, Role = $2 WHERE Draft_Key = $3;';
var updateDraft = 'UPDATE Drafts SET Name = $1, Teams = $2, Rounds = $3, Date = $4 WHERE Draft_Key = $5 RETURNING Draft_Key;';
var userDrafts = 'SELECT Guild, oChannel, Msg, Draft_Key FROM Drafts WHERE Drafter = $1 AND COALESCE(Channel, \'\') = \'\';';
var resetDraft_1 = `SELECT Drafter, Role FROM Drafts WHERE Channel = $1;`;
var resetDraft_2 = `UPDATE Drafts SET Channel = '', Role = '' WHERE Channel = $1;`;
var getDraft = 'SELECT Guild, oChannel, Msg, Draft_Key FROM Drafts WHERE Name = $1 AND Drafter = $2;';

class DraftScheduler extends AbstractModule {
  constructor() {
    super();

    var sched = later.parse.recur().on(12).hour();
    this.job = later.setInterval(this.updateDrafts, sched);
  }

  updateDrafts() {
    var today;
    var tomorrow;
    today = new Date();
    today = new Date(today.getFullYear(), today.getMonth(), today.getDate());
    tomorrow = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1);
    this.pgClient.query(selectDrafts, [today, tomorrow], (err, res) => {
      if (err) {
        console.log(err, res); return;
      }

      res.rows.reduce((acc, row) => {
        var chName = `draft-${row.name.replace(/\s+/g, '-')}`;
        var roleId;

        this.dClient.guilds.get(row.guild)
          .channels.get(row.ochannel)
          .messages.fetch(row.msg)
          .then(msg => {
            var ready = false;

            msg.guild.createRole({
              'data': {
                'name': `${row.name} Drafters`,
                'color': Math.floor(Math.random() * 256 * 256 * 256),
                'hoist': false,
                'position': 1,
                'permissions': 0,
                'mentionable': true
              },
              'reason': `People drafting ${row.name}`
            })
              .then(role => {

                async.parallel(
                  msg.reactions.map((acc, key, rxns) => {
                    return (callback) => {
                      rxns.get(key).fetchUsers().then(users => callback(null, users.array()));
                    };
                  }),
                  (err, results) => {
                    var drafters = results.reduce((acc, users) => {
                      users.reduce((l, user) => {
                        l.push(user);
                        return l;
                      }, acc);

                      return acc;
                    }, []);

                    async.parallel(
                      drafters.map(drafter => callback => {
                        var gm = msg.guild.member(drafter);
                        gm.addRole(role, `You're drafting ${row.name}`);
                        callback(null, gm.nickname);
                      }),
                      (err, results) => {
                        msg.guild.createChannel(chName, 'text', {
                          'nsfw': false,
                          'parent': msg.channel.parent.id,
                          'reason': `Drafting channel for ${row.name}`
                        })
                          .then(ch => {
                            ch.send(`Hello <@&${role.id}>! This channel has been setup to draft ${row.name} today at ${row.date.toTimeString()}.
Teams competing can be found at the following link: ${row.teams}
Here are the drafters:
${results.join('\n')}`);
                            console.log(row.draft_key);
                            this.pgClient.query(setDraftChannel, [ch.id, role.id, row.draft_key]);
                          });
                      });
                  });
              });
          });
      }, 0);
    });
  }

  saveDraft(msg, draft_key, cb) {
    var r = draft.exec(msg.content);
    if (!r) {
      return false;
    }

    var name;
    var teams;
    var rounds;
    var date;
    var msgId;
    var chId;
    var guildId;
    var drafter;
    name = r[1];
    teams = r[2];
    rounds = parseInt(r[3]);
    date = new Date(new Date().getFullYear() + " " + r[4]);
    guildId = msg.channel.guild.id;
    chId = msg.channel.id;
    msgId = msg.id;
    drafter = msg.author.id;

    if (date.getHours() < 12) {
      date.setHours(date.getHours() + 12);
    }

    var query;
    var values;

    if (draft_key) {
      query = updateDraft;
      values = [name, teams, rounds, date, draft_key];
    } else {
      query = insertDraft;
      values = [name, teams, rounds, date, guildId, chId, msgId, drafter];
    }

    async.parallel(
      [callback => this.pgClient.query(query, values, (err, res) => {
        callback(err, res);
      })],
      (err, res) => {
        if (err) {
          console.log(err);
          return;
        }
        cb(res[0].rows[0].draft_key);
      });
  }

  getEvents() {
    return [
      {
        'key': 'message',
        'callback': message => {
          this.saveDraft(message, null, (key) => {
            this.pgClient.query(selectDraftsKey, [key], (err, res) => {
              message.channel.send(`Hey ${message.author.username}, I have you setup to run **${res.rows[0].name}** on **${res.rows[0].date}**.
It will be **${res.rows[0].rounds} rounds** of these teams: <${res.rows[0].teams}>
I'll setup your channel and roles the day of.`);
            });
          });
        }
      },
      {
        'key': 'message',
        'callback': message => {
          var r = /^!updateMyDrafts$/i.exec(message.content);
          if (!r) {
            return;
          }

          this.pgClient.query(userDrafts, [message.author.id], (err, res) => {
            if (err) {
              console.log(err, res);
            }

            var msgs = res.rows.map(row => callback => {
              this.dClient.guilds.get(row.guild).channels.get(row.ochannel).messages.fetch(row.msg).then(msg => callback(null, {
                'key': row.draft_key,
                'message': msg
              }));
            });

            async.parallel(
              msgs,
              (err, drafts) => drafts.map(draft => {
                this.saveDraft(draft.message, draft.key, (key) => {
                  this.pgClient.query(selectDraftsKey, [key], (err, res) => {
                    message.channel.send(`Hey ${message.author.username}, I've updated your draft of **${res.rows[0].name}** on **${res.rows[0].date}**.
It will be **${res.rows[0].rounds} rounds** of these teams: <${res.rows[0].teams}>`);
                  });
                });
              }));
          });
        }
      },
      {
        'key': 'message',
        'callback': message => {
          var r = /!reset/i.exec(message.content);
          if (!r) return;

          this.pgClient.query(resetDraft_1, [message.channel.id], (err, res) => {
            var drafter = res.rows[0].drafter;
            var role = res.rows[0].role;

            var author = message.guild.members.get(message.author.id);
            if (author.permissions.bitfield & Permissions.FLAGS.ADMINISTRATOR || message.author.id == drafter) {
              return;
              this.pgClient.query(resetDraft_2, [message.channel.id], console.log);
              message.guild.roles.get(role).delete('Cleaning up draft');
              message.channel.delete('Cleaning Up Draft');
            }
          });
        }
      },
      {
        'key': 'messageUpdate',
        'callback': (oldMessage, newMessage) => {
          var o = draft.exec(oldMessage.content);
          if (!o || oldMessage.content == newMessage.content || oldMessage.content == '') return;

          this.pgClient.query(getDraft, [o[1], oldMessage.author.id], (err, res) => {
            if (err) {
              console.log(err, res);
            }

            var msgs = res.rows.map(row => callback => {
              this.dClient.guilds.get(row.guild).channels.get(row.ochannel).messages.fetch(row.msg).then(msg => callback(null, {
                'key': row.draft_key,
                'message': msg
              }));
            });

            async.parallel(
              msgs,
              (err, drafts) => drafts.map(draft => {
                this.saveDraft(draft.message, draft.key, (key) => {
                  this.pgClient.query(selectDraftsKey, [key], (err, res) => {
                    oldMessage.channel.send(`Hey ${oldMessage.author.username}, I've updated your draft of **${res.rows[0].name}** on **${res.rows[0].date}**.
It will be **${res.rows[0].rounds} rounds** of these teams: <${res.rows[0].teams}>`);
                  });
                });
              }));
          });
        }
      },];
  }

  getEndpoints() {
    return {
      '/getDrafts': (request, response) => {
        this.updateDrafts(); response.send('Checking if there\'s drafts to make...');
      }
    };
  }
}

module.exports = DraftScheduler;<|endoftext|>


<commit_before>
'use strict';

var cluster = require('cluster');
var os = require('os');

var chai = require('chai');
var sinon = require('sinon');
var expect = chai.expect;
var assert = chai.assert;

chai.config.includeStack = true;

describe('Test utilities', function() {
  var util = require('../');

  describe('Clone', function() {
    var clone;
    before(function() {
      clone = util.clone;
    });

    it('should be able to clone an object', function() {
      var obj = {
        a: {
          b: {
            key: 'field'
          }
        },
        b: [1,2, { key: 'field2' } ],
        c: 3
      };

      var result = clone(obj);
      expect(result).to.deep.equal(obj);
      expect(result).to.not.equal(obj);
    });

    it('should be able to clone an object with `null`', function() {
      var obj = {
        a: null,
        b: 'tester',
        c: []
      };

      var result = clone(obj);
      expect(result).to.deep.equal(obj);
      expect(result).to.not.equal(obj);
    });

    it('should be able to clone just a value', function() {
      var obj = 'test';
      var result = clone(obj);
      expect(result).to.equal(obj);
    });
  });

  describe('Merge', function() {
    var merge;
    before(function() {
      merge = util.merge;
    });

    it('should be able to merge two objects', function() {
      var a = {
        a: 'b'
      };

      var b = {
        b: 'c'
      };

      var o = {
        a: 'b',
        b: 'c'
      };

      var r = merge(a, b);
      expect(r).to.deep.equal(o);

    });

    it('should be able to handle arrays', function() {
      var a = {
        a: [1, 2, 3]
      };

      var b = {
        b: 'string'
      };

      var o = {
        a: [1, 2, 3],
        b: 'string'
      };

      var r = merge(a, b);
      expect(r).to.deep.equal(o);

      var p = merge(b, a);
      expect(r).to.deep.equal(o);
    });
  });

  describe('memoize', function() {
    var memoize;
    before(function() {
      memoize = util.memoize;
    });

    it('should be able to memoize a function', function() {
      var stub = sinon.stub();

      function echo(i) {
        stub();
        return i;
      };

      var echoCache = memoize(echo);

      var a1 = echoCache(1);
      var a2 = echoCache(1);

      assert.ok(a1 === a2);
      assert.ok(stub.calledOnce);
    });

    it('should be able to memoize a function but get called when having different arguments', function() {
      var stub = sinon.stub();

      function echo(i) {
        stub();
        return i;
      }

      var echoCache = memoize(echo);

      var a1 = echoCache(1);
      var a2 = echoCache(2);

      assert.notOk(a1 === a2);
      assert.notOk(stub.calledOnce);
      assert.ok(stub.calledTwice);
    });

    it('should be able to memoize and keep context for different functions', function() {
      var stub1 = sinon.stub();
      var stub2 = sinon.stub();

      function echo1(i) {
        stub1();
        return i;
      }

      function echo2(i) {
        stub2();
        return i + 1;
      }

      var cache1 = memoize(echo1);
      var cache2 = memoize(echo2);

      var a1 = cache1(1);
      var a2 = cache1(1);
      var b1 = cache2(3);
      var b2 = cache2(3);

      assert.ok(a1 === 1);
      assert.ok(a2 === 1);
      assert.ok(stub1.calledOnce);
      assert.ok(b1 === 4);
      assert.ok(b2 === 4);
      assert.ok(stub2.calledOnce);
    });
  });

  describe('Cluster', function() {
    var setup;
    before(function() {
      setup = util.cluster;
    });

    afterEach(function() {
      cluster.removeAllListeners('exit');
    });

    it('should maintain a minimum of 1 forked', function(done) {
      var mockCpus = ['cpu1'];

      var cpu = sinon.stub(os, 'cpus').returns(mockCpus);
      var fork = sinon.stub(cluster, 'fork');

      setup();

      process.nextTick(function() {
        assert.ok(cpu.calledOnce);
        assert.ok(fork.calledOnce);

        os.cpus.restore();
        cluster.fork.restore();
        done();
      });
    });

    it('should maintain up to max - 1', function(done) {
      var mockCpus = ['cpu1', 'cpu2', 'cpu3'];

      var cpu = sinon.stub(os, 'cpus').returns(mockCpus);
      var fork = sinon.stub(cluster, 'fork');

      setup();

      process.nextTick(function() {
        assert.ok(cpu.calledOnce);

        expect(fork.callCount).to.be.equal(mockCpus.length - 1);

        os.cpus.restore();
        cluster.fork.restore();

        done();
      });
    });

    it('should be able to re-fork when a worker dies unexpectedly', function(done) {
      var fork = sinon.stub(cluster, 'fork');

      var mock = {
        suicide: false
      };

      setup();

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(os.cpus().length - 1);

        cluster.emit('exit', mock);

        expect(fork.callCount).to.be.equal(os.cpus().length);
        cluster.fork.restore();
        done();
      });
    });

    it('should prevent forking when worker dies by suiciding', function(done) {
      var fork = sinon.stub(cluster, 'fork');

      var mock = {
        suicide: true
      };

      setup();

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(os.cpus().length - 1);
        cluster.emit('exit', mock);
        expect(fork.callCount).to.be.equal(os.cpus().length - 1);

        cluster.fork.restore();
        done();
      });
    });

    it('should simply execute callback when process is not master', function(done) {
      var orig = cluster.isMaster;

      cluster.isMaster = false;

      var stub = sinon.stub();

      setup(stub);

      process.nextTick(function() {
        assert.ok(stub.calledOnce);

        cluster.isMaster = orig;
        done();
      });
    });

    it('should be able to take config', function(done) {
      var defaults = {
        enable: true,
        instances: 3
      };

      var fork = sinon.stub(cluster, 'fork');

      setup(defaults);

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(3);

        cluster.fork.restore();
        done();
      });
    });

    it('should be able to take config and callback', function(done) {
      var defaults = {
        enable: true,
        instances: 4
      };

      var fork = sinon.stub(cluster, 'fork');

      var stub = sinon.stub();

      setup(defaults, stub);

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(4);
        assert.ok(stub.notCalled);

        cluster.fork.restore();

        done();
      });
    });

    it('should be able to call callback on worker', function(done) {
      var defaults = {};

      var orig = cluster.isMaster;

      cluster.isMaster = false;

      var fork = sinon.stub(cluster, 'fork');
      var stub = sinon.stub();

      setup(defaults, stub);

      process.nextTick(function() {
        assert.ok(fork.notCalled);

        assert.ok(stub.calledOnce);

        cluster.fork.restore();

        cluster.isMaster = orig;

        done();
      });
    });

    it('should be able to disable cluster', function(done) {
      var defaults = {
        instances: 2
      };

      expect(defaults).to.not.have.property('enable');

      var fork = sinon.stub(cluster, 'fork');
      var stub = sinon.stub();

      setup(defaults, stub);

      process.nextTick(function() {
        assert.ok(fork.notCalled);
        assert.ok(stub.calledOnce);

        cluster.fork.restore();
        done();
      });
    });
  });

  describe('crypto', function() {
    var unique;

    before(function() {
      unique = util.unique;
    });

    it('should be able to get a token without prefix', function(done) {
      var prefix = 'hello';
      unique(prefix, function(err, token) {
        expect(err).to.not.be.ok;
        expect(token).to.be.a('string').to.match(/hello:/);

        done();
      });
    });

    it('should be able to ommit optional prefix', function(done) {
      unique(function(err, token) {
        expect(err).to.not.be.ok;
        expect(token).to.be.a('string');
        done();
      });
    });
  });
});
<commit_msg>test to ensure default instance is set<commit_after>
'use strict';

var cluster = require('cluster');
var os = require('os');

var chai = require('chai');
var sinon = require('sinon');
var expect = chai.expect;
var assert = chai.assert;

chai.config.includeStack = true;

describe('Test utilities', function() {
  var util = require('../');

  describe('Clone', function() {
    var clone;
    before(function() {
      clone = util.clone;
    });

    it('should be able to clone an object', function() {
      var obj = {
        a: {
          b: {
            key: 'field'
          }
        },
        b: [1,2, { key: 'field2' } ],
        c: 3
      };

      var result = clone(obj);
      expect(result).to.deep.equal(obj);
      expect(result).to.not.equal(obj);
    });

    it('should be able to clone an object with `null`', function() {
      var obj = {
        a: null,
        b: 'tester',
        c: []
      };

      var result = clone(obj);
      expect(result).to.deep.equal(obj);
      expect(result).to.not.equal(obj);
    });

    it('should be able to clone just a value', function() {
      var obj = 'test';
      var result = clone(obj);
      expect(result).to.equal(obj);
    });
  });

  describe('Merge', function() {
    var merge;
    before(function() {
      merge = util.merge;
    });

    it('should be able to merge two objects', function() {
      var a = {
        a: 'b'
      };

      var b = {
        b: 'c'
      };

      var o = {
        a: 'b',
        b: 'c'
      };

      var r = merge(a, b);
      expect(r).to.deep.equal(o);

    });

    it('should be able to handle arrays', function() {
      var a = {
        a: [1, 2, 3]
      };

      var b = {
        b: 'string'
      };

      var o = {
        a: [1, 2, 3],
        b: 'string'
      };

      var r = merge(a, b);
      expect(r).to.deep.equal(o);

      var p = merge(b, a);
      expect(r).to.deep.equal(o);
    });
  });

  describe('memoize', function() {
    var memoize;
    before(function() {
      memoize = util.memoize;
    });

    it('should be able to memoize a function', function() {
      var stub = sinon.stub();

      function echo(i) {
        stub();
        return i;
      };

      var echoCache = memoize(echo);

      var a1 = echoCache(1);
      var a2 = echoCache(1);

      assert.ok(a1 === a2);
      assert.ok(stub.calledOnce);
    });

    it('should be able to memoize a function but get called when having different arguments', function() {
      var stub = sinon.stub();

      function echo(i) {
        stub();
        return i;
      }

      var echoCache = memoize(echo);

      var a1 = echoCache(1);
      var a2 = echoCache(2);

      assert.notOk(a1 === a2);
      assert.notOk(stub.calledOnce);
      assert.ok(stub.calledTwice);
    });

    it('should be able to memoize and keep context for different functions', function() {
      var stub1 = sinon.stub();
      var stub2 = sinon.stub();

      function echo1(i) {
        stub1();
        return i;
      }

      function echo2(i) {
        stub2();
        return i + 1;
      }

      var cache1 = memoize(echo1);
      var cache2 = memoize(echo2);

      var a1 = cache1(1);
      var a2 = cache1(1);
      var b1 = cache2(3);
      var b2 = cache2(3);

      assert.ok(a1 === 1);
      assert.ok(a2 === 1);
      assert.ok(stub1.calledOnce);
      assert.ok(b1 === 4);
      assert.ok(b2 === 4);
      assert.ok(stub2.calledOnce);
    });
  });

  describe('Cluster', function() {
    var setup;
    before(function() {
      setup = util.cluster;
    });

    afterEach(function() {
      cluster.removeAllListeners('exit');
    });

    it('should maintain a minimum of 1 forked', function(done) {
      var mockCpus = ['cpu1'];

      var cpu = sinon.stub(os, 'cpus').returns(mockCpus);
      var fork = sinon.stub(cluster, 'fork');

      setup();

      process.nextTick(function() {
        assert.ok(cpu.calledOnce);
        assert.ok(fork.calledOnce);

        os.cpus.restore();
        cluster.fork.restore();
        done();
      });
    });

    it('should maintain up to max - 1', function(done) {
      var mockCpus = ['cpu1', 'cpu2', 'cpu3'];

      var cpu = sinon.stub(os, 'cpus').returns(mockCpus);
      var fork = sinon.stub(cluster, 'fork');

      setup();

      process.nextTick(function() {
        assert.ok(cpu.calledOnce);

        expect(fork.callCount).to.be.equal(mockCpus.length - 1);

        os.cpus.restore();
        cluster.fork.restore();

        done();
      });
    });

    it('should be able to re-fork when a worker dies unexpectedly', function(done) {
      var fork = sinon.stub(cluster, 'fork');

      var mock = {
        suicide: false
      };

      setup();

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(os.cpus().length - 1);

        cluster.emit('exit', mock);

        expect(fork.callCount).to.be.equal(os.cpus().length);
        cluster.fork.restore();
        done();
      });
    });

    it('should prevent forking when worker dies by suiciding', function(done) {
      var fork = sinon.stub(cluster, 'fork');

      var mock = {
        suicide: true
      };

      setup();

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(os.cpus().length - 1);
        cluster.emit('exit', mock);
        expect(fork.callCount).to.be.equal(os.cpus().length - 1);

        cluster.fork.restore();
        done();
      });
    });

    it('should simply execute callback when process is not master', function(done) {
      var orig = cluster.isMaster;

      cluster.isMaster = false;

      var stub = sinon.stub();

      setup(stub);

      process.nextTick(function() {
        assert.ok(stub.calledOnce);

        cluster.isMaster = orig;
        done();
      });
    });

    it('should be able to take config', function(done) {
      var defaults = {
        enable: true
      };

      var fork = sinon.stub(cluster, 'fork');

      setup(defaults);

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(1);

        cluster.fork.restore();
        done();
      });
    });

    it('should be able to take config and callback', function(done) {
      var defaults = {
        enable: true,
        instances: 4
      };

      var fork = sinon.stub(cluster, 'fork');

      var stub = sinon.stub();

      setup(defaults, stub);

      process.nextTick(function() {
        expect(fork.callCount).to.be.equal(4);
        assert.ok(stub.notCalled);

        cluster.fork.restore();

        done();
      });
    });

    it('should be able to call callback on worker', function(done) {
      var defaults = {};

      var orig = cluster.isMaster;

      cluster.isMaster = false;

      var fork = sinon.stub(cluster, 'fork');
      var stub = sinon.stub();

      setup(defaults, stub);

      process.nextTick(function() {
        assert.ok(fork.notCalled);

        assert.ok(stub.calledOnce);

        cluster.fork.restore();

        cluster.isMaster = orig;

        done();
      });
    });

    it('should be able to disable cluster', function(done) {
      var defaults = {
        instances: 2
      };

      expect(defaults).to.not.have.property('enable');

      var fork = sinon.stub(cluster, 'fork');
      var stub = sinon.stub();

      setup(defaults, stub);

      process.nextTick(function() {
        assert.ok(fork.notCalled);
        assert.ok(stub.calledOnce);

        cluster.fork.restore();
        done();
      });
    });
  });

  describe('crypto', function() {
    var unique;

    before(function() {
      unique = util.unique;
    });

    it('should be able to get a token without prefix', function(done) {
      var prefix = 'hello';
      unique(prefix, function(err, token) {
        expect(err).to.not.be.ok;
        expect(token).to.be.a('string').to.match(/hello:/);

        done();
      });
    });

    it('should be able to ommit optional prefix', function(done) {
      unique(function(err, token) {
        expect(err).to.not.be.ok;
        expect(token).to.be.a('string');
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>///import core
///import plugins\removeformat.js
///commands 格式刷
///commandsName  FormatMatch
///commandsTitle  格式刷
/**
 * 格式刷，只格式inline的
 * @function
 * @name baidu.editor.execCommand
 * @param {String}     cmdName    formatmatch执行格式刷
 */
UE.plugins['formatmatch'] = function(){

    var me = this,
        list = [],img,
        flag = 0;

     me.addListener('reset',function(){
         list = [];
         flag = 0;
     });

    function addList(type,evt){

        if(browser.webkit){
            var target = evt.target.tagName == 'IMG' ? evt.target : null;
        }

        function addFormat(range){

            if(text){
                range.selectNode(text);
            }
            return range.applyInlineStyle(list[list.length-1].tagName,null,list);

        }

        me.undoManger && me.undoManger.save();

        var range = me.selection.getRange(),
            imgT = target || range.getClosedNode();
        if(img && imgT && imgT.tagName == 'IMG'){
            //trace:964

            imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline');

            img = null;
        }else{
            if(!img){
                var collapsed = range.collapsed;
                if(collapsed){
                    var text = me.document.createTextNode('match');
                    range.insertNode(text).select();

                }
                me.__hasEnterExecCommand = true;
                //不能把block上的属性干掉
                //trace:1553
                var removeFormatAttributes = me.options.removeFormatAttributes;
                me.options.removeFormatAttributes = '';
                me.execCommand('removeformat');
                me.options.removeFormatAttributes = removeFormatAttributes;
                me.__hasEnterExecCommand = false;
                //trace:969
                range = me.selection.getRange();
                if(list.length){
                    addFormat(range);
                }
                if(text){
                    range.setStartBefore(text).collapse(true);

                }
                range.select();
                text && domUtils.remove(text);
            }

        }

        me.undoManger && me.undoManger.save();
        me.removeListener('mouseup',addList);
        flag = 0;
    }

    me.commands['formatmatch'] = {
        execCommand : function( cmdName ) {

            if(flag){
                flag = 0;
                list = [];
                 me.removeListener('mouseup',addList);
                return;
            }

            var range = me.selection.getRange();
            img = range.getClosedNode();
            if(!img || img.tagName != 'IMG'){
               range.collapse(true).shrinkBoundary();
               var start = range.startContainer;
               list = domUtils.findParents(start,true,function(node){
                   return !domUtils.isBlockElm(node) && node.nodeType == 1;
               });
               //a不能加入格式刷, 并且克隆节点
               for(var i=0,ci;ci=list[i];i++){
                   if(ci.tagName == 'A'){
                       list.splice(i,1);
                       break;
                   }
               }

            }

            me.addListener('mouseup',addList);
            flag = 1;

        },
        queryCommandState : function() {
            return flag;
        },
        notNeedUndo : 1
    };
};

<commit_msg>[fixed] byxuheng<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of perseo-fe
 *
 * perseo-fe is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * perseo-fe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with perseo-fe.
 * If not, see http://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */
'use strict';

var domain = require('domain'),
    util = require('util'),
    actions = require('../models/actions'),
    metrics = require('../models/metrics'),
    myutils = require('../myutils'),
    config = require('../../config'),
    constants = require('../constants'),
    logger = require('logops'),
    recentAxn = {},
    corrAge = {};

function PostAction(req, resp) {
    var firedEvent,
        errorAxn,
        nextDomain,
        delay,
        correlator = req.headers[constants.CORRELATOR_HEADER],
        rulesWithCorr,
        errMsg,
        now = Date.now(),
        MAX_AGE_CORR = 15 * 60 * 1000;

    firedEvent = req.body || {};
    firedEvent.subservice = req.subservice;
    firedEvent.service = req.service;
    logger.debug({}, 'Post action');
    metrics.IncMetrics(req.service, req.subservice, metrics.firedRules);

    if (correlator) {
        // try detect loop
        corrAge[correlator] = now;
        rulesWithCorr = recentAxn[correlator];
        if (!rulesWithCorr) {
            //There is no array yet for this correlator
            rulesWithCorr = recentAxn[correlator] = [];
        }
        if (util.isArray(rulesWithCorr)) {
            for (var i = 0; i < rulesWithCorr.length; i++) {
                if (rulesWithCorr[i] === firedEvent.ruleName) {
                    errMsg = util.format(
                        'check infinite loop for %s (%s) - the rule has not been triggered',
                        firedEvent.ruleName,
                        correlator
                    );
                    logger.error(errMsg);
                    metrics.IncMetrics(req.service, req.subservice, metrics.errAction);
                    myutils.respondWOMetrics(resp, { httpCode: 500, message: errMsg });
                    return;
                }
            }
            // rule not found for this correlator, add it
            rulesWithCorr.push(firedEvent.ruleName);
        }
    }
    // Purge old correlators
    for (var p in corrAge) {
        if (corrAge.hasOwnProperty(p)) {
            if (now - corrAge[p] > MAX_AGE_CORR) {
                delete recentAxn[p];
                delete corrAge[p];
            }
        }
    }

    errorAxn = actions.errorsAction(firedEvent);
    if (errorAxn) {
        myutils.logErrorIf(errorAxn);
        myutils.respondWOMetrics(resp, errorAxn, null);
        return;
    }
    //We need to do this before losing response domain
    nextDomain = domain.create();
    if (process.domain) {
        nextDomain.context = {};
        nextDomain.context.path = process.domain.context.path;
        nextDomain.context.op = process.domain.context.op;
        nextDomain.context.comp = process.domain.context.comp;
        nextDomain.context.trans = process.domain.context.trans;
        nextDomain.context.corr = process.domain.context.corr;
        nextDomain.start = process.domain.start;
        nextDomain.context.srv = process.domain.context.srv;
        nextDomain.context.subsrv = process.domain.context.subsrv;
    }
    //Don't wait until action is finished
    resp.end();

    if (config.isMaster) {
        delay = 0;
    } else {
        delay = config.slaveDelay;
    }
    // TODO: Tricky ... To refactor?
    var cleanDomain, domainErrorHandler;

    domainErrorHandler = function(err) {
        logger.error(err);
        cleanDomain();
    };
    cleanDomain = function() {
        var responseTime = Date.now() - nextDomain.start;
        logger.debug('response-time: %s', responseTime);
        nextDomain.removeListener('error', domainErrorHandler);
        delete nextDomain.context;
    };
    nextDomain.on('error', domainErrorHandler);
    firedEvent.fiwarePerseoContext = nextDomain.context;
    setTimeout(function() {
        nextDomain.run(function() {
            for (var p in firedEvent.ev) {
                if (firedEvent[p] === undefined) {
                    firedEvent[p] = firedEvent.ev[p];
                }
            }
            actions.Do(firedEvent, function(err) {
                myutils.logErrorIf(err);
                cleanDomain();
            });
        });
    }, delay);
}

function AddTo(app) {
    app.post(config.endpoint.actionsPath, PostAction);
}

/**
 * AddTo adds path and handler function to the Express app.
 *
 *  @param {Object}  Express application
 */
module.exports.AddTo = AddTo;
<commit_msg>remove cbnotif from correlator<commit_after>/*
 * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of perseo-fe
 *
 * perseo-fe is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * perseo-fe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with perseo-fe.
 * If not, see http://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */
'use strict';

var domain = require('domain'),
    util = require('util'),
    actions = require('../models/actions'),
    metrics = require('../models/metrics'),
    myutils = require('../myutils'),
    config = require('../../config'),
    constants = require('../constants'),
    logger = require('logops'),
    recentAxn = {},
    corrAge = {};

function PostAction(req, resp) {
    var firedEvent,
        errorAxn,
        nextDomain,
        delay,
        correlator = req.headers[constants.CORRELATOR_HEADER],
        rulesWithCorr,
        errMsg,
        now = Date.now(),
        MAX_AGE_CORR = 15 * 60 * 1000;

    // remove cbnotif from correlator
    correlator = correlator.replace(/ cbnotif=\d;-/g,'');
    firedEvent = req.body || {};
    firedEvent.subservice = req.subservice;
    firedEvent.service = req.service;
    logger.debug({}, 'Post action');
    metrics.IncMetrics(req.service, req.subservice, metrics.firedRules);

    if (correlator) {
        // try detect loop
        corrAge[correlator] = now;
        rulesWithCorr = recentAxn[correlator];
        if (!rulesWithCorr) {
            //There is no array yet for this correlator
            rulesWithCorr = recentAxn[correlator] = [];
        }
        if (util.isArray(rulesWithCorr)) {
            for (var i = 0; i < rulesWithCorr.length; i++) {
                if (rulesWithCorr[i] === firedEvent.ruleName) {
                    errMsg = util.format(
                        'check infinite loop for %s (%s) - the rule has not been triggered',
                        firedEvent.ruleName,
                        correlator
                    );
                    logger.error(errMsg);
                    metrics.IncMetrics(req.service, req.subservice, metrics.errAction);
                    myutils.respondWOMetrics(resp, { httpCode: 500, message: errMsg });
                    return;
                }
            }
            // rule not found for this correlator, add it
            rulesWithCorr.push(firedEvent.ruleName);
        }
    }
    // Purge old correlators
    for (var p in corrAge) {
        if (corrAge.hasOwnProperty(p)) {
            if (now - corrAge[p] > MAX_AGE_CORR) {
                delete recentAxn[p];
                delete corrAge[p];
            }
        }
    }

    errorAxn = actions.errorsAction(firedEvent);
    if (errorAxn) {
        myutils.logErrorIf(errorAxn);
        myutils.respondWOMetrics(resp, errorAxn, null);
        return;
    }
    //We need to do this before losing response domain
    nextDomain = domain.create();
    if (process.domain) {
        nextDomain.context = {};
        nextDomain.context.path = process.domain.context.path;
        nextDomain.context.op = process.domain.context.op;
        nextDomain.context.comp = process.domain.context.comp;
        nextDomain.context.trans = process.domain.context.trans;
        nextDomain.context.corr = process.domain.context.corr;
        nextDomain.start = process.domain.start;
        nextDomain.context.srv = process.domain.context.srv;
        nextDomain.context.subsrv = process.domain.context.subsrv;
    }
    //Don't wait until action is finished
    resp.end();

    if (config.isMaster) {
        delay = 0;
    } else {
        delay = config.slaveDelay;
    }
    // TODO: Tricky ... To refactor?
    var cleanDomain, domainErrorHandler;

    domainErrorHandler = function(err) {
        logger.error(err);
        cleanDomain();
    };
    cleanDomain = function() {
        var responseTime = Date.now() - nextDomain.start;
        logger.debug('response-time: %s', responseTime);
        nextDomain.removeListener('error', domainErrorHandler);
        delete nextDomain.context;
    };
    nextDomain.on('error', domainErrorHandler);
    firedEvent.fiwarePerseoContext = nextDomain.context;
    setTimeout(function() {
        nextDomain.run(function() {
            for (var p in firedEvent.ev) {
                if (firedEvent[p] === undefined) {
                    firedEvent[p] = firedEvent.ev[p];
                }
            }
            actions.Do(firedEvent, function(err) {
                myutils.logErrorIf(err);
                cleanDomain();
            });
        });
    }, delay);
}

function AddTo(app) {
    app.post(config.endpoint.actionsPath, PostAction);
}

/**
 * AddTo adds path and handler function to the Express app.
 *
 *  @param {Object}  Express application
 */
module.exports.AddTo = AddTo;
<|endoftext|>


<commit_before>var testResourceRe = /\/tests\//,

	copyOnly = function(mid){
		var list = {
			"dojox/dojox.profile":1,
			"dojox/package.json":1,
			"dojox/mobile/themes/common/compile":1
		};
		return (mid in list) || /^dojox\/resources\//.test(mid);
	},

	excludes = [
		"secure",
		"cometd",
		"data/(demos|ItemExplorer|StoreExplorer|restListener)",
		"drawing",
		"editor/plugins/(ResizeTableColumn|SpellCheck)",
		"embed/(IE)",
		"flash",
		"gantt",
		"help",
		"image/(Gallery|SlideShow|ThumbnailPicker)",
		"jq",
		"jsonPath",
		"lang/(aspect|async|docs|observable|oo|typed|functional/(binrec|curry|linrec|listcomp|multirec|numrec|tailrec|util|zip))",
		"layout/(BorderContainer|dnd|ext-dijit)",
		"mobile/app/",
		"rails",
		"robot",
		"socket/Reconnect",
		"storage",
		"sql",
		"widget/(AnalogGauge|AutoRotator|BarGauge|Calendar|CalendarFx|CalendarViews|DataPresentation|DocTester|DynamicTooltip|FeedPortlet|FilePicker|FisheyeList|gauge|Iterator|Loader|Pager|Portlet|RollingList|Rotator|rotator|SortList|UpgradeBar|Wizard)",
		"wire",
		"xmpp",
		"NodeList"
	],

	excludesRe = new RegExp(("^dojox/(" + excludes.join("|") + ")").replace(/\//, "\\/")),

	usesDojoProvideEtAl = function(mid){
		return excludesRe.test(mid);
	};

var profile = {
	resourceTags:{
		test: function(filename, mid){
			return testResourceRe.test(mid);
		},

		copyOnly: function(filename, mid){
			return copyOnly(mid);
		},

		amd: function(filename, mid){
			return !testResourceRe.test(mid) && !copyOnly(mid) && !usesDojoProvideEtAl(mid) && /\.js$/.test(filename);
		},

		miniExclude: function(filename, mid){
			return 0;
		}
	},

	trees:[
		[".", ".", /(\/\.)|(~$)/]
	]
};
<commit_msg>mark dojox/Nodelist as AMD for the builder.  refs #14024<commit_after>var testResourceRe = /\/tests\//,

	copyOnly = function(mid){
		var list = {
			"dojox/dojox.profile":1,
			"dojox/package.json":1,
			"dojox/mobile/themes/common/compile":1
		};
		return (mid in list) || /^dojox\/resources\//.test(mid);
	},

	excludes = [
		"secure",
		"cometd",
		"data/(demos|ItemExplorer|StoreExplorer|restListener)",
		"drawing",
		"editor/plugins/(ResizeTableColumn|SpellCheck)",
		"embed/(IE)",
		"flash",
		"gantt",
		"help",
		"image/(Gallery|SlideShow|ThumbnailPicker)",
		"jq",
		"jsonPath",
		"lang/(aspect|async|docs|observable|oo|typed|functional/(binrec|curry|linrec|listcomp|multirec|numrec|tailrec|util|zip))",
		"layout/(BorderContainer|dnd|ext-dijit)",
		"mobile/app/",
		"rails",
		"robot",
		"socket/Reconnect",
		"storage",
		"sql",
		"widget/(AnalogGauge|AutoRotator|BarGauge|Calendar|CalendarFx|CalendarViews|DataPresentation|DocTester|DynamicTooltip|FeedPortlet|FilePicker|FisheyeList|gauge|Iterator|Loader|Pager|Portlet|RollingList|Rotator|rotator|SortList|UpgradeBar|Wizard)",
		"wire",
		"xmpp"
	],

	excludesRe = new RegExp(("^dojox/(" + excludes.join("|") + ")").replace(/\//, "\\/")),

	usesDojoProvideEtAl = function(mid){
		return excludesRe.test(mid);
	};

var profile = {
	resourceTags:{
		test: function(filename, mid){
			return testResourceRe.test(mid);
		},

		copyOnly: function(filename, mid){
			return copyOnly(mid);
		},

		amd: function(filename, mid){
			return !testResourceRe.test(mid) && !copyOnly(mid) && !usesDojoProvideEtAl(mid) && /\.js$/.test(filename);
		},

		miniExclude: function(filename, mid){
			return 0;
		}
	},

	trees:[
		[".", ".", /(\/\.)|(~$)/]
	]
};
<|endoftext|>


<commit_before>"use strict";
const colName = "groups";
const core = require("soajs");
const Mongo = core.mongo;

let indexing = {};

function Group(soajs, localConfig, mongoCore) {
    let __self = this;
    if (mongoCore) {
        __self.mongoCore = mongoCore;
        __self.mongoCoreExternal = true;
    }
    if (!__self.mongoCore) {
        __self.mongoCoreExternal = false;
        __self.mongoCore = new Mongo(soajs.meta.tenantDB(soajs.registry.tenantMetaDB, localConfig.serviceName, soajs.tenant.code));
    }
    if (indexing && soajs && soajs.tenant && soajs.tenant.id && !indexing[soajs.tenant.id]) {
        indexing[soajs.tenant.id] = true;

        __self.mongoCore.createIndex(colName, {'code': 1}, {unique: true}, function (err, result) {
        });
        __self.mongoCore.createIndex(colName, {'tenant.id': 1}, {}, function (err, result) {
        });
        soajs.log.debug("Group: Indexes for " + soajs.tenant.id + " Updated!");
    }
}

/**
 * To get all group(s)
 *
 * @param cb
 */
Group.prototype.getGroups = function (data, cb) {
    let __self = this;
    let condition = {};
    __self.mongoCore.find(colName, condition, null, null, (err, records) => {
        return cb(err, records);
    });
};

/**
 * To get a group
 *
 * @param data
 *  should have:
 *      required (id)
 *      optional (code)
 *
 * @param cb
 */
Group.prototype.getGroup = function (data, cb) {
    let __self = this;
    if (!data || !(data.id || data.code)) {
        let error = new Error("Group: must provide either id or code.");
        return cb(error, null);
    }
    let condition = {};

    if (data.id) {
        __self.validateId(data.id, (err, _id) => {
            if (err) {
                return cb(err, null);
            }
            condition = {'_id': _id};
            __self.mongoCore.findOne(colName, condition, null, null, (err, record) => {
                return cb(err, record);
            });
        });
    } else if (data.code) {
        condition = {'code': data.code};
    }
    __self.mongoCore.findOne(colName, condition, null, null, (err, record) => {
        return cb(err, record);
    });
};

/**
 * To add a group
 *
 * @param data
 *  should have:
 *      required (code, name, description)
 *      optional (config, tId, tCode)
 *
 * @param cb
 */
Group.prototype.add = function (data, cb) {
    let __self = this;
    if (!data || !data.code || !data.name || !data.description) {
        let error = new Error("Group: code, name, and description are required.");
        return cb(error, null);
    }
    let record = {
        "code": data.code,
        "name": data.name,
        "description": data.description
    };
    if (data.config) {
        record.config = data.config;
    }
    if (data.tId && data.tCode) {
        record.tenant = {
            "id": data.tId,
            "code": data.tCode
        };
    }
    __self.mongoCore.insert(colName, record, (err, record) => {
        if (record && Array.isArray(record))
            record = record [0];
        return cb(err, record);
    });
};

/**
 * To edit a group
 *
 * @param data
 *  should have:
 *      required (id, name)
 *      optional (config, description)
 *
 * @param cb
 */
Group.prototype.edit = function (data, cb) {
    let __self = this;
    if (!data || !data.name || !data.id) {
        let error = new Error("Group: name and id are required.");
        return cb(error, null);
    }
    __self.validateId(data.id, (err, _id) => {
        if (err) {
            return cb(err, null);
        }

        let s = {
            '$set': {
                'name': data.name
            }
        };
        if (data.description) {
            s['$set'].description = data.description;
        }
        if (data.config) {
            s['$set'].config = data.config;
        }
        let condition = {'_id': _id};
        let extraOptions = {
            'upsert': false,
            'safe': true
        };
        __self.mongoCore.update(colName, condition, s, extraOptions, (err, record) => {
            return cb(err, record);
        });
    });
};

/**
 * To delete a group
 *
 * @param data
 *  should have:
 *      required (id)
 *
 * @param cb
 */
Group.prototype.delete = function (data, cb) {
    let __self = this;
    if (!data || !data.id) {
        let error = new Error("Group: id is required.");
        return cb(error, null);
    }
    __self.validateId(data.id, (err, _id) => {
        if (err) {
            return cb(err, null);
        }
        let condition = {'_id': _id};
        __self.mongoCore.findOne(colName, condition, null, null, (err, record) => {
            if (err) {
                return cb(err);
            }
            if (record.locked) {
                //return error msg that this record is locked
                let error = new Error("Group: cannot delete a locked record.");
                return cb(error, null);
            }
            __self.mongoCore.remove(colName, condition, (err) => {
                return cb(err, record);
            });
        });
    });
};

/**
 * To add allowed environment(s) to groups
 *
 * @param data
 *  should have:
 *      required (groups[code, code], allowedEnvironments[env, env])
 *
 * @param cb
 */
Group.prototype.addAllowedEnvironments = function (data, cb) {
    let __self = this;
    if (!data || !data.allowedEnvironments || !data.groups) {
        let error = new Error("Group: allowedEnvironments and groups are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {}
    };
    if (data.allowedEnvironments) {
        for (let i = 0; i < data.allowedEnvironments.length; i++) {
            let env = data.allowedEnvironments[i].toUpperCase();
            s['$set']['config.allowedEnvironments.' + env] = {};
        }
    }
    let condition = {'code': {'$in': data.groups}};
    let extraOptions = {
        'upsert': false,
        'safe': true
    };
    __self.mongoCore.update(colName, condition, s, extraOptions, (err, records) => {
        return cb(err, records);
    });
};

/**
 * To add allowed package(s) to groups
 *
 * @param data
 *  should have:
 *      required (groups[code, code], allowedPackages[{product: "", package: ""}])
 *
 * @param cb
 */
Group.prototype.addAllowedPackages = function (data, cb) {
    let __self = this;
    if (!data || !data.allowedPackages || !data.groups) {
        let error = new Error("Group: allowedPackages and groups are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {}
    };
    if (data.allowedPackages) {
        for (let i = 0; i < data.allowedPackages.length; i++) {
            let prodPack = data.allowedPackages[i];
            s['$set']['config.allowedPackages.' + prodPack.product] = [prodPack.package];
        }
    }
    let condition = {'code': {'$in': data.groups}};
    let extraOptions = {
        'upsert': false,
        'safe': true
    };
    __self.mongoCore.update(colName, condition, s, extraOptions, (err, record) => {
        return cb(err, record);
    });
};

Group.prototype.validateId = function (id, cb) {
    let __self = this;

    if (!id) {
        let error = new Error("Group: must provide an id.");
        return cb(error, null);
    }

    try {
        id = __self.mongoCore.ObjectId(id);
        return cb(null, id);
    } catch (e) {
        return cb(e, null);
    }
};

Group.prototype.closeConnection = function () {
    let __self = this;

    if (!__self.mongoCoreExternal)
        __self.mongoCore.closeDb();
};

module.exports = Group;<commit_msg>fixes<commit_after>"use strict";
const colName = "groups";
const core = require("soajs");
const Mongo = core.mongo;

let indexing = {};

function Group(soajs, localConfig, mongoCore) {
    let __self = this;
    if (mongoCore) {
        __self.mongoCore = mongoCore;
        __self.mongoCoreExternal = true;
    }
    if (!__self.mongoCore) {
        __self.mongoCoreExternal = false;
        __self.mongoCore = new Mongo(soajs.meta.tenantDB(soajs.registry.tenantMetaDB, localConfig.serviceName, soajs.tenant.code));
    }
    if (indexing && soajs && soajs.tenant && soajs.tenant.id && !indexing[soajs.tenant.id]) {
        indexing[soajs.tenant.id] = true;

        __self.mongoCore.createIndex(colName, {'code': 1}, {unique: true}, function (err, result) {
        });
        __self.mongoCore.createIndex(colName, {'tenant.id': 1}, {}, function (err, result) {
        });
        soajs.log.debug("Group: Indexes for " + soajs.tenant.id + " Updated!");
    }
}

/**
 * To get all group(s)
 *
 * @param cb
 */
Group.prototype.getGroups = function (data, cb) {
    let __self = this;
    let condition = {};
    __self.mongoCore.find(colName, condition, null, null, (err, records) => {
        return cb(err, records);
    });
};

/**
 * To get a group
 *
 * @param data
 *  should have:
 *      required (id)
 *      optional (code)
 *
 * @param cb
 */
Group.prototype.getGroup = function (data, cb) {
    let __self = this;
    if (!data || !(data.id || data.code)) {
        let error = new Error("Group: must provide either id or code.");
        return cb(error, null);
    }
    let condition = {};

    if (data.id) {
        __self.validateId(data.id, (err, _id) => {
            if (err) {
                return cb(err, null);
            }
            condition = {'_id': _id};
            __self.mongoCore.findOne(colName, condition, null, null, (err, record) => {
                return cb(err, record);
            });
        });
    } else {
        if (data.code) {
            condition = {'code': data.code};
        }

        __self.mongoCore.findOne(colName, condition, null, null, (err, record) => {
            return cb(err, record);
        });
    }
};

/**
 * To add a group
 *
 * @param data
 *  should have:
 *      required (code, name, description)
 *      optional (config, tId, tCode)
 *
 * @param cb
 */
Group.prototype.add = function (data, cb) {
    let __self = this;
    if (!data || !data.code || !data.name || !data.description) {
        let error = new Error("Group: code, name, and description are required.");
        return cb(error, null);
    }
    let record = {
        "code": data.code,
        "name": data.name,
        "description": data.description
    };
    if (data.config) {
        record.config = data.config;
    }
    if (data.tId && data.tCode) {
        record.tenant = {
            "id": data.tId,
            "code": data.tCode
        };
    }
    __self.mongoCore.insert(colName, record, (err, record) => {
        if (record && Array.isArray(record))
            record = record [0];
        return cb(err, record);
    });
};

/**
 * To edit a group
 *
 * @param data
 *  should have:
 *      required (id, name)
 *      optional (config, description)
 *
 * @param cb
 */
Group.prototype.edit = function (data, cb) {
    let __self = this;
    if (!data || !data.name || !data.id) {
        let error = new Error("Group: name and id are required.");
        return cb(error, null);
    }
    __self.validateId(data.id, (err, _id) => {
        if (err) {
            return cb(err, null);
        }

        let s = {
            '$set': {
                'name': data.name
            }
        };
        if (data.description) {
            s['$set'].description = data.description;
        }
        if (data.config) {
            s['$set'].config = data.config;
        }
        let condition = {'_id': _id};
        let extraOptions = {
            'upsert': false,
            'safe': true
        };
        __self.mongoCore.update(colName, condition, s, extraOptions, (err, record) => {
            return cb(err, record);
        });
    });
};

/**
 * To delete a group
 *
 * @param data
 *  should have:
 *      required (id)
 *
 * @param cb
 */
Group.prototype.delete = function (data, cb) {
    let __self = this;
    if (!data || !data.id) {
        let error = new Error("Group: id is required.");
        return cb(error, null);
    }
    __self.validateId(data.id, (err, _id) => {
        if (err) {
            return cb(err, null);
        }
        let condition = {'_id': _id};
        __self.mongoCore.findOne(colName, condition, null, null, (err, record) => {
            if (err) {
                return cb(err);
            }
            if (record.locked) {
                //return error msg that this record is locked
                let error = new Error("Group: cannot delete a locked record.");
                return cb(error, null);
            }
            __self.mongoCore.remove(colName, condition, (err) => {
                return cb(err, record);
            });
        });
    });
};

/**
 * To add allowed environment(s) to groups
 *
 * @param data
 *  should have:
 *      required (groups[code, code], allowedEnvironments[env, env])
 *
 * @param cb
 */
Group.prototype.addAllowedEnvironments = function (data, cb) {
    let __self = this;
    if (!data || !data.allowedEnvironments || !data.groups) {
        let error = new Error("Group: allowedEnvironments and groups are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {}
    };
    if (data.allowedEnvironments) {
        for (let i = 0; i < data.allowedEnvironments.length; i++) {
            let env = data.allowedEnvironments[i].toUpperCase();
            s['$set']['config.allowedEnvironments.' + env] = {};
        }
    }
    let condition = {'code': {'$in': data.groups}};
    let extraOptions = {
        'upsert': false,
        'safe': true
    };
    __self.mongoCore.update(colName, condition, s, extraOptions, (err, records) => {
        return cb(err, records);
    });
};

/**
 * To add allowed package(s) to groups
 *
 * @param data
 *  should have:
 *      required (groups[code, code], allowedPackages[{product: "", package: ""}])
 *
 * @param cb
 */
Group.prototype.addAllowedPackages = function (data, cb) {
    let __self = this;
    if (!data || !data.allowedPackages || !data.groups) {
        let error = new Error("Group: allowedPackages and groups are required.");
        return cb(error, null);
    }
    let s = {
        '$set': {}
    };
    if (data.allowedPackages) {
        for (let i = 0; i < data.allowedPackages.length; i++) {
            let prodPack = data.allowedPackages[i];
            s['$set']['config.allowedPackages.' + prodPack.product] = [prodPack.package];
        }
    }
    let condition = {'code': {'$in': data.groups}};
    let extraOptions = {
        'upsert': false,
        'safe': true
    };
    __self.mongoCore.update(colName, condition, s, extraOptions, (err, record) => {
        return cb(err, record);
    });
};

Group.prototype.validateId = function (id, cb) {
    let __self = this;

    if (!id) {
        let error = new Error("Group: must provide an id.");
        return cb(error, null);
    }

    try {
        id = __self.mongoCore.ObjectId(id);
        return cb(null, id);
    } catch (e) {
        return cb(e, null);
    }
};

Group.prototype.closeConnection = function () {
    let __self = this;

    if (!__self.mongoCoreExternal)
        __self.mongoCore.closeDb();
};

module.exports = Group;<|endoftext|>


<commit_before>loadTests([
{
	description: "lists - normal behaviour",
	starting_text: [
					"* Asagi\n* Charlotte \n* Tsurugi",
					"* Asagi\n* Charlotte \n* Tsurugi\ntest",
					],
	expected: [
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] Tsurugi\n[/list]",
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] Tsurugi\ntest\n[/list]"
			  ],
	options: null
},
{
	description: "lists - quotes into lists",
	starting_text: [
					"* Asagi\n* Charlotte \n* >Tsurugi\n>not goddess",
					],
	expected: [
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] [quote]Tsurugi\nnot goddess\n[/quote]\n[/list]",
			  ],
	options: null
},

]);<commit_msg>modify the "normal behaviour" test, add a new test for a "sane" handling of quotes inside lists<commit_after>loadTests([
{
	description: "lists - normal behaviour",
	starting_text: [
					"* Asagi\n* Charlotte \n* Tsurugi",
					"* Asagi\n* Charlotte \n* Tsurugi\ntest",
					],
	expected: [
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] Tsurugi\n[/list]",
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] Tsurugi\ntest\n[/list]"
			  ],
	options: null
},
{
	description: "lists - quotes into lists - normal behaviour",
	starting_text: [
					"* Asagi\n* Charlotte \n* >Tsurugi\n>not goddess",
					],
	expected: [
	            /*
	            as you can see from the html code produced by Markdown Dingus,
	            the
 tag is inside the
. We have to consider
	            this behaviour the "normal" one.

Asagi

Charlotte

>Tsurugi

not a goddess

	            */
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] >Tsurugi\n\n[quote]not goddess\n[/list]\n[/quote]",
			  ],
	options: null
},
{
	description: "lists - quotes into lists - using check_quotes_into_lists",
	starting_text: [
					"* Asagi\n* Charlotte \n* >Tsurugi\n>not goddess",
					],
	expected: [
				"[list]\n[*] Asagi\n[*] Charlotte \n[*] [quote]Tsurugi\nnot goddess\n[/quote]\n[/list]",
			  ],
	options: {check_quotes_into_lists: true}
}
]);<|endoftext|>


<commit_before>/* http://github.com/avih/nopromise MIT */
(function(){

var FUNCTION = "function",
    staticNativePromise,
    async = setTimeout;

try {
    staticNativePromise = Promise.resolve(1);
    async = function(f) { staticNativePromise.then(f) };
} catch (e) {}

try {
    async = setImmediate;
} catch (e) {}

try {
    async = process.nextTick || async;
} catch (e) {}

function NoPromise() {
    var _state,
        _output,
        _resolvers = Array(),
        new_promise = {
            resolve: _resolve,
            reject:  _reject,
            then:    _then
        };
    return new_promise.promise = new_promise;

    function _resolve(value) {
        if (!_state) {
            _state = 1;
            _output = value;
            _resolvers.forEach(async);
        }
    }
    function _reject(value) {
        if (!_state) {
            _state = 2;
            _output = value;
            _resolvers.forEach(async);
        }
    }

    function _then(onFulfilled, onRejected) {
        var promise2 = NoPromise();
        _state ? async(promise2Resolver) : _resolvers.push(promise2Resolver);
        return promise2;

        function promise2Resolver() {
            var handler = _state < 2 ? onFulfilled : onRejected;

            if (typeof handler != FUNCTION) {
                (_state < 2 ? promise2.resolve : promise2.reject)(_output);
            } else {
                promise2Resolution(0, handler);
            }
        }

        function promise2Resolution(x, handler) {
            var then,
                done = 0;

            try {
                if (handler)
                    x = handler(_output);

                if (x == promise2) {
                    promise2.reject(TypeError());

                } else if ((typeof x == FUNCTION || x && typeof x == "object")
                           && typeof (then = x.then) == FUNCTION) {
                    then.call(x, function(y) { done++ || promise2Resolution(y) },
                                 function(r) { done++ || promise2.reject(r)    });

                } else {
                    promise2.resolve(x);
                }

            } catch (e) {
                done++ || promise2.reject(e);
            }
        }
    }
}

NoPromise.deferred = NoPromise;
try {
  module.exports = NoPromise;
} catch (e) {
  this.NoPromise = NoPromise;
}

})()<commit_msg>perf: don't use .promise internally - 670(175)/1220(398)<commit_after>/* http://github.com/avih/nopromise MIT */
(function(){

var FUNCTION = "function",
    staticNativePromise,
    async = setTimeout;

try {
    staticNativePromise = Promise.resolve(1);
    async = function(f) { staticNativePromise.then(f) };
} catch (e) {}

try {
    async = setImmediate;
} catch (e) {}

try {
    async = process.nextTick || async;
} catch (e) {}

function NoPromise() {
    var _state,
        _output,
        _resolvers = Array();

    return {
        resolve: _resolve,
        reject:  _reject,
        then:    _then
    };

    function _resolve(value) {
        if (!_state) {
            _state = 1;
            _output = value;
            _resolvers.forEach(async);
        }
    }
    function _reject(value) {
        if (!_state) {
            _state = 2;
            _output = value;
            _resolvers.forEach(async);
        }
    }

    function _then(onFulfilled, onRejected) {
        var promise2 = NoPromise();
        _state ? async(promise2Resolver) : _resolvers.push(promise2Resolver);
        return promise2;

        function promise2Resolver() {
            var handler = _state < 2 ? onFulfilled : onRejected;

            if (typeof handler != FUNCTION) {
                (_state < 2 ? promise2.resolve : promise2.reject)(_output);
            } else {
                promise2Resolution(0, handler);
            }
        }

        function promise2Resolution(x, handler) {
            var then,
                done = 0;

            try {
                if (handler)
                    x = handler(_output);

                if (x == promise2) {
                    promise2.reject(TypeError());

                } else if ((typeof x == FUNCTION || x && typeof x == "object")
                           && typeof (then = x.then) == FUNCTION) {
                    then.call(x, function(y) { done++ || promise2Resolution(y) },
                                 function(r) { done++ || promise2.reject(r)    });

                } else {
                    promise2.resolve(x);
                }

            } catch (e) {
                done++ || promise2.reject(e);
            }
        }
    }
}

NoPromise.deferred = function() { var d = NoPromise(); return d.promise = d };
try {
  module.exports = NoPromise;
} catch (e) {
  this.NoPromise = NoPromise;
}

})()<|endoftext|>


<commit_before>var mongoose  = require('mongoose')
  , Schema    = mongoose.Schema
  , ObjectId  = Schema.Types.ObjectId;

var generateHexKey = function(length){
  length = length;
  return (new Array(length + 1)).join('n').replace(/n/g, function(){
    return Math.floor(Math.random()*16).toString(16);
  });
};

var generateDirectAddress = function(){
  // TODO: Setup system-wide configuration that depend on NODE_ENV
  // Keys of length 6 provide 16777216 possibilities. This will need to be
  // expanded once we have over ~2k people (chance collisions > 1/10k),
  // or we need a way to lookup keys until we find a unique one.
  return generateHexKey(6) + '@direct.' + process.env.HOSTNAME || 'localhost:3000';
}
// CarePlan schema
var CarePlanSchema = new Schema({
  name: String, // Required, but overwritten by patient account name
  photo: {}, // Overwritten by patient account name
  directAddress: {type: String, required: true, default: generateDirectAddress },
  ownerId: {type: ObjectId, required: true},
  careTeamIds: [{type: ObjectId}]
});

CarePlanSchema.static('ownedBy', function(user){
  return this.where({ownerId: user.id});
});

CarePlanSchema.static('for', function(user){
  return this.findOne({id: user.carePlanId });
});

CarePlanSchema.static('accessibleTo', function(user){
  return this.where().or([{ownerId: user.id}, {_id: user.carePlanId }, {careTeamIds: user.id}])
});

module.exports = mongoose.model('CarePlan', CarePlanSchema);<commit_msg>No more undefined direct addresses<commit_after>var mongoose  = require('mongoose')
  , Schema    = mongoose.Schema
  , ObjectId  = Schema.Types.ObjectId;

var generateHexKey = function(length){
  length = length;
  return (new Array(length + 1)).join('n').replace(/n/g, function(){
    return Math.floor(Math.random()*16).toString(16);
  });
};

var generateDirectAddress = function(){
  // TODO: Setup system-wide configuration that depend on NODE_ENV
  // Keys of length 6 provide 16777216 possibilities. This will need to be
  // expanded once we have over ~2k people (chance collisions > 1/10k),
  // or we need a way to lookup keys until we find a unique one.
  return generateHexKey(6) + '@direct.' + (process.env.HOSTNAME || 'localhost:3000');
}
// CarePlan schema
var CarePlanSchema = new Schema({
  name: String, // Required, but overwritten by patient account name
  photo: {}, // Overwritten by patient account name
  directAddress: {type: String, required: true, default: generateDirectAddress },
  ownerId: {type: ObjectId, required: true},
  careTeamIds: [{type: ObjectId}]
});

CarePlanSchema.static('ownedBy', function(user){
  return this.where({ownerId: user.id});
});

CarePlanSchema.static('for', function(user){
  return this.findOne({id: user.carePlanId });
});

CarePlanSchema.static('accessibleTo', function(user){
  return this.where().or([{ownerId: user.id}, {_id: user.carePlanId }, {careTeamIds: user.id}])
});

module.exports = mongoose.model('CarePlan', CarePlanSchema);<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Types = Schema.Types;

var feedSchema = new Schema({
    user_id: Types.ObjectId,
    month: Types.String,// one feed document per month to keep a “page” of recent posts in the initial page view
    posts: [
        {
            _id: Types.ObjectId,
            by: {
                _id: Types.ObjectId,
                first_name: Types.String,
                last_name: Types.String
            },
            herds: [
                {
                    _id: Types.ObjectId,
                    name: Types.String
                }
            ],
            type: {type: Types.String, enum: ['status', 'checkin', 'photo']},
            detail: Types.Mixed,// Mixed: Mongoose loses the ability to auto detect and save those changes, use markModified
            comments_shown: Types.Number,// because $size query operator does not allow inequality comparisons
            comments: [
                {
                    _id: Types.ObjectId,
                    by: {
                        _id: Types.ObjectId,
                        first_name: Types.String,
                        last_name: Types.String
                    },
                    text: Types.String
                }
            ]
        }
    ]
});

feedSchema.set('collection', 'posts');

feedSchema.set('toJSON', { virtuals: true });

feedSchema.virtual('created_at').get(function() {
    return this._id.getTimestamp();
});

module.exports = mongoose.model('Feed', feedSchema);<commit_msg>add Feed method for getting prior month's feed posts<commit_after>'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Types = Schema.Types;

var feedSchema = new Schema({
    user_id: Types.ObjectId,
    month: Types.String,// one feed document per month to keep a “page” of recent posts in the initial page view
    posts: [
        {
            _id: Types.ObjectId,
            by: {
                _id: Types.ObjectId,
                first_name: Types.String,
                last_name: Types.String
            },
            herds: [
                {
                    _id: Types.ObjectId,
                    name: Types.String
                }
            ],
            type: {type: Types.String, enum: ['status', 'checkin', 'photo']},
            detail: Types.Mixed,// Mixed: Mongoose loses the ability to auto detect and save those changes, use markModified
            comments_shown: Types.Number,// because $size query operator does not allow inequality comparisons
            comments: [
                {
                    _id: Types.ObjectId,
                    by: {
                        _id: Types.ObjectId,
                        first_name: Types.String,
                        last_name: Types.String
                    },
                    text: Types.String
                }
            ]
        }
    ]
});

feedSchema.set('collection', 'posts');

feedSchema.set('toJSON', { virtuals: true });

feedSchema.virtual('created_at').get(function() {
    return this._id.getTimestamp();
});

feedSchema.methods.getPriorMonthFeed = function(cb) {
    var priorMonth = new Date(parseInt(this.month.substr(0,4)), parseInt(this.month.substr(4,2)) - 2, 1);
    var month = '' + priorMonth.getFullYear();
    if (priorMonth.getMonth() < 9) {
        month += '0' + (priorMonth.getMonth() + 1);
    } else {
        month += '' + (priorMonth.getMonth() + 1);
    }
    var query = this.model('Feed').find({user_id: this.user_id});
    query.where({month: month});
    return query.exec(cb);
};

module.exports = mongoose.model('Feed', feedSchema);<|endoftext|>


<commit_before>//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
/*
 * css.normalize.js
 *
 * CSS Normalization
 *
 * CSS paths are normalized based on an optional basePath and the RequireJS config
 *
 * Usage:
 *   normalize(css, fromBasePath, toBasePath);
 *
 * css: the stylesheet content to normalize
 * fromBasePath: the absolute base path of the css relative to any root (but without ../ backtracking)
 * toBasePath: the absolute new base path of the css relative to the same root
 *
 * Absolute dependencies are left untouched.
 *
 * Urls in the CSS are picked up by regular expressions.
 * These will catch all statements of the form:
 *
 * url(*)
 * url('*')
 * url("*")
 *
 * @import '*'
 * @import "*"
 *
 * (and so also @import url(*) variations)
 *
 * For urls needing normalization
 *
 */

define(function() {

  // regular expression for removing double slashes
  // eg http://www.example.com//my///url/here -> http://www.example.com/my/url/here
  var slashes = /([^:])\/+/g
  var removeDoubleSlashes = function(uri) {
    return uri.replace(slashes, '$1/');
  }

  // given a relative URI, and two absolute base URIs, convert it from one base to another
  var protocolRegEx = /[^\:\/]*:\/\/([^\/])*/;
  var absUrlRegEx = /^(\/|data:)/;
  function convertURIBase(uri, fromBase, toBase) {
    if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
      return uri;
    uri = removeDoubleSlashes(uri);
    // if toBase specifies a protocol path, ensure this is the same protocol as fromBase, if not
    // use absolute path at fromBase
    var toBaseProtocol = toBase.match(protocolRegEx);
    var fromBaseProtocol = fromBase.match(protocolRegEx);
    if (fromBaseProtocol && (!toBaseProtocol || toBaseProtocol[1] != fromBaseProtocol[1] || toBaseProtocol[2] != fromBaseProtocol[2]))
      return absoluteURI(uri, fromBase);

    else {
      return relativeURI(absoluteURI(uri, fromBase), toBase);
    }
  };

  // given a relative URI, calculate the absolute URI
  function absoluteURI(uri, base) {
    if (uri.substr(0, 2) == './')
      uri = uri.substr(2);

    // absolute urls are left in tact
    if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
      return uri;

    var baseParts = base.split('/');
    var uriParts = uri.split('/');

    baseParts.pop();

    while (curPart = uriParts.shift())
      if (curPart == '..')
        baseParts.pop();
      else
        baseParts.push(curPart);

    return baseParts.join('/');
  };

  // given an absolute URI, calculate the relative URI
  function relativeURI(uri, base) {

    // reduce base and uri strings to just their difference string
    var baseParts = base.split('/');
    baseParts.pop();
    base = baseParts.join('/') + '/';
    i = 0;
    while (base.substr(i, 1) == uri.substr(i, 1))
      i++;
    while (base.substr(i, 1) != '/')
      i--;
    base = base.substr(i + 1);
    uri = uri.substr(i + 1);

    // each base folder difference is thus a backtrack
    baseParts = base.split('/');
    var uriParts = uri.split('/');
    out = '';
    while (baseParts.shift())
      out += '../';

    // finally add uri parts
    while (curPart = uriParts.shift())
      out += curPart + '/';

    return out.substr(0, out.length - 1);
  };

  var normalizeCSS = function(source, fromBase, toBase) {

    fromBase = removeDoubleSlashes(fromBase);
    toBase = removeDoubleSlashes(toBase);

    var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\(\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig;
    var result, url, source;

    while (result = urlRegEx.exec(source)) {
      url = result[3] || result[2] || result[5] || result[6] || result[4];
      var newUrl;
      newUrl = convertURIBase(url, fromBase, toBase);
      var quoteLen = result[5] || result[6] ? 1 : 0;
      source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1) + newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1);
      urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length);
    }

    return source;
  };

  normalizeCSS.convertURIBase = convertURIBase;
  normalizeCSS.absoluteURI = absoluteURI;
  normalizeCSS.relativeURI = relativeURI;

  return normalizeCSS;
});
//>>excludeEnd('excludeRequireCss')
<commit_msg>Ensure url(#id) values do not get re-written. Fixes https://github.com/guybedford/require-css/issues/161<commit_after>//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
/*
 * css.normalize.js
 *
 * CSS Normalization
 *
 * CSS paths are normalized based on an optional basePath and the RequireJS config
 *
 * Usage:
 *   normalize(css, fromBasePath, toBasePath);
 *
 * css: the stylesheet content to normalize
 * fromBasePath: the absolute base path of the css relative to any root (but without ../ backtracking)
 * toBasePath: the absolute new base path of the css relative to the same root
 *
 * Absolute dependencies are left untouched.
 *
 * Urls in the CSS are picked up by regular expressions.
 * These will catch all statements of the form:
 *
 * url(*)
 * url('*')
 * url("*")
 *
 * @import '*'
 * @import "*"
 *
 * (and so also @import url(*) variations)
 *
 * For urls needing normalization
 *
 */

define(function() {

  // regular expression for removing double slashes
  // eg http://www.example.com//my///url/here -> http://www.example.com/my/url/here
  var slashes = /([^:])\/+/g
  var removeDoubleSlashes = function(uri) {
    return uri.replace(slashes, '$1/');
  }

  // given a relative URI, and two absolute base URIs, convert it from one base to another
  var protocolRegEx = /[^\:\/]*:\/\/([^\/])*/;
  var absUrlRegEx = /^(\/|data:)/;
  function convertURIBase(uri, fromBase, toBase) {
    if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
      return uri;
    uri = removeDoubleSlashes(uri);
    // if toBase specifies a protocol path, ensure this is the same protocol as fromBase, if not
    // use absolute path at fromBase
    var toBaseProtocol = toBase.match(protocolRegEx);
    var fromBaseProtocol = fromBase.match(protocolRegEx);
    if (fromBaseProtocol && (!toBaseProtocol || toBaseProtocol[1] != fromBaseProtocol[1] || toBaseProtocol[2] != fromBaseProtocol[2]))
      return absoluteURI(uri, fromBase);

    else {
      return relativeURI(absoluteURI(uri, fromBase), toBase);
    }
  };

  // given a relative URI, calculate the absolute URI
  function absoluteURI(uri, base) {
    if (uri.substr(0, 2) == './')
      uri = uri.substr(2);

    // absolute urls are left in tact
    if (uri.match(absUrlRegEx) || uri.match(protocolRegEx))
      return uri;

    var baseParts = base.split('/');
    var uriParts = uri.split('/');

    baseParts.pop();

    while (curPart = uriParts.shift())
      if (curPart == '..')
        baseParts.pop();
      else
        baseParts.push(curPart);

    return baseParts.join('/');
  };

  // given an absolute URI, calculate the relative URI
  function relativeURI(uri, base) {

    // reduce base and uri strings to just their difference string
    var baseParts = base.split('/');
    baseParts.pop();
    base = baseParts.join('/') + '/';
    i = 0;
    while (base.substr(i, 1) == uri.substr(i, 1))
      i++;
    while (base.substr(i, 1) != '/')
      i--;
    base = base.substr(i + 1);
    uri = uri.substr(i + 1);

    // each base folder difference is thus a backtrack
    baseParts = base.split('/');
    var uriParts = uri.split('/');
    out = '';
    while (baseParts.shift())
      out += '../';

    // finally add uri parts
    while (curPart = uriParts.shift())
      out += curPart + '/';

    return out.substr(0, out.length - 1);
  };

  var normalizeCSS = function(source, fromBase, toBase) {

    fromBase = removeDoubleSlashes(fromBase);
    toBase = removeDoubleSlashes(toBase);

    var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\((?!#)\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig;
    var result, url, source;

    while (result = urlRegEx.exec(source)) {
      url = result[3] || result[2] || result[5] || result[6] || result[4];
      var newUrl;
      newUrl = convertURIBase(url, fromBase, toBase);
      var quoteLen = result[5] || result[6] ? 1 : 0;
      source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1) + newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1);
      urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length);
    }

    return source;
  };

  normalizeCSS.convertURIBase = convertURIBase;
  normalizeCSS.absoluteURI = absoluteURI;
  normalizeCSS.relativeURI = relativeURI;

  return normalizeCSS;
});
//>>excludeEnd('excludeRequireCss')
<|endoftext|>


<commit_before>var LogReceiver = require('./log_receiver');

function LogSender(socket, roomName) {
  var self = this;

  this.socket = socket;
  this._history = [];
  this.roomName = roomName;
  this.sRoomId = LogSender.prefix + roomName;
  this.rRoomId = LogReceiver.prefix + roomName;

  socket.join(this.sRoomId);
  socket.on("disconnect", function () {
    console.log("disconnected: " + socket.id);
  });

  // Let viewers know room was created
  if(!socket.server.sockets.adapter.rooms[this.rRoomId]) {
    socket.server.emit("created", { room: roomName });
  }

  // hook event for sending logs to viewers
  socket.on("log", function(data) { self.emitLog(data); });

  // add instance to rooms
  LogSender.rooms[roomName] = this;

  if(!LogSender.roomHistories[roomName]) {
    LogSender.roomHistories[roomName] = [];
  }

  console.log(socket.id + " joined room: " + this.sRoomId);
};

// global access to rooms
LogSender.rooms = {};
LogSender.roomHistories = {};
LogSender.prefix = "room:s:";
LogSender.create = function(socket, roomName) {
  return new LogSender(socket, roomName)
}

LogSender.prototype = {
  emitLog: function(data) {
    data.time = new Date(data.time).getTime();
    this._pushToLocalHistory(data);
    this._pushToRoomHistories(data);
    this.socket.server.to(this.rRoomId).emit("logged", data);
    return data;
  },

  instanceHistory: function() {
    return this._history;
  },

  roomHistory: function() {
    return LogSender.roomHistories[this.roomName];
  },

  _pushToLocalHistory: function(item) {
    this._history.push(item);
    if(this._history.size > 100) {
      this._history.shift();
    }
  },

  _pushToRoomHistories: function(item) {
    var histories = LogSender.roomHistories[this.roomName];
    histories.push(item);
    if(histories.size > 1000) {
      histories.shift();
    }

  }
};

module.exports = LogSender;
<commit_msg>create on("log") event after initializing room history<commit_after>var LogReceiver = require('./log_receiver');

function LogSender(socket, roomName) {
  var self = this;

  this.socket = socket;
  this._history = [];
  this.roomName = roomName;
  this.sRoomId = LogSender.prefix + roomName;
  this.rRoomId = LogReceiver.prefix + roomName;

  socket.join(this.sRoomId);
  socket.on("disconnect", function () {
    console.log("disconnected: " + socket.id);
  });

  // Let viewers know room was created
  if(!socket.server.sockets.adapter.rooms[this.rRoomId]) {
    socket.server.emit("created", { room: roomName });
  }

  // add instance to rooms
  LogSender.rooms[roomName] = this;

  if(!LogSender.roomHistories[roomName]) {
    LogSender.roomHistories[roomName] = [];
  }

  // hook event for sending logs to viewers
  socket.on("log", function(data) { self.emitLog(data); });

  console.log(socket.id + " joined room: " + this.sRoomId);
};

// global access to rooms
LogSender.rooms = {};
LogSender.roomHistories = {};
LogSender.prefix = "room:s:";
LogSender.create = function(socket, roomName) {
  return new LogSender(socket, roomName)
}

LogSender.prototype = {
  emitLog: function(data) {
    data.time = new Date(data.time).getTime();
    this._pushToLocalHistory(data);
    this._pushToRoomHistories(data);
    this.socket.server.to(this.rRoomId).emit("logged", data);
    return data;
  },

  instanceHistory: function() {
    return this._history;
  },

  roomHistory: function() {
    return LogSender.roomHistories[this.roomName];
  },

  _pushToLocalHistory: function(item) {
    this._history.push(item);
    if(this._history.size > 100) {
      this._history.shift();
    }
  },

  _pushToRoomHistories: function(item) {
    var histories = LogSender.roomHistories[this.roomName];
    histories.push(item);
    if(histories.size > 1000) {
      histories.shift();
    }

  }
};

module.exports = LogSender;
<|endoftext|>