<commit_before>var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var config = require('./config');

var public_room_online_users = [];

io.on('connection', function(socket){

    var user;

    socket.on('online_notification', function(msg){
        switch(msg.plugin)
        {
            case 'cocreation' :
                break;
            case 'spodpublic' :
                console.log(public_room_online_users);

                if(!public_room_online_users["room_" + msg.room_id]) {
                    console.log("new room " + msg.room_id);
                    public_room_online_users["room_" + msg.room_id] = [];
                }

                if(public_room_online_users["room_" + msg.room_id].indexOf(msg.user_id) == -1) {
                    console.log("new user : "+msg.user_id+", for room " + msg.room_id);
                    public_room_online_users["room_" + msg.room_id].push(msg.user_id);
                    user = msg.user_id;
                }

                io.emit('online_notification_' + msg.room_id, public_room_online_users["room_" + msg.room_id]);
                break;
            default:
                break;
        }
    });

    socket.on('disconnect', function () {
        io.emit('offline_notification', user);

        for(var room in public_room_online_users)
        {
            var index = public_room_online_users[room].indexOf(user);
            if(index > -1) public_room_online_users[room].splice(index, 1);
        }
    });

    socket.on('realtime_notification', function(msg){

        switch(msg.plugin)
        {
            case 'cocreation' :
                io.emit('realtime_message_' + msg.entity_type + "_" + msg.entity_id, msg);
                break;
            case 'spodpublic' :
                console.log(msg);
                io.emit('realtime_message_' + msg.room_id, msg);
                break;
            default:
                io.emit('realtime_message', msg);
                break;
        }
    });

});

http.listen(config.port, function(){
    console.log('listening on *:' + config.port);
});<commit_msg>agora enhancement<commit_after>var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var config = require('./config');

var public_room_online_users = [];

io.on('connection', function(socket){

    var user;

    socket.on('online_notification', function(msg){
        switch(msg.plugin)
        {
            case 'cocreation' :
                break;
            case 'agora' :
                console.log(public_room_online_users);

                if(!public_room_online_users["room_" + msg.room_id]) {
                    console.log("new room " + msg.room_id);
                    public_room_online_users["room_" + msg.room_id] = [];
                }

                if(public_room_online_users["room_" + msg.room_id].indexOf(msg.user_id) == -1) {
                    console.log("new user : "+msg.user_id+", for room " + msg.room_id);
                    public_room_online_users["room_" + msg.room_id].push(msg.user_id);
                    user = msg.user_id;
                }

                io.emit('online_notification_' + msg.room_id, public_room_online_users["room_" + msg.room_id]);
                break;
            default:
                break;
        }
    });

    socket.on('disconnect', function () {
        io.emit('offline_notification', user);

        for(var room in public_room_online_users)
        {
            var index = public_room_online_users[room].indexOf(user);
            if(index > -1) public_room_online_users[room].splice(index, 1);
        }
    });

    socket.on('realtime_notification', function(msg){

        switch(msg.plugin)
        {
            case 'cocreation' :
                io.emit('realtime_message_' + msg.entity_type + "_" + msg.entity_id, msg);
                break;
            case 'agora' :
                console.log(msg);
                io.emit('realtime_message_' + msg.room_id, msg);
                break;
            default:
                io.emit('realtime_message', msg);
                break;
        }
    });

});

http.listen(config.port, function(){
    console.log('listening on *:' + config.port);
});<|endoftext|>


<commit_before>import { Accounts } from 'meteor/accounts-base';
import Bans from './collection.js';

// Check during login whether the user currently has their login disabled

// User ban callback

Accounts.validateLoginAttempt((attempt) => {
  if (!attempt.allowed) {
    return false;
  }
  if (attempt.user && attempt.user.banned && new Date(attempt.user.banned) > new Date()) {
    throw new Meteor.Error('user-banned', 'This account is banned until ' + new Date(attempt.user.banned));
  } else {
    return true;
  }
})

Accounts.validateLoginAttempt((attempt) => {
  if (!attempt.allowed) {
    return false;
  }
  const ban = Bans.findOne({ip: attempt.connection.clientAddress});
  if (ban && new Date(ban.expirationDate) > new Date()) {
    throw new Meteor.Error('address-banned', 'Your ip-address is banned until ' + new Date(ban.expirationDate) + ' for ' + ban.reason);
  } else {
    return true;
  }
})
<commit_msg>Fixed IP address ban<commit_after>import { Accounts } from 'meteor/accounts-base';
import Bans from './collection.js';
import { ForwardedWhitelist } from '../../modules/forwarded_whitelist.js';
// Check during login whether the user currently has their login disabled

// User ban callback

Accounts.validateLoginAttempt((attempt) => {
  if (!attempt.allowed) {
    return false;
  }
  if (attempt.user && attempt.user.banned && new Date(attempt.user.banned) > new Date()) {
    throw new Meteor.Error('user-banned', 'This account is banned until ' + new Date(attempt.user.banned));
  } else {
    return true;
  }
})

Accounts.validateLoginAttempt((attempt) => {
  if (!attempt.allowed) {
    return false;
  }
  const ban = Bans.findOne({ip: attempt.connection && ForwardedWhitelist.getClientIP(attempt.connection)});
  if (ban && new Date(ban.expirationDate) > new Date()) {
    throw new Meteor.Error('address-banned', 'Your ip-address is banned until ' + new Date(ban.expirationDate) + ' for ' + ban.reason);
  } else {
    return true;
  }
})
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { schedule, danger, fail, warn, message, markdown } from "danger";
import fs from "fs";
import path from 'path';
import GitHubApi from 'github';
import parseDiff from 'parse-diff';

// Make sure there are changelog entries
const hasChangelog = danger.git.modified_files.includes("changelog.md")
if (!hasChangelog) { warn("No Changelog changes!") }

const jsFiles = danger.git.created_files.filter(path => path.endsWith("js"));

function absolute (relPath) {
  return path.resolve(__dirname, relPath)
}

const flowIgnorePaths = [
  'node_modules',
  'test',
  'build',
  'examples',
  'doc',
  'android',
  'ios',
  'bin',
  'dist',
  'flow-typed'
].map(function (rel) {
  return absolute(rel)
});

// new js files should have `@flow` at the top
const unFlowedFiles = jsFiles.filter(filepath => {
  let i = 0
  const len = flowIgnorePaths.length
  while (i < len) {
    const p = flowIgnorePaths[i]
    if (absolute(filepath).indexOf(p) > -1) {
      // ignore this file because it's in the flow-ignore-paths.
      return false;
    }
    i++
  }
  const content = fs.readFileSync(filepath);
  return !content.includes("@flow");
});

if (unFlowedFiles.length > 0) {
  warn(
    `These new JS files do not have Flow enabled: ${unFlowedFiles.join(", ")}`
  );
}

// Error or Warn when delete public interface
var methion_break_change = false;
for (let c of danger.git.commits) {
  // console.log("msg:" + c.message);
  if (c.message && c.message.match(/break\s+change/i)) {
    methion_break_change = true;
    break;
  }
}

// File name match any of these patterns will be ignored.
function is_ignored_public_check(file) {
  var ignored_break_change_pattern = [
    /^android\/sdk\/src\/test\/.+/,
     /^android\/playground\/.+/
  ];
  for (let p of ignored_break_change_pattern) {
    if (file.match(p)) {
      return true;
    }
  }
  return false;
}

var has_app_changes = false;
var has_test_changes = false;
var codefiles = [];
for (let file of danger.git.modified_files) {
  if (file.match(/WeexSDK\/Source/)) {
    has_app_changes = true;
  } else if (file.match(/WeexSDKTests/)) {
    has_test_changes = true;
  }

  if (!is_ignored_public_check(file) && file.endsWith(".java")) {
    var diff = danger.git.diffForFile(file);
    // console.log("diff：" + diff+ typeof diff);
    if (diff && diff.match(/^-\s*?public\s+[\s\S]+$/gm)) {
      if (methion_break_change) {
        warn("Potential BREAK CHANGE. Modify public in   " + file);
      } else {
        warn(
          "Potential BREAK CHANGE. Modify public in " +
            file +
            " without metion it in commit message. You'd better add 'break change' in your commit log. "
        );
      }
    }
  }

  if (
    file.endsWith(".h") ||
    file.endsWith(".m") ||
    file.endsWith(".mm") ||
    file.endsWith(".java") ||
    file.endsWith(".js")
  ) {
    codefiles.push(file);
  }
}
if(danger.git.added_files){
  for (let file of danger.git.added_files) {
    if (
      file.endsWith(".h") ||
      file.endsWith(".m") ||
      file.endsWith(".mm") ||
      file.endsWith(".java") ||
      file.endsWith(".js")
    ) {
      codefiles.push(file);
    }
  }
}

if (danger.git.lines_of_code > 500) {
  warn("Big PR");
}

if (danger.git.lines_of_code > 100 && has_app_changes && !has_test_changes) {
  warn("This PR may need tests.");
}

//check ios copyright
//see scripts/rh/header.template
const copyright_header_components = [
  "Licensed to the Apache Software Foundation \\(ASF\\) under one",
  "or more contributor license agreements.  See the NOTICE file",
  "distributed with this work for additional information",
  "regarding copyright ownership\\.  The ASF licenses this file",
  'to you under the Apache License, Version 2\\.0 \\(the',
  '"License"\\); you may not use this file except in compliance',
  'with the License\\.  You may obtain a copy of the License at'
];

//path prefix
const ignoreCopyrightVerifyPath = [
  'test',
  'pre-build',
  'android/playground/app/src/main/assets',
  'android/sdk/assets',
  'ios/playground/bundlejs',
  'ios/sdk/WeexSDK/Resources',
  'ios/sdk/WeexSDK/Sources/Layout'
]

codefiles.forEach(filepath => {
  for(var i=ignoreCopyrightVerifyPath.length-1;i>=0;i--){
    if(filepath.startsWith(ignoreCopyrightVerifyPath[i])){
      return
    }
  }
  const content = fs.readFileSync(filepath).toString();
  for (const line of copyright_header_components) {
    if (!content.match(new RegExp(line))) {
      fail("Code file "+ filepath +" does not have the copyright header.");
      return;
    }
  }
});

/*
 * try to find the appropriate reviewer according to the blame info
 * will be seperated to a danger plugin
 */

schedule(new Promise((resolve, reject) => {
  findReviewer(resolve, reject)
}));

function findReviewer(resolve, reject) {
  var github = new GitHubApi({
    protocol: "https",
    host: "api.github.com",
  });

  var fileToDeletedLinesMap = {}
  var fileToNormalLinesMap = {}
  var fileToBlamesMap = {}
  github.pullRequests.get({
    owner: danger.github.pr.base.user.login,
    repo: danger.github.pr.base.repo.name,
    number: danger.github.pr.number,
    headers: {Accept: 'application/vnd.github.diff'}
  }, function (err, result) {
    parseDeleteAndNormalLines(result.data, fileToDeletedLinesMap, fileToNormalLinesMap)
    var promises = danger.git.modified_files.map(function(file) {
      let repoURL = danger.github.pr.base.repo.html_url
      let fileName = file.replace(/^.*[\\\/]/, '')
      let blameURL = repoURL + '/blame/' + danger.github.pr.base.ref + '/' + file
      // console.log("Getting blame html: " + blameURL)
      return getContent(blameURL)
    });

    Promise.all(promises).then(datas => {
      datas.forEach(function(data, index) {
        fileToBlamesMap[danger.git.modified_files[index]] = parseBlame(data);
      });
      findBlameReviewers(fileToDeletedLinesMap, fileToNormalLinesMap, fileToBlamesMap)
      resolve()
    })
  });
}

function getContent(url) {
  // return new pending promise
  return new Promise((resolve, reject) => {
    // select http or https module, depending on reqested url
    const lib = url.startsWith('https') ? require('https') : require('http');
    const request = lib.get(url, (response) => {
      // handle http errors
      if (response.statusCode < 200 || response.statusCode > 299) {
         reject(new Error('Failed to load page, status code: ' + response.statusCode));
       }
      // temporary data holder
      const body = [];
      // on every content chunk, push it to the data array
      response.on('data', (chunk) => body.push(chunk));
      // we are done, resolve promise with those joined chunks
      response.on('end', () => resolve(body.join('')));
    });
    // handle connection errors of the request
    request.on('error', (err) => reject(err))
    })
}

function parseDeleteAndNormalLines(diffData, fileToDeletedLinesMap, fileToNormalLinesMap) {
  var diffs = parseDiff(diffData)
  diffs.forEach(diff => {
    fileToDeletedLinesMap[diff.from] = [];
    fileToNormalLinesMap[diff.from] = [];
    diff.chunks.forEach(chunk => {
      chunk.changes.forEach(change => {
        if (change.del) {
          fileToDeletedLinesMap[diff.from].push(change.ln)
        }
        if (change.normal) {
          fileToNormalLinesMap[diff.from].push(change.ln1)
        }
      })
    })
  })
}

function parseBlame(html) {
  let regular = /(<img alt="@([^"]+)" class="avatar blame-commit-avatar"|<tr class="blame-line")/g
  var match
  var currentUser
  var lines = []
  while ((match = regular.exec(html)) !== null) {
    let user = match[2]
    if (user) {
      currentUser = user
    } else {
      lines.push(currentUser)
    }
  }

  return lines
}

function findBlameReviewers(fileToDeletedLinesMap, fileToNormalLinesMap, fileToBlamesMap) {
  var reviewers = {};

  // deleted lines get 3 points, normal line get 1 point
  Object.keys(fileToDeletedLinesMap).forEach(function (file) {
    let deletedLines = fileToDeletedLinesMap[file]
    var blames = fileToBlamesMap[file]
    deletedLines.forEach(lineNumber => {
      var name = blames[lineNumber]
      reviewers[name] = (reviewers[name] || 0) + 3
    })
  });

  Object.keys(fileToNormalLinesMap).forEach(function (file) {
    let normalLines = fileToNormalLinesMap[file];
    var blames = fileToBlamesMap[file]
    normalLines.forEach(lineNumber => {
      var name = blames[lineNumber]
      reviewers[name] = (reviewers[name] || 0) + 1
    })
  });

  console.log('blame point:', reviewers)
  var names = Object.keys(reviewers)
  names.sort((name1, name2) => {
    return reviewers[name1] > reviewers[name2] ? -1 : 1
  })

  var prUser = danger.github.pr.user.login
  names.splice(names.findIndex(el => {
    return el === prUser
  }), 1)

  if (names.length > 0) {
    if (names.length > 2) {
      names = names.slice(0, 2)
    }
    names = names.map(name => {
      return '@' + name
    })

    message("According to the blame info, we recommended " + names.join(' , ') + " to be the reviewers.")
  }
}

/*
 * find reviewer end
 */<commit_msg>* [test] add try catch to danger reviewer plugin<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { schedule, danger, fail, warn, message, markdown } from "danger";
import fs from "fs";
import path from 'path';
import GitHubApi from 'github';
import parseDiff from 'parse-diff';

// Make sure there are changelog entries
const hasChangelog = danger.git.modified_files.includes("changelog.md")
if (!hasChangelog) { warn("No Changelog changes!") }

const jsFiles = danger.git.created_files.filter(path => path.endsWith("js"));

function absolute (relPath) {
  return path.resolve(__dirname, relPath)
}

const flowIgnorePaths = [
  'node_modules',
  'test',
  'build',
  'examples',
  'doc',
  'android',
  'ios',
  'bin',
  'dist',
  'flow-typed'
].map(function (rel) {
  return absolute(rel)
});

// new js files should have `@flow` at the top
const unFlowedFiles = jsFiles.filter(filepath => {
  let i = 0
  const len = flowIgnorePaths.length
  while (i < len) {
    const p = flowIgnorePaths[i]
    if (absolute(filepath).indexOf(p) > -1) {
      // ignore this file because it's in the flow-ignore-paths.
      return false;
    }
    i++
  }
  const content = fs.readFileSync(filepath);
  return !content.includes("@flow");
});

if (unFlowedFiles.length > 0) {
  warn(
    `These new JS files do not have Flow enabled: ${unFlowedFiles.join(", ")}`
  );
}

// Error or Warn when delete public interface
var methion_break_change = false;
for (let c of danger.git.commits) {
  // console.log("msg:" + c.message);
  if (c.message && c.message.match(/break\s+change/i)) {
    methion_break_change = true;
    break;
  }
}

// File name match any of these patterns will be ignored.
function is_ignored_public_check(file) {
  var ignored_break_change_pattern = [
    /^android\/sdk\/src\/test\/.+/,
     /^android\/playground\/.+/
  ];
  for (let p of ignored_break_change_pattern) {
    if (file.match(p)) {
      return true;
    }
  }
  return false;
}

var has_app_changes = false;
var has_test_changes = false;
var codefiles = [];
for (let file of danger.git.modified_files) {
  if (file.match(/WeexSDK\/Source/)) {
    has_app_changes = true;
  } else if (file.match(/WeexSDKTests/)) {
    has_test_changes = true;
  }

  if (!is_ignored_public_check(file) && file.endsWith(".java")) {
    var diff = danger.git.diffForFile(file);
    // console.log("diff：" + diff+ typeof diff);
    if (diff && diff.match(/^-\s*?public\s+[\s\S]+$/gm)) {
      if (methion_break_change) {
        warn("Potential BREAK CHANGE. Modify public in   " + file);
      } else {
        warn(
          "Potential BREAK CHANGE. Modify public in " +
            file +
            " without metion it in commit message. You'd better add 'break change' in your commit log. "
        );
      }
    }
  }

  if (
    file.endsWith(".h") ||
    file.endsWith(".m") ||
    file.endsWith(".mm") ||
    file.endsWith(".java") ||
    file.endsWith(".js")
  ) {
    codefiles.push(file);
  }
}
if(danger.git.added_files){
  for (let file of danger.git.added_files) {
    if (
      file.endsWith(".h") ||
      file.endsWith(".m") ||
      file.endsWith(".mm") ||
      file.endsWith(".java") ||
      file.endsWith(".js")
    ) {
      codefiles.push(file);
    }
  }
}

if (danger.git.lines_of_code > 500) {
  warn("Big PR");
}

if (danger.git.lines_of_code > 100 && has_app_changes && !has_test_changes) {
  warn("This PR may need tests.");
}

//check ios copyright
//see scripts/rh/header.template
const copyright_header_components = [
  "Licensed to the Apache Software Foundation \\(ASF\\) under one",
  "or more contributor license agreements.  See the NOTICE file",
  "distributed with this work for additional information",
  "regarding copyright ownership\\.  The ASF licenses this file",
  'to you under the Apache License, Version 2\\.0 \\(the',
  '"License"\\); you may not use this file except in compliance',
  'with the License\\.  You may obtain a copy of the License at'
];

//path prefix
const ignoreCopyrightVerifyPath = [
  'test',
  'pre-build',
  'android/playground/app/src/main/assets',
  'android/sdk/assets',
  'ios/playground/bundlejs',
  'ios/sdk/WeexSDK/Resources',
  'ios/sdk/WeexSDK/Sources/Layout'
]

codefiles.forEach(filepath => {
  for(var i=ignoreCopyrightVerifyPath.length-1;i>=0;i--){
    if(filepath.startsWith(ignoreCopyrightVerifyPath[i])){
      return
    }
  }
  const content = fs.readFileSync(filepath).toString();
  for (const line of copyright_header_components) {
    if (!content.match(new RegExp(line))) {
      fail("Code file "+ filepath +" does not have the copyright header.");
      return;
    }
  }
});

/*
 * try to find the appropriate reviewer according to the blame info
 * will be seperated to a danger plugin
 */

schedule(new Promise((resolve, reject) => {
  try {
    findReviewer(resolve, reject)
  } catch (e) {
    console.log(e)
    resolve()
  }
}));

function findReviewer(resolve, reject) {
  var github = new GitHubApi({
    protocol: "https",
    host: "api.github.com",
  });

  var fileToDeletedLinesMap = {}
  var fileToNormalLinesMap = {}
  var fileToBlamesMap = {}
  github.pullRequests.get({
    owner: danger.github.pr.base.user.login,
    repo: danger.github.pr.base.repo.name,
    number: danger.github.pr.number,
    headers: {Accept: 'application/vnd.github.diff'}
  }, function (err, result) {
    parseDeleteAndNormalLines(result.data, fileToDeletedLinesMap, fileToNormalLinesMap)
    var promises = danger.git.modified_files.map(function(file) {
      let repoURL = danger.github.pr.base.repo.html_url
      let fileName = file.replace(/^.*[\\\/]/, '')
      let blameURL = repoURL + '/blame/' + danger.github.pr.base.ref + '/' + file
      // console.log("Getting blame html: " + blameURL)
      return getContent(blameURL)
    });

    Promise.all(promises).then(datas => {
      datas.forEach(function(data, index) {
        fileToBlamesMap[danger.git.modified_files[index]] = parseBlame(data);
      });
      findBlameReviewers(fileToDeletedLinesMap, fileToNormalLinesMap, fileToBlamesMap)
      resolve()
    })
  });
}

function getContent(url) {
  // return new pending promise
  return new Promise((resolve, reject) => {
    // select http or https module, depending on reqested url
    const lib = url.startsWith('https') ? require('https') : require('http');
    const request = lib.get(url, (response) => {
      // handle http errors
      if (response.statusCode < 200 || response.statusCode > 299) {
         reject(new Error('Failed to load page, status code: ' + response.statusCode));
       }
      // temporary data holder
      const body = [];
      // on every content chunk, push it to the data array
      response.on('data', (chunk) => body.push(chunk));
      // we are done, resolve promise with those joined chunks
      response.on('end', () => resolve(body.join('')));
    });
    // handle connection errors of the request
    request.on('error', (err) => reject(err))
    })
}

function parseDeleteAndNormalLines(diffData, fileToDeletedLinesMap, fileToNormalLinesMap) {
  var diffs = parseDiff(diffData)
  diffs.forEach(diff => {
    fileToDeletedLinesMap[diff.from] = [];
    fileToNormalLinesMap[diff.from] = [];
    diff.chunks.forEach(chunk => {
      chunk.changes.forEach(change => {
        if (change.del) {
          fileToDeletedLinesMap[diff.from].push(change.ln)
        }
        if (change.normal) {
          fileToNormalLinesMap[diff.from].push(change.ln1)
        }
      })
    })
  })
}

function parseBlame(html) {
  let regular = /(<img alt="@([^"]+)" class="avatar blame-commit-avatar"|<tr class="blame-line")/g
  var match
  var currentUser
  var lines = []
  while ((match = regular.exec(html)) !== null) {
    let user = match[2]
    if (user) {
      currentUser = user
    } else {
      lines.push(currentUser)
    }
  }

  return lines
}

function findBlameReviewers(fileToDeletedLinesMap, fileToNormalLinesMap, fileToBlamesMap) {
  var reviewers = {};

  // deleted lines get 3 points, normal line get 1 point
  Object.keys(fileToDeletedLinesMap).forEach(function (file) {
    let deletedLines = fileToDeletedLinesMap[file]
    var blames = fileToBlamesMap[file]
    deletedLines.forEach(lineNumber => {
      var name = blames[lineNumber]
      reviewers[name] = (reviewers[name] || 0) + 3
    })
  });

  Object.keys(fileToNormalLinesMap).forEach(function (file) {
    let normalLines = fileToNormalLinesMap[file];
    var blames = fileToBlamesMap[file]
    normalLines.forEach(lineNumber => {
      var name = blames[lineNumber]
      reviewers[name] = (reviewers[name] || 0) + 1
    })
  });

  console.log('blame point:', reviewers)
  var names = Object.keys(reviewers)
  names.sort((name1, name2) => {
    return reviewers[name1] > reviewers[name2] ? -1 : 1
  })

  var prUser = danger.github.pr.user.login
  names.splice(names.findIndex(el => {
    return el === prUser
  }), 1)

  if (names.length > 0) {
    if (names.length > 2) {
      names = names.slice(0, 2)
    }
    names = names.map(name => {
      return '@' + name
    })

    message("According to the blame info, we recommended " + names.join(' , ') + " to be the reviewers.")
  }
}

/*
 * find reviewer end
 */<|endoftext|>


<commit_before>"use strict";

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
let { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class southxchange extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'southxchange',
            'name': 'SouthXchange',
            'countries': 'AR', // Argentina
            'rateLimit': 1000,
            'hasFetchTickers': true,
            'hasCORS': false,
            'hasWithdraw': true,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27838912-4f94ec8a-60f6-11e7-9e5d-bbf9bd50a559.jpg',
                'api': 'https://www.southxchange.com/api',
                'www': 'https://www.southxchange.com',
                'doc': 'https://www.southxchange.com/Home/Api',
            },
            'api': {
                'public': {
                    'get': [
                        'markets',
                        'price/{symbol}',
                        'prices',
                        'book/{symbol}',
                        'trades/{symbol}',
                    ],
                },
                'private': {
                    'post': [
                        'cancelMarketOrders',
                        'cancelOrder',
                        'generatenewaddress',
                        'listOrders',
                        'listBalances',
                        'placeOrder',
                        'withdraw',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'tierBased': false,
                    'percentage': true,
                    'maker': 0.2 / 100,
                    'taker': 0.2 / 100,
                },
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetMarkets ();
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let market = markets[p];
            let base = market[0];
            let quote = market[1];
            let symbol = base + '/' + quote;
            let id = symbol;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'info': market,
            });
        }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privatePostListBalances ();
        if (!balances)
            throw new ExchangeError (this.id + ' fetchBalance got an unrecognized response');
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['Currency'];
            let uppercase = currency.toUpperCase ();
            let free = parseFloat (balance['Available']);
            let used = parseFloat (balance['Unconfirmed']);
            let total = this.sum (free, used);
            let account = {
                'free': free,
                'used': used,
                'total': total,
            };
            result[uppercase] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetBookSymbol (this.extend ({
            'symbol': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'BuyOrders', 'SellOrders', 'Price', 'Amount');
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': this.safeFloat (ticker, 'Bid'),
            'ask': this.safeFloat (ticker, 'Ask'),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': this.safeFloat (ticker, 'Last'),
            'change': this.safeFloat (ticker, 'Variation24Hr'),
            'percentage': undefined,
            'average': undefined,
            'baseVolume': this.safeFloat (ticker, 'Volume24Hr'),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetPrices (params);
        let tickers = this.indexBy (response, 'Market');
        let ids = Object.keys (tickers);
        let result = {};
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let symbol = id;
            let market = undefined;
            if (id in this.markets_by_id) {
                market = this.markets_by_id[id];
                symbol = market['symbol'];
            }
            let ticker = tickers[id];
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetPriceSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = trade['At'] * 1000;
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'id': undefined,
            'order': undefined,
            'type': undefined,
            'side': trade['Type'],
            'price': trade['Price'],
            'amount': trade['Amount'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetTradesSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let order = {
            'listingCurrency': market['base'],
            'referenceCurrency': market['quote'],
            'type': side,
            'amount': amount,
        };
        if (type == 'limit')
            order['limitPrice'] = price;
        let response = await this.privatePostPlaceOrder (this.extend (order, params));
        return {
            'info': response,
            'id': response.toString (),
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privatePostCancelOrder (this.extend ({
            'orderCode': id,
        }, params));
    }

    async withdraw (currency, amount, address, params = {}) {
        let response = await this.privatePostWithdraw (this.extend ({
            'currency': currency,
            'address': address,
            'amount': amount,
        }, params));
        return {
            'info': response,
            'id': undefined,
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api == 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            query = this.extend ({
                'key': this.apiKey,
                'nonce': nonce,
            }, query);
            body = this.json (query);
            headers = {
                'Content-Type': 'application/json',
                'Hash': this.hmac (this.encode (body), this.encode (this.secret), 'sha512'),
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        return response;
    }
}
<commit_msg>southxchange withdraw tag and linting #1313<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
let { ExchangeError } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class southxchange extends Exchange {

    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'southxchange',
            'name': 'SouthXchange',
            'countries': 'AR', // Argentina
            'rateLimit': 1000,
            'hasFetchTickers': true,
            'hasCORS': false,
            'hasWithdraw': true,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/27838912-4f94ec8a-60f6-11e7-9e5d-bbf9bd50a559.jpg',
                'api': 'https://www.southxchange.com/api',
                'www': 'https://www.southxchange.com',
                'doc': 'https://www.southxchange.com/Home/Api',
            },
            'api': {
                'public': {
                    'get': [
                        'markets',
                        'price/{symbol}',
                        'prices',
                        'book/{symbol}',
                        'trades/{symbol}',
                    ],
                },
                'private': {
                    'post': [
                        'cancelMarketOrders',
                        'cancelOrder',
                        'generatenewaddress',
                        'listOrders',
                        'listBalances',
                        'placeOrder',
                        'withdraw',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'tierBased': false,
                    'percentage': true,
                    'maker': 0.2 / 100,
                    'taker': 0.2 / 100,
                },
            },
        });
    }

    async fetchMarkets () {
        let markets = await this.publicGetMarkets ();
        let result = [];
        for (let p = 0; p < markets.length; p++) {
            let market = markets[p];
            let base = market[0];
            let quote = market[1];
            let symbol = base + '/' + quote;
            let id = symbol;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'info': market,
            });
        }
        return result;
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        let balances = await this.privatePostListBalances ();
        if (!balances)
            throw new ExchangeError (this.id + ' fetchBalance got an unrecognized response');
        let result = { 'info': balances };
        for (let b = 0; b < balances.length; b++) {
            let balance = balances[b];
            let currency = balance['Currency'];
            let uppercase = currency.toUpperCase ();
            let free = parseFloat (balance['Available']);
            let used = parseFloat (balance['Unconfirmed']);
            let total = this.sum (free, used);
            let account = {
                'free': free,
                'used': used,
                'total': total,
            };
            result[uppercase] = account;
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, params = {}) {
        await this.loadMarkets ();
        let orderbook = await this.publicGetBookSymbol (this.extend ({
            'symbol': this.marketId (symbol),
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'BuyOrders', 'SellOrders', 'Price', 'Amount');
    }

    parseTicker (ticker, market = undefined) {
        let timestamp = this.milliseconds ();
        let symbol = undefined;
        if (market)
            symbol = market['symbol'];
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': this.safeFloat (ticker, 'Bid'),
            'ask': this.safeFloat (ticker, 'Ask'),
            'vwap': undefined,
            'open': undefined,
            'close': undefined,
            'first': undefined,
            'last': this.safeFloat (ticker, 'Last'),
            'change': this.safeFloat (ticker, 'Variation24Hr'),
            'percentage': undefined,
            'average': undefined,
            'baseVolume': this.safeFloat (ticker, 'Volume24Hr'),
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetPrices (params);
        let tickers = this.indexBy (response, 'Market');
        let ids = Object.keys (tickers);
        let result = {};
        for (let i = 0; i < ids.length; i++) {
            let id = ids[i];
            let symbol = id;
            let market = undefined;
            if (id in this.markets_by_id) {
                market = this.markets_by_id[id];
                symbol = market['symbol'];
            }
            let ticker = tickers[id];
            result[symbol] = this.parseTicker (ticker, market);
        }
        return result;
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let ticker = await this.publicGetPriceSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        return this.parseTicker (ticker, market);
    }

    parseTrade (trade, market) {
        let timestamp = trade['At'] * 1000;
        return {
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': market['symbol'],
            'id': undefined,
            'order': undefined,
            'type': undefined,
            'side': trade['Type'],
            'price': trade['Price'],
            'amount': trade['Amount'],
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let response = await this.publicGetTradesSymbol (this.extend ({
            'symbol': market['id'],
        }, params));
        return this.parseTrades (response, market, since, limit);
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let order = {
            'listingCurrency': market['base'],
            'referenceCurrency': market['quote'],
            'type': side,
            'amount': amount,
        };
        if (type === 'limit')
            order['limitPrice'] = price;
        let response = await this.privatePostPlaceOrder (this.extend (order, params));
        return {
            'info': response,
            'id': response.toString (),
        };
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        return await this.privatePostCancelOrder (this.extend ({
            'orderCode': id,
        }, params));
    }

    async withdraw (currency, amount, address, tag = undefined, params = {}) {
        let response = await this.privatePostWithdraw (this.extend ({
            'currency': currency,
            'address': address,
            'amount': amount,
        }, params));
        return {
            'info': response,
            'id': undefined,
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.implodeParams (path, params);
        let query = this.omit (params, this.extractParams (path));
        if (api === 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            query = this.extend ({
                'key': this.apiKey,
                'nonce': nonce,
            }, query);
            body = this.json (query);
            headers = {
                'Content-Type': 'application/json',
                'Hash': this.hmac (this.encode (body), this.encode (this.secret), 'sha512'),
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let response = await this.fetch2 (path, api, method, params, headers, body);
        return response;
    }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
// globals isEqual
// jshint esversion: 6
"use strict";

/* jshint ignore:start */
const path = require("path");
const puppeteer = require('puppeteer');

const fileUrl = (relPath) => {
    return 'file://' + path.resolve(process.cwd(), relPath);
};

var dataUriForBase64PNG = (pngBase64) => {
    return "data:image/png;base64," + pngBase64;
};

const renderPage = async (browser, url, successCallback) => {
    const page = await browser.newPage();

    page.on('console', msg => {
        for (let i = 0; i < msg.args().length; ++i) {
            console.log(`${i}: ${msg.args()[i]}`);
        }
    });
    page.on('pageerror', msg => {
        console.error(msg);
    });
    await page.setViewport({ width: 200, height: 100 });
    await page.goto(url);

    const screenshot = await page.screenshot();
    return dataUriForBase64PNG(screenshot.toString('base64'));
};

const runTest = async (browser) => {
    const imageUrl = await renderPage(browser, fileUrl('test/integrationTestPage.html'));
    const targetImageUrl = await renderPage(browser, fileUrl('test/fixtures/testResult.png'));

    const imageDiffPage = await browser.newPage();
    await imageDiffPage.goto(fileUrl('test/diffHelperPage.html'));

    const equal = await imageDiffPage.evaluate(function (url1, url2) {
        return isEqual(url1, url2, 5);
    }, imageUrl, targetImageUrl);

    const screenshotTarget = 'build/rasterizeHtmlSmokeTestDiff.png';
    console.log('Writing diff to ' + screenshotTarget);
    await imageDiffPage.screenshot({path: screenshotTarget});

    return equal;
};

(async () => {
    try {
        const browser = await puppeteer.launch({args: ['--allow-file-access-from-files']});
        const success = await runTest(browser);
        browser.close();

        process.exit(success ? 0 : 1);
    } catch (e) {
        console.error(e);
        process.exit(2);
    }
})();
/* jshint ignore:end */
<commit_msg>Debug failure in Travis<commit_after>#!/usr/bin/env node
// globals isEqual
// jshint esversion: 6
"use strict";

/* jshint ignore:start */
const path = require("path");
const puppeteer = require('puppeteer');

const fileUrl = (relPath) => {
    return 'file://' + path.resolve(process.cwd(), relPath);
};

var dataUriForBase64PNG = (pngBase64) => {
    return "data:image/png;base64," + pngBase64;
};

const renderPage = async (browser, url, successCallback) => {
    const page = await browser.newPage();

    page.on('console', msg => {
        for (let i = 0; i < msg.args().length; ++i) {
            console.log(`${i}: ${msg.args()[i]}`);
        }
    });
    page.on('pageerror', msg => {
        console.error(msg);
    });
    await page.setViewport({ width: 200, height: 100 });
    await page.goto(url);

    await new Promise(fulfill => setTimeout(fulfill, 500));

    const screenshot = await page.screenshot();
    return dataUriForBase64PNG(screenshot.toString('base64'));
};

const runTest = async (browser) => {
    const imageUrl = await renderPage(browser, fileUrl('test/integrationTestPage.html'));
    const targetImageUrl = await renderPage(browser, fileUrl('test/fixtures/testResult.png'));
    console.log('imageUrl', imageUrl);
    console.log('targetImageUrl', targetImageUrl);

    const imageDiffPage = await browser.newPage();
    await imageDiffPage.goto(fileUrl('test/diffHelperPage.html'));

    const equal = await imageDiffPage.evaluate(function (url1, url2) {
        return isEqual(url1, url2, 5);
    }, imageUrl, targetImageUrl);

    const screenshotTarget = 'build/rasterizeHtmlSmokeTestDiff.png';
    console.log('Writing diff to ' + screenshotTarget);
    await imageDiffPage.screenshot({path: screenshotTarget});

    return equal;
};

(async () => {
    try {
        const browser = await puppeteer.launch({args: ['--allow-file-access-from-files']});
        const success = await runTest(browser);
        browser.close();

        process.exit(success ? 0 : 1);
    } catch (e) {
        console.error(e);
        process.exit(2);
    }
})();
/* jshint ignore:end */
<|endoftext|>


<commit_before>/* eslint-env node */
'use strict';

module.exports = {
  name: 'hash-to-query',

  isDevelopingAddon: function() {
    return true;
  },

  contentFor (type, config) {
    if (type === 'body') {
      return `
<script type='text/javascript'>
  var hash = window.location.hash;
  if (hash && hash.length > 1) {
    var pathName = window.location.pathname;
    if (pathName.indexOf('/methods/') === -1 &&
        pathName.indexOf('/properties/') === -1 &&
        pathName.indexOf('/events/') === -1) {
      var type = hash.slice(1, hash.indexOf('_'));
      var name = hash.slice(hash.indexOf('_') + 1, hash.length);
      var anchor = '?anchor=' +
                   name +
                   '&show=inherited,protected,private,deprecated' +
                   '&type=' +
                   type;
      window.location.href = window.location.origin + pathName + anchor;
    }
  }
</script>
`
    }
    return '';
  }
};
<commit_msg>remove unnecessary check in hash to query (#391)<commit_after>/* eslint-env node */
'use strict';

module.exports = {
  name: 'hash-to-query',

  isDevelopingAddon: function() {
    return true;
  },

  contentFor (type, config) {
    if (type === 'body') {
      return `
<script type='text/javascript'>
  var hash = window.location.hash;
  if (hash && hash.length > 1) {
    var pathName = window.location.pathname;
    var type = hash.slice(1, hash.indexOf('_'));
    var name = hash.slice(hash.indexOf('_') + 1, hash.length);
    var anchor = '?anchor=' +
                 name +
                 '&show=inherited,protected,private,deprecated' +
                 '&type=' +
                 type;
    window.location.href = window.location.origin + pathName + anchor;
  }
</script>
`
    }
    return '';
  }
};
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Thu Aug 24 2017 17:43:21 GMT+0330 (Iran Standard Time)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: [
      // './showif.js',
      './test/*.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      './test/*.js': ['webpack']
      // './showif.js' :['webpack']

    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome','Firefox'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
<commit_msg>karma test<commit_after>// Karma configuration
// Generated on Thu Aug 24 2017 17:43:21 GMT+0330 (Iran Standard Time)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    // basePath: './',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha'],

    // list of files / patterns to load in the browser
    files: [
      // './showif.js',
      './test/*.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      './test/*.js': ['webpack']
      // './showif.js' :['webpack']

    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome','Firefox'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}
<|endoftext|>


<commit_before>/**
 * This file is part of Superdesk.
 *
 * Copyright 2013, 2014 Sourcefabric z.u. and contributors.
 *
 * For the full copyright and license information, please see the
 * AUTHORS and LICENSE files distributed with this source code, or
 * at https://www.sourcefabric.org/superdesk/license
 */

define([
    'angular',
    'lodash',
    './module',
    './posts.service',
    './blog.service',
    './pages-manager.service'
], function(angular, _) {
    'use strict';

    angular.module('liveblog.edit')
        .directive('lbPostsList', [
            'postsService', 'notify', '$q', '$timeout', 'session', 'PagesManager',
            function(postsService, notify, $q, $timeout, session, PagesManager) {

                LbPostsListCtrl.$inject = ['$scope', '$element'];
                function LbPostsListCtrl($scope, $element) {
                    var vm = this;
                    angular.extend(vm, {
                        isLoading: true,
                        blogId: $scope.lbPostsBlogId,
                        allowUnpublish: $scope.lbPostsAllowUnpublish,
                        allowReordering: $scope.lbPostsAllowReordering,
                        onPostSelected: $scope.lbPostsOnPostSelected,
                        showReorder: false,
                        hideAllPosts: false,
                        originalOrder: 0,
                        pagesManager: new PagesManager($scope.lbPostsBlogId,
                                                       $scope.lbPostsStatus,
                                                       10,
                                                       $scope.lbPostsOrderBy || 'editorial'),
                        fetchNewPage: function() {
                            vm.isLoading = true;
                            return vm.pagesManager.fetchNewPage().then(function() {
                                vm.isLoading = false;
                            });
                        },
                        startReorder: function(post) {
                            vm.reorderPost = post;
                        },
                        clearReorder: function() {
                            vm.reorderPost = false;
                            $timeout(function() {
                                vm.keepHighlighted = false;
                            }, 2000);
                            $timeout(function() {
                                vm.hideAllPosts = false;
                            }, 200);
                        },
                        getOrder: function(position) {
                            return angular.element($element.find('.posts').find('li .lb-post').get(position)).scope().post.order;
                        },
                        reorder: function(index, location) {
                            if (vm.allowReordering) {
                                var position = index;
                                var order, before, after;
                                if (position === 0) {
                                    order = vm.getOrder(0) + 1;
                                } else if (position === $element.find('.posts').find('li .lb-post').length - 1) {
                                    order = vm.getOrder(position) - 1;
                                } else {
                                    if (location === 'above') {
                                        before = vm.getOrder(position - 1);
                                        after = vm.getOrder(position);
                                    } else {
                                        before = vm.getOrder(position);
                                        after = vm.getOrder(position + 1);
                                    }
                                    order = after + (before - after) / 2;
                                }
                                vm.updatePostOrder(vm.reorderPost, order);
                            }
                        },
                        updatePostOrder: function(post, order) {
                            vm.hideAllPosts = true;
                            postsService.savePost(post.blog, post, undefined, {order: order}).then(function() {
                                vm.keepHighlighted = order;
                                vm.clearReorder();
                            }, function() {
                                vm.hideAllPosts = false;
                                notify.pop();
                                notify.error(gettext('Something went wrong. Please reload and try again later'));
                            });
                        },
                        isPostsEmpty: function() {
                            return vm.pagesManager.count() < 1 && !vm.isLoading;
                        },
                        isFilterEnable: function() {
                            return vm.pagesManager.authors.length > 0;
                        },
                        setAuthorFilter: function(users) {
                            vm.authorFilters = users;
                            vm.isLoading = true;
                            return vm.pagesManager.setAuthors(users.map(function(user) {return user._id;})).then(function() {
                                vm.isLoading = false;
                            });
                        }
                    });
                    $scope.lbPostsInstance = vm;
                    // retrieve first page
                    vm.fetchNewPage()
                    // retrieve updates when event is recieved
                    .then(function() {
                        $scope.$on('posts', function(e, event_params) {
                            vm.isLoading = true;
                            vm.pagesManager.retrieveUpdate(true).then(function() {
                                if (event_params.deleted === true) {
                                    notify.pop();
                                    notify.info(gettext('Post removed'));
                                }
                                vm.isLoading = false;
                            });
                        });
                    });
                }
                return {
                    scope: {
                        lbPostsBlogId: '=',
                        lbPostsStatus: '@',
                        lbPostsOrderBy: '@',
                        lbPostsAllowUnpublish: '=',
                        lbPostsAllowReordering: '=',
                        lbPostsOnPostSelected: '=',
                        lbPostsInstance: '='
                    },
                    restrict: 'EA',
                    transclude: true,
                    templateUrl: 'scripts/liveblog-edit/views/posts.html',
                    controllerAs: 'postsList',
                    controller: LbPostsListCtrl
                };
            }
        ])
        .directive('lbPost', [
            'notify', 'gettext', 'asset', 'postsService', 'modal', 'blogSecurityService',
            function(notify, gettext, asset, postsService, modal, blogSecurityService) {
                return {
                    scope: {
                        post: '=',
                        onEditClick: '=',
                        //the post that is in the process of being reordered
                        reorderPost: '=',
                        //the order property of the post that was reordered and should stay highlighted a bit more
                        keepHighlighted: '=',
                        allowUnpublish: '=',
                        allowReordering: '=',
                        //call when the user clicks on the reorder icon
                        startReorder: '&',
                        //call when the user has chosen a new place for the post
                        reorder: '&',
                        //the index of the post in the list
                        index: '='
                    },
                    restrict: 'E',
                    templateUrl: 'scripts/liveblog-edit/views/post.html',
                    link: function(scope, elem, attrs) {
                        angular.extend(scope, {
                            isAbleToEditContribution: function(post) {
                                return blogSecurityService.canPublishAPost() || blogSecurityService.isUserOwner(post);
                            },
                            toggleMultipleItems: function() {
                                scope.show_all = !scope.show_all;
                            },
                            removePost: function(post) {
                                postsService.remove(angular.copy(post)).then(function(message) {
                                    notify.pop();
                                    notify.info(gettext('Removing post...'));
                                }, function() {
                                    notify.pop();
                                    notify.error(gettext('Something went wrong'));
                                });
                            },
                            preMovePost: function(post) {
                                scope.startReorder({post: post});
                            },
                            movePost: function(index, location) {
                                scope.reorder({index: index, location: location});
                            },
                            askRemovePost: function(post) {
                                modal.confirm(gettext('Are you sure you want to delete the post?'))
                                    .then(function() {
                                        scope.removePost(post);
                                    });
                            },
                            unpublishPost: function(post) {
                                // don't save the original post coming for the posts list, because it needs
                                // to conserve its original update date in the posts list directive
                                // in order to retrieve updates from this date (if latest)
                                post = angular.copy(post);
                                // save the post as draft
                                postsService.saveDraft(post.blog, post).then(function(post) {
                                    notify.pop();
                                    notify.info(gettext('Post saved as draft'));
                                }, function() {
                                    notify.pop();
                                    notify.error(gettext('Something went wrong. Please try again later'));
                                });
                            }
                        });
                    }
                };
            }
        ])
        .directive('stopEvent', function () {
            return {
                restrict: 'A',
                link: function (scope, element, attr) {
                    element.bind(attr.stopEvent, function (e) {
                        e.stopPropagation();
                    });
                }
            };
        })
        .directive('selectTextOnClick', [function() {
            return {
                link: function(scope, elem, attrs) {
                    elem.bind('click', function() {
                        elem.focus();
                        elem.select();
                    });
                }
            };
        }])
        .directive('lbBindHtml', [function() {
            return {
                restrict: 'A',
                priority: 2,
                link: function(scope, elem, attrs) {
                    attrs.$observe('htmlContent', function() {
                        if (attrs.htmlLocation) {
                            //need to inject the html in a specific element
                            elem.find('[' + attrs.htmlLocation + ']').html(attrs.htmlContent);
                        } else {
                            //inject streaght in the elem
                            elem.html(attrs.htmlContent);
                        }
                    });
                }
            };
        }])
        .directive('lbFilterByMember', ['api', function(api) {
            return {
                restrict: 'E',
                scope: {
                    blogId: '=',
                    onFilterChange: '='
                },
                templateUrl: 'scripts/liveblog-edit/views/filter-by-member.html',
                controllerAs: 'vm',
                controller: ['$scope', function($scope) {
                    var vm = this;
                    angular.extend(vm, {
                        members: [],
                        openSelector: false,
                        preselectedUsers: [],
                        selectedUsers: [],
                        findUserInPreselection: function(user_id) {
                            return _.find(vm.preselectedUsers, function(user) {
                                return user._id === user_id;
                            });
                        },
                        toggleUserInPreselection: function(user) {
                            var old_user = vm.findUserInPreselection(user._id);
                            if (old_user) {
                                vm.preselectedUsers.splice(vm.preselectedUsers.indexOf(old_user), 1);
                            } else {
                                vm.preselectedUsers.push(user);
                            }
                        },
                        isUserInPreselection: function(user) {
                            return vm.findUserInPreselection(user._id);
                        },
                        confirmPreselection: function() {
                            vm.updateFilters(angular.copy(vm.preselectedUsers));
                        },
                        updateFilters: function(fitlers) {
                            vm.selectedUsers = fitlers;
                            $scope.onFilterChange(vm.selectedUsers);
                        },
                        clearSelection: function() {
                            vm.updateFilters([]);
                        },
                        removeUserFromSelection: function(user) {
                            var filters = angular.copy(vm.selectedUsers);
                            filters.splice(vm.selectedUsers.indexOf(user), 1);
                            vm.updateFilters(filters);
                        },
                        toggleSelector: function() {
                            vm.openSelector = !vm.openSelector;
                            if (vm.openSelector) {
                                // clear the search input
                                vm.search = '';
                                // preset the preselection to the current selection
                                vm.preselectedUsers = angular.copy(vm.selectedUsers);
                                // retrieve blog information to know the owner and the members
                                api('blogs').getById($scope.blogId).then(function(blog) {
                                    // add the owner
                                    var ids = [blog.original_creator];
                                    // add the members
                                    if (blog.members) {
                                        ids.push.apply(ids, blog.members.map(function(member) {return member.user;}));
                                    }
                                    // retrieve information about these users and list them in the view
                                    api('users').query({where: {_id: {$in: ids}}}).then(function(data) {
                                        vm.members = data._items;
                                    });
                                });
                            }
                        }
                    });
                }]
            };
        }])
        .directive('autofocus', ['$timeout', function($timeout) {
            return {
                restrict: 'A',
                link : function($scope, $element) {
                    $timeout(function() {
                        $element[0].focus();
                    });
                }
            };
        }])
        .directive('fullHeight', ['$timeout', '$window', 'lodash', function($timeout, $window, _) {
            return {
                restrict: 'A',
                link : function($scope, $element) {
                    // update the element height to the window height minus its vertical offset
                    function setHeight() {
                        $timeout(function() {
                            var height = $window.innerHeight - $element.offset().top;
                            $element.css('height', height);
                            $element[0].focus();
                        });
                    }
                    // initialize
                    setHeight();
                    // update when the window size changes
                    angular.element($window).on('resize', _.debounce(setHeight, 500));
                    // update when offset changes
                    $scope.$watch(function() {
                        return $element.offset().top;
                    }, _.debounce(setHeight, 500));
                }
            };
        }]);
});

// EOF
<commit_msg>jshint<commit_after>/**
 * This file is part of Superdesk.
 *
 * Copyright 2013, 2014 Sourcefabric z.u. and contributors.
 *
 * For the full copyright and license information, please see the
 * AUTHORS and LICENSE files distributed with this source code, or
 * at https://www.sourcefabric.org/superdesk/license
 */

define([
    'angular',
    'lodash',
    './module',
    './posts.service',
    './blog.service',
    './pages-manager.service'
], function(angular, _) {
    'use strict';

    angular.module('liveblog.edit')
        .directive('lbPostsList', [
            'postsService', 'notify', '$q', '$timeout', 'session', 'PagesManager',
            function(postsService, notify, $q, $timeout, session, PagesManager) {

                LbPostsListCtrl.$inject = ['$scope', '$element'];
                function LbPostsListCtrl($scope, $element) {
                    var vm = this;
                    angular.extend(vm, {
                        isLoading: true,
                        blogId: $scope.lbPostsBlogId,
                        allowUnpublish: $scope.lbPostsAllowUnpublish,
                        allowReordering: $scope.lbPostsAllowReordering,
                        onPostSelected: $scope.lbPostsOnPostSelected,
                        showReorder: false,
                        hideAllPosts: false,
                        originalOrder: 0,
                        pagesManager: new PagesManager($scope.lbPostsBlogId,
                                                       $scope.lbPostsStatus,
                                                       10,
                                                       $scope.lbPostsOrderBy || 'editorial'),
                        fetchNewPage: function() {
                            vm.isLoading = true;
                            return vm.pagesManager.fetchNewPage().then(function() {
                                vm.isLoading = false;
                            });
                        },
                        startReorder: function(post) {
                            vm.reorderPost = post;
                        },
                        clearReorder: function() {
                            vm.reorderPost = false;
                            $timeout(function() {
                                vm.keepHighlighted = false;
                            }, 2000);
                            $timeout(function() {
                                vm.hideAllPosts = false;
                            }, 200);
                        },
                        getOrder: function(position) {
                            return angular.element($element.find('.posts').find('li .lb-post').get(position)).scope().post.order;
                        },
                        reorder: function(index, location) {
                            if (vm.allowReordering) {
                                var position = index;
                                var order, before, after;
                                if (position === 0) {
                                    order = vm.getOrder(0) + 1;
                                } else if (position === $element.find('.posts').find('li .lb-post').length - 1) {
                                    order = vm.getOrder(position) - 1;
                                } else {
                                    if (location === 'above') {
                                        before = vm.getOrder(position - 1);
                                        after = vm.getOrder(position);
                                    } else {
                                        before = vm.getOrder(position);
                                        after = vm.getOrder(position + 1);
                                    }
                                    order = after + (before - after) / 2;
                                }
                                vm.updatePostOrder(vm.reorderPost, order);
                            }
                        },
                        updatePostOrder: function(post, order) {
                            vm.hideAllPosts = true;
                            postsService.savePost(post.blog, post, undefined, {order: order}).then(function() {
                                vm.keepHighlighted = order;
                                vm.clearReorder();
                            }, function() {
                                vm.hideAllPosts = false;
                                notify.pop();
                                notify.error(gettext('Something went wrong. Please reload and try again later'));
                            });
                        },
                        isPostsEmpty: function() {
                            return vm.pagesManager.count() < 1 && !vm.isLoading;
                        },
                        isFilterEnable: function() {
                            return vm.pagesManager.authors.length > 0;
                        },
                        setAuthorFilter: function(users) {
                            vm.authorFilters = users;
                            vm.isLoading = true;
                            return vm.pagesManager.setAuthors(users.map(function(user) {return user._id;})).then(function() {
                                vm.isLoading = false;
                            });
                        }
                    });
                    $scope.lbPostsInstance = vm;
                    // retrieve first page
                    vm.fetchNewPage()
                    // retrieve updates when event is recieved
                    .then(function() {
                        $scope.$on('posts', function(e, event_params) {
                            vm.isLoading = true;
                            vm.pagesManager.retrieveUpdate(true).then(function() {
                                if (event_params.deleted === true) {
                                    notify.pop();
                                    notify.info(gettext('Post removed'));
                                }
                                vm.isLoading = false;
                            });
                        });
                    });
                }
                return {
                    scope: {
                        lbPostsBlogId: '=',
                        lbPostsStatus: '@',
                        lbPostsOrderBy: '@',
                        lbPostsAllowUnpublish: '=',
                        lbPostsAllowReordering: '=',
                        lbPostsOnPostSelected: '=',
                        lbPostsInstance: '='
                    },
                    restrict: 'EA',
                    transclude: true,
                    templateUrl: 'scripts/liveblog-edit/views/posts.html',
                    controllerAs: 'postsList',
                    controller: LbPostsListCtrl
                };
            }
        ])
        .directive('lbPost', [
            'notify', 'gettext', 'asset', 'postsService', 'modal', 'blogSecurityService',
            function(notify, gettext, asset, postsService, modal, blogSecurityService) {
                return {
                    scope: {
                        post: '=',
                        onEditClick: '=',
                        //the post that is in the process of being reordered
                        reorderPost: '=',
                        //the order property of the post that was reordered and should stay highlighted a bit more
                        keepHighlighted: '=',
                        allowUnpublish: '=',
                        allowReordering: '=',
                        //call when the user clicks on the reorder icon
                        startReorder: '&',
                        //call when the user has chosen a new place for the post
                        reorder: '&',
                        //the index of the post in the list
                        index: '='
                    },
                    restrict: 'E',
                    templateUrl: 'scripts/liveblog-edit/views/post.html',
                    link: function(scope, elem, attrs) {
                        angular.extend(scope, {
                            isAbleToEditContribution: function(post) {
                                return blogSecurityService.canPublishAPost() || blogSecurityService.isUserOwner(post);
                            },
                            toggleMultipleItems: function() {
                                scope.show_all = !scope.show_all;
                            },
                            removePost: function(post) {
                                postsService.remove(angular.copy(post)).then(function(message) {
                                    notify.pop();
                                    notify.info(gettext('Removing post...'));
                                }, function() {
                                    notify.pop();
                                    notify.error(gettext('Something went wrong'));
                                });
                            },
                            preMovePost: function(post) {
                                scope.startReorder({post: post});
                            },
                            movePost: function(index, location) {
                                scope.reorder({index: index, location: location});
                            },
                            askRemovePost: function(post) {
                                modal.confirm(gettext('Are you sure you want to delete the post?'))
                                    .then(function() {
                                        scope.removePost(post);
                                    });
                            },
                            unpublishPost: function(post) {
                                // don't save the original post coming for the posts list, because it needs
                                // to conserve its original update date in the posts list directive
                                // in order to retrieve updates from this date (if latest)
                                post = angular.copy(post);
                                // save the post as draft
                                postsService.saveDraft(post.blog, post).then(function(post) {
                                    notify.pop();
                                    notify.info(gettext('Post saved as draft'));
                                }, function() {
                                    notify.pop();
                                    notify.error(gettext('Something went wrong. Please try again later'));
                                });
                            }
                        });
                    }
                };
            }
        ])
        .directive('stopEvent', function () {
            return {
                restrict: 'A',
                link: function (scope, element, attr) {
                    element.bind(attr.stopEvent, function (e) {
                        e.stopPropagation();
                    });
                }
            };
        })
        .directive('selectTextOnClick', [function() {
            return {
                link: function(scope, elem, attrs) {
                    elem.bind('click', function() {
                        elem.focus();
                        elem.select();
                    });
                }
            };
        }])
        .directive('lbBindHtml', [function() {
            return {
                restrict: 'A',
                priority: 2,
                link: function(scope, elem, attrs) {
                    attrs.$observe('htmlContent', function() {
                        if (attrs.htmlLocation) {
                            //need to inject the html in a specific element
                            elem.find('[' + attrs.htmlLocation + ']').html(attrs.htmlContent);
                        } else {
                            //inject streaght in the elem
                            elem.html(attrs.htmlContent);
                        }
                    });
                }
            };
        }])
        .directive('lbFilterByMember', ['api', function(api) {
            return {
                restrict: 'E',
                scope: {
                    blogId: '=',
                    onFilterChange: '='
                },
                templateUrl: 'scripts/liveblog-edit/views/filter-by-member.html',
                controllerAs: 'vm',
                controller: ['$scope', function($scope) {
                    var vm = this;
                    angular.extend(vm, {
                        members: [],
                        openSelector: false,
                        preselectedUsers: [],
                        selectedUsers: [],
                        findUserInPreselection: function(user_id) {
                            return _.find(vm.preselectedUsers, function(user) {
                                return user._id === user_id;
                            });
                        },
                        toggleUserInPreselection: function(user) {
                            var old_user = vm.findUserInPreselection(user._id);
                            if (old_user) {
                                vm.preselectedUsers.splice(vm.preselectedUsers.indexOf(old_user), 1);
                            } else {
                                vm.preselectedUsers.push(user);
                            }
                        },
                        isUserInPreselection: function(user) {
                            return vm.findUserInPreselection(user._id);
                        },
                        confirmPreselection: function() {
                            vm.updateFilters(angular.copy(vm.preselectedUsers));
                        },
                        updateFilters: function(fitlers) {
                            vm.selectedUsers = fitlers;
                            $scope.onFilterChange(vm.selectedUsers);
                        },
                        clearSelection: function() {
                            vm.updateFilters([]);
                        },
                        removeUserFromSelection: function(user) {
                            var filters = angular.copy(vm.selectedUsers);
                            filters.splice(vm.selectedUsers.indexOf(user), 1);
                            vm.updateFilters(filters);
                        },
                        toggleSelector: function() {
                            vm.openSelector = !vm.openSelector;
                            if (vm.openSelector) {
                                // clear the search input
                                vm.search = '';
                                // preset the preselection to the current selection
                                vm.preselectedUsers = angular.copy(vm.selectedUsers);
                                // retrieve blog information to know the owner and the members
                                api('blogs').getById($scope.blogId).then(function(blog) {
                                    // add the owner
                                    var ids = [blog.original_creator];
                                    // add the members
                                    if (blog.members) {
                                        ids.push.apply(ids, blog.members.map(function(member) {return member.user;}));
                                    }
                                    // retrieve information about these users and list them in the view
                                    api('users').query({where: {_id: {$in: ids}}}).then(function(data) {
                                        vm.members = data._items;
                                    });
                                });
                            }
                        }
                    });
                }]
            };
        }])
        .directive('autofocus', ['$timeout', function($timeout) {
            return {
                restrict: 'A',
                link: function($scope, $element) {
                    $timeout(function() {
                        $element[0].focus();
                    });
                }
            };
        }])
        .directive('fullHeight', ['$timeout', '$window', 'lodash', function($timeout, $window, _) {
            return {
                restrict: 'A',
                link: function($scope, $element) {
                    // update the element height to the window height minus its vertical offset
                    function setHeight() {
                        $timeout(function() {
                            var height = $window.innerHeight - $element.offset().top;
                            $element.css('height', height);
                            $element[0].focus();
                        });
                    }
                    // initialize
                    setHeight();
                    // update when the window size changes
                    angular.element($window).on('resize', _.debounce(setHeight, 500));
                    // update when offset changes
                    $scope.$watch(function() {
                        return $element.offset().top;
                    }, _.debounce(setHeight, 500));
                }
            };
        }]);
});

// EOF
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Wed Jan 04 2017 08:31:39 GMT+0300 (EAT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'jasmine/spec/inverted-index-test.js',
      'public/src/inverted-index.js',
    ],

    // list of files to exclude
    exclude: [
    ],
plugins:[
             'karma-jasmine',
             'coveralls' ,
             'karma-coverage',
             'karma-chrome-launcher',
             ],
customLaunchers: {
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'public/src/inverted-index.js': 'coverage'
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress' , "coverage", "coveralls"],

    coverageReporter: {
      type: 'lcov', // lcov or lcovonly are required for generating lcov.info files
      dir: 'coverage/'
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    //browsers: ['Chrome'],
    browsers: process.env.TRAVIS ? ["Chrome_travis_ci"] : ["Chrome"],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
  if(process.env.TRAVIS) {
  config.browsers = ['Chrome_travis_ci'];
  }
}
<commit_msg>modify reporters to single quotes<commit_after>// Karma configuration
// Generated on Wed Jan 04 2017 08:31:39 GMT+0300 (EAT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: [
      'jasmine/spec/inverted-index-test.js',
      'public/src/inverted-index.js',
    ],

    // list of files to exclude
    exclude: [
    ],
plugins:[
             'karma-jasmine',
             'coveralls' ,
             'karma-coverage',
             'karma-chrome-launcher',
             ],
customLaunchers: {
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'public/src/inverted-index.js': 'coverage'
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress' , 'coverage', 'coveralls'],

    coverageReporter: {
      type: 'lcov', // lcov or lcovonly are required for generating lcov.info files
      dir: 'coverage/'
    },

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    //browsers: ['Chrome'],
    browsers: process.env.TRAVIS ? ["Chrome_travis_ci"] : ["Chrome"],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
  if(process.env.TRAVIS) {
  config.browsers = ['Chrome_travis_ci'];
  }
}
<|endoftext|>


<commit_before>import { define } from '../../src/index';

let componentCount = 0;

export default function component (opts) {
  return define(`my-el-${++componentCount}`, opts);
}
<commit_msg>test: Remove redundant test helper.<commit_after><|endoftext|>


<commit_before>// gridfs-stream

/**
 * Module dependencies.
 */

var GridWriteStream = require('./writestream')
var GridReadStream = require('./readstream')

/**
 * Grid constructor
 *
 * @param {mongo.Db} db - an open mongo.Db instance
 * @param {mongo} [mongo] - the native driver you are using
 */

function Grid (db, mongo) {
  if (!(this instanceof Grid)) {
    return new Grid(db, mongo);
  }

  mongo || (mongo = Grid.mongo ? Grid.mongo : undefined);

  if (!mongo) throw new Error('missing mongo argument\nnew Grid(db, mongo)');
  if (!db) throw new Error('missing db argument\nnew Grid(db, mongo)');

  // the db must already be open b/c there is no `open` event emitted
  // in old versions of the driver
  this.db = db;
  this.mongo = mongo;
}

/**
 * Creates a writable stream.
 *
 * @param {Object} [options]
 * @return Stream
 */

Grid.prototype.createWriteStream = function (options) {
  return new GridWriteStream(this, options);
}

/**
 * Creates a readable stream. Pass at least a filename or _id option
 *
 * @param {Object} options
 * @return Stream
 */

Grid.prototype.createReadStream = function (options) {
  return new GridReadStream(this, options);
}

/**
 * The collection used to store file data in mongodb.
 * @return {Collection}
 */

Object.defineProperty(Grid.prototype, 'files', {
  get: function () {
    if (this._col) return this._col;
    return this.collection();
  }
});

/**
 * Changes the default collection to `name` or to the default mongodb gridfs collection if not specified.
 *
 * @param {String|undefined} name root gridfs collection name
 * @return {Collection}
 */

Grid.prototype.collection = function (name) {
  name || (name = this.mongo.GridStore.DEFAULT_ROOT_COLLECTION);
  return this._col = this.db.collection(name + ".files");
}

/**
 * Removes a file by passing any options, at least an _id or filename
 *
 * @param {Object} options
 * @param {Function} callback
 */

Grid.prototype.remove = function (options, callback) {
  var _id;
  if (options._id) {
    _id = this.tryParseObjectId(options._id) || options._id;
  }
  if (!_id) {
    _id = options.filename;
  }
  return this.mongo.GridStore.unlink(this.db, _id, options, callback);
}

/**
 * Checks if a file exists by passing a filename
 *
 * @param {Object} options
 * @param {Function} callback
 */

Grid.prototype.exist = function (options, callback) {
    var _id;
    if (options._id) {
        _id = this.tryParseObjectId(options._id) || options._id;
    }
    if (!_id) {
        _id = options.filename;
    }
    return this.mongo.GridStore.exist(this.db, _id, callback);
}

/**
 * Attemps to parse `string` into an ObjectId
 *
 * @param {GridReadStream} self
 * @param {String|ObjectId} string
 * @return {ObjectId|Boolean}
 */

Grid.prototype.tryParseObjectId = function tryParseObjectId (string) {
  try {
    return new this.mongo.BSONPure.ObjectID(string);
  } catch (_) {
    return false;
  }
}

/**
 * expose
 */

module.exports = exports = Grid;
<commit_msg>fix #50<commit_after>// gridfs-stream

/**
 * Module dependencies.
 */

var GridWriteStream = require('./writestream')
var GridReadStream = require('./readstream')

/**
 * Grid constructor
 *
 * @param {mongo.Db} db - an open mongo.Db instance
 * @param {mongo} [mongo] - the native driver you are using
 */

function Grid (db, mongo) {
  if (!(this instanceof Grid)) {
    return new Grid(db, mongo);
  }

  mongo || (mongo = Grid.mongo ? Grid.mongo : undefined);

  if (!mongo) throw new Error('missing mongo argument\nnew Grid(db, mongo)');
  if (!db) throw new Error('missing db argument\nnew Grid(db, mongo)');

  // the db must already be open b/c there is no `open` event emitted
  // in old versions of the driver
  this.db = db;
  this.mongo = mongo;
}

/**
 * Creates a writable stream.
 *
 * @param {Object} [options]
 * @return Stream
 */

Grid.prototype.createWriteStream = function (options) {
  return new GridWriteStream(this, options);
}

/**
 * Creates a readable stream. Pass at least a filename or _id option
 *
 * @param {Object} options
 * @return Stream
 */

Grid.prototype.createReadStream = function (options) {
  return new GridReadStream(this, options);
}

/**
 * The collection used to store file data in mongodb.
 * @return {Collection}
 */

Object.defineProperty(Grid.prototype, 'files', {
  get: function () {
    if (this._col) return this._col;
    return this.collection();
  }
});

/**
 * Changes the default collection to `name` or to the default mongodb gridfs collection if not specified.
 *
 * @param {String|undefined} name root gridfs collection name
 * @return {Collection}
 */

Grid.prototype.collection = function (name) {
  name || (name = this.mongo.GridStore.DEFAULT_ROOT_COLLECTION);
  return this._col = this.db.collection(name + ".files");
}

/**
 * Removes a file by passing any options, at least an _id or filename
 *
 * @param {Object} options
 * @param {Function} callback
 */

Grid.prototype.remove = function (options, callback) {
  var _id;
  if (options._id) {
    _id = this.tryParseObjectId(options._id) || options._id;
  }
  if (!_id) {
    _id = options.filename;
  }
  return this.mongo.GridStore.unlink(this.db, _id, options, callback);
}

/**
 * Checks if a file exists by passing a filename
 *
 * @param {Object} options
 * @param {Function} callback
 */

Grid.prototype.exist = function (options, callback) {
    var _id;
    if (options._id) {
        _id = this.tryParseObjectId(options._id) || options._id;
    }
    if (!_id) {
        _id = options.filename;
    }
    return this.mongo.GridStore.exist(this.db, _id, options.root, callback);
}

/**
 * Attemps to parse `string` into an ObjectId
 *
 * @param {GridReadStream} self
 * @param {String|ObjectId} string
 * @return {ObjectId|Boolean}
 */

Grid.prototype.tryParseObjectId = function tryParseObjectId (string) {
  try {
    return new this.mongo.BSONPure.ObjectID(string);
  } catch (_) {
    return false;
  }
}

/**
 * expose
 */

module.exports = exports = Grid;
<|endoftext|>