<commit_before>// epicyclic gear source:
//

// TODO: endless zoom into recursive epicyclic gears

var d3 = require('d3');

var x = Math.sin(2 * Math.PI / 3);
var y = Math.cos(2 * Math.PI / 3);

var frame = null;

var offset = 0;
var speed = 1;
var start = Date.now();

var gears  = function (options) {
  var width = options.width;
  var height = options.height;
  var radius = Math.min(width, height) / 8;

  // set height and width of container
  var svg = d3.select(options.selector).append("svg")
      .attr("width", width)
      .attr("height", height);

  // clear existing gears
  svg.selectAll("g").remove();

  // add new gears
  frame = svg
    .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
    .append("g")
    .datum({radius: Infinity});

  frame.append("g")
      .attr("class", "annulus")
      .datum({teeth: 40, radius: -radius * 5, annulus: true})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "sun")
      .datum({teeth: 8, radius: radius})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "planet")
      .attr("transform", "translate(0,-" + radius * 3 + ")")
      .datum({teeth: 16, radius: -radius * 2})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "planet")
      .attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
      .datum({teeth: 16, radius: -radius * 2})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "planet")
      .attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
      .datum({teeth: 16, radius: -radius * 2})
    .append("path")
      .attr("d", gear);

  d3.selectAll("input[name=reference]")
      .data([radius * 5, Infinity, -radius])
      .on("change", function(radius1) {
        var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
        frame.datum({radius: radius1});
        svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
      });
}

var gear = function gear(d) {
  var n = d.teeth,
      r2 = Math.abs(d.radius),
      r0 = r2 - 8,
      r1 = r2 + 8,
      r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
      da = Math.PI / n,
      a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
      i = -1,
      path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
  while (++i < n) path.push(
      "A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
      "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
      "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
      "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
      "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
      "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
  path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
  return path.join("");
}

d3.timer(function() {
  if (frame) {
    var angle = (Date.now() - start) * speed;
    var transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
    frame.selectAll("path").attr("transform", transform);
    frame.attr("transform", transform); // frame of reference
  }
});

module.exports = gears;<commit_msg>add much needed source for epicyclic gears<commit_after>// epicyclic gear source:
// http://bl.ocks.org/mbostock/1353700

// TODO: endless zoom into recursive epicyclic gears

var d3 = require('d3');

var x = Math.sin(2 * Math.PI / 3);
var y = Math.cos(2 * Math.PI / 3);

var frame = null;

var offset = 0;
var speed = 1;
var start = Date.now();

var gears  = function (options) {
  var width = options.width;
  var height = options.height;
  var radius = Math.min(width, height) / 8;

  // set height and width of container
  var svg = d3.select(options.selector).append("svg")
      .attr("width", width)
      .attr("height", height);

  // clear existing gears
  svg.selectAll("g").remove();

  // add new gears
  frame = svg
    .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
    .append("g")
    .datum({radius: Infinity});

  frame.append("g")
      .attr("class", "annulus")
      .datum({teeth: 40, radius: -radius * 5, annulus: true})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "sun")
      .datum({teeth: 8, radius: radius})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "planet")
      .attr("transform", "translate(0,-" + radius * 3 + ")")
      .datum({teeth: 16, radius: -radius * 2})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "planet")
      .attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
      .datum({teeth: 16, radius: -radius * 2})
    .append("path")
      .attr("d", gear);

  frame.append("g")
      .attr("class", "planet")
      .attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
      .datum({teeth: 16, radius: -radius * 2})
    .append("path")
      .attr("d", gear);

  d3.selectAll("input[name=reference]")
      .data([radius * 5, Infinity, -radius])
      .on("change", function(radius1) {
        var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
        frame.datum({radius: radius1});
        svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
      });
}

var gear = function gear(d) {
  var n = d.teeth,
      r2 = Math.abs(d.radius),
      r0 = r2 - 8,
      r1 = r2 + 8,
      r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
      da = Math.PI / n,
      a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
      i = -1,
      path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
  while (++i < n) path.push(
      "A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
      "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
      "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
      "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
      "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
      "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
  path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
  return path.join("");
}

d3.timer(function() {
  if (frame) {
    var angle = (Date.now() - start) * speed;
    var transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
    frame.selectAll("path").attr("transform", transform);
    frame.attr("transform", transform); // frame of reference
  }
});

module.exports = gears;<|endoftext|>


<commit_before>import $ from 'jquery';
import {toPromise} from "../util/index";

export const ajax = $['ajax'];

export const when = $['when'];

export function doRequest(method, opts, mConfig, url, data, options) {
    if (method === 'GET') {
        options = data;
        data = undefined;
    }

    options = options || {};
    let extras = {
        ...opts
    };

    if (!!data) {
        let data2Call = data;
        if (data instanceof FormData) {
            extras.contentType = false;
            extras.processData = false;
        } else if (data instanceof String) {
            extras.processData = false;
        } else {
            data2Call = JSON.stringify(data);
        }

        extras.data = data2Call;
    }

    return toPromise(ajax({
        url: url,
        type: method,
        contentType: 'application/json',
        ...extras,
        ...options,
    }));
}
<commit_msg>fixed string problem<commit_after>import $ from 'jquery';
import {toPromise} from "../util/index";

export const ajax = $['ajax'];

export const when = $['when'];

export function doRequest(method, opts, mConfig, url, data, options) {
    if (method === 'GET') {
        options = data;
        data = undefined;
    }

    options = options || {};
    let extras = {
        ...opts
    };

    if (!!data) {
        let data2Call = data;
        if (data instanceof FormData) {
            extras.contentType = false;
            extras.processData = false;
        } else if (typeof data === 'string') {
            extras.processData = false;
        } else {
            data2Call = JSON.stringify(data);
        }

        extras.data = data2Call;
    }

    return toPromise(ajax({
        url: url,
        type: method,
        contentType: 'application/json',
        ...extras,
        ...options,
    }));
}
<|endoftext|>


<commit_before>
/*!
 * Engine - stats
 * Copyright (c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var os = require('os')
  , fs = require('fs')
  , Log = require('log')
  , repl = require('./repl')
  , utils = require('../utils');

/**
 * Enable stat tracking.
 *
 * @return {Function}
 * @api public
 */

module.exports = function(){
  return function(master){
    master.stats = {
        start: new Date
      , totalmem: os.totalmem()
      , freemem: os.freemem()
      , totalWorkersSpawned: 0
    };

    // total workers spawned
    master.on('worker', function(worker){
      ++master.stats.totalWorkersSpawned;

      // worker-specific stats
      worker.stats = {
        start: new Date
      };
    });
  }
};

/**
 * REPL statistics command.
 */

repl.stats = function(master, sock){
  // master stats
  sock.head('Master');
  sock.row('os', os.type() + ' ' + os.release());
  sock.row('started', master.stats.start.toUTCString());
  sock.row('uptime', utils.formatDateRange(new Date, master.stats.start));
  sock.row('workers', master.children.length);
  sock.row('spawned', master.stats.totalWorkersSpawned);

  // resources
  sock.head('Resources');
  sock.row('load average', os.loadavg().map(function(n){ return n.toFixed(2); }).join(' '));
  sock.row('cores utilized', master.children.length + ' / ' + os.cpus().length);
  var free = utils.formatBytes(master.stats.freemem);
  var total = utils.formatBytes(master.stats.totalmem);
  sock.row('memory at boot (free / total)', free + ' / ' + total);
  var free = utils.formatBytes(os.freemem());
  var total = utils.formatBytes(os.totalmem());
  sock.row('memory now (free / total)', free + ' / ' + total);

  // worker stats
  sock.head('Workers');
  master.children.forEach(function(worker){
    sock.row(
      'uptime #' + worker.id
      , utils.formatDateRange(new Date, worker.stats.start));
  });
  sock.write('\n');
};

repl.stats.description = 'Display server statistics';
<commit_msg>added deaths to stats<commit_after>
/*!
 * Engine - stats
 * Copyright (c) 2010 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var os = require('os')
  , fs = require('fs')
  , Log = require('log')
  , repl = require('./repl')
  , utils = require('../utils');

/**
 * Enable stat tracking.
 *
 * @return {Function}
 * @api public
 */

module.exports = function(){
  return function(master){
    master.stats = {
        start: new Date
      , totalmem: os.totalmem()
      , freemem: os.freemem()
      , totalWorkersSpawned: 0
    };

    // total workers spawned
    master.on('worker', function(worker){
      ++master.stats.totalWorkersSpawned;

      // worker-specific stats
      worker.stats = {
        start: new Date
      };
    });
  }
};

/**
 * REPL statistics command.
 */

repl.stats = function(master, sock){
  var active = master.children.length
    , total = master.stats.totalWorkersSpawned;

  // master stats
  sock.head('Master');
  sock.row('os', os.type() + ' ' + os.release());
  sock.row('started', master.stats.start.toUTCString());
  sock.row('uptime', utils.formatDateRange(new Date, master.stats.start));
  sock.row('workers', active);
  sock.row('deaths', total - active);

  // resources
  sock.head('Resources');
  sock.row('load average', os.loadavg().map(function(n){ return n.toFixed(2); }).join(' '));
  sock.row('cores utilized', active + ' / ' + os.cpus().length);
  var free = utils.formatBytes(master.stats.freemem);
  var total = utils.formatBytes(master.stats.totalmem);
  sock.row('memory at boot (free / total)', free + ' / ' + total);
  var free = utils.formatBytes(os.freemem());
  var total = utils.formatBytes(os.totalmem());
  sock.row('memory now (free / total)', free + ' / ' + total);

  // worker stats
  sock.head('Workers');
  master.children.forEach(function(worker){
    sock.row(
      'uptime #' + worker.id
      , utils.formatDateRange(new Date, worker.stats.start));
  });
  sock.write('\n');
};

repl.stats.description = 'Display server statistics';
<|endoftext|>


<commit_before>import outcome from '../outcome';

/*
 * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
 *
 *
 */

export default function(result) {
  if (!headers.hasOwnProperty('cache-control')) {
    outcome.error('default', 'Missing Cache-Control header!');
  }
}
<commit_msg>Fix checkCache<commit_after>import outcome from '../outcome';

/*
 * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
 *
 *
 */

export default function(result) {
  if (!result.response.headers.hasOwnProperty('cache-control')) {
    outcome.error('resources', result.url, 'Missing Cache-Control header!');
  }
  return result;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Maximilian Antoni <max@javascript.studio>
 */
'use strict';

const chalk = require('chalk');
const source_map = require('source-map');

const SPACES = new Array(80).join(' ');

function highlight_source(src, loc) {
  const c1 = loc.start.column;
  let c2 = loc.start.line === loc.end.line ? loc.end.column : src.length;
  if (c1 >= c2) {
    c2 = c1 + 1;
  }
  const pre = src.substring(0, c1);
  const hi = src.substring(c1, c2);
  const post = src.substring(c2);
  return `${pre}${chalk.yellow.underline(hi)}${post}`;
}

function pad_line_number(num) {
  return num < 10 ? `   ${num} ` : (num < 100 ? `  ${num} ` : ` ${num} `);
}

function line_number(pos) {
  return chalk.bgBlack.gray(pad_line_number(pos.line || 0));
}

function section(errs, title, color, source_map_consumer) {
  if (!errs.length) {
    return;
  }
  const heading = `${title}${SPACES.substring(title.length)}`;
  console.log(`\n${chalk[color](chalk.bold.underline(heading))}\n`);

  const errs_by_file = [];
  const errs_index = {};
  for (let i = 0, l = errs.length; i < l; i++) {
    const e = errs[i];
    if (source_map_consumer) {
      const mapped = source_map_consumer.originalPositionFor(e.loc.start);
      e.file = mapped.source || '[unknown]';
    } else {
      e.file = '[stdin]';
    }
    if (errs_index.hasOwnProperty(e.file)) {
      errs_by_file[errs_index[e.file]].errs.push(e);
    } else {
      errs_index[e.file] = errs_by_file.length;
      errs_by_file.push({
        file: e.file,
        errs: [e]
      });
    }
  }
  errs_by_file.forEach(err => {
    console.log(`\n📄  ${err.file}\n\n`);
    err.errs.forEach(err => {
      let source = err.source;
      let loc = err.loc;
      if (source_map_consumer) {
        const start = source_map_consumer.originalPositionFor(loc.start);
        if (start.source) {
          const src = source_map_consumer.sourceContentFor(start.source, true);
          if (src) {
            source = src.split('\n')[start.line - 1];
            const end = loc.end.line
              ? source_map_consumer.originalPositionFor(loc.end)
              : { line: start.line, column: start.column + 1 };
            if (start.column === 0 && end.column === 0) {
              start.column = loc.start.column;
              end.column = loc.end.column;
            }
            loc = { start, end };
          }
        }
      }
      const line = line_number(loc.start);
      const code = highlight_source(source, loc);
      console.log(chalk[color](`   ${err.name}: ${err.message}`));
      if (code) {
        console.log(`   ${line} ${code}\n`);
      }
      const occurrence = err.occurrences[0];
      occurrence.stack.forEach(s => {
        let m = s.match(/:([0-9]+):([0-9]+)$/);
        let line = null;
        let column = null;
        let name = null;
        let file_loc = null;
        if (m) {
          line = m[1];
          column = m[2];
        } else {
          m = s.match(/at ([^ ]+) \(.+:([0-9]+):([0-9]+)\)$/);
          if (!m) {
            console.log(`      ${s}`);
            return;
          }
          name = m[1];
          line = m[2];
          column = m[3];
        }
        if (source_map_consumer) {
          const mapped = source_map_consumer.originalPositionFor({
            line: Number(line),
            column: Number(column)
          });
          if (mapped.source
              && mapped.source.indexOf('node_modules/browser-pack/') === -1) {
            file_loc = `${mapped.source}:${mapped.line}:${column}`;
          }
        } else {
          file_loc = `[stdin]:${line}:${column}`;
        }
        if (file_loc && name) {
          console.log(`      at ${name} (${file_loc})`);
        } else if (file_loc) {
          console.log(`      at ${file_loc}`);
        } else if (name) {
          console.log(`      at ${name}`);
        }
      });
      console.log('');
      const values = occurrence.values;
      if (values) {
        const max_length = Object.keys(values)
          .reduce((max, key) => Math.max(max, key.length), 0);
        const spaces = new Array(max_length + 1).join(' ');
        Object.keys(values).forEach((key) => {
          const blank = spaces.substring(key.length);
          console.log(`   ${chalk.gray(`${key}:`)} ${blank} ${values[key]}`);
        });
        console.log('');
      }
    });
  });
  console.log('');
}

function stats(report) {
  const nodes = report.evaluated_nodes;
  const percent = Math.round(nodes * 100 / report.total_nodes);
  const seconds = (report.duration / 1000).toFixed(1);
  console.log('');
  console.log(`${chalk.gray('Build Duration:')}  ${seconds}s`);
  if (nodes) {
    console.log(`${chalk.gray('Nodes Analyzed:')}  ${nodes} = ${percent}%`);
  }
  if (report.api_functions) {
    console.log(`${chalk.gray('API Functions:')}   ${report.api_functions}`);
  }
  console.log('');
}

module.exports = function (report, map) {
  stats(report);
  const consumer = map ? new source_map.SourceMapConsumer(map) : null;
  section(report.errors.parser, 'Parser Errors', 'red', consumer);
  section(report.errors.runtime, 'Runtime Errors', 'red', consumer);
  if (report.exceptions) {
    section(report.exceptions.thrown, 'Thrown Exceptions', 'magenta', consumer);
  }
};
<commit_msg>Improve error report layout and coloring<commit_after>/*
 * Copyright (c) Maximilian Antoni <max@javascript.studio>
 */
'use strict';

const chalk = require('chalk');
const source_map = require('source-map');

const SPACES = new Array(80).join(' ');
const at = chalk.gray('at');

function highlight_source(src, loc) {
  const c1 = loc.start.column;
  let c2 = loc.start.line === loc.end.line ? loc.end.column : src.length;
  if (c1 >= c2) {
    c2 = c1 + 1;
  }
  const pre = src.substring(0, c1);
  const hi = src.substring(c1, c2);
  const post = src.substring(c2);
  return `${pre}${chalk.yellow.underline(hi)}${post}`;
}

function pad_line_number(num) {
  return num < 10 ? `   ${num} ` : (num < 100 ? `  ${num} ` : ` ${num} `);
}

function line_number(pos) {
  return chalk.bgBlack.gray(pad_line_number(pos.line || 0));
}

function section(errs, title, color, source_map_consumer) {
  if (!errs.length) {
    return;
  }
  const heading = `${title}${SPACES.substring(title.length)}`;
  console.log(`\n${chalk[color](chalk.bold.underline(heading))}\n`);

  const errs_by_file = [];
  const errs_index = {};
  for (let i = 0, l = errs.length; i < l; i++) {
    const e = errs[i];
    if (source_map_consumer) {
      const mapped = source_map_consumer.originalPositionFor(e.loc.start);
      e.file = mapped.source || '[unknown]';
    } else {
      e.file = '[stdin]';
    }
    if (errs_index.hasOwnProperty(e.file)) {
      errs_by_file[errs_index[e.file]].errs.push(e);
    } else {
      errs_index[e.file] = errs_by_file.length;
      errs_by_file.push({
        file: e.file,
        errs: [e]
      });
    }
  }
  errs_by_file.forEach(err => {
    console.log(`\n📄  ${err.file}\n\n`);
    err.errs.forEach(err => {
      let source = err.source;
      let loc = err.loc;
      if (source_map_consumer) {
        const start = source_map_consumer.originalPositionFor(loc.start);
        if (start.source) {
          const src = source_map_consumer.sourceContentFor(start.source, true);
          if (src) {
            source = src.split('\n')[start.line - 1];
            const end = loc.end.line
              ? source_map_consumer.originalPositionFor(loc.end)
              : { line: start.line, column: start.column + 1 };
            if (start.column === 0 && end.column === 0) {
              start.column = loc.start.column;
              end.column = loc.end.column;
            }
            loc = { start, end };
          }
        }
      }
      const line = line_number(loc.start);
      const code = highlight_source(source, loc).trim();
      console.log(chalk[color](`   ${err.name}: ${err.message}`));
      if (code) {
        console.log(`   ${line} ${code}\n`);
      }
      const occurrence = err.occurrences[0];
      occurrence.stack.forEach(s => {
        let m = s.match(/:([0-9]+):([0-9]+)$/);
        let line = null;
        let column = null;
        let name = null;
        let file_loc = null;
        if (m) {
          line = m[1];
          column = m[2];
        } else {
          m = s.match(/at ([^ ]+) \(.+:([0-9]+):([0-9]+)\)$/);
          if (!m) {
            const p = s.indexOf('at ');
            if (p === 0) {
              s = `${at} ${s.substring(p + 3)}`;
            }
            console.log(`         ${s}`);
            return;
          }
          name = m[1];
          line = m[2];
          column = m[3];
        }
        if (source_map_consumer) {
          const mapped = source_map_consumer.originalPositionFor({
            line: Number(line),
            column: Number(column)
          });
          if (mapped.source
              && mapped.source.indexOf('node_modules/browser-pack/') === -1) {
            file_loc = `${mapped.source}:${mapped.line}:${column}`;
          }
        } else {
          file_loc = `[stdin]:${line}:${column}`;
        }
        if (file_loc && name) {
          console.log(`         ${at} ${name} ${chalk.gray(`(${file_loc})`)}`);
        } else if (file_loc) {
          console.log(`         ${at} ${chalk.gray(file_loc)}`);
        } else if (name) {
          console.log(`         ${at} ${name}`);
        }
      });
      console.log('');
      const values = occurrence.values;
      if (values) {
        const max_length = Object.keys(values)
          .reduce((max, key) => Math.max(max, key.length), 0);
        const spaces = new Array(max_length + 1).join(' ');
        Object.keys(values).forEach((key) => {
          const blank = spaces.substring(key.length);
          const value = chalk.cyan(values[key]);
          console.log(`         ${chalk.gray(`${key}:`)} ${blank} ${value}`);
        });
        console.log('');
      }
      console.log('\n');
    });
  });
  console.log('');
}

function stats(report) {
  const nodes = report.evaluated_nodes;
  const percent = Math.round(nodes * 100 / report.total_nodes);
  const seconds = (report.duration / 1000).toFixed(1);
  console.log('');
  console.log(`${chalk.gray('Build Duration:')}  ${seconds}s`);
  if (nodes) {
    console.log(`${chalk.gray('Nodes Analyzed:')}  ${nodes} = ${percent}%`);
  }
  if (report.api_functions) {
    console.log(`${chalk.gray('API Functions:')}   ${report.api_functions}`);
  }
  console.log('');
}

module.exports = function (report, map) {
  stats(report);
  const consumer = map ? new source_map.SourceMapConsumer(map) : null;
  section(report.errors.parser, 'Parser Errors', 'red', consumer);
  section(report.errors.runtime, 'Runtime Errors', 'red', consumer);
  if (report.exceptions) {
    section(report.exceptions.thrown, 'Thrown Exceptions', 'magenta', consumer);
  }
};
<|endoftext|>


<commit_before>import EventEmitter from '../EventEmitter'
import shallowEquals from '../shallow-equals'
import PQueue from '../p-queue'
import { loadGetInitialProps, getURL } from '../utils'
import { _notifyBuildIdMismatch } from './'
import { formatPath, parsePath } from '../url'

export default class Router {
  constructor (pathname, query, as, { pageLoader, Component, ErrorComponent, err } = {}) {
    // represents the current component key
    this.route = toRoute(pathname)

    // set up the component cache (by route keys)
    this.components = {}
    // We should not keep the cache, if there's an error
    // Otherwise, this cause issues when when going back and
    // come again to the errored page.
    if (Component !== ErrorComponent) {
      this.components[this.route] = { Component, err }
    }

    // Handling Router Events
    this.events = new EventEmitter()

    this.pageLoader = pageLoader
    this.prefetchQueue = new PQueue({ concurrency: 2 })
    this.ErrorComponent = ErrorComponent
    this.pathname = pathname
    this.query = query
    this.asPath = as
    this.subscriptions = []
    this.componentLoadCancel = null

    if (typeof window !== 'undefined') {
      // in order for `e.state` to work on the `onpopstate` event
      // we have to register the initial route upon initialization
      this.changeState('replaceState', formatPath(this), getURL())

      window.addEventListener('popstate', (e) => {
        if (!e.state) {
          // We get state as undefined for two reasons.
          //  1. With older safari (< 8) and older chrome (< 34)
          //  2. When the URL changed with #
          //
          // In the both cases, we don't need to proceed and change the route.
          // (as it's already changed)
          // But we can simply replace the state with the new changes.
          // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
          // So, doing the following for (1) does no harm.
          this.changeState('replaceState', formatPath(this), getURL())
          return
        }

        const { url, as, options } = e.state
        this.replace(url, as, options)
      })
    }
  }

  update (route, Component) {
    const data = this.components[route]
    if (!data) {
      throw new Error(`Cannot update unavailable route: ${route}`)
    }

    const newData = { ...data, Component }
    this.components[route] = newData

    if (route === this.route) {
      this.notify(newData)
    }
  }

  async reload (route) {
    delete this.components[route]
    this.pageLoader.clearCache(route)

    if (route !== this.route) return

    const { pathname, query } = this
    const url = window.location.href

    this.events.emit('routeChangeStart', url)
    const routeInfo = await this.getRouteInfo(route, pathname, query, url)
    const { error } = routeInfo

    if (error && error.cancelled) {
      return
    }

    this.notify(routeInfo)

    if (error) {
      this.events.emit('routeChangeError', error, url)
      throw error
    }

    this.events.emit('routeChangeComplete', url)
  }

  back () {
    window.history.back()
  }

  push (url, as = url, options = {}) {
    return this.change('pushState', url, as, options)
  }

  replace (url, as = url, options = {}) {
    return this.change('replaceState', url, as, options)
  }

  async change (method, _url, _as, options) {
    // If url and as provided as an object representation,
    // we'll format them into the string version here.
    const url = typeof _url === 'object' ? formatPath(_url) : _url
    let as = typeof _as === 'object' ? formatPath(_as) : _as

    this.abortComponentLoad(as)
    const { pathname, query } = parsePath(url, true)

    // If the url change is only related to a hash change
    // We should not proceed. We should only change the state.
    if (this.onlyAHashChange(as)) {
      this.changeState(method, url, as)
      return
    }

    // If asked to change the current URL we should reload the current page
    // (not location.reload() but reload getInitalProps and other Next.js stuffs)
    // We also need to set the method = replaceState always
    // as this should not go into the history (That's how browsers work)
    if (!this.urlIsNew(pathname, query)) {
      method = 'replaceState'
    }

    const route = toRoute(pathname)
    const { shallow = false } = options
    let routeInfo = null

    this.events.emit('routeChangeStart', as)

    // If shallow === false and other conditions met, we reuse the
    // existing routeInfo for this route.
    // Because of this, getInitialProps would not run.
    if (shallow && this.isShallowRoutingPossible(route)) {
      routeInfo = this.components[route]
    } else {
      routeInfo = await this.getRouteInfo(route, pathname, query, as)
    }

    const { error } = routeInfo

    if (error && error.cancelled) {
      return false
    }

    this.events.emit('beforeHistoryChange', as)
    this.changeState(method, url, as, options)
    const hash = window.location.hash.substring(1)

    this.route = route
    this.pathname = pathname
    this.query = query
    this.asPath = as
    this.notify({ ...routeInfo, hash })

    if (error) {
      this.events.emit('routeChangeError', error, as)
      throw error
    }

    this.events.emit('routeChangeComplete', as)
    return true
  }

  changeState (method, url, as, options = {}) {
    if (method !== 'pushState' || getURL() !== as) {
      console.log('changeState', method, as)
      window.history[method]({ url, as, options }, null, as)
    }
  }

  async getRouteInfo (route, pathname, query, as) {
    let routeInfo = null

    try {
      routeInfo = this.components[route]
      if (!routeInfo) {
        routeInfo = { Component: await this.fetchComponent(route, as) }
      }

      const { Component } = routeInfo
      const ctx = { pathname, query, asPath: as }
      routeInfo.props = await this.getInitialProps(Component, ctx)

      this.components[route] = routeInfo
    } catch (err) {
      if (err.cancelled) {
        return { error: err }
      }

      if (err.buildIdMismatched) {
        // Now we need to reload the page or do the action asked by the user
        _notifyBuildIdMismatch(as)
        // We also need to cancel this current route change.
        // We do it like this.
        err.cancelled = true
        return { error: err }
      }

      if (err.statusCode === 404) {
        // Indicate main error display logic to
        // ignore rendering this error as a runtime error.
        err.ignore = true
      }

      const Component = this.ErrorComponent
      routeInfo = { Component, err }
      const ctx = { err, pathname, query }
      routeInfo.props = await this.getInitialProps(Component, ctx)

      routeInfo.error = err
    }

    return routeInfo
  }

  onlyAHashChange (as) {
    if (!this.asPath) return false
    const [ oldUrlNoHash ] = this.asPath.split('#')
    const [ newUrlNoHash ] = as.split('#')

    // If the urls are change, there's more than a hash change
    return oldUrlNoHash === newUrlNoHash
  }

  urlIsNew (pathname, query) {
    return this.pathname !== pathname || !shallowEquals(query, this.query)
  }

  isShallowRoutingPossible (route) {
    return (
      // If there's cached routeInfo for the route.
      Boolean(this.components[route]) &&
      // If the route is already rendered on the screen.
      this.route === route
    )
  }

  async prefetch (url) {
    // We don't add support for prefetch in the development mode.
    // If we do that, our on-demand-entries optimization won't performs better
    if (process.env.NODE_ENV === 'development') return

    const { pathname } = parsePath(url)
    const route = toRoute(pathname)
    return this.prefetchQueue.add(() => this.fetchRoute(route))
  }

  async fetchComponent (route, as) {
    let cancelled = false
    const cancel = this.componentLoadCancel = function () {
      cancelled = true
    }

    try {
      const Component = await this.fetchRoute(route)

      if (cancelled) {
        const error = new Error(`Abort fetching component for route: "${route}"`)
        error.cancelled = true
        throw error
      }

      if (cancel === this.componentLoadCancel) {
        this.componentLoadCancel = null
      }

      return Component
    } catch (err) {
      // There's an error in loading the route.
      // Usually this happens when there's a failure in the webpack build
      // So in that case, we need to load the page with full SSR
      // That'll clean the invalid exising client side information.
      // (Like cached routes)
      window.location.href = as
      throw err
    }
  }

  async getInitialProps (Component, ctx) {
    let cancelled = false
    const cancel = () => { cancelled = true }
    this.componentLoadCancel = cancel

    const props = await loadGetInitialProps(Component, ctx)

    if (cancel === this.componentLoadCancel) {
      this.componentLoadCancel = null
    }

    if (cancelled) {
      const err = new Error('Loading initial props cancelled')
      err.cancelled = true
      throw err
    }

    return props
  }

  async fetchRoute (route) {
    return this.pageLoader.loadPage(route)
  }

  abortComponentLoad (as) {
    if (this.componentLoadCancel) {
      this.events.emit('routeChangeError', new Error('Route Cancelled'), as)
      this.componentLoadCancel()
      this.componentLoadCancel = null
    }
  }

  notify (data) {
    this.subscriptions.forEach((fn) => fn(data))
  }

  subscribe (fn) {
    this.subscriptions.push(fn)
    return () => {
      let index = this.subscriptions.indexOf(fn)
      if (index >= 0) {
        this.subscriptions.splice(index, 1)
      }
    }
  }
}

function toRoute (path) {
  return path.replace(/\/$/, '') || '/'
}
<commit_msg>Add raven breadcrumb for Router.change<commit_after>/* global Raven */
import EventEmitter from '../EventEmitter'
import shallowEquals from '../shallow-equals'
import PQueue from '../p-queue'
import { loadGetInitialProps, getURL } from '../utils'
import { _notifyBuildIdMismatch } from './'
import { formatPath, parsePath } from '../url'

export default class Router {
  constructor (pathname, query, as, { pageLoader, Component, ErrorComponent, err } = {}) {
    // represents the current component key
    this.route = toRoute(pathname)

    // set up the component cache (by route keys)
    this.components = {}
    // We should not keep the cache, if there's an error
    // Otherwise, this cause issues when when going back and
    // come again to the errored page.
    if (Component !== ErrorComponent) {
      this.components[this.route] = { Component, err }
    }

    // Handling Router Events
    this.events = new EventEmitter()

    this.pageLoader = pageLoader
    this.prefetchQueue = new PQueue({ concurrency: 2 })
    this.ErrorComponent = ErrorComponent
    this.pathname = pathname
    this.query = query
    this.asPath = as
    this.subscriptions = []
    this.componentLoadCancel = null

    if (typeof window !== 'undefined') {
      // in order for `e.state` to work on the `onpopstate` event
      // we have to register the initial route upon initialization
      this.changeState('replaceState', formatPath(this), getURL())

      window.addEventListener('popstate', (e) => {
        if (!e.state) {
          // We get state as undefined for two reasons.
          //  1. With older safari (< 8) and older chrome (< 34)
          //  2. When the URL changed with #
          //
          // In the both cases, we don't need to proceed and change the route.
          // (as it's already changed)
          // But we can simply replace the state with the new changes.
          // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
          // So, doing the following for (1) does no harm.
          this.changeState('replaceState', formatPath(this), getURL())
          return
        }

        const { url, as, options } = e.state
        this.replace(url, as, options)
      })
    }
  }

  update (route, Component) {
    const data = this.components[route]
    if (!data) {
      throw new Error(`Cannot update unavailable route: ${route}`)
    }

    const newData = { ...data, Component }
    this.components[route] = newData

    if (route === this.route) {
      this.notify(newData)
    }
  }

  async reload (route) {
    delete this.components[route]
    this.pageLoader.clearCache(route)

    if (route !== this.route) return

    const { pathname, query } = this
    const url = window.location.href

    this.events.emit('routeChangeStart', url)
    const routeInfo = await this.getRouteInfo(route, pathname, query, url)
    const { error } = routeInfo

    if (error && error.cancelled) {
      return
    }

    this.notify(routeInfo)

    if (error) {
      this.events.emit('routeChangeError', error, url)
      throw error
    }

    this.events.emit('routeChangeComplete', url)
  }

  back () {
    window.history.back()
  }

  push (url, as = url, options = {}) {
    return this.change('pushState', url, as, options)
  }

  replace (url, as = url, options = {}) {
    return this.change('replaceState', url, as, options)
  }

  async change (method, _url, _as, options) {
    if (typeof Raven !== 'undefined') {
      Raven.captureBreadcrumb({
        message: 'Router.change',
        method,
        url: _url,
        as: _as
      })
    }
    // If url and as provided as an object representation,
    // we'll format them into the string version here.
    const url = typeof _url === 'object' ? formatPath(_url) : _url
    let as = typeof _as === 'object' ? formatPath(_as) : _as

    this.abortComponentLoad(as)
    const { pathname, query } = parsePath(url, true)

    // If the url change is only related to a hash change
    // We should not proceed. We should only change the state.
    if (this.onlyAHashChange(as)) {
      this.changeState(method, url, as)
      return
    }

    // If asked to change the current URL we should reload the current page
    // (not location.reload() but reload getInitalProps and other Next.js stuffs)
    // We also need to set the method = replaceState always
    // as this should not go into the history (That's how browsers work)
    if (!this.urlIsNew(pathname, query)) {
      method = 'replaceState'
    }

    const route = toRoute(pathname)
    const { shallow = false } = options
    let routeInfo = null

    this.events.emit('routeChangeStart', as)

    // If shallow === false and other conditions met, we reuse the
    // existing routeInfo for this route.
    // Because of this, getInitialProps would not run.
    if (shallow && this.isShallowRoutingPossible(route)) {
      routeInfo = this.components[route]
    } else {
      routeInfo = await this.getRouteInfo(route, pathname, query, as)
    }

    const { error } = routeInfo

    if (error && error.cancelled) {
      return false
    }

    this.events.emit('beforeHistoryChange', as)
    this.changeState(method, url, as, options)
    const hash = window.location.hash.substring(1)

    this.route = route
    this.pathname = pathname
    this.query = query
    this.asPath = as
    this.notify({ ...routeInfo, hash })

    if (error) {
      this.events.emit('routeChangeError', error, as)
      throw error
    }

    this.events.emit('routeChangeComplete', as)
    return true
  }

  changeState (method, url, as, options = {}) {
    if (method !== 'pushState' || getURL() !== as) {
      console.log('changeState', method, as)
      window.history[method]({ url, as, options }, null, as)
    }
  }

  async getRouteInfo (route, pathname, query, as) {
    let routeInfo = null

    try {
      routeInfo = this.components[route]
      if (!routeInfo) {
        routeInfo = { Component: await this.fetchComponent(route, as) }
      }

      const { Component } = routeInfo
      const ctx = { pathname, query, asPath: as }
      routeInfo.props = await this.getInitialProps(Component, ctx)

      this.components[route] = routeInfo
    } catch (err) {
      if (err.cancelled) {
        return { error: err }
      }

      if (err.buildIdMismatched) {
        // Now we need to reload the page or do the action asked by the user
        _notifyBuildIdMismatch(as)
        // We also need to cancel this current route change.
        // We do it like this.
        err.cancelled = true
        return { error: err }
      }

      if (err.statusCode === 404) {
        // Indicate main error display logic to
        // ignore rendering this error as a runtime error.
        err.ignore = true
      }

      const Component = this.ErrorComponent
      routeInfo = { Component, err }
      const ctx = { err, pathname, query }
      routeInfo.props = await this.getInitialProps(Component, ctx)

      routeInfo.error = err
    }

    return routeInfo
  }

  onlyAHashChange (as) {
    if (!this.asPath) return false
    const [ oldUrlNoHash ] = this.asPath.split('#')
    const [ newUrlNoHash ] = as.split('#')

    // If the urls are change, there's more than a hash change
    return oldUrlNoHash === newUrlNoHash
  }

  urlIsNew (pathname, query) {
    return this.pathname !== pathname || !shallowEquals(query, this.query)
  }

  isShallowRoutingPossible (route) {
    return (
      // If there's cached routeInfo for the route.
      Boolean(this.components[route]) &&
      // If the route is already rendered on the screen.
      this.route === route
    )
  }

  async prefetch (url) {
    // We don't add support for prefetch in the development mode.
    // If we do that, our on-demand-entries optimization won't performs better
    if (process.env.NODE_ENV === 'development') return

    const { pathname } = parsePath(url)
    const route = toRoute(pathname)
    return this.prefetchQueue.add(() => this.fetchRoute(route))
  }

  async fetchComponent (route, as) {
    let cancelled = false
    const cancel = this.componentLoadCancel = function () {
      cancelled = true
    }

    try {
      const Component = await this.fetchRoute(route)

      if (cancelled) {
        const error = new Error(`Abort fetching component for route: "${route}"`)
        error.cancelled = true
        throw error
      }

      if (cancel === this.componentLoadCancel) {
        this.componentLoadCancel = null
      }

      return Component
    } catch (err) {
      // There's an error in loading the route.
      // Usually this happens when there's a failure in the webpack build
      // So in that case, we need to load the page with full SSR
      // That'll clean the invalid exising client side information.
      // (Like cached routes)
      window.location.href = as
      throw err
    }
  }

  async getInitialProps (Component, ctx) {
    let cancelled = false
    const cancel = () => { cancelled = true }
    this.componentLoadCancel = cancel

    const props = await loadGetInitialProps(Component, ctx)

    if (cancel === this.componentLoadCancel) {
      this.componentLoadCancel = null
    }

    if (cancelled) {
      const err = new Error('Loading initial props cancelled')
      err.cancelled = true
      throw err
    }

    return props
  }

  async fetchRoute (route) {
    return this.pageLoader.loadPage(route)
  }

  abortComponentLoad (as) {
    if (this.componentLoadCancel) {
      this.events.emit('routeChangeError', new Error('Route Cancelled'), as)
      this.componentLoadCancel()
      this.componentLoadCancel = null
    }
  }

  notify (data) {
    this.subscriptions.forEach((fn) => fn(data))
  }

  subscribe (fn) {
    this.subscriptions.push(fn)
    return () => {
      let index = this.subscriptions.indexOf(fn)
      if (index >= 0) {
        this.subscriptions.splice(index, 1)
      }
    }
  }
}

function toRoute (path) {
  return path.replace(/\/$/, '') || '/'
}
<|endoftext|>


<commit_before>Router.map(function() {
    this.route('home', {
        path: '/'
    });
});
<commit_msg>removed home route<commit_after><|endoftext|>


<commit_before>

//-------------------------------------------------------+
//  Sherdog MMA API
//  sherdog.getFighter(url, callback(data));
//-------------------------------------------------------+

var request = require("request");
var cheerio = require("cheerio");

//-------------------------------------------------------+
//  Get Fighter Profile
//-------------------------------------------------------+

module.exports.getFighter = function(url, callback) {
  request(url, function(error, response, html) {
    if (!error && response.statusCode == 200) {
      var $ = cheerio.load(html);

      //----------------------------------+
      //  JSON object for Fighter
      //----------------------------------+
      var fighter = {
        name: "",
        nickname: "",
        bio: {
          age: "",
          birthday: "",
          locality: "",
          nationality: "",
          association: "",
          height: "",
          weight: "",
          weight_class: ""
        },
        record: {
          wins: {
            total: 0,
            knockouts: 0,
            submissions: 0,
            decisions: 0,
            others: 0
          },
          losses: {
            total: 0,
            knockouts: 0,
            submissions: 0,
            decisions: 0,
            others: 0
          },
          no_contests: 0
        },
        fights: []
      };

      // Fighter name, nickname
      $('h1[itemprop="name"]').filter(function() {
        var el = $(this);
        name = el.find('span.fn').text();
        nickname = el.find('span.nickname').text();
        fighter.name = name;
        fighter.nickname = nickname.replace(/['"]+/g, '');
      });

      // Fighter bio
      $('.bio').filter(function() {
        var el = $(this);
        age = el.find('.item.birthday strong').text();
        birthday = el.find('span[itemprop="birthDate"]').text();
        locality = el.find('span[itemprop="addressLocality"]').text();
        nationality = el.find('strong[itemprop="nationality"]').text();
        association = el.find('.item.association span[itemprop="name"]').text();
        height = el.find('.item.height strong').text();
        weight = el.find('.item.weight strong').text();
        weight_class = el.find('.item.wclass strong').text();
        fighter.bio.age = age.slice(5);
        fighter.bio.birthday = birthday;
        fighter.bio.locality = locality;
        fighter.bio.nationality = nationality;
        fighter.bio.association = association;
        fighter.bio.height = height;
        fighter.bio.weight = weight;
        fighter.bio.weight_class = weight_class;
      });

      // Fighter record
      $('.record .count_history').filter(function() {
        var el = $(this);
        var wins = el.find('.left_side .bio_graph').first();
        var winsByKnockout = wins.find('.graph_tag:nth-child(3)');
        var winsBySubmission = wins.find('.graph_tag:nth-child(5)');
        var winsByDecision = wins.find('.graph_tag:nth-child(7)');
        var winsByOther = wins.find('.graph_tag:nth-child(9)');
        var losses = el.find('.left_side .bio_graph.loser');
        var lossesByKnockout = losses.find('.graph_tag:nth-child(3)');
        var lossesBySubmission = losses.find('.graph_tag:nth-child(5)');
        var lossesByDecision = losses.find('.graph_tag:nth-child(7)');
        var lossesByOther = losses.find('.graph_tag:nth-child(9)');
        var noContests = el.find('.right_side .bio_graph');
        var getTotal = function(el) { return parseInt(el.text().split(' ')[0] || 0); }
        var getPercent = function(el) { return el.find('em').text().split('%')[0]; }

        wins_total = parseInt(wins.find('.card .counter').text());
        losses_total = parseInt(losses.find('.counter').text());
        no_contests_total = parseInt(noContests.find('.counter').text());
        fighter.record.wins.total = wins_total;
        fighter.record.losses.total = losses_total;
        fighter.record.no_contests = no_contests_total;
        fighter.record.wins.knockouts = getTotal(winsByKnockout);
        fighter.record.wins.submissions = getTotal(winsBySubmission);
        fighter.record.wins.decisions = getTotal(winsByDecision);
        fighter.record.wins.others = getTotal(winsByOther);
        fighter.record.losses.knockouts = getTotal(lossesByKnockout);
        fighter.record.losses.submissions = getTotal(lossesBySubmission);
        fighter.record.losses.decisions = getTotal(lossesByDecision);
      });

      // Fighter Fight History
      $('.module.fight_history tr:not(.table_head)').each(function() {
        var el = $(this);
        result = el.find('td:nth-child(1) .final_result').text();
        opponent_name = el.find('td:nth-child(2) a').text();
        opponent_url = el.find('td:nth-child(2) a').attr('href');
        event_name = el.find('td:nth-child(3) a').text();
        event_url = el.find('td:nth-child(3) a').attr('href');
        event_date = el.find('td:nth-child(3) .sub_line').text();
        method = el.find('td:nth-child(4)').text().split(/\)(.*)/)[0] + ")";
        referee = el.find('td:nth-child(4) .sub_line').text();
        round = el.find('td:nth-child(5)').text();
        time = el.find('td:nth-child(6)').text();
        //----------------------------------+
        //  JSON object for Fight
        //----------------------------------+
        var fight = {
          name: event_name,
          date: event_date,
          url: event_url,
          result: result,
          method: method,
          referee: referee,
          round: round,
          time: time,
          opponent: {
            name: opponent_name,
            url: opponent_url
          }
        };
        fighter.fights.push(fight);
      });

      callback(fighter);
    }
  });
}

<commit_msg>removing unnecessary bio object<commit_after>

//-------------------------------------------------------+
//  Sherdog MMA API
//  sherdog.getFighter(url, callback(data));
//-------------------------------------------------------+

var request = require("request");
var cheerio = require("cheerio");

//-------------------------------------------------------+
//  Get Fighter Profile
//-------------------------------------------------------+

module.exports.getFighter = function(url, callback) {
  request(url, function(error, response, html) {
    if (!error && response.statusCode == 200) {
      var $ = cheerio.load(html);

      //----------------------------------+
      //  JSON object for Fighter
      //----------------------------------+
      var fighter = {
        name: "",
        nickname: "",
        age: "",
        birthday: "",
        locality: "",
        nationality: "",
        association: "",
        height: "",
        weight: "",
        weight_class: ""
        record: {
          wins: {
            total: 0,
            knockouts: 0,
            submissions: 0,
            decisions: 0,
            others: 0
          },
          losses: {
            total: 0,
            knockouts: 0,
            submissions: 0,
            decisions: 0,
            others: 0
          },
          no_contests: 0
        },
        fights: []
      };

      // Fighter name, nickname
      $('h1[itemprop="name"]').filter(function() {
        var el = $(this);
        name = el.find('span.fn').text();
        nickname = el.find('span.nickname').text();
        fighter.name = name;
        fighter.nickname = nickname.replace(/['"]+/g, '');
      });

      // Fighter bio
      $('.bio').filter(function() {
        var el = $(this);
        age = el.find('.item.birthday strong').text();
        birthday = el.find('span[itemprop="birthDate"]').text();
        locality = el.find('span[itemprop="addressLocality"]').text();
        nationality = el.find('strong[itemprop="nationality"]').text();
        association = el.find('.item.association span[itemprop="name"]').text();
        height = el.find('.item.height strong').text();
        weight = el.find('.item.weight strong').text();
        weight_class = el.find('.item.wclass strong').text();
        fighter.age = age.slice(5);
        fighter.birthday = birthday;
        fighter.locality = locality;
        fighter.nationality = nationality;
        fighter.association = association;
        fighter.height = height;
        fighter.weight = weight;
        fighter.weight_class = weight_class;
      });

      // Fighter record
      $('.record .count_history').filter(function() {
        var el = $(this);
        var wins = el.find('.left_side .bio_graph').first();
        var winsByKnockout = wins.find('.graph_tag:nth-child(3)');
        var winsBySubmission = wins.find('.graph_tag:nth-child(5)');
        var winsByDecision = wins.find('.graph_tag:nth-child(7)');
        var winsByOther = wins.find('.graph_tag:nth-child(9)');
        var losses = el.find('.left_side .bio_graph.loser');
        var lossesByKnockout = losses.find('.graph_tag:nth-child(3)');
        var lossesBySubmission = losses.find('.graph_tag:nth-child(5)');
        var lossesByDecision = losses.find('.graph_tag:nth-child(7)');
        var lossesByOther = losses.find('.graph_tag:nth-child(9)');
        var noContests = el.find('.right_side .bio_graph');
        var getTotal = function(el) { return parseInt(el.text().split(' ')[0] || 0); }
        var getPercent = function(el) { return el.find('em').text().split('%')[0]; }

        wins_total = parseInt(wins.find('.card .counter').text());
        losses_total = parseInt(losses.find('.counter').text());
        no_contests_total = parseInt(noContests.find('.counter').text());
        fighter.record.wins.total = wins_total;
        fighter.record.losses.total = losses_total;
        fighter.record.no_contests = no_contests_total;
        fighter.record.wins.knockouts = getTotal(winsByKnockout);
        fighter.record.wins.submissions = getTotal(winsBySubmission);
        fighter.record.wins.decisions = getTotal(winsByDecision);
        fighter.record.wins.others = getTotal(winsByOther);
        fighter.record.losses.knockouts = getTotal(lossesByKnockout);
        fighter.record.losses.submissions = getTotal(lossesBySubmission);
        fighter.record.losses.decisions = getTotal(lossesByDecision);
      });

      // Fighter Fight History
      $('.module.fight_history tr:not(.table_head)').each(function() {
        var el = $(this);
        result = el.find('td:nth-child(1) .final_result').text();
        opponent_name = el.find('td:nth-child(2) a').text();
        opponent_url = el.find('td:nth-child(2) a').attr('href');
        event_name = el.find('td:nth-child(3) a').text();
        event_url = el.find('td:nth-child(3) a').attr('href');
        event_date = el.find('td:nth-child(3) .sub_line').text();
        method = el.find('td:nth-child(4)').text().split(/\)(.*)/)[0] + ")";
        referee = el.find('td:nth-child(4) .sub_line').text();
        round = el.find('td:nth-child(5)').text();
        time = el.find('td:nth-child(6)').text();
        //----------------------------------+
        //  JSON object for Fight
        //----------------------------------+
        var fight = {
          name: event_name,
          date: event_date,
          url: event_url,
          result: result,
          method: method,
          referee: referee,
          round: round,
          time: time,
          opponent: {
            name: opponent_name,
            url: opponent_url
          }
        };
        fighter.fights.push(fight);
      });

      callback(fighter);
    }
  });
}

<|endoftext|>


<commit_before>function toggleSuite(suiteId) {
    toggleElement(suiteId, ['keyword', 'suite', 'test']);
}

function toggleTest(testId) {
    toggleElement(testId, ['keyword']);
}

function toggleKeyword(kwId) {
    toggleElement(kwId, ['keyword', 'message']);
}

function addElements(elems, templateName, target){
    for (var i in elems) {
        $.tmpl(templateName, elems[i]).appendTo(target);
    }
}

function toggleElement(elementId, childrenNames) {
    var childElement = $("#"+elementId+"_children");
    childElement.toggle();
    populateChildren(elementId, childElement, childrenNames);
    var foldingButton = $('#'+elementId+'_foldingbutton');
    foldingButton.text(foldingButton.text() == '+' ? '-' : '+');
}

function populateChildren(elementId, childElement, childrenNames) {
    if (!childElement.hasClass("populated")) {
        var element = window.testdata.find(elementId);
        element.callWhenChildrenReady(drawCallback(element, childElement, childrenNames));
        childElement.addClass("populated");
    }
}

function drawCallback(element, childElement, childrenNames) {
    return function () {
        $.map(childrenNames, function (childName) {
            addElements(element[childName + 's'](), childName + 'Template', childElement);
        });
    }
}

function expandRecursively(){
    if (!window.elementsToExpand.length)
        return;
    var element = window.elementsToExpand.pop();
    if (element == undefined || elementHiddenByUser(element.id)) {
        window.elementsToExpand = [];
        return;
    }
    expandElement(element);
    element.callWhenChildrenReady( function () {
        var children = element.children();
        for (var i = children.length-1; i >= 0; i--) {
            if (window.expandDecider(children[i]))
                window.elementsToExpand.push(children[i]);
        }
        if (window.elementsToExpand.length)
            setTimeout(expandRecursively, 0);
    });
}

function expandElement(element) {
    var childElement = $("#" + element.id + "_children");
    childElement.show();
    populateChildren(element.id, childElement, element.childrenNames);
    $('#'+element.id+'_foldingbutton').text('-');
}

function elementHiddenByUser(elementId) {
    var domElement = $("#"+elementId);
    return !domElement.is(":visible");
}

function expandAllChildren(elementId) {
    window.elementsToExpand = [window.testdata.find(elementId)];
    window.expandDecider = function() {return true;};
    expandRecursively();
}

function expandCriticalFailed(element) {
    if (element.status == "FAIL") {
        window.elementsToExpand = [element];
        window.expandDecider = function(e) {return e.status == "FAIL" && (e.isCritical === undefined || e.isCritical);};
        expandRecursively();
    }
}

function expandSuite(suite) {
    if (suite.status == "PASS")
        expandElement(suite);
    else
        expandCriticalFailed(suite);
}
<commit_msg>backout animation change - not the cause of the current problem<commit_after>function toggleSuite(suiteId) {
    toggleElement(suiteId, ['keyword', 'suite', 'test']);
}

function toggleTest(testId) {
    toggleElement(testId, ['keyword']);
}

function toggleKeyword(kwId) {
    toggleElement(kwId, ['keyword', 'message']);
}

function addElements(elems, templateName, target){
    for (var i in elems) {
        $.tmpl(templateName, elems[i]).appendTo(target);
    }
}

function toggleElement(elementId, childrenNames) {
    var childElement = $("#"+elementId+"_children");
    childElement.toggle(100);
    populateChildren(elementId, childElement, childrenNames);
    var foldingButton = $('#'+elementId+'_foldingbutton');
    foldingButton.text(foldingButton.text() == '+' ? '-' : '+');
}

function populateChildren(elementId, childElement, childrenNames) {
    if (!childElement.hasClass("populated")) {
        var element = window.testdata.find(elementId);
        element.callWhenChildrenReady(drawCallback(element, childElement, childrenNames));
        childElement.addClass("populated");
    }
}

function drawCallback(element, childElement, childrenNames) {
    return function () {
        $.map(childrenNames, function (childName) {
            addElements(element[childName + 's'](), childName + 'Template', childElement);
        });
    }
}

function expandRecursively(){
    if (!window.elementsToExpand.length)
        return;
    var element = window.elementsToExpand.pop();
    if (element == undefined || elementHiddenByUser(element.id)) {
        window.elementsToExpand = [];
        return;
    }
    expandElement(element);
    element.callWhenChildrenReady( function () {
        var children = element.children();
        for (var i = children.length-1; i >= 0; i--) {
            if (window.expandDecider(children[i]))
                window.elementsToExpand.push(children[i]);
        }
        if (window.elementsToExpand.length)
            setTimeout(expandRecursively, 0);
    });
}

function expandElement(element) {
    var childElement = $("#" + element.id + "_children");
    childElement.show(100);
    populateChildren(element.id, childElement, element.childrenNames);
    $('#'+element.id+'_foldingbutton').text('-');
}

function elementHiddenByUser(elementId) {
    var domElement = $("#"+elementId);
    return !domElement.is(":visible");
}

function expandAllChildren(elementId) {
    window.elementsToExpand = [window.testdata.find(elementId)];
    window.expandDecider = function() {return true;};
    expandRecursively();
}

function expandCriticalFailed(element) {
    if (element.status == "FAIL") {
        window.elementsToExpand = [element];
        window.expandDecider = function(e) {return e.status == "FAIL" && (e.isCritical === undefined || e.isCritical);};
        expandRecursively();
    }
}

function expandSuite(suite) {
    if (suite.status == "PASS")
        expandElement(suite);
    else
        expandCriticalFailed(suite);
}
<|endoftext|>


<commit_before>suite('rb/views/DraftReviewBannerView', function() {
    var model,
        view,
        template = _.template([
            '
',
            '
',
            '
You have a pending review.
',
            '  <input id="review-banner-edit" type="button" ',
            '         value="Edit Review" />',
            '  <input id="review-banner-publish-container" type="button" ',
            '         value="Publish" />',
            '  <input id="review-banner-discard" type="button" ',
            '         value="Discard" />',
            '
',
            '
'
        ].join(''));

    beforeEach(function() {
        var $el = $(template()).appendTo($testsScratch);

        model = new RB.DraftReview();
        view = new RB.DraftReviewBannerView({
            el: $el,
            model: model
        });

        view.render();
    });

    afterEach(function() {
        view.remove();
    });

    describe('Button states', function() {
        var $buttons;

        beforeEach(function() {
            $buttons = view.$('input');
        });

        describe('Enabled', function() {
            it('Default', function() {
                expect($buttons.prop('disabled')).toBe(false);
            });

            it('When saved', function() {
                $buttons.prop('disabled', true);
                model.trigger('saved');
                expect($buttons.prop('disabled')).toBe(false);
            });

            it('When destroyed', function() {
                $buttons.prop('disabled', true);
                model.trigger('destroyed');
                expect($buttons.prop('disabled')).toBe(false);
            });
        });

        describe('Disabled', function() {
            it('When saving', function() {
                model.trigger('saving');
                expect($buttons.prop('disabled')).toBe(true);
            });

            it('When destroying', function() {
                model.trigger('destroying');
                expect($buttons.prop('disabled')).toBe(true);
            });
        });
    });

    describe('Button events', function() {
        it('Edit Review', function() {
            spyOn(RB.ReviewDialogView, 'create');

            view.$('#review-banner-edit').click();

            expect(RB.ReviewDialogView.create).toHaveBeenCalled();
            expect(RB.ReviewDialogView.create.calls.argsFor(0)[0].review)
                .toBe(model);
        });

        it('Publish', function() {
            spyOn(model, 'publish');

            view.$('#review-banner-publish').click();

            expect(model.publish).toHaveBeenCalled();
        });

        it('Publish to Submitter Only', function() {
            spyOn(model, 'publish');

            /*
             * The alternative buttons from the split button are added to the
             * .
             */
            $('#review-banner-publish-submitter-only').click();

            expect(model.publish).toHaveBeenCalled();
        });

        it('Discard', function() {
            var $buttons = $();

            spyOn(model, 'destroy');
            spyOn($.fn, 'modalBox').and.callFake(function(options) {
                _.each(options.buttons, function($btn) {
                    $buttons = $buttons.add($btn);
                });

                /* Simulate the modalBox API for what we need. */
                return {
                    modalBox: function(cmd) {
                        expect(cmd).toBe('buttons');

                        return $buttons;
                    }
                };
            });

            view.$('#review-banner-discard').click();
            expect($.fn.modalBox).toHaveBeenCalled();

            $buttons.filter('input[value="Discard"]').click();
            expect(model.destroy).toHaveBeenCalled();
        });
    });

    describe('Methods', function() {
        it('show', function() {
            expect(view.$el.is(':visible')).toBe(false);

            view.show();
            expect(view.$el.is(':visible')).toBe(true);
        });

        it('hide', function() {
            view.$el.show();
            expect(view.$el.is(':visible')).toBe(true);

            view.hide();
            expect(view.$el.is(':visible')).toBe(false);
        });
    });
});
<commit_msg>Fix unit tests for DraftReviewBannerView.<commit_after>suite('rb/views/DraftReviewBannerView', function() {
    var model,
        view,
        template = _.template([
            '
',
            '
',
            '
You have a pending review.
',
            '  <input id="review-banner-edit" type="button" ',
            '         value="Edit Review" />',
            '  <input id="review-banner-publish-container" type="button" ',
            '         value="Publish" />',
            '  <input id="review-banner-discard" type="button" ',
            '         value="Discard" />',
            '
',
            '
'
        ].join(''));

    beforeEach(function() {
        var $el = $(template()).appendTo($testsScratch);

        model = new RB.DraftReview();
        view = new RB.DraftReviewBannerView({
            el: $el,
            model: model
        });

        view.render();
    });

    afterEach(function() {
        view.remove();
    });

    describe('Button states', function() {
        var $buttons;

        beforeEach(function() {
            $buttons = view.$('input');
        });

        describe('Enabled', function() {
            it('Default', function() {
                expect($buttons.prop('disabled')).toBe(false);
            });

            it('When saved', function() {
                $buttons.prop('disabled', true);
                model.trigger('saved');
                expect($buttons.prop('disabled')).toBe(false);
            });

            it('When destroyed', function() {
                $buttons.prop('disabled', true);
                model.trigger('destroyed');
                expect($buttons.prop('disabled')).toBe(false);
            });
        });

        describe('Disabled', function() {
            it('When saving', function() {
                model.trigger('saving');
                expect($buttons.prop('disabled')).toBe(true);
            });

            it('When destroying', function() {
                model.trigger('destroying');
                expect($buttons.prop('disabled')).toBe(true);
            });
        });
    });

    describe('Button events', function() {
        it('Edit Review', function() {
            spyOn(RB.ReviewDialogView, 'create');

            view.$('#review-banner-edit').click();

            expect(RB.ReviewDialogView.create).toHaveBeenCalled();
            expect(RB.ReviewDialogView.create.calls.argsFor(0)[0].review)
                .toBe(model);
        });

        it('Publish', function() {
            spyOn(model, 'publish');

            view.$('#review-banner-publish').click();

            expect(model.publish).toHaveBeenCalled();
        });

        it('Publish to Submitter Only', function() {
            spyOn(model, 'publish');

            /*
             * The alternative buttons from the split button are added to the
             * .
             */
            $('#review-banner-publish-submitter-only').click();

            expect(model.publish).toHaveBeenCalled();
        });

        it('Discard', function() {
            var $buttons = $();

            spyOn(model, 'destroy');
            spyOn($.fn, 'modalBox').and.callFake(function(options) {
                _.each(options.buttons, function($btn) {
                    $buttons = $buttons.add($btn);
                });

                /* Simulate the modalBox API for what we need. */
                return {
                    modalBox: function(cmd) {
                        expect(cmd).toBe('buttons');

                        return $buttons;
                    }
                };
            });

            view.$('#review-banner-discard').click();
            expect($.fn.modalBox).toHaveBeenCalled();

            $buttons.filter('input[value="Discard"]').click();
            expect(model.destroy).toHaveBeenCalled();
        });
    });

    describe('Methods', function() {
        it('show', function() {
            expect(view.$el.hasClass('hidden')).toBe(true);

            view.show();
            expect(view.$el.hasClass('hidden')).toBe(false);
        });

        it('hide', function() {
            view.$el.addClass('hidden');

            view.hide();
            expect(view.$el.hasClass('hidden')).toBe(true);
        });
    });
});
<|endoftext|>


<commit_before>navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

var peer = new Adawarp();
var myID = null;
var call;

var localStream;
var connectedCall;

var myID;
var partnerID;

window.onload = function(){
    displayMyCamera();
    peer.on('open', function(){
        document.getElementById("my-id").innerHTML = peer.id;
    });
    peer.login();
}

peer.on('connection', function(conn) {
    document.getElementById("partnerID").innerHTML = conn.peer;
    conn.on('data', function(data){
        document.getElementById("receive_message").innerHTML = data;
        //convertData(data);
        console.log(typeof(data));
    });
});

peer.on('call', function(call){
    connectedCall = call;
    call.answer(localStream);

    call.on('stream', function(stream){
        document.getElementById("partnerVideo").src = URL.createObjectURL(stream);
    });
});

function displayMyCamera(){
    navigator.getUserMedia({audio: true, video: true}, function(stream){
        localStream = stream;
        document.getElementById("myVideo").src = URL.createObjectURL(stream);
    }, function() { alert("Error!"); });
}<commit_msg>commentout converting data<commit_after>navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

var peer = new Adawarp();
var myID = null;
var call;

var localStream;
var connectedCall;

var myID;
var partnerID;

var yaw = 90;

window.onload = function(){
    displayMyCamera();
    peer.on('open', function(){
        document.getElementById("my-id").innerHTML = peer.id;
    });
    peer.login();
}

peer.on('connection', function(conn) {
    document.getElementById("partnerID").innerHTML = conn.peer;
    conn.on('data', function(data){
        document.getElementById("receive_message").innerHTML = data;
        //convertData(data);
        data = parseInt(data);
        console.log(typeof(data));
    });
});

peer.on('call', function(call){
    connectedCall = call;
    call.answer(localStream);

    call.on('stream', function(stream){
        document.getElementById("partnerVideo").src = URL.createObjectURL(stream);
    });
});

function displayMyCamera(){
    navigator.getUserMedia({audio: true, video: true}, function(stream){
        localStream = stream;
        document.getElementById("myVideo").src = URL.createObjectURL(stream);
    }, function() { alert("Error!"); });
}<|endoftext|>


<commit_before>// ==UserScript==
// @author         sk3dsu(Fadli Ishak)
// @name           MyLowyat
// @version        0.1
// @description    Removing some elements of the forum to be a bit cleaner for SFW.
// @namespace      https://github.com/mfadliishak/lowyatAvatars
// @icon           https://forum.lowyat.net/favicon.ico
// @match          http*://forum.lowyat.net/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js
// ==/UserScript==

/**
 * 1. Remove all those annoying avatars!
 *
 */
var avatars = $('.avatarwrap');
for (i = 0; i < avatars.length; i++)
{
    var item = avatars[i];
    item.style = "display:none;";
}
<commit_msg>Remove Lowyat Banner.<commit_after>// ==UserScript==
// @author         sk3dsu(Fadli Ishak)
// @name           MyLowyat
// @version        0.1
// @description    Removing some elements of the forum to be a bit cleaner for SFW.
// @namespace      https://github.com/mfadliishak/lowyatAvatars
// @icon           https://forum.lowyat.net/favicon.ico
// @match          http*://forum.lowyat.net/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js
// ==/UserScript==

/**
 * 1. Remove all those annoying avatars!
 *
 */
var avatars = $('.avatarwrap');
for (i = 0; i < avatars.length; i++)
{
    var item = avatars[i];
    item.style = "display:none;";
}

/**
 * 2. Remove that big banner up there.
 *
 */
var banner = $('.borderwrap');
if (banner)
{
	banner.style = "display:none;";
}
<|endoftext|>


<commit_before>import Ember from 'ember';

var SettingsGeneralController = Ember.ObjectController.extend({
    needs: ['settings'],
    site: Ember.computed.alias('controllers.settings.model'),

    actions: {
        removeLogo: function() {
            this.get('model').set('logo', null);
            this.send('save');
        },

        removeCover: function() {
            this.get('model').set('cover', null);
            this.send('save');
        },

        // called by 'select-image' modal controller
        imageSelected: function(field, image) {
            var model = this.get('model');
            model.set(field, image);

            // save model
            var self = this;
            model.save().then(function (siteSaved) {
                self.get('flashes').success('Saved.');
                return siteSaved;
            }).catch(function () {
                self.get('flashes').danger('Failed to save.');
            });
        },

        save: function () {
            var self = this;

            return this.get('model').save().then(function (model) {
                self.get('flashes').success('Settings saved.');

                return model;
            }).catch(function (/* errors */) {
                self.get('flashes').danger('Failed to save settings.');
            });
        }
    }
});

export default SettingsGeneralController;
<commit_msg>Removes auto-save when changing cover/logo on settings/general<commit_after>import Ember from 'ember';

var SettingsGeneralController = Ember.ObjectController.extend({
    needs: ['settings'],
    site: Ember.computed.alias('controllers.settings.model'),

    actions: {
        removeLogo: function() {
            this.get('model').set('logo', null);
        },

        removeCover: function() {
            this.get('model').set('cover', null);
        },

        // called by 'select-image' modal controller
        imageSelected: function(field, image) {
            var model = this.get('model');
            model.set(field, image);
        },

        save: function () {
            var self = this;

            return this.get('model').save().then(function (model) {
                self.get('flashes').success('Settings saved.');

                return model;
            }).catch(function (/* errors */) {
                self.get('flashes').danger('Failed to save settings.');
            });
        }
    }
});

export default SettingsGeneralController;
<|endoftext|>


<commit_before>'use strict';

angular.module('tdpharmaClientApp')
  .controller('ProductsCtrl', ProductsCtrl);

ProductsCtrl.$inject = [
  '$cookies', '$filter', '$timeout', 'APP_CONFIGURATION', 'Category', 'Medicine', 'User',
  'toastr', 'S3Upload', 'lodash', 'serverConfig', 'InventoryItem'];

function ProductsCtrl($cookies, $filter, $timeout, APP_CONFIGURATION, Category, Medicine, User, toastr, S3Upload, _, serverConfig, InventoryItem) {

  var ctrl = this;
  ctrl.IMAGE_PLACEHOLDER = APP_CONFIGURATION.SERVER_DEFAULT_PICTURE_ENDPOINT + '/images/inventoryitem.svg';
  ctrl.tabs = [
    { title:'Category', template:'app/products/includes/category.html', active: true },
    { title:'Details', template:'app/products/includes/details.html', disabled: true }
  ];
  ctrl.categories = [];
  ctrl.amazon_config = {};
  ctrl.medicine = {med_batches_attributes:[{}]};
  ctrl.maxDate = new Date();
  ctrl.selected_user = {};
  ctrl.dateOptions = {
    formatYear: 'yy',
    startingDay: 1
  };
  ctrl.loading = true;
  ctrl.updateUser = updateUser;
  ctrl.open = open;
  ctrl.nextTab = nextTab;
  ctrl.updateTotalAmount = updateTotalAmount;
  ctrl.uploadImage = uploadImage;
  ctrl.saveDirectUpload = saveDirectUpload;
  ctrl.save = save;

  prepareData();

  // Function definition
  function prepareData(){
    User.query().$promise.then(function(resp){
        ctrl.store_users = resp;
    }).catch(function(err){
      toastr.error(err.data.data.errors, $filter('translate')('TOASTR_SORRY'));
    });

    Category.get({}, function(x) {
      ctrl.categories = x.data;
      ctrl.selected = [ctrl.categories[0], ctrl.categories[0].children[0]]

    });

    serverConfig.get({id: 'temp_amazon_s3'}).$promise.then(function(resp){
      ctrl.amazon_config = resp.data;
    }).catch(function(err){
      toastr.error(err.data.data.errors, $filter('translate')('TOASTR_SORRY'));
    })
  }

  function updateUser(item){
    var resp = item;
    _.each(ctrl.medicine.med_batches_attributes, function(b){
      b.user_id = item.id;
    });
  }

  function nextTab() {
    var idx = ctrl.tabs.findIndex(function(x) {return x.active});
    var tab = ctrl.tabs[idx+1];
    tab.active = true;
    tab.disabled = false;
  }

  function updateTotalAmount() {
    if (ctrl.medicine.med_batches_attributes[0].amount_per_pkg && ctrl.medicine.med_batches_attributes[0].amount_unit) {
      ctrl.medicine.med_batches_attributes[0].total_units = ctrl.medicine.med_batches_attributes[0].amount_per_pkg * ctrl.medicine.med_batches_attributes[0].amount_unit;
    }
  }

  function uploadImage(){
    var direct_link;
    if (ctrl.file) {
      var filename = moment().format('YYYYMMDDDDmmssssss');
      direct_link = S3Upload.upload(ctrl.amazon_config, ctrl.file, filename);
    }
    return direct_link;
  }

  function finishSuccess(item){
    ctrl.medicine = {med_batches_attributes:[{user_id: ctrl.selected_user.id}]};
    ctrl.file = null;
    _.extend(ctrl.tabs[0], {active: true, disabled: false});
    _.extend(ctrl.tabs[1], {active: false, disabled: true});
    toastr.success(item.itemable.name + $filter('translate')('TOASTR_CREATED'), $filter('translate')('TOASTR_CONGRATS'));
  }

  function saveDirectUpload(){
    // First attach the category id into the medicine
    if (ctrl.selected[1]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[1].id;
    } else if (ctrl.selected[0]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[0].id;
    }
    // Validate form and save
    if (validateForm()) {
      ctrl.loading = false;
      var params = {
        medicine: ctrl.medicine
      };
      async.waterfall([
          function(callback) {
            // First process the image
            if (ctrl.file) {
              var filename = moment().format('YYYYMMDDDDmmssssss');
              S3Upload.upload(ctrl.amazon_config, ctrl.file, filename).then(function(resp){
                if (resp) {
                  params.direct_upload_url = resp;
                }
                return callback(null, params);
              }).catch(function(error){
                return callback({error: error});
              })
            } else {
              callback(null, params);             // No image to processed so just return the same params
            }
          },
          function(arg1, callback) {
            // Save the medicines
            Medicine.save({}, params).$promise.then(function(resp){
              return callback(null, resp.data);
            }).catch(function(error){
              callback({error: error.data.data.errors});
            });
          },
          function(arg1, callback) {
            // Wait until medicine image is ready
            var item = arg1;
            var retry = 10;
            if (arg1.photo_thumb && arg1.photo_thumb.processed === false) {
              async.whilst(
                function(){
                  return (item.photo_thumb.processed === false);
                },
                function(cb) {
                  toastr.info($filter('translate')('PROCESSING_IMAGE'));
                  InventoryItem.get({id: item.id}).$promise.then(function(resp){
                    item = resp.data;
                  }).catch(function(error){
                    return cb(error.data.data.errors);
                  })
                  retry = retry - 1;
                  if (retry == 0) {
                    return cb($filter('translate')('PROCESSING_IMAGE_TIMEOUT'));
                  }
                  $timeout(cb, 4000)
                },
                function(err) {
                  // Loop completed because of error
                  if (err) {
                    return callback({error: err});
                  } else {
                    // Reset form
                    finishSuccess(item);
                    return callback(null, item);
                  }
                }
              );
            } else {
              // Reset form when there is no photo
              finishSuccess(item);
              return callback(null, item);
            }
          }
        ], function (err, result){
        // After all processes are done or there is an error
        if (err) {
          toastr.error(err.error);
        }
        ctrl.loading = false;
      })
    }
  }

  function save() {
    // First attach the category id into the medicine
    if (ctrl.selected[1]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[1].id;
    } else if (ctrl.selected[0]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[0].id;
    }
    // Validate form and save
    if (validateForm()) {
      var params = {
        medicine: ctrl.medicine
      };
      if (ctrl.file) {
        params.image = ctrl.file.$ngfDataUrl;
      }
      Medicine.save({}, params).$promise.then(function(resp){
        // Reset form
        ctrl.medicine = {med_batches_attributes:[{user_id: ctrl.selected_user.id}]};
        ctrl.file = null;
        _.extend(ctrl.tabs[0], {active: true, disabled: false});
        _.extend(ctrl.tabs[1], {active: false, disabled: true});
        toastr.success(resp.data.name + $filter('translate')('TOASTR_CREATED'), $filter('translate')('TOASTR_CONGRATS'))
      }).catch(function(error){
        toastr.error(error.data.data.errors, $filter('translate')('TOASTR_SORRY'));
      });
    }
  }

  function validateForm(){
    var ok_flag = true;
    if (!ctrl.medicine.med_batches_attributes[0].user_id) {
      toastr.error($filter('translate')('AUTHOR_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].category_id) {
      toastr.error($filter('translate')('CATEGORY_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.name) {
      toastr.error($filter('translate')('NAME_REQUIRED'));
      ok_flag = false;
    }
    if ( ok_flag && !ctrl.medicine.concentration) {
     toastr.error($filter('translate')('CONCENTRATION_REQUIRED'));
     ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.concentration_unit) {
      toastr.error($filter('translate')('CONCENTRATION_UNIT_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.mfg_location) {
      toastr.error($filter('translate')('MFG_LOCATION_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.manufacturer) {
      toastr.error($filter('translate')('MANUFACTURER_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].mfg_date){
      toastr.error($filter('translate')('MFG_DATE_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].expire_date) {
      toastr.error($filter('translate')('EXPIRE_DATE_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].package){
      toastr.error($filter('translate')('PACKAGE_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].amount_per_pkg) {
      toastr.error($filter('translate')('AMOUNT_PER_PKG_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].amount_unit) {
      toastr.error($filter('translate')('AMOUNT_UNIT_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].total_units) {
      toastr.error($filter('translate')('TOTAL_UNITS_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].total_price) {
      toastr.error($filter('translate')('PRICE_REQUIRED'));
      ok_flag = false;
    }
    return ok_flag;
  }

  function open(status, $event, $index) {
    ctrl[status] = ctrl[status] || [];
    ctrl[status][$index] = ctrl[status][$index] || {};
    ctrl[status][$index].opened = true;
  };

}
<commit_msg>Added default author when adding a product<commit_after>'use strict';

angular.module('tdpharmaClientApp')
  .controller('ProductsCtrl', ProductsCtrl);

ProductsCtrl.$inject = [
  '$cookies', '$filter', '$timeout', 'APP_CONFIGURATION', 'Category', 'Medicine', 'User',
  'toastr', 'S3Upload', 'lodash', 'serverConfig', 'InventoryItem'];

function ProductsCtrl($cookies, $filter, $timeout, APP_CONFIGURATION, Category, Medicine, User, toastr, S3Upload, _, serverConfig, InventoryItem) {

  var ctrl = this;
  ctrl.IMAGE_PLACEHOLDER = APP_CONFIGURATION.SERVER_DEFAULT_PICTURE_ENDPOINT + '/images/inventoryitem.svg';
  ctrl.tabs = [
    { title:'Category', template:'app/products/includes/category.html', active: true },
    { title:'Details', template:'app/products/includes/details.html', disabled: true }
  ];
  ctrl.categories = [];
  ctrl.amazon_config = {};
  ctrl.medicine = {med_batches_attributes:[{}]};
  ctrl.maxDate = new Date();
  ctrl.selected_user = {};
  ctrl.dateOptions = {
    formatYear: 'yy',
    startingDay: 1
  };
  ctrl.loading = true;
  ctrl.updateUser = updateUser;
  ctrl.open = open;
  ctrl.nextTab = nextTab;
  ctrl.updateTotalAmount = updateTotalAmount;
  ctrl.uploadImage = uploadImage;
  ctrl.saveDirectUpload = saveDirectUpload;
  ctrl.save = save;

  prepareData();

  // Function definition
  function prepareData(){
    User.query().$promise.then(function(resp){
        ctrl.store_users = resp;
        if (!ctrl.store_users.length) return;
        ctrl.selected_user = ctrl.store_users[0];
        User.get().$promise.then(function(user) {
          var users = ctrl.store_users.filter(function(x) {return x.id===user.id});
          if (users.length) ctrl.selected_user = users[0];
        })
    }).catch(function(err){
      toastr.error(err.data.data.errors, $filter('translate')('TOASTR_SORRY'));
    });

    Category.get({}, function(x) {
      ctrl.categories = x.data;
      ctrl.selected = [ctrl.categories[0], ctrl.categories[0].children[0]]

    });

    serverConfig.get({id: 'temp_amazon_s3'}).$promise.then(function(resp){
      ctrl.amazon_config = resp.data;
    }).catch(function(err){
      toastr.error(err.data.data.errors, $filter('translate')('TOASTR_SORRY'));
    })
  }

  function updateUser(item){
    var resp = item;
    _.each(ctrl.medicine.med_batches_attributes, function(b){
      b.user_id = item.id;
    });
  }

  function nextTab() {
    var idx = ctrl.tabs.findIndex(function(x) {return x.active});
    var tab = ctrl.tabs[idx+1];
    tab.active = true;
    tab.disabled = false;
  }

  function updateTotalAmount() {
    if (ctrl.medicine.med_batches_attributes[0].amount_per_pkg && ctrl.medicine.med_batches_attributes[0].amount_unit) {
      ctrl.medicine.med_batches_attributes[0].total_units = ctrl.medicine.med_batches_attributes[0].amount_per_pkg * ctrl.medicine.med_batches_attributes[0].amount_unit;
    }
  }

  function uploadImage(){
    var direct_link;
    if (ctrl.file) {
      var filename = moment().format('YYYYMMDDDDmmssssss');
      direct_link = S3Upload.upload(ctrl.amazon_config, ctrl.file, filename);
    }
    return direct_link;
  }

  function finishSuccess(item){
    ctrl.medicine = {med_batches_attributes:[{user_id: ctrl.selected_user.id}]};
    ctrl.file = null;
    _.extend(ctrl.tabs[0], {active: true, disabled: false});
    _.extend(ctrl.tabs[1], {active: false, disabled: true});
    toastr.success(item.itemable.name + $filter('translate')('TOASTR_CREATED'), $filter('translate')('TOASTR_CONGRATS'));
  }

  function saveDirectUpload(){
    // First attach the category id into the medicine
    if (ctrl.selected[1]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[1].id;
    } else if (ctrl.selected[0]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[0].id;
    }
    // Validate form and save
    if (validateForm()) {
      ctrl.loading = false;
      var params = {
        medicine: ctrl.medicine
      };
      async.waterfall([
          function(callback) {
            // First process the image
            if (ctrl.file) {
              var filename = moment().format('YYYYMMDDDDmmssssss');
              S3Upload.upload(ctrl.amazon_config, ctrl.file, filename).then(function(resp){
                if (resp) {
                  params.direct_upload_url = resp;
                }
                return callback(null, params);
              }).catch(function(error){
                return callback({error: error});
              })
            } else {
              callback(null, params);             // No image to processed so just return the same params
            }
          },
          function(arg1, callback) {
            // Save the medicines
            Medicine.save({}, params).$promise.then(function(resp){
              return callback(null, resp.data);
            }).catch(function(error){
              callback({error: error.data.data.errors});
            });
          },
          function(arg1, callback) {
            // Wait until medicine image is ready
            var item = arg1;
            var retry = 10;
            if (arg1.photo_thumb && arg1.photo_thumb.processed === false) {
              async.whilst(
                function(){
                  return (item.photo_thumb.processed === false);
                },
                function(cb) {
                  toastr.info($filter('translate')('PROCESSING_IMAGE'));
                  InventoryItem.get({id: item.id}).$promise.then(function(resp){
                    item = resp.data;
                  }).catch(function(error){
                    return cb(error.data.data.errors);
                  })
                  retry = retry - 1;
                  if (retry == 0) {
                    return cb($filter('translate')('PROCESSING_IMAGE_TIMEOUT'));
                  }
                  $timeout(cb, 4000)
                },
                function(err) {
                  // Loop completed because of error
                  if (err) {
                    return callback({error: err});
                  } else {
                    // Reset form
                    finishSuccess(item);
                    return callback(null, item);
                  }
                }
              );
            } else {
              // Reset form when there is no photo
              finishSuccess(item);
              return callback(null, item);
            }
          }
        ], function (err, result){
        // After all processes are done or there is an error
        if (err) {
          toastr.error(err.error);
        }
        ctrl.loading = false;
      })
    }
  }

  function save() {
    // First attach the category id into the medicine
    if (ctrl.selected[1]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[1].id;
    } else if (ctrl.selected[0]) {
      ctrl.medicine.med_batches_attributes[0].category_id = ctrl.selected[0].id;
    }
    // Validate form and save
    if (validateForm()) {
      var params = {
        medicine: ctrl.medicine
      };
      if (ctrl.file) {
        params.image = ctrl.file.$ngfDataUrl;
      }
      Medicine.save({}, params).$promise.then(function(resp){
        // Reset form
        ctrl.medicine = {med_batches_attributes:[{user_id: ctrl.selected_user.id}]};
        ctrl.file = null;
        _.extend(ctrl.tabs[0], {active: true, disabled: false});
        _.extend(ctrl.tabs[1], {active: false, disabled: true});
        toastr.success(resp.data.name + $filter('translate')('TOASTR_CREATED'), $filter('translate')('TOASTR_CONGRATS'))
      }).catch(function(error){
        toastr.error(error.data.data.errors, $filter('translate')('TOASTR_SORRY'));
      });
    }
  }

  function validateForm(){
    var ok_flag = true;
    if (!ctrl.medicine.med_batches_attributes[0].user_id) {
      toastr.error($filter('translate')('AUTHOR_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].category_id) {
      toastr.error($filter('translate')('CATEGORY_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.name) {
      toastr.error($filter('translate')('NAME_REQUIRED'));
      ok_flag = false;
    }
    if ( ok_flag && !ctrl.medicine.concentration) {
     toastr.error($filter('translate')('CONCENTRATION_REQUIRED'));
     ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.concentration_unit) {
      toastr.error($filter('translate')('CONCENTRATION_UNIT_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.mfg_location) {
      toastr.error($filter('translate')('MFG_LOCATION_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.manufacturer) {
      toastr.error($filter('translate')('MANUFACTURER_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].mfg_date){
      toastr.error($filter('translate')('MFG_DATE_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].expire_date) {
      toastr.error($filter('translate')('EXPIRE_DATE_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].package){
      toastr.error($filter('translate')('PACKAGE_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].amount_per_pkg) {
      toastr.error($filter('translate')('AMOUNT_PER_PKG_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].amount_unit) {
      toastr.error($filter('translate')('AMOUNT_UNIT_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].total_units) {
      toastr.error($filter('translate')('TOTAL_UNITS_REQUIRED'));
      ok_flag = false;
    }
    if (ok_flag && !ctrl.medicine.med_batches_attributes[0].total_price) {
      toastr.error($filter('translate')('PRICE_REQUIRED'));
      ok_flag = false;
    }
    return ok_flag;
  }

  function open(status, $event, $index) {
    ctrl[status] = ctrl[status] || [];
    ctrl[status][$index] = ctrl[status][$index] || {};
    ctrl[status][$index].opened = true;
  };

}
<|endoftext|>