<commit_before>var url = require('url');

module.exports = bookshelf.Model.extend({
  tableName: 'comment',

  user: function() {
    return this.belongsTo(User);
  },

  post: function() {
    return this.belongsTo(Post);
  },

  text: function() {
    return this.get('comment_text');
  },

  mentions: function() {
    return RichText.getUserMentions(this.text());
  },

  thanks: function() {
    return this.hasMany(Thank);
  },

  community: function() {
    return this.relations.post.relations.communities.first();
  }

}, {

  find: function(id, options) {
    return Comment.where({id: id}).fetch(options);
  },

  createdInTimeRange: function(collection, startTime, endTime) {
    if (endTime == undefined) {
      endTime = startTime;
      startTime = collection;
      collection = Comment;
    }

    return collection.query(function(qb) {
      qb.whereRaw('comment.date_commented between ? and ?', [startTime, endTime]);
      qb.where('comment.active', true);
    })
  },

  sendNotificationEmail: function(opts) {
    // opts.version corresponds to names of versions in SendWithUs

    return Promise.join(
      User.find(opts.recipientId),
      Comment.find(opts.commentId, {
        withRelated: [
          'user', 'post', 'post.communities', 'post.creator'
        ]
      })
    )
    .spread(function(recipient, comment) {

      if (!comment) return;

      var post = comment.relations.post,
        commenter = comment.relations.user,
        creator = post.relations.creator,
        community = post.relations.communities.models[0],
        text = RichText.qualifyLinks(comment.get('comment_text')),
        replyTo = Email.postReplyAddress(post.id, recipient.id);

      var postLabel = format('%s %s',
        (recipient.id == creator.id ? 'your' : 'the'), post.get('type'));

      return Email.sendNewCommentNotification({
        version: opts.version,
        email: recipient.get('email'),
        sender: {
          address: replyTo,
          reply_to: replyTo,
          name: format('%s (via Hylo)', commenter.get('name'))
        },
        data: {
          community_name:        community.get('name'),
          commenter_name:        commenter.get('name'),
          commenter_avatar_url:  commenter.get('avatar_url'),
          commenter_profile_url: Frontend.Route.profile(commenter) + '?ctt=comment_email',
          comment_text:          text,
          post_label:            postLabel,
          post_title:            post.get('name'),
          post_url:              Frontend.Route.post(post, community) + '?ctt=comment_email',
          unfollow_url:          Frontend.Route.unfollow(post, community),
          tracking_pixel_url:    Analytics.pixelUrl('Comment', {userId: recipient.id})
        }
      });

    })

  },

  sendPushNotification: function(userId, comment, version, options) {
    return Device.where({user_id: userId}).fetchAll()
    .then(devices => {
      if (devices.length === 0)
        return;

      return comment.load(
        ['user', 'post', 'post.communities', 'post.creator'],
        _.pick(options, "transacting")
      ).then(comment => {
        var post = comment.relations.post,
            commenter = comment.relations.user,
            creator = post.relations.creator,
            community = post.relations.communities.models[0],
            path = url.parse(Frontend.Route.post(post,community)).path,
            alertText;

        switch (version) {
        case 'mention':
          alertText = commenter.get("name") + " mentioned you in a comment";
          break;
        default:
          alertText = commenter.get("name") + " commented on \"" + post.get("name") + "\"";
        };

        return [alertText, path];
      })
      .spread((text, path) => {
        return Promise.map(devices, d => d.sendPushNotification(text, path));
      });
    });
  },

});
<commit_msg>Fixed comment.sendPushNotification<commit_after>var url = require('url');

module.exports = bookshelf.Model.extend({
  tableName: 'comment',

  user: function() {
    return this.belongsTo(User);
  },

  post: function() {
    return this.belongsTo(Post);
  },

  text: function() {
    return this.get('comment_text');
  },

  mentions: function() {
    return RichText.getUserMentions(this.text());
  },

  thanks: function() {
    return this.hasMany(Thank);
  },

  community: function() {
    return this.relations.post.relations.communities.first();
  }

}, {

  find: function(id, options) {
    return Comment.where({id: id}).fetch(options);
  },

  createdInTimeRange: function(collection, startTime, endTime) {
    if (endTime == undefined) {
      endTime = startTime;
      startTime = collection;
      collection = Comment;
    }

    return collection.query(function(qb) {
      qb.whereRaw('comment.date_commented between ? and ?', [startTime, endTime]);
      qb.where('comment.active', true);
    })
  },

  sendNotificationEmail: function(opts) {
    // opts.version corresponds to names of versions in SendWithUs

    return Promise.join(
      User.find(opts.recipientId),
      Comment.find(opts.commentId, {
        withRelated: [
          'user', 'post', 'post.communities', 'post.creator'
        ]
      })
    )
    .spread(function(recipient, comment) {

      if (!comment) return;

      var post = comment.relations.post,
        commenter = comment.relations.user,
        creator = post.relations.creator,
        community = post.relations.communities.models[0],
        text = RichText.qualifyLinks(comment.get('comment_text')),
        replyTo = Email.postReplyAddress(post.id, recipient.id);

      var postLabel = format('%s %s',
        (recipient.id == creator.id ? 'your' : 'the'), post.get('type'));

      return Email.sendNewCommentNotification({
        version: opts.version,
        email: recipient.get('email'),
        sender: {
          address: replyTo,
          reply_to: replyTo,
          name: format('%s (via Hylo)', commenter.get('name'))
        },
        data: {
          community_name:        community.get('name'),
          commenter_name:        commenter.get('name'),
          commenter_avatar_url:  commenter.get('avatar_url'),
          commenter_profile_url: Frontend.Route.profile(commenter) + '?ctt=comment_email',
          comment_text:          text,
          post_label:            postLabel,
          post_title:            post.get('name'),
          post_url:              Frontend.Route.post(post, community) + '?ctt=comment_email',
          unfollow_url:          Frontend.Route.unfollow(post, community),
          tracking_pixel_url:    Analytics.pixelUrl('Comment', {userId: recipient.id})
        }
      });

    })

  },

  sendPushNotification: function(userId, comment, version, options) {
    return Device.where({user_id: userId}).fetchAll()
    .then(devices => {
      if (devices.length === 0)
        return;

      return comment.load(
        ['user', 'post', 'post.communities', 'post.creator'],
        _.pick(options, "transacting")
      ).then(comment => {
        var post = comment.relations.post,
            commenter = comment.relations.user,
            creator = post.relations.creator,
            community = post.relations.communities.models[0],
            path = url.parse(Frontend.Route.post(post,community)).path,
            alertText;

        switch (version) {
        case 'mention':
          alertText = commenter.get("name") + " mentioned you in a comment";
          break;
        default:
          alertText = commenter.get("name") + " commented on \"" + post.get("name") + "\"";
        };

        return [alertText, path];
      })
      .spread((text, path) => {
        return Promise.map(devices.models, d => d.sendPushNotification(text, path));
      });
    });
  },

});
<|endoftext|>


<commit_before>'use strict';

// Simple function wrapper that batches Node-style calls.

// Batching is achieved by wrapping a function in logic that records calls in
// a batch for some time, then calls that function once with the accumulated
// batch, giving it an opportunity to process all the calls efficiently at
// once. Unbatching takes a batch of calls, applies then individually to a
// function, then returns a batch of results.

const _ = require('underscore');
const yieldable = require('cf-abacus-yieldable');

const map = _.map;
const identity = _.identity;
const initial = _.initial;
const zip = _.zip;
const last = _.last;
const extend = _.extend;
const isFunction = _.isFunction;
const object = _.object;
const pairs = _.pairs;
const functions = _.functions;
const bind = _.bind;
const filter = _.filter;

// Setup debug log
const debug = require('cf-abacus-debug')('cf-abacus-batch');

// Return a function that records calls for some time and presents the whole
// list of calls later to the given batch function
const batchifyfn = (fn, timeout) => {
    // Convert to a function with callback
    const fcb = yieldable.functioncb(fn);

    // Warning: calls is a mutable variable, but that's by design as we're
    // using it to record and accumulate function calls
    let calls = [];

    // Determine the application function name
    const name = fcb.fname || fcb.name;

    const wrapper = function() {
        // Record each call arguments in our list of calls
        const call = map(arguments, identity);
        debug('Recording function call %o', call);
        // Warning: mutating variable calls, by design
        calls.push(call);

        // Use a timer to decide  when to pass the list of calls to the batch
        // function
        if(calls.length === 1)
            setTimeout(() => {
                const bcalls = calls;
                // Warning: mutating variable calls, by design again
                calls = [];

                // Pass the list of calls to the batch function
                debug('Calling batch function %s with %o', name, bcalls);
                fcb(map(bcalls, (call) => initial(call)), (err, vals) => {
                    // Pass each call result to the corresponding callback
                    debug('Returning batch function results %o', vals);
                    return map(zip(bcalls, vals), (call) => last(call[0]).apply(undefined, err ? [err] : call[1]));
                });
            }, timeout);
    };

    // Store the application function name in the wrapper function
    wrapper.fname = name;

    return wrapper;
};

// Return a function that takes a list of calls, applies each individual call
// to a function and returns a list of results
const unbatchify = (fn) => {
    // Convert to a function with callback
    const fcb = yieldable.functioncb(fn);

    return (calls, cb) => {
        debug('Applying batch of %d function calls', calls.length);
        // Warning: count is a mutable variable, but that's by design as we
        // need to count results from the individual function calls
        let count = 0;
        // Warning: count is a mutable variable, but that's by design as we
        // need to collect results from the individual function calls
        let vals = [];

        // Apply each function call
        map(calls, (call, i) => {
            console.log('CALL', call);
            fcb.apply(undefined, call.concat([(err, val) => {
                // Collect function call result
                debug('Collecting function result %d', i);
                // Warning: mutating variable vals
                vals[i] = [err, val];
                // Warning: mutating variable count
                count++;
                // Call back when we've collected all the results
                if(count === calls.length) {
                    debug('Calling back with batch function results');
                    cb(undefined, vals);
                }
            }]));
        });
    };
};

// Bind a function to an object while retaining the function name
const nbind = (o, k) => extend(bind(o[k], o), { fname: (o.name || o.fname ? (o.name || o.fname) + '.' : '') + (o[k].name || o[k].fname || k) });

// Convert an application function using batchifyfn, if the given function is a
// module then convert all the functions under the module's batch property as
// well.
const batchify = (fn, timeout) => extend(
    isFunction(fn) ? batchifyfn(fn, timeout) : {},
    object(pairs(fn)),
    object(map(filter(functions(fn), (k) => /^batch_/.test(k)), (k) => [k.substr(6), batchifyfn(nbind(fn, k), timeout)])));

// Export our public functions
module.exports = batchify;
module.exports.batchify = batchify;
module.exports.unbatchify = unbatchify;

<commit_msg>Minor cleanup, remove call to console.log.<commit_after>'use strict';

// Simple function wrapper that batches Node-style calls.

// Batching is achieved by wrapping a function in logic that records calls in
// a batch for some time, then calls that function once with the accumulated
// batch, giving it an opportunity to process all the calls efficiently at
// once. Unbatching takes a batch of calls, applies then individually to a
// function, then returns a batch of results.

const _ = require('underscore');
const yieldable = require('cf-abacus-yieldable');

const map = _.map;
const identity = _.identity;
const initial = _.initial;
const zip = _.zip;
const last = _.last;
const extend = _.extend;
const isFunction = _.isFunction;
const object = _.object;
const pairs = _.pairs;
const functions = _.functions;
const bind = _.bind;
const filter = _.filter;

// Setup debug log
const debug = require('cf-abacus-debug')('cf-abacus-batch');

// Return a function that records calls for some time and presents the whole
// list of calls later to the given batch function
const batchifyfn = (fn, timeout) => {
    // Convert to a function with callback
    const fcb = yieldable.functioncb(fn);

    // Warning: calls is a mutable variable, but that's by design as we're
    // using it to record and accumulate function calls
    let calls = [];

    // Determine the application function name
    const name = fcb.fname || fcb.name;

    const wrapper = function() {
        // Record each call arguments in our list of calls
        const call = map(arguments, identity);
        debug('Recording function call %o', call);
        // Warning: mutating variable calls, by design
        calls.push(call);

        // Use a timer to decide  when to pass the list of calls to the batch
        // function
        if(calls.length === 1)
            setTimeout(() => {
                const bcalls = calls;
                // Warning: mutating variable calls, by design again
                calls = [];

                // Pass the list of calls to the batch function
                debug('Calling batch function %s with %o', name, bcalls);
                fcb(map(bcalls, (call) => initial(call)), (err, vals) => {
                    // Pass each call result to the corresponding callback
                    debug('Returning batch function results %o', vals);
                    return map(zip(bcalls, vals), (call) => last(call[0]).apply(undefined, err ? [err] : call[1]));
                });
            }, timeout);
    };

    // Store the application function name in the wrapper function
    wrapper.fname = name;

    return wrapper;
};

// Return a function that takes a list of calls, applies each individual call
// to a function and returns a list of results
const unbatchify = (fn) => {
    // Convert to a function with callback
    const fcb = yieldable.functioncb(fn);

    return (calls, cb) => {
        debug('Applying batch of %d function calls', calls.length);
        // Warning: count is a mutable variable, but that's by design as we
        // need to count results from the individual function calls
        let count = 0;
        // Warning: count is a mutable variable, but that's by design as we
        // need to collect results from the individual function calls
        let vals = [];

        // Apply each function call
        map(calls, (call, i) => {
            fcb.apply(undefined, call.concat([(err, val) => {
                // Collect function call result
                debug('Collecting function result %d', i);
                // Warning: mutating variable vals
                vals[i] = [err, val];
                // Warning: mutating variable count
                count++;
                // Call back when we've collected all the results
                if(count === calls.length) {
                    debug('Calling back with batch function results');
                    cb(undefined, vals);
                }
            }]));
        });
    };
};

// Bind a function to an object while retaining the function name
const nbind = (o, k) => extend(bind(o[k], o), { fname: (o.name || o.fname ? (o.name || o.fname) + '.' : '') + (o[k].name || o[k].fname || k) });

// Convert an application function using batchifyfn, if the given function is a
// module then convert all the functions under the module's batch property as
// well.
const batchify = (fn, timeout) => extend(
    isFunction(fn) ? batchifyfn(fn, timeout) : {},
    object(pairs(fn)),
    object(map(filter(functions(fn), (k) => /^batch_/.test(k)), (k) => [k.substr(6), batchifyfn(nbind(fn, k), timeout)])));

// Export our public functions
module.exports = batchify;
module.exports.batchify = batchify;
module.exports.unbatchify = unbatchify;

<|endoftext|>


<commit_before>/*eslint-env node */
var cloudant = require('cloudant')(cloudantService.credentials.url);
exports.cloudant = cloudant;
var itemsDb = cloudant.use('items');
exports.itemsDb = itemsDb;

//populate the db with these items.
var populateDB = function() {

    var products = [
    {
        name: 'War Room Table',
        color: 'tan',
        quantity: 5,
        description: 'A Beautiful War Room table, perfect for collaborative work spaces!',
        usaDollarPrice: 180.00,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/f/fd/Meeting_room,_table_and_paper_board.jpg'
    },
    {
        name: 'Foosball Table',
        color: 'white',
        quantity: 53,
        description: 'Wooden table, some assembly required.',
        usaDollarPrice: 125.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/6/62/FAS_Foosball_table_1.jpg'
    },
    {
        name: 'Ping pong table',
        color: 'green',
        quantity: 7,
        description: 'A very sturdy ping pong table. Includes 2 paddles and a regulation sized net.',
        usaDollarPrice: 199.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/0/0c/Table_tennis_table_007.JPG'
    },
    {
        name: 'IBM Coffee Beans',
        color: 'brown',
        quantity: 155,
        description: 'These have been fueling IBMers for ages!',
        usaDollarPrice: 15.00,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/c/c5/Roasted_coffee_beans.jpg'
    },
    {
        name: 'Ping pong balls',
        color: 'white',
        quantity: 97,
        description: '3 star ping pong balls, regulation size.',
        usaDollarPrice: 12.00,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/f/fd/Tischtennisball-weiss-004.jpg'
    },
    {
        name: 'Travel Backpack',
        color: 'green',
        quantity: 64,
        description: 'This backpack is perfect for traveling.',
        usaDollarPrice: 49.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Rucksack_Schweizer_Armee_1960er_a.jpg/828px-Rucksack_Schweizer_Armee_1960er_a.jpg'
    },
    {
        name: 'Monitor',
        color: 'white',
        quantity: 24,
        description: 'A computer monitor.',
        usaDollarPrice: 159.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/LG_L194WT-SF_LCD_monitor.jpg/1191px-LG_L194WT-SF_LCD_monitor.jpg'
    },
    {
        name: 'Water Bottle',
        color: 'orange, blue, yellow',
        quantity: 71,
        description: '3 different colors to match your personality!',
        usaDollarPrice: 19.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/0/07/Multi-use_water_bottle.JPG'
    }];

    for (var p in products){
        itemsDb.insert(products[p], function(err/*, body, header*/) {
            if (err){
                //console.log('error in populating the DB items: ' + err );
            }
        });
    }
};
exports.populateDB = populateDB;

//Initiate the database.
var initDB = function() {
    cloudant.db.create('items', function(err/*, body*/) {
	    if (!err) {
	        populateDB();
	        //console.log('Successfully created database and populated!');
	    } else {
	        //console.log("Database already exists.");
	    }
    });
};
exports.initDB = initDB;
<commit_msg>Revert "clean up lint errors and warnings"<commit_after>cloudant = require('cloudant')(cloudantService.credentials.url);
db = cloudant.use('items');

//Initiate the database.
initDB = function() {
    cloudant.db.create('items', function(err, body){
    if(!err){
        populateDB();
        //console.log('Successfully created database and populated!');
    }
    else{
        //console.log("Database already exists.");
    }
    });
}

//populate the db with these items.
populateDB = function() {

    var products = [
    {
        name: 'War Room Table',
        color: 'tan',
        quantity: 5,
        description: 'A Beautiful War Room table, perfect for collaborative work spaces!',
        usaDollarPrice: 180.00,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/f/fd/Meeting_room,_table_and_paper_board.jpg'
    },
    {
        name: 'Foosball Table',
        color: 'white',
        quantity: 53,
        description: 'Wooden table, some assembly required.',
        usaDollarPrice: 125.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/6/62/FAS_Foosball_table_1.jpg'
    },
    {
        name: 'Ping pong table',
        color: 'green',
        quantity: 7,
        description: 'A very sturdy ping pong table. Includes 2 paddles and a regulation sized net.',
        usaDollarPrice: 199.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/0/0c/Table_tennis_table_007.JPG'
    },
    {
        name: 'IBM Coffee Beans',
        color: 'brown',
        quantity: 155,
        description: 'These have been fueling IBMers for ages!',
        usaDollarPrice: 15.00,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/c/c5/Roasted_coffee_beans.jpg'
    },
    {
        name: 'Ping pong balls',
        color: 'white',
        quantity: 97,
        description: '3 star ping pong balls, regulation size.',
        usaDollarPrice: 12.00,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/f/fd/Tischtennisball-weiss-004.jpg'
    },
    {
        name: 'Travel Backpack',
        color: 'green',
        quantity: 64,
        description: 'This backpack is perfect for traveling.',
        usaDollarPrice: 49.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/thumb/3/39/Rucksack_Schweizer_Armee_1960er_a.jpg/828px-Rucksack_Schweizer_Armee_1960er_a.jpg'
    },
    {
        name: 'Monitor',
        color: 'white',
        quantity: 24,
        description: 'A computer monitor.',
        usaDollarPrice: 159.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/LG_L194WT-SF_LCD_monitor.jpg/1191px-LG_L194WT-SF_LCD_monitor.jpg'
    },
    {
        name: 'Water Bottle',
        color: 'orange, blue, yellow',
        quantity: 71,
        description: '3 different colors to match your personality!',
        usaDollarPrice: 19.99,
        imgsrc:'http://upload.wikimedia.org/wikipedia/commons/0/07/Multi-use_water_bottle.JPG'
    }];

    for(p in products){
        db.insert(products[p], function(err, body, header){
            if(err){
                //console.log('error in populating the DB items: ' + err );
            }
        });
    }
}
<|endoftext|>


<commit_before>var utils = require('../lib/utils.js');

const LOOK_INTO_THE_FUTURE = 6;

// [y, x] coords? not today!
function fixPos(player) {
  const [y, x] = player.position;
  player.position = [x, y];
  return player;
}

const min = Math.min;
const max = Math.max;

function north(map, [x, y]) {
  if (y === 0) { return -1; }
  return map[x][y - 1];
}
function south(map, [x, y]) {
  if (y >= map.length - 1) { return -1; }
  return map[x][y + 1];
}
function east(map, [x, y]) {
  if (x === 0) { return -1; }
  return map[x - 1][y];
}
function west(map, [x, y]) {
  if (x >= map.length - 1) { return -1; }
  return map[x + 1][y];
}
function getPos(map, direction, position) {
  switch (direction) {
  case 'north':
    return north(map, position);
  case 'south':
    return south(map, position);
  case 'east':
    return east(map, position);
  case 'west':
    return west(map, position);
  }
}

function whereToGo(map, player) {
  const {direction, position} = player;
  const [x, y] = position;

  const current = map[y][x];
  const ahead = getPos(map, direction, position);

  if (ahead > current) {
    return 'move';
  }

  const danger = [
    ['north', north(map, position)],
    ['south', south(map, position)],
    ['east', east(map, position)],
    ['west', west(map, position)]
  ];

  danger.sort((a, b) => b[1] - a[1]);
  if (danger[0][0] === current) {
    return '';
  }

  return danger[0][0];
}

function playerTurns(player, fn) {
  fn(Object.assign({}, player, {direction: 'north'}));
  fn(Object.assign({}, player, {direction: 'east'}));
  fn(Object.assign({}, player, {direction: 'south'}));
  fn(Object.assign({}, player, {direction: 'west'}));
}

function playerMove(ammo, gridSize, player) {
  const {direction, position} = player;
  let next = {direction, ammo: player.ammo};

  switch (direction) {
  case 'north':
    next.position = [position[0], max(position[1] - 1, 0)];
    break;
  case 'south':
    next.position = [position[0], min(position[1] + 1, gridSize - 1)];
    break;
  case 'east':
    next.position = [min(position[0] + 1, gridSize - 1), position[1]];
    break;
  case 'west':
    next.position = [max(position[0] - 1, 0), position[1]];
    break;
  }

  ammo.forEach(([y, x]) => {
    if (y === next.position[1] && x === next.position[0]) {
      next.ammo += 1;
    }
  });

  return next;
}

function printMap(map, player) {
  let block = [];
  for (let y = 0; y < map.length; y++) {
    let row = '';
    for (let x = 0; x < map.length; x++) {
      if (x === player.position[0] && y === player.position[1]) {
        switch (player.direction) {
        case 'east':
          row += '▶';
          break;
        case 'west':
          row += '◀';
          break;
        case 'north':
          row += '▲';
          break;
        case 'south':
          row += '▼';
          break;
        }
        continue;
      }

      const value = map[x][y];
      if (value === Infinity) {
        row += ' ';
        continue;
      }

      row += value;
    }
    block.push(row);
  }
  return '\n' + block.join('\n');
}

function mapLine(map, value, start, end) {
  const startX = min(start[0], end[0]);
  const startY = min(start[1], end[1]);
  const endX = max(start[0], end[0]);
  const endY = max(start[1], end[1]);

  for (let x = startX; x <= endX; x++) {
    for (let y = startY; y <= endY; y++) {
      map[x][y] = min(map[x][y], value);
    }
  }

  return map;
}

function mapEnemie(map, enemie, value) {
  const {position} = enemie;
  const gridSize = map.length;

  const [x, y] = position;
  const MIN = 0;
  const MAX = gridSize - 1;

  switch (enemie.direction) {
  case 'north':
    mapLine(map, value, [x, y], [x, MIN]);
    break;
  case 'south':
    mapLine(map, value, [x, y], [x, MAX]);
    break;
  case 'east':
    mapLine(map, value, [x, y], [MAX, y]);
    break;
  case 'west':
    mapLine(map, value, [x, y], [MIN, y]);
    break;
  default:
    console.log('WTF?');
  }

  return map;
}

function recursiveMapEnemie(ammo, map, enemie, value) {
  if (value > LOOK_INTO_THE_FUTURE) {
    return;
  }

  if (enemie.ammo > 0) {
    mapEnemie(map, enemie, value);
  }

  recursiveMapEnemie(
    ammo,
    map,
    playerMove(ammo, map.length, enemie),
    value + 1,
  );

  playerTurns(enemie, (enemieTurns) => {
    recursiveMapEnemie(
      ammo,
      map,
      playerMove(ammo, map.length, enemieTurns),
      value + 1,
    );
  });
}

function createMap(size, value = 0) {
  const BLANK = new Array(size).fill(value);

  let map = BLANK;
  map = map.map(() => BLANK.slice(0));
  return map;
}

function ai(player, enemies, game) {
  fixPos(player);

  if (utils.canKill(player, enemies) && player.ammo) {
    return 'shoot';
  }

  const map = createMap(game.gridSize, Infinity);

  enemies.forEach((enemie) => {
    fixPos(enemie);

    recursiveMapEnemie(game.ammoPosition, map, enemie, 1);
  });

  console.log(printMap(map, player));

  return whereToGo(map, player);

  /*
  let directionToAmmo;
  if (utils.canKill(player, enemies) && player.ammo) {
    return 'shoot';
  }

  if (game.ammoPosition.length) {
    directionToAmmo = utils.fastGetDirection(player.position, game.ammoPosition[0]);

    if (directionToAmmo !== player.direction) return directionToAmmo;
    return utils.safeRandomMove();
  }

  return 'move';
  */
}

module.exports = {
  info: {
    name: ':)',
    style: 2
  },
  ai,
  createMap,
  mapLine,
  mapEnemie,
  printMap,
  playerMove
};
<commit_msg>Doesn't bring game down to a crawl so much<commit_after>var utils = require('../lib/utils.js');

const LOOK_INTO_THE_FUTURE = 4;

// [y, x] coords? not today!
function fixPos(player) {
  const [y, x] = player.position;
  player.position = [x, y];
  return player;
}

const min = Math.min;
const max = Math.max;

function north(map, [x, y]) {
  if (y === 0) { return -1; }
  return map[x][y - 1];
}
function south(map, [x, y]) {
  if (y >= map.length - 1) { return -1; }
  return map[x][y + 1];
}
function east(map, [x, y]) {
  if (x === 0) { return -1; }
  return map[x - 1][y];
}
function west(map, [x, y]) {
  if (x >= map.length - 1) { return -1; }
  return map[x + 1][y];
}
function getPos(map, direction, position) {
  switch (direction) {
  case 'north':
    return north(map, position);
  case 'south':
    return south(map, position);
  case 'east':
    return east(map, position);
  case 'west':
    return west(map, position);
  }
}

function whereToGo(map, player, enemies, game) {
  const {direction, position} = player;
  const [x, y] = position;

  const current = map[y][x];
  const ahead = getPos(map, direction, position);

  if (ahead > current || current === 1) {
    return 'move';
  }

  let danger = [
    ['north', north(map, position)],
    ['south', south(map, position)],
    ['east', east(map, position)],
    ['west', west(map, position)]
  ];

  danger = danger
    .filter((a) => a[1] > -1)
    .sort((a, b) => b[1] - a[1]);

  return danger[0][0];
}

function playerTurns(player, fn) {
  fn(Object.assign({}, player, {direction: 'north'}));
  fn(Object.assign({}, player, {direction: 'east'}));
  fn(Object.assign({}, player, {direction: 'south'}));
  fn(Object.assign({}, player, {direction: 'west'}));
}

function playerMove(ammo, gridSize, player) {
  const {direction, position} = player;
  let next = {direction, ammo: player.ammo};

  switch (direction) {
  case 'north':
    next.position = [position[0], max(position[1] - 1, 0)];
    break;
  case 'south':
    next.position = [position[0], min(position[1] + 1, gridSize - 1)];
    break;
  case 'east':
    next.position = [min(position[0] + 1, gridSize - 1), position[1]];
    break;
  case 'west':
    next.position = [max(position[0] - 1, 0), position[1]];
    break;
  }

  ammo.forEach(([y, x]) => {
    if (y === next.position[1] && x === next.position[0]) {
      next.ammo += 1;
    }
  });

  return next;
}

function printMap(map, player) {
  let block = [];
  for (let y = 0; y < map.length; y++) {
    let row = '';
    for (let x = 0; x < map.length; x++) {
      if (x === player.position[0] && y === player.position[1]) {
        switch (player.direction) {
        case 'east':
          row += '▶';
          break;
        case 'west':
          row += '◀';
          break;
        case 'north':
          row += '▲';
          break;
        case 'south':
          row += '▼';
          break;
        }
        continue;
      }

      const value = map[x][y];
      if (value === Infinity) {
        row += ' ';
        continue;
      }

      row += value;
    }
    block.push(row);
  }
  return '\n' + block.join('\n');
}

function mapLine(map, value, start, end) {
  const startX = min(start[0], end[0]);
  const startY = min(start[1], end[1]);
  const endX = max(start[0], end[0]);
  const endY = max(start[1], end[1]);

  for (let x = startX; x <= endX; x++) {
    for (let y = startY; y <= endY; y++) {
      map[x][y] = min(map[x][y], value);
    }
  }

  return map;
}

function mapEnemie(map, enemie, value) {
  const {position} = enemie;
  const gridSize = map.length;

  const [x, y] = position;
  const MIN = 0;
  const MAX = gridSize - 1;

  switch (enemie.direction) {
  case 'north':
    mapLine(map, value, [x, y], [x, MIN]);
    break;
  case 'south':
    mapLine(map, value, [x, y], [x, MAX]);
    break;
  case 'east':
    mapLine(map, value, [x, y], [MAX, y]);
    break;
  case 'west':
    mapLine(map, value, [x, y], [MIN, y]);
    break;
  default:
    console.log('WTF?');
  }

  return map;
}

function recursiveMapEnemie(ammo, map, enemie, value) {
  if (value > LOOK_INTO_THE_FUTURE) {
    return;
  }

  if (enemie.ammo > 0) {
    mapEnemie(map, enemie, value);
  }

  recursiveMapEnemie(
    ammo,
    map,
    playerMove(ammo, map.length, enemie),
    value + 1,
  );

  playerTurns(enemie, (enemieTurns) => {
    recursiveMapEnemie(
      ammo,
      map,
      playerMove(ammo, map.length, enemieTurns),
      value + 1,
    );
  });
}

function createMap(size, value = 0) {
  const BLANK = new Array(size).fill(value);

  let map = BLANK;
  map = map.map(() => BLANK.slice(0));
  return map;
}

function ai(player, enemies, game) {
  fixPos(player);

  if (utils.canKill(player, enemies) && player.ammo) {
    return 'shoot';
  }

  const map = createMap(game.gridSize, Infinity);

  enemies.forEach((enemie) => {
    fixPos(enemie);

    recursiveMapEnemie(game.ammoPosition, map, enemie, 1);
  });

  console.log(printMap(map, player));

  return whereToGo(map, player, enemies, game);

  /*
  let directionToAmmo;
  if (utils.canKill(player, enemies) && player.ammo) {
    return 'shoot';
  }

  if (game.ammoPosition.length) {
    directionToAmmo = utils.fastGetDirection(player.position, game.ammoPosition[0]);

    if (directionToAmmo !== player.direction) return directionToAmmo;
    return utils.safeRandomMove();
  }

  return 'move';
  */
}

module.exports = {
  info: {
    name: ':)',
    style: 2
  },
  ai,
  createMap,
  mapLine,
  mapEnemie,
  printMap,
  playerMove
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import { StyleSheet, View, Text } from 'react-native';
import Step from './Step';
const STEP = {
  increment: 'increment',
  decrement: 'decrement',
};
const TEXT_POSITION = {
  left: 'left',
  center: 'center',
  right: 'right',
};

export default class SimpleStepper extends Component {
  static propTypes = {
    initialValue: PropTypes.number,
    minimumValue: PropTypes.number,
    maximumValue: PropTypes.number,
    stepValue: PropTypes.number,
    valueChanged: PropTypes.func,
    activeOpacity: PropTypes.number,
    disabledOpacity: PropTypes.number,
    incrementImage: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    decrementImage: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    disabled: PropTypes.bool,
    renderDecrementImage: PropTypes.func,
    renderIncrementImage: PropTypes.func,
    renderDecrementStep: PropTypes.func,
    renderIncrementStep: PropTypes.func,
    wraps: PropTypes.bool,
    onMin: PropTypes.func,
    onMax: PropTypes.func,
    onIncrement: PropTypes.func,
    onDecrement: PropTypes.func,
    showText: PropTypes.bool,
    renderText: PropTypes.func,
    textStyle: PropTypes.object,
    containerStyle: PropTypes.object,
    separatorStyle: PropTypes.object,
    incrementStepStyle: PropTypes.object,
    decrementStepStyle: PropTypes.object,
    incrementImageStyle: PropTypes.object,
    decrementImageStyle: PropTypes.object,
    textPosition: PropTypes.oneOfType([TEXT_POSITION.left, TEXT_POSITION.center, TEXT_POSITION.right]),
  };
  static defaultProps = {
    initialValue: 0,
    minimumValue: 0,
    maximumValue: 10,
    stepValue: 1,
    valueChanged: () => {},
    decrementImage: require('./assets/decrement.png'),
    incrementImage: require('./assets/increment.png'),
    activeOpacity: 0.4,
    disabledOpacity: 0.5,
    disabled: false,
    renderDecrementImage: undefined,
    renderIncrementImage: undefined,
    renderDecrementStep: undefined,
    renderIncrementStep: undefined,
    wraps: false,
    onMin: () => {},
    onMax: () => {},
    onIncrement: () => {},
    onDecrement: () => {},
    showText: false,
    renderText: undefined,
    textStyle: {
      padding: 8,
      fontSize: 20,
      fontWeight: 'bold',
      color: 'blue',
    },
    containerStyle: {
      backgroundColor: 'transparent',
      flexDirection: 'row',
      borderWidth: 2,
      borderRadius: 8,
      overflow: 'hidden',
      alignItems: 'center',
      borderColor: 'blue',
    },
    separatorStyle: {
      width: StyleSheet.hairlineWidth,
      backgroundColor: 'blue',
      height: '100%',
    },
    incrementStepStyle: {
      padding: 8,
    },
    decrementStepStyle: {
      padding: 8,
    },
    incrementImageStyle: {
      height: 36,
      width: 36,
    },
    decrementImageStyle: {
      height: 36,
      width: 36,
    },
    textPosition: TEXT_POSITION.center,
  };
  constructor(props) {
    super(props);
    this.state = {
      value: props.initialValue,
    };
    this.validateValue(props.initialValue, props);
  }
  componentWillReceiveProps(nextProps) {
    const { initialValue, stepValue, minimumValue, maximumValue, disabled } = this.props;
    const { value } = this.state;
    if (nextProps.initialValue !== initialValue) {
      this.validateValue(nextProps.initialValue, nextProps, nextProps.value !== nextProps.initialValue);
    } else if (nextProps.disabled !== disabled || nextProps.stepValue !== stepValue) {
      this.validateValue(value, nextProps);
    } else if (nextProps.minimumValue !== minimumValue || nextProps.maximumValue !== maximumValue) {
      const isOkay = nextProps.minimumValue < nextProps.maximumValue;
      if (isOkay) {
        this.validateValue(value, nextProps);
      }
    }
  }
  setValue = value => {
    this.validateValue(value, this.props, this.state.value !== value);
  };
  decrementAction = () => {
    const { stepValue, onDecrement } = this.props;
    const { value } = this.state;
    const nextValue = value - stepValue;
    this.validateValue(nextValue, this.props, true, onDecrement);
  };
  incrementAction = () => {
    const { stepValue, onIncrement } = this.props;
    const { value } = this.state;
    const nextValue = value + stepValue;
    this.validateValue(nextValue, this.props, true, onIncrement);
  };
  validateValue = (value, props, changed = false, onAction = () => {}) => {
    const { minimumValue, maximumValue, wraps, valueChanged, onMin, onMax } = props;
    const { hasReachedMin, hasReachedMax } = this._getHasMinMax(value);
    if (value > maximumValue) {
      value = wraps ? minimumValue : maximumValue;
    } else if (value == maximumValue) {
      value = maximumValue;
    } else if (value < minimumValue) {
      value = wraps ? maximumValue : minimumValue;
    } else if (value == minimumValue) {
      value = minimumValue;
    }
    onAction(value);
    if (hasReachedMin) {
      onMin(value);
    }
    if (hasReachedMax) {
      onMax(value);
    }
    if (changed) {
      valueChanged(value);
      this.setState({ value });
    }
  };
  _getHasMinMax = value => {
    const { minimumValue, maximumValue, stepValue, wraps } = this.props;
    let hasReachedMax = true;
    let hasReachedMin = true;
    switch (true) {
      case wraps:
        hasReachedMin = false;
        hasReachedMax = false;
        break;
      case stepValue >= 0:
        hasReachedMax = value >= maximumValue;
        hasReachedMin = value <= minimumValue;
        break;
      case stepValue < 0:
        // step value is negative
        // swap the max and min conditions.
        hasReachedMax = value <= minimumValue;
        hasReachedMin = value >= maximumValue;
        break;
    }
    return {
      hasReachedMax,
      hasReachedMin,
    };
  };
  _getImageSource = (type, source) => {
    if (typeof source == 'string') {
      if (source.length == 0) {
        if (type == STEP.decrement) {
          return require('./assets/decrement.png');
        } else if (type == STEP.increment) {
          return require('./assets/increment.png');
        }
      } else {
        return { uri: source };
      }
    }
    return source;
  };
  _getImageViewProps = (type, opacity) => {
    let style = {
      height: 36,
      width: 36,
    };
    let imageSource = null;
    switch (type) {
      case STEP.increment:
        const { incrementImageStyle, incrementImage } = this.props;
        style = incrementImageStyle;
        imageSource = incrementImage;
        break;
      case STEP.decrement:
        const { decrementImageStyle, decrementImage } = this.props;
        style = decrementImageStyle;
        imageSource = decrementImage;
        break;
    }
    return {
      style,
      opacity,
      source: this._getImageSource(type, imageSource),
    };
  };
  _renderText = (value, renderText, textStyle) => {
    if (renderText) {
      return renderText(value);
    }
    return <Text style={textStyle}>{value}</Text>;
  };
  render() {
    const {
      activeOpacity,
      disabled,
      disabledOpacity,
      showText,
      renderText,
      containerStyle,
      separatorStyle,
      textStyle,
      incrementStepStyle,
      decrementStepStyle,
      renderIncrementImage,
      renderDecrementImage,
      renderDecrementStep,
      renderIncrementStep,
      textPosition,
    } = this.props;
    const { value } = this.state;
    const { hasReachedMin, hasReachedMax } = this._getHasMinMax(value);
    const decrementOpacity = hasReachedMin || disabled ? disabledOpacity : 1;
    const incrementOpacity = hasReachedMax || disabled ? disabledOpacity : 1;
    const decrementImageProps = this._getImageViewProps(STEP.decrement, decrementOpacity);
    const incrementImageProps = this._getImageViewProps(STEP.increment, incrementOpacity);
    const isLeft = showText && textPosition == TEXT_POSITION.left;
    const isCenter = showText && textPosition == TEXT_POSITION.center;
    const isRight = showText && textPosition == TEXT_POSITION.right;
    return (
      <View>
        <View style={containerStyle}>
          {isLeft && this._renderText(value, renderText, textStyle)}
          {isLeft && <View style={separatorStyle} />}
          {renderDecrementStep
            ? renderDecrementStep(this.props)
            : <Step
                style={decrementStepStyle}
                activeOpacity={activeOpacity}
                onPress={this.decrementAction}
                disabled={hasReachedMin || disabled}
                renderImage={renderIncrementImage}
                imageStyle={decrementImageProps.style}
                imageOpacity={decrementImageProps.opacity}
                imageSource={decrementImageProps.source}
              />}
          {isCenter && <View style={separatorStyle} />}
          {isCenter && this._renderText(value, renderText, textStyle)}
          <View style={separatorStyle} />
          {renderIncrementStep
            ? renderIncrementStep(this.props)
            : <Step
                style={incrementStepStyle}
                activeOpacity={activeOpacity}
                onPress={this.incrementAction}
                disabled={hasReachedMax || disabled}
                renderImage={renderDecrementImage}
                imageStyle={incrementImageProps.style}
                imageOpacity={incrementImageProps.opacity}
                imageSource={incrementImageProps.source}
              />}
          {isRight && <View style={separatorStyle} />}
          {isRight && this._renderText(value, renderText, textStyle)}
        </View>
      </View>
    );
  }
}
<commit_msg>make componentWillRecieveProp unsafe<commit_after>import React, { Component } from 'react';
import { PropTypes } from 'prop-types';
import { StyleSheet, View, Text } from 'react-native';
import Step from './Step';
const STEP = {
  increment: 'increment',
  decrement: 'decrement',
};
const TEXT_POSITION = {
  left: 'left',
  center: 'center',
  right: 'right',
};

export default class SimpleStepper extends Component {
  static propTypes = {
    initialValue: PropTypes.number,
    minimumValue: PropTypes.number,
    maximumValue: PropTypes.number,
    stepValue: PropTypes.number,
    valueChanged: PropTypes.func,
    activeOpacity: PropTypes.number,
    disabledOpacity: PropTypes.number,
    incrementImage: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    decrementImage: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    disabled: PropTypes.bool,
    renderDecrementImage: PropTypes.func,
    renderIncrementImage: PropTypes.func,
    renderDecrementStep: PropTypes.func,
    renderIncrementStep: PropTypes.func,
    wraps: PropTypes.bool,
    onMin: PropTypes.func,
    onMax: PropTypes.func,
    onIncrement: PropTypes.func,
    onDecrement: PropTypes.func,
    showText: PropTypes.bool,
    renderText: PropTypes.func,
    textStyle: PropTypes.object,
    containerStyle: PropTypes.object,
    separatorStyle: PropTypes.object,
    incrementStepStyle: PropTypes.object,
    decrementStepStyle: PropTypes.object,
    incrementImageStyle: PropTypes.object,
    decrementImageStyle: PropTypes.object,
    textPosition: PropTypes.oneOfType([TEXT_POSITION.left, TEXT_POSITION.center, TEXT_POSITION.right]),
  };
  static defaultProps = {
    initialValue: 0,
    minimumValue: 0,
    maximumValue: 10,
    stepValue: 1,
    valueChanged: () => {},
    decrementImage: require('./assets/decrement.png'),
    incrementImage: require('./assets/increment.png'),
    activeOpacity: 0.4,
    disabledOpacity: 0.5,
    disabled: false,
    renderDecrementImage: undefined,
    renderIncrementImage: undefined,
    renderDecrementStep: undefined,
    renderIncrementStep: undefined,
    wraps: false,
    onMin: () => {},
    onMax: () => {},
    onIncrement: () => {},
    onDecrement: () => {},
    showText: false,
    renderText: undefined,
    textStyle: {
      padding: 8,
      fontSize: 20,
      fontWeight: 'bold',
      color: 'blue',
    },
    containerStyle: {
      backgroundColor: 'transparent',
      flexDirection: 'row',
      borderWidth: 2,
      borderRadius: 8,
      overflow: 'hidden',
      alignItems: 'center',
      borderColor: 'blue',
    },
    separatorStyle: {
      width: StyleSheet.hairlineWidth,
      backgroundColor: 'blue',
      height: '100%',
    },
    incrementStepStyle: {
      padding: 8,
    },
    decrementStepStyle: {
      padding: 8,
    },
    incrementImageStyle: {
      height: 36,
      width: 36,
    },
    decrementImageStyle: {
      height: 36,
      width: 36,
    },
    textPosition: TEXT_POSITION.center,
  };
  constructor(props) {
    super(props);
    this.state = {
      value: props.initialValue,
    };
    this.validateValue(props.initialValue, props);
  }
  UNSAFE_componentWillReceiveProp(nextProps) {
    const { initialValue, stepValue, minimumValue, maximumValue, disabled } = this.props;
    const { value } = this.state;
    if (nextProps.initialValue !== initialValue) {
      this.validateValue(nextProps.initialValue, nextProps, nextProps.value !== nextProps.initialValue);
    } else if (nextProps.disabled !== disabled || nextProps.stepValue !== stepValue) {
      this.validateValue(value, nextProps);
    } else if (nextProps.minimumValue !== minimumValue || nextProps.maximumValue !== maximumValue) {
      const isOkay = nextProps.minimumValue < nextProps.maximumValue;
      if (isOkay) {
        this.validateValue(value, nextProps);
      }
    }
  }
  setValue = value => {
    this.validateValue(value, this.props, this.state.value !== value);
  };
  decrementAction = () => {
    const { stepValue, onDecrement } = this.props;
    const { value } = this.state;
    const nextValue = value - stepValue;
    this.validateValue(nextValue, this.props, true, onDecrement);
  };
  incrementAction = () => {
    const { stepValue, onIncrement } = this.props;
    const { value } = this.state;
    const nextValue = value + stepValue;
    this.validateValue(nextValue, this.props, true, onIncrement);
  };
  validateValue = (value, props, changed = false, onAction = () => {}) => {
    const { minimumValue, maximumValue, wraps, valueChanged, onMin, onMax } = props;
    const { hasReachedMin, hasReachedMax } = this._getHasMinMax(value);
    if (value > maximumValue) {
      value = wraps ? minimumValue : maximumValue;
    } else if (value == maximumValue) {
      value = maximumValue;
    } else if (value < minimumValue) {
      value = wraps ? maximumValue : minimumValue;
    } else if (value == minimumValue) {
      value = minimumValue;
    }
    onAction(value);
    if (hasReachedMin) {
      onMin(value);
    }
    if (hasReachedMax) {
      onMax(value);
    }
    if (changed) {
      valueChanged(value);
      this.setState({ value });
    }
  };
  _getHasMinMax = value => {
    const { minimumValue, maximumValue, stepValue, wraps } = this.props;
    let hasReachedMax = true;
    let hasReachedMin = true;
    switch (true) {
      case wraps:
        hasReachedMin = false;
        hasReachedMax = false;
        break;
      case stepValue >= 0:
        hasReachedMax = value >= maximumValue;
        hasReachedMin = value <= minimumValue;
        break;
      case stepValue < 0:
        // step value is negative
        // swap the max and min conditions.
        hasReachedMax = value <= minimumValue;
        hasReachedMin = value >= maximumValue;
        break;
    }
    return {
      hasReachedMax,
      hasReachedMin,
    };
  };
  _getImageSource = (type, source) => {
    if (typeof source == 'string') {
      if (source.length == 0) {
        if (type == STEP.decrement) {
          return require('./assets/decrement.png');
        } else if (type == STEP.increment) {
          return require('./assets/increment.png');
        }
      } else {
        return { uri: source };
      }
    }
    return source;
  };
  _getImageViewProps = (type, opacity) => {
    let style = {
      height: 36,
      width: 36,
    };
    let imageSource = null;
    switch (type) {
      case STEP.increment:
        const { incrementImageStyle, incrementImage } = this.props;
        style = incrementImageStyle;
        imageSource = incrementImage;
        break;
      case STEP.decrement:
        const { decrementImageStyle, decrementImage } = this.props;
        style = decrementImageStyle;
        imageSource = decrementImage;
        break;
    }
    return {
      style,
      opacity,
      source: this._getImageSource(type, imageSource),
    };
  };
  _renderText = (value, renderText, textStyle) => {
    if (renderText) {
      return renderText(value);
    }
    return <Text style={textStyle}>{value}</Text>;
  };
  render() {
    const {
      activeOpacity,
      disabled,
      disabledOpacity,
      showText,
      renderText,
      containerStyle,
      separatorStyle,
      textStyle,
      incrementStepStyle,
      decrementStepStyle,
      renderIncrementImage,
      renderDecrementImage,
      renderDecrementStep,
      renderIncrementStep,
      textPosition,
    } = this.props;
    const { value } = this.state;
    const { hasReachedMin, hasReachedMax } = this._getHasMinMax(value);
    const decrementOpacity = hasReachedMin || disabled ? disabledOpacity : 1;
    const incrementOpacity = hasReachedMax || disabled ? disabledOpacity : 1;
    const decrementImageProps = this._getImageViewProps(STEP.decrement, decrementOpacity);
    const incrementImageProps = this._getImageViewProps(STEP.increment, incrementOpacity);
    const isLeft = showText && textPosition == TEXT_POSITION.left;
    const isCenter = showText && textPosition == TEXT_POSITION.center;
    const isRight = showText && textPosition == TEXT_POSITION.right;
    return (
      <View>
        <View style={containerStyle}>
          {isLeft && this._renderText(value, renderText, textStyle)}
          {isLeft && <View style={separatorStyle} />}
          {renderDecrementStep
            ? renderDecrementStep(this.props)
            : <Step
                style={decrementStepStyle}
                activeOpacity={activeOpacity}
                onPress={this.decrementAction}
                disabled={hasReachedMin || disabled}
                renderImage={renderIncrementImage}
                imageStyle={decrementImageProps.style}
                imageOpacity={decrementImageProps.opacity}
                imageSource={decrementImageProps.source}
              />}
          {isCenter && <View style={separatorStyle} />}
          {isCenter && this._renderText(value, renderText, textStyle)}
          <View style={separatorStyle} />
          {renderIncrementStep
            ? renderIncrementStep(this.props)
            : <Step
                style={incrementStepStyle}
                activeOpacity={activeOpacity}
                onPress={this.incrementAction}
                disabled={hasReachedMax || disabled}
                renderImage={renderDecrementImage}
                imageStyle={incrementImageProps.style}
                imageOpacity={incrementImageProps.opacity}
                imageSource={incrementImageProps.source}
              />}
          {isRight && <View style={separatorStyle} />}
          {isRight && this._renderText(value, renderText, textStyle)}
        </View>
      </View>
    );
  }
}
<|endoftext|>


<commit_before>/*
 This file is part of MyConference.

 MyConference is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License version 3
 as published by the Free Software Foundation.

 This program 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 find a copy of the GNU Affero General Public License in the
 root directory along with this program.
 If not, see http://www.gnu.org/licenses/agpl-3.0.html.
 */
describe('Feedback', function () {
  var scope,
    backendServiceMock,
    ctrl,
    ionicPopupMock,
    attendedDeferred,
    resolveDeferred,
    eventDeferred,
    alreadyFeedbackedDeferred;

  beforeEach(module('starter'));
  beforeEach(module(function ($provide, $urlRouterProvider) {
    $provide.value('$ionicTemplateCache', function () {
    });
    $urlRouterProvider.deferIntercept();
  }));
  beforeEach(inject(function ($rootScope, $controller, $q, $httpBackend) {
    $httpBackend.whenGET('locales/de.json').respond(200, '');

    attendedDeferred = $q.defer();
    alreadyFeedbackedDeferred = $q.defer();
    eventDeferred = $q.defer();
    resolveDeferred = $q.defer();
    resolveDeferred.resolve([]);
    backendServiceMock = {
      isCurrentUserOrganizer: jasmine.createSpy("isCurrentUserOrganizer").and.returnValue(resolveDeferred.promise),
      getEventById: jasmine.createSpy("getEventById").and.returnValue(eventDeferred.promise),
      isCurrentUserRegisteredForEvent: jasmine.createSpy("isCurrentUserRegisteredForEvent").and.returnValue(resolveDeferred.promise),
      isCurrentUserAttendedForEvent: jasmine.createSpy("isCurrentUserAttendedForEvent").and.returnValue(attendedDeferred.promise),
      getFileDetails: jasmine.createSpy("getFileDetails").and.returnValue(resolveDeferred),
      loadAgendaWithParams: jasmine.createSpy("loadAgendaWithParams").and.returnValue(resolveDeferred.promise),
      uploadFile: jasmine.createSpy("uploadFile").and.returnValue(resolveDeferred.promise),
      deleteFile: jasmine.createSpy("deleteFile").and.returnValue(resolveDeferred.promise),
      addCurrentUserToEvent: jasmine.createSpy("addCurrentUserToEvent").and.returnValue(resolveDeferred.promise),
      getOrganisers: jasmine.createSpy("getOrganisers").and.returnValue(resolveDeferred.promise),
      currentUser: jasmine.createSpy("currentUser").and.returnValue(resolveDeferred.promise),
      sendPushNotificationToUsers: jasmine.createSpy("sendPushNotificationToUsers").and.returnValue(resolveDeferred.promise),
      removeCurrentUserFromEvent: jasmine.createSpy("removeCurrentUserFromEvent").and.returnValue(resolveDeferred.promise),
      deleteAgenda: jasmine.createSpy("deleteAgenda").and.returnValue(resolveDeferred.promise),
      deleteEvent: jasmine.createSpy("deleteEvent").and.returnValue(resolveDeferred.promise),
      hasCurrentUserAlreadyGivenFeedback: jasmine.createSpy("hasCurrentUserAlreadyGivenFeedback").and.returnValue(alreadyFeedbackedDeferred.promise),
      getUser: jasmine.createSpy("getUser").and.returnValue(resolveDeferred.promise),
      fetchCurrentUser: jasmine.createSpy("fetchCurrentUser").and.returnValue(resolveDeferred.promise),
      addingAgenda: jasmine.createSpy("addingAgenda").and.returnValue(resolveDeferred.promise)
    };

    ionicPopupMock = jasmine.createSpyObj('$ionicPopup spy', ['alert']);
    scope = $rootScope.$new();
    ctrl = $controller('EventCtrl', {
      $scope: scope,
      $ionicPopup: ionicPopupMock,
      backendService: backendServiceMock,
      $stateParams: {eventId: 1}
    });

    now = new Date(2016, 6, 4, 13, 22, 9);
    jasmine.clock().mockDate(now);
    twoDaysAgo = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 2, 0, 0, 0);
    today = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
    inThreeDays = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 3, 0, 0, 0);
    threeHoursBefore = new Date(0, 0, 0, now.getHours() - 3, now.getMinutes(), now.getSeconds());
    oneHourBefore = new Date(0, 0, 0, now.getHours() - 1, now.getMinutes(), now.getSeconds());
    fiveMinutesAfter = new Date(0, 0, 0, now.getHours(), now.getMinutes() + 5, now.getSeconds());
    fourHoursAfter = new Date(0, 0, 0, now.getHours() + 4, now.getMinutes(), now.getSeconds());
  }));

  describe("isFeedbackAllowed", function () {
    describe("with attended user who did not feedbacked", function () {
      beforeEach(function () {
        attendedDeferred.resolve(true);
        alreadyFeedbackedDeferred.resolve(false);
      });
      it("should not display the Feedback button for future event", function () {
        eventDeferred.resolve(
          {
            'data': {
              "title": "test",
              "date": inThreeDays.toISOString(),
              "begin": oneHourBefore,
              "end": fourHoursAfter
            }
          }
        );
        scope.$digest();
        expect(scope.isFeedbackAllowed).toBe(false);
      });

      it("should display the Feedback button for current event", function () {
        eventDeferred.resolve({
          'data': {
            "title": "test",
            "date": today.toISOString(),
            "begin": oneHourBefore,
            "end": fiveMinutesAfter
          }
        });
        scope.$digest();
        expect(scope.isFeedbackAllowed).toBe(true);
      });

      it("should display the Feedback button for event that ended less than 48h ago", function () {
        eventDeferred.resolve({
          'data': {
            "title": "test",
            "date": twoDaysAgo.toISOString(),
            "begin": oneHourBefore,
            "end": fourHoursAfter
          }
        });
        scope.$digest();
        expect(scope.isFeedbackAllowed).toBe(true);
      });

      it("should not display the Feedback button for event that ended more than 48h ago", function () {
        eventDeferred.resolve({
          'data': {
            "title": "test",
            "date": twoDaysAgo.toISOString(),
            "begin": threeHoursBefore,
            "end": oneHourBefore
          }
        });
        scope.$digest();
        expect(scope.isFeedbackAllowed).toBe(false);
      });
    });

    describe("with attended user who already feedbacked", function () {
      beforeEach(function () {
        attendedDeferred.resolve(true);
        alreadyFeedbackedDeferred.resolve(true);
      });
      it("should not display the Feedback button for attended user who already feedbacked", function () {
        eventDeferred.resolve(
          {
            'data': {
              "title": "test",
              "date": inThreeDays.toISOString(),
              "begin": oneHourBefore,
              "end": fourHoursAfter
            }
          }
        );
        scope.$digest();
        expect(scope.isFeedbackAllowed).toBe(false);
      });
    });

    describe("with not attended user", function () {
      beforeEach(function () {
        attendedDeferred.resolve(false);
        alreadyFeedbackedDeferred.resolve(false);
      });
      it("should not display the Feedback button for unattended user", function () {
        eventDeferred.resolve(
          {
            'data': {
              "title": "test",
              "date": inThreeDays.toISOString(),
              "begin": oneHourBefore,
              "end": fourHoursAfter
            }
          }
        );
        scope.$digest();
        expect(scope.isFeedbackAllowed).toBe(false);
      });
    });
  })

  describe("areFeedbackResultsVisible", function () {
    beforeEach(function () {
      attendedDeferred.resolve(true);
      alreadyFeedbackedDeferred.resolve(false);
    });
    it("should not display the Feedback results button for future event", function () {
      eventDeferred.resolve(
        {
          'data': {
            "title": "test",
            "date": inThreeDays,
            "begin": oneHourBefore,
            "end": fourHoursAfter
          }
        }
      );
      scope.$digest();
      expect(scope.areFeedbackResultsVisible).toBe(false);
    });

    it("should not display the Feedback results button for current event", function () {
      eventDeferred.resolve({
        'data': {
          "title": "test",
          "date": today,
          "begin": oneHourBefore,
          "end": fiveMinutesAfter
        }
      });
      scope.$digest();
      expect(scope.areFeedbackResultsVisible).toBe(false);
    });

    it("should display the Feedback results button for event that ended", function () {
      eventDeferred.resolve({
        'data': {
          "title": "test",
          "date": today,
          "begin": threeHoursBefore,
          "end": oneHourBefore
        }
      });
      scope.$digest();
      expect(scope.areFeedbackResultsVisible).toBe(true);
    });
  })
});
<commit_msg>Removed feedback.test.js due to Failed status<commit_after><|endoftext|>


<commit_before>var traverse = require("../../traverse");
var util     = require("../../util");
var t        = require("../../types");

exports.ClassDeclaration = function (node, parent, file, scope) {
  return new Class(node, file, scope, true).run();
};

exports.ClassExpression = function (node, parent, file, scope) {
  return new Class(node, file, scope, false).run();
};

/**
 * Description
 *
 * @param {Node} node
 * @param {File} file
 * @param {Scope} scope
 * @param {Boolean} closure
 */

function Class(node, file, scope, isStatement) {
  this.isStatement = isStatement;
  this.scope       = scope;
  this.node        = node;
  this.file        = file;

  this.hasInstanceMutators = false;
  this.hasStaticMutators   = false;

  this.instanceMutatorMap = {};
  this.staticMutatorMap   = {};
  this.hasConstructor     = false;
  this.className          = node.id || file.generateUidIdentifier("class", scope);
  this.superName          = node.superClass;
}

/**
 * Description
 *
 * @returns {Array}
 */

Class.prototype.run = function () {
  var superName = this.superName;
  var className = this.className;
  var file      = this.file;

  //

  var body = this.body = [];

  var constructor;
  if (this.node.id) {
    constructor = t.functionDeclaration(className, [], t.blockStatement([]));
    body.push(constructor);
  } else {
    constructor = t.functionExpression(null, [], t.blockStatement([]));
    body.push(t.variableDeclaration("var", [
      t.variableDeclarator(className, constructor)
    ]));
  }
  this.constructor = constructor;

  var closureArgs = [];
  var closureParams = [];

  //

  if (superName) {
    closureArgs.push(superName);

    if (!t.isIdentifier(superName)) {
      var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
      superName = superRef;
    }

    closureParams.push(superName);

    this.superName = superName;
    body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
  }

  this.buildBody();

  t.inheritsComments(body[0], this.node);

  var init;

  if (body.length === 1) {
    // only a constructor so no need for a closure container
    init = t.toExpression(constructor);
  } else {
    body.push(t.returnStatement(className));
    init = t.callExpression(
      t.functionExpression(null, closureParams, t.blockStatement(body)),
      closureArgs
    );
  }

  if (this.isStatement) {
    return t.variableDeclaration("let", [
      t.variableDeclarator(className, init)
    ]);
  } else {
    return init;
  }
};

/**
 * Description
 */

Class.prototype.buildBody = function () {
  var constructor = this.constructor;
  var className   = this.className;
  var superName   = this.superName;
  var classBody   = this.node.body.body;
  var body        = this.body;
  var self        = this;

  for (var i in classBody) {
    var node = classBody[i];
    if (t.isMethodDefinition(node)) {
      self.replaceInstanceSuperReferences(node);

      if (node.key.name === "constructor") {
        self.pushConstructor(node);
      } else {
        self.pushMethod(node);
      }
    } else if (t.isPrivateDeclaration(node)) {
      self.closure = true;
      body.unshift(node);
    }
  }

  if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) {
    constructor.body.body.push(util.template("class-super-constructor-call", {
      CLASS_NAME: className
    }, true));
  }

  var instanceProps;
  var staticProps;

  if (this.hasInstanceMutators) {
    instanceProps = util.buildDefineProperties(this.instanceMutatorMap);
  }

  if (this.hasStaticMutators) {
    staticProps = util.buildDefineProperties(this.staticMutatorMap);
  }

  if (instanceProps || staticProps) {
    staticProps = staticProps || t.literal(null);

    var args = [className, staticProps];
    if (instanceProps) args.push(instanceProps);

    body.push(t.expressionStatement(
      t.callExpression(this.file.addHelper("prototype-properties"), args)
    ));
  }
};

/**
 * Push a method to it's respective mutatorMap.
 *
 * @param {Node} node MethodDefinition
 */

Class.prototype.pushMethod = function (node) {
  var methodName = node.key;

  var kind = node.kind;
  var mutatorMap = this.instanceMutatorMap;
  if (node.static) {
    this.hasStaticMutators = true;
    mutatorMap = this.staticMutatorMap;
  } else {
    this.hasInstanceMutators = true;
  }

  if (kind === "") {
    kind = "value";
  }

  util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
};

/**
 * Gets a node representing the super class value of the named property.
 *
 * @example
 *
 *   _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
 *
 * @param {Node} property
 * @param {boolean} isStatic
 * @param {boolean} isComputed
 *
 * @returns {Node}
 */

Class.prototype.superProperty = function (property, isStatic, isComputed, thisExpression) {
  return t.callExpression(
    this.file.addHelper("get"),
    [
      t.callExpression(
        t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
        [
          isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
        ]
      ),
      isComputed ? property : t.literal(property.name),
      thisExpression
    ]
  );
};

/**
 * Replace all `super` references with a reference to our `superClass`.
 *
 * @param {Node} methodNode MethodDefinition
 */

Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
  var method = methodNode.value;
  var self   = this;

  traverse(method, {
    enter: function (node, parent) {
      var property;
      var computed;
      var args;

      if (t.isIdentifier(node, { name: "super" })) {
        if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
          throw self.file.errorWithNode(node, "illegal use of bare super");
        }
      } else if (t.isCallExpression(node)) {
        var callee = node.callee;
        if (t.isIdentifier(callee, { name: "super" })) {
          // super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
          property = methodNode.key;
          computed = methodNode.computed;
          args = node.arguments;
        } else {
          if (!t.isMemberExpression(callee)) return;
          if (callee.object.name !== "super") return;

          // super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
          property = callee.property;
          computed = callee.computed;
          args = node.arguments;
        }
      } else if (t.isMemberExpression(node)) {
        if (!t.isIdentifier(node.object, { name: "super" })) return;

        // super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
        property = node.property;
        computed = node.computed;
      }

      if (property) {
        var thisExpression = t.thisExpression();
        var superProperty = self.superProperty(property, methodNode.static, computed, thisExpression);
        if (args) {
          return t.callExpression(
            t.memberExpression(superProperty, t.identifier("call"), false),
            [thisExpression].concat(args)
          );
        } else {
          return superProperty;
        }
      }
    }
  });
};

/**
 * Replace the constructor body of our class.
 *
 * @param {Node} method MethodDefinition
 */

Class.prototype.pushConstructor = function (method) {
  if (method.kind) {
    throw this.file.errorWithNode(method, "illegal kind for constructor method");
  }

  var construct = this.constructor;
  var fn        = method.value;

  this.hasConstructor = true;

  t.inherits(construct, fn);
  t.inheritsComments(construct, method);

  construct._ignoreUserWhitespace = true;
  construct.defaults              = fn.defaults;
  construct.params                = fn.params;
  construct.body                  = fn.body;
  construct.rest                  = fn.rest;
};
<commit_msg>add support for super instead of closures - fixes #425<commit_after>var traverse = require("../../traverse");
var util     = require("../../util");
var t        = require("../../types");

exports.ClassDeclaration = function (node, parent, file, scope) {
  return new Class(node, file, scope, true).run();
};

exports.ClassExpression = function (node, parent, file, scope) {
  return new Class(node, file, scope, false).run();
};

/**
 * Description
 *
 * @param {Node} node
 * @param {File} file
 * @param {Scope} scope
 * @param {Boolean} closure
 */

function Class(node, file, scope, isStatement) {
  this.isStatement = isStatement;
  this.scope       = scope;
  this.node        = node;
  this.file        = file;

  this.hasInstanceMutators = false;
  this.hasStaticMutators   = false;

  this.instanceMutatorMap = {};
  this.staticMutatorMap   = {};
  this.hasConstructor     = false;
  this.className          = node.id || file.generateUidIdentifier("class", scope);
  this.superName          = node.superClass;
}

/**
 * Description
 *
 * @returns {Array}
 */

Class.prototype.run = function () {
  var superName = this.superName;
  var className = this.className;
  var file      = this.file;

  //

  var body = this.body = [];

  var constructor;
  if (this.node.id) {
    constructor = t.functionDeclaration(className, [], t.blockStatement([]));
    body.push(constructor);
  } else {
    constructor = t.functionExpression(null, [], t.blockStatement([]));
    body.push(t.variableDeclaration("var", [
      t.variableDeclarator(className, constructor)
    ]));
  }
  this.constructor = constructor;

  var closureParams = [];
  var closureArgs = [];

  //

  if (superName) {
    closureArgs.push(superName);

    if (!t.isIdentifier(superName)) {
      var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
      superName = superRef;
    }

    closureParams.push(superName);

    this.superName = superName;
    body.push(t.expressionStatement(t.callExpression(file.addHelper("inherits"), [className, superName])));
  }

  this.buildBody();

  t.inheritsComments(body[0], this.node);

  var init;

  if (body.length === 1) {
    // only a constructor so no need for a closure container
    init = t.toExpression(constructor);
  } else {
    body.push(t.returnStatement(className));
    init = t.callExpression(
      t.functionExpression(null, closureParams, t.blockStatement(body)),
      closureArgs
    );
  }

  if (this.isStatement) {
    return t.variableDeclaration("let", [
      t.variableDeclarator(className, init)
    ]);
  } else {
    return init;
  }
};

/**
 * Description
 */

Class.prototype.buildBody = function () {
  var constructor = this.constructor;
  var className   = this.className;
  var superName   = this.superName;
  var classBody   = this.node.body.body;
  var body        = this.body;
  var self        = this;

  for (var i in classBody) {
    var node = classBody[i];
    if (t.isMethodDefinition(node)) {
      self.replaceInstanceSuperReferences(node);

      if (node.key.name === "constructor") {
        self.pushConstructor(node);
      } else {
        self.pushMethod(node);
      }
    } else if (t.isPrivateDeclaration(node)) {
      self.closure = true;
      body.unshift(node);
    }
  }

  if (!this.hasConstructor && superName && !t.isFalsyExpression(superName)) {
    constructor.body.body.push(util.template("class-super-constructor-call", {
      CLASS_NAME: className
    }, true));
  }

  var instanceProps;
  var staticProps;

  if (this.hasInstanceMutators) {
    instanceProps = util.buildDefineProperties(this.instanceMutatorMap);
  }

  if (this.hasStaticMutators) {
    staticProps = util.buildDefineProperties(this.staticMutatorMap);
  }

  if (instanceProps || staticProps) {
    staticProps = staticProps || t.literal(null);

    var args = [className, staticProps];
    if (instanceProps) args.push(instanceProps);

    body.push(t.expressionStatement(
      t.callExpression(this.file.addHelper("prototype-properties"), args)
    ));
  }
};

/**
 * Push a method to it's respective mutatorMap.
 *
 * @param {Node} node MethodDefinition
 */

Class.prototype.pushMethod = function (node) {
  var methodName = node.key;

  var kind = node.kind;
  var mutatorMap = this.instanceMutatorMap;
  if (node.static) {
    this.hasStaticMutators = true;
    mutatorMap = this.staticMutatorMap;
  } else {
    this.hasInstanceMutators = true;
  }

  if (kind === "") {
    kind = "value";
  }

  util.pushMutatorMap(mutatorMap, methodName, kind, node.computed, node);
};

/**
 * Gets a node representing the super class value of the named property.
 *
 * @example
 *
 *   _get(Object.getPrototypeOf(CLASS.prototype), "METHOD", this)
 *
 * @param {Node} property
 * @param {boolean} isStatic
 * @param {boolean} isComputed
 *
 * @returns {Node}
 */

Class.prototype.superProperty = function (property, isStatic, isComputed, thisExpression) {
  return t.callExpression(
    this.file.addHelper("get"),
    [
      t.callExpression(
        t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
        [
          isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
        ]
      ),
      isComputed ? property : t.literal(property.name),
      thisExpression
    ]
  );
};

/**
 * Replace all `super` references with a reference to our `superClass`.
 *
 * @param {Node} methodNode MethodDefinition
 */

Class.prototype.replaceInstanceSuperReferences = function (methodNode) {
  var method = methodNode.value;
  var self   = this;

  var topLevelThisReference;

  traverse2(method, true);

  if (topLevelThisReference) {
    method.body.body.unshift(t.variableDeclaration("var", [
      t.variableDeclarator(topLevelThisReference, t.thisExpression())
    ]));
  }

  function traverse2(node, topLevel) {
    traverse(node, {
      enter: function (node, parent) {
        if (t.isFunction(node) && !t.isArrowFunctionExpression(node)) {
          traverse2(node, false);
          return this.skip();
        }

        var property;
        var computed;
        var args;

        if (t.isIdentifier(node, { name: "super" })) {
          if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
            throw self.file.errorWithNode(node, "illegal use of bare super");
          }
        } else if (t.isCallExpression(node)) {
          var callee = node.callee;
          if (t.isIdentifier(callee, { name: "super" })) {
            // super(); -> _get(Object.getPrototypeOf(ClassName), "MethodName", this).call(this);
            property = methodNode.key;
            computed = methodNode.computed;
            args = node.arguments;
          } else {
            if (!t.isMemberExpression(callee)) return;
            if (callee.object.name !== "super") return;

            // super.test(); -> _get(Object.getPrototypeOf(ClassName.prototype), "test", this).call(this);
            property = callee.property;
            computed = callee.computed;
            args = node.arguments;
          }
        } else if (t.isMemberExpression(node)) {
          if (!t.isIdentifier(node.object, { name: "super" })) return;

          // super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
          property = node.property;
          computed = node.computed;
        }

        if (property) {
          var thisReference;
          if (topLevel) {
            thisReference = t.thisExpression();
          } else {
            topLevelThisReference = thisReference = topLevelThisReference || self.file.generateUidIdentifier("this");
          }

          var superProperty = self.superProperty(property, methodNode.static, computed, thisReference);
          if (args) {
            return t.callExpression(
              t.memberExpression(superProperty, t.identifier("call"), false),
              [thisReference].concat(args)
            );
          } else {
            return superProperty;
          }
        }
      }
    });
  }
};

/**
 * Replace the constructor body of our class.
 *
 * @param {Node} method MethodDefinition
 */

Class.prototype.pushConstructor = function (method) {
  if (method.kind) {
    throw this.file.errorWithNode(method, "illegal kind for constructor method");
  }

  var construct = this.constructor;
  var fn        = method.value;

  this.hasConstructor = true;

  t.inherits(construct, fn);
  t.inheritsComments(construct, method);

  construct._ignoreUserWhitespace = true;
  construct.defaults              = fn.defaults;
  construct.params                = fn.params;
  construct.body                  = fn.body;
  construct.rest                  = fn.rest;
};
<|endoftext|>


<commit_before>( function( mw, $ ) { "use strict";
	mw.PluginManager.add( 'watermark', mw.KBaseComponent.extend({

		defaultConfig: {
			"parent": "videoHolder",
			"order": "3",
			"cssClass": "bottomLeft",
			"img": null,
			"href": null,
			"padding": null,
			"hideTimeout": 0
		},
		isSafeEnviornment: function(){
			return !!this.getConfig('img');
		},
		setup: function(){
			var _this = this;
			// support legacy position config:
			if( this.getConfig('watermarkPosition') ){
				this.setConfig('cssClass', this.getConfig('watermarkPosition'));
			}
			this.bind('AdSupport_StartAdPlayback', function(){
				_this.getComponent().hide();
			});
			this.bind('AdSupport_EndAdPlayback', function(){
				_this.getComponent().show();
			});

			if( this.getConfig('hideTimeout') != 0 ){

				this.bind('onChangeMediaDone playerReady', function(){
					_this.getComponent().show();
						_this.timeoutWatermark();
				});

			};
		},
		getComponent: function(){
			var _this = this;
			if(!this.$el){
				this.$el = $('<div />')
							.addClass ( this.getCssClass() )
							.append(
								$('<a />').attr({
									'href' : this.getConfig('href'),
									'target' : '_blank'
								})
								.click( function(){
									_this.getPlayer().sendNotification( 'watermarkClick' );
									return true;
								})
								.append(
									$('<img />').attr({
										'src': this.getConfig('img')
									})
								)
							);
				if( this.getConfig('padding') ){
					this.$el.css('padding', this.getConfig('padding') );
				}
			}
			return this.$el;
		},
		timeoutWatermark: function(){
			var _this = this;
			this.bind('firstPlay', function() {
				setTimeout(function () {
					_this.$el.fadeOut("slow");
				}, _this.getConfig('hideTimeout') * 1000)
			});
		}
	}));

})( window.mw, jQuery );
<commit_msg>#SUP-5808 #comment fix watermark path mapping #time 1h<commit_after>( function( mw, $ ) { "use strict";
	mw.PluginManager.add( 'watermark', mw.KBaseComponent.extend({

		defaultConfig: {
			"parent": "videoHolder",
			"order": "3",
			"cssClass": "bottomLeft",
			"img": null,
			"href": null,
			"padding": null,
			"hideTimeout": 0
		},
		isSafeEnviornment: function(){
			return this.getConfig('img') || this.getConfig('watermarkPath');
		},
		setup: function(){
			var _this = this;
			// support legacy position config:
			if( this.getConfig('watermarkPosition') ){
				this.setConfig('cssClass', this.getConfig('watermarkPosition'));
			}
			// support legacy path config:
			if( this.getConfig('watermarkPath') ){
				this.setConfig('img', this.getConfig('watermarkPath'));
			}
			this.bind('AdSupport_StartAdPlayback', function(){
				_this.getComponent().hide();
			});
			this.bind('AdSupport_EndAdPlayback', function(){
				_this.getComponent().show();
			});

			if( this.getConfig('hideTimeout') != 0 ){

				this.bind('onChangeMediaDone playerReady', function(){
					_this.getComponent().show();
						_this.timeoutWatermark();
				});

			}
		},
		getComponent: function(){
			var _this = this;
			if(!this.$el){
				this.$el = $('<div />')
							.addClass ( this.getCssClass() )
							.append(
								$('<a />').attr({
									'href' : this.getConfig('href'),
									'target' : '_blank'
								})
								.click( function(){
									_this.getPlayer().sendNotification( 'watermarkClick' );
									return true;
								})
								.append(
									$('<img />').attr({
										'src': this.getConfig('img')
									})
								)
							);
				if( this.getConfig('padding') ){
					this.$el.css('padding', this.getConfig('padding') );
				}
			}
			return this.$el;
		},
		timeoutWatermark: function(){
			var _this = this;
			this.bind('firstPlay', function() {
				setTimeout(function () {
					_this.$el.fadeOut("slow");
				}, _this.getConfig('hideTimeout') * 1000)
			});
		}
	}));

})( window.mw, jQuery );
<|endoftext|>


<commit_before>type marked$AlignFlag = 'left' | 'right' | 'center'

type marked$NodeCallback<T> = (e: ?Error, d: ?T) => void

class marked$Renderer {
  options: marked$MarkedOptions;
  code: (c: string, l: string) => string;
  blockquote: (q: string) => string;
  html: (h: string) => string;
  heading: (t: string, l: number) => string;
  hr: () => string;
  list: (b: string, o: boolean) => string;
  listitem: (t: string) => string;
  paragraph: (t: string) => string;
  table: (h: string, b: string) => string;
  tablerow: (c: string) => string;
  tablecell: (c: string, f: ?marked$AlignFlag) => string;
  heading: (t: string, l: number) => string;
  strong: (t: string) => string;
  em: (t: string) => string;
  codespan: (c: string) => string;
  br: () => string;
  del: (t: string) => string;
  link: (h: string, ti: string, te: string) => string;
  image: (h: string, ti: string, te: string) => string;
  text: (t: string) => string;
  constructor(o?: marked$MarkedOptions): marked$Renderer {
    return this;
  }
}

type marked$HighlightFunction =
  ((c: string, l: string, cb: marked$NodeCallback<string>) => void)
  | ((c: string, cb: marked$NodeCallback<string>) => void)
  | ((c: string, l?: string) => string)

type marked$MarkedOptions = {
  highlight?: marked$HighlightFunction;
  renderer?: marked$Renderer;
  gfm?: boolean;
  tables?: boolean;
  breaks?: boolean;
  pedantic?: boolean;
  sanitize?: boolean;
  smartLists?: boolean;
  smartypants?: boolean;
}

/*
 * marked$Tokens
 */

type marked$Space = { type: 'space'; }
type marked$Code = { type: 'code'; text: string; lang?: string; }
type marked$Heading = { type: 'heading'; depth: number; text: string; }
type marked$Table = { type: 'table'; header: string; align: Array<marked$AlignFlag> ; cells: Array<Array<string>> }
type marked$Hr = { type: 'hr'; }
type marked$BlockquoteStart = { type: 'blockquote_start' }
type marked$BlockquoteEnd = { type: 'blockquote_end' }
type marked$ListStart = { type: 'list_start' }
type marked$ListEnd = { type: 'list_end' }
type marked$Paragraph = { type: 'paragraph'; pre: boolean; text: string; }
type marked$Html = { type: 'paragraph'; pre: boolean; text: string; }
type marked$Text = { type: 'text'; text: string; }

type marked$Token =
  marked$Space
  | marked$Code
  | marked$Heading
  | marked$Table
  | marked$Hr
  | marked$BlockquoteStart
  | marked$BlockquoteEnd
  | marked$ListStart
  | marked$ListEnd
  | marked$Paragraph
  | marked$Html
  | marked$Text

type marked$Link = {
  title: ?string;
  href: string;
}

type marked$Tokens = { links: Array<marked$Link> } & Array<marked$Token>;

type marked$NoopRule = {
  (i: mixed): void;
  exec: (i: mixed) => void;
}

type marked$Rule = RegExp | marked$NoopRule

type marked$lex = (t: string) => marked$Tokens;

class marked$Lexer {
  static lexer: (t: string, o?: marked$MarkedOptions) => marked$Tokens;
  static rules: { [key: string]: marked$Rule };
  rules: { [key: string]: marked$Rule };
  lex: marked$lex;
  tokens: marked$Tokens;
  options: marked$MarkedOptions;
  constructor(o?: marked$MarkedOptions): marked$Lexer {
    return this;
  }
}

class marked$Parser {
  static parse: (t: marked$Tokens, o?: marked$MarkedOptions) => string;
  parse: (t: marked$Tokens) => string;
  next: () => marked$Token;
  peek: () => marked$Token;
  parsemarked$Text: () => string;
  tok: () => string;
  tokens: marked$Tokens;
  token: ?marked$Token;
  options: marked$MarkedOptions;
  renderer: marked$Renderer;
  constructor(o?: marked$MarkedOptions): marked$Parser {
    return this;
  }
}

class marked$InlineLexer {
  static rules: Array<marked$Rule>;
  static output: (s: string, l: Array<marked$Link>, o?: marked$MarkedOptions) => string;
  output: (s: string) => string;
  outputmarked$Link: (c: Array<string>, l: marked$Link) => string;
  smartypants: (t: string) => string;
  mangle: (t: string) => string;
  options: marked$MarkedOptions;
  links: Array<marked$Link>;
  rules: Array<marked$Rule>;
  renderer: marked$Renderer;
  constructor(l: Array<marked$Link>, o?: marked$MarkedOptions): marked$InlineLexer {
    return this;
  }
}

type marked$Marked = {
  (md: string, o: marked$MarkedOptions, cb: marked$NodeCallback<string>): void;
  (md: string, cb: marked$NodeCallback<string>): void;
  (md: string, o?: marked$MarkedOptions): string;
  setOptions: (o: marked$MarkedOptions) => void;
  defaults: marked$MarkedOptions;
  Parser: typeof marked$Parser;
  parser: typeof marked$Parser.parse;
  Lexer: typeof marked$Lexer;
  lexer: typeof marked$Lexer.lexer;
  InlineLexer: typeof marked$InlineLexer;
  inlinelexer: marked$InlineLexer.output;
  Renderer: typeof marked$Renderer;
  parse: marked$Marked;
}

declare module marked {
  declare export default marked$Marked;
}

<commit_msg>Use `typeof` function rather than function as a type (#2781)<commit_after>type marked$AlignFlag = 'left' | 'right' | 'center'

type marked$NodeCallback<T> = (e: ?Error, d: ?T) => void

class marked$Renderer {
  options: marked$MarkedOptions;
  code: (c: string, l: string) => string;
  blockquote: (q: string) => string;
  html: (h: string) => string;
  heading: (t: string, l: number) => string;
  hr: () => string;
  list: (b: string, o: boolean) => string;
  listitem: (t: string) => string;
  paragraph: (t: string) => string;
  table: (h: string, b: string) => string;
  tablerow: (c: string) => string;
  tablecell: (c: string, f: ?marked$AlignFlag) => string;
  heading: (t: string, l: number) => string;
  strong: (t: string) => string;
  em: (t: string) => string;
  codespan: (c: string) => string;
  br: () => string;
  del: (t: string) => string;
  link: (h: string, ti: string, te: string) => string;
  image: (h: string, ti: string, te: string) => string;
  text: (t: string) => string;
  constructor(o?: marked$MarkedOptions): marked$Renderer {
    return this;
  }
}

type marked$HighlightFunction =
  ((c: string, l: string, cb: marked$NodeCallback<string>) => void)
  | ((c: string, cb: marked$NodeCallback<string>) => void)
  | ((c: string, l?: string) => string)

type marked$MarkedOptions = {
  highlight?: marked$HighlightFunction;
  renderer?: marked$Renderer;
  gfm?: boolean;
  tables?: boolean;
  breaks?: boolean;
  pedantic?: boolean;
  sanitize?: boolean;
  smartLists?: boolean;
  smartypants?: boolean;
}

/*
 * marked$Tokens
 */

type marked$Space = { type: 'space'; }
type marked$Code = { type: 'code'; text: string; lang?: string; }
type marked$Heading = { type: 'heading'; depth: number; text: string; }
type marked$Table = { type: 'table'; header: string; align: Array<marked$AlignFlag> ; cells: Array<Array<string>> }
type marked$Hr = { type: 'hr'; }
type marked$BlockquoteStart = { type: 'blockquote_start' }
type marked$BlockquoteEnd = { type: 'blockquote_end' }
type marked$ListStart = { type: 'list_start' }
type marked$ListEnd = { type: 'list_end' }
type marked$Paragraph = { type: 'paragraph'; pre: boolean; text: string; }
type marked$Html = { type: 'paragraph'; pre: boolean; text: string; }
type marked$Text = { type: 'text'; text: string; }

type marked$Token =
  marked$Space
  | marked$Code
  | marked$Heading
  | marked$Table
  | marked$Hr
  | marked$BlockquoteStart
  | marked$BlockquoteEnd
  | marked$ListStart
  | marked$ListEnd
  | marked$Paragraph
  | marked$Html
  | marked$Text

type marked$Link = {
  title: ?string;
  href: string;
}

type marked$Tokens = { links: Array<marked$Link> } & Array<marked$Token>;

type marked$NoopRule = {
  (i: mixed): void;
  exec: (i: mixed) => void;
}

type marked$Rule = RegExp | marked$NoopRule

type marked$lex = (t: string) => marked$Tokens;

class marked$Lexer {
  static lexer: (t: string, o?: marked$MarkedOptions) => marked$Tokens;
  static rules: { [key: string]: marked$Rule };
  rules: { [key: string]: marked$Rule };
  lex: marked$lex;
  tokens: marked$Tokens;
  options: marked$MarkedOptions;
  constructor(o?: marked$MarkedOptions): marked$Lexer {
    return this;
  }
}

class marked$Parser {
  static parse: (t: marked$Tokens, o?: marked$MarkedOptions) => string;
  parse: (t: marked$Tokens) => string;
  next: () => marked$Token;
  peek: () => marked$Token;
  parsemarked$Text: () => string;
  tok: () => string;
  tokens: marked$Tokens;
  token: ?marked$Token;
  options: marked$MarkedOptions;
  renderer: marked$Renderer;
  constructor(o?: marked$MarkedOptions): marked$Parser {
    return this;
  }
}

class marked$InlineLexer {
  static rules: Array<marked$Rule>;
  static output: (s: string, l: Array<marked$Link>, o?: marked$MarkedOptions) => string;
  output: (s: string) => string;
  outputmarked$Link: (c: Array<string>, l: marked$Link) => string;
  smartypants: (t: string) => string;
  mangle: (t: string) => string;
  options: marked$MarkedOptions;
  links: Array<marked$Link>;
  rules: Array<marked$Rule>;
  renderer: marked$Renderer;
  constructor(l: Array<marked$Link>, o?: marked$MarkedOptions): marked$InlineLexer {
    return this;
  }
}

type marked$Marked = {
  (md: string, o: marked$MarkedOptions, cb: marked$NodeCallback<string>): void;
  (md: string, cb: marked$NodeCallback<string>): void;
  (md: string, o?: marked$MarkedOptions): string;
  setOptions: (o: marked$MarkedOptions) => void;
  defaults: marked$MarkedOptions;
  Parser: typeof marked$Parser;
  parser: typeof marked$Parser.parse;
  Lexer: typeof marked$Lexer;
  lexer: typeof marked$Lexer.lexer;
  InlineLexer: typeof marked$InlineLexer;
  inlinelexer: typeof marked$InlineLexer.output;
  Renderer: typeof marked$Renderer;
  parse: marked$Marked;
}

declare module marked {
  declare export default marked$Marked;
}
<|endoftext|>