'use strict'

var postcss = require('postcss')
var defined = require('defined')

var noop = postcss.plugin('noop', function () {
  return function (css) {}
})

module.exports = postcss.plugin('@emilbayes/css-pipeline', function (options) {
  options = options || {}
  var rtl = defined(options.rtl, process.env.RTL == true, false)
  var debug = defined(options.debug, process.env.DEBUG == true, false)

  return postcss([
    require('postcss-import')({
      plugins: [
        debug === true ? require('stylelint')(require('stylelint-config-standard')) : noop()
      ]
    }),
    require('postcss-url')({url: 'rebase'}),
    rtl === true ? require('rtlcss')() : noop(),
    require('postcss-cssnext')(),
    debug === false ? require('cssnano')({ autoprefixer: false }) : noop(),
    debug === true ? require('postcss-browser-reporter')() : noop()
  ])
})

'use strict'

var postcss = require('postcss')
var defined = require('defined')

var noop = postcss.plugin('noop', function () {
  return function (css) {}
})

module.exports = postcss.plugin('@emilbayes/css-pipeline', function (options) {
  options = options || {}
  var rtl = defined(options.rtl, process.env.RTL == true, false)
  var debug = defined(options.debug, process.env.DEBUG == true, false)

  return Object.assign(postcss([
    require('postcss-import')({
      plugins: [
        debug === true ? require('stylelint')(require('stylelint-config-standard')) : noop()
      ]
    }),
    require('postcss-url')({url: 'rebase'}),
    rtl === true ? require('rtlcss')() : noop(),
    require('postcss-cssnext')(),
    debug === false ? require('cssnano')({ autoprefixer: false }) : noop(),
    debug === true ? require('postcss-browser-reporter')() : noop()
  ]), {debug: debug, rtl: rtl})
})

Add resolved debug and rtl values to plugin


var pageMod = require("sdk/page-mod");

pageMod.PageMod({
  include: "https://twitter.com/",
  contentScript: "var MomentsButton = document.querySelector('.moments');" +
  "if(MomentsButton !== null){" +
  	"MomentsButton.parentNode.removeChild(MomentsButton);" +
  "}"
});

var pageMod = require("sdk/page-mod");

pageMod.PageMod({
  include: "https://twitter.com/*",
  contentScript: "var MomentsButton = document.querySelector('.moments');" +
  "if(MomentsButton !== null){" +
  	"MomentsButton.parentNode.removeChild(MomentsButton);" +
  "}"
});

Correct paths that this will work on


module.exports = function express() {
    var http = require('http');

    var app = function(request, response) {
        response.statusCode = 404;
        response.end();
    }

    app.listen = function(port, callback) {
        var server = http.createServer(this);
        server.listen(port, function() {
            callback();
        })
        return server;
    }
    return app;
}

module.exports = function express() {
    var http = require('http');

    var app = function(request, response, next) {
        app.handle(request, response, next);
        response.statusCode = 404;
        response.end();

    }

    app.handle = function(request, response, next) {
        var stack = app.stack;

        function next() {
            var middleWare = stack.shift();
            if (middleWare == undefined) {
                return;
            }
            middleWare(request, response, next);
        }
        next();

    }

    app.listen = function(port, callback) {
        var server = http.createServer(this);
        server.listen(port, function() {
            callback();
        })
        return server;
    }

    app.stack = [];

    app.use = function(func) {
        app.stack.push(func);
    }

    return app;
}

Implement of next by passing next method to app.handle.


/**
 * Detects if only the primary button has been clicked in mouse events.
 * @param {MouseEvent} event
 * @return {boolean}
 */
module.exports = function isPrimaryClick (event) {
	return (
		!event.altKey &&
		!event.ctrlKey &&
		!event.metaKey &&
		!event.shiftKey
	) && (
		('button' in event && event.button === 0) ||
		('buttons' in event && event.buttons === 1)
	);
};

/**
 * Detects if only the primary button has been clicked in mouse events.
 * @param {MouseEvent} e Event instance (or Event-like, i.e. `SyntheticEvent`)
 * @return {Boolean}
 */
module.exports = function isPrimaryClick (e) {
	return !(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) && (
		('button' in e && e.button === 0) ||
		('buttons' in e && e.buttons === 1)
	);
};

Simplify code and enhance comments


"use strict";

const ElementInstance = require('./elementInstance');
const he = require('he');

class HiddenInstance extends ElementInstance {
  async init(data={}) {
    await super.init(data);
    const TagSingle = this.context.theme.getRenderable('TagSingle');
    let renderable = TagSingle.newInstance(this.context, {
      name: this.name,
      data: {
        tag: 'input',
        attributes: {
          type: 'hidden',
          name: this.name,
          value: he.escape((this.data && (this.data.value != undefined)) ? this.data.value : ''),
        },
      },
    });
    this.addInstance(renderable);
  }
}

module.exports = HiddenInstance;

"use strict";

const ElementInstance = require('./elementInstance');
const he = require('he');

class HiddenInstance extends ElementInstance {
  async init(data={}) {
    await super.init(data);
    const TagSingle = this.context.theme.getRenderable('TagSingle');
    let renderable = TagSingle.newInstance(this.context, {
      name: this.name,
      data: {
        tag: 'input',
        attributes: {
          type: 'hidden',
          name: this.name,
          value: he.escape(
            this.data.value
            ? this.data.value
            : this.context.post[this.formInstance.id][this.name] != undefined
              ? this.context.post[this.formInstance.id][this.name]
              : this.data.defaultValue
                ? this.data.defaultValue
                : ''),
        },
      },
    });
    this.addInstance(renderable);
  }
}

module.exports = HiddenInstance;

Improve Hidden element value logic


import GeometryResourceDescriptor from './GeometryResourceDescriptor';
import PropTypes from 'react/lib/ReactPropTypes';
import THREE from 'three.js';

class ShapeGeometryResourceDescriptor extends GeometryResourceDescriptor {
  constructor(react3RendererInstance) {
    super(react3RendererInstance);

    this.hasProp('type', {
      type: PropTypes.oneOf([
        'points',
        'spacedPoints',
        'shape',
      ]).isRequired,
      update: this.triggerRemount,
      'default': '',
    });

    this.hasProp('divisions', {
      type: PropTypes.number,
      update: this.triggerRemount,
      'default': 5,
    });
  }

  applyInitialProps(threeObject, props) {
    super.applyInitialProps(threeObject, props);

    threeObject.userData._divisions = props.divisions;

    threeObject.userData._type = props.type;
  }

  applyToSlot(threeObject, parentObject, shape:THREE.Shape) {
    if (!shape) {
      return super.applyToSlot(threeObject, parentObject, null);
    }

    let geometry;

    switch (threeObject.userData._type) {
    case 'points':
      geometry = shape.createPointsGeometry();
      break;
    case 'spacedPoints':
      geometry = shape.createSpacedPointsGeometry(threeObject.userData._divisions);
      break;
    case 'shape':
      // TODO shapeGeometryDescriptor
      geometry = new THREE.ShapeGeometry(shape);
      break;
    'default':
      debugger;
      break;
    }

    return super.applyToSlot(threeObject, parentObject, geometry);
  }
}

module.exports = ShapeGeometryResourceDescriptor;

import GeometryResourceDescriptor from './GeometryResourceDescriptor';
import PropTypes from 'react/lib/ReactPropTypes';
import THREE from 'three.js';

class ShapeGeometryResourceDescriptor extends GeometryResourceDescriptor {
  constructor(react3RendererInstance) {
    super(react3RendererInstance);

    this.hasProp('type', {
      type: PropTypes.oneOf([
        'points',
        'spacedPoints',
        'shape',
      ]).isRequired,
      update: this.triggerRemount,
      'default': '',
    });

    this.hasProp('divisions', {
      type: PropTypes.number,
      update: this.triggerRemount,
      'default': 5,
    });
  }

  applyInitialProps(threeObject, props) {
    super.applyInitialProps(threeObject, props);

    threeObject.userData._divisions = props.divisions;

    threeObject.userData._type = props.type;
  }

  applyToSlot(threeObject, parentObject, shape:THREE.Shape) {
    if (!shape) {
      return super.applyToSlot(threeObject, parentObject, null);
    }

    let geometry;

    switch (threeObject.userData._type) {
    case 'points':
      geometry = shape.createPointsGeometry();
      break;
    case 'spacedPoints':
      geometry = shape.createSpacedPointsGeometry(threeObject.userData._divisions);
      break;
    case 'shape':
      // TODO shapeGeometryDescriptor
      geometry = new THREE.ShapeGeometry(shape);
      break;
    default:
      debugger;
      break;
    }

    return super.applyToSlot(threeObject, parentObject, geometry);
  }
}

module.exports = ShapeGeometryResourceDescriptor;

Fix bad default case statement


const micro = require('micro');
const {router, get} = require('microrouter');
const {delay} = require('./helpers/delay');
const {element, number, boolean} = require('./helpers/random');
const products = require('./products');

const randomHandler = async function (req, res) {

  if (boolean()) {
    process.exit(1);
  }

  const timeout = number(5000, 15000);
  await delay(timeout);
  micro.send(res, 200, await Promise.resolve(element(products)));
};

const allHandler = async function (req, res) {

  if (boolean()) {
    process.exit(1);
  }

  const timeout = number(5000, 15000);
  await delay(timeout);
  micro.send(res, 200, await Promise.resolve(products));
};

const server = micro(router(
  get('/random', randomHandler),
  get('/all', allHandler)
));

server.listen(process.env.PORT || 3000, () => console.log('Listening...'))

exports.default = server

const micro = require('micro');
const {router, get} = require('microrouter');
const {delay} = require('./helpers/delay');
const {element, number} = require('./helpers/random');
const products = require('./products');

const randomHandler = async function (req, res) {
  const timeout = number(5000, 15000);
  await delay(timeout);
  micro.send(res, 200, await Promise.resolve(element(products)));
};

const allHandler = async function (req, res) {
  const timeout = number(5000, 15000);
  await delay(timeout);
  micro.send(res, 200, await Promise.resolve(products));
};

const server = micro(router(
  get('/random', randomHandler),
  get('/all', allHandler)
));

server.listen(process.env.PORT || 3000, () => console.log('Listening...'))

exports.default = server

Revert "feat(core): kill process for uptime demonstration"


'use strict';

module.exports = function(){

};

'use strict';

var fs = require('fs');
var exec = require('child_process').exec;
var plist = require('plist');
var unzip = require('unzip');

var rimraf = require('rimraf');
var tmp = require('temporary');
var glob = require("glob");

var output = new tmp.Dir();

module.exports = function (file, callback){
  fs.createReadStream(file)
    .pipe(unzip.Extract({ path: output.path }))
    .on('close', function(){
      var path = glob.sync(output.path + '/Payload/*/')[0];

      var metadata = plist.parse(fs.readFileSync(path + 'Info.plist', 'utf8'));

      exec('security cms -D -i embedded.mobileprovision > Provisioning.plist', { cwd: path }, function() {
        var provisioning = plist.parse(fs.readFileSync(path + 'Provisioning.plist', 'utf8'));
        delete provisioning.DeveloperCertificates;

        rimraf.sync(output.path);

        return callback({
          metadata: metadata,
          provisioning: provisioning
        });
      });
    });
};

Create inital logic for reading, extracting and converting the .plist files


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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.
 */
(function () {
  'use strict';

  angular.module('pnc.common.pnc-client.message-bus').factory('buildStatusListener', [
    '$log',
    '$rootScope',
    'pncEventAdaptor',
    function ($log, $rootScope, pncEventAdaptor) {
      return function (message) {
        if (message.eventType === 'BUILD_STATUS_CHANGED') {
          var event = pncEventAdaptor.convert(message);
          $log.debug('Following event is broadcasted: %O', event);
          $rootScope.$broadcast(event.eventType, event.payload);
        }
      };
    }
  ]);

})();

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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.
 */
(function () {
  'use strict';

  angular.module('pnc.common.pnc-client.message-bus').factory('buildStatusListener', [
    '$log',
    '$rootScope',
    'pncEventAdaptor',
    function ($log, $rootScope, pncEventAdaptor) {
      return function (message) {
        if (message.eventType === 'BUILD_STATUS_CHANGED' || message.eventType === 'BUILD_SET_STATUS_CHANGED') {
          var event = pncEventAdaptor.convert(message);
          $log.debug('Following event is broadcasted: %O', event);
          $rootScope.$broadcast(event.eventType, event.payload);
        }
      };
    }
  ]);

})();

Add build set status listener


'use strict';

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class CandidateMatchCategory extends Component {
    render() {
        return (

                    {this.props.matchRate}

                    {this.props.categoryName}

        );
    }
}

CandidateMatchCategory.propTypes = {
    matchRate: PropTypes.number,
    category: PropTypes.string
};

export default CandidateMatchCategory;

'use strict';

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class CandidateMatchCategory extends Component {
    render() {
        return (

                    {this.props.matchRate}

                    {this.props.categoryName}

        );
    }
}

CandidateMatchCategory.propTypes = {
    matchRate: PropTypes.number,
    categoryName: PropTypes.string
};

export default CandidateMatchCategory;

Fix typo in prop name


import Textcomplete from '../src/textcomplete';
import Completer from '../src/completer';

const assert = require('power-assert');

import {getTextarea} from './test-helper';

describe('Textcomplete', function () {
  describe('#completer', function () {
    it('should be a Completer', function () {
      var textcomplete = new Textcomplete(getTextarea());
      assert.ok(textcomplete.completer instanceof Completer);
    });
  });

  describe('#register', function () {
    it('should return itself', function () {
      var textcomplete = new Textcomplete(getTextarea());
      assert.strictEqual(textcomplete.register([{}]), textcomplete);
    });

    it('should call Completer#registerStrategy', function () {
      // TODO use spy object
    });
  });
});

import Textcomplete from '../src/textcomplete';

const assert = require('power-assert');

import {getTextarea} from './test-helper';

describe('Textcomplete', function () {
  describe('#register', function () {
    it('should return itself', function () {
      var textcomplete = new Textcomplete(getTextarea());
      assert.strictEqual(textcomplete.register([{}]), textcomplete);
    });

    it('should call Completer#registerStrategy', function () {
      // TODO use spy object
    });
  });
});

Remove meaning less test case


// Navigation helper for the test iframe. Queues navigation actions and
// callbacks, then executes them serially with respect to async. This is to
// avoid deep nesting of callbacks in tests.
//
// After last successful navigation, asyncTest is automatically resumed.
//
// Usage:
//
//   navigate(this.frame)
//   .pjax(pjaxOptions, function(frame){ ... }
//   .back(-1, function(frame){ ... }
//
function navigate(frame) {
  var queue = []
  var api = {}

  api.pjax = function(options, callback) {
    queue.push([options, callback])
    return api
  }
  api.back = api.pjax

  var workOff = function() {
    var item = queue.shift()
    if (!item) {
      start()
      return
    }

    var target = item[0], callback = item[1]

    frame.$(frame.document).one("pjax:end", function() {
      if (callback) callback(frame)
      setTimeout(workOff, 0)
    })

    if (typeof target == "number") {
      frame.history.go(target)
    } else {
      frame.$.pjax(target)
    }
  }

  setTimeout(workOff, 0)

  return api
}

// Navigation helper for the test iframe. Queues navigation actions and
// callbacks, then executes them serially with respect to async. This is to
// avoid deep nesting of callbacks in tests.
//
// If a `then`able object is returned from a callback, then the navigation will
// resume only after the promise has been resolved.
//
// After last successful navigation, asyncTest is automatically resumed.
//
// Usage:
//
//   navigate(this.frame)
//   .pjax(pjaxOptions, function(frame){ ... }
//   .back(-1, function(frame){ ... }
//
function navigate(frame) {
  var queue = []
  var api = {}

  api.pjax = function(options, callback) {
    queue.push([options, callback])
    return api
  }
  api.back = api.pjax

  var workOff = function() {
    var item = queue.shift()
    if (!item) {
      start()
      return
    }

    var target = item[0], callback = item[1]

    frame.$(frame.document).one("pjax:end", function() {
      var promise = callback && callback(frame)
      if (promise && typeof promise.then == "function") promise.then(workOff)
      else setTimeout(workOff, 0)
    })

    if (typeof target == "number") {
      frame.history.go(target)
    } else {
      frame.$.pjax(target)
    }
  }

  setTimeout(workOff, 0)

  return api
}

// A poor man's Promise implementation. Only resolvable promises with no
// reject/catch support.
function PoorMansPromise(setup) {
  var result, callback, i = 0, callbacks = []
  setup(function(_result) {
    result = _result
    while (callback = callbacks[i++]) callback(result)
  })
  this.then = function(done) {
    if (i == 0) callbacks.push(done)
    else setTimeout(function(){ done(result) }, 0)
    return this
  }
}

Add rudimentary Promise support to `navigate` helper


/*
** TailwindCSS Configuration File
**
** Docs: https://tailwindcss.com/docs/configuration
** Default: https://github.com/tailwindcss/tailwindcss/blob/master/stubs/defaultConfig.stub.js
*/
module.exports = {
  theme: {},
  variants: {},
  plugins: [],
};

Add blue and gray colors.


const { relative } = require('path')

module.exports = ReactUniversalServerLoader

function ReactUniversalServerLoader(source, map) {
  const filename = relative(this.options.context, this.resourcePath)
  const importPath = relative(this.context, this.resourcePath)
  const id = filename.replace(/[/.]/g, '_')
  return createServerCode({ importPath, id, filename })
}

function createServerCode({ importPath, id, filename }) {
  return `|import Component from './${importPath}'
          |import assignStatics from 'hoist-non-react-statics'
          |import { renderToString } from 'react-dom/server'
          |
          |assignStatics(WrapWithScript, Component)
          |
          |export default function WrapWithScript(props) {
          |  const content = renderToString(<Component id='${id}' {...props} />)
          |  return (
          |

          |

          |

const { relative } = require('path')

module.exports = ReactUniversalServerLoader

function ReactUniversalServerLoader(source, map) {
  const filename = relative(this.options.context, this.resourcePath)
  const importPath = relative(this.context, this.resourcePath)
  const id = filename.replace(/[/.]/g, '_')
  return createServerCode({ importPath, id, filename })
}

function createServerCode({ importPath, id, filename }) {
  return `|import Component from './${importPath}'
          |import assignStatics from 'hoist-non-react-statics'
          |import { renderToString } from 'react-dom/server'
          |
          |assignStatics(WrapWithScript, Component)
          |
          |export default function WrapWithScript({ universalContainerProps, ...props }) {
          |  const content = renderToString(<Component id='${id}' {...props} />)
          |  return (
          |    <React.Fragment>
          |      <div {...universalContainerProps} id='${id}' data-props={JSON.stringify(props)} dangerouslySetInnerHTML={{ __html: content }} />
          |      <script defer src={__webpack_public_path__ + __webpack_js_chunk_information__.manifest['${filename}'].filename} />
          |    </React.Fragment>
          |  )
          |}
          |`.split(/^[ \t]*\|/m).join('')
}

Remove unnecessary wrapping DOM nodes around universal apps & be able to pass props to root-app-container


class MCWorkflowFiltersComponentController {
    /*@ngInject*/
    constructor(workflowFiltersService, $stateParams) {
        this.whichFilter = 'all';
        this.workflowFiltersService = workflowFiltersService;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
    }

    filterBySamples() {
        this.workflowFiltersService.filterBySamples(this.projectId, this.experimentId);
    }
}

angular.module('materialscommons').component('mcWorkflowFilters', {
    templateUrl: 'app/project/experiments/experiment/components/workflow/mc-workflow-filters.html',
    controller: MCWorkflowFiltersComponentController
});

class MCWorkflowFiltersComponentController {
    /*@ngInject*/
    constructor(workflowFiltersService, $stateParams) {
        this.whichFilter = 'all';
        this.workflowFiltersService = workflowFiltersService;
        this.projectId = $stateParams.project_id;
        this.experimentId = $stateParams.experiment_id;
        this.showSamplesFilter = true;
        this.showProcessesFilter = false;
    }

    filterBySamples() {
        this.workflowFiltersService.filterBySamples(this.projectId, this.experimentId);
    }
}

angular.module('materialscommons').component('mcWorkflowFilters', {
    templateUrl: 'app/project/experiments/experiment/components/workflow/mc-workflow-filters.html',
    controller: MCWorkflowFiltersComponentController
});

Make sample filters the default.


$(function(){
  $('.more-or-less').each(function(i, el) {
  console.log(el);
    $(el).find("li a").click(function() {
    $(el).find("button").html($(this).text() + ' ');
    $(el).find("input.more-or-less-type").val($(this).text());
    });
  });

  $(".formify").each(function (_, element) {
    var value = $(element).find("[data-selected='true']").first().addClass("active").data("value");
    $(element).append('<input class="formify-value" type="hidden" name="' + $(this).data('name') + '" value="' + value + '" >');
  });

  $(".formify .btn").click(function () {
    $(this).addClass("active");
    var val = $(this).data("value");
    var input = $(this).parent().find(".formify-value")
    console.log(val)
    $(input).val(val)
  });

  $(".incident").click(function() {
    $(this).toggleClass("selected");
  });

  $(".select-all").click(function(event) {
    $(event.target).parent().parent().find("input").prop("checked", true);
    event.preventDefault();
  });

  $(".clear-all").click(function(event) {
    $(event.target).parent().parent().find("input").prop("checked", false);
    event.preventDefault();
  });
})

$(function(){
  $('.more-or-less').each(function(i, el) {
  console.log(el);
    $(el).find("li a").click(function() {
    $(el).find("button").html($(this).text() + ' ');
    $(el).find("input.more-or-less-type").val($(this).text());
    });
  });

  $(".formify").each(function (_, element) {
    var value = $(element).find("[data-selected='true']").first().addClass("active").data("value");
    $(element).append('<input class="formify-value" type="hidden" name="filter[' + $(this).data('name') + ']" value="' + value + '" >');
  });

  $(".formify .btn").click(function () {
    $(this).addClass("active");
    var val = $(this).data("value");
    var input = $(this).parent().find(".formify-value")
    console.log(val)
    $(input).val(val)
  });

  $(".incident").click(function() {
    $(this).toggleClass("selected");
  });

  $(".select-all").click(function(event) {
    $(event.target).parent().parent().find("input").prop("checked", true);
    event.preventDefault();
  });

  $(".clear-all").click(function(event) {
    $(event.target).parent().parent().find("input").prop("checked", false);
    event.preventDefault();
  });
})

Bring formified inputs into the world of the filter.


AFRAME.registerComponent('socket-controls', {
  schema: {
    previousPos: {default: 0},
    nextPos: {default: 0},
    socket: {default: null},
    dur: {default: 100} // set this to update cycle length
  },

  init: function() {
    const data = this.data;
    const socket = window.socket;
    const el = this.el;
    socket.on('enemyPositionUpdate', positionUpdate => {
      data.previousPos = data.nextPos; // switch this to current position
      data.nextPos = positionUpdate;
      el.setAttribute('position', data.nextPos);
    });
  },

  tick: function(t, dt) {
  },

  update: function (previousData) {
  },

});

AFRAME.registerComponent('socket-controls', {
  schema: {
    previousPos: {default: 0},
    nextPos: {default: 0},
    socket: {default: null},
    lastUpdateTime: new Date(),
    dur: {default: 100} // set this to update cycle length
  },

  init: function() {
    const data = this.data;
    const socket = window.socket;
    const el = this.el;
    socket.on('enemyPositionUpdate', positionUpdate => {
      data.lastUpdateTime = Date.now()
      data.previousPos = data.nextPos; // switch this to current position
      data.nextPos = positionUpdate;
      el.setAttribute('position', data.nextPos);
    });
  },

  tick: function(t, dt) {
    // linear interp from data.lastPos to data.nextPos
  },

  update: function (previousData) {
  },

});

Set up linear interpolation for position updates


import React from 'react';
import { Link } from 'react-router';
import { Menu, Segment } from 'semantic-ui-react';
import DynamicLinks from './DynamicLinks';

const Navbar = ({ id, location, logout }) =>
  <Segment inverted>
    <Menu inverted pointing secondary>
      <Menu.Item
        as={Link}
        to="dashboard"
        className="logo"
      >
        <img alt="raptor" src="/client/src/assets/half-raptor.png" />
      </Menu.Item>
      <Menu.Item as={Link} to="/landing" name="About" active={location === 'landing'} />
      <Menu.Item as={Link} to="/listings" name="Listings" active={location === 'listings'} />
      <Menu.Item as={Link} to="/dashboard" name="customer dashboard" active={location === 'dashboard'} />
      <Menu.Item as={Link} to="/addlisting" name="addlisting" active={location === 'addlisting'} />
      <DynamicLinks id={id} logout={logout} />
    </Menu>
  </Segment>;

export default Navbar;

Navbar.propTypes = {
  location: React.PropTypes.string.isRequired,
};

import React from 'react';
import { Link } from 'react-router';
import { Menu, Segment } from 'semantic-ui-react';
import DynamicLinks from './DynamicLinks';

const Navbar = ({ id, location, logout }) =>
  <Segment inverted>
    <Menu inverted pointing secondary>
      <Menu.Item
        as={Link}
        to="dashboard"
        className="logo"
      >
        <img alt="raptor" src="/client/src/assets/half-raptor.png" />
      </Menu.Item>
      <Menu.Item as={Link} to="/landing" name="About" active={location === '/landing'} />
      <Menu.Item as={Link} to="/listings" name="Listings" active={location === '/listings'} />
      <Menu.Item as={Link} to="/dashboard" name="customer dashboard" active={location === '/dashboard'} />
      <Menu.Item as={Link} to="/addlisting" name="addlisting" active={location === '/addlisting'} />
      <DynamicLinks id={id} logout={logout} />
    </Menu>
  </Segment>;

export default Navbar;

Navbar.propTypes = {
  location: React.PropTypes.string.isRequired,
};

Fix active links on navbar


//Code below manages Wistia gating. Enter email address once, then rest are ungated
wistiaEmbeds.onFind(function(video) {
  var email = Wistia.localStorage("golden-ticket");
  if (email) {
    console.log('email being set');
    video.setEmail(email);
  }
});
wistiaEmbeds.bind("conversion", function(video, type, data) {
  if (/^(pre|mid|post)-roll-email$/.test(type)) {
    console.log('about to save on local storage');
    Wistia.localStorage("golden-ticket", data);
    for (var i = 0; i < wistiaEmbeds.length; i++) {
      wistiaEmbeds[i].setEmail(data);
    }
  }
});

//Code below manages Wistia gating. Enter email address once, then rest are ungated
wistiaEmbeds.onFind(function(video) {
  var email = Wistia.localStorage("golden-ticket");
  if (email) {
    video.setEmail(email);
  }
});
wistiaEmbeds.bind("conversion", function(video, type, data) {
  if (/^(pre|mid|post)-roll-email$/.test(type)) {
    Wistia.localStorage("golden-ticket", data);
    for (var i = 0; i < wistiaEmbeds.length; i++) {
      wistiaEmbeds[i].setEmail(data);
    }
  }
});

//code below allows users to resume video from whence they left off
wistiaEmbeds.onFind(function(video) {
  video.addPlugin("resumable", {
    src: "//fast.wistia.com/labs/resumable/plugin.js"
  });
});

Add code to pickup where viewer left off


const helpers = require('./support/helpers.js');

beforeAll(() => {
  jest.useFakeTimers();
});

afterAll(() => {
  require('./support/teardown.js');
});

describe('Prevent duplicate form submissions', () => {

  let form;
  let button;
  let formSubmitSpy;

  beforeEach(() => {

    // set up DOM
    document.body.innerHTML = `
      <form action="/" method="post">
        <button class="button" type="submit">Continue</button>
      </form>`;

    form = document.querySelector('form');
    button = document.querySelector('button');

    // requires a helper due to JSDOM not implementing the submit method
    formSubmitSpy = helpers.spyOnFormSubmit(jest, form);

    require('../../app/assets/javascripts/preventDuplicateFormSubmissions.js');

  });

  afterEach(() => {

    document.body.innerHTML = '';

    // we run the previewPane.js script every test
    // the module cache needs resetting each time for the script to execute
    jest.resetModules();

    formSubmitSpy.mockClear();

  });

  test("It should prevent any clicks of the 'submit' button after the first one submitting the form", () => {

    helpers.triggerEvent(button, 'click');
    helpers.triggerEvent(button, 'click');

    expect(formSubmitSpy.mock.calls.length).toEqual(1);

  });

  test("It should allow clicks again after 1.5 minutes", () => {

    helpers.triggerEvent(button, 'click');

    jest.advanceTimersByTime(1500);

    helpers.triggerEvent(button, 'click');

    expect(formSubmitSpy.mock.calls.length).toEqual(2);

  });

});

const helpers = require('./support/helpers.js');

beforeAll(() => {
  jest.useFakeTimers();
});

afterAll(() => {
  require('./support/teardown.js');
});

describe('Prevent duplicate form submissions', () => {

  let form;
  let button;
  let formSubmitSpy;

  beforeEach(() => {

    // set up DOM
    document.body.innerHTML = `
      <form action="/" method="post">
        <button class="button" type="submit">Continue</button>
      </form>`;

    form = document.querySelector('form');
    button = document.querySelector('button');

    // requires a helper due to JSDOM not implementing the submit method
    formSubmitSpy = helpers.spyOnFormSubmit(jest, form);

    require('../../app/assets/javascripts/preventDuplicateFormSubmissions.js');

  });

  afterEach(() => {

    document.body.innerHTML = '';

    // we run the previewPane.js script every test
    // the module cache needs resetting each time for the script to execute
    jest.resetModules();

    formSubmitSpy.mockClear();

  });

  test("It should prevent any clicks of the 'submit' button after the first one submitting the form", () => {

    helpers.triggerEvent(button, 'click');
    helpers.triggerEvent(button, 'click');

    expect(formSubmitSpy.mock.calls.length).toEqual(1);

  });

  test("It should allow clicks again after 1.5 seconds", () => {

    helpers.triggerEvent(button, 'click');

    jest.advanceTimersByTime(1500);

    helpers.triggerEvent(button, 'click');

    expect(formSubmitSpy.mock.calls.length).toEqual(2);

  });

});

Fix description of time until re-enable clicks


/*global describe, it*/
/*
 * mochify.js
 *
 * Copyright (c) 2014 Maximilian Antoni <mail@maxantoni.de>
 *
 * @license MIT
 */
'use strict';

var assert = require('assert');
var run    = require('./fixture/run');

describe('stack', function () {
  this.timeout(3000);

  it('does not screw up xunit', function (done) {
    run('passes', ['-R', 'xunit'], function (code, stdout) {
      var lines = stdout.split('\n');
      var expect = '<testcase classname="test" name="passes" time="0';
      assert.equal(lines[1].substring(0, expect.length), expect);
      assert.equal(lines[2], '</testsuite>');
      assert.equal(code, 0);
      done();
    });
  });

});

/*global describe, it*/
/*
 * mochify.js
 *
 * Copyright (c) 2014 Maximilian Antoni <mail@maxantoni.de>
 *
 * @license MIT
 */
'use strict';

var assert = require('assert');
var run    = require('./fixture/run');

describe('stack', function () {
  this.timeout(5000);

  it('does not screw up xunit', function (done) {
    run('passes', ['-R', 'xunit'], function (code, stdout) {
      var lines = stdout.split('\n');
      var expect = '<testcase classname="test" name="passes" time="0';
      assert.equal(lines[1].substring(0, expect.length), expect);
      assert.equal(lines[2], '</testsuite>');
      assert.equal(code, 0);
      done();
    });
  });

});

Increase timeout for stack test


!(function( global ) {

  // NEX<->CRX support set up
  var nexAPIStubs = ['app', 'extension', 'windows', 'tabs', 'browserAction', 'contextMenus', 'i18n', 'webRequest'];
  if(!global.chrome) {
    global.chrome = {};
  }
  for(var i = 0, l = nexAPIStubs.length; i < l; i++) {
    global.chrome[ nexAPIStubs[ i ] ] = global.chrome[ nexAPIStubs[ i ] ] || global.navigator[ nexAPIStubs[ i ] ] || {};
  }

  var Opera = function() {};

  Opera.prototype.REVISION = '1';

  Opera.prototype.version = function() {
    return this.REVISION;
  };

  Opera.prototype.buildNumber = function() {
    return this.REVISION;
  };

  Opera.prototype.postError = function( str ) {
    console.log( str );
  };

  var opera = global.opera || new Opera();

  var manifest = chrome.app.getDetails(); // null in injected scripts / popups

  navigator.browserLanguage=navigator.language; //Opera defines both, some extensions use the former

  var isReady = false;

  var _delayedExecuteEvents = [
    // Example:
    // { 'target': opera.extension, 'methodName': 'message', 'args': event }
  ];

  function addDelayedEvent(target, methodName, args) {
    if(isReady) {
      target[methodName].apply(target, args);
    } else {
      _delayedExecuteEvents.push({
        "target": target,
        "methodName": methodName,
        "args": args
      });
    }
  };

!(function( global ) {

  var Opera = function() {};

  Opera.prototype.REVISION = '1';

  Opera.prototype.version = function() {
    return this.REVISION;
  };

  Opera.prototype.buildNumber = function() {
    return this.REVISION;
  };

  Opera.prototype.postError = function( str ) {
    console.log( str );
  };

  var opera = global.opera || new Opera();

  var manifest = chrome.app.getDetails(); // null in injected scripts / popups

  navigator.browserLanguage=navigator.language; //Opera defines both, some extensions use the former

  var isReady = false;

  var _delayedExecuteEvents = [
    // Example:
    // { 'target': opera.extension, 'methodName': 'message', 'args': event }
  ];

  function addDelayedEvent(target, methodName, args) {
    if(isReady) {
      target[methodName].apply(target, args);
    } else {
      _delayedExecuteEvents.push({
        "target": target,
        "methodName": methodName,
        "args": args
      });
    }
  };

Remove defunct NEX aliasing from OEX shim (see: DNA-2416)


module.exports = function(params) {
  const { crashReporter } = require('electron');
  const { uploadToServer } = params;

  crashReporter.start({
    productName: 'Atom',
    companyName: 'GitHub',
    submitURL: 'https://atom.io/crash_reports',
    uploadToServer
  });
};

module.exports = function(params) {
  const { crashReporter } = require('electron');
  const platformRelease = require('os').release();
  const { uploadToServer } = params;

  crashReporter.start({
    productName: 'Atom',
    companyName: 'GitHub',
    submitURL: 'https://atom.io/crash_reports',
    uploadToServer,
    extra: { platformRelease }
  });
};

Add platformRelease to data posted to Atom.io with crashes


// Each key corresponds to the current practical room level and contains a separate objects containing settings enabled
// at that level. Each higher level inherits the settings from the level below it.
let roomLevelOptions = {
  1: {
    'UPGRADERS_QUANTITY': 5
  },
  2: {},
  3: {},
  4: {
    'DEDICATED_MINERS': true,
    'PURE_CARRY_FILLERS': true
  },
  5: {},
  6: {
    'EXTRACT_MINERALS': true
  },
  7: {},
  8: {
    'UPGRADERS_QUANTITY': 1
  }
}

// Have each level inherit the settings from the previous level unless already set.
for (let level = 0; level <= 8; level++) {
  for (let addLevel = level - 1; addLevel > 0; addLevel--) {
    const keys = Object.keys(roomLevelOptions[addLevel])
    for (let key of keys) {
      if (typeof roomLevelOptions[level][key] === 'undefined') {
        roomLevelOptions[level][key] = roomLevelOptions[addLevel][key]
      }
    }
  }
}

Room.prototype.getRoomSetting = function (key) {
  const level = this.getPracticalRoomLevel()
  return roomLevelOptions[level][key] ? roomLevelOptions[level][key] : false
}

// Each key corresponds to the current practical room level and contains a separate objects containing settings enabled
// at that level. Each higher level inherits the settings from the level below it.
let roomLevelOptions = {
  1: {
    'UPGRADERS_QUANTITY': 5
  },
  2: {},
  3: {},
  4: {
    'DEDICATED_MINERS': true,
    'PURE_CARRY_FILLERS': true
  },
  5: {},
  6: {
    'EXTRACT_MINERALS': true,
    'UPGRADERS_QUANTITY': 3
  },
  7: {},
  8: {
    'UPGRADERS_QUANTITY': 1
  }
}

// Have each level inherit the settings from the previous level unless already set.
for (let level = 0; level <= 8; level++) {
  for (let addLevel = level - 1; addLevel > 0; addLevel--) {
    const keys = Object.keys(roomLevelOptions[addLevel])
    for (let key of keys) {
      if (typeof roomLevelOptions[level][key] === 'undefined') {
        roomLevelOptions[level][key] = roomLevelOptions[addLevel][key]
      }
    }
  }
}

Room.prototype.getRoomSetting = function (key) {
  const level = this.getPracticalRoomLevel()
  return roomLevelOptions[level][key] ? roomLevelOptions[level][key] : false
}

Reduce starting upgrader quantity to 3 at practical room level 6


require("../www/discography/js/lib/model.js");
require("../www/discography/js/models/artist.js");
require("../www/discography/js/lib/ajax.js");
require("../www/discography/js/lib/promise.js");

/******************************************************************************/
//
// Jasmine Docs: https://jasmine.github.io/2.4/introduction.html
//
/******************************************************************************/

describe("Artist model interface", function() {
  it("fetchOne should provide one artist", function(done) {
    // Some test data:
    var record = {name: "The Wombats"};

    // Pretend the server responded with the above object:
    ajaxSpy('get', record);

    // Call into the Artist model:
    Artist.fetchOne(1).then(function(artist) {
      expect(artist.name).toEqual(record.name);
      expect(artist.save).toBeDefined();
      done(); // Make sure to call `done' last.
    }).catch(function() {
      done.fail("shouldn't have failed");
    });
  });

  it("fetchAll should provide all artists", function(done) {
    var records = [
      {name: "Peter Bjorn and John"},
      {name: "David Bowie"},
    ];

    ajaxSpy('get', records);

    Artist.fetchAll().
      then(function(artists) {
        expect(artists.length).toBe(records.length);
        expect(artists[0].name).toBe(records[0].name);
        expect(artists.every(function(artist) {
          return artist instanceof Artist;
        })).toBeTruthy();
        done();
      }).
      catch(function() {
        done.fail("promise rejected");
      });
  });
});

require("../www/discography/js/lib/model.js");
require("../www/discography/js/models/artist.js");
require("../www/discography/js/lib/ajax.js");
require("../www/discography/js/lib/promise.js");

/******************************************************************************/
//
// Jasmine Docs: https://jasmine.github.io/2.4/introduction.html
//
/******************************************************************************/

describe("Artist model interface", function() {
  it("fetchOne should provide one artist", function(done) {
    // Some test data:
    var record = {name: "The Wombats"};

    // Pretend the server responded with the above object:
    ajaxSpy('get', record);

    // Call into the Artist model:
    Artist.fetchOne(1).then(function(artist) {
      expect(artist.name).toEqual(record.name);
      expect(artist.save).toBeDefined();
      done(); // Make sure to call `done' last.
    }).catch(function() {
      done.fail("shouldn't have failed");
    });
  });
});

Remove test that was accidentally added from a previous class


Template.tomeDetails.helpers({
    displayDate: function() {
        return moment(this.releaseDate, "YYYY/MM/DD").fromNow();
    },
    notOwned: function() {
        return !this.owned;
    },
    allTomes: function() {
        return Mangas.find({
            "user": Meteor.userId(),
            "mangasName": this.mangasName
        }, {
            sort: {
                "tomeNumber": 1
            }
        });
    }
});

Template.tomeDetails.events({
    'click #setOwnedTrue': function() {
        Meteor.call('setOwnedTrue', this._id, function(error) {
            if (error) {
                return throwError(error.message);
            }
        });
    },
    'click #setOwnedFalse': function() {
        Meteor.call('setOwnedFalse', this._id, function(error) {
            if (error) {
                return throwError(error.message);
            }
        });
    }
});

Template.tomeDetails.helpers({
    displayDate: function() {
        return moment(this.releaseDate, "YYYY/MM/DD").fromNow();
    },
    notOwned: function() {
        return !this.owned;
    },
    allTomesOwned: function() {
        return Mangas.find({
            "user": Meteor.userId(),
            "mangasName": this.mangasName,
            "owned": true
        }, {
            sort: {
                "tomeNumber": 1
            }
        });
    },
    allTomesMissing: function() {
        return Mangas.find({
            "user": Meteor.userId(),
            "mangasName": this.mangasName,
            "owned": false
        }, {
            sort: {
                "tomeNumber": 1
            }
        });
    },
    missingTome: function() {
        var a = Mangas.findOne({
            "user": Meteor.userId(),
            "mangasName": this.mangasName,
            "owned": false
        });
        if (a) {
            return true;
        } else {
            return false;
        }
    },
    ownedTome: function() {
        var a = Mangas.findOne({
            "user": Meteor.userId(),
            "mangasName": this.mangasName,
            "owned": true
        });
        if (a) {
            return true;
        } else {
            return false;
        }
    },
});

Template.tomeDetails.events({
    'click #setOwnedTrue': function() {
        Meteor.call('setOwnedTrue', this._id, function(error) {
            if (error) {
                return throwError(error.message);
            }
        });
    },
    'click #setOwnedFalse': function() {
        Meteor.call('setOwnedFalse', this._id, function(error) {
            if (error) {
                return throwError(error.message);
            }
        });
    }
});

Add helpers to know if the user own mangas or not


(function() {
  function escape(text) {
    return text
      .replace(/&/g, "&")
      .replace(/>/g, ">")
      .replace(/-->/g, "-->")
      .replace(/>>/g, ">>")
      .replace(/>\|/g, ">|")
      .replace(/</g, "<")
      .replace(/<!--/g, "<!--")
      .replace(/<</g, "<<")
      .replace(/\|</g, "|<")
      .replace(/>\|([\d\D]*?)\|</g, function(_, pre) {
        var escaped = pre
          .replace(/>>/g, ">>")
          .replace(/<</g, "<<")
          ;
        return ['>|', escaped, '|<'].join('');
      })
      ;
  }
  document.getElementById("escape").addEventListener("click", function() {
    var src = document.getElementById("source").value;
    var dst = escape(src);
    document.getElementById("destination").value = dst;
  });
})();

(function() {
  function escape(text) {
    return text
      .replace(/&/g, "&")
      .replace(/</g, "<")
      .replace(/>/g, ">")
      .replace(/<!--/g, "<!--")
      .replace(/-->/g, "-->")
      .replace(/<</g, "<<")
      .replace(/>>/g, ">>")
      .replace(/>\|/g, ">|")
      .replace(/\|</g, "|<")
      .replace(/>\|([\d\D]*?)\|</g, function(_, pre) {
        var escaped = pre
          .replace(/<</g, "<<")
          .replace(/>>/g, ">>")
          ;
        return ['>|', escaped, '|<'].join('');
      })
      ;
  }
  document.getElementById("escape").addEventListener("click", function() {
    var src = document.getElementById("source").value;
    var dst = escape(src);
    document.getElementById("destination").value = dst;
  });
})();

Refactor order of replace in escape


/*global shower*/
// Start the app
require( ['detector', 'app', 'container', 'renderer'], function ( Detector, app, container, renderer ) {
  if ( ! Detector.webgl ) {
    Detector.addGetWebGLMessage();
    container.innerHTML = "";
  }

  app.init();
  app.draw();
  var lastSlideNumber = -1;
  var rendering = false;
  var tick = function() {
    window.requestAnimationFrame( tick );
    if ( shower.isSlideMode() ) {
      var slideNumber = shower.getCurrentSlideNumber();
      if ( slideNumber !== lastSlideNumber ) {
        // Have changed slide
        lastSlideNumber = slideNumber;

        // Check for presence of threejs container in new slide
        var slideId = shower.getSlideHash( slideNumber ).slice( 1 );
        var c = document.querySelector( "[id='" + slideId + "'] .threejs-container" );
        if ( c ) {
          rendering = true;
          renderer.setContainer( c );
        } else {
          rendering = false;
        }

        // Set parameters for specific slide
        if ( slideNumber === 0 ) {
          app.spin = true;
        }
        if ( slideNumber === 1 ) {
          app.spin = false;
        }
      }

      if ( rendering ) {
        app.draw();
      }
    }
  };
  tick();
} );

/*global shower*/
// Start the app
require( ['detector', 'app', 'container', 'renderer'], function ( Detector, app, container, renderer ) {
  if ( ! Detector.webgl ) {
    Detector.addGetWebGLMessage();
    container.innerHTML = "";
  }

  app.init();
  app.draw();
  var lastSlideNumber = -1;
  var rendering = false;
  var tick = function() {
    window.requestAnimationFrame( tick );
    if ( shower.isSlideMode() ) {
      var slideNumber = shower.getCurrentSlideNumber();
      if ( slideNumber !== lastSlideNumber ) {
        // Have changed slide
        lastSlideNumber = slideNumber;

        // Check for presence of threejs container in new slide
        var slideId = shower.getSlideHash( slideNumber ).slice( 1 );
        var c = document.querySelector( "[id='" + slideId + "'] .threejs-container" );
        if ( c ) {
          rendering = true;
          renderer.setContainer( c );
        } else {
          rendering = false;
        }

        // Set parameters for specific slide
        if ( slideNumber === 0 ) {
          app.spin = true;
        }
        if ( slideNumber === 1 ) {
          setTimeout( function() { rendering = false; }, 1500 );
          app.spin = false;
        }
      }

      if ( rendering ) {
        app.draw();
      }
    }
  };
  tick();
} );

Stop rendering after delay on first slide


const assert = require('assert');
const string = require('../util/string');

TrailingWhitespacesRule = {};

TrailingWhitespacesRule.name = 'TrailingWhitespaces';

TrailingWhitespacesRule.infer = function (sample, callback) {
    callback('strip');
};

TrailingWhitespacesRule.transform = function (input, value, output) {
    assert(value === 'strip');

    input.on('data', function (token) {
        if (token.type === 'Whitespaces') {
            var lineCount = 0;
            Array.prototype.forEach.call(token.value, function (character) {
                if (character === '\n')
                    lineCount++;
            });

            var pos = token.value.lastIndexOf('\n');
            if (pos !== -1)
                token.value = '\n'.repeat(lineCount) + token.value.substr(pos + 1);
        }
        output.write(token);
    });
    input.on('end', function () {
        output.end();
    });
};

module.exports = TrailingWhitespacesRule;

const assert = require('assert');
const string = require('../util/string');

TrailingWhitespacesRule = {};

TrailingWhitespacesRule.name = 'TrailingWhitespaces';

TrailingWhitespacesRule.infer = function (sample, callback) {
    callback('strip');
};

TrailingWhitespacesRule.transform = function (input, value, output) {
    assert(value === 'strip');

    input.on('data', function (token) {

        if (token.type === 'Whitespaces') {

            var pos = token.value.lastIndexOf('\n');

            if (pos !== -1) {

	            var lineCount = (token.value.match(/\n/g)||[]).length;
                token.value = '\n'.repeat(lineCount) + token.value.substr(pos + 1);

			}

        }

        output.write(token);

    });

    input.on('end', function () {
        output.end();
    });
};

module.exports = TrailingWhitespacesRule;

Use RegEx to count lines.


import { platform, DefaultDOMElement as DOM } from 'substance'

// ATTENTION: have to use a custom getMountPoint because
// during the tests are change the behavior of platform and DefaultDOMElement
export function getMountPoint (t) {
  if (platform.inBrowser) {
    if (t.sandbox) {
      let el = t.sandbox.createElement('div')
      t.sandbox.append(el)
      return el
    } else {
      let bodyEl = DOM.wrap(window.document.body)
      let sandboxEl = bodyEl.createElement('div')
      bodyEl.append(sandboxEl)
      return sandboxEl
    }
  } else {
    // otherwise we create a detached DOM
    let htmlDoc = DOM.parseHTML('')
    return htmlDoc.find('body')
  }
}

import { platform, DefaultDOMElement as DOM, DefaultDOMElement } from 'substance'

// ATTENTION: have to use a custom getMountPoint because
// during the tests we change the behavior of platform and DefaultDOMElement
export function getMountPoint (t) {
  if (platform.inBrowser) {
    if (t.sandbox) {
      // let el = t.sandbox.createElement('div')
      // HACK: struggling to avoid that the wron substance API is used
      // i.e. substance-test is using its own version. When using the sandbox element
      // generated by the test-suite, we will not 'see' elements and components
      // created with the substance API used here
      let el = DefaultDOMElement.wrap(window.document).createElement('div')
      t.sandbox.append(el)
      return el
    } else {
      let bodyEl = DOM.wrap(window.document.body)
      let sandboxEl = bodyEl.createElement('div')
      bodyEl.append(sandboxEl)
      return sandboxEl
    }
  } else {
    // otherwise we create a detached DOM
    let htmlDoc = DOM.parseHTML('')
    return htmlDoc.find('body')
  }
}

Use correct substance API in tests.


const chordRegex = require('../src/chord-regex')
const tape = require('tape')

tape('Regex against valid chords', function (test) {
  let chords = [
    'C', 'D', 'E', 'F', 'G', 'A', 'B', // white keys
    'C#', 'Eb', 'F#', 'Ab', 'G#', 'Bb', // sharps and flats
    'Db', 'D#', 'Gb', 'A#', // for those who like to use non-canon names for sharps and flats
    'Cm', 'Cm7', 'CM7', 'Cmaj7', 'CmM7', // minors and 7ths
    'C6', 'C9', 'C11', 'C13', // few more extension chords
    'Caug', 'Cdim', 'Csus', 'Csus2', 'Csus4',
    'C/E', 'D/F#' // Slash chords
  ]

  console.log(chords.length)
  test.plan(chords.length)

  chords.forEach(chord => {
    const input = '[' + chord + ']'
    if (chordRegex.exec(input) === null || chordRegex.exec(input).length === 0) {
      test.fail('Failed for input: ' + input)
    } else {
      const match = chordRegex.exec(input)[1]
      test.equal(match, chord, input + ' passed with match ' + match)
    }
  })
})

const chordRegex = require('../src/chord-regex')
const tape = require('tape')

tape('Regex against valid chords', function (test) {
  let chords = [
    'C', 'D', 'E', 'F', 'G', 'A', 'B', // white keys
    'C#', 'Eb', 'F#', 'Ab', 'G#', 'Bb', // sharps and flats
    'Db', 'D#', 'Gb', 'A#', // for those who like to use non-canon names for sharps and flats
    'Cm', 'Caug', 'Cdim', 'Csus', 'Csus2', 'Csus4', // a few more triads
    'Cm7', 'CM7', 'Cmaj7', 'CmM7', // 7ths
    'C6', 'C9', 'C11', 'C13', // few more extension chords
    'C/E', 'D/F#' // Slash chords
  ]

  test.plan(chords.length)

  chords.forEach(chord => {
    const input = '[' + chord + ']'
    if (chordRegex.exec(input) === null || chordRegex.exec(input).length === 0) {
      test.fail('Failed for input: ' + input)
    } else {
      const match = chordRegex.exec(input)[1]
      test.equal(match, chord, input + ' passed with match ' + match)
    }
  })
})

Add alt names for 7th chords


var mousePosition = [140, 20];

$(document).on("mousemove", function (event) {
    mousePosition = [event.pageX - $('.js-mouseContainer').offset().left,
                     event.pageY - $(".js-mouseContainer").offset().top];
});
var mouseDown = false;
var rightMouseDown = false;
$(document).on('mousedown', function (event) {
    if (event.which == 1) mouseDown = true;
    else if (event.which == 3) rightMouseDown = true;
});
$(document).on('mouseup', function (event) {
    if (event.which == 1) mouseDown = false;
    else if (event.which == 3) rightMouseDown = false;
});
function relativeMousePosition(element) {
    var elementOffset = $(element).offset();
    var containerOffset = $('.js-mouseContainer').offset();
    return [mousePosition[0] - (elementOffset.left - containerOffset.left),
            mousePosition[1] - (elementOffset.top - containerOffset.top)];
}
function isMouseOverElement(element) {
    var relativePosition = relativeMousePosition(element);
    return relativePosition[0] >= 0 && relativePosition[0] <= $(element).outerWidth()
        && relativePosition[1] >= 0 && relativePosition[1] <= $(element).outerHeight();
}

var mousePosition = [140, 20];

$(document).on("mousemove", function (event) {
    mousePosition = [event.pageX - $('.js-mouseContainer').offset().left,
                     event.pageY - $(".js-mouseContainer").offset().top];
});
var mouseDown = false;
var rightMouseDown = false;
$(document).on('mousedown', function (event) {
    if (event.which == 1) mouseDown = true;
    else if (event.which == 3) rightMouseDown = true;
});
$(document).on('mouseup', function (event) {
    if (event.which == 1) mouseDown = false;
    else if (event.which == 3) rightMouseDown = false;
});
$(document).on('contextmenu', function (event) {
    mouseDown = rightMouseDown = false;
});
function relativeMousePosition(element) {
    var elementOffset = $(element).offset();
    var containerOffset = $('.js-mouseContainer').offset();
    return [mousePosition[0] - (elementOffset.left - containerOffset.left),
            mousePosition[1] - (elementOffset.top - containerOffset.top)];
}
function isMouseOverElement(element) {
    var relativePosition = relativeMousePosition(element);
    return relativePosition[0] >= 0 && relativePosition[0] <= $(element).outerWidth()
        && relativePosition[1] >= 0 && relativePosition[1] <= $(element).outerHeight();
}

Fix opening context menu was leaving rightMouseDown stuck on true.


"use strict";

var path = '../';

jest.autoMockOff();
jest.mock('../../../api/user');

describe('TotalTrack Component', function() {
  var React       = require('react/addons');
  var user        = require('../../../api/user');
  var TestUtils   = React.addons.TestUtils;
  var findByClass = TestUtils.findRenderedDOMComponentWithClass;
  var TotalTracks = require(path);
  var Component;

  beforeEach(function() {
    user.getInfo.mockClear();
    Component = TestUtils.renderIntoDocument(<TotalTracks />);
  });

  describe('When data is requested', function() {
    it('Makes one correct request for the data', function() {
      expect(user.getInfo.mock.calls.length).toEqual(1);
    });

    it('Accepts a callback function', function() {
      expect(user.getInfo).toBeCalledWith(Component.setPlayCount);
    });
  });

  describe('When no data is returned', function() {
    beforeEach(function() {
      Component.setPlayCount(null);
    });

    it('Adds an error class to the container element', function() {
      var element = findByClass(Component, "TotalTracks--error");
      var errorMsg = findByClass(Component, "TotalTracks__error-msg");

      expect(element).toBeDefined();
      expect(errorMsg).toBeDefined();
    });

    it('Attempts to re-load itself', function() {
      expect(user.getInfo).toBeCalledWith(Component.setPlayCount);
      expect(user.getInfo.mock.calls.length > 1).toBeTruthy();
    });
  });

  describe('When the component is loading', function() {
    it('Displays a loading icon by default', function() {
      var spinner = findByClass(Component, "TotalTracks__spinner");
      expect(spinner).toBeDefined();
    });
  });

  describe('When data is retreived', function() {
    beforeEach(function() {
      Component.setState({
        loading: false,
        playCount: 10000
      });
    });

    it('Displays a formatted playcount', function() {
      var playcount = findByClass(Component, "TotalTracks__playcount");

      expect(playcount).toBeDefined();
      expect(playcount.getDOMNode().textContent).toBe('10,000');
    });

    it('Displays a label', function() {
      var label = findByClass(Component, "TotalTracks__label");
      expect(label.getDOMNode().textContent).toBe('Tracks Played');
    });
  });
});

'use strict';

jest.autoMockOff();

describe('TotalTrack Component', function() {
  var React       = require('react/addons');
  var TestUtils   = React.addons.TestUtils;
  var findByClass = TestUtils.findRenderedDOMComponentWithClass;
  var TotalTracks = require('../');
  var Component;

  beforeEach(function() {
    Component = TestUtils.renderIntoDocument(<TotalTracks playCount="10000" />);
  });

  it('Displays a formatted playcount', function() {
    var playcount = findByClass(Component, "TotalTracks__playcount");

    expect(playcount).toBeDefined();
    expect(playcount.getDOMNode().textContent).toBe('10,000');
  });

  it('Displays a label', function() {
    var label = findByClass(Component, "TotalTracks__label");
    expect(label.getDOMNode().textContent).toBe('Tracks Played');
  });
});

Fix TotalTracks test after ES6 conversion


import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';

setApplication(Application.create(config.APP));

start();

import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
import * as QUnit from 'qunit';
import { setup } from 'qunit-dom';

setup(QUnit.assert);

setApplication(Application.create(config.APP));

start();

Add missing qunit-dom initialization code


defaultConstructor = function(attrs) {
  var doc = this;
  var Class = doc.constructor;
  attrs = attrs || {};

  // Create "_values" property when legacy browsers support is turned on.
  if (!Astro.config.supportLegacyBrowsers) {
    doc._values = {};
  }

  // Set values of all fields.
  Astro.utils.fields.setAllValues(doc, attrs, {
    cast: true,
    default: true
  });

  // Create the "_original" property inside the document for storing original
  // object's values (before any modifications). Thanks to it, we can compare
  // "_original" values with the current values and decide what fields have been
  // modified. Now, let's copy current values to the original property but only
  // if there is the "_id" property. Otherwise we only copy the "_id" property.
  // Thanks to that, if there is no "_id" property, then we can set fields of
  // the new document on the initiation stage. If there is the "_id" property
  // it means that we are fetching document from the collection.
  if (_.isString(attrs._id)) {
    doc._original = EJSON.clone(Astro.utils.fields.getAllValues(doc, {
      cast: false,
      default: false,
      plain: false
    }));
  } else {
    doc._original = {
      _id: attrs._id
    };
  }

  // Set the "_isNew" flag indicating if an object had been persisted in the
  // collection.
  doc._isNew = true;
};

defaultConstructor = function(attrs) {
  var doc = this;
  var Class = doc.constructor;
  attrs = attrs || {};

  // Create "_values" property when legacy browsers support is turned on.
  if (!Astro.config.supportLegacyBrowsers) {
    doc._values = {};
  }

  // Set values of all fields.
  Astro.utils.fields.setAllValues(doc, attrs, {
    cast: true,
    default: true
  });

  // 1. Create the "_original" property inside the document for storing original
  // object's values (before any modifications). Thanks to it, we can compare
  // "_original" values with the current values and decide what fields have been
  // modified.
  // 2. Copy values to the "_original" property, if it's an already saved
  // document fetched from the collection or a document that does not get stored
  // in the collection directly.
  if (attrs._id || !Class.getCollection()) {
    doc._original = EJSON.clone(Astro.utils.fields.getAllValues(doc, {
      cast: false,
      default: false,
      plain: false
    }));
  } else {
    doc._original = {
      _id: attrs._id
    };
  }

  // Set the "_isNew" flag indicating if an object had been persisted in the
  // collection.
  doc._isNew = true;
};

Make nested docs not modified by default


/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2021
 */

import { UIDatabase } from '../database/index';

const PATIENT_SURVEY_TYPE = 'PatientSurvey';
const VACCINE_SUPPLEMENTAL_DATA = 'VaccineSupplementalData';

export const selectSurveySchemas = () =>
  UIDatabase.objects('FormSchema').filtered(`type=='${PATIENT_SURVEY_TYPE}'`);

export const selectSupplementalDataSchemas = () =>
  UIDatabase.objects('FormSchema').filtered(`type=='${VACCINE_SUPPLEMENTAL_DATA}'`);

/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2021
 */

import { UIDatabase } from '../database/index';

const PATIENT_SURVEY_TYPE = 'PatientSurvey';
const VACCINE_SUPPLEMENTAL_DATA = 'VaccineSupplementalData';

export const selectSurveySchemas = () => selectFormSchema(`type=='${PATIENT_SURVEY_TYPE}'`);

export const selectSupplementalDataSchemas = () =>
  selectFormSchema(`type=='${VACCINE_SUPPLEMENTAL_DATA}'`);

const selectFormSchema = filter =>
  UIDatabase.objects('FormSchema').filtered(filter).sorted('version', true);

Sort form schemas by version and return highest version


  var down = function () {
    $("#plane").animate({
      top: "-=10",
    }, 3000)
  };

  var up = function () {
    $("#plane").animate({
      top: "+=10",
    }, 3000)
  };

  var turbulance = function () {
    up();
    down();
    console.log("called method ")
  };

$(document).ready(function(){

  // when page loads plane flys in from the right of the page and then images will appear in the windows

  //top right corner of the image going to be x, y 0
  $("#plane").animate({
    right: "+=800",
  }, 3000, function(){
    setInterval(turbulance, 1000);
  })

  $("#window-container").animate({
    right: "+=900",
  }, 3000, function(){
    // setInterval(turbulance, 1000);
  })

});

  var down = function () {
    $("#plane").animate({
      top: "-=10",
    }, 3000)
  };

  var up = function () {
    $("#plane").animate({
      top: "+=10",
    }, 3000)
  };

  var turbulance = function () {
    up();
    down();
    console.log("called method ")
  };

$(document).ready(function(){

  // when page loads plane flys in from the right of the page and then images will appear in the windows

  //top right corner of the image going to be x, y 0
  $("#plane").animate({
    left: "+=85%",
  }, 4000, function(){
    // setInterval(turbulance, 1000);
  })

  // $("#window-container").animate({
  //   right: "+=900",
  // }, 3000, function(){
  //   // setInterval(turbulance, 1000);
  // })

});

Change animation to have plane fly in from left


//= require foundation/foundation
//= require foundation/foundation.alerts
//= require foundation/foundation.interchange
//= require foundation/foundation.orbit
//= require foundation/foundation.reveal
//= require foundation/foundation.tooltips
//= require foundation/foundation.topbar

// The order matters

//= require foundation/foundation
//= require foundation/foundation.alerts
//= require foundation/foundation.interchange
//= require foundation/foundation.orbit
//= require foundation/foundation.reveal
//= require foundation/foundation.topbar
//= require foundation/foundation.tooltips

Fix test where order matters


/**
 * Creates a new sprite.
 *
 * @constructor
 * @param {string} image The URL of the image to make a sprite from.
 */
function Sprite(image, onload) {
    this.image = new Image();
    this.image.src = image;

    var sprite = this;
    this.image.onload = function OnImageLoad(event) {
        sprite.size = new Vector2(sprite.image.width, sprite.image.height);
        Log.info(sprite.size + " sprite loaded: " + sprite.image.src, "OnImageLoad");

        if (typeof onload === 'function') {
            onload();
        } else if(typeof onload !== 'undefined') {
            throw new InvalidArgumentError("onload", "onload should be a function! Received: " + onload);
        }
    }
}

/**
 * Render this sprite to a screen.
 *
 * @param {Screen}  screen   The screen to render this sprite to.
 * @param {Vector2} position The position to render this sprite on.
 */
Sprite.prototype.render = function (screen, position) {
    screen.render(this.image, position, this.size);
};

/**
 * @override
 * @returns {string} The textual representation of this object.
 */
Sprite.prototype.toString = function () {
    return "Sprite { " + this.image.src + " }"
};

/**
 * Creates a new Sprite.
 *
 * @constructor
 * @param {string} image The URL of the image to make a sprite from.
 */
function Sprite(image, onload) {
    this.image = new Image();
    this.image.src = image;

    var sprite = this;
    this.image.onload = function OnImageLoad(event) {
        sprite.size = new Vector2(sprite.image.width, sprite.image.height);
        Log.info(sprite.size + " sprite loaded: " + sprite.image.src, "OnImageLoad");

        if (typeof onload === 'function') {
            onload();
        } else if(typeof onload !== 'undefined') {
            throw new InvalidArgumentError("onload", "onload should be a function! Received: " + onload);
        }
    }
}

/**
 * Render this sprite to a screen.
 *
 * @param {Screen}  screen   The screen to render this sprite to.
 * @param {Vector2} position The position to render this sprite on.
 */
Sprite.prototype.render = function (screen, position) {
    screen.render(this.image, position, this.size);
};

/**
 * @override
 * @returns {string} The textual representation of this object.
 */
Sprite.prototype.toString = function () {
    return "Sprite { " + this.image.src + " }"
};

Change constructor documentation to use a capital S.


$(document).ready(() => {
  $('#dialog').dialog({
    title: 'Add New Todo',
    autoOpen: false,
    modal: true,
    show: {
      effect: 'blind',
      duration: 1000
    },
    hide: {
      effect: 'blind',
      duration: 1000
    },
    buttons: [{
      text: 'Add',
      click: function() {
        $(this).dialog('close')
      }
    }]
  });

  $('#opener').click(() => {
    $('#dialog').dialog('open');
  })
})

$(document).ready(() => {
  $('#dialog').dialog({
    title: 'Add New Todo',
    autoOpen: false,
    modal: true,
    show: {
      effect: 'blind',
      duration: 1000
    },
    hide: {
      effect: 'blind',
      duration: 1000
    },
    buttons: [{
      text: 'Add',
      click: function() {
        $(this).dialog('close')
      }
    }]
  });

  $('#opener').click(() => {
    $('#dialog').dialog('open');
  })

// Click listener for todo items
  $('li').click(() => {
    $(event.target).toggleClass('completed')
  })

})

Create click event to indicate when todo complete


define([
  'underscore', 'controllers/ApplicationController', 'models/Thread', 'models/Message', 'utils/Utils'
], function(_, ApplicationController, Thread, Message, Utils) {
  var MessageController = Utils.inherit(ApplicationController, function(networkAgent) {
    ApplicationController.call(this, networkAgent);
  });

  MessageController.prototype.create = function(args, format) {
    var self = this;

    Message.new(args).exists(function(exists) {
      Message.create(args, function(message, error) {
        if (error) {
          throw new Error("Failed to create message:", error);
        }

        Utils.debug("Created or updated message:", message.id);

        if (!exists) {
          Utils.debug("Spreading message:", message.id);
          self._networkAgent.spreadMessage(message.toJson());
        }

        self._response(format, {
          html: function() {
            WebRtcBbs.context.routing.to('/thread/show', {threadId: args.threadId});
          }
        });
      });
    });
  };

  return MessageController;
});

define([
  'underscore', 'controllers/ApplicationController', 'models/Thread', 'models/Message', 'utils/Utils'
], function(_, ApplicationController, Thread, Message, Utils) {
  var MessageController = Utils.inherit(ApplicationController, function(networkAgent) {
    ApplicationController.call(this, networkAgent);
  });

  MessageController.prototype.create = function(args, format) {
    var self = this;

    Message.new(args).exists(function(exists) {
      Message.create(args, function(message, error) {
        if (error) {
          throw new Error("Failed to create message:", error);
        }

        Utils.debug("Created or updated message:", message.id);

        if (!exists) {
          Utils.debug("Spreading message:", message.id);
          self._networkAgent.spreadMessage(message.toJson());
        }

        self._response(format, {
          html: function() {
            WebRtcBbs.context.routing.to('/thread/show', {threadId: args.threadId}, true);
          }
        });
      });
    });
  };

  return MessageController;
});

Modify not to push state to history on posting message.


import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('tags-widget', 'Integration | Component | tags widget', {
  integration: true
});

test('it renders', function(assert) {
  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });

  this.render(hbs`{{tags-widget}}`);

  assert.equal(this.$().text().trim(), '');

  // Template block usage:
  this.render(hbs`
    {{#tags-widget}}
      template block text
    {{/tags-widget}}
  `);

  assert.equal(this.$().text().trim(), 'template block text');
});

import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('tags-widget', 'Integration | Component | tags widget', {
  integration: true
});

test('it renders a tag', function(assert) {
  // Set any properties with this.set('myProperty', 'value');
  // Handle any actions with this.on('myAction', function(val) { ... });
  this.set('tags', ["hello"]);

  this.render(hbs`{{tags-widget tags=tags}}`);

  assert.equal(this.$('span').text().trim(), 'hello');
});

Add test for tags component.


angular.module('MyModule')
    .controller('circlecontroller', function ($scope, $timeout, KineticService, UtilityService, AgentService) {
       'use strict';

       var stage = {};
       function init() {
          $scope.pageName = "CIRCLES";
          stage = KineticService.createStage('container', 1024, 768);

          for (var i = 0; i < 5; i++) {
             var v1 = new Vec2(UtilityService.randomInt( -10, 10), UtilityService.randomInt( -10, 10));
             v1.normalize();
             AgentService.createAgent(stage, null, v1, UtilityService.randomInt(4, 20));
          }
       }

       init();

       $scope.onTimeout = function () {
          mytimeout = $timeout($scope.onTimeout, 40);

          AgentService.checkAllBoundaries(stage.getWidth(), stage.getHeight());

          AgentService.moveAllAgents();

          AgentService.drawAllLayers();
       };

       var mytimeout = $timeout($scope.onTimeout, 40);

       $scope.$on("$destroy", function () {
          $timeout.cancel(mytimeout);
       });

    });

angular.module('MyModule')
    .controller('circlecontroller', function ($scope, $timeout, KineticService, UtilityService, AgentService) {
       'use strict';

       var stage = {};
       function init() {
          $scope.pageName = "CIRCLES";
          stage = KineticService.createStage('container', 1024, 768);

          for (var i = 0; i < 25; i++) {
             var v1 = new Vec2(UtilityService.randomInt( -10, 10), UtilityService.randomInt( -10, 10));
             v1.normalize();
             AgentService.createAgent(stage, null, v1, UtilityService.randomInt(4, 20));
          }
       }

       init();

       $scope.onTimeout = function () {
          mytimeout = $timeout($scope.onTimeout, 40);

          AgentService.checkAllBoundaries(stage.getWidth(), stage.getHeight());

          AgentService.moveAllAgents();

          AgentService.drawAllLayers();
       };

       var mytimeout = $timeout($scope.onTimeout, 40);

       $scope.$on("$destroy", function () {
          $timeout.cancel(mytimeout);
       });

    });

Increase to 25 agents for iOS performance test.


import assert from 'assert';
import SpiesTeardown from './spies-teardown';
import ReactTester from '../../../src/index';

describe('spies teardown', () => {
  let component;

  beforeEach(() => {
    component = ReactTester
      .create()
      .use(SpiesTeardown);
  });

  describe('refreshes spies each time', () => {
    beforeEach(() => {
      component
        .addFlavour('lemon', {});
    });

    it('is called once the first time I check', () => {
      const callcount = component.ComponentToUse.prototype.spiedOn.callCount;

      assert(callcount, 1);
    });

    it('is called once the second time I check', () => {
      const callcount = component.ComponentToUse.prototype.spiedOn.callCount;

      assert(callcount, 1);
    });
  });

  describe('allows me to tear down when I want to', () => {
    beforeEach(() => {
      component
        .addFlavour('chocolate', {});
    });

    it('spies automatically', () => {
      const isSpy = component.ComponentToUse.prototype.spiedOn.isSinonProxy;

      assert(isSpy, true);
    });

    it('can be unwrapped', () => {
      component.teardown();
      const isSpy = typeof component.ComponentToUse.prototype.spiedOn.isSinonProxy;

      assert(isSpy, 'undefined');
    });
  });
});

import assert from 'assert';
import SpiesTeardown from './spies-teardown';
import ReactTester from '../../../src/index';

describe('spies teardown', () => {
  let tester;

  beforeEach(() => {
    tester = ReactTester
      .create()
      .use(SpiesTeardown);
  });

  describe('refresh spies each time should', () => {
    beforeEach(() => tester.addFlavour('LEMON', {}));

    it('allow normal spy behaviour on the first test pass', () => {
      const actual = tester.ComponentToUse.prototype.spiedOn.callCount;
      const expected = 1;

      assert(actual, expected);
    });

    it('allow normal spy behaviour on the second test pass', () => {
      const actual = tester.ComponentToUse.prototype.spiedOn.callCount;
      const expected = 1;

      assert(actual, expected);
    });
  });

  describe('should', () => {
    beforeEach(() => tester.addFlavour('CHOCOLATE', {}));

    it('add spies automatically', () => {
      const actual = tester.ComponentToUse.prototype.spiedOn.isSinonProxy;
      const expected = true;
      assert(actual, expected);
    });

    it('allow them to be unwrapped', () => {
      tester.teardown();
      const actual = typeof tester.ComponentToUse.prototype.spiedOn.isSinonProxy;
      const expected = 'undefined';

      assert(actual, expected);
    });
  });
});

Bring tests inline with CraigB style


'use strict';

// MODULES //

var debug = require( 'debug' )( 'time-series:set:x' );
var isTypedArray = require( '@stdlib/utils/is-typed-array' );
var isNumberArray = require( '@stdlib/utils/is-number' ).isPrimitiveNumberArray;
var isEmptyArray = require( '@stdlib/utils/is-empty-array' );
var events = require( './../../events' );

// VARIABLES //

var CHANGE_EVENT = events( 'x' );

// SET //

/**
* Sets the plot x-values.
*
* @private
* @param {(NumericArray|EmptyArray)} x - x-values
* @throws {TypeError} must be a numeric or empty array
*/
function set( x ) {
	/*jshint validthis: true */ // TODO: eslint

	// TODO: allow a Date array; convert to timestamps
	if (
		!isTypedArray( x ) &&
		!isNumberArray( x ) &&
		!isEmptyArray( x )
	) {
		throw new TypeError( 'invalid value. `x` must be a numeric or empty array. Value: `' + x + '`.' );
	}
	debug( 'Current value: %s.', JSON.stringify( this._xData ) );

	// TODO: copy?
	this._xData = x;
	debug( 'New Value: %s.', JSON.stringify( this._xData ) );

	this.emit( CHANGE_EVENT );
} // end FUNCTION set()

// EXPORTS //

module.exports = set;

'use strict';

// MODULES //

var debug = require( 'debug' )( 'time-series:set:x' );
var isTypedArray = require( '@stdlib/utils/is-typed-array' );
var isNumberArray = require( '@stdlib/utils/is-number' ).isPrimitiveNumberArray;
var isEmptyArray = require( '@stdlib/utils/is-empty-array' );
var events = require( './../../events' );

// VARIABLES //

var CHANGE_EVENT = events( 'x' );

// SET //

/**
* Sets the plot x-values.
*
* @private
* @param {(NumericArray|EmptyArray)} x - x-values
* @throws {TypeError} must be a numeric or empty array
*/
function set( x ) {
	/*jshint validthis: true */ // TODO: eslint

	// TODO: allow a Date array; convert to timestamps
	if (
		!isTypedArray( x ) &&
		!isEmptyArray( x ) &&
		!isNumberArray( x )
	) {
		throw new TypeError( 'invalid value. `x` must be a numeric or empty array. Value: `' + x + '`.' );
	}
	debug( 'Current value: %s.', JSON.stringify( this._xData ) );

	// TODO: copy?
	this._xData = x;
	debug( 'New Value: %s.', JSON.stringify( this._xData ) );

	this.emit( CHANGE_EVENT );
} // end FUNCTION set()

// EXPORTS //

module.exports = set;

Move most expensive type check to last


'use strict';

var helpers = require('../helpers');

module.exports = {
  'name': 'no-qualifying-elements',
  'defaults': {
    'allow-element-with-attribute': false,
    'allow-element-with-class': false,
    'allow-element-with-id': false
  },
  'detect': function (ast, parser) {
    var result = [];

    ast.traverseByTypes(['simpleSelector'], function (selectors) {

      selectors.content.forEach(function (item, i) {
        if (item.is('class') || item.is('attribute') || item.is('id')) {
          var previous = selectors.content[i - 1] || false;

          if (previous && previous.is('ident')) {
            if (!parser.options['allow-element-with-' + item.type]) {
              result = helpers.addUnique(result, {
                'ruleId': parser.rule.name,
                'line': item.start.line,
                'column': item.start.column,
                'message': 'Qualifying element not allowed for ' + item.type,
                'severity': parser.severity
              });
            }
          }
        }
      });
    });

    return result;
  }
};

'use strict';

var helpers = require('../helpers');

module.exports = {
  'name': 'no-qualifying-elements',
  'defaults': {
    'allow-element-with-attribute': false,
    'allow-element-with-class': false,
    'allow-element-with-id': false
  },
  'detect': function (ast, parser) {
    var result = [];

    ast.traverseByType('simpleSelector', function (selectors) {

      selectors.content.forEach(function (item, i) {
        if (item.is('class') || item.is('attribute') || item.is('id')) {
          var previous = selectors.content[i - 1] || false;

          if (previous && previous.is('ident')) {
            if (!parser.options['allow-element-with-' + item.type]) {
              result = helpers.addUnique(result, {
                'ruleId': parser.rule.name,
                'line': item.start.line,
                'column': item.start.column,
                'message': 'Qualifying element not allowed for ' + item.type,
                'severity': parser.severity
              });
            }
          }
        }
      });
    });

    return result;
  }
};

Change types to type as only one type


'use strict';

var _ = require('lodash'),
    path = require('path');

_.extend(exports, {
  envOverrides: {},

  supervisordConfigPath: function() {
    var config = require('api-umbrella-config').global();
    return path.join(config.get('etc_dir'), 'supervisord.conf');
  },

  env: function() {
    return _.merge({
      'PATH': [
        path.resolve(__dirname, '../bin'),
        path.resolve(__dirname, '../node_modules/.bin'),
        '/opt/api-umbrella/embedded/elasticsearch/bin',
        '/opt/api-umbrella/embedded/sbin',
        '/opt/api-umbrella/embedded/bin',
        '/opt/api-umbrella/embedded/jre/bin',
        '/usr/local/sbin',
        '/usr/local/bin',
        '/usr/sbin',
        '/usr/bin',
        '/sbin',
        '/bin',
      ].join(':'),
    }, this.envOverrides);
  },

  overrideEnv: function(overrides) {
    this.envOverrides = overrides;
  },
});

'use strict';

var _ = require('lodash'),
    path = require('path');

_.extend(exports, {
  envOverrides: {},

  supervisordConfigPath: function() {
    var config = require('api-umbrella-config').global();
    return path.join(config.get('etc_dir'), 'supervisord.conf');
  },

  env: function() {
    return _.merge({
      'PATH': [
        path.resolve(__dirname, '../bin'),
        path.resolve(__dirname, '../node_modules/.bin'),
        '/opt/api-umbrella/embedded/elasticsearch/bin',
        '/opt/api-umbrella/embedded/sbin',
        '/opt/api-umbrella/embedded/bin',
        '/opt/api-umbrella/embedded/jre/bin',
        '/usr/local/sbin',
        '/usr/local/bin',
        '/usr/sbin',
        '/usr/bin',
        '/sbin',
        '/bin',
      ].join(':'),

      // Reset Ruby related environment variables. This is in case the system
      // being installed onto has something like rvm/rbenv/chruby in place.
      // This ensures that we're using our API Umbrella bundled version of Ruby
      // on PATH rather than another version.
      'GEM_HOME': '',
      'GEM_PATH': '',
      'GEM_ROOT': '',
      'RUBYOPT': '',
      'RUBY_ENGINE': '',
      'RUBY_ROOT': '',
      'RUBY_VERSION': '',
    }, this.envOverrides);
  },

  overrideEnv: function(overrides) {
    this.envOverrides = overrides;
  },
});

Reset Ruby environment variables before launching.


þ.extend('CHAINABLES', {

    addClass: function (values) {
        var i, þnodes = this;

        if (typeof values === "string") values = [values];

        return this.each(function (nodeIndex) {
            //each node
            for (i = 0; i < values.length; i++) {
                //each value
                if (!þnodes.hasClass(values[i], nodeIndex)) {
                    if (this.className)
                        this.className = this.className + ' ' + values[i];
                    else
                        this.className = values[i];
                }
            }
        }, true);
    },

    removeClass: function (values) {
        var i;

        if (typeof values === "string") values = [values];

        return this.each(function (nodeIndex) {
            for (i = 0; i < values.length; i++) {
                //
                var classNames = this.className.split(' ');
                var position = classNames.indexOf(values[i]);
                if (position >= 0) {
                    classNames.splice(position, 1); //Deleted it from array
                    this.className = classNames.join(' ');//Join remaining
                }
            }
        }, true);

    },

});

þ.extend('CHAINABLES', {
    //Add a single or an array of classes to this.nodes
    addClass: function (values) {
        var i, þnodes = this;

        if (typeof values === "string") values = [values];

        return this.each(function (nodeIndex) {
            //each node
            for (i = 0; i < values.length; i++) {
                //each value
                if (!þnodes.hasClass(values[i], nodeIndex)) {
                    if (this.className)
                        this.className = this.className + ' ' + values[i];
                    else
                        this.className = values[i];
                }
            }
        }, true);
    },

    //Remove a single or an array of classes from this.nodes
    removeClass: function (values) {
        var i;

        if (typeof values === "string") values = [values];

        return this.each(function (nodeIndex) {
            for (i = 0; i < values.length; i++) {
                var classNames = this.className.split(' ');
                var position = classNames.indexOf(values[i]);
                if (position >= 0) {
                    classNames.splice(position, 1); //Deleted it from array
                    this.className = classNames.join(' ');//Join remaining
                }
            }
        }, true);

    },

});

Add comments and cleanup syntax


/*
Copyright 2016 OpenMarket Ltd

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.
*/

var q = require("q");
var request = require('browser-request');

var SdkConfig = require('./SdkConfig');

class ScalarAuthClient {
    getScalarToken(openid_token_object) {
        var defer = q.defer();

        var scalar_rest_url = SdkConfig.get().integrations_rest_url;
        request({
            method: 'POST',
            uri: scalar_rest_url+'/register',
            body: openid_token_object,
            json: true,
        }, (err, response, body) => {
            if (err) {
                defer.reject(err);
            } else if (response.statusCode / 100 !== 2) {
                defer.reject({statusCode: response.statusCode});
            } else {
                defer.resolve(body.access_token);
            }
        });

        return defer.promise;
    }
}

module.exports = ScalarAuthClient;

/*
Copyright 2016 OpenMarket Ltd

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.
*/

var q = require("q");
var request = require('browser-request');

var SdkConfig = require('./SdkConfig');

class ScalarAuthClient {
    getScalarToken(openid_token_object) {
        var defer = q.defer();

        var scalar_rest_url = SdkConfig.get().integrations_rest_url;
        request({
            method: 'POST',
            uri: scalar_rest_url+'/register',
            body: openid_token_object,
            json: true,
        }, (err, response, body) => {
            if (err) {
                defer.reject(err);
            } else if (response.statusCode / 100 !== 2) {
                defer.reject({statusCode: response.statusCode});
            } else if (!body || !body.scalar_token) {
                defer.reject(new Error("Missing scalar_token in response"));
            } else {
                defer.resolve(body.scalar_token);
            }
        });

        return defer.promise;
    }
}

module.exports = ScalarAuthClient;

Change register response access_token to scalar_token


Application.Services.factory('ProcessList',
                             ["Restangular", "pubsub", processListService]);
function processListService(Restangular, pubsub) {
    var service = {
        processes: {}
    };

    return {
        getProcesses: function(project_id){
            if (service.processes.hasOwnProperty(project_id)){
                return service.processes[project_id];
            } else {
                this.loadProcesses(project_id);
            }
        },

        loadProcesses: function (project_id) {
            Restangular.one('processes').one('project', project_id).getList().then(function(data){
                service.processes[project_id] = data;
            });
        }
    };

}

Application.Services.factory('ProcessList',
                             ["Restangular", "$q", processListService]);
function processListService(Restangular, $q) {
    var service = {
        processes: {}
    };

    return {
        getProcesses: function(project_id){
            var deffered = $q.defer();
            var pid = project_id;
            if (service.processes.hasOwnProperty(project_id)){
                deffered.resolve(service.processes[project_id]);
            } else {
                Restangular.one('processes').one('project', project_id)
                    .getList().then(function(processes){
                        service.processes[pid] = processes;
                        deffered.resolve(service.processes[pid]);
                    });
            }
            return deffered.promise;
        }
    };
}

Return promises. Fix missing return in else statement.


var BlockDevice = require( 'blockdevice' )
var Disk = require( 'disk' )
var ExFAT = require( '..' )
var assert = require( 'assert' )

var log = console.log.bind( console )
var inspect = function( value ) {
  return require( 'util' ).inspect( value, {
    colors: true,
    // depth: null,
  })
}

suite( 'ExFAT', function() {

  var device = null
  var disk = null
  var partition = null
  var volume = null

  suiteSetup( 'Create BlockDevice', function() {
    device = new BlockDevice({
      path: __dirname + '/data/usb-thumb-exfat.bin',
      mode: 'r',
      blockSize: 512,
    })
  })

  suiteSetup( 'Open Disk', function( done ) {
    disk = new Disk( device )
    disk.open( done )
  })

  test( 'Instance ExFAT Volume', function( done ) {

    log( inspect( disk ) )
    log( '' )

    var part = disk.mbr.partitions[0]
    partition = device.partition({
      firstLBA: part.firstLBA,
      lastLBA: part.firstLBA + part.sectors
    })

    volume = new ExFAT.Volume( partition )

    volume.mount( function( error ) {
      log( inspect( volume ) )
      log( '' )
      done( error )
    })

  })

  teardown( 'Close Disk', function( done ) {
    disk.close( done )
  })

})

var BlockDevice = require( 'blockdevice' )
var Disk = require( 'disk' )
var ExFAT = require( '..' )
var assert = require( 'assert' )

var log = console.log.bind( console )
var inspect = function( value ) {
  return require( 'util' ).inspect( value, {
    colors: true,
    // depth: null,
  })
}

suite( 'ExFAT', function() {

  var device = null
  var disk = null
  var partition = null
  var volume = null

  suiteSetup( 'Create BlockDevice', function() {
    device = new BlockDevice({
      path: __dirname + '/data/usb-thumb-exfat.bin',
      mode: 'r',
      blockSize: 512,
    })
  })

  suiteSetup( 'Open Disk', function( done ) {
    disk = new Disk( device )
    disk.open( function( error ) {
      if( error ) console.log( 'ERROR', error.message )
      // log( inspect( disk ) )
      // log( '' )
      done()
    })
  })

  test( 'Instance ExFAT Volume', function( done ) {

    log( inspect( disk ) )
    log( '' )

    var part = disk.mbr.partitions[0]

    partition = device.partition({
      firstLBA: part.firstLBA,
      lastLBA: part.firstLBA + part.sectors
    })

    volume = new ExFAT.Volume( partition )

    volume.mount( function( error ) {
      log( inspect( volume ) )
      log( '' )
      done( error )
    })

  })

  suiteTeardown( 'Close Disk', function( done ) {
    disk.close( done )
  })

})

Update test: Fix missing callbacks


import { jsdom } from 'jsdom';

// NOTE: emulate browser environment with `jsdom`.
global.document = jsdom('<body></body>');
global.window = document.defaultView;
global.navigator = window.navigator;

// NOTE: some libraries use `__DEV__` constant for showing some development
//       information. For example, `react-router` use it for showing warnings.
//       In test environment we don't have webpack plugins, because just
//       define this constant and set it to `false`.
global.__DEV__ = true; // eslint-disable-line

// NOTE: mock function for unloadable modules.
function noop() { }

// NOTE: load `.jss` as JavaScript module
require.extensions['.jss'] = require.extensions['.js'];

// NOTE: don't load anything, if module require other `.css` module.
require.extensions['.css'] = noop;

// NOTE: don't load anything, if module require other `.pcss` module.
require.extensions['.pcss'] = noop;

Add cap for `.pcss` files in tests


const Long = require('long')

module.exports = offset => !offset || Long.fromValue(offset).compare(0) === -1

const Long = require('long')

module.exports = offset => !offset || Long.fromValue(offset).isNegative()

Check for "offset is negative" directly


module.exports = {
  stories: ['../stories/**/*.stories.json'],
  logLevel: 'debug',
  addons: [
    '@storybook/addon-docs',
    '@storybook/addon-a11y',
    '@storybook/addon-actions',
    '@storybook/addon-backgrounds',
    '@storybook/addon-links',
    '@storybook/addon-controls',
  ],
};

module.exports = {
  stories: ['../stories/**/*.stories.@(json|yaml)'],
  logLevel: 'debug',
  addons: [
    '@storybook/addon-docs',
    '@storybook/addon-a11y',
    '@storybook/addon-actions',
    '@storybook/addon-backgrounds',
    '@storybook/addon-links',
    '@storybook/addon-controls',
  ],
};

Add `yaml` extension to the stories glob