<commit_before>nextCreationStepAfter = function(currentStep){
  var currentIndex =_.indexOf(CREATION_STEPS, currentStep);
  if (currentIndex == -1){
    throw new Meteor.Error(currentStep + 'is not a valid step in CREATION_STEPS');
  }
  return CREATION_STEPS[currentIndex + 1];
};

creationStepBefore = function(currentStep){
  var currentIndex = _.indexOf(CREATION_STEPS, currentStep);
  if (currentIndex == -1){
    throw new Meteor.Error(currentStep + 'is not a valid step in CREATION_STEPS');
  } else if (currentIndex === 0) {
    throw new Meteor.Error(currentStep + 'has no prior steps in in CREATION_STEPS');
  }
  return CREATION_STEPS[currentIndex - 1];
};


buildRegExp = function(searchText) {
  // this is a dumb implementation
  var parts = searchText.trim().split(/[ \-\:]+/);
  return new RegExp("(" + parts.join('|') + ")", "ig");
};


idFromPathSegment = function(pathSegment) { // everything after last dash
  return pathSegment.substring(pathSegment.lastIndexOf('-') + 1);
};

generateStreamPathSegment = function(shortId, title){
  return _s.slugify(title ? title.toLowerCase() : 'deep-stream') + '-' + shortId;
};

newTypeSpecificContextBlock = function (doc) {
  switch (doc.type) {
    case 'stream':
      return new Stream(doc);
    case 'video':
      return new VideoBlock(doc);
    case 'text':
      return new TextBlock(doc);
    case 'map':
      return new MapBlock(doc);
    case 'image':
      return new ImageBlock(doc);
    case 'audio':
      return new AudioBlock(doc);
    case 'twitter':
      return new TwitterBlock(doc);
    case 'link':
      return new LinkBlock(doc);
    case 'news':
      return new NewsBlock(doc);
    default:
      return new ContextBlock(doc);
  }
};

// only the curator may update the stream
updateDeepstream = function(selector, modifier, options) {
  if (_.isEmpty(modifier)){
    return
  }
  modifier.$set = _.extend(modifier.$set || {}, {savedAt: new Date});
  selector.curatorIds = this.userId; // this.userId must be the user (use via .call or .apply)

  return Deepstreams.update(selector, modifier, _.defaults({}, options, {removeEmptyStrings: false}));
};

updateContextBlock = function(selector, modifier, options) {
  if (_.isEmpty(modifier)){
    return
  }
  modifier.$set = _.extend(modifier.$set || {}, {savedAt: new Date});

  return ContextBlocks.update(selector, modifier, _.defaults({}, options, {removeEmptyStrings: false}));
};

addContextToStream =  function (streamShortId, contextBlock) {
  check(streamShortId, String);
  check(contextBlock, Object);

  var deepstream = Deepstreams.findOne({shortId: streamShortId}, {fields: {'creationStep': 1, 'curatorIds': 1}});

  if(!_.contains(deepstream.curatorIds, this.userId)){
    throw new Meteor.Error('User not authorized to add context to this stream');
  }

  var pushObject, pushSelectorString;
  pushSelectorString = 'contextBlocks';
  pushObject = {};
  var contextBlockToInsert = _.extend({}, _.omit(contextBlock, '_id'), {
    streamShortId: streamShortId,
    authorId: this.userId,
    addedAt: new Date,
    savedAt: new Date
  });

  var contextId = ContextBlocks.insert(contextBlockToInsert);

  pushObject[pushSelectorString] = _.extend(_.pick(contextBlockToInsert, ['type', 'source', 'addedAt']), {_id: contextId, rank: 0});

  var modifierObject = {
    '$addToSet': pushObject
  };


  modifierObject['$set'] = {};

  // advance creation if at this creation step
  if (deepstream.creationStep === 'add_cards') {
    _.extend(modifierObject['$set'], {
      creationStep: nextCreationStepAfter('add_cards')
    });
  }

  if (!contextId) {
    throw new Meteor.Error('Context block not inserted')
  }

  var numUpdated = updateDeepstream.call(this, {shortId: streamShortId}, modifierObject);

  if (!numUpdated) {
    throw new Meteor.Error('Stream not updated')
  }


  if (Meteor.isClient) {
    Session.set("mediaDataType", Session.get('mediaDataType'));
    Session.set("mediaDataType", null); // leave search mode
    var typeSpecificContextBlock = newTypeSpecificContextBlock(contextBlock);<commit_msg>keep context type across adds<commit_after>nextCreationStepAfter = function(currentStep){
  var currentIndex =_.indexOf(CREATION_STEPS, currentStep);
  if (currentIndex == -1){
    throw new Meteor.Error(currentStep + 'is not a valid step in CREATION_STEPS');
  }
  return CREATION_STEPS[currentIndex + 1];
};

creationStepBefore = function(currentStep){
  var currentIndex = _.indexOf(CREATION_STEPS, currentStep);
  if (currentIndex == -1){
    throw new Meteor.Error(currentStep + 'is not a valid step in CREATION_STEPS');
  } else if (currentIndex === 0) {
    throw new Meteor.Error(currentStep + 'has no prior steps in in CREATION_STEPS');
  }
  return CREATION_STEPS[currentIndex - 1];
};


buildRegExp = function(searchText) {
  // this is a dumb implementation
  var parts = searchText.trim().split(/[ \-\:]+/);
  return new RegExp("(" + parts.join('|') + ")", "ig");
};


idFromPathSegment = function(pathSegment) { // everything after last dash
  return pathSegment.substring(pathSegment.lastIndexOf('-') + 1);
};

generateStreamPathSegment = function(shortId, title){
  return _s.slugify(title ? title.toLowerCase() : 'deep-stream') + '-' + shortId;
};

newTypeSpecificContextBlock = function (doc) {
  switch (doc.type) {
    case 'stream':
      return new Stream(doc);
    case 'video':
      return new VideoBlock(doc);
    case 'text':
      return new TextBlock(doc);
    case 'map':
      return new MapBlock(doc);
    case 'image':
      return new ImageBlock(doc);
    case 'audio':
      return new AudioBlock(doc);
    case 'twitter':
      return new TwitterBlock(doc);
    case 'link':
      return new LinkBlock(doc);
    case 'news':
      return new NewsBlock(doc);
    default:
      return new ContextBlock(doc);
  }
};

// only the curator may update the stream
updateDeepstream = function(selector, modifier, options) {
  if (_.isEmpty(modifier)){
    return
  }
  modifier.$set = _.extend(modifier.$set || {}, {savedAt: new Date});
  selector.curatorIds = this.userId; // this.userId must be the user (use via .call or .apply)

  return Deepstreams.update(selector, modifier, _.defaults({}, options, {removeEmptyStrings: false}));
};

updateContextBlock = function(selector, modifier, options) {
  if (_.isEmpty(modifier)){
    return
  }
  modifier.$set = _.extend(modifier.$set || {}, {savedAt: new Date});

  return ContextBlocks.update(selector, modifier, _.defaults({}, options, {removeEmptyStrings: false}));
};

addContextToStream =  function (streamShortId, contextBlock) {
  check(streamShortId, String);
  check(contextBlock, Object);

  var deepstream = Deepstreams.findOne({shortId: streamShortId}, {fields: {'creationStep': 1, 'curatorIds': 1}});

  if(!_.contains(deepstream.curatorIds, this.userId)){
    throw new Meteor.Error('User not authorized to add context to this stream');
  }

  var pushObject, pushSelectorString;
  pushSelectorString = 'contextBlocks';
  pushObject = {};
  var contextBlockToInsert = _.extend({}, _.omit(contextBlock, '_id'), {
    streamShortId: streamShortId,
    authorId: this.userId,
    addedAt: new Date,
    savedAt: new Date
  });

  var contextId = ContextBlocks.insert(contextBlockToInsert);

  pushObject[pushSelectorString] = _.extend(_.pick(contextBlockToInsert, ['type', 'source', 'addedAt']), {_id: contextId, rank: 0});

  var modifierObject = {
    '$addToSet': pushObject
  };


  modifierObject['$set'] = {};

  // advance creation if at this creation step
  if (deepstream.creationStep === 'add_cards') {
    _.extend(modifierObject['$set'], {
      creationStep: nextCreationStepAfter('add_cards')
    });
  }

  if (!contextId) {
    throw new Meteor.Error('Context block not inserted')
  }

  var numUpdated = updateDeepstream.call(this, {shortId: streamShortId}, modifierObject);

  if (!numUpdated) {
    throw new Meteor.Error('Stream not updated')
  }


  if (Meteor.isClient) {
    Session.set("previousMediaDataType", Session.get('mediaDataType'));
    Session.set("mediaDataType", null); // leave search mode
    var typeSpecificContextBlock = newTypeSpecificContextBlock(contextBlock);
{'fraction_non_alphanumeric': 0.1386575208231259, 'fraction_numerical': 0.002204801567858893, 'mean_word_length': 4.21059349074665, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5747230', 'n_tokens_mistral': 2548, 'n_tokens_neox': 2453, 'n_words': 633}