(function ()
{
	'use strict';
	angular
		.module('PLMApp')
		.factory('BaseballSecondView', BaseballSecondView);

	function BaseballSecondView()
	{
		var ctx;
		var canvasWidth;
		var canvasHeight;

		var service = {
			draw: draw,
		};

		return service;

		function initUtils(canvas, baseballWorld)
		{
			ctx = canvas.getContext('2d');
			canvasWidth = canvas.width;
			canvasHeight = canvas.height;
		};

		function draw(canvas, baseballWorld)
		{
			initUtils(canvas, baseballWorld);
			ctx.beginPath();

			//draws edge of our drawArena
			ctx.strokeRect(0,0, canvasWidth, canvasHeight);
			ctx.closePath();
		};

	};

})();

(function ()
{
	'use strict';
	angular
		.module('PLMApp')
		.factory('BaseballSecondView', BaseballSecondView);

	function BaseballSecondView()
	{
		var ctx;
		var canvasWidth;
		var canvasHeight;

		var service = {
			draw: draw,
		};

		return service;

		function initUtils(canvas, baseballWorld)
		{
			ctx = canvas.getContext('2d');
			canvasWidth = canvas.width;
			canvasHeight = canvas.height;
		};

		function draw(canvas, baseballWorld)
		{
			initUtils(canvas, baseballWorld);
			ctx.beginPath();
			ctx.strokeStyle = '#000000';
			//draws edge of our drawArena
			ctx.strokeRect(0,0, canvasWidth, canvasHeight);
			ctx.closePath();
		};

	};

})();

Put the color black for the canvas border


Template.postsList.helpers({
  posts: function() {
    return Posts.find();
  }
});

Template.postsList.helpers({
  posts: function() {
    return Posts.find({}, {sort: {submitted: -1}});
  }
});

Sort posts by submitted timestamp.


// ==UserScript==
// @name         Anchor tags in Central
// @namespace    http://central.tri.be/
// @version      0.1
// @description  Adds anchor tags to some links in central
// @author       You
// @include        /^https:\/\/central.tri.be(\/.*)?/
// @grant        none
// ==/UserScript==

var central_links = {};

( function( $, my ) {
    my.init = function() {
        my.$pr_heading = $( 'table.attributes th:contains(Pull Request:)' );
        var $link_cell = my.$pr_heading.next();
        var link = $link_cell.html();
        $link_cell.html( '' + link + '' );

        my.$forum_heading = $( 'table.attributes th:contains(Forum threads:)' );
        $link_cell = my.$forum_heading.next();
        var links = $link_cell.html().split( "
" );
        for ( var i in links ) {
            links[i] = String( links[i] ).replace( /(http[^\n <]+)/, '$1' );
        }

        $link_cell.html( links.join( '
' ) );
    };

    $( function() {
        my.init();
    });
} )( jQuery, central_links );

// ==UserScript==
// @name         Anchor tags in Central
// @namespace    http://central.tri.be/
// @version      0.1
// @description  Adds anchor tags to some links in central
// @author       You
// @include        /^https:\/\/central.tri.be(\/.*)?/
// @grant        none
// ==/UserScript==

var central_links = {};

( function( $, my ) {
    my.init = function() {
        my.$headings = $( 'table.attributes' ).find( 'th:contains(Pull Request:), th:contains(Forum threads:), th:contains(User Story:), th:contains(UserVoice Threads:)' );

        my.$headings.each( function() {
            var $this = $( this ),
                $link_cell = $this.next( 'td' ),
                link = $link_cell.html();

            if ( ! link ) {
                return;
            }

            var links;
            if ( link.indexOf( '
' ) ) {
                links = link.split( '
' );
            } else {
                links = link.split( ' ' );
            }

            for ( var i in links ) {
                links[i] = String( links[i] ).replace( /(http[^\n <]+)/, '$1' );
            }

            $link_cell.html( links.join( '
' ) );
        } );
    };

    $( function() {
        my.init();
    });
} )( jQuery, central_links );

Improve to handle better all the possible cases


var core = require('./core')
  , id = require('./id')
  , classCache = {}

var proto = exports.proto = Object.create(id.proto);

exports.getClass = function (c) {
  var pointer = core.objc_getClass(c);
  return classCache[c] = exports.wrap(pointer);
}
// Making the getClass function available to the id module, to avoid circular deps
id._getClass = exports.getClass;

exports.wrap = function wrap (pointer) {
  var w = id.wrap(pointer);
  w.isClass = true;
  w.__proto__ = proto;
  return pointer;
}

var core = require('./core')
  , id = require('./id')
  , classCache = {}

var proto = exports.proto = Object.create(id.proto);

exports.getClass = function (c) {
  var pointer = core.objc_getClass(c);
  return classCache[c] = exports.wrap(pointer);
}
// Making the getClass function available to the id module, to avoid circular deps
id._getClass = exports.getClass;

exports.wrap = function wrap (pointer) {
  var w = id.wrap(pointer);
  w.isClass = true;
  w.__proto__ = proto;
  return w;
}

Fix a bug where the pointer was being returned instead of the wrapped instance.


import React from 'react'
import PropTypes from 'prop-types'

const BadgeButton = ({label, url}) =>
  <a href={url} type="application/hal+json">
    <span
      style={{
        fontSize: '0.8em',
        backgroundColor: 'white',
        borderRadius: '3px',
        color: 'black',
        padding: 3,
      }}
    >
      {label}
    </span>
  </a>

BadgeButton.propTypes = {
  label: PropTypes.string.isRequired,
  url: PropTypes.string.isRequired,
}

export default BadgeButton

import React from 'react'
import PropTypes from 'prop-types'

const BadgeButton = ({label, url}) =>
  <a href={url} type="application/hal+json">
    <span
      style={{
          border-radius: 60px,
          color: white,
          padding: 4px 12px 4px,
          font-weight: 500,
          background-color: #01c0c8,
          font-size: 14px,
          font-weight: 400,
          transition: all .18s ease-in-out
      }}
    >
      {label}
    </span>
  </a>

BadgeButton.propTypes = {
  label: PropTypes.string.isRequired,
  url: PropTypes.string.isRequired,
}

export default BadgeButton

Update badge button inline styles


var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var coveralls = require('gulp-coveralls');
var del = require('del');

gulp.task('clean', function() {
    "use strict";
    del(['node_modules', 'coverage'], function(err, delfiles) {
        return err;
    });
});

gulp.task('dist', function() {
    "use strict";
    return gulp.src(['./index.js', './lib/**/*.js'])
        .pipe(sourcemaps.init())
        .pipe(concat('libtlks.js'))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('dist'))
        .pipe(rename('libtlks.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dist'))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('dist'));
});

gulp.task('jshint', function() {
    "use strict";
    return gulp.src(['./test/**/*.js', './lib/**/*.js', 'index.js', 'gulpfile.js'])
        .pipe(jshint())
        .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('coveralls', function() {
    "use strict";
    gulp.src('./coverage/**/lcov.info')
        .pipe(coveralls());
});

gulp.task('default', ['jshint'], function() {});

var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var coveralls = require('gulp-coveralls');
var del = require('del');

gulp.task('clean', function() {
    "use strict";
    del(['node_modules', 'coverage'], function(err, delfiles) {
        return err;
    });
});

gulp.task('dist', function() {
    "use strict";
    return gulp.src(['./index.js', './lib/**/*.js'])
        .pipe(sourcemaps.init())
        .pipe(concat('libtlks.js'))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('dist'))
        .pipe(rename('libtlks.min.js'))
        .pipe(uglify())
        .pipe(gulp.dest('dist'))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('dist'));
});

gulp.task('jshint', function() {
    "use strict";
    return gulp.src(['./test/**/*.js', './lib/**/*.js', 'index.js', 'gulpfile.js'])
        .pipe(jshint())
        .pipe(jshint.reporter('jshint-stylish'))
        .pipe(jshint.reporter('fail'));
});

gulp.task('coveralls', function() {
    "use strict";
    gulp.src('./coverage/**/lcov.info')
        .pipe(coveralls());
});

gulp.task('default', ['jshint'], function() {});

Make tests fail if jshint does not pass correctly


import webpack from 'webpack';
import compression from 'compression';

const config = require('../../webpack/webpack.config.babel');
const compiler = webpack(config);

const bundleStart = Date.now();

compiler.plugin('done', function() {
  console.log('[BASE] Bundled project in ' + (Date.now() - bundleStart) + 'ms!');
});

const applyProdMiddleware = function(){
  return [
    compression()
  ];
};

module.exports = applyProdMiddleware;

import webpack from 'webpack';
import compression from 'compression';

const config = require('../../webpack/webpack.config.babel');
const compiler = webpack(config);

const bundleStart = Date.now();

compiler.plugin('done', function() {
  console.log('[BASE] Bundled project in ' + (Date.now() - bundleStart) + 'ms!');
});

const allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
};

const applyProdMiddleware = function(){
  return [
    compression(),
    allowCrossDomain
  ];
};

module.exports = applyProdMiddleware;

Allow cross Domain on prod config


var gulp = require('gulp'),
    mocha = require('gulp-mocha'),
    eslint = require('gulp-eslint'),
    babel = require('gulp-babel'),
    sourcemaps = require('gulp-sourcemaps');

require('babel/register');

gulp.task('lint', function () {
    return gulp
        .src(['./src/**/*.js', './tests/**/*.js'])
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failOnError());
});

gulp.task('test', ['lint'], function () {
    return gulp
        .src('./tests/**/*.js', {read: false})
        .pipe(mocha());
});

gulp.task('dist', ['test'], function () {
    return gulp
        .src('./src/**/*.js')
        .pipe(sourcemaps.init())
        .pipe(babel())
        .pipe(sourcemaps.write(''))
        .pipe(gulp.dest('./dist'));
});

gulp.task('watch', function () {
    gulp.watch(['./src/**/*', './tests/**/*'], ['default']);
});

gulp.task('default', ['dist']);

var gulp = require('gulp'),
    mocha = require('gulp-mocha'),
    eslint = require('gulp-eslint'),
    babel = require('gulp-babel'),
    sourcemaps = require('gulp-sourcemaps');

require('babel/register');

gulp.task('lint', function () {
    return gulp
        .src(['./src/**/*.js', './tests/**/*.js'])
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failOnError());
});

gulp.task('test', ['lint'], function () {
    return gulp
        .src('./tests/**/*.js', {read: false})
        .pipe(mocha());
});

gulp.task('dist', ['test'], function () {
    return gulp
        .src('./src/**/*.js')
        .pipe(sourcemaps.init())
        .pipe(babel())
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest('./dist'));
});

gulp.task('watch', function () {
    gulp.watch(['./src/**/*', './tests/**/*'], ['default']);
});

gulp.task('default', ['dist']);

Write sourcemaps to a separate file.


var gulp = require('gulp');
var rename = require('gulp-rename');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var babelify = require('babelify');

gulp.task('default', ['build', 'watch']);

gulp.task('watch', function () {
  gulp.watch('./src/*.js', ['build']);
  gulp.watch('./*.js', ['build']);
});

function build(file) {
  return browserify(file, {
      noParse: [require.resolve('./src/zxing')]
    })
    .transform(babelify, {
      ignore: /zxing\.js$/i,
      presets: ['es2015'],
      plugins: ['syntax-async-functions', 'transform-regenerator']
    })
    .bundle()
    .pipe(source('instascan.js'));
}

gulp.task('dist', function () {
  return build('./export.js')
    .pipe(buffer())
    .pipe(uglify())
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('./dist/'));
});

gulp.task('build', function () {
  return build('./export.js')
    .pipe(gulp.dest('./dist/'));
});

var gulp = require('gulp');
var rename = require('gulp-rename');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var uglify = require('gulp-uglify');
var babelify = require('babelify');

gulp.task('default', ['build', 'watch']);

gulp.task('watch', function () {
  gulp.watch('./src/*.js', ['build']);
  gulp.watch('./*.js', ['build']);
});

function build(file) {
  return browserify(file, {
      noParse: [require.resolve('./src/zxing')]
    })
    .transform(babelify, {
      ignore: /zxing\.js$/i,
      presets: ['es2015'],
      plugins: ['syntax-async-functions', 'transform-regenerator']
    })
    .bundle()
    .pipe(source('instascan.js'));
}

gulp.task('release', function () {
  return build('./export.js')
    .pipe(buffer())
    .pipe(uglify())
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('./dist/'));
});

gulp.task('build', function () {
  return build('./export.js')
    .pipe(gulp.dest('./dist/'));
});

Rename gulp 'dist' target to 'release'.


import React from 'react'

class Nav extends React.Component {
  componentDidMount() {
    // initSideNav()
  }
  render() {
    return (

Alumnus

    )
  }
}

export default Nav

Add helvetica as a class using tachyons


const test = require('tap').test;
const TextToSpeech = require('../../src/extensions/scratch3_text2speech/index.js');

const fakeStage = {
    textToSpeechLanguage: null
};

const fakeRuntime = {
    getTargetForStage: () => fakeStage,
    on: () => {} // Stub out listener methods used in constructor.
};

const ext = new TextToSpeech(fakeRuntime);

test('if no language is saved in the project, use default', t => {
    t.strictEqual(ext.getCurrentLanguage(), 'en');
    t.end();
});

test('if an unsupported language is dropped onto the set language block, use default', t => {
    ext.setLanguage({LANGUAGE: 'nope'});
    t.strictEqual(ext.getCurrentLanguage(), 'en');
    t.end();
});

test('get the extension locale for a supported locale that differs', t => {
    ext.setLanguage({LANGUAGE: 'ja-hira'});
    t.strictEqual(ext.getCurrentLanguage(), 'ja');
    t.end();
});

const test = require('tap').test;
const TextToSpeech = require('../../src/extensions/scratch3_text2speech/index.js');

const fakeStage = {
    textToSpeechLanguage: null
};

const fakeRuntime = {
    getTargetForStage: () => fakeStage,
    on: () => {} // Stub out listener methods used in constructor.
};

const ext = new TextToSpeech(fakeRuntime);

test('if no language is saved in the project, use default', t => {
    t.strictEqual(ext.getCurrentLanguage(), 'en');
    t.end();
});

test('if an unsupported language is dropped onto the set language block, use default', t => {
    ext.setLanguage({LANGUAGE: 'nope'});
    t.strictEqual(ext.getCurrentLanguage(), 'en');
    t.end();
});

test('if a supported language name is dropped onto the set language block, use it', t => {
    ext.setLanguage({LANGUAGE: 'español'});
    t.strictEqual(ext.getCurrentLanguage(), 'es');
    t.end();
});

test('get the extension locale for a supported locale that differs', t => {
    ext.setLanguage({LANGUAGE: 'ja-hira'});
    t.strictEqual(ext.getCurrentLanguage(), 'ja');
    t.end();
});

Add test for dropped language name


'use strict';

/* Services */

// Demonstrate how to register services
// In this case it is a simple value service.

// While this is here as a trivial example, I've been using it to
// keep track of the version number of my application.
angular.module('myApp.services', []).
  value('version', '0.3');

'use strict';

/* Services */

// Demonstrate how to register services
// In this case it is a simple value service.

// While this is here as a trivial example, I've been using it to
// keep track of the version number of my application.
angular.module('myApp.services', []).
  value('version', '0.4');

Set the version number for a new tag.


var fs    = require('fs');
var nconf = require('nconf');

/** Load Configuration according to the following hierarchy
 *  (where items higher on the list take precedence)
 *
 *  1. Command line arguments
 *  2. Environment variables
 *  3. The config.json file (if it exists) in the root directory
 *  4. The defaults defined below
 */

nconf
  .argv()
  .env();

// If config.json exists, load from that
try {
  var config_url = './config.json';
  fs.readFileSync(config_url);
  nconf.file(config_url);
} catch (err) {}

nconf.defaults({
  PORT: 5990,
  NODE_ENV: 'development',
  HOST: 'localhost',
  // sqlite: {
  //   schemas: __dirname + '/../schemas-for-sqlite',
  //   files: __dirname + '../'
  // },
  rippled_servers: [
    {
      host: 's-west.ripple.com',
      port: 443,
      secure: true
    }
  ]
});

module.exports = nconf;

var fs    = require('fs');
var path  = require('path');
var URL   = require('url');
var nconf = require('nconf');

/** Load Configuration according to the following hierarchy
 *  (where items higher on the list take precedence)
 *
 *  1. Command line arguments
 *  2. Environment variables
 *  3. The config.json file (if it exists) in the root directory
 *  4. The defaults defined below
 */

nconf.argv().env();

// If config.json exists, load from that
var configPath = nconf.get('config') || path.join(__dirname, '/config.json');

if (fs.existsSync(configPath)) {
  nconf.file(configPath);
}

if (nconf.get('rippled')) {
  var rippledURL = URL.parse(nconf.get('rippled'));

  var opts = {
    host: rippledURL.hostname,
    port: Number(rippledURL.port),
    secure: (rippledURL.protocol === 'wss:')
  }

  nconf.set('rippled_servers', [ opts ]);
}

nconf.defaults({
  PORT: 5990,
  NODE_ENV: 'development',
  HOST: 'localhost',
  // sqlite: {
  //   schemas: __dirname + '/../schemas-for-sqlite',
  //   files: __dirname + '../'
  // },
  rippled_servers: [
    {
      host: 's-west.ripple.com',
      port: 443,
      secure: true
    }
  ]
});

module.exports = nconf;

Allow --config and --rippled arguments


Kwf.onContentReady(function linkTagIntern(el){
    var links = $(el).find('a');

    if(links && links.length) {
        $.each(links, function(i, link){
            if($(link).data('checkIntern')) return;
            $(link).data('checkIntern', true);
            var pos = $(link).attr('href') ? $(link).attr('href').indexOf('#') : null;
            if (pos > 0 && $(link).attr('href').substr(0, 1) == '/') {
                var target = $($(link).attr('href').substr(pos));
                if (target && target.length) {
                    $(link).click(function(e){
                        e.preventDefault();
                        $('html, body').stop().animate({scrollTop: target.offset().top}, 500, function() {
                            window.location.hash = $(link).attr('href').substr(pos);
                        });
                    });
                }
            }
        });
    }
}, { defer: true });

Kwf.onJElementReady('a', function anchorLinks(el) {
    var pos = $(el).attr('href') ? $(el).attr('href').indexOf('#') : null;
    if (pos > 0 && $(el).attr('href').substr(0, 1) == '/') {
        var target = $($(el).attr('href').substr(pos));
        if (target && target.length) {
            $(el).click(function(e){
                e.preventDefault();
                $('html, body').stop().animate({scrollTop: target.offset().top}, 500, function() {
                    window.location.hash = $(el).attr('href').substr(pos);
                });
            });
        }
    }
}, {defer: true});

Change anchorLink (smooth-scroll) function to onJElementReady - use the anchor tag directly


import Ember from 'ember';

export default Ember.Component.extend({

    init () {
        this._super(...arguments);
        let parameters = this.get('parameters');
        this.set('filters', Object.keys(parameters).map((key, idx, arr) => {
            return {
                "key": key,
                "value": parameters[key]
            }
        }).filter((item) => {
            if (item.key == "page") {
                return false;
            }
            return true;
        }));
    },

    actions: {

        removeFilter(filter) {
            let queryParams = {};
            queryParams[filter.key] = undefined;
            this.attrs.transitionToFacet("search", queryParams);
        },

        transitionToFacet(parameter, parameterValue) {
            let queryParams = {};
            queryParams[parameter] = parameterValue;
            this.attrs.transitionToFacet("search", queryParams);
        }

    }

});

import Ember from 'ember';

var ID_FILTERS = ['contributors', 'funders', 'publishers'];

export default Ember.Component.extend({
    filters: null,
    init () {
      this._super(...arguments);
      let parameters = this.get('parameters');
      var filters = Object.keys(parameters).map((key) => {
        return {
          "key": key,
          "value": parameters[key]
        }
      }).filter((item) => {
        return item.key !== "page";
      });

      // Find and format all query params that use ids for the value
      var ids = filters.filter((item) => {
          return ID_FILTERS.indexOf(item.key) !== -1;
      }).map((param) => {
          return {key: param.value, doc_count: 0}
      });

      // Fetch display names
      if (ids.length !== 0) {
        this.fetchAgentDetails(ids).then((data) => {
          for (var i = 0; i < data.length; i++) {
            for (var filter = 0; filter < filters.length; filter++) {
              if (filters[filter].value === data[i].id) {
                  Ember.set(filters[filter], 'value', data[i].name);
              }
            }
          }
        });
      }
      this.set('filters', filters);
    },

    fetchAgentDetails: async function(data) {
        let agent_details = await Ember.$.ajax({
            url: 'https://dev-labs.cos.io/bulk_get_agents',
            crossDomain: true,
            data: JSON.stringify(data),
            type: 'POST',
            contentType: 'application/json'
        });
        return JSON.parse(agent_details);
    },

    actions: {

        removeFilter(filter) {
            let queryParams = {};
            queryParams[filter.key] = undefined;
            this.attrs.transitionToFacet("search", queryParams);
        },

        transitionToFacet(parameter, parameterValue) {
            let queryParams = {};
            queryParams[parameter] = parameterValue;
            this.attrs.transitionToFacet("search", queryParams);
        }

    }

});

Replace tag ids with display name


'use strict';

const fs = require('fs');
const path = require('path');

const runInlineTest = require('jscodeshift/dist/testUtils').runInlineTest;
const EmberQUnitTransform = require('../ember-qunit-codemod');

const fixtureFolder = `${__dirname}/../__testfixtures__/ember-qunit-codemod`;

describe('ember-qunit-codemod', function() {
  fs
    .readdirSync(fixtureFolder)
    .filter(filename => /\.input\.js$/.test(filename))
    .forEach(filename => {
      let testName = filename.replace('.input.js', '');
      let inputPath = path.join(fixtureFolder, `${testName}.input.js`);
      let outputPath = path.join(fixtureFolder, `${testName}.output.js`);

      describe(testName, function() {
        it('transforms correctly', function() {
          runInlineTest(
            EmberQUnitTransform,
            {},
            { source: fs.readFileSync(inputPath, 'utf8') },
            fs.readFileSync(outputPath, 'utf8')
          );
        });

        it('is idempotent', function() {
          runInlineTest(
            EmberQUnitTransform,
            {},
            { source: fs.readFileSync(outputPath, 'utf8') },
            fs.readFileSync(outputPath, 'utf8')
          );
        });
      });
    });
});

'use strict';

const fs = require('fs');
const path = require('path');

const runInlineTest = require('jscodeshift/dist/testUtils').runInlineTest;
const EmberQUnitTransform = require('../ember-qunit-codemod');

const fixtureFolder = `${__dirname}/../__testfixtures__/ember-qunit-codemod`;

describe('ember-qunit-codemod', function() {
  fs
    .readdirSync(fixtureFolder)
    .filter(filename => /\.input\.[jt]s$/.test(filename))
    .forEach(filename => {
      let extension = path.extname(filename);
      let testName = filename.replace(`.input${extension}`, '');
      let inputPath = path.join(fixtureFolder, `${testName}.input${extension}`);
      let outputPath = path.join(fixtureFolder, `${testName}.output${extension}`);

      describe(testName, function() {
        it('transforms correctly', function() {
          runInlineTest(
            EmberQUnitTransform,
            {},
            { source: fs.readFileSync(inputPath, 'utf8') },
            fs.readFileSync(outputPath, 'utf8')
          );
        });

        it('is idempotent', function() {
          runInlineTest(
            EmberQUnitTransform,
            {},
            { source: fs.readFileSync(outputPath, 'utf8') },
            fs.readFileSync(outputPath, 'utf8')
          );
        });
      });
    });
});

Update testing harness to support *.ts files.


(function(Modules) {
  "use strict";

  if (
    !('oninput' in document.createElement('input'))
  ) return;

  const tagPattern = /\(\([^\)\(]+\)\)/g;

  Modules.HighlightTags = function() {

    this.start = function(textarea) {

      this.$textbox = $(textarea)
        .wrap(`

        `)
        .after(this.$backgroundMaskForeground = $(`

        `))
        .on("input", this.update)
        .on("scroll", this.maintainScrollParity);

      this.initialHeight = this.$textbox.height();

      this.$backgroundMaskForeground.width(
        this.$textbox.width()
      );

      this.$textbox
        .trigger("input");

    };

    this.resize = () => this.$textbox.height(
      Math.max(
        this.initialHeight,
        this.$backgroundMaskForeground.outerHeight()
      )
    );

    this.replacePlaceholders = () => this.$backgroundMaskForeground.html(
      $('
').text(this.$textbox.val()).html().replace(
        tagPattern, match => `<span class='tag'>${match}</span>`
      )
    )

    this.update = () => (
      this.replacePlaceholders() && this.resize()
    )

    this.maintainScrollParity = () => this.$backgroundMaskForeground.scrollTop(
      this.$textbox.scrollTop()
    );

  };

})(window.GOVUK.Modules);

(function(Modules) {
  "use strict";

  if (
    !('oninput' in document.createElement('input'))
  ) return;

  const tagPattern = /\(\([^\)\(]+\)\)/g;

  Modules.HighlightTags = function() {

    this.start = function(textarea) {

      this.$textbox = $(textarea)
        .wrap(`

        `)
        .after(this.$backgroundMaskForeground = $(`

        `))
        .on("input", this.update);

      this.initialHeight = this.$textbox.height();

      this.$backgroundMaskForeground.width(
        this.$textbox.width()
      );

      this.$textbox
        .trigger("input");

    };

    this.resize = () => this.$textbox.height(
      Math.max(
        this.initialHeight,
        this.$backgroundMaskForeground.outerHeight()
      )
    );

    this.replacePlaceholders = () => this.$backgroundMaskForeground.html(
      $('
').text(this.$textbox.val()).html().replace(
        tagPattern, match => `<span class='tag'>${match}</span>`
      )
    );

    this.update = () => (
      this.replacePlaceholders() && this.resize()
    );

  };

})(window.GOVUK.Modules);

Remove method that maintain’s scroll parity


import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { FormattedNumber } from 'react-intl';

import { makeSelectInjected } from '../AccountProvider/selectors';

import Alert from '../../components/Alert';

class EstimateWarning extends React.Component {
  static propTypes = {
    estimate: PropTypes.func.isRequired,
    args: PropTypes.array.isRequired,
    injected: PropTypes.string,
  };

  static defaultProps = {
    args: [],
  };

  constructor(props) {
    super(props);

    this.state = {
      gas: null,
    };

    this.runEstimate(props.estimate, props.args);
  }

  componentWillReceiveProps(props) {
    if (props.estimate !== this.props.estimate || props.args !== this.props.args) {
      this.runEstimate(props.estimate, props.args);
    }
  }

  runEstimate(estimate, args) {
    estimate(...args).then((gas) => this.setState({ gas }));
  }

  render() {
    const { injected } = this.props;
    const { gas } = this.state;

    if (!injected || !gas) {
      return null;
    }

    return (
      <Alert>
        Be sure to give at least <FormattedNumber value={gas} /> gas limit for your transaction.
        Otherwise transaction can fail
      </Alert>
    );
  }
}

export default connect((state) => ({
  injected: makeSelectInjected()(state),
}))(EstimateWarning);

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { FormattedNumber } from 'react-intl';

import { makeSelectIsLocked } from '../AccountProvider/selectors';

import Alert from '../../components/Alert';

class EstimateWarning extends React.Component {
  static propTypes = {
    estimate: PropTypes.func.isRequired,
    args: PropTypes.array.isRequired,
    isLocked: PropTypes.bool,
  };

  static defaultProps = {
    args: [],
  };

  constructor(props) {
    super(props);

    this.state = {
      gas: null,
    };

    this.runEstimate(props.estimate, props.args);
  }

  componentWillReceiveProps(props) {
    if (props.estimate !== this.props.estimate || props.args !== this.props.args) {
      this.runEstimate(props.estimate, props.args);
    }
  }

  runEstimate(estimate, args) {
    if (!this.props.isLocked) {
      estimate(...args).then((gas) => this.setState({ gas }));
    }
  }

  render() {
    const { isLocked } = this.props;
    const { gas } = this.state;

    if (isLocked || !gas) {
      return null;
    }

    return (
      <Alert>
        Be sure to give at least <FormattedNumber value={gas} /> gas limit for your transaction.
        Otherwise transaction can fail
      </Alert>
    );
  }
}

export default connect((state) => ({
  isLocked: makeSelectIsLocked()(state),
}))(EstimateWarning);

Disable estimate warning for locked accounts


/* Hebrew translation for the jQuery Timepicker Addon */
/* Written by Lior Lapid */
(function($) {
	$.timepicker.regional["he"] = {
		timeOnlyTitle: "בחירת זמן",
		timeText: "שעה",
		hourText: "שעות",
		minuteText: "דקות",
		secondText: "שניות",
		millisecText: "אלפית השנייה",
		timezoneText: "אזור זמן",
		currentText: "עכשיו",
		closeText:"סגור",
		timeFormat: "hh:mm tt",
		amNames: ['לפנה"צ', 'AM', 'A'],
		pmNames: ['אחה"צ', 'PM', 'P'],
		ampm: false,
		isRTL: false
	};
	$.timepicker.setDefaults($.timepicker.regional["he"]);
})(jQuery);

/* Hebrew translation for the jQuery Timepicker Addon */
/* Written by Lior Lapid */
(function($) {
	$.timepicker.regional["he"] = {
		timeOnlyTitle: "בחירת זמן",
		timeText: "שעה",
		hourText: "שעות",
		minuteText: "דקות",
		secondText: "שניות",
		millisecText: "אלפית השנייה",
		timezoneText: "אזור זמן",
		currentText: "עכשיו",
		closeText:"סגור",
		timeFormat: "hh:mm tt",
		amNames: ['לפנה"צ', 'AM', 'A'],
		pmNames: ['אחה"צ', 'PM', 'P'],
		ampm: false,
		isRTL: true
	};
	$.timepicker.setDefaults($.timepicker.regional["he"]);
})(jQuery);

Enable rtl for proper localizations


const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const methodOverride = require('method-override');

app.set('view engine', 'pug');
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended: true}));

if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

var collection = [];
var id = 1;

// '/'
app.get('/', function(req, res, next) {
  res.send('Hellooooo');
});

// '/collection'
// '/add'
// '/delete'

app.listen(3000, function() {
  console.log('Server is listening on port 3000');
});

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const methodOverride = require('method-override');

app.set('view engine', 'pug');
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(methodOverride('_method'));

if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

var collection = [];
var id = 1;

// '/'
app.get('/', function(req, res, next) {
  res.redirect('/collection');
});

// '/collection'
app.get('/collection', function(req, res, next) {
  res.render('show', {collection});
});

// '/add'
app.post('/add', function(req, res, next) {
  collection.push();
});

// '/delete'
app.delete('/collection/:id', function(req, res, next) {

});

app.listen(3000, function() {
  console.log('Server is listening on port 3000');
});

Include show page, add, and delete routes


var GameInputFactory = function (canvas) {

  var pressedKeys = {};
  var mousePos = {};

  function setKey(event, status) {
    var code = event.keyCode;
    var key;

    switch(code) {
      case 32:
        key = 'SPACE'; break;
      case 37:
        key = 'LEFT'; break;
      case 38:
        key = 'UP'; break;
      case 39:
        key = 'RIGHT'; break;
      case 40:
        key = 'DOWN'; break;
      default:
        // Convert ASCII codes to letters
        key = String.fromCharCode(event.keyCode);
    }

    pressedKeys[key] = status;
  }

  document.addEventListener('keydown', function(e) {
    setKey(e, true);
  });

  document.addEventListener('keyup', function(e) {
    setKey(e, false);
  });

  canvas.addEventListener('mousedown', function(e) {
    // Scale position to game coordinate system
    mousePos.x = e.offsetX / e.target.width * GameState.WIDTH;
    mousePos.y = e.offsetY / e.target.height * GameState.HEIGHT;
    pressedKeys['MOUSE'] = true;
  });

  canvas.addEventListener('mouseup', function(e) {
    pressedKeys['MOUSE'] = false;
  });

  window.addEventListener('blur', function() {
    pressedKeys = {};
  });

  function isDown(key) {
    return pressedKeys[key];
  }

  function getMousePos() {
    return mousePos;
  }

  return {
    isDown: isDown,
    getMousePos: getMousePos
  };

};

var GameInputFactory = function (canvas) {

  var pressedKeys = {};
  var mousePos = {};

  function setKey(event, status) {
    var code = event.keyCode;
    var key;

    switch(code) {
      case 32:
        key = 'SPACE'; break;
      case 37:
        key = 'LEFT'; break;
      case 38:
        key = 'UP'; break;
      case 39:
        key = 'RIGHT'; break;
      case 40:
        key = 'DOWN'; break;
      default:
        // Convert ASCII codes to letters
        key = String.fromCharCode(event.keyCode);
    }

    pressedKeys[key] = status;
  }

  document.addEventListener('keydown', function(e) {
    setKey(e, true);
  });

  document.addEventListener('keyup', function(e) {
    setKey(e, false);
  });

  canvas.addEventListener('mousemove', function (e) {
    // Scale position to game coordinate system
    mousePos.x = e.offsetX / e.target.width * GameState.WIDTH;
    mousePos.y = e.offsetY / e.target.height * GameState.HEIGHT;
  });

  canvas.addEventListener('mousedown', function(e) {
    pressedKeys['MOUSE'] = true;
  });

  canvas.addEventListener('mouseup', function(e) {
    pressedKeys['MOUSE'] = false;
  });

  window.addEventListener('blur', function() {
    pressedKeys = {};
  });

  function isDown(key) {
    return pressedKeys[key];
  }

  function getMousePos() {
    return mousePos;
  }

  return {
    isDown: isDown,
    getMousePos: getMousePos
  };

};

Attach mouse coordinate update to "mousemove" event


(function () {
  angular
    .module("ng-geocoder")
    .factory("ngGeocoderService", ngGeocoderService);

  ngGeocoderService.$inject = ["$q"];

  function ngGeocoderService ($q) {
    var geocoder = new google.maps.Geocoder();
    var service  = {
      "geocodeById": geocodeById,
      "geocodeByQuery": geocodeByQuery
    }

    return service;

    function handleReply (defer, results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        return defer.resolve(results);
      } else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) {
        return defer.resolve([]);
      } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
        return defer.reject("Over query limit");
      } else if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
        return defer.reject("Request denied");
      }

      return defer.reject("Unknown error");
    }

    function geocodeById (placeId) {
      return geocode({ "placeId": placeId });
    }

    function geocodeByQuery (query, region) {
      return geocode({ "address": query, "region": region });
    }

    function geocode (options) {
      var defer = $q.defer();

      geocoder.geocode(options, function (results, status) {
        handleReply(defer, results, status);
      });

      return defer.promise;
    }
  }
})();

(function () {
  angular
    .module("ng-geocoder")
    .factory("ngGeocoderService", ngGeocoderService);

  ngGeocoderService.$inject = ["$q"];

  function ngGeocoderService ($q) {
    var geocoder = new google.maps.Geocoder();
    var service  = {
      "geocodeById": geocodeById,
      "geocodeByQuery": geocodeByQuery
    }

    return service;

    function handleReply (defer, results, status) {
      switch (status) {
        case google.maps.GeocoderStatus.OK:
          return defer.resolve(results);
        case google.maps.GeocoderStatus.ZERO_RESULTS:
          return defer.resolve([]);
        case google.maps.GeocoderStatus.OVER_QUERY_LIMIT:
          return defer.reject("Over query limit");
        case google.maps.GeocoderStatus.REQUEST_DENIED:
          return defer.reject("Request denied");
        default:
          return defer.reject("Unknown error");
      }
    }

    function geocodeById (placeId) {
      return geocode({ "placeId": placeId });
    }

    function geocodeByQuery (query, region) {
      var params = {
        "address": query,
        "region": region
      }

      return geocode(params);
    }

    function geocode (options) {
      var defer = $q.defer();

      geocoder.geocode(options, function (results, status) {
        handleReply(defer, results, status);
      });

      return defer.promise;
    }
  }
})();

Change if...else statement to switch for better code organization


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require babel-polyfill
//= require jquery
//= require jquery_ujs
//= require jquery-ui/sortable
//= require jquery-ui/selectable
//= require jquery-ui/slider
//= require jquery-ui/datepicker
//= require jqueryui-timepicker-addon
// Required by Blacklight
//= require blacklight/blacklight
//= require browse_everything
//= require nestedSortable/jquery.mjs.nestedSortable
//= require bootstrap-select
//= require openseadragon

// = require curation_concerns/application
//= require_tree .

//= require modernizr
//= require jquery.iiifOsdViewer

Blacklight.onLoad(function() {
  Initializer = require('plum_boot')
  window.plum = new Initializer()
})

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui/sortable
//= require jquery-ui/selectable
//= require jquery-ui/slider
//= require jquery-ui/datepicker
//= require jqueryui-timepicker-addon
// Required by Blacklight
//= require blacklight/blacklight
//= require browse_everything
//= require nestedSortable/jquery.mjs.nestedSortable
//= require bootstrap-select
//= require openseadragon

// = require curation_concerns/application
//= require_tree .

//= require modernizr
//= require jquery.iiifOsdViewer

Blacklight.onLoad(function() {
  Initializer = require('plum_boot')
  window.plum = new Initializer()
})

Fix error causing PhantomJS to eat RAM


define(['piwik'], function(){

  var _paq = _paq || [];
  _paq.push(["trackPageView"]);
  _paq.push(["enableLinkTracking"]);

  (function() {
    var u="http://estatisticas.dialoga.gov.br/";
    _paq.push(["setTrackerUrl", u+"piwik.php"]);
    _paq.push(["setSiteId", "65"]);
    var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
    g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
  })();

  window._paq = _paq;
  return _paq;

});

define(['piwik'], function(){

  var _paq = _paq || [];
  _paq.push(["trackPageView"]);
  _paq.push(["enableLinkTracking"]);

  var isProduction = /^http:\/\/dialoga\.gov\.br\//.test(window.location.href);
  var siteId = isProduction ? 65 : 1;

  (function() {
    var u="http://estatisticas.dialoga.gov.br/";
    _paq.push(["setTrackerUrl", u+"piwik.php"]);
    _paq.push(["setSiteId", "65"]);
    var d=document, g=d.createElement("script"), s=d.getElementsByTagName("script")[0]; g.type="text/javascript";
    g.defer=true; g.async=true; g.src=u+"piwik.js"; s.parentNode.insertBefore(g,s);
  })();

  window._paq = _paq;
  return _paq;

});

Set site id for production and staging environments


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require turbolinks
//= require jquery3
//= require jquery_ujs
//= require foundation
//= require_tree .

$(function(){ $(document).foundation(); });

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require rails-ujs
//= require turbolinks
//= require jquery3
//= require jquery_ujs
//= require foundation
//= require_tree .

$(document).on('turbolinks:load', function() {
  $(document).foundation();
});

Fix issue with turbolinks and foundation


// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require underscore-min
//= require handlebars-min
//= require backbone
//= require_tree .

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require underscore-min
//= require handlebars-min
//= require backbone
//= require bootstrap-sprockets
//= require_tree .

Add bootstrap-sprockets require to app.js.


/* global angular */
(function() {
    angular.module("googlechart")
        .factory("agcScriptTagHelper", agcScriptTagHelperFactory);

    agcScriptTagHelperFactory.$inject = ["$q", "$document"];
    function agcScriptTagHelperFactory($q, $document)
    {
        /** Add a script tag to the document's head section and return an angular
          * promise that resolves when the script has loaded.
          */
        function agcScriptTagHelper(url)
        {
            var deferred = $q.defer();
            var head = $document.getElementsByTagName('head')[0];
            var script = $document.createElement('script');

            script.setAttribute('type', 'text/javascript');
            script.src = url;

            if (script.addEventListener) { // Standard browsers (including IE9+)
                script.addEventListener('load', onLoad, false);
                script.onerror = onError;
            } else { // IE8 and below
                script.onreadystatechange = function () {
                    if (script.readyState === 'loaded' || script.readyState === 'complete') {
                        script.onreadystatechange = null;
                        onLoad();
                    }
                };
            }
            head.appendChild(script);

            function onLoad() {
                deferred.resolve();
            }

            function onError() {
                deferred.reject();
            }

            return deferred.promise;
        }

        return agcScriptTagHelper;
    }
})();

/* global angular */
(function() {
    angular.module("googlechart")
        .factory("agcScriptTagHelper", agcScriptTagHelperFactory);

    agcScriptTagHelperFactory.$inject = ["$q", "$document"];
    function agcScriptTagHelperFactory($q, $document)
    {
        /** Add a script tag to the document's head section and return an angular
          * promise that resolves when the script has loaded.
          */
        function agcScriptTagHelper(url)
        {
            var deferred = $q.defer();
            var head = $document.find('head')[0];
            var script = angular.element('<script></script>');

            script.setAttribute('type', 'text/javascript');
            script.src = url;

            if (script.addEventListener) { // Standard browsers (including IE9+)
                script.addEventListener('load', onLoad, false);
                script.onerror = onError;
            } else { // IE8 and below
                script.onreadystatechange = function () {
                    if (script.readyState === 'loaded' || script.readyState === 'complete') {
                        script.onreadystatechange = null;
                        onLoad();
                    }
                };
            }
            head.appendChild(script);

            function onLoad() {
                deferred.resolve();
            }

            function onError() {
                deferred.reject();
            }

            return deferred.promise;
        }

        return agcScriptTagHelper;
    }
})();

Tag helper code should have used jqLite API.


(function(env){
    env.ddg_spice_expand_url = function(api_response) {
        "use strict";

        // Get the orignal query.
        var query = DDG.get_query().replace(/expand\s*/i, "");

        // Check if there are any errors.
        if (!api_response["long-url"] || api_response["long-url"] === query) {
            return Spice.failed('expand_url');
        }

        // Display the plug-in.
        Spice.add({
            id: "expand_url",
            name: "Expand URL",
            data: api_response,
            meta: {
                sourceUrl: "http://longurl.org/expand?url=" + encodeURIComponent(query),
                sourceName: "LongURL"
            },
            templates: {
                group: 'info',
                options: {
                    content: Spice.expand_url.content
                }
            }
        });
    }
}(this));

(function(env){
    env.ddg_spice_expand_url = function(api_response) {
        "use strict";

        // Get the orignal query.
        var query = DDG.get_query().replace(/expand\s*/i, "");

        // Check if there are any errors.
        if (!api_response["long-url"] || api_response["long-url"] === query) {
            return Spice.failed('expand_url');
        }

        // Display the plug-in.
        Spice.add({
            id: "expand_url",
            name: "Expand URL",
            data: api_response,
            meta: {
                sourceUrl: "http://longurl.org/expand?url=" + encodeURIComponent(query),
                sourceName: "LongURL"
            },
            templates: {
                group: 'base',
                options: {
                    content: Spice.expand_url.content,
		    moreAt: true
                }
            }
        });
    }
}(this));

Move to group 'base' and enable "More at ..."


// To use it create some files under `routes/`
// e.g. `server/routes/ember-hamsters.js`
//
// module.exports = function(app) {
//   app.get('/ember-hamsters', function(req, res) {
//     res.send('hello');
//   });
// };

module.exports = function(app) {
  var globSync   = require('glob').sync;
  var mocks      = globSync('./mocks/**/*.js', { cwd: __dirname }).map(require);
  var proxies    = globSync('./proxies/**/*.js', { cwd: __dirname }).map(require);

  // Log proxy requests
  var morgan  = require('morgan');
  app.use(morgan('dev'));

  mocks.forEach(function(route) { route(app); });
  proxies.forEach(function(route) { route(app); });

};

// To use it create some files under `mocks/`
// e.g. `server/mocks/ember-hamsters.js`
//
// module.exports = function(app) {
//   app.get('/ember-hamsters', function(req, res) {
//     res.send('hello');
//   });
// };

module.exports = function(app) {
  var globSync   = require('glob').sync;
  var mocks      = globSync('./mocks/**/*.js', { cwd: __dirname }).map(require);
  var proxies    = globSync('./proxies/**/*.js', { cwd: __dirname }).map(require);

  // Log proxy requests
  var morgan  = require('morgan');
  app.use(morgan('dev'));

  mocks.forEach(function(route) { route(app); });
  proxies.forEach(function(route) { route(app); });

};

Change comment for server blueprint to include correct information


const config = require('./src/utils/config');

const COMMON_ENV = {
  ...config.db,

  // Use a single connection to execute migrations.
  pool: {
    min: 1,
    max: 1,
  },
  migrations: {
    tableName: 'knex_migrations',
    directory: 'db/migrations',
  },
};

// Feel free to create any number of other environments.
// The ones below are a best attempt at sensible defaults.
module.exports = {
  // Developer's local machine
  development: {
    ...COMMON_ENV,

    seeds: {
      directory: 'db/seeds-dev',
    },
  },

  // Production environment
  production: {
    ...COMMON_ENV,

    seeds: {
      directory: 'db/seeds-prod',
    },
  },
};

const config = require('./src/utils/config');

const COMMON_ENV = {
  ...config.db,

  // Use a single connection to execute migrations.
  pool: {
    min: 1,
    max: 1,
  },
  migrations: {
    tableName: 'knex_migrations',
    directory: 'db/migrations',
  },
};

// Feel free to create any number of other environments.
// The ones below are a best attempt at sensible defaults.
module.exports = {
  // Developer's local machine
  development: {
    ...COMMON_ENV,

    seeds: {
      directory: 'db/seeds-dev',
    },
  },

  // Production environment
  production: {
    ...COMMON_ENV,

    seeds: {
      directory: 'db/seeds-dev', // TODO: change to -prod before final deployment
    },
  },
};

Use -dev seed everywhere for now


import 'select2';
import 'select2/dist/css/select2.css';
import 'select2-bootstrap-theme/dist/select2-bootstrap.css';

Template.newActivity.created = function () {
  this.subscribe('allCurrentResidents');
  this.subscribe('allHomes');
  this.subscribe('allActivityTypes');
  this.subscribe('allRolesExceptAdmin');
};

Template.newActivity.helpers({
  select2Options () {
    // Get placeholder text localization
    const placeholderText = TAPi18n.__('newActivity-residentSelect-placeholder');

    const options = {
      closeOnSelect: false,
      placeholder: placeholderText,
    };

    return options;
  },
  'today': function () {
    // Default date today, as a string
    return Date();
  },
});

import 'select2';
import 'select2/dist/css/select2.css';

Template.newActivity.created = function () {
  this.subscribe('allCurrentResidents');
  this.subscribe('allHomes');
  this.subscribe('allActivityTypes');
  this.subscribe('allRolesExceptAdmin');
};

Template.newActivity.helpers({
  select2Options () {
    // Get placeholder text localization
    const placeholderText = TAPi18n.__('newActivity-residentSelect-placeholder');

    const options = {
      closeOnSelect: false,
      placeholder: placeholderText,
    };

    return options;
  },
  'today': function () {
    // Default date today, as a string
    return Date();
  },
});

Remove style that was breaking deployment


import dropboxFs from 'dropbox-fs'
import fs from 'fs'
import { promisify } from 'util'

import { dropboxApiKey } from '../config'

export const readFile = (...options) => {
  return dropboxApiKey ? dropboxReadFile(...options) : fsReadFile(...options)
}

export const writeFile = (...options) => {
  return dropboxApiKey ? dropboxWriteFile(...options) : fsWriteFile(...options)
}

const dfs = (dropboxApiKey) => {
  return dropboxFs({
    apikey: dropboxApiKey,
  })
}

const dropboxReadFile = (path) => {
  return dfs(dropboxApiKey).readFile(`/${path}`, { encoding: 'utf8' })
}

const dropboxWriteFile = (path, content) => {
  return dfs(dropboxApiKey).writeFile(`/${path}`, content, { encoding: 'utf8' })
}

const fsReadFile = (path) => {
  const readFile = promisify(fs.readFile)
  return readFile(path, { encoding: 'utf8' }).catch((error) => {
    if (error.status === 409 && error.error.indexOf('not_found') !== -1) {
      error.code = 'ENOENT'
    }
    throw error
  })
}

const fsWriteFile = (path, content) => {
  const writeFile = promisify(fs.writeFile)
  return writeFile(path, content, { encoding: 'utf8' })
}

import dropboxFs from 'dropbox-fs'
import fs from 'fs'
import { promisify } from 'util'

import { dropboxApiKey } from '../config'

export const readFile = (...options) => {
  return dropboxApiKey ? dropboxReadFile(...options) : fsReadFile(...options)
}

export const writeFile = (...options) => {
  return dropboxApiKey ? dropboxWriteFile(...options) : fsWriteFile(...options)
}

const dfs = (dropboxApiKey) => {
  return dropboxFs({
    apiKey: dropboxApiKey,
  })
}

const dropboxReadFile = (path) => {
  return dfs(dropboxApiKey).readFile(`/${path}`, { encoding: 'utf8' })
}

const dropboxWriteFile = (path, content) => {
  return dfs(dropboxApiKey).writeFile(`/${path}`, content, { encoding: 'utf8' })
}

const fsReadFile = (path) => {
  const readFile = promisify(fs.readFile)
  return readFile(path, { encoding: 'utf8' }).catch((error) => {
    if (error.status === 409 && error.error.indexOf('not_found') !== -1) {
      error.code = 'ENOENT'
    }
    throw error
  })
}

const fsWriteFile = (path, content) => {
  const writeFile = promisify(fs.writeFile)
  return writeFile(path, content, { encoding: 'utf8' })
}

Fix typo in setting up dropbox api


import React, { Component } from 'react'

import { fetchOrganization } from '../../core/firebaseRestAPI'
import { authenticate } from '../../lib/session'
import { uuid } from '../../lib/uuid'

import Layout from '../../components/Layout'
import Loading from '../../components/Loading'
import OrganizationEdit from '../../components/OrganizationEdit'

const blankOrganization = () => ({
  id: uuid(),
  longDescription: "",
  name: "",
  url: ""
})

class OrganizationAdminPage extends Component {
  constructor(props) {
    super(props)
    this.state = {
      organization: null,
    }
  }

  componentWillMount() {
    authenticate()
  }

  componentDidMount() {
    const match = this.props.route.pattern.exec(window.location.pathname)
    const organizationId = match[1]

    if (organizationId === 'new') {
      this.setState({ organization: blankOrganization() })
    } else {
      fetchOrganization(organizationId)
        .then(organization => {
          this.setState({ organization })
        })
    }
  }

  componentDidUpdate() {
    const { organization } = this.state

    if (organization && organization.name) {
      document.title = organization.name
    } else {
      document.title = 'Create Organization'
    }
  }

  render() {
    const { organization } = this.state

    return (
      <Layout admin>
        { organization ?
            <OrganizationEdit organization={organization} /> :
            <Loading />
        }
      </Layout>
    )
  }
}

export default OrganizationAdminPage

import React, { Component } from 'react'

import { fetchOrganization } from '../../core/firebaseRestAPI'
import { authenticate } from '../../lib/session'
import { uuid } from '../../lib/uuid'

import Layout from '../../components/Layout'
import Loading from '../../components/Loading'
import OrganizationEdit from '../../components/OrganizationEdit'

const blankOrganization = () => ({
  id: uuid(),
  longDescription: "",
  name: "",
  url: "",
  phones: []
})

class OrganizationAdminPage extends Component {
  constructor(props) {
    super(props)
    this.state = {
      organization: null,
    }
  }

  componentWillMount() {
    authenticate()
  }

  componentDidMount() {
    const match = this.props.route.pattern.exec(window.location.pathname)
    const organizationId = match[1]

    if (organizationId === 'new') {
      this.setState({ organization: blankOrganization() })
    } else {
      fetchOrganization(organizationId)
        .then(organization => {
          this.setState({ organization })
        })
    }
  }

  componentDidUpdate() {
    const { organization } = this.state

    if (organization && organization.name) {
      document.title = organization.name
    } else {
      document.title = 'Create Organization'
    }
  }

  render() {
    const { organization } = this.state

    return (
      <Layout admin>
        { organization ?
            <OrganizationEdit organization={organization} /> :
            <Loading />
        }
      </Layout>
    )
  }
}

export default OrganizationAdminPage

Include phones in default org object


class ScoreController {
  constructor($scope, $state, $window, SocketService, VibrateService) {
    'ngInject';

    this.$window = $window;
    this.$state = $state;
    this.SocketService = SocketService;
    this.VibrateService = VibrateService;

    this.text = 'Waiting for results';
    this.haveNextRound = true;
    this.canContinue = false;

    $scope.$on('owner_disconnect', function(event, args) {
      alert('Computer disconnected from the game. Game ended.');
      $state.go('main');
    });

    $scope.$on('server_disconnect', function(event, args) {
      alert('Server disconnected. Game ended.');
      $state.go('main');
    });

    this.SocketService.extendedHandler = (message) => {
      if (message.type === 'end_score') {
        this.VibrateService.vibrate();

        this.canContinue = true;
        this.haveNextRound = message.haveNextRound;

        if (this.haveNextRound) {
          this.text = 'Next Question';
        } else {
          this.text = 'End Game';
        }
      }
    };
  }

  continue () {
    this.SocketService.send({
      type: 'continue'
    });

    if (this.haveNextRound) {
      this.$state.go('game');
    } else {
      this.$state.go('result');
    }
  }
}

export default ScoreController;

class ScoreController {
  constructor($scope, $state, $window, SocketService, VibrateService) {
    'ngInject';

    this.$window = $window;
    this.$state = $state;
    this.SocketService = SocketService;
    this.VibrateService = VibrateService;

    this.text = 'Waiting for results';
    this.haveNextRound = true;
    this.canContinue = false;

    $scope.$on('owner_disconnect', function(event, args) {
      alert('Computer disconnected from the game. Game ended.');
      $state.go('main');
    });

    $scope.$on('server_disconnect', function(event, args) {
      alert('Server disconnected. Game ended.');
      $state.go('main');
    });

    this.SocketService.extendedHandler = (message) => {
      if (message.type === 'end_score') {
        this.VibrateService.vibrate();

        this.canContinue = true;
        this.haveNextRound = message.haveNextRound;

        if (this.haveNextRound) {
          this.text = 'Next Question';
        } else {
          this.text = 'End Game';
        }

      } else if(message.type === 'continue') {
        this.moveToNextSection();
      }
    };
  }

  continue() {
    this.SocketService.send({
      type: 'continue'
    });

    this.moveToNextSection();
  }

  moveToNextSection() {
    if (this.haveNextRound) {
      this.$state.go('game');
    } else {
      this.$state.go('result');
    }
  }
}

export default ScoreController;

Fix multiple players score page


/**
 * power-assert - Empower your assertions
 *
 * https://github.com/twada/power-assert
 *
 * Copyright (c) 2013-2014 Takuto Wada
 * Licensed under the MIT license.
 *   https://raw.github.com/twada/power-assert/master/MIT-LICENSE.txt
 */
var espower = require('espower'),
    esprima = require('esprima'),
    escodegen = require('escodegen'),
    argv = require('optimist').argv,
    fs = require('fs'),
    options = {},
    file = argv._[0],
    path = fs.realpathSync(file),
    source = fs.readFileSync(file, 'utf-8'),
    tree = esprima.parse(source, {tolerant: true, loc: true, range: true, tokens: true});

if (argv.powerAssertVariableName) {
  options['powerAssertVariableName'] = argv.powerAssertVariableName;
}
options['path'] = path;
options['source'] = source;
tree = espower(tree, options);
console.log(escodegen.generate(tree));

/**
 * power-assert - Empower your assertions
 *
 * https://github.com/twada/power-assert
 *
 * Copyright (c) 2013-2014 Takuto Wada
 * Licensed under the MIT license.
 *   https://raw.github.com/twada/power-assert/master/MIT-LICENSE.txt
 */
var espower = require('espower'),
    esprima = require('esprima'),
    escodegen = require('escodegen'),
    argv = require('optimist').argv,
    fs = require('fs'),
    options = {},
    file = argv._[0],
    path = fs.realpathSync(file),
    source = fs.readFileSync(file, 'utf-8'),
    tree = esprima.parse(source, {tolerant: true, loc: true, tokens: true, raw: true, source: path});

if (argv.powerAssertVariableName) {
  options['powerAssertVariableName'] = argv.powerAssertVariableName;
}
options['path'] = path;
options['source'] = source;
tree = espower(tree, options);
console.log(escodegen.generate(tree));

Add raw option (even if ignored by esprima 1.1.x)


angular.module('gnucash-reports-view.reports.category', ['gnucash-reports-view.reports.base',
                                                          'nvd3'])
    .config(['ReportsManagementProvider', function(provider) {
        provider.addTemplate('account_usage_categories', 'src/reports/category/category.html');
        provider.addTemplate('expenses_categories', 'src/reports/category/category.html');
        provider.addTemplate('investment_allocation', 'src/reports/category/category.html');
    }]);

angular.module('gnucash-reports-view.reports.category', ['gnucash-reports-view.reports.base',
                                                          'nvd3'])
    .config(['ReportsManagementProvider', function(provider) {
        var categoryTemplate = 'src/reports/category/category.html';
        provider.addTemplate('account_usage_categories', categoryTemplate);
        provider.addTemplate('expenses_categories', categoryTemplate);
        provider.addTemplate('investment_allocation', categoryTemplate);
        provider.addTemplate('expense_accounts', categoryTemplate);
    }]);

Add support for expense_account reports.


import React from 'react'
import FeedbackLink from '../components/FeedbackLink.js'

class FeedbackSection extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      rateMessage: 'How was it? Rate it:',
      showButtons: true
    }
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    this.setState({
      rateMessage: 'Thanks!',
      showButtons: false
    })
  }

  render() {
    return (

{this.state.rateMessage}

Your feedback is greatly appreciated!

        {this.state.showButtons ? (

            <FeedbackLink
              className="m-r-1"
              text="Good 👌"
              value="good"
              onClick={this.handleClick}
            />
            <FeedbackLink
              className="m-r-1"
              text="Too long 📘"
              value="long"
              onClick={this.handleClick}
            />
            <FeedbackLink
              className="m-r-1"
              text="Too short 📝"
              value="short"
              onClick={this.handleClick}
            />
            <FeedbackLink
              className="m-r-1"
              text="Bad 👎"
              value="bad"
              onClick={this.handleClick}
            />

        ) : (

        )}

    )
  }
}

export default FeedbackSection

import React from 'react'
import FeedbackLink from '../components/FeedbackLink.js'

class FeedbackSection extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      rateMessage: 'How was it? Rate it:',
      showButtons: true
    }
  }

  handleClick = () => {
    this.setState({
      rateMessage: 'Thanks!',
      showButtons: false
    })
  }

  render() {
    return (

{this.state.rateMessage}

Your feedback is greatly appreciated!

        {this.state.showButtons ? (

            <FeedbackLink
              className="m-r-1"
              text="Good 👌"
              value="good"
              onClick={this.handleClick}
            />
            <FeedbackLink
              className="m-r-1"
              text="Too long 📘"
              value="long"
              onClick={this.handleClick}
            />
            <FeedbackLink
              className="m-r-1"
              text="Too short 📝"
              value="short"
              onClick={this.handleClick}
            />
            <FeedbackLink
              className="m-r-1"
              text="Bad 👎"
              value="bad"
              onClick={this.handleClick}
            />

        ) : null}

    )
  }
}

export default FeedbackSection

Change conditional rendering and this bindings


//TODO we might need to filter on the language, but for now english seems to be
//the only language available
/**
 * Builds the query that retrieve the GSBPM overlook
 */
const GSBPMDescription = () => `
  PREFIX gsbpm: <http://rdf.unece.org/models/gsbpm#>
  PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
  select ?phase ?phaseLabel ?subprocess ?subprocessLabel where {
   ?phase a gsbpm:Phase ;
          skos:narrower ?subProcess ;
   OPTIONAL {
     ?phase skos:prefLabel ?phaseLabel
   }
   OPTIONAL {
     ?subprocess skos:prefLabel ?subprocessLabel
   }
  }
 `

export default {
  GSBPMDescription
}

//TODO we might need to filter on the language, but for now english seems to be
//the only language available
/**
 * Builds the query that retrieve the GSBPM overlook
 */
const GSBPMDescription = () => `
  PREFIX gsbpm: <http://rdf.unece.org/models/gsbpm#>
  PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
  select ?phase ?phaseLabel ?subprocess ?subprocessLabel where {
   ?phase a gsbpm:Phase ;
          skos:narrower ?subprocess ;
   OPTIONAL {
     ?phase skos:prefLabel ?phaseLabel
   }
   OPTIONAL {
     ?subprocess skos:prefLabel ?subprocessLabel
   }
  }
 `

export default {
  GSBPMDescription
}

Rename `subProcess` to `subprocess` missing parts


L.Util.getWKT = function(layer) {
    coord2str = function (obj) {
        if(obj.lng) return obj.lng + ' ' + obj.lat + ' 0.0';
        if(obj.length == 0) return null;
        var n, c, wkt = [];
        for (n in obj) {
            c = coord2str(obj[n]);
            if (c) wkt.push(c);
        }
        return ("(" + String(wkt) + ")");
    };
    var coords = '()';
    if(layer.getLatLng) {
        coords = '(' + coord2str(layer.getLatLng()) + ')';
    }
    else if (layer.getLatLngs) {
        coords = coord2str(layer.getLatLngs());
    }
    var wkt = '';
    if (layer instanceof L.Marker) wkt += 'POINT'+coords;
    else if (layer instanceof L.Polygon) wkt += 'POLYGON('+coords+')';
    else if (layer instanceof L.MultiPolygon) wkt += 'MULTIPOLYGON('+coords+')';
    else if (layer instanceof L.Polyline) wkt += 'LINESTRING'+coords;
    else if (layer instanceof L.MultiPolyline) wkt += 'MULTILINESTRING('+coords+')';
    else {
        wkt += 'GEOMETRY'+coords;
    }
    return wkt;
};

L.Util.getWKT = function(layer) {
    coord2str = function (obj) {
        if(obj.lng) return obj.lng + ' ' + obj.lat;
        if(obj.length === 0) return null;
        var n, c, wkt = [];
        for (n in obj) {
            c = coord2str(obj[n]);
            if (c) wkt.push(c);
        }
        return ("(" + String(wkt) + ")");
    };
    var coords = '()';
    if(layer.getLatLng) {
        coords = '(' + coord2str(layer.getLatLng()) + ')';
    }
    else if (layer.getLatLngs) {
        coords = coord2str(layer.getLatLngs());
    }
    var wkt = '';
    if (layer instanceof L.Marker) wkt += 'POINT'+coords;
    else if (layer instanceof L.Polygon) wkt += 'POLYGON('+coords+')';
    else if (layer instanceof L.MultiPolygon) wkt += 'MULTIPOLYGON('+coords+')';
    else if (layer instanceof L.Polyline) wkt += 'LINESTRING'+coords;
    else if (layer instanceof L.MultiPolyline) wkt += 'MULTILINESTRING('+coords+')';
    else {
        wkt += 'GEOMETRY'+coords;
    }
    return wkt;
};

Remove 3rd coord in JS WKT serializer


command: 'echo ""',
refreshFrequency: 3600000,

style: [
	'@import "/common/base.css"',
	'@import "/common/fira/fira.css"',
].join('\n'),

render: function(output) {
	return ''
},

command: 'echo ""',
refreshFrequency: 3600000,

render: function(output) {
	return [
		'<link rel="stylesheet" type="text/css" href="/common/base.css">',
		'<link rel="stylesheet" type="text/css" href="/common/fira/fira.css">',
	].join('\n')
},

Use links to load the css files


/**
 * # authReducer.js
 *
 * The reducer for all the actions from the various log states
 */
'use strict';
/**
 * ## Imports
 *
 * InitialState
 */
import InitialState from './deviceInitialState';

/**
 * Device actions to test
 */
const {
  SET_PLATFORM,
  SET_VERSION,
  SET_STATE
} = require('../../lib/constants');

const initialState = new InitialState;

/**
 * ## deviceReducer function
 * @param {Object} state - initialState
 * @param {Object} action - type and payload
 */
export default function deviceReducer(state = initialState, action) {
  if (!(state instanceof InitialState)) return initialState.merge(state);

  switch (action.type) {

    /**
     * ### set the platform in the state
     *
     */
  case SET_PLATFORM:
    const {platform} = action.payload;
    return state.set('platform', platform);

    /**
     * ### set the version in the state
     *
     */
  case SET_VERSION:
    const {version} = action.payload;
    return state.set('version', version);

    /**
     * ### restore your state
     *
     * Support for Hot Loading
     */
  case SET_STATE:
    const device = JSON.parse(action.payload).device;
    var next = state.set('isMobile',device.isMobile)
          .set('platform',device.platform)
          .set('version',device.version);
    return next;
  }

  return state;
}

/**
 * # authReducer.js
 *
 * The reducer for all the actions from the various log states
 */
'use strict';
/**
 * ## Imports
 *
 * InitialState
 */
import InitialState from './deviceInitialState';

/**
 * Device actions to test
 */
const {
  SET_PLATFORM,
  SET_VERSION,
  SET_STATE
} = require('../../lib/constants').default;

const initialState = new InitialState;

/**
 * ## deviceReducer function
 * @param {Object} state - initialState
 * @param {Object} action - type and payload
 */
export default function deviceReducer(state = initialState, action) {
  if (!(state instanceof InitialState)) return initialState.merge(state);

  switch (action.type) {

    /**
     * ### set the platform in the state
     *
     */
  case SET_PLATFORM:
    const platform = action.payload;
    return state.set('platform', platform);

    /**
     * ### set the version in the state
     *
     */
  case SET_VERSION:
    const version = action.payload;
    return state.set('version', version);

    /**
     * ### restore your state
     *
     * Support for Hot Loading
     */
  case SET_STATE:
    const device = JSON.parse(action.payload).device;
    var next = state.set('isMobile',device.isMobile)
          .set('platform',device.platform)
          .set('version',device.version);
    return next;
  }

  return state;
}

Fix a bug with setVersion and setPlatform


const mediaExtensions = {
  audio: [
    '.aac', '.aif', '.aiff', '.asf', '.dff', '.dsf', '.flac', '.m2a',
    '.m2a', '.m4a', '.mpc', '.m4b', '.mka', '.mp2', '.mp3', '.mpc', '.oga',
    '.ogg', '.opus', '.spx', '.wma', '.wav', '.wv', '.wvp'],
  video: [
    '.avi', '.mp4', '.m4v', '.webm', '.mov', '.mkv', '.mpg', '.mpeg',
    '.ogv', '.webm', '.wmv'],
  image: ['.gif', '.jpg', '.jpeg', '.png']
}

module.exports = mediaExtensions

Add m2ts video container support


var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.json({ appName: 'Highpine REST API v1' });
});

module.exports = router;

let express = require('express');
let router = express.Router();

router.get('/', function(req, res, next) {
  res.json({ appName: 'Highpine backend' });
});

module.exports = router;

Change the backend homepage title.


/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule AlgoliaDocSearch
 */

var AlgoliaDocSearch = React.createClass({
  render: function() {
    return (
      <div className="algolia-search-wrapper">
        <input id="algolia-doc-search" tabindex="0" type="text" placeholder="Search docs..." />
      </div>
    );
  }
});

module.exports = AlgoliaDocSearch;

/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule AlgoliaDocSearch
 */

var AlgoliaDocSearch = React.createClass({
  render: function() {
    return (
      <div className="algolia-search-wrapper">
        <input id="algolia-doc-search" tabIndex="0" type="text" placeholder="Search docs..." />
      </div>
    );
  }
});

module.exports = AlgoliaDocSearch;

Use tabIndex instead of tabindex


module.exports = {
    // Packet constants
    PLAYER_START: "1",
    PLAYER_ADD: "2",
    PLAYER_ANGLE: "2",
    PLAYER_UPDATE: "3",
    PLAYER_ATTACK :"4",
    LEADERBOAD: "5",
    PLAYER_MOVE: "3",
    PLAYER_REMOVE: "4",
    LEADERS_UPDATE: "5",
    LOAD_GAME_OBJ: "6",
    GATHER_ANIM: "7",
    AUTO_ATK: "7",
    WIGGLE: "8",
    CLAN_CREATE: "8",
    PLAYER_LEAVE_CLAN: "9",
    CLAN_REQ_JOIN: "10",
    CLAN_ACC_JOIN: "11",
    CLAN_KICK: "12",
    CHAT: "ch",
    CLAN_DEL: "ad",
    PLAYER_SET_CLAN: "st",
    SET_CLAN_PLAYERS: "sa",
    CLAN_ADD: "ac",
    CLAN_NOTIFY: "an",
    MINIMAP: "mm",
    DISCONN: "d"
}

module.exports = {
    // Packet constants
    PLAYER_START: "1",
    PLAYER_ADD: "2",
    PLAYER_ANGLE: "2",
    PLAYER_UPDATE: "3",
    PLAYER_ATTACK :"4",
    LEADERBOAD: "5",
    PLAYER_MOVE: "3",
    PLAYER_REMOVE: "4",
    LEADERS_UPDATE: "5",
    LOAD_GAME_OBJ: "6",
    GATHER_ANIM: "7",
    AUTO_ATK: "7",
    WIGGLE: "8",
    CLAN_CREATE: "8",
    PLAYER_LEAVE_CLAN: "9",
    STAT_UPDATE: "9",
    CLAN_REQ_JOIN: "10",
    CLAN_ACC_JOIN: "11",
    CLAN_KICK: "12",
    CHAT: "ch",
    CLAN_DEL: "ad",
    PLAYER_SET_CLAN: "st",
    SET_CLAN_PLAYERS: "sa",
    CLAN_ADD: "ac",
    CLAN_NOTIFY: "an",
    MINIMAP: "mm",
    DISCONN: "d"
}

Add stat update packet code


import React from 'react';
import * as PropTypes from 'prop-types';

import styles from './NewsItem.module.css';

const handleNewsItemClick = (link) => {
    const winOption = {
        name: link,
        url: link,
        autoShow: true,
        defaultWidth: 800,
        defaultHeight: 800,
        minWidth: 850,
        minHeight: 500,
        frame: true,
        contextMenu: true,
    };
    window.fin.Window.create(winOption);
}

const NewsItem = ({headline, source, copy, link}) => (

{source}

 handleNewsItemClick(link)}>

{headline}

{copy}

);

NewsItem.propTypes = {
    headline: PropTypes.string.isRequired,
    source: PropTypes.string.isRequired,
    copy: PropTypes.string.isRequired
};

export default NewsItem;

import React from 'react';
import * as PropTypes from 'prop-types';

import styles from './NewsItem.module.css';

const handleNewsItemClick = (link) => {
    const winOption = {
        name: link,
        url: link,
        autoShow: true,
        defaultWidth: 800,
        defaultHeight: 800,
        minWidth: 850,
        minHeight: 500,
        frame: true,
        contextMenu: true,
        api: {
            iframe: {
                sameOriginInjection: false
            }
        }
    };
    window.fin.Window.create(winOption);
}

const NewsItem = ({headline, source, copy, link}) => (

{source}

 handleNewsItemClick(link)}>

{headline}

{copy}

);

NewsItem.propTypes = {
    headline: PropTypes.string.isRequired,
    source: PropTypes.string.isRequired,
    copy: PropTypes.string.isRequired
};

export default NewsItem;

Remove fin API object from article window


import React, { useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { gainShape } from '~client/prop-types/page/funds';
import GraphFundItem from '~client/components/GraphFundItem';
import FundGainInfo from '~client/components/FundGainInfo';

export default function ListRowFundsDesktop({ row: { item, sold, prices, gain } }) {
    const [popout, setPopout] = useState(false);
    const onToggleGraph = useCallback(() => {
        setPopout(!popout);
    }, [popout, setPopout]);

    return (
        <span className={classNames('fund-extra-info', { popout })}>
            <GraphFundItem name={item.toLowerCase().replace(/\W+/g, '-')}
                sold={sold}
                values={prices}
                popout={popout}
                onToggle={onToggleGraph}
            />
            <FundGainInfo gain={gain} sold={sold} />
        </span>
    );
}

ListRowFundsDesktop.propTypes = {
    row: PropTypes.shape({
        id: PropTypes.string.isRequired,
        item: PropTypes.string.isRequired,
        sold: PropTypes.bool.isRequired,
        prices: PropTypes.array.isRequired,
        gain: gainShape.isRequired
    })
};

import React, { useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import { gainShape } from '~client/prop-types/page/funds';
import GraphFundItem from '~client/components/GraphFundItem';
import FundGainInfo from '~client/components/FundGainInfo';

export default function ListRowFundsDesktop({ row: { item, sold, prices, gain } }) {
    const [popout, setPopout] = useState(false);
    const onToggleGraph = useCallback(() => {
        setPopout(!popout);
    }, [popout, setPopout]);

    if (!(prices && prices.length)) {
        return null;
    }

    return (
        <span className={classNames('fund-extra-info', { popout })}>
            <GraphFundItem name={item.toLowerCase().replace(/\W+/g, '-')}
                sold={sold}
                values={prices}
                popout={popout}
                onToggle={onToggleGraph}
            />
            <FundGainInfo gain={gain} sold={sold} />
        </span>
    );
}

ListRowFundsDesktop.propTypes = {
    row: PropTypes.shape({
        id: PropTypes.string.isRequired,
        item: PropTypes.string.isRequired,
        sold: PropTypes.bool.isRequired,
        prices: PropTypes.array,
        gain: gainShape.isRequired
    })
};

Make prices data optional in funds row component


import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from '../helpers/start-app';

const { run } = Ember;

let application;

function getCssProperty(element, property) {
  let elem = document.getElementById(element);
  return window.getComputedStyle(elem, null).getPropertyValue(property);
}

module('Acceptance: Application (Chrome Only)', {
  beforeEach() {
    application = startApp();
  },
  afterEach() {
    run(application, 'destroy');
  }
});

/**
  Execute this test in Chrome or PhantomJS for correct results
*/
test('Verify postcss has run', (assert) => {
  assert.expect(4);

  visit('/');
  andThen(function() {
    assert.equal(currentPath(), 'index', 'On the index page');
    assert.equal(find('#title').length, 1, 'Page contains a header title');
    assert.equal(getCssProperty('title', 'color'), 'rgb(0, 0, 0)', 'postcss-color-gray has run');
    assert.equal(getCssProperty('paragraph', 'color'), 'rgb(102, 51, 153)', 'postcss-rebeccapurple has run');
  });
});

test('Verify additional files can be compiled', (assert) => {
  assert.expect(2);

  visit('/');
  andThen(function() {
    assert.equal(currentPath(), 'index', "On the index page");
    assert.equal(getCssProperty('paragraph', 'margin-bottom'), '16px', 'secondary.css has been processed');
  });
});

import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from '../helpers/start-app';

const { run } = Ember;

let application;

function getCssProperty(element, property) {
  let elem = document.getElementById(element);
  return window.getComputedStyle(elem, null).getPropertyValue(property);
}

module('Acceptance: Application (Chrome Only)', {
  beforeEach() {
    application = startApp();
  },
  afterEach() {
    run(application, 'destroy');
  }
});

/**
  Execute this test in Chrome or PhantomJS for correct results
*/
test('Verify postcss has run', (assert) => {
  assert.expect(4);

  visit('/');
  andThen(function() {
    assert.equal(currentPath(), 'index', 'On the index page');
    assert.equal(find('#title').length, 1, 'Page contains a header title');
    assert.equal(getCssProperty('title', 'color'), 'rgb(0, 0, 0)', 'postcss-color-gray has run');
    assert.equal(getCssProperty('paragraph', 'color'), 'rgb(102, 51, 153)', 'postcss-rebeccapurple has run');
  });
});

test('Verify additional files can be compiled', (assert) => {
  assert.expect(2);

  visit('/');
  andThen(function() {
    assert.equal(currentPath(), 'index', 'On the index page');
    assert.equal(getCssProperty('paragraph', 'margin-bottom'), '16px', 'secondary.css has been processed');
  });
});

Fix quotes in test description for linting


import { test } from 'qunit';
import moduleForAcceptance from '../../tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | application');

test('enabled flags are shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.enabled_foo').length, 1);
  });
});

test('disabled flags are not shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.enabled_bar').length, 0);
  });
});

test('disabled else blocks are shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.disabled_bar').length, 1);
  });
});

test('enabled else blocks are not shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.disabled_foo').length, 0);
  });
});

import { test } from 'qunit';
import moduleForAcceptance from '../../tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | application');

test('enabled flags are shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.enabled_foo').length, 1);
    assert.equal(find('.enabled_foo').text(), 'ENABLED_FOO!! \\o/');
  });
});

test('disabled flags are not shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.enabled_bar').length, 0);
  });
});

test('disabled else blocks are shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.disabled_bar').length, 1);
    assert.equal(find('.disabled_bar').text(), 'DISABLED_BAR!! \\o/');
  });
});

test('enabled else blocks are not shown', function(assert) {
  visit('/');

  andThen(function() {
    assert.equal(find('.disabled_foo').length, 0);
  });
});

Add additional matchers to test to assert text output


$(document).ready(function() {
  console.log('There is jQuery');
});

var loadTodos = function() {
  $.ajax({
    url: "/graphql?query={todoList{id,text,done}}",
    context: document.body
  }).done(function(data) {
    console.log(data);
    var dataParsed = JSON.parse(data);
    var todos = dataParsed.data.todoList;

    if (!$('.todo-list').length) {
      $(this).append('

');
    }

    if (!todos.length) {
      $(this).append('
There are no tasks for you today
');
    }

    $.each(todos, function(i, v) {
      var doneHtml = '<input id="' + v.id + '" type="checkbox"' + (v.done ? ' checked="checked"' : '') + '>';
      var labelHtml = '' + doneHtml + v.text + '';
      var itemHtml = '
' + labelHtml + '
';

      $('.todo-list').append(itemHtml);
    });
  });
};

$(document).ready(function() {
  loadTodos();
});

Add loading todos via `/graphql` query


import path from 'path';
import { BrowserWindow } from 'electron';

export default async () => {
  if (process.env.NODE_ENV === 'development') {
    const installer = require('electron-devtools-installer'); // eslint-disable-line

    const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
    const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
    for (const name of extensions) {
      try {
        await installer.default(installer[name], forceDownload);
      } catch (e) {} // eslint-disable-line
    }
    BrowserWindow.addDevToolsExtension(path.resolve('dist/devtools-helper/'));
  } else {
    BrowserWindow.addDevToolsExtension(path.join(__dirname, 'devtools-helper/'));
  }
  BrowserWindow.addDevToolsExtension(
    path.resolve('node_modules/apollo-client-devtools/shells/webextension/')
  );
};

import path from 'path';
import { BrowserWindow } from 'electron';

export default async () => {
  if (process.env.NODE_ENV === 'development') {
    const installer = require('electron-devtools-installer'); // eslint-disable-line

    const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS'];
    const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
    for (const name of extensions) {
      try {
        await installer.default(installer[name], forceDownload);
      } catch (e) {} // eslint-disable-line
    }
    BrowserWindow.addDevToolsExtension(path.resolve('dist/devtools-helper/'));
    BrowserWindow.addDevToolsExtension(
      path.join(__dirname, '../node_modules/apollo-client-devtools/shells/webextension/')
    );
  } else {
    BrowserWindow.addDevToolsExtension(path.join(__dirname, 'devtools-helper/'));
    BrowserWindow.addDevToolsExtension(
      path.join(__dirname, 'node_modules/apollo-client-devtools/shells/webextension/')
    );
  }
};

Fix extension path of apollo-client-devtools in packaged app


/**
 * Job: <%=name%>
 *
 * Expected configuration:
 *
 * { }
 */

module.exports = function(config, dependencies, job_callback) {
    var text = "Hello World!";

    // first parameter is error (if any). Second parameter is the job result (if success)

    // you can use the following dependencies:
    // - dependencies.request : request module (https://github.com/mikeal/request)
    // - dependencies.logger : logger interface

    job_callback(null, {title: config.widgetTitle, text: text});
};

Add name variable and JSDoc header for the job template


"use strict";
const { assert } = require("chai");
const { describe, it } = require("mocha-sugar-free");

const { JSDOM, VirtualConsole } = require("../..");

describe("API: virtual console jsdomErrors", () => {
  // Note that web-platform-tests do not log CSS parsing errors, so this has to be an API test.
  it("should not omit invalid stylesheet errors due to spaces (GH-2123)", () => {
    const virtualConsole = new VirtualConsole();

    const errors = [];
    virtualConsole.on("jsdomError", e => {
      errors.push(e);
    });

    // eslint-disable-next-line no-new
    new JSDOM(`

          Hello!

      `, { virtualConsole });

    assert.isEmpty(errors);
  });
});

"use strict";
const { assert } = require("chai");
const { describe, it } = require("mocha-sugar-free");

const { JSDOM, VirtualConsole } = require("../..");

describe("API: virtual console jsdomErrors", () => {
  // Note that web-platform-tests do not log CSS parsing errors, so this has to be an API test.
  it("should not emit invalid stylesheet errors due to spaces (GH-2123)", () => {
    const virtualConsole = new VirtualConsole();

    const errors = [];
    virtualConsole.on("jsdomError", e => {
      errors.push(e);
    });

    // eslint-disable-next-line no-new
    new JSDOM(`

          Hello!

      `, { virtualConsole });

    assert.isEmpty(errors);
  });
});

Fix typo in test description


// Phaser 2 wasn't intended to be used with npm modules. See webpack config for how these libs are
// exposed. These need to be imported here so that all other files have access to them from the
// global scope.
import pixi from "pixi";
import p2 from "p2";
import Phaser from "phaser";

import load from "./states/load";
import start from "./states/start";

const game = new Phaser.Game({
  width: 750,
  height: 750,
  renderer: Phaser.WEBGL,
  parent: "game-container"
});

game.state.add("load", load);
game.state.add("start", start);

game.state.start("load");

// // Phaser 2 wasn't intended to be used with npm modules. See webpack config for how these libs are
// // exposed. These need to be imported here so that all other files have access to them from the
// // global scope.
// import pixi from "pixi";
// import p2 from "p2";
// import Phaser from "phaser";

// import load from "./states/load";
// import start from "./states/start";

// const game = new Phaser.Game({
//   width: 750,
//   height: 750,
//   renderer: Phaser.WEBGL,
//   parent: "game-container"
// });

// game.state.add("load", load);
// game.state.add("start", start);

// game.state.start("load");

import Phaser from "phaser";

const game = new Phaser.Game({
  type: Phaser.AUTO,
  parent: "game-container",
  width: 750,
  height: 750,
  backgroundColor: "#ff0000",
  pixelArt: false
});

Convert performance example to bare minimum phaser 3 game to suppress build errors


'use strict';

var toUint   = require('es5-ext/number/to-uint')
  , maxValue = require('./max-value');

module.exports = function (value) {
	value = toUint(value);
	if (value > maxValue) {
		throw new TypeError(value + " is to large for a timeout");
	}
	return value;
};

'use strict';

var toPosInt = require('es5-ext/number/to-pos-integer')
  , maxValue = require('./max-value');

module.exports = function (value) {
	value = toPosInt(value);
	if (value > maxValue) {
		throw new TypeError(value + " is to large for a timeout");
	}
	return value;
};

Update up to changes in es5-ext


import {Instrumenter} from 'istanbul';
import convertSourceMap from 'convert-source-map';

// Customized from istanbul-instrument-loader to support
// source maps properly.
module.exports = function(source, sourceMap) {
  if (sourceMap) {
    source = `${source}\n${convertSourceMap.fromObject(sourceMap).toComment()}`;
  }

  let instrumenter = new Instrumenter({
    embedSource: true,
    includeUntested: true,
    sourceMap: true
  });

  if (this.cacheable) {
    this.cacheable();
  }

  source = instrumenter.instrumentSync(source, this.resourcePath);
  sourceMap = convertSourceMap.fromSource(source).toJSON();

  this.callback(undefined, source, sourceMap);
};

import {Instrumenter} from 'istanbul';
import convertSourceMap from 'convert-source-map';

// Customized from istanbul-instrument-loader to support
// source maps properly.
module.exports = function(source, sourceMap) {
  if (sourceMap) {
    source = `${source}\n${convertSourceMap.fromObject(sourceMap).toComment()}`;
  }

  let instrumenter = new Instrumenter({
    embedSource: true,
    includeUntested: true,
    sourceMap: true
  });

  if (this.cacheable) {
    this.cacheable();
  }

  source = instrumenter.instrumentSync(source, this.resourcePath);
  sourceMap = convertSourceMap.fromSource(source);
  sourceMap = sourceMap && sourceMap.toJSON();

  this.callback(undefined, source, sourceMap);
};

Handle missing source maps in a safer fashion


var Mystique = require('mystique');

var AppointmentItemTransformer = Mystique.Transformer.extend({
  resourceName: 'appointmentItem',
  mapOut: function(appointmentItem) {
    return {
      id: appointmentItem.id,
      service: appointmentItem.service,
      name: appointmentItem.name,
      startTime: appointmentItem.startTime,
      length: appointmentItem.length,
      title: appointmentItem.title,
    };
  },

  mapIn(req) {
    return {
      service: req.getJson('appointmentItem.service'),
      name: req.getJson('appointmentItem.name'),
      startTime: req.getJson('appointmentItem.startTime'),
      length: req.getJson('appointmentItem.length'),
      title: req.getJson('appointmentItem.title'),
    };
  },
});

Mystique.registerTransformer('AppointmentItem', AppointmentItemTransformer);

var Mystique = require('mystique');

var AppointmentItemTransformer = Mystique.Transformer.extend({
  resourceName: 'appointmentItem',
  mapOut: function(appointmentItem) {
    return {
      id: appointmentItem.id,
      service: appointmentItem.service,
      name: appointmentItem.name,
      startTime: appointmentItem.startTime,
      length: appointmentItem.length,
      title: appointmentItem.title,
      client: appointmentItem.client,
    };
  },

  mapIn(req) {
    return {
      service: req.getJson('appointmentItem.service'),
      name: req.getJson('appointmentItem.name'),
      startTime: req.getJson('appointmentItem.startTime'),
      length: req.getJson('appointmentItem.length'),
      title: req.getJson('appointmentItem.title'),
    };
  },
});

Mystique.registerTransformer('AppointmentItem', AppointmentItemTransformer);

Update client out from appointmentItem


/*jshint node:true*/

'use strict';

var path = require('path');

module.exports = {
  normalizeEntityName: function() {
    // this prevents an error when the entityName is
    // not specified (since that doesn't actually matter
    // to us
  },

  fileMapTokens: function() {
    return {
      __root__: function(options) {
        if (options.inAddon) {
          return path.join('tests', 'dummy', 'app');
        }

        return 'app';
      }
    };
  },

  afterInstall: function() {
    this.insertIntoFile('.jshintrc', '    "server",', {
      after: '"predef": [\n'
    });

    this.insertIntoFile('tests/.jshintrc', '    "server",', {
      after: '"predef": [\n'
    });

    return this.addBowerPackagesToProject([
      {name: 'pretender', target: '~0.9.0'},
      {name: 'lodash', target: '~3.7.0'},
      {name: 'Faker', target: '~3.0.0'}
    ]);
  }
};

/*jshint node:true*/

'use strict';

var path = require('path');

module.exports = {
  normalizeEntityName: function() {
    // this prevents an error when the entityName is
    // not specified (since that doesn't actually matter
    // to us
  },

  fileMapTokens: function() {
    return {
      __root__: function(options) {
        if (options.inAddon) {
          return path.join('tests', 'dummy', 'app');
        }

        return 'app';
      }
    };
  },

  afterInstall: function() {
    this.insertIntoFile('.jshintrc', '    "server",', {
      after: '"predef": [\n'
    });

    this.insertIntoFile('tests/.jshintrc', '    "server",', {
      after: '"predef": [\n'
    });

    return this.addBowerPackagesToProject([
      {name: 'pretender', target: '~0.10.1'},
      {name: 'lodash', target: '~3.7.0'},
      {name: 'Faker', target: '~3.0.0'}
    ]);
  }
};

Update Pretender version to ~0.10.1


module.exports = {
    baseURL: 'http://localhost:9000',
    browser: 'chrome',
    driverCapabilities: {
        "chromeOptions": {
            "binary": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
        }
    },
    quit: 'never'
}

module.exports = {
    baseURL: 'http://localhost:9000',
    browser: 'chrome',
    driverCapabilities: {
        "chromeOptions": {
            "binary": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
            "args": [ "start-maximized" ]
        }
    },
    quit: 'never'
}

Add start-maximized to chrome options