<commit_before>/**
 * event emitter
 */
export default class EventEmitter {
  constructor () {
    /** @private */
    this._handlers = new Map()
  }
  /**
   * @param {string|Symbol} type
   * @param {function} handler
   */
  on (type, handler) {
    if (!this._handlers.has(type)) {
      this._handlers.set(type, new Set())
    }
    this._handlers.get(type).add(handler)
  }
  /**
   * @param {string|Symbol} type
   * @param {function} handler
   */
  off (type, handler) {
    if (!this._handlers.has(type)) {
      return
    }
    this._handlers.get(type).delete(handler)
  }
  /**
   * @param {string|Symbol} type
   * @param {*} data
   */
  emit (type, data) {
    if (this._handlers.has(type)) {
      this._handlers.get(type).forEach(func => func(data))
    }
  }
}
<commit_msg>change event emitter API<commit_after>/**
 * event emitter
 */
export default class EventEmitter {
  constructor () {
    /** @private */
    this._handlers = new Map()
  }
  /**
   * @param {string|Symbol} type
   * @param {function} handler
   */
  on (type, handler) {
    if (!this._handlers.has(type)) {
      this._handlers.set(type, new Set())
    }
    this._handlers.get(type).add(handler)
  }
  /**
   * @param {string|Symbol} type
   * @param {function} handler
   * @returns {boolean}
   */
  off (type, handler) {
    if (!this._handlers.has(type)) {
      return false
    }
    return this._handlers.get(type).delete(handler)
  }
  /**
   * @param {string|Symbol} type
   * @param {*} data
   */
  emit (type, data) {
    if (this._handlers.has(type)) {
      this._handlers.get(type).forEach(func => func(data))
    }
  }
}
<|endoftext|>


<commit_before>
// Much of this code has been purloined from targetable.js – do we need the
// hashchange tracking here? I have commented it

import Stream, { Source } from '../../fn/stream/stream.js';

const assign = Object.assign;

const captureOptions = {
    capture: true,
    passive: true
};

/*
Config
*/

export const config = {
    minScrollEventInterval: 0.0375,
    maxScrollEventInterval: 0.18
};

// Capture scroll events in capture phase, as scroll events from elements
// other than document do not bubble.

var trackingInterval = config.maxScrollEventInterval;

function update(source, e) {
    const { times } = source;
    if (times.length < 2) {
        times.length = 0;
        return;
    }

    // Dynamically adjust maxScrollEventInterval to tighten it up,
    // imposing a baseline of 60ms (0.0375s * 1.6)
    let n = times.length, interval = 0;
    while (--n) {
        const t = times[n] - times[n - 1];
        interval = t > interval ? t : interval;
    }

    interval = interval < config.minScrollEventInterval ?
        config.minScrollEventInterval :
        interval ;

    trackingInterval =  (1.4 * interval) > config.maxScrollEventInterval ?
        config.maxScrollEventInterval :
        (1.4 * interval) ;

    source.value.stop();
    source.value = undefined;
}

function Scrolls(element) {
    this.element = element;
    this.times   = [];
}

assign(Scrolls.prototype, Source.prototype, {
    start: function() {
        // Method may be used once only
        //if (window.DEBUG) { this.start = startError; }

        /*
        window.addEventListener('hashchange', function hashchange(e) {
            hashtime = e.timeStamp / 1000;
            //console.log('hashchange', hashtime, window.location.hash);
        });
        */

        this.element.addEventListener('scroll', this, captureOptions);

        // Update count of running streams
        ++Stream.count;
    },

    handleEvent: function(e) {
        // Ignore the first scroll event following a hashchange. The browser sends a
        // scroll event even where a target cannot be scrolled to, such as a
        // navigation with position: fixed, for example. This can cause targetable
        // to recalculate again, and shift the target back to one fo the targetables,
        // where it should stay on the navigation element.
        const time = e.timeStamp / 1000;

        // Make sure this only happens once after a hashchange
        /*if (hashtime !== undefined) {
            // If we are not mid-scroll, and the latest hashchange was less than
            // 0.1s ago, ignore
            if (!times.length && hashtime > time - 0.1) {
                //console.log('scroll', 'ignored');
                hashtime = undefined;
                return;
            }

            hashtime = undefined;
        }*/

        this.times.push(time);

        if (this.value) {
            // Update only when there is a trackingInterval second pause in scrolling
            clearTimeout(this.timer);
            this.value.push(e);
        }
        else {
            this.value = Stream.of(e);
            this.target.push(this.value);
        }

        this.timer = setTimeout(update, trackingInterval * 1000, this, e);
    },

    stop: function() {
        this.element.removeEventListener('scroll', scroll);
        Source.prototype.stop.apply(this, arguments);
    }
});

export default function scrolls(element) {
    return new Stream(new Scrolls(element));
}
<commit_msg>Detect single scroll events as scrol gesture<commit_after>
// Much of this code has been purloined from targetable.js – do we need the
// hashchange tracking here? I have commented it

import Stream, { Source } from '../../fn/stream/stream.js';

const assign = Object.assign;

const captureOptions = {
    capture: true,
    passive: true
};

/*
Config
*/

export const config = {
    minScrollEventInterval: 0.0375,
    maxScrollEventInterval: 0.18
};

// Capture scroll events in capture phase, as scroll events from elements
// other than document do not bubble.

var trackingInterval = config.maxScrollEventInterval;

function adjustTrackingInterval(times) {
    // Dynamically adjust maxScrollEventInterval to tighten it up,
    // imposing a baseline of 60ms (0.0375s * 1.6)

    let n = times.length;
    let interval = 0;

    while (--n) {
        const t = times[n] - times[n - 1];
        interval = t > interval ? t : interval;
    }

    interval = interval < config.minScrollEventInterval ?
        config.minScrollEventInterval :
        interval ;

    trackingInterval =  (1.4 * interval) > config.maxScrollEventInterval ?
        config.maxScrollEventInterval :
        (1.4 * interval) ;
}

function update(source, e) {
    const { times } = source;

    source.value.stop();
    source.value = undefined;

    if (times.length > 1) {
        adjustTrackingInterval(times);
    }

    times.length = 0;
}

function Scrolls(element) {
    this.element = element;
    this.times   = [];
}

assign(Scrolls.prototype, Source.prototype, {
    start: function() {
        // Method may be used once only
        //if (window.DEBUG) { this.start = startError; }

        /*
        window.addEventListener('hashchange', function hashchange(e) {
            hashtime = e.timeStamp / 1000;
            //console.log('hashchange', hashtime, window.location.hash);
        });
        */

        this.element.addEventListener('scroll', this, captureOptions);

        // Update count of running streams
        ++Stream.count;
    },

    handleEvent: function(e) {
        // Ignore the first scroll event following a hashchange. The browser sends a
        // scroll event even where a target cannot be scrolled to, such as a
        // navigation with position: fixed, for example. This can cause targetable
        // to recalculate again, and shift the target back to one fo the targetables,
        // where it should stay on the navigation element.
        const time = e.timeStamp / 1000;

        // Make sure this only happens once after a hashchange
        /*if (hashtime !== undefined) {
            // If we are not mid-scroll, and the latest hashchange was less than
            // 0.1s ago, ignore
            if (!times.length && hashtime > time - 0.1) {
                //console.log('scroll', 'ignored');
                hashtime = undefined;
                return;
            }

            hashtime = undefined;
        }*/

        this.times.push(time);

        if (this.value) {
            clearTimeout(this.timer);
            this.value.push(e);
        }
        else {
            this.value = Stream.of(e);
            this.target.push(this.value);
        }

        // Update only when there is a trackingInterval second pause in scrolling
        this.timer = setTimeout(update, trackingInterval * 1000, this, e);
    },

    stop: function() {
        this.element.removeEventListener('scroll', scroll);
        Source.prototype.stop.apply(this, arguments);
    }
});

export default function scrolls(element) {
    return new Stream(new Scrolls(element));
}
<|endoftext|>


<commit_before>var fs = require('fs')
var path = require('path')
var app = require('app')

var settingspath = path.join(app.getPath('userData'), 'settings.json')
var enginespath = path.join(app.getPath('userData'), 'engines.json')

var settings = {}
var engines = []

exports.load = function() {
    settings = JSON.parse(fs.readFileSync(settingspath, { encoding: 'utf8' }))
    engines = JSON.parse(fs.readFileSync(enginespath, { encoding: 'utf8' }))
    return exports
}

exports.save = function() {
    fs.writeFileSync(settingspath, JSON.stringify(settings, null, '    '))
    fs.writeFileSync(enginespath, JSON.stringify(engines, null, '    '))
    return exports
}

exports.get = function(key) {
    return settings[key]
}

exports.set = function(key, value) {
    settings[key] = value
    return exports.save()
}

exports.default = function(key, value) {
    if (exports.get(key) == null) exports.set(key, value)
    return exports
}

exports.addEngine = function(name, path, args) {
    engines.push({
        name: name,
        path: path,
        args: args
    })
    exports.save()
}

exports.getEngines = function() {
    var list = engines.slice(0)
    list.sort(function(x, y) { return x.name >= y.name })
    return list
}

try {
    fs.accessSync(settingspath, fs.F_OK)
    fs.accessSync(enginespath, fs.F_OK)
} catch(err) {
    exports.save()
}

exports.load()

// Generate default settings
exports
.default('app.startup_check_updates', true)
.default('app.startup_check_updates_delay', 100)
.default('app.startup_loadgame_delay', 100)
.default('console.blocked_commands', [
    'boardsize', 'clear_board', 'play',
    'genmove', 'undo', 'fixed_handicap',
    'place_free_handicap', 'set_free_handicap',
    'loadsgf'
])
.default('console.max_history_count', 30)
.default('game.default_board_size', 19)
.default('game.default_komi', 6.5)
.default('game.goto_end_after_loading', false)
.default('game.show_ko_warning', true)
.default('game.show_suicide_warning', true)
.default('graph.collapse_min_depth', 1)
.default('graph.collapse_tokens_count', 100000)
.default('graph.delay', 300)
.default('graph.grid_size', 25)
.default('graph.node_active_color', '#f76047')
.default('graph.node_collapsed_color', '#333')
.default('graph.node_inactive_color', '#777')
.default('graph.node_color', '#eee')
.default('graph.node_comment_color', '#6bb1ff')
.default('graph.node_size', 4)
.default('gtp.attach_delay', 300)
.default('gtp.move_delay', 300)
.default('scoring.method', 'territory')
.default('sound.enable', true)
.default('view.comments_height', 50)
.default('view.comments_minheight', 20)
.default('view.console_width', 250)
.default('view.fuzzy_stone_placement', true)
.default('view.show_console', false)
.default('view.show_comments', false)
.default('view.show_coordinates', false)
.default('view.show_variations', true)
.default('view.show_graph', false)
.default('view.sidebar_width', 200)
.default('view.sidebar_minwidth', 100)
.default('window.height', 648)
.default('window.minheight', 590)
.default('window.minwidth', 550)
.default('window.width', 608)
<commit_msg>setting.getEngines returns reference<commit_after>var fs = require('fs')
var path = require('path')
var app = require('app')

var settingspath = path.join(app.getPath('userData'), 'settings.json')
var enginespath = path.join(app.getPath('userData'), 'engines.json')

var settings = {}
var engines = []

exports.load = function() {
    settings = JSON.parse(fs.readFileSync(settingspath, { encoding: 'utf8' }))
    engines = JSON.parse(fs.readFileSync(enginespath, { encoding: 'utf8' }))
    engines.sort(function(x, y) { return x.name >= y.name })
    return exports
}

exports.save = function() {
    fs.writeFileSync(settingspath, JSON.stringify(settings, null, '    '))
    fs.writeFileSync(enginespath, JSON.stringify(engines, null, '    '))
    return exports
}

exports.get = function(key) {
    return settings[key]
}

exports.set = function(key, value) {
    settings[key] = value
    return exports.save()
}

exports.default = function(key, value) {
    if (exports.get(key) == null) exports.set(key, value)
    return exports
}

exports.addEngine = function(name, path, args) {
    engines.push({
        name: name,
        path: path,
        args: args
    })
    exports.save()
}

exports.getEngines = function() {
    return engines
}

try {
    fs.accessSync(settingspath, fs.F_OK)
    fs.accessSync(enginespath, fs.F_OK)
} catch(err) {
    exports.save()
}

exports.load()

// Generate default settings
exports
.default('app.startup_check_updates', true)
.default('app.startup_check_updates_delay', 100)
.default('app.startup_loadgame_delay', 100)
.default('console.blocked_commands', [
    'boardsize', 'clear_board', 'play',
    'genmove', 'undo', 'fixed_handicap',
    'place_free_handicap', 'set_free_handicap',
    'loadsgf'
])
.default('console.max_history_count', 30)
.default('game.default_board_size', 19)
.default('game.default_komi', 6.5)
.default('game.goto_end_after_loading', false)
.default('game.show_ko_warning', true)
.default('game.show_suicide_warning', true)
.default('graph.collapse_min_depth', 1)
.default('graph.collapse_tokens_count', 100000)
.default('graph.delay', 300)
.default('graph.grid_size', 25)
.default('graph.node_active_color', '#f76047')
.default('graph.node_collapsed_color', '#333')
.default('graph.node_inactive_color', '#777')
.default('graph.node_color', '#eee')
.default('graph.node_comment_color', '#6bb1ff')
.default('graph.node_size', 4)
.default('gtp.attach_delay', 300)
.default('gtp.move_delay', 300)
.default('scoring.method', 'territory')
.default('sound.enable', true)
.default('view.comments_height', 50)
.default('view.comments_minheight', 20)
.default('view.console_width', 250)
.default('view.fuzzy_stone_placement', true)
.default('view.show_console', false)
.default('view.show_comments', false)
.default('view.show_coordinates', false)
.default('view.show_variations', true)
.default('view.show_graph', false)
.default('view.sidebar_width', 200)
.default('view.sidebar_minwidth', 100)
.default('window.height', 648)
.default('window.minheight', 590)
.default('window.minwidth', 550)
.default('window.width', 608)
<|endoftext|>


<commit_before>import Parchment from 'parchment';
import Quill from '../core/quill';
import logger from '../core/logger';
import Module from '../core/module';

let debug = logger('quill:toolbar');

class Toolbar extends Module {
  constructor(quill, options) {
    super(quill, options);
    this.container = this.options.container || this.options;
    if (typeof this.container === 'string') {
      this.container = document.querySelector(this.container);
    } else if (Array.isArray(this.container)) {
      let container = document.createElement('div');
      addControls(container, this.container);
      quill.container.parentNode.insertBefore(container, quill.container);
      this.container = container;
    }
    if (!(this.container instanceof HTMLElement)) {
      return debug.error('Container required for toolbar', this.options);
    }
    this.container.classList.add('ql-toolbar');
    this.container.classList.toggle('ios', /iPhone|iPad/i.test(navigator.userAgent));
    this.controls = [];
    this.handlers = {
      'clean': () => {
        let range = this.quill.getSelection();
        if (range != null) {
          let startLength = this.quill.getLength();
          this.quill.removeFormat(range);
          let endLength = this.quill.getLength();
          // account for embed removals
          this.quill.setSelection(range.index, range.length - (startLength-endLength));
        }
        return true;
      }
    };
    [].forEach.call(this.container.querySelectorAll('a, button, input[type=button], select'), (input) => {
      this.attach(input);
    });
    this.quill.on(Quill.events.SELECTION_CHANGE, this.update, this);
    this.quill.on(Quill.events.SCROLL_OPTIMIZE, () => {
      let [range, ] = this.quill.selection.getRange();  // quill.getSelection triggers update
      this.update(range);
    });
  }

  attach(input) {
    let format = [].find.call(input.classList, (className) => {
      return className.indexOf('ql-') === 0;
    });
    if (!format) return;
    format = format.slice('ql-'.length);
    let eventName = input.tagName === 'SELECT' ? 'change' : 'click';
    input.addEventListener(eventName, () => {
      this.quill.focus();
      let value;
      if (input.tagName === 'SELECT') {
        if (input.selectedIndex < 0) return;
        value = input.options[input.selectedIndex].value || false;
      } else {
        value = input.classList.contains('ql-active') ? false : input.dataset.value || true;
      }
      if (this.handlers[format]) {
        if (this.handlers[format](value)) return;
      }
      this.quill.format(format, value, Quill.sources.USER);
    });
    // TODO use weakmap
    this.controls.push([format, input]);
  }

  update(range) {
    if (range == null) return;
    let formats = this.quill.getFormat(range);
    this.controls.forEach(function(pair) {
      let [format, input] = pair;
      if (input.tagName === 'SELECT') {
        let option;
        if (formats[format] == null) {
          option = input.querySelector('option[selected]');
        } else if (!Array.isArray(formats[format])) {
          option = input.querySelector(`option[value="${formats[format]}"]`);
        }
        if (option == null) {
          input.value = '';   // TODO make configurable?
          input.selectedIndex = -1;
        } else {
          option.selected = true;
        }
      } if (input.dataset.value) {
        input.classList.toggle('ql-active', input.dataset.value == formats[format]);  // Intentional ==
      } else {
        input.classList.toggle('ql-active', formats[format] || false);
      }
    });
  }
}
Toolbar.DEFAULTS = {};

function addButton(container, format, value) {
  let input = document.createElement('button');
  input.classList.add('ql-' + format);
  if (value != null) {
    input.dataset.value = value;
  }
  container.appendChild(input);
}

function addControls(container, groups) {
  if (!Array.isArray(groups[0])) {
    groups = [groups];
  }
  groups.forEach(function(controls) {
    let group = document.createElement('span');
    group.classList.add('ql-formats');
    controls.forEach(function(control) {
      if (typeof control === 'string') {
        addButton(group, control);
      } else {
        let format = Object.keys(control)[0];
        let value = control[format];
        if (Array.isArray(value)) {
          addSelect(group, format, value);
        } else {
          addButton(group, format, value);
        }
      }
    });
    container.appendChild(group);
  });
}

function addSelect(container, format, values) {
  let input = document.createElement('select');
  input.classList.add('ql-' + format);
  values.forEach(function(value) {
    let option = document.createElement('option');
    if (value !== false) {
      option.setAttribute('value', value);
    } else {
      option.setAttribute('selected', 'selected');
    }
    input.appendChild(option);
  });
  container.appendChild(input);
}

export { Toolbar as default, addControls };
<commit_msg>add indent control<commit_after>import Parchment from 'parchment';
import Quill from '../core/quill';
import logger from '../core/logger';
import Module from '../core/module';

let debug = logger('quill:toolbar');

class Toolbar extends Module {
  constructor(quill, options) {
    super(quill, options);
    this.container = this.options.container || this.options;
    if (typeof this.container === 'string') {
      this.container = document.querySelector(this.container);
    } else if (Array.isArray(this.container)) {
      let container = document.createElement('div');
      addControls(container, this.container);
      quill.container.parentNode.insertBefore(container, quill.container);
      this.container = container;
    }
    if (!(this.container instanceof HTMLElement)) {
      return debug.error('Container required for toolbar', this.options);
    }
    this.container.classList.add('ql-toolbar');
    this.container.classList.toggle('ios', /iPhone|iPad/i.test(navigator.userAgent));
    this.controls = [];
    this.handlers = {
      'indent': (value) => {
        let range = this.quill.getSelection();
        let formats = this.quill.getFormat(range);
        let indent = parseInt(formats.indent || 0);
        if (value === '+1') {
          this.quill.format('indent', indent + 1);
        } else if (value === '-1') {
          this.quill.format('indent', indent - 1);
        }
      },
      'clean': () => {
        let range = this.quill.getSelection();
        if (range != null) {
          let startLength = this.quill.getLength();
          this.quill.removeFormat(range);
          let endLength = this.quill.getLength();
          // account for embed removals
          this.quill.setSelection(range.index, range.length - (startLength-endLength));
        }
        return true;
      }
    };
    [].forEach.call(this.container.querySelectorAll('a, button, input[type=button], select'), (input) => {
      this.attach(input);
    });
    this.quill.on(Quill.events.SELECTION_CHANGE, this.update, this);
    this.quill.on(Quill.events.SCROLL_OPTIMIZE, () => {
      let [range, ] = this.quill.selection.getRange();  // quill.getSelection triggers update
      this.update(range);
    });
  }

  attach(input) {
    let format = [].find.call(input.classList, (className) => {
      return className.indexOf('ql-') === 0;
    });
    if (!format) return;
    format = format.slice('ql-'.length);
    let eventName = input.tagName === 'SELECT' ? 'change' : 'click';
    input.addEventListener(eventName, () => {
      this.quill.focus();
      let value;
      if (input.tagName === 'SELECT') {
        if (input.selectedIndex < 0) return;
        value = input.options[input.selectedIndex].value || false;
      } else {
        value = input.classList.contains('ql-active') ? false : input.dataset.value || true;
      }
      if (this.handlers[format]) {
        if (this.handlers[format](value)) return;
      }
      this.quill.format(format, value, Quill.sources.USER);
    });
    // TODO use weakmap
    this.controls.push([format, input]);
  }

  update(range) {
    if (range == null) return;
    let formats = this.quill.getFormat(range);
    this.controls.forEach(function(pair) {
      let [format, input] = pair;
      if (input.tagName === 'SELECT') {
        let option;
        if (formats[format] == null) {
          option = input.querySelector('option[selected]');
        } else if (!Array.isArray(formats[format])) {
          option = input.querySelector(`option[value="${formats[format]}"]`);
        }
        if (option == null) {
          input.value = '';   // TODO make configurable?
          input.selectedIndex = -1;
        } else {
          option.selected = true;
        }
      } if (input.dataset.value) {
        input.classList.toggle('ql-active', input.dataset.value == formats[format]);  // Intentional ==
      } else {
        input.classList.toggle('ql-active', formats[format] || false);
      }
    });
  }
}
Toolbar.DEFAULTS = {};

function addButton(container, format, value) {
  let input = document.createElement('button');
  input.classList.add('ql-' + format);
  if (value != null) {
    input.dataset.value = value;
  }
  container.appendChild(input);
}

function addControls(container, groups) {
  if (!Array.isArray(groups[0])) {
    groups = [groups];
  }
  groups.forEach(function(controls) {
    let group = document.createElement('span');
    group.classList.add('ql-formats');
    controls.forEach(function(control) {
      if (typeof control === 'string') {
        addButton(group, control);
      } else {
        let format = Object.keys(control)[0];
        let value = control[format];
        if (Array.isArray(value)) {
          addSelect(group, format, value);
        } else {
          addButton(group, format, value);
        }
      }
    });
    container.appendChild(group);
  });
}

function addSelect(container, format, values) {
  let input = document.createElement('select');
  input.classList.add('ql-' + format);
  values.forEach(function(value) {
    let option = document.createElement('option');
    if (value !== false) {
      option.setAttribute('value', value);
    } else {
      option.setAttribute('selected', 'selected');
    }
    input.appendChild(option);
  });
  container.appendChild(input);
}

export { Toolbar as default, addControls };
<|endoftext|>


<commit_before>var swarm = require('./')
var sw = swarm()

console.log('i am peer-' + process.pid)

sw.on('peer', function (stream) {
  console.log('new connection!')
  var i = 0
  setInterval(function () {
    stream.write('i am peer-' + process.pid + ' #' + (++i) + '\n')
  }, 500)
  stream.pipe(process.stdout)
})<commit_msg>fix wording<commit_after>var swarm = require('./')
var sw = swarm()

console.log('i am peer-' + process.pid)

sw.on('peer', function (stream) {
  console.log('new connection!')
  var i = 0
  setInterval(function () {
    stream.write('message from remote peer-' + process.pid + ' #' + (++i) + '\n')
  }, 500)
  stream.pipe(process.stdout)
})<|endoftext|>


<commit_before>'use strict';

var Store = require('./');
var store = new Store('app');

store
  .set('a', 'b')
  .set('c', 'd')
  .set('e', 'f');

store.save('actual/app.json');

console.log(store.get());
store.delete();<commit_msg>update example<commit_after>var Store = require('./');
var store = new Store('app', {cwd: 'actual'});

store
  .set('a', 'b')
  .set('c', 'd')
  .set('e', 'f');

store.save();

console.log(store.get());
store.omit('a');

console.log(store.get());
store.delete();

console.log(store.get());<|endoftext|>


<commit_before>const {KVStore} = require('../models/kv-store');
const {Summoner} = require('../models/summoner');
const async = require('async');

module.exports = class Repo {
  saveSummoners(summonersData, callback) {
    let self = this;
    Summoner.insertMany(summonersData, {ordered: false}, (err, docs) => {
      if(err) {
        console.error('Error Saving Summoners:', err);
      }
      callback(null);
    });
  }
  saveSummoner(summonerData, callback) {
    Summoner.create(summonerData, (err, doc) => {
      if(err && err.code !== 11000) {
        console.error(err);
      }
      callback(null);
    });
  }
}<commit_msg>saving summoners in batches<commit_after>const {KVStore} = require('../models/kv-store');
const {Summoner} = require('../models/summoner');
const async = require('async');

module.exports = class Repo {
  saveSummoners(summonersData, callback) {
    let self = this;
    Summoner.insertMany(summonersData, {ordered: false}, (err, docs) => {
      if(err) {
        err = err
        .filter(error => error.code !== 11000)
        .map(error => error.toJSON());
        console.error('Error Saving Summoners:', err);
      }
      callback(null);
    });
  }
  saveSummoner(summonerData, callback) {
    Summoner.create(summonerData, (err, doc) => {
      if(err && err.code !== 11000) {
        console.error(err);
      }
      callback(null);
    });
  }
}<|endoftext|>