<commit_before>function makeLink(el, dep_name) {
  var link = '"https://npmjs.com/package/' + dep_name + '"'
  $(el).find('span')[0].innerHTML = '"' + dep_name + '"'
}

function getDepName(el) {
  var match = el.innerText.match(/\s*"([^"]+)".*$/)
  return match && match[1]
}

function linkify() {
  var lines = $('table.js-file-line-container td')

  if (!lines.length) return

  var start_dep
    , end_dep
    , start_dev_dep
    , end_dev_dep
    , start_opt_dep
    , end_opt_dep

  for (var line = 0; line < lines.length; line++) {
    var line_text = lines[line].innerText

    if (!start_dep && /^\s*"dependencies"\s*:\s*\{\s*$/.test(line_text)) {
      start_dep = line
    }

    if (!start_dev_dep && /^\s*"devDependencies"\s*:\s*\{\s*$/.test(line_text)) {
      start_dev_dep = line
    }

    if (!start_opt_dep && /^\s*"optionalDependencies"\s*:\s*\{\s*$/.test(line_text)) {
      start_opt_dep = line
    }

    if (/}/.test(line_text)) {
      if (start_dep && !end_dep) {
        end_dep = line
      } else if (start_dev_dep && !end_dev_dep) {
        end_dev_dep = line
      } else if (start_opt_dep && !end_opt_dep) {
        end_opt_dep = line
      }
    }

    if (start_dep && end_dep && start_dev_dep && end_dev_dep) {
      break
    }
  }

  for (line = start_dep + 1; line < end_dep; line++) {
    var dep = getDepName(lines[line])

    if (dep) {
      makeLink(lines[line], dep)
    }
  }

  for (line = start_dev_dep + 1; line < end_dev_dep; line++) {
    dep = getDepName(lines[line])

    if (dep) {
      makeLink(lines[line], dep)
    }
  }

  for (line = start_opt_dep + 1; line < end_opt_dep; line++) {
    dep = getDepName(lines[line])

    if (dep) {
      makeLink(lines[line], dep)
    }
  }
}

chrome.extension.onMessage.addListener(function () {
  linkify()
});
<commit_msg>Make code less dumb, support more dependencies<commit_after>function makeLink(el, dep_name) {
  var link = '"https://npmjs.com/package/' + dep_name + '"'
  $(el).find('span')[0].innerHTML = '"' + dep_name + '"'
}

function getDepName(el) {
  var match = el.innerText.match(/\s*"([^"]+)".*$/)
  return match && match[1]
}

var block_start = /^\s*"(:?dev|peer|optional|bundled)?[dD]ependencies"\s*:\s*\{\s*$/
  , block_end = /}/

function linkify() {
  var lines = $('table.js-file-line-container td')

  if (!lines.length) return

  for (var line = 0; line < lines.length; line++) {
    if (block_start.test(lines[line].innerText)) {
      while (line < lines.length && !block_end.test(lines[++line].innerText)) {
        var dep = getDepName(lines[line])

        if (dep) {
          makeLink(lines[line], dep)
        }
      }
    }
  }
}

chrome.extension.onMessage.addListener(function () {
  linkify()
});
<|endoftext|>


<commit_before>draw_hitrate = function(hitrate_points, hitrate_lines, weapons) {
	/* calculate line data. For 0.0 values use the value of the predecessor */
	var n_weapons = hitrate_points.length;
	var visible = Array(n_weapons);
	for (w = 0; w < n_weapons; ++w) {
		var data = hitrate_points[w];
		var allZero = true;
		for (d = 0; d < data.length; ++d) {
			if (data[d] > 0.0) {
				allZero = false;
			}
		}
		visible[w] = !allZero;
	}

	var datapoints_h = hitrate_points[0].length;

	/* color scale */
	var c = pv.colors(
		"#3cf", // gauntlet
		"#ff0", // machine gun
		"orange", // shotgun
		"#d00", // rocket launcher
		"#c09", // plasma gun
		"#390", // grenade launcher
		"#fc0", // lighning gun
		"#5d0", // railgun
		"lightblue", // bfg
		"black" // teleport
	);

	var vis = new pv.Panel()
		.width(100 + datapoints_h * 30)
		.height(150)
		.bottom(20);

	vis.add(pv.Panel)
		.left(100)
		.data(hitrate_lines)
		.add(pv.Line)
			.strokeStyle(function() c(this.parent.index))
			.data(function(d) d)
			.bottom(function(d) d * 140)
			.left(function() this.index * 30)
		.add(pv.Dot)
			.data(function() hitrate_points[this.parent.index])
			.visible(function(d) d > 0);

	/* Legend */
	legende = vis.add(pv.Panel);

	legende.add(pv.Dot)
		.data(weapons)
		.left(10)
		.top(function() this.index * 12 + 10)
		.strokeStyle(null)
		.fillStyle(function(d) visible[this.index] ? c(this.index) : "#BBBBBB")
	.anchor("right").add(pv.Label)
		.text(function(d) d)
		.textStyle(function(d) visible[this.index] ? "black" : "#BBBBBB");

	vis.render();
}
<commit_msg>Tweaking hitrate diagram<commit_after>draw_hitrate = function(hitrate_points, hitrate_lines, weapons) {
	/* calculate line data. For 0.0 values use the value of the predecessor */
	var n_weapons = hitrate_points.length;
	var visible = Array(n_weapons);
	for (w = 0; w < n_weapons; ++w) {
		var data = hitrate_points[w];
		var allZero = true;
		for (d = 0; d < data.length; ++d) {
			if (data[d] > 0.0) {
				allZero = false;
			}
		}
		visible[w] = !allZero;
	}

	var datapoints_h = hitrate_points[0].length;
	var diagram_width = 600;
	var point_gap = diagram_width / datapoints_h;

	/* color scale */
	var c = pv.colors(
		"#3cf", // gauntlet
		"#ff0", // machine gun
		"orange", // shotgun
		"#e00", // rocket launcher
		"#c09", // plasma gun
		"#390", // grenade launcher
		"#cc3", // lighning gun
		"#5d0", // railgun
		"#0ff", // bfg
		"black" // teleport
	);

	var vis = new pv.Panel()
		.width(diagram_width + 120) // plus legend
		.height(150)
		.bottom(20);

	vis.add(pv.Panel)
		.left(110)
		.data(hitrate_lines)
		.add(pv.Line)
			.strokeStyle(function() c(this.parent.index))
			.data(function(d) d)
			.bottom(function(d) d * 140)
			.left(function() this.index * point_gap)
		.add(pv.Dot)
			.data(function() hitrate_points[this.parent.index])
			.visible(function(d) d > 0);

	/* Legend */
	legende = vis.add(pv.Panel);

	legende.add(pv.Dot)
		.data(weapons)
		.left(10)
		.top(function() this.index * 12 + 10)
		.strokeStyle(null)
		.fillStyle(function(d) visible[this.index] ? c(this.index) : "#BBBBBB")
	.anchor("right").add(pv.Label)
		.text(function(d) d)
		.textStyle(function(d) visible[this.index] ? "black" : "#BBBBBB");

	vis.render();
}
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2020 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const path = require('path');
const rollup = require('rollup');
const crypto = require('crypto')

const MNEMONIC = 'Rollup';
const PID = process.pid;

let worker;
try {
  worker = require('./worker');
} catch {
  // TODO: rely on the linker to link the first-party package
  const helper = process.env['BAZEL_NODE_RUNFILES_HELPER'];
  if (!helper) throw new Error('No runfiles helper and no @bazel/worker npm package');
  const runfiles = require(helper);
  const workerRequire = runfiles.resolve('build_bazel_rules_nodejs/packages/rollup/worker.js');
  if (!workerRequire)
    throw new Error(`build_bazel_rules_nodejs/packages/rollup/worker.js missing in runfiles ${
        JSON.stringify(runfiles.manifest)}, ${runfiles.dir}`);
  worker = require(workerRequire);
}

// Store the cache forever to re-use on each build
let cacheMap = Object.create(null);

// Generate a unique cache ID based on the input/outputOptions
function computeCacheKey(inputOptions, outputOptions) {
  const hash = crypto.createHash('sha256');
  const hashContent = JSON.stringify(inputOptions) + JSON.stringify(outputOptions);
  return hash.update(hashContent).digest('hex');
}

async function runRollup(cacheKeyData, inputOptions, outputOptions) {
  const cacheKey = computeCacheKey(cacheKeyData);

  let cache = cacheMap[cacheKey];

  const rollupStartTime = Date.now();

  const bundle = await rollup.rollup({...inputOptions, cache});

  const rollupEndTime = Date.now();
  worker.debug(
      `${MNEMONIC}[${PID}][${cacheKey}].rollup()`, (rollupEndTime - rollupStartTime) / 1000);

  cacheMap[cacheKey] = bundle.cache;

  try {
    await bundle.write(outputOptions);
  } catch (e) {
    worker.log(e);
    return false;
  }

  const bundleEndTime = Date.now();
  worker.debug(`${MNEMONIC}[${PID}][${cacheKey}].write()`, (bundleEndTime - rollupEndTime) / 1000);

  return true;
}

// Run rollup, will use + re-populate the cache
async function runRollupBundler(args /*, inputs */) {
  const {inputOptions, outputOptions} = await parseCLIArgs(args);

  return runRollup(inputOptions.input, inputOptions, outputOptions);
}

// Load the config file.
// Must be rollup-ed first to allow use of es6 within the config.
// See the rollup CLI version:
// https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L14
async function loadConfigFile(configFile) {
  const cjsConfigFile = configFile + '.cjs.js';

  // inputOptions: https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L21-L28
  const inputOptions = {
    external: id => (id[0] !== '.' && !path.isAbsolute(id)) || id.slice(-5, id.length) === '.json',
    input: configFile,
    treeshake: false,
    preserveSymlinks: true,
  };

  // outputOptions: https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L35-L38
  const outputOptions = {
    exports: 'named',
    format: 'cjs',
    file: cjsConfigFile,
  };

  await runRollup(configFile, inputOptions, outputOptions);

  // Read the config file:
  // https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L54-L61
  //
  // Supports:
  // * async results
  // * commonjs "default" export
  let config = await Promise.resolve(require(cjsConfigFile));
  if (config.default) {
    config = config.default;
  }

  // Does NOT support (unlike rollup CLI):
  // * factory function
  // * multiple configs for multiple outputs
  if (Array.isArray(config) || typeof config === 'function') {
    throw new Error('Arrays + factory configs unsupported');
  }

  return config;
}

// Processing of --environment CLI options into environment vars
// https://github.com/rollup/rollup/blob/v1.31.0/cli/run/index.ts#L50-L57
function extractEnvironmentVariables(vars) {
  vars.split(',').forEach(pair => {
    const [key, ...value] = pair.split(':');
    if (value.length) {
      process.env[key] = value.join(':');
    } else {
      process.env[key] = String(true);
    }
  });
}

// Parse a subset of supported CLI arguments required for the rollup_bundle rule API.
// Returns input/outputOptions for the rollup.bundle/write() API
//  input:  https://rollupjs.org/guide/en/#inputoptions-object
//  output: https://rollupjs.org/guide/en/#outputoptions-object
async function parseCLIArgs(args) {
  let inputOptions = {
    onwarn(...warnArgs) {
      worker.log(...warnArgs);
    },
  };

  let outputOptions = {};

  let configFile = null;

  // Input files to rollup
  let inputs = [];

  // Followed by suppported rollup CLI options
  for (let i = 0; i < args.length; i++) {
    const arg = args[i];

    // Non-option is assumed to be an input file
    if (!arg.startsWith('--')) {
      inputs.push(arg);
      continue;
    }

    const option = arg.slice(2);
    switch (option) {
      case 'config':
        configFile = path.resolve(args[++i]);
        break;

      case 'silent':
        inputOptions.onwarn = () => {};
        break;

      case 'format':
      case 'output.dir':
      case 'output.file':
      case 'sourcemap':
        outputOptions[option.replace('output.', '')] = args[++i];
        break;

      case 'preserveSymlinks':
        inputOptions[option] = true;
        break;

      // Common rollup CLI args, but not required for use
      case 'environment':
        extractEnvironmentVariables(args[++i]);
        break;

      default:
        throw new Error(`${MNEMONIC}: invalid or unsupported argument ${arg}`);
    }
  }

  // If outputting a directory then rollup_bundle.bzl passed a series
  // of name=path files as the input.
  // TODO: do some not have the =?
  if (outputOptions.dir) {
    inputs = inputs.reduce((m, nameInput) => {
      const [name, input] = nameInput.split('=', 2);
      m[name] = input;
      return m;
    }, {});
  }

  // Additional options passed via config file
  if (configFile) {
    const config = await loadConfigFile(configFile);

    if (config.output) {
      outputOptions = {...config.output, ...outputOptions};
    }

    inputOptions = {...config, ...inputOptions};

    // Delete from our copied inputOptions, not the config which
    // may be external and persisted across runs
    delete inputOptions.output;
  }

  // The inputs are the rule entry_point[s]
  inputOptions.input = inputs;

  return {inputOptions, outputOptions};
}

async function main(args) {
  // Bazel will pass a special argument to the program when it's running us as a worker
  if (worker.runAsWorker(args)) {
    worker.log(`Running ${MNEMONIC} as a Bazel worker`);

    worker.runWorkerLoop(runRollupBundler);
  } else {
    // Running standalone so stdout is available as usual
    console.log(`Running ${MNEMONIC} as a standalone process`);
    console.error(
        `Started a new process to perform this action. Your build might be misconfigured, try
      --strategy=${MNEMONIC}=worker`);

    // Parse the options from the bazel-supplied options file.
    // The first argument to the program is prefixed with '@'
    // because Bazel does that for param files. Strip it first.
    const paramFile = process.argv[2].replace(/^@/, '');
    const args = require('fs').readFileSync(paramFile, 'utf-8').trim().split('\n');

    return (await runRollupBundler(args)) ? 0 : 1;
  }
}

if (require.main === module) {
  main(process.argv.slice(2)).then(r => (process.exitCode = r));
}
<commit_msg>chore(rollup): cleanup incorrect method signature<commit_after>/**
 * @license
 * Copyright 2020 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const path = require('path');
const rollup = require('rollup');
const crypto = require('crypto')

const MNEMONIC = 'Rollup';
const PID = process.pid;

let worker;
try {
  worker = require('./worker');
} catch {
  // TODO: rely on the linker to link the first-party package
  const helper = process.env['BAZEL_NODE_RUNFILES_HELPER'];
  if (!helper) throw new Error('No runfiles helper and no @bazel/worker npm package');
  const runfiles = require(helper);
  const workerRequire = runfiles.resolve('build_bazel_rules_nodejs/packages/rollup/worker.js');
  if (!workerRequire)
    throw new Error(`build_bazel_rules_nodejs/packages/rollup/worker.js missing in runfiles ${
        JSON.stringify(runfiles.manifest)}, ${runfiles.dir}`);
  worker = require(workerRequire);
}

// Store the cache forever to re-use on each build
let cacheMap = Object.create(null);

// Generate a unique cache ID based on the given json data
function computeCacheKey(cacheKeyData) {
  const hash = crypto.createHash('sha256');
  const hashContent = JSON.stringify(cacheKeyData);
  return hash.update(hashContent).digest('hex');
}

async function runRollup(cacheKeyData, inputOptions, outputOptions) {
  const cacheKey = computeCacheKey(cacheKeyData);

  let cache = cacheMap[cacheKey];

  const rollupStartTime = Date.now();

  const bundle = await rollup.rollup({...inputOptions, cache});

  const rollupEndTime = Date.now();
  worker.debug(
      `${MNEMONIC}[${PID}][${cacheKey}].rollup()`, (rollupEndTime - rollupStartTime) / 1000);

  cacheMap[cacheKey] = bundle.cache;

  try {
    await bundle.write(outputOptions);
  } catch (e) {
    worker.log(e);
    return false;
  }

  const bundleEndTime = Date.now();
  worker.debug(`${MNEMONIC}[${PID}][${cacheKey}].write()`, (bundleEndTime - rollupEndTime) / 1000);

  return true;
}

// Run rollup, will use + re-populate the cache
async function runRollupBundler(args /*, inputs */) {
  const {inputOptions, outputOptions} = await parseCLIArgs(args);

  return runRollup(inputOptions.input, inputOptions, outputOptions);
}

// Load the config file.
// Must be rollup-ed first to allow use of es6 within the config.
// See the rollup CLI version:
// https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L14
async function loadConfigFile(configFile) {
  const cjsConfigFile = configFile + '.cjs.js';

  // inputOptions: https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L21-L28
  const inputOptions = {
    external: id => (id[0] !== '.' && !path.isAbsolute(id)) || id.slice(-5, id.length) === '.json',
    input: configFile,
    treeshake: false,
    preserveSymlinks: true,
  };

  // outputOptions: https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L35-L38
  const outputOptions = {
    exports: 'named',
    format: 'cjs',
    file: cjsConfigFile,
  };

  await runRollup(configFile, inputOptions, outputOptions);

  // Read the config file:
  // https://github.com/rollup/rollup/blob/v1.31.0/cli/run/loadConfigFile.ts#L54-L61
  //
  // Supports:
  // * async results
  // * commonjs "default" export
  let config = await Promise.resolve(require(cjsConfigFile));
  if (config.default) {
    config = config.default;
  }

  // Does NOT support (unlike rollup CLI):
  // * factory function
  // * multiple configs for multiple outputs
  if (Array.isArray(config) || typeof config === 'function') {
    throw new Error('Arrays + factory configs unsupported');
  }

  return config;
}

// Processing of --environment CLI options into environment vars
// https://github.com/rollup/rollup/blob/v1.31.0/cli/run/index.ts#L50-L57
function extractEnvironmentVariables(vars) {
  vars.split(',').forEach(pair => {
    const [key, ...value] = pair.split(':');
    if (value.length) {
      process.env[key] = value.join(':');
    } else {
      process.env[key] = String(true);
    }
  });
}

// Parse a subset of supported CLI arguments required for the rollup_bundle rule API.
// Returns input/outputOptions for the rollup.bundle/write() API
//  input:  https://rollupjs.org/guide/en/#inputoptions-object
//  output: https://rollupjs.org/guide/en/#outputoptions-object
async function parseCLIArgs(args) {
  let inputOptions = {
    onwarn(...warnArgs) {
      worker.log(...warnArgs);
    },
  };

  let outputOptions = {};

  let configFile = null;

  // Input files to rollup
  let inputs = [];

  // Followed by suppported rollup CLI options
  for (let i = 0; i < args.length; i++) {
    const arg = args[i];

    // Non-option is assumed to be an input file
    if (!arg.startsWith('--')) {
      inputs.push(arg);
      continue;
    }

    const option = arg.slice(2);
    switch (option) {
      case 'config':
        configFile = path.resolve(args[++i]);
        break;

      case 'silent':
        inputOptions.onwarn = () => {};
        break;

      case 'format':
      case 'output.dir':
      case 'output.file':
      case 'sourcemap':
        outputOptions[option.replace('output.', '')] = args[++i];
        break;

      case 'preserveSymlinks':
        inputOptions[option] = true;
        break;

      // Common rollup CLI args, but not required for use
      case 'environment':
        extractEnvironmentVariables(args[++i]);
        break;

      default:
        throw new Error(`${MNEMONIC}: invalid or unsupported argument ${arg}`);
    }
  }

  // If outputting a directory then rollup_bundle.bzl passed a series
  // of name=path files as the input.
  // TODO: do some not have the =?
  if (outputOptions.dir) {
    inputs = inputs.reduce((m, nameInput) => {
      const [name, input] = nameInput.split('=', 2);
      m[name] = input;
      return m;
    }, {});
  }

  // Additional options passed via config file
  if (configFile) {
    const config = await loadConfigFile(configFile);

    if (config.output) {
      outputOptions = {...config.output, ...outputOptions};
    }

    inputOptions = {...config, ...inputOptions};

    // Delete from our copied inputOptions, not the config which
    // may be external and persisted across runs
    delete inputOptions.output;
  }

  // The inputs are the rule entry_point[s]
  inputOptions.input = inputs;

  return {inputOptions, outputOptions};
}

async function main(args) {
  // Bazel will pass a special argument to the program when it's running us as a worker
  if (worker.runAsWorker(args)) {
    worker.log(`Running ${MNEMONIC} as a Bazel worker`);

    worker.runWorkerLoop(runRollupBundler);
  } else {
    // Running standalone so stdout is available as usual
    console.log(`Running ${MNEMONIC} as a standalone process`);
    console.error(
        `Started a new process to perform this action. Your build might be misconfigured, try
      --strategy=${MNEMONIC}=worker`);

    // Parse the options from the bazel-supplied options file.
    // The first argument to the program is prefixed with '@'
    // because Bazel does that for param files. Strip it first.
    const paramFile = process.argv[2].replace(/^@/, '');
    const args = require('fs').readFileSync(paramFile, 'utf-8').trim().split('\n');

    return (await runRollupBundler(args)) ? 0 : 1;
  }
}

if (require.main === module) {
  main(process.argv.slice(2)).then(r => (process.exitCode = r));
}
<|endoftext|>


<commit_before>define( ['dojo/_base/array',
         'JBrowse/Util',
         './Util',
         'JBrowse/Model/SimpleFeature'
        ],
        function( array, Util, BAMUtil, SimpleFeature ) {

var SEQRET_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N'];
var CIGAR_DECODER  = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?'];

var readInt   = BAMUtil.readInt;
var readShort = BAMUtil.readShort;
var readFloat = BAMUtil.readFloat;

var counter = 0;

var Feature = Util.fastDeclare(
{
    constructor: function( args ) {
        this.store = args.store;
        this.file  = args.file;
        this.data  = {
            type: 'match',
            source: args.store.source
        };
        this.bytes = {
            start: args.bytes.start,
            end: args.bytes.end,
            byteArray: args.bytes.byteArray
        };

        this._coreParse();
    },

    get: function( field ) {
        field = field.toLowerCase();
        return field in this.data ? this.data[field] : // maybe already parsed
            function() {
                var v = this.data[field] = this[field] ? this[field]()                       : // maybe we have a special parser for it
                                           this._flagMasks[field] ? this._parseFlag( field ) : // or is it a flag?
                                           this._parseTag( field );                            // otherwise, must be a tag
                return v;
            }.call(this);
    },

    tags: function() {
        return this.get('_tags');
    },

    _tags: function() {
        this._parseAllTags();
        var tags = [ 'seq', 'seq_reverse_complemented', 'unmapped' ];
        if( ! this.get('unmapped') )
            tags.push( 'start', 'end', 'strand', 'score', 'qual', 'MQ', 'CIGAR', 'length_on_ref' );
        if( this.get('multi_segment_template') ) {
            tags.push( 'multi_segment_all_aligned',
                       'multi_segment_next_segment_unmapped',
                       'multi_segment_next_segment_reversed',
                       'multi_segment_first',
                       'multi_segment_last',
                       'secondary_alignment',
                       'qc_failed',
                       'duplicate',
                       'next_segment_position'
                     );
        }

        var d = this.data;
        for( var k in d ) {
            if( d.hasOwnProperty( k ) && k[0] != '_' )
                tags.push( k );
        }

        var seen = {};
        tags = array.filter( tags, function(t) {
            if( t in this.data && this.data[t] === undefined )
                return false;

            var s = seen[t];
            seen[t] = true;
            return ! s;
        },this);

        return tags;
    },

    parent: function() {
        return undefined;
    },

    children: function() {
        return this.get('subfeatures');
    },

    id: function() {
        return this.get('name')+'/'+this.get('MD')+'/'+this.get('CIGAR')+'/'+this.get('start');
    },

    // special parsers
    /**
     * Mapping quality score.
     */
    mq: function() {
        var mq = (this.get('_bin_mq_nl') & 0xff00) >> 8;
        return mq == 255 ? undefined : mq;
    },
    score: function() {
        return this.get('MQ');
    },
    qual: function() {
        if( this.get('unmapped') )
            return undefined;

        var qseq = [];
        var byteArray = this.bytes.byteArray;
        var p = this.bytes.start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op')*4 + this.get('_seq_bytes');
        var lseq = this.get('seq_length');
        for (var j = 0; j < lseq; ++j) {
            qseq.push( byteArray[p + j] );
        }
        return qseq.join(' ');
    },
    strand: function() {
        // var xs = this.get('XS');
        // return xs ? ( xs == '-' ? -1 : 1 ) :
        return this.get('seq_reverse_complemented') ? -1 :  1;
    },
    /**
     * Length in characters of the read name.
     */
    _l_read_name: function() {
        return this.get('_bin_mq_nl') & 0xff;
    },
    /**
     * number of bytes in the sequence field
     */
    _seq_bytes: function() {
        return (this.get('seq_length') + 1) >> 1;
    },
    seq: function() {
        var seq = '';
        var byteArray = this.bytes.byteArray;
        var p = this.bytes.start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op')*4;
        var seqBytes = this.get('_seq_bytes');
        for (var j = 0; j < seqBytes; ++j) {
            var sb = byteArray[p + j];
            seq += SEQRET_DECODER[(sb & 0xf0) >> 4];
            seq += SEQRET_DECODER[(sb & 0x0f)];
        }
        return seq;
    },
    name: function() {
        return this.get('read_name');
    },
    read_name: function() {
        var byteArray = this.bytes.byteArray;
        var readName = '';
        var nl = this.get('_l_read_name');
        var p = this.bytes.start + 36;
        for (var j = 0; j < nl-1; ++j) {
            readName += String.fromCharCode(byteArray[p+j]);
        }
        return readName;
    },
    _n_cigar_op: function() {
        return this.get('_flag_nc') & 0xffff;
    },
    cigar: function() {
        if( this.get('unmapped') )
            return undefined;

        var byteArray   = this.bytes.byteArray;
        var numCigarOps = this.get('_n_cigar_op');
        var p = this.bytes.start + 36 + this.get('_l_read_name');
        var cigar = '';
        var lref = 0;
        for (var c = 0; c < numCigarOps; ++c) {
            var cigop = readInt(byteArray, p);
            var lop = cigop >> 4;
            var op = CIGAR_DECODER[cigop & 0xf];
            cigar = cigar + lop + op;
            p += 4;
        }
        return cigar;
    },
    next_segment_position: function() {
        var nextRefID = this.get('_next_refID');
        var nextSegment = this.file.indexToChr[nextRefID];
        if( nextSegment )
            return nextSegment.name+':'+this.get('_next_pos');
        else
            return undefined;
    },
    subfeatures: function() {
        if( ! this.store.createSubfeatures )
            return undefined;

        var cigar = this.get('CIGAR');
        if( cigar )
            return this._cigarToSubfeats( cigar );

        return undefined;
    },
    length_on_ref: function() {
        if( this.get('unmapped') )
            return undefined;

        var numbers = this.get('CIGAR').match(/\d+(?=[MDN=X])/ig);
        var sum = 0;
        for( var i = 0; i<numbers.length; i++ )
            sum += parseInt( numbers[i] );
        return sum;
    },
    _flags: function() {
        return (this.data._flag_nc & 0xffff0000) >> 16;
    },
    end: function() {
        return this.get('start') + ( this.get('length_on_ref') || this.get('seq_length') || undefined );
    },

    seq_id: function() {
        if( this.get('unmapped') )
            return undefined;

        return ( this.file.indexToChr[ this._refID ] || {} ).name;
    },

    /**
     * parse the core data: start, end, strand, etc
     */
    _coreParse: function() {
        var byteArray = this.bytes.byteArray;
        var blockStart = this.bytes.start;

        var tempBytes = new Uint8Array( 36 );
        for( var i = 0; i<36; i++ ) {
            tempBytes[i] = byteArray[i+blockStart];
        }
        var ints = new Int32Array( tempBytes.buffer );

        this._refID = ints[1];
        var start = this.data.start = ints[2];
        this.data._bin_mq_nl = ints[3];
        this.data._flag_nc   = ints[4];
        this.data.seq_length = ints[5];
        this.data._next_refID = ints[6];
        this.data._next_pos   = ints[7];
        this.data.template_length = ints[8];
    },

    /**
     * Get the value of a tag, parsing the tags as far as necessary.
     * Only called if we have not already parsed that field.
     */
    _parseTag: function( tagName ) {
        var byteArray = this.bytes.byteArray;
        var p = this.bytes.start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op')*4 + this.get('_seq_bytes') + this.get('seq_length');
        var blockEnd = this.bytes.end;
        while( p < blockEnd && !(tag == tagName)) { // really should be blockEnd - 3, but this works too and is faster
            var tag = String.fromCharCode( byteArray[p] ) + String.fromCharCode(byteArray[p + 1] );
            var origType = String.fromCharCode( byteArray[p + 2] );
            var type = origType.toLowerCase();
            p += 3;

            var value;
            if (type == 'a') {
                value = String.fromCharCode( byteArray[p] );
                p += 1;
            } else if (type == 'i' ) {
                value = readInt(byteArray, p );
                p += 4;
            } else if (type == 'c' ) {
                value = byteArray[p];
                p += 1;
            } else if (type == 's' ) {
                value = readShort(byteArray, p);
                p += 2;
            } else if (type == 'f') {
                value = readFloat( byteArray, p );
                p += 4;
            } else if ( type == 'z' || type == 'h' ) {
                value = '';
                while( p <= blockEnd ) {
                    var cc = byteArray[p++];
                    if( cc == 0 ) {
                        break;
                    }
                    else {
                        value += String.fromCharCode(cc);
                    }
                }
            } else {
                console.warn( "Unknown BAM tag type '"+origType
                              +'\', tags for '+(readName||'(unnamed read)')
                              +' may be incomplete'
                            );
                value = undefined;
                p = blockEnd+1; // stop parsing tags
            }
            if( tag == tagName )
                return value;
            else
                this.data[tag] = value;
        }
        return undefined;
    },
    _parseAllTags: function() {
        if( ! this._allTagsParsed )
            this._parseTag(); // calling _parseTag with no arg just parses
                              // all the tags and returns the last one

        this._allTagsParsed = true;
    },

    _flagMasks: {
        multi_segment_template:              0x1,
        multi_segment_all_aligned:           0x2,
        unmapped:                            0x4,
        multi_segment_next_segment_unmapped: 0x8,
        seq_reverse_complemented:            0x10,
        multi_segment_next_segment_reversed: 0x20,
        multi_segment_first:                 0x40,
        multi_segment_last:                  0x80,
        secondary_alignment:                 0x100,
        qc_failed:                           0x200,
        duplicate:                           0x400
    },

    _parseFlag: function( flagName ) {
        return !!( this.get('_flags') & this._flagMasks[flagName] );
    },

    _parseCigar: function( cigar ) {
        return array.map( cigar.match(/\d+\D/g), function( op ) {
           return [ op.match(/\D/)[0].toUpperCase(), parseInt( op ) ];
        });
    },

    /**
     *  take a cigar string, and initial position, return an array of subfeatures
     */
    _cigarToSubfeats: function(cigar)    {
        var subfeats = [];
        var min = this.get('start');
        var max;
        var ops = this._parseCigar( cigar );
        for (var i = 0; i < ops.length; i++)  {
            var lop = ops[i][1];
            var op = ops[i][0];  // operation type
            // converting "=" to "E" to avoid possible problems later with non-alphanumeric type name
            if (op === "=")  { op = "E"; }

            switch (op) {
            case 'M':
            case 'D':
            case 'N':
            case 'E':
            case 'X':
                max = min + lop;
                break;
            case 'I':
                max = min;
                break;
            case 'P':  // not showing padding deletions (possibly change this later -- could treat same as 'I' ?? )
            case 'H':  // not showing hard clipping (since it's unaligned, and offset arg meant to be beginning of aligned part)
            case 'S':  // not showing soft clipping (since it's unaligned, and offset arg meant to be beginning of aligned part)
                break;
                // other possible cases
            }
            if( op !== 'N' ) {
                var subfeat = new SimpleFeature({
                    data: {
                    type: op,
                        start: min,
                        end: max,
                        strand: this.get('strand'),
                        cigar_op: lop+op
                    },
                    parent: this
                });
                subfeats.push(subfeat);
            }
            min = max;
        }
        return subfeats;
    }

});

return Feature;
});<commit_msg>make lazy bam tag uniqification case-insensitive<commit_after>define( ['dojo/_base/array',
         'JBrowse/Util',
         './Util',
         'JBrowse/Model/SimpleFeature'
        ],
        function( array, Util, BAMUtil, SimpleFeature ) {

var SEQRET_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N'];
var CIGAR_DECODER  = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?'];

var readInt   = BAMUtil.readInt;
var readShort = BAMUtil.readShort;
var readFloat = BAMUtil.readFloat;

var counter = 0;

var Feature = Util.fastDeclare(
{
    constructor: function( args ) {
        this.store = args.store;
        this.file  = args.file;
        this.data  = {
            type: 'match',
            source: args.store.source
        };
        this.bytes = {
            start: args.bytes.start,
            end: args.bytes.end,
            byteArray: args.bytes.byteArray
        };

        this._coreParse();
    },

    get: function( field ) {
        field = field.toLowerCase();
        return field in this.data ? this.data[field] : // maybe already parsed
            function() {
                var v = this.data[field] = this[field] ? this[field]()                       : // maybe we have a special parser for it
                                           this._flagMasks[field] ? this._parseFlag( field ) : // or is it a flag?
                                           this._parseTag( field );                            // otherwise, must be a tag
                return v;
            }.call(this);
    },

    tags: function() {
        return this.get('_tags');
    },

    _tags: function() {
        this._parseAllTags();

        var tags = [ 'seq', 'seq_reverse_complemented', 'unmapped' ];
        if( ! this.get('unmapped') )
            tags.push( 'start', 'end', 'strand', 'score', 'qual', 'MQ', 'CIGAR', 'length_on_ref' );
        if( this.get('multi_segment_template') ) {
            tags.push( 'multi_segment_all_aligned',
                       'multi_segment_next_segment_unmapped',
                       'multi_segment_next_segment_reversed',
                       'multi_segment_first',
                       'multi_segment_last',
                       'secondary_alignment',
                       'qc_failed',
                       'duplicate',
                       'next_segment_position'
                     );
        }

        var d = this.data;
        for( var k in d ) {
            if( d.hasOwnProperty( k ) && k[0] != '_' )
                tags.push( k );
        }

        var seen = {};
        tags = array.filter( tags, function(t) {
            if( t in this.data && this.data[t] === undefined )
                return false;

            var lt = t.toLowerCase();
            var s = seen[lt];
            seen[lt] = true;
            return ! s;
        },this);

        return tags;
    },

    parent: function() {
        return undefined;
    },

    children: function() {
        return this.get('subfeatures');
    },

    id: function() {
        return this.get('name')+'/'+this.get('MD')+'/'+this.get('CIGAR')+'/'+this.get('start');
    },

    // special parsers
    /**
     * Mapping quality score.
     */
    mq: function() {
        var mq = (this.get('_bin_mq_nl') & 0xff00) >> 8;
        return mq == 255 ? undefined : mq;
    },
    score: function() {
        return this.get('MQ');
    },
    qual: function() {
        if( this.get('unmapped') )
            return undefined;

        var qseq = [];
        var byteArray = this.bytes.byteArray;
        var p = this.bytes.start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op')*4 + this.get('_seq_bytes');
        var lseq = this.get('seq_length');
        for (var j = 0; j < lseq; ++j) {
            qseq.push( byteArray[p + j] );
        }
        return qseq.join(' ');
    },
    strand: function() {
        // var xs = this.get('XS');
        // return xs ? ( xs == '-' ? -1 : 1 ) :
        return this.get('seq_reverse_complemented') ? -1 :  1;
    },
    /**
     * Length in characters of the read name.
     */
    _l_read_name: function() {
        return this.get('_bin_mq_nl') & 0xff;
    },
    /**
     * number of bytes in the sequence field
     */
    _seq_bytes: function() {
        return (this.get('seq_length') + 1) >> 1;
    },
    seq: function() {
        var seq = '';
        var byteArray = this.bytes.byteArray;
        var p = this.bytes.start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op')*4;
        var seqBytes = this.get('_seq_bytes');
        for (var j = 0; j < seqBytes; ++j) {
            var sb = byteArray[p + j];
            seq += SEQRET_DECODER[(sb & 0xf0) >> 4];
            seq += SEQRET_DECODER[(sb & 0x0f)];
        }
        return seq;
    },
    name: function() {
        return this.get('read_name');
    },
    read_name: function() {
        var byteArray = this.bytes.byteArray;
        var readName = '';
        var nl = this.get('_l_read_name');
        var p = this.bytes.start + 36;
        for (var j = 0; j < nl-1; ++j) {
            readName += String.fromCharCode(byteArray[p+j]);
        }
        return readName;
    },
    _n_cigar_op: function() {
        return this.get('_flag_nc') & 0xffff;
    },
    cigar: function() {
        if( this.get('unmapped') )
            return undefined;

        var byteArray   = this.bytes.byteArray;
        var numCigarOps = this.get('_n_cigar_op');
        var p = this.bytes.start + 36 + this.get('_l_read_name');
        var cigar = '';
        var lref = 0;
        for (var c = 0; c < numCigarOps; ++c) {
            var cigop = readInt(byteArray, p);
            var lop = cigop >> 4;
            var op = CIGAR_DECODER[cigop & 0xf];
            cigar = cigar + lop + op;
            p += 4;
        }
        return cigar;
    },
    next_segment_position: function() {
        var nextRefID = this.get('_next_refID');
        var nextSegment = this.file.indexToChr[nextRefID];
        if( nextSegment )
            return nextSegment.name+':'+this.get('_next_pos');
        else
            return undefined;
    },
    subfeatures: function() {
        if( ! this.store.createSubfeatures )
            return undefined;

        var cigar = this.get('CIGAR');
        if( cigar )
            return this._cigarToSubfeats( cigar );

        return undefined;
    },
    length_on_ref: function() {
        if( this.get('unmapped') )
            return undefined;

        var numbers = this.get('CIGAR').match(/\d+(?=[MDN=X])/ig);
        var sum = 0;
        for( var i = 0; i<numbers.length; i++ )
            sum += parseInt( numbers[i] );
        return sum;
    },
    _flags: function() {
        return (this.data._flag_nc & 0xffff0000) >> 16;
    },
    end: function() {
        return this.get('start') + ( this.get('length_on_ref') || this.get('seq_length') || undefined );
    },

    seq_id: function() {
        if( this.get('unmapped') )
            return undefined;

        return ( this.file.indexToChr[ this._refID ] || {} ).name;
    },

    /**
     * parse the core data: start, end, strand, etc
     */
    _coreParse: function() {
        var byteArray = this.bytes.byteArray;
        var blockStart = this.bytes.start;

        var tempBytes = new Uint8Array( 36 );
        for( var i = 0; i<36; i++ ) {
            tempBytes[i] = byteArray[i+blockStart];
        }
        var ints = new Int32Array( tempBytes.buffer );

        this._refID = ints[1];
        var start = this.data.start = ints[2];
        this.data._bin_mq_nl = ints[3];
        this.data._flag_nc   = ints[4];
        this.data.seq_length = ints[5];
        this.data._next_refID = ints[6];
        this.data._next_pos   = ints[7];
        this.data.template_length = ints[8];
    },

    /**
     * Get the value of a tag, parsing the tags as far as necessary.
     * Only called if we have not already parsed that field.
     */
    _parseTag: function( tagName ) {
        var byteArray = this.bytes.byteArray;
        var p = this.bytes.start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op')*4 + this.get('_seq_bytes') + this.get('seq_length');
        var blockEnd = this.bytes.end;
        while( p < blockEnd && !(tag == tagName)) { // really should be blockEnd - 3, but this works too and is faster
            var tag = String.fromCharCode( byteArray[p] ) + String.fromCharCode(byteArray[p + 1] );
            var origType = String.fromCharCode( byteArray[p + 2] );
            var type = origType.toLowerCase();
            p += 3;

            var value;
            if (type == 'a') {
                value = String.fromCharCode( byteArray[p] );
                p += 1;
            } else if (type == 'i' ) {
                value = readInt(byteArray, p );
                p += 4;
            } else if (type == 'c' ) {
                value = byteArray[p];
                p += 1;
            } else if (type == 's' ) {
                value = readShort(byteArray, p);
                p += 2;
            } else if (type == 'f') {
                value = readFloat( byteArray, p );
                p += 4;
            } else if ( type == 'z' || type == 'h' ) {
                value = '';
                while( p <= blockEnd ) {
                    var cc = byteArray[p++];
                    if( cc == 0 ) {
                        break;
                    }
                    else {
                        value += String.fromCharCode(cc);
                    }
                }
            } else {
                console.warn( "Unknown BAM tag type '"+origType
                              +'\', tags for '+(readName||'(unnamed read)')
                              +' may be incomplete'
                            );
                value = undefined;
                p = blockEnd+1; // stop parsing tags
            }
            if( tag == tagName )
                return value;
            else
                this.data[tag] = value;
        }
        return undefined;
    },
    _parseAllTags: function() {
        if( ! this._allTagsParsed )
            this._parseTag(); // calling _parseTag with no arg just parses
                              // all the tags and returns the last one

        this._allTagsParsed = true;
    },

    _flagMasks: {
        multi_segment_template:              0x1,
        multi_segment_all_aligned:           0x2,
        unmapped:                            0x4,
        multi_segment_next_segment_unmapped: 0x8,
        seq_reverse_complemented:            0x10,
        multi_segment_next_segment_reversed: 0x20,
        multi_segment_first:                 0x40,
        multi_segment_last:                  0x80,
        secondary_alignment:                 0x100,
        qc_failed:                           0x200,
        duplicate:                           0x400
    },

    _parseFlag: function( flagName ) {
        return !!( this.get('_flags') & this._flagMasks[flagName] );
    },

    _parseCigar: function( cigar ) {
        return array.map( cigar.match(/\d+\D/g), function( op ) {
           return [ op.match(/\D/)[0].toUpperCase(), parseInt( op ) ];
        });
    },

    /**
     *  take a cigar string, and initial position, return an array of subfeatures
     */
    _cigarToSubfeats: function(cigar)    {
        var subfeats = [];
        var min = this.get('start');
        var max;
        var ops = this._parseCigar( cigar );
        for (var i = 0; i < ops.length; i++)  {
            var lop = ops[i][1];
            var op = ops[i][0];  // operation type
            // converting "=" to "E" to avoid possible problems later with non-alphanumeric type name
            if (op === "=")  { op = "E"; }

            switch (op) {
            case 'M':
            case 'D':
            case 'N':
            case 'E':
            case 'X':
                max = min + lop;
                break;
            case 'I':
                max = min;
                break;
            case 'P':  // not showing padding deletions (possibly change this later -- could treat same as 'I' ?? )
            case 'H':  // not showing hard clipping (since it's unaligned, and offset arg meant to be beginning of aligned part)
            case 'S':  // not showing soft clipping (since it's unaligned, and offset arg meant to be beginning of aligned part)
                break;
                // other possible cases
            }
            if( op !== 'N' ) {
                var subfeat = new SimpleFeature({
                    data: {
                    type: op,
                        start: min,
                        end: max,
                        strand: this.get('strand'),
                        cigar_op: lop+op
                    },
                    parent: this
                });
                subfeats.push(subfeat);
            }
            min = max;
        }
        return subfeats;
    }

});

return Feature;
});<|endoftext|>


<commit_before>import Http from "../services/Http";

export const state = () => ({
    user: null,
    count: 0,
});

export const mutations = {
    user(state, user) {
        state.user = user;
    },

    count(state, count) {
        state.count = count
    }
};

export const actions = {
    async refresh({commit}) {
        let user = await Http.for('user').get();

        commit('user', Object.keys(user).length === 0 ? null : user);
    },

    async refreshUserCount({commit}) {
        let data = await Http.for('leaderboard').get('users');

        commit('count', data.count);
    },

    async login({commit, dispatch}, {username, password}) {
        try {
            await Http.for('user').post('login', {username, password});

            await dispatch('refresh');

            dispatch('toast/add', {type: 'success', message: 'Welcome back to DevWars!'}, {root: true});

            dispatch('navigate', '/dashboard', {root: true});
        } catch (e) {
            dispatch('toast/error', e.response.data, {root: true});

            commit('user', null)
        }
    },

    async register({commit, dispatch}, registration) {
        try {
            await Http.for('user').post('register', registration);

            await dispatch('refresh');

            dispatch('navigate', '/dashboard', {root: true});
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async logout({commit, dispatch}) {
        await Http.for('user').post('logout');

        await dispatch('navigate', '/', {root: true});

        commit('user', null);
    },

    async settings({commit, dispatch}, data) {
        try {
            let user = await Http.for('user/settings').post(data);

            commit('user', user);
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async password({commit, dispatch}, data) {
        try {
            await Http.for('user/reset/change').put(data);

            dispatch('toast/success', `We've updated your password!`, {root: true});
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async email({dispatch, commit}, data) {
        try {
            let user = await Http.for('user/settings').post('email', data);

            commit('user', user);

            await dispatch('toast/success', `We've updated your email, please go verify your email.`, {root: true});
            await dispatch('navigate', '/pending', {root: true});
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async forgot({dispatch, commit}, email) {
        await Http.for('user/reset').save({email});

        dispatch('toast/success', `Check your email for a guide to reset your password.`, {root: true});
    },

    async resetByKey({dispatch, commit}, data) {
        await Http.for('user/reset').put({}, data);

        dispatch('toast/success', `We've updated your password, give it a go!`, {root: true});
    }
};
<commit_msg>updated email to usernameOrEmail<commit_after>import Http from "../services/Http";

export const state = () => ({
    user: null,
    count: 0,
});

export const mutations = {
    user(state, user) {
        state.user = user;
    },

    count(state, count) {
        state.count = count
    }
};

export const actions = {
    async refresh({commit}) {
        let user = await Http.for('user').get();

        commit('user', Object.keys(user).length === 0 ? null : user);
    },

    async refreshUserCount({commit}) {
        let data = await Http.for('leaderboard').get('users');

        commit('count', data.count);
    },

    async login({commit, dispatch}, {username, password}) {
        try {
            await Http.for('user').post('login', {username, password});

            await dispatch('refresh');

            dispatch('toast/add', {type: 'success', message: 'Welcome back to DevWars!'}, {root: true});

            dispatch('navigate', '/dashboard', {root: true});
        } catch (e) {
            dispatch('toast/error', e.response.data, {root: true});

            commit('user', null)
        }
    },

    async register({commit, dispatch}, registration) {
        try {
            await Http.for('user').post('register', registration);

            await dispatch('refresh');

            dispatch('navigate', '/dashboard', {root: true});
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async logout({commit, dispatch}) {
        await Http.for('user').post('logout');

        await dispatch('navigate', '/', {root: true});

        commit('user', null);
    },

    async settings({commit, dispatch}, data) {
        try {
            let user = await Http.for('user/settings').post(data);

            commit('user', user);
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async password({commit, dispatch}, data) {
        try {
            await Http.for('user/reset/change').put(data);

            dispatch('toast/success', `We've updated your password!`, {root: true});
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async email({dispatch, commit}, data) {
        try {
            let user = await Http.for('user/settings').post('email', data);

            commit('user', user);

            await dispatch('toast/success', `We've updated your email, please go verify your email.`, {root: true});
            await dispatch('navigate', '/pending', {root: true});
        } catch (e) {
            dispatch('toast/errors', e, {root: true});
        }
    },

    async forgot({dispatch, commit}, email) {
        await Http.for('user/reset').save({username_or_email: email});

        dispatch('toast/success', `Check your email for a guide to reset your password.`, {root: true});
    },

    async resetByKey({dispatch, commit}, data) {
        await Http.for('user/reset').put({}, data);

        dispatch('toast/success', `We've updated your password, give it a go!`, {root: true});
    }
};
<|endoftext|>


<commit_before>define([
  // Application.
  "app"
],

// Map dependencies from above array.
function(app) {

  // Create a new module.
  var ParkingNonDowntown = app.module();

  ParkingNonDowntown.Views.Calculator = Backbone.View.extend({

      tagName:    "section",
      className:  "content",
      template:   "panels/requirements/city/parking_non_downtown",

    serialize: function() {
      var model;
      var answers = {};

      for (m in this.collection.models) {
        model = this.collection.models[m];
        answers[model.get("name")] = model.get("value");
      }
      return {
        answers: answers
        // formatted fee
      };
    },

    cleanup: function() {
      this.collection.off(null, null, this);
    },

    // Calculates the number of spaces a business must provide.
    // Require the business sub-type and other fields specific to that business.
    calculateSpaces: function (business_subtype) {

      //console.log('calculating spaces for ', business_subtype);

      var spaces;

      switch (business_subtype) {
        case 'parking_auto':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 400);
          return spaces;
          break;

        case 'parking_service_stations':
          var service_bays = this.collection.getAnswer("service_bays"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(service_bays * 3) + employees;
          return spaces;
          break;

        case 'parking_banks_with_atms':
          var square_feet = this.collection.getAnswer("square_feet"),
            atms = this.collection.getAnswer("ATMs"),
            spaces = Math.round((square_feet / 400) + (atms * 1.5));
          return spaces;
          break;

        case 'parking_banks_no_atms':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 400);
          return spaces;
          break;

        case 'parking_billiard':
          var tables = this.collection.getAnswer("tables"),
            spaces = Math.round(tables * 1.5);
          return spaces;
          break;

        case 'parking_child_homes':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(beds / 5) + employees;
          return spaces;
          break;

        case 'parking_daycare_foster':
          var guests = this.collection.getAnswer("guests"),
            spaces = Math.round(guests / 5) + 1;
          return spaces;
          break;

        case 'parking_communication':
          var square_feet = this.collection.getAnswer("square_feet"),
            // the following line contained a reference to field_1, swapped out for square_feet
            spaces = Math.round(square_feet / 1000);
          return spaces;
          break;

        case 'parking_lower_schools':
          var employees = this.collection.getAnswer("employees"),
            spaces = employees;
          return spaces;
          break;

        case 'parking_high_schools':
          var students = this.collection.getAnswer("students"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(students / 10) + employees;
          return spaces;
          break;

        case 'parking_colleges':
          var students = this.collection.getAnswer("students"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(students / 3) + employees;
          return spaces;
          break;

        case 'parking_multi_program_fitness':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = (square_feet / 100),
            spaces = (square_feet > 15000) ? Math.round(spaces * 1.1) : Math.round(spaces);
          return spaces;
          break;

        case 'parking_single_program_fitness':
          var aerobics_area = this.collection.getAnswer("aerobics_area"),
            basketball_volleyball_occupancy = this.collection.getAnswer("basketball_volleyball_occupancy"),
            pool_lanes = this.collection.getAnswer("pool_lanes"),
            pool_non_water_area = this.collection.getAnswer("pool_non_water_area"),
            weights_area = this.collection.getAnswer("weights_area"),
            square_feet = this.collection.getAnswer("square_feet"),
            spaces = (aerobics_area / 50) + (basketball_volleyball_occupancy / 3) + (pool_lanes * 2) + (pool_non_water_area / 300) + (weights_area / 250),
            spaces = (square_feet > 15000) ? Math.round(spaces * 1.1) : Math.round(spaces);
          return spaces;
          break;

        case 'parking_food':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 120);
          return spaces;
          break;

        case 'parking_take_out':
          var square_feet = this.collection.getAnswer("square_feet"),
            take_out_area = this.collection.getAnswer("take_out_area"),
            spaces = Math.round((square_feet / 120) + (take_out_area / 50));
          return spaces;
          break;

        case 'parking_funeral':
          var seats = this.collection.getAnswer("seats"),
            spaces = Math.round(seats / 5);
          return spaces;
          break;

        case 'parking_furn_repair':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 500);
          return spaces;
          break;

        case 'parking_halls_with_seats':
          var seats = this.collection.getAnswer("seats"),
            spaces = Math.round(seats / 3.5);
          return spaces;
          break;

        case 'parking_halls_no_seats':
          var max_occupancy_load = this.collection.getAnswer("max_occupancy_load"),
            spaces = Math.round(max_occupancy_load / 3);
          return spaces;
          break;

        case 'parking_household':
          var sales_area = this.collection.getAnswer("sales_area"),
            spaces = Math.round(sales_area / 800);
          return spaces;
          break;

        case 'parking_laundry':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 200);
          return spaces;
          break;

        case 'parking_community_care':
          var guests = this.collection.getAnswer("guests"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((guests / 5) + 1 + employees);
          return spaces;
          break;

        case 'parking_hotels':
          var hotel_units = this.collection.getAnswer("hotel_units"),
            spaces = hotel_units + 1;
          return spaces;
          break;

        case 'parking_convalescent':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((beds / 5) + employees);
          return spaces;
          break;

        case 'parking_hospitals':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((beds / 5) + employees);
          return spaces;
          break;

        case 'parking_medical_offices':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 200);
          return spaces;
          break;

        case 'parking_physical_therapy':
          var square_feet = this.collection.getAnswer("square_feet"),
            pool_water_area = this.collection.getAnswer("pool_water_area"),
            spaces = Math.round((square_feet / 200) + (pool_water_area / 50));
          return spaces;
          break;

        case 'parking_office':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 300);
          return spaces;
          break;

        case 'parking_plants':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 500);
          return spaces;
          break;

        case 'parking_research':
          var square_feet = this.collection.getAnswer("square_feet"),
            employees = this.collection.getAnswer("employees"),
            spaces_by_square_footage = Math.round(square_feet / 325),
            spaces_by_employees = Math.round(employees / 2);
          return (spaces_by_square_footage >= spaces_by_employees) ? spaces_by_square_footage : spaces_by_employees;
          break;

        case 'parking_retail':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 250);
          return spaces;
          break;

        case 'parking_boarding':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((beds / 5) + employees);
          return spaces;
          break;

        case 'parking_institutions':
          var guests = this.collection.getAnswer("guests"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((guests / 5) + employees);
          return spaces;
          break;

        case 'parking_nursing':
          var guests = this.collection.getAnswer("guests"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((guests / 5) + employees + 1);
          return spaces;
          break;

        case 'parking_theaters':
          var seats = this.collection.getAnswer("seats");
          if ((seats - 350) > 0) {
            // if 351+ seats
            spaces = Math.round(350 / 3.5) + Math.round((seats - 350) / 5);
          } else {
            // if 0-350 seats
            spaces = Math.round(seats / 3.5);
          }
          return spaces;
          break;

        case 'parking_warehouses':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 1000);
          return spaces;
          break;

        case 'parking_worship':
          var seats = this.collection.getAnswer("seats"),
            spaces = Math.round(seats / 3.5);
          return spaces;
          break;

        default:
          return "Unable to calculate.";
          break;
      }
    },

    initialize: function(options) {
      this.collection.on("reset", this.render, this);

      _.bindAll(this, 'beforeRender', 'render', 'afterRender');
      var _this = this;
      this.render = _.wrap(this.render, function(render) {
        _this.beforeRender();
        render();
        _this.afterRender();
        return _this;
      });
    },

    beforeRender: function() {
    },

    render: function() {
      return this;
    },

    clearAnswer: function(field_name) {
      this.collection.addAnswer(field_name, null);
    },

    afterRender: function(o) {
      // hide all the forms by default
      $('.business-type-rule').hide();
      $('.business-sub-type-rule').hide();

      var self = this;

      // When the applicant selects a business category
      $('#business_type').change(function() {
        self.clearAnswer('business_type');
        self.clearAnswer('required_parking_spaces');
        $('.business-type-rule').hide();
        selected_option = '#business_type_' + $(this).val() || '';
        $(selected_option).show();
      });

      // When the applicant selects a business sub-category
      $('.business_subtype').change(function() {
        $('.business-sub-type-rule').hide();
        selected_option = "#subtype_" + $(this).val() || '';
        $(selected_option).show();
      });

    },

    events: {
      "change select,input":"saveInput",
    },

    saveInput:function(ev) {
      ev.preventDefault();
      var $elem = $(ev.target);
      this.collection.addAnswer($elem.attr("name"), $elem.val());
      this.calculate();
    },

    calculate:function() {
      var type = 'parking_' + this.collection.getAnswer('business_type');
      var subtype = this.collection.getAnswer('business_subtype');
      var business_subtype = subtype || type;

      var spaces = this.calculateSpaces(business_subtype);

      this.collection.addAnswer('required_parking_spaces', spaces);

      var display_text = "
You must provide "
      + spaces
      + " car parking space"
      + ((spaces !== 1) ? "s" : "")
      + ".
";

      $("#parking_spaces")
      .html(display_text)
      .show();

    }

  });

  // Return the module for AMD compliance.
  return ParkingNonDowntown;
});
<commit_msg>Fixed non-downtown parking calc text. Was showing spaces = 'NaN', now is invisible until proper calculation is done.<commit_after>define([
  // Application.
  "app"
],

// Map dependencies from above array.
function(app) {

  // Create a new module.
  var ParkingNonDowntown = app.module();

  ParkingNonDowntown.Views.Calculator = Backbone.View.extend({

      tagName:    "section",
      className:  "content",
      template:   "panels/requirements/city/parking_non_downtown",

    serialize: function() {
      var model;
      var answers = {};

      for (m in this.collection.models) {
        model = this.collection.models[m];
        answers[model.get("name")] = model.get("value");
      }
      return {
        answers: answers
        // formatted fee
      };
    },

    cleanup: function() {
      this.collection.off(null, null, this);
    },

    // Calculates the number of spaces a business must provide.
    // Require the business sub-type and other fields specific to that business.
    calculateSpaces: function (business_subtype) {

      //console.log('calculating spaces for ', business_subtype);

      var spaces;

      switch (business_subtype) {
        case 'parking_auto':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 400);
          return spaces;
          break;

        case 'parking_service_stations':
          var service_bays = this.collection.getAnswer("service_bays"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(service_bays * 3) + employees;
          return spaces;
          break;

        case 'parking_banks_with_atms':
          var square_feet = this.collection.getAnswer("square_feet"),
            atms = this.collection.getAnswer("ATMs"),
            spaces = Math.round((square_feet / 400) + (atms * 1.5));
          return spaces;
          break;

        case 'parking_banks_no_atms':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 400);
          return spaces;
          break;

        case 'parking_billiard':
          var tables = this.collection.getAnswer("tables"),
            spaces = Math.round(tables * 1.5);
          return spaces;
          break;

        case 'parking_child_homes':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(beds / 5) + employees;
          return spaces;
          break;

        case 'parking_daycare_foster':
          var guests = this.collection.getAnswer("guests"),
            spaces = Math.round(guests / 5) + 1;
          return spaces;
          break;

        case 'parking_communication':
          var square_feet = this.collection.getAnswer("square_feet"),
            // the following line contained a reference to field_1, swapped out for square_feet
            spaces = Math.round(square_feet / 1000);
          return spaces;
          break;

        case 'parking_lower_schools':
          var employees = this.collection.getAnswer("employees"),
            spaces = employees;
          return spaces;
          break;

        case 'parking_high_schools':
          var students = this.collection.getAnswer("students"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(students / 10) + employees;
          return spaces;
          break;

        case 'parking_colleges':
          var students = this.collection.getAnswer("students"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round(students / 3) + employees;
          return spaces;
          break;

        case 'parking_multi_program_fitness':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = (square_feet / 100),
            spaces = (square_feet > 15000) ? Math.round(spaces * 1.1) : Math.round(spaces);
          return spaces;
          break;

        case 'parking_single_program_fitness':
          var aerobics_area = this.collection.getAnswer("aerobics_area"),
            basketball_volleyball_occupancy = this.collection.getAnswer("basketball_volleyball_occupancy"),
            pool_lanes = this.collection.getAnswer("pool_lanes"),
            pool_non_water_area = this.collection.getAnswer("pool_non_water_area"),
            weights_area = this.collection.getAnswer("weights_area"),
            square_feet = this.collection.getAnswer("square_feet"),
            spaces = (aerobics_area / 50) + (basketball_volleyball_occupancy / 3) + (pool_lanes * 2) + (pool_non_water_area / 300) + (weights_area / 250),
            spaces = (square_feet > 15000) ? Math.round(spaces * 1.1) : Math.round(spaces);
          return spaces;
          break;

        case 'parking_food':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 120);
          return spaces;
          break;

        case 'parking_take_out':
          var square_feet = this.collection.getAnswer("square_feet"),
            take_out_area = this.collection.getAnswer("take_out_area"),
            spaces = Math.round((square_feet / 120) + (take_out_area / 50));
          return spaces;
          break;

        case 'parking_funeral':
          var seats = this.collection.getAnswer("seats"),
            spaces = Math.round(seats / 5);
          return spaces;
          break;

        case 'parking_furn_repair':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 500);
          return spaces;
          break;

        case 'parking_halls_with_seats':
          var seats = this.collection.getAnswer("seats"),
            spaces = Math.round(seats / 3.5);
          return spaces;
          break;

        case 'parking_halls_no_seats':
          var max_occupancy_load = this.collection.getAnswer("max_occupancy_load"),
            spaces = Math.round(max_occupancy_load / 3);
          return spaces;
          break;

        case 'parking_household':
          var sales_area = this.collection.getAnswer("sales_area"),
            spaces = Math.round(sales_area / 800);
          return spaces;
          break;

        case 'parking_laundry':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 200);
          return spaces;
          break;

        case 'parking_community_care':
          var guests = this.collection.getAnswer("guests"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((guests / 5) + 1 + employees);
          return spaces;
          break;

        case 'parking_hotels':
          var hotel_units = this.collection.getAnswer("hotel_units"),
            spaces = hotel_units + 1;
          return spaces;
          break;

        case 'parking_convalescent':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((beds / 5) + employees);
          return spaces;
          break;

        case 'parking_hospitals':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((beds / 5) + employees);
          return spaces;
          break;

        case 'parking_medical_offices':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 200);
          return spaces;
          break;

        case 'parking_physical_therapy':
          var square_feet = this.collection.getAnswer("square_feet"),
            pool_water_area = this.collection.getAnswer("pool_water_area"),
            spaces = Math.round((square_feet / 200) + (pool_water_area / 50));
          return spaces;
          break;

        case 'parking_office':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 300);
          return spaces;
          break;

        case 'parking_plants':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 500);
          return spaces;
          break;

        case 'parking_research':
          var square_feet = this.collection.getAnswer("square_feet"),
            employees = this.collection.getAnswer("employees"),
            spaces_by_square_footage = Math.round(square_feet / 325),
            spaces_by_employees = Math.round(employees / 2);
          return (spaces_by_square_footage >= spaces_by_employees) ? spaces_by_square_footage : spaces_by_employees;
          break;

        case 'parking_retail':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 250);
          return spaces;
          break;

        case 'parking_boarding':
          var beds = this.collection.getAnswer("beds"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((beds / 5) + employees);
          return spaces;
          break;

        case 'parking_institutions':
          var guests = this.collection.getAnswer("guests"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((guests / 5) + employees);
          return spaces;
          break;

        case 'parking_nursing':
          var guests = this.collection.getAnswer("guests"),
            employees = this.collection.getAnswer("employees"),
            spaces = Math.round((guests / 5) + employees + 1);
          return spaces;
          break;

        case 'parking_theaters':
          var seats = this.collection.getAnswer("seats");
          if ((seats - 350) > 0) {
            // if 351+ seats
            spaces = Math.round(350 / 3.5) + Math.round((seats - 350) / 5);
          } else {
            // if 0-350 seats
            spaces = Math.round(seats / 3.5);
          }
          return spaces;
          break;

        case 'parking_warehouses':
          var square_feet = this.collection.getAnswer("square_feet"),
            spaces = Math.round(square_feet / 1000);
          return spaces;
          break;

        case 'parking_worship':
          var seats = this.collection.getAnswer("seats"),
            spaces = Math.round(seats / 3.5);
          return spaces;
          break;

        default:
          return "Unable to calculate.";
          break;
      }
    },

    initialize: function(options) {
      this.collection.on("reset", this.render, this);

      _.bindAll(this, 'beforeRender', 'render', 'afterRender');
      var _this = this;
      this.render = _.wrap(this.render, function(render) {
        _this.beforeRender();
        render();
        _this.afterRender();
        return _this;
      });
    },

    beforeRender: function() {
    },

    render: function() {
      return this;
    },

    clearAnswer: function(field_name) {
      this.collection.addAnswer(field_name, null);
    },

    afterRender: function(o) {
      // hide all the forms by default
      $('.business-type-rule').hide();
      $('.business-sub-type-rule').hide();

      var self = this;

      // When the applicant selects a business category
      $('#business_type').change(function() {
        self.clearAnswer('business_type');
        self.clearAnswer('required_parking_spaces');
        $('.business-type-rule').hide();
        selected_option = '#business_type_' + $(this).val() || '';
        $(selected_option).show();
      });

      // When the applicant selects a business sub-category
      $('.business_subtype').change(function() {
        $('.business-sub-type-rule').hide();
        selected_option = "#subtype_" + $(this).val() || '';
        $(selected_option).show();
      });

    },

    events: {
      "change select,input":"saveInput",
    },

    saveInput:function(ev) {
      ev.preventDefault();
      var $elem = $(ev.target);
      this.collection.addAnswer($elem.attr("name"), $elem.val());
      this.calculate();
    },

    calculate:function() {
      var type = 'parking_' + this.collection.getAnswer('business_type');
      var subtype = this.collection.getAnswer('business_subtype');
      var business_subtype = subtype || type;

      var spaces = this.calculateSpaces(business_subtype);

      this.collection.addAnswer('required_parking_spaces', spaces);

      var display_text = "
You must provide "
      + spaces
      + " car parking space"
      + ((spaces !== 1) ? "s" : "")
      + ".
";

      if ( !(isNaN(spaces) || spaces == null) ) {
		$("#parking_spaces")
		.html(display_text)
		.show();
	  }
    }

  });

  // Return the module for AMD compliance.
  return ParkingNonDowntown;
});
<|endoftext|>