'use strict';

var Utils = require('../../utils');

module.exports = (function() {
  var QueryGenerator = {
    dialect: 'mssql',

    showTablesQuery: function () {
      return 'SELECT * FROM sys.Tables';
    },

    dropTableQuery: function(tableName, options) {
      options = options || {};

      var query = "IF OBJECT_ID('dbo.<%= tableName %>', 'U') IS NOT NULL DROP TABLE dbo.<%= tableName %>";

      return Utils._.template(query)({
        tableName: tableName
      });
    }
  };

  return Utils._.extend(Utils._.clone(require('../mysql/query-generator')), QueryGenerator);
})();

'use strict';

var Utils = require('../../utils');

module.exports = (function() {
  var QueryGenerator = {
    dialect: 'mssql',

    quoteIdentifier: function(identifier, force) {
      if (identifier === '*') return identifier;
      return Utils.addTicks(identifier, '"');
    },

    showTablesQuery: function () {
      return 'SELECT * FROM sys.Tables';
    },

    dropTableQuery: function(tableName, options) {
      options = options || {};

      var query = "IF OBJECT_ID('dbo.<%= tableName %>', 'U') IS NOT NULL DROP TABLE dbo.<%= tableName %>";

      return Utils._.template(query)({
        tableName: tableName
      });
    },

    createTableQuery: function(tableName, attributes, options) {
      var query       = "IF OBJECT_ID('<%= unquotedTable %>', N'U') IS NULL CREATE TABLE <%= table %> (<%= attributes%>)"
        , attrStr     = []
        , self        = this
        , primaryKeys = Utils._.keys(Utils._.pick(attributes, function(dataType){
          return dataType.indexOf('PRIMARY KEY') >= 0;
        }));

      for (var attr in attributes) {
        if (attributes.hasOwnProperty(attr)) {
          var dataType = attributes[attr];
          if (primaryKeys.length > 1){
            dataType = dataType.replace(/ PRIMARY KEY/, '');
          }
          attrStr.push(self.quote(attr) + " " + dataType);
        }
      }

      if (primaryKeys.length > 1) {
        attrStr.push('PRIMARY KEY(' + primaryKeys.map(function(column){
          return self.quote(column);
        }).join(', ') + ')');
      }

      var values = {
          unquotedTable: tableName,
          table: self.quote(tableName),
          attributes: attrStr.join(", ")
        };

      return Utils._.template(query)(values).trim() + ";";
    }
  };

  return Utils._.extend(Utils._.clone(require('../mysql/query-generator')), QueryGenerator);
})();

Add first steps for createTableQuery


'use strict';

var accumulator = require('../lib/accumulator.js'),
    nock = require('nock');

describe('accumulator', function() {
    afterEach(function() {
        nock.cleanAll();
    });

    it('resolves successfully when all urls are successful', function(done) {
        var url = "http://localhost:32768/",
            statusCode = 200,
            thirty_seconds_in_ms = 30 * 1000;

        nock(url)
            .head('/')
            .reply(statusCode);

        var url_b = "http://localhost:32769/";
        nock(url_b)
            .head('/')
            .reply(statusCode);

        var pending = accumulator([url, url_b], thirty_seconds_in_ms);

        pending.done(function() {
            done();
        });
    });
});

'use strict';

var accumulator = require('../lib/accumulator.js'),
    nock = require('nock'),
    successCode = 200;

describe('accumulator', function() {
    afterEach(function() {
        nock.cleanAll();
    });

    it('resolves successfully when all URLs are successful', function(done) {
        var urls = ['http://localhost:32001/', 'http://localhost:32002'],
            thirty_seconds_in_ms = 30 * 1000;

        urls.forEach(function(url) {
            nock(url)
                .head('/')
                .reply(successCode);
        });

        var pending = accumulator(urls, thirty_seconds_in_ms);

        pending.done(function() {
            done();
        });
    });

    it('errors out if one of the URLs is not successful', function(done) {
        var urls = ['http://localhost:32001/', 'http://localhost:32002'],
            one_second_in_ms = 1 * 1000;

        urls.forEach(function(url) {
            nock(url)
                .head('/')
                .reply(successCode);
        });

        urls.push('http://not.going.to.respond.localhost:32003/');

        var pending = accumulator(urls, one_second_in_ms);

        pending.done(
            function() {},
            function() {
                done();
            });
    });
});

Add test for failure case to accumulator


export default {
  coreModules: [
    'meteor/accounts-base',
    'meteor/blaze',
    'meteor/check',
    'meteor/ddp-client',
    'meteor/ddp-rate-limiter',
    'meteor/ejson',
    'meteor/email',
    'meteor/http',
    'meteor/check',
    'meteor/meteor',
    'meteor/mongo',
    'meteor/random',
    'meteor/reactive-var',
    'meteor/session',
    'meteor/templating',
    'meteor/tracker',
  ],
};

export default {
  coreModules: [
    'meteor/accounts-base',
    'meteor/blaze',
    'meteor/check',
    'meteor/ddp-client',
    'meteor/ddp-rate-limiter',
    'meteor/ejson',
    'meteor/email',
    'meteor/http',
    'meteor/check',
    'meteor/meteor',
    'meteor/mongo',
    'meteor/random',
    'meteor/reactive-var',
    'meteor/session',
    'meteor/templating',
    'meteor/tracker',
  ],

  namedExports: {
    'meteor/accounts-base': ['AccountsClient', 'Accounts', 'AccountsServer'],
    'meteor/blaze': ['Blaze'],
    'meteor/check': ['check', 'Match'],
    'meteor/ddp-client': ['DDP'],
    'meteor/ddp-rate-limiter': ['DDPRateLimiter'],
    'meteor/ejson': ['EJSON'],
    'meteor/email': ['Email'],
    'meteor/http': ['HTTP'],
    'meteor/meteor': ['Meteor'],
    'meteor/mongo': ['Mongo'],
    'meteor/random': ['Random'],
    'meteor/reactive-var': ['ReactiveVar'],
    'meteor/session': ['Session'],
    'meteor/templating': ['Template'],
    'meteor/tracker': ['Tracker'],
  },
};

Add namedExports to meteor environment


var vm = require('vm');

exports.javascript = function(element, code, filename) {
  var document = element.ownerDocument,
      window = document.parentWindow;

  if (window) {
    var tracelimitbak = Error.stackTraceLimit;
    Error.stackTraceLimit = 100;
    try {
      vm.Script.runInNewContext(code, window, filename);
    }
    catch(e) {
      element.trigger(
        'error', 'Running ' + filename + ' failed.',
        {error: e, filename: filename}
      );
    }
    Error.stackTraceLimit = tracelimitbak;
  }
};

var vm = require('vm');

exports.javascript = function(element, code, filename) {
  var document = element.ownerDocument,
      window = document.parentWindow;

  if (window) {
    var ctx = window.__scriptContext;
    if (!ctx) {
      window.__scriptContext = ctx = vm.createContext({});
      ctx.__proto__ = window;
    }
    var tracelimitbak = Error.stackTraceLimit;
    Error.stackTraceLimit = 100;
    try {
      vm.Script.runInContext(code, ctx, filename);
    }
    catch(e) {
      element.trigger(
        'error', 'Running ' + filename + ' failed.',
        {error: e, filename: filename}
      );
    }
    Error.stackTraceLimit = tracelimitbak;
  }
};

Revert "Patch to allow Ender packages to work with jsdom.env"


(function() {
    "use strict";

    var h1 = document.getElementsByTagName("h1")[0];
    h1.style.backgroundColor = "lightblue";
})();

(function() {
    "use strict";

    document.getElementsByTagName("html")[0].className = "js";

    var h1 = document.getElementsByTagName("h1")[0];
    h1.style.backgroundColor = "lightblue";
})();

Change html element class when javascript is available


var frisby = require('frisby');
var root = "http://localhost:3000";
var gamesPath = "/games"

frisby.create('Game starts when a user POSTs a new game')
  .post(root + gamesPath)
  .expectStatus(200)
  .expectHeaderContains('content-type', 'application/json')
  // .inspectJSON()
  .expectJSON({ status: "setup" })
  .expectJSONTypes({ id: Number })
.toss();

frisby.create('Setup ends when a user updates game with PUT')
  .put(root + gamesPath + "2")
  .expectStatus(200)
  .expectHeaderContains('content-type', 'application/json')
  .expectJSON({})
// .toss();

var frisby = require('frisby');
var root = "http://localhost:3000";
var gamesPath = "/games";
var id = 2;

frisby.create('Game starts when a user POSTs a new game')
  .post(root + gamesPath)
  .expectStatus(200)
  .expectHeaderContains('content-type', 'application/json')
  // .inspectJSON()
  .expectJSON({ status: "setup" })
  .expectJSONTypes({ id: Number })
.toss();

frisby.create('Setup ends when a user updates game with PUT')
  .put(root + gamesPath + "/" + id)
  .expectStatus(200)
  .expectHeaderContains('content-type', 'application/json')
  .expectJSON({})
// .toss();

frisby.create('Poll for game state via GET /games/:id')
  .get(root + gamesPath + "/" + id)
  .expectStatus(200)
  .expectHeaderContains('content-type', 'application/json')
  .expectJSON({})
// .toss();

frisby.create('Fire a shot via POST /games/:id/shots')
  .post(root + gamesPath + '/' + id + '/shots')
  .expectStatus(200)
  .expectHeaderContains('content-type', 'application/json')
  .expectJSON({})
// .toss();

Create skipped features to flesh out API


import React        from 'react'
import { merge }    from 'lodash'
import {
  Router as ReactRouter,
  RouterContext,
  browserHistory,
  createMemoryHistory,
  match
} from 'react-router'

import {
  syncHistoryWithStore,
  routerReducer
} from 'react-router-redux'

export {
  Route,
  IndexRoute,
  Redirect,
  IndexRedirect,
  Link,
  IndexLink,
} from 'react-router'

export renderer from './renderer'

export default Router

export class Router {

  static defaults = {
    routes: []
  };

  constructor(opts) {
    this.options = merge({}, Router.defaults, opts)
    this.routes = this.options.routes
  }

  registerStore(store) {
    syncHistoryWithStore(this.history, store)
  }

  getReducer() {
    return routerReducer
  }

  getComponent(renderProps, client = false) {
    return client
      ? <ReactRouter {...renderProps} />
      : <RouterContext {...renderProps} />
  }

  match(req, callback) {
    if (arguments.length === 1 && typeof req === 'function') {
      callback = req
      req = null
    }
    return match(this.createMatchOptions(req), callback)
  }

  createMatchOptions(req) {
    const opts = { routes: this.routes }
    if (req) {
      opts.history = createMemoryHistory()
      opts.location = req.url
    } else {
      opts.history = browserHistory
    }
    this.history = opts.history
    return opts
  }

}

import React        from 'react'
import { merge }    from 'lodash'
import {
  Router as ReactRouter,
  RouterContext,
  browserHistory,
  createMemoryHistory,
  match
} from 'react-router'

import {
  syncHistoryWithStore,
  routerReducer
} from 'react-router-redux'

export {
  Route,
  IndexRoute,
  Redirect,
  IndexRedirect,
  Link,
  IndexLink,
} from 'react-router'

export renderer from './renderer'

export default Router

export class Router {

  static defaults = {
    routes: []
  };

  constructor(opts) {
    this.options = merge({}, Router.defaults, opts)
    this.routes = this.options.routes
  }

  registerStore(store) {
    this.history = syncHistoryWithStore(this.history, store)
  }

  getReducer() {
    return routerReducer
  }

  getComponent(renderProps, client = false) {
    return client
      ? <ReactRouter {...renderProps} />
      : <RouterContext {...renderProps} />
  }

  match(req, callback) {
    if (arguments.length === 1 && typeof req === 'function') {
      callback = req
      req = null
    }
    return match(this.createMatchOptions(req), callback)
  }

  createMatchOptions(req) {
    const opts = { routes: this.routes }
    if (req) {
      opts.history = createMemoryHistory()
      opts.location = req.url
    } else {
      opts.history = browserHistory
    }
    this.history = opts.history
    return opts
  }

}

Fix issue with not using upgraded history object


CubeGame.Credits = function() {};
CubeGame.Credits.prototype = {
    create: function() {
        this.credits = "Avoid the obstacles with the Cube!\nCreated with the Phaser Game Engine\n\nImages created in Inkscape\nSounds created in Audacity";
        this.creditsText = CubeGame.factory.addText(100, 50, this.credits, 30, "#5f5f5f");

        this.menuButton = this.game.add.button(100, 400, "Textures", this.menuState, this);
        this.menuButton.frameName = "MenuButton";

        this.creditsThingsGroup = this.game.add.group();
        this.creditsThingsGroup.add(this.menuButton);
        this.creditsThingsGroup.add(this.creditsText);
        this.creditsThingsSlideIn = this.game.add.tween(this.creditsThingsGroup)
            .from({x:1500}, 500, Phaser.Easing.Sinusoidal.Out).start();
    },
    menuState: function() {
        this.game.state.start("Menu");
    }
};

CubeGame.Credits = function() {};
CubeGame.Credits.prototype = {
    create: function() {
        this.credits = "Avoid the obstacles with the Cube!\nA Javascript/HTML5 Game\nCreated with the Phaser Game Engine\n\nImages created in Inkscape\nSounds created in Audacity";
        this.creditsText = CubeGame.factory.addText(100, 50, this.credits, 30, "#5f5f5f");

        this.menuButton = this.game.add.button(100, 400, "Textures", this.menuState, this);
        this.menuButton.frameName = "MenuButton";

        this.creditsThingsGroup = this.game.add.group();
        this.creditsThingsGroup.add(this.menuButton);
        this.creditsThingsGroup.add(this.creditsText);
        this.creditsThingsSlideIn = this.game.add.tween(this.creditsThingsGroup)
            .from({x:1500}, 500, Phaser.Easing.Sinusoidal.Out).start();
    },
    menuState: function() {
        this.game.state.start("Menu");
    }
};

Add note in credits about Javascript/HTML5


jQuery(function($) {

    var PhileoLikes = function(form, options) {
        this.options = $.extend({}, $.fn.phileo.defaults, options);
        this.$form = $(form);

        this.$count = $(this.options.count);

        var self = this;
        this.$form.submit(function(event) {
            event.preventDefault();

            $.ajax({
                url: self.$form.attr('action'),
                type: "POST",
                data: self.$form.serialize(),
                statusCode: {
                    200: function(data, textStatus, jqXHR) {
                        self.$count.text(data.likes_count);
                        self.$form[data.liked ? 'addClass' : 'removeClass'](self.options.toggle_class);
                    }
                }
            });
        });
    };

    $.fn.phileo = function(options) {
        $(this).each(function(i, el) {
            var phileo = new PhileoLikes(el, options);
            $(el).data('Phileo', {instance: phileo});
        });
        return this;
    };

    $.fn.phileo.defaults = {
        toggle_class: 'phileo-liked',
        count: false
    };
});

!function($){
    "use strict";

    var PhileoLikes = function(form, options) {
        this.options = $.extend({}, $.fn.phileo.defaults, options);
        this.$form = $(form);

        this.$count = $(this.options.count);

        var self = this;
        this.$form.submit(function(event) {
            event.preventDefault();

            $.ajax({
                url: self.$form.attr('action'),
                type: "POST",
                data: self.$form.serialize(),
                statusCode: {
                    200: function(data, textStatus, jqXHR) {
                        self.$count.text(data.likes_count);
                        self.$form[data.liked ? 'addClass' : 'removeClass'](self.options.toggle_class);
                    }
                }
            });
        });
    };

    $.fn.phileo = function(options) {
        $(this).each(function(i, el) {
            var phileo = new PhileoLikes(el, options);
            $(el).data('Phileo', {instance: phileo});
        });
        return this;
    };

    $.fn.phileo.defaults = {
        toggle_class: 'phileo-liked',
        count: false
    };
}( window.jQuery || window.ender );

Add jQuery plugin on page load, not domready


document.addEventListener('beforeload', onBeforeLoad, true);

var config = [
    {
        source: 'source.js',
        reSource: 'reSource.js'
    }
];

function onBeforeLoad(event) {
    if (event.srcElement.tagName == 'SCRIPT') {
        console.error(event.url);
        for(var i = 0; i < config.length; i++) {
            if (event.url == config[i].source) {
                event.preventDefault();
                var script = document.createElement('script');
                script.setAttribute('src', config[i].reSource);
                event.srcElement.parentNode.replaceChild(script, event.srcElement);
                return;
            }
        }
    }
}

document.addEventListener('beforeload', onBeforeLoad, true);

var config = [
    {
        source: 'source.js',
        reSource: 'reSource.js'
    }
];

function onBeforeLoad(event) {
    if (event.srcElement.tagName == 'SCRIPT') {
        for(var i = 0; i < config.length; i++) {
            var regexp = new RegExp(config[i].source);
            if (regexp.test(event.url)) {
                event.preventDefault();
                var script = document.createElement('script');
                script.setAttribute('src', config[i].reSource);
                event.srcElement.parentNode.replaceChild(script, event.srcElement);
                return;
            }
        }
    }
}

Replace strings comparison with regexp


'use strict';

var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var filesize = require('gulp-filesize');
var minifyCss = require('gulp-minify-css');
var plumber = require('gulp-plumber');
var jslint = require('gulp-jslint');

gulp.task('sass', function () {
    gulp.src('./src/WebRobot/FreelanceBundle/Resources/assets/sass/**/*.scss')
        .pipe(plumber())
        .pipe(filesize())
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer({
            browsers: ['last 2 versions'],
            cascade: false
        }))
        .pipe(minifyCss({compatibility: 'ie8'}))
        .pipe(gulp.dest('./src/WebRobot/FreelanceBundle/Resources/public/css'))
        .pipe(filesize());
});

gulp.task('js', function () {
    gulp.src('./src/WebRobot/FreelanceBundle/Resources/assets/js/**/*.js')
        .pipe(plumber())
        .pipe(filesize())
        .pipe(jslint({
            node: true,
            reporter: 'default'
        }))
        .pipe(gulp.dest('./src/WebRobot/FreelanceBundle/Resources/public/js'))

});

gulp.task('sass:watch', function () {
    gulp.watch('./src/WebRobot/FreelanceBundle/Resources/assets/sass/**/*.scss', ['sass']);
});

gulp.task('default', ['sass', 'js']);

'use strict';

var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var filesize = require('gulp-filesize');
var minifyCss = require('gulp-minify-css');
var plumber = require('gulp-plumber');
var jslint = require('gulp-jslint');

gulp.task('sass', function () {
    gulp.src('./src/WebRobot/FreelanceBundle/Resources/assets/sass/**/*.scss')
        .pipe(plumber())
        .pipe(filesize())
        .pipe(sass().on('error', sass.logError))
        .pipe(autoprefixer({
            browsers: ['last 2 versions'],
            cascade: false
        }))
        .pipe(minifyCss({compatibility: 'ie8'}))
        .pipe(gulp.dest('./src/WebRobot/FreelanceBundle/Resources/public/css'))
        .pipe(filesize());
});

gulp.task('js', function () {
    gulp.src('./src/WebRobot/FreelanceBundle/Resources/assets/js/**/*.js')
        .pipe(plumber())
        .pipe(filesize())
        .pipe(jslint({
            node: true,
            reporter: 'default'
        }))
        .pipe(gulp.dest('./src/WebRobot/FreelanceBundle/Resources/public/js'))

});

gulp.task('default',function() {
    gulp.watch('./src/WebRobot/FreelanceBundle/Resources/assets/sass/*.scss',['sass', 'js']);
});

Remove sass:watch task and replace by default


// @flow
/**
 * Part of GDL gdl-frontend.
 * Copyright (C) 2018 GDL
 *
 * See LICENSE
 */

import * as React from 'react';
import Taken from './Taken';
import { Trans } from '@lingui/react';
import Link from 'next/link';
import { Typography } from '@material-ui/core';

import Container from '../../elements/Container';
import A from '../../elements/A';
import Head from '../Head';
import Layout from '../Layout';
import { spacing } from '../../style/theme/';

const NotFound = () => (
  <Layout>
    <Head title="Page not found" />
    <Container>
      <Typography component="h1" align="center" variant="headline" gutterBottom>
        <Trans>Oh no!</Trans>
      </Typography>
      <Typography
        component="h2"
        align="center"
        variant="subheading"
        gutterBottom
      >
        <Trans>The page you were looking for was taken by a 404.</Trans>
      </Typography>
      <div
        css={{
          textAlign: 'center',
          marginTop: spacing.medium,
          marginBottom: spacing.medium
        }}
      >
        <Taken height="100%" />
      </div>
      <Link href="/" passHref>
        <A align="center">
          <Trans>Take me home</Trans>
        </A>
      </Link>
    </Container>
  </Layout>
);

export default NotFound;

// @flow
/**
 * Part of GDL gdl-frontend.
 * Copyright (C) 2018 GDL
 *
 * See LICENSE
 */

import * as React from 'react';
import Taken from './Taken';
import { Trans } from '@lingui/react';
import Link from 'next/link';
import { Typography } from '@material-ui/core';

import Container from '../../elements/Container';
import A from '../../elements/A';
import Head from '../Head';
import Layout from '../Layout';
import { spacing } from '../../style/theme/';

const NotFound = () => (
  <Layout>
    <Head title="Page not found" />
    <Container my="30px">
      <Typography component="h1" align="center" variant="headline" gutterBottom>
        <Trans>Oh no!</Trans>
      </Typography>
      <Typography
        component="h2"
        align="center"
        variant="subheading"
        gutterBottom
      >
        <Trans>The page you were looking for was taken by a 404.</Trans>
      </Typography>
      <div
        css={{
          textAlign: 'center',
          marginTop: spacing.medium,
          marginBottom: spacing.medium
        }}
      >
        <Taken height="100%" />
      </div>
      <Link href="/" passHref>
        <A align="center">
          <Trans>Take me home</Trans>
        </A>
      </Link>
    </Container>
  </Layout>
);

export default NotFound;

Add container spacing to 404 page


const setItem = type => (key, item) => {
  const obj = window[`${type}Storage`];
  return obj.setItem(key, JSON.stringify(item));
};
const getItem = type => (key, defaultValue, saveIfNotExist) => {
  const obj = window[`${type}Storage`];
  const savedItem = obj.getItem(key);
  if (!savedItem && saveIfNotExist) {
    setItem(type)(key, defaultValue);
  }

  return savedItem ? JSON.parse(savedItem) : defaultValue;
};

export const storage = {
  local: {
    setItem: setItem('local'),
    getItem: getItem('local'),
  },
  session: {
    setItem: setItem('session'),
    getItem: getItem('session'),
  },
};

export const getTreeNodeData = (treeData, key) => {
  const arr = [treeData];
  while (arr.length) {
    const node = arr.pop();
    if (node.key === key) return node;
    if (node.children) arr.push.apply(arr, node.children);
  }
  return null;
};

const setItem = type => (key, item) => {
  const obj = window[`${type}Storage`];
  return obj.setItem(key, JSON.stringify(item));
};
const getItem = type => (key, defaultValue, saveIfNotExist) => {
  const obj = window[`${type}Storage`];
  const savedItem = obj.getItem(key);
  if (!savedItem && saveIfNotExist) {
    setItem(type)(key, defaultValue);
  }
  try {
    if (savedItem) return JSON.parse(savedItem);
  } catch (e) {
    obj.removeItem(key);
    return defaultValue;
  }
  return defaultValue;
};

const removeItem = type => (key) => {
  const obj = window[`${type}Storage`];
  obj.removeItem(key);
};

export const storage = {
  local: {
    setItem: setItem('local'),
    getItem: getItem('local'),
    removeItem: removeItem('local'),
  },
  session: {
    setItem: setItem('session'),
    getItem: getItem('session'),
    removeItem: removeItem('session'),
  },
};

export const getTreeNodeData = (treeData, key) => {
  const arr = [treeData];
  while (arr.length) {
    const node = arr.pop();
    if (node.key === key) return node;
    if (node.children) arr.push.apply(arr, node.children);
  }
  return null;
};

Fix a bug that failed to show Rekit Studio.


/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const ChunkGroup = require("./ChunkGroup");

class Entrypoint extends ChunkGroup {
	constructor(name) {
		super(name);
		this.runtimeChunk = undefined;
	}

	isInitial() {
		return true;
	}

	getFiles() {
		const files = new Set();

		for(let chunkIdx = 0; chunkIdx < this.chunks.length; chunkIdx++) {
			for(let fileIdx = 0; fileIdx < this.chunks[chunkIdx].files.length; fileIdx++) {
				files.add(this.chunks[chunkIdx].files[fileIdx]);
			}
		}

		return Array.from(files);
	}

	setRuntimeChunk(chunk) {
		this.runtimeChunk = chunk;
	}

	getRuntimeChunk() {
		return this.runtimeChunk || this.chunks[0];
	}
}

module.exports = Entrypoint;

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
"use strict";

const ChunkGroup = require("./ChunkGroup");

class Entrypoint extends ChunkGroup {
	constructor(name) {
		super(name);
		this.runtimeChunk = undefined;
	}

	isInitial() {
		return true;
	}

	getFiles() {
		const files = new Set();

		for(const chunk of this.chunks) {
			for(const file of chunk) {
				files.add(file);
			}
		}

		return Array.from(files);
	}

	setRuntimeChunk(chunk) {
		this.runtimeChunk = chunk;
	}

	getRuntimeChunk() {
		return this.runtimeChunk || this.chunks[0];
	}
}

module.exports = Entrypoint;

Simplify for loop in EntryPoint.getFiles


var Application = require('application');

module.exports = (function() {

    function prepareDOM() {
        document.body.innerHTML = '';
        document.body.appendChild(document.createElement('gelato-application'));
        document.body.appendChild(document.createElement('gelato-dialogs'));
        document.body.appendChild(document.createElement('gelato-navbars'));
        document.body.appendChild(document.createElement('gelato-sidebars'));
    }

    function start() {
        prepareDOM();
        window.app = new Application();
        window.app.start();
    }

    if (location.protocol === 'file:') {
        $.ajax({
            url: 'cordova.js',
            dataType: 'script'
        }).done(function() {
            document.addEventListener('deviceready', start, false);
        }).fail(function() {
            console.error(new Error('Unable to load cordova.js file.'));
        });
    } else {
        $(document).ready(start);
    }

})();

var Application = require('application');

module.exports = (function() {

    function prepareDOM() {
        document.body.appendChild(document.createElement('gelato-application'));
        document.body.appendChild(document.createElement('gelato-dialogs'));
        document.body.appendChild(document.createElement('gelato-navbars'));
        document.body.appendChild(document.createElement('gelato-sidebars'));
    }

    function start() {
        prepareDOM();
        window.app = new Application();
        window.app.start();
    }

    if (location.protocol === 'file:') {
        $.ajax({
            url: 'cordova.js',
            dataType: 'script'
        }).done(function() {
            document.addEventListener('deviceready', start, false);
        }).fail(function() {
            console.error(new Error('Unable to load cordova.js file.'));
        });
    } else {
        $(document).ready(start);
    }

})();

Stop force clearing the dom when gelato is preparing it.


/**
  RemoteCall
  @description function that makes the remote call using the fetch polyfill,
    running a series of provided lifecycle hooks
  @exports @default {function} callRemoteResource
**/

/* eslint no-unused-vars:0 */
// TODO: should probably use a global fetch instance if we can
import fetch from 'isomorphic-fetch';

/**
  @private
  @name callRemoteResource
  @desc makes a call using the fetch API w/ the given request data & hooks
  @param {object} request
  @param {string} request.uri
  @param {string} request.method
  @param {object} request.headers
  @param {string} request.body
  @param {object} request.requestOps arbitrary options passed to fetch
  @param {object} hooks the lifecycle hooks evaluated at various times
  @param {function} hooks.onBeforeCall
  @param {function} hooks.onCallSuccess(data, response)
  @param {function} hooks.onCallFailure(statusCode, data, response)
**/
export default function callRemoteResource(request, hooks) {
  return null;
}

/**
  RemoteCall
  @description function that makes the remote call using the fetch polyfill,
    running a series of provided lifecycle hooks
  @exports @default {function} callRemoteResource
**/

/* eslint no-unused-vars:0 */
// TODO: should probably use a global fetch instance if we can
import fetch from 'isomorphic-fetch';

/**
  @private
  @name callRemoteResource
  @desc makes a call using the fetch API w/ the given request data & hooks
  @param {object} request
  @param {string} request.uri
  @param {string} request.method
  @param {object} request.headers
  @param {string} request.body
  @param {object} request.requestOps arbitrary options passed to fetch
  @param {array} statusActions an array of objects w/ code & callback keys
  @param {object} hooks the lifecycle hooks evaluated at various times
  @param {function} hooks.onBeforeCall
  @param {function} hooks.onCallSuccess(data, response)
  @param {function} hooks.onCallFailure(statusCode, data, response)
**/
export default function callRemoteResource(request, statusActions, hooks) {
  return null;
}

Add statusActions arg to remote call sig


(function(){

	/**
	 * Reticle 3D Sprite
	 * @param {THREE.Color} [color=0xfffff] - Color of the reticle sprite
	 * @param {string} [url=PANOLENS.DataImage.Reticle] - Image asset url
	 */
	PANOLENS.Reticle = function ( color, url ) {

		var map, material;

		color = color || 0xffffff;
		url = url || PANOLENS.DataImage.Reticle;

		map = PANOLENS.Utils.TextureLoader.load( url );
		material = new THREE.SpriteMaterial( { map: map, color: color } );

		THREE.Sprite.call( this, material );

		this.visible = false;

	}

	PANOLENS.Reticle.prototype = Object.create( THREE.Sprite.prototype );

	PANOLENS.Reticle.prototype.constructor = PANOLENS.Reticle;

	PANOLENS.Reticle.prototype.show = function () {

		this.visible = true;

	};

	PANOLENS.Reticle.prototype.hide = function () {

		this.visible = false;

	};

})();

(function(){

	/**
	 * Reticle 3D Sprite
	 * @param {THREE.Color} [color=0xfffff] - Color of the reticle sprite
	 * @param {string} [url=PANOLENS.DataImage.Reticle] - Image asset url
	 */
	PANOLENS.Reticle = function ( color, url ) {

		var map, material;

		color = color || 0xffffff;
		url = url || PANOLENS.DataImage.Reticle;

		map = PANOLENS.Utils.TextureLoader.load( url );
		material = new THREE.SpriteMaterial( { map: map, color: color, depthTest: false } );

		THREE.Sprite.call( this, material );

		this.visible = false;
		this.renderOrder = 10;

	}

	PANOLENS.Reticle.prototype = Object.create( THREE.Sprite.prototype );

	PANOLENS.Reticle.prototype.constructor = PANOLENS.Reticle;

	PANOLENS.Reticle.prototype.show = function () {

		this.visible = true;

	};

	PANOLENS.Reticle.prototype.hide = function () {

		this.visible = false;

	};

})();

Fix reticle render order and depthTest


'use strict';
import VectorLayer from 'ol/layer/Vector';
import { Vector as VectorSource } from 'ol/source';

describe('layermanager', function () {
    var scope;
    var $componentController, scope;

    var layerForCluster = new VectorLayer({
        title: 'Bookmarks',
        source: new VectorSource({})
    })

    beforeEach(function () {
        angular.mock.module(function ($provide) {
            $provide.value('config', {
                default_layers: [layerForCluster]
            });
        });

        angular.mock.module('hs.layermanager')
    }); //<--- Hook module

    beforeEach(inject(function (_$componentController_, $rootScope) {
        scope = $rootScope.$new();
        $componentController = _$componentController_;
    }));

    it('Clusterization', function () {
        var ctrl = $componentController('hs.layerEditor', { $scope: scope }, { currentLayer: { layer: layerForCluster } });
        scope.cluster(true);

        expect(layerForCluster.get('cluster')).toBe(true);
        expect(layerForCluster.getSource().getSource).toBeDefined();

        scope.changeDistance($scope.distance)
    });
});

'use strict';
import VectorLayer from 'ol/layer/Vector';
import { Vector as VectorSource } from 'ol/source';

describe('layermanager', function () {
    var scope;
    var $componentController, scope;

    var layerForCluster = new VectorLayer({
        title: 'Bookmarks',
        source: new VectorSource({})
    })

    beforeEach(function () {
        angular.mock.module(function ($provide) {
            $provide.value('config', {
                default_layers: [layerForCluster]
            });
        });

        angular.mock.module('hs.layermanager')
    }); //<--- Hook module

    beforeEach(inject(function (_$componentController_, $rootScope) {
        scope = $rootScope.$new();
        $componentController = _$componentController_;
    }));

    it('clusterization', function () {
        var ctrl = $componentController('hs.layerEditor', { $scope: scope }, { currentLayer: { layer: layerForCluster } });
        scope.cluster(true);

        expect(layerForCluster.get('cluster')).toBe(true);
        expect(layerForCluster.getSource().getSource).toBeDefined();

        scope.distance.value = 15;
        scope.changeDistance(scope.distance.value);
        expect(layerForCluster.getSource().getDistance()).toBe(15);

        //Turn clusterization off
        scope.cluster(false);
        expect(layerForCluster.getSource().getSource).toBeUndefined();

    });
});

Test for clusterization distance and turning off


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

import DayPickerInput from 'react-day-picker/DayPickerInput';
import 'react-day-picker/lib/style.css';

function CustomOverlay({ classNames, selectedDay, children }) {
  return (

Hello day picker!

          {selectedDay
            ? `You picked: ${selectedDay.toLocaleDateString()}`
            : 'Please pick a day'}

        {children}

  );
}

CustomOverlay.propTypes = {
  classNames: PropTypes.object.isRequired,
  selectedDay: PropTypes.oneOfType([Date]),
  children: PropTypes.number.isRequired,
};

export default function Example() {
  return (
    <DayPickerInput
      overlayComponent={CustomOverlay}
      dayPickerProps={{
        todayButton: 'Today',
      }}
    />
  );
}

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

import DayPickerInput from 'react-day-picker/DayPickerInput';
import 'react-day-picker/lib/style.css';

function CustomOverlay({ classNames, selectedDay, children, ...props }) {
  return (

Hello day picker!

        <button onClick={() => console.log('clicked!')}>button</button>

          {selectedDay
            ? `You picked: ${selectedDay.toLocaleDateString()}`
            : 'Please pick a day'}

        {children}

  );
}

CustomOverlay.propTypes = {
  classNames: PropTypes.object.isRequired,
  selectedDay: PropTypes.instanceOf(Date),
  children: PropTypes.node.isRequired,
};

export default function Example() {
  return (
    <DayPickerInput
      overlayComponent={CustomOverlay}
      dayPickerProps={{
        todayButton: 'Today',
      }}
    />
  );
}

Make sure we pass the correct props to the overlay


require(["gitbook"], function(gitbook) {

});

require(["gitbook", "core/navigation"], function(gitbook, navigation) {
    gitbook.events.bind("page.change", function() {
        var prev = 0;

        $(".book-body .body-inner").scroll(function(e) {
            var y = $(e.target).scrollTop(); // offset of scroll
            var vH = $(e.target).height(); // size visible
            var h = $(e.target)[0].scrollHeight; // size of all content

            if ((y + vH) >= h) {
                navigation.goNext();
            } else if (y <= 0 && prev > 0) {
                navigation.goPrev();
            }

            prev = y;
        });
    });
});

Add base for infinite scrolling


/**
 * Copyright 2017 CA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* @flow */
import examples from './examples';

const doc = require('!!react-docgen-loader!../Archetype.js');

export default {
  behavior: 'behavior dummy text for the archetype component',
  design: 'design theory about the archetype component',
  doc,
  examples,
  title: 'Archetype'
};

/**
 * Copyright 2017 CA
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* @flow */
import examples from './examples';

const doc = require('!!react-docgen-loader!../Archetype.js');

export default {
  behavior: 'behavior dummy text for the archetype component',
  design: 'design theory about the archetype component',
  doc,
  examples,
  slug: 'archetype',
  title: 'Archetype'
};

Add 'slug' property to demo object


/*eslint-disable */

//script from:
//https://analytics.google.com/analytics/web/#management/Settings/a67365892w117922625p123341464/%3Fm.page%3DTrackingCode/

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-67365892-6', 'auto');
ga('send', 'pageview');
i/*eslint-enable */

/*eslint-disable */

//script from:
//https://analytics.google.com/analytics/web/#management/Settings/a67365892w117922625p123341464/%3Fm.page%3DTrackingCode/

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-67365892-5', 'auto');
ga('send', 'pageview');
/*eslint-enable */

Switch to NHS Beta GA tracking id


import Promise from 'bluebird'
import {Cycle, Phase, Project} from 'src/server/services/dataService'

export default async function sendCycleLaunchAnnouncements(cycleId) {
  const [cycle, phases] = await Promise.all([
    await Cycle.get(cycleId),
    await Phase.filter({hasVoting: true}),
  ])
  await Promise.each(phases, phase => _sendAnnouncementToPhase(cycle, phase))
}

async function _sendAnnouncementToPhase(cycle, phase) {
  const chatService = require('src/server/services/chatService')

  const projects = await Project.filter({cycleId: cycle.id, phaseId: phase.id}).pluck('name', 'goal')
  try {
    await chatService.sendChannelMessage(phase.channelName, _buildAnnouncement(cycle, projects))
  } catch (err) {
    console.warn(`Failed to send cycle launch announcement to Phase ${phase.number} for cycle ${cycle.cycleNumber}: ${err}`)
  }
}

function _buildAnnouncement(cycle, projects) {
  let announcement = `🚀  *Cycle ${cycle.cycleNumber} has been launched!*\n`
  if (projects.length > 0) {
    const projectListString = projects.map(p => `  • #${p.name} - _${p.goal.title}_`).join('\n')
    announcement += `>The following projects have been created:\n${projectListString}`
  } else {
    announcement += '>No projects created'
  }
  return announcement
}

import Promise from 'bluebird'
import {Cycle, Phase, Project} from 'src/server/services/dataService'

export default async function sendCycleLaunchAnnouncements(cycleId) {
  const [cycle, phases] = await Promise.all([
    await Cycle.get(cycleId),
    await Phase.filter({hasVoting: true}),
  ])
  await Promise.each(phases, phase => _sendAnnouncementToPhase(cycle, phase))
}

async function _sendAnnouncementToPhase(cycle, phase) {
  const chatService = require('src/server/services/chatService')

  const numOfProjects = await Project.filter({cycleId: cycle.id, phaseId: phase.id}).count()
  try {
    await chatService.sendChannelMessage(phase.channelName, _buildAnnouncement(cycle, numOfProjects))
  } catch (err) {
    console.warn(`Failed to send cycle launch announcement to Phase ${phase.number} for cycle ${cycle.cycleNumber}: ${err}`)
  }
}

function _buildAnnouncement(cycle, numOfProjects) {
  let announcement = `🚀  *Cycle ${cycle.cycleNumber} has been launched!*\n`
  if (numOfProjects > 0) {
    announcement += `>${numOfProjects} projects were created.\n`
  } else {
    announcement += '>No projects created'
  }
  return announcement
}

Remove list of project names from slack announcement for cycle launch.


/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

/**
 * Tests don't have access to the requestionAnimationFrame API, so this function
 * provides a mock for it. It holds on to all queued calls, and the returned function
 * will flush and execute all of the calls in the order they were received.
 *
 * It uses jest.spyOn, which will automatically clear itself after the test is run.
 *
 * Usage:
 *
 *    const flushRafCalls = mockRaf();
 *    requestAnimationFrame(() => {
 *      // Do something
 *    });
 *    flushRafCalls();
 *
 */
export default function mockRaf() {
  const fns = [];
  jest.spyOn(window, 'requestAnimationFrame').mockImplementation(fn => {
    fns.push(fn);
  });

  return (timestamps: ?(number[])) => {
    while (fns.length > 0) {
      if (!timestamps) {
        const fn = fns.shift();
        fn();
      } else {
        const timestamp = timestamps.shift();
        if (timestamp === undefined) {
          return;
        }
        const fn = fns.shift();
        fn(timestamp);
      }
    }
  };
}

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// @flow

/**
 * Tests don't have access to the requestionAnimationFrame API, so this function
 * provides a mock for it. It holds on to all queued calls, and the returned function
 * will flush and execute all of the calls in the order they were received.
 *
 * It uses jest.spyOn, which will automatically clear itself after the test is run.
 *
 * Usage:
 *
 *    const flushRafCalls = mockRaf();
 *    requestAnimationFrame(() => {
 *      // Do something
 *    });
 *    flushRafCalls();
 *
 */
export default function mockRaf() {
  const fns = [];
  jest.spyOn(window, 'requestAnimationFrame').mockImplementation(fn => {
    fns.push(fn);
  });

  /**
   * Execute the queued functions, one at a time.
   *
   * If no argument is passed, flush and execute all functions in the
   * queue.
   *
   * If an array of timestamps is passed, those timestamps will be
   * passed in sequence to each queued function. When the array runs
   * out, the execution loop will stop, even if there are remaining
   * functions to be called.
   */
  return (timestamps: ?(number[])) => {
    while (fns.length > 0) {
      let arg = undefined;
      if (timestamps) {
        arg = timestamps.shift();
        if (arg === undefined) {
          // We've run into the end of the passed array of
          // timestamps. End the loop.
          return;
        }
      }
      const fn = fns.shift();
      fn(arg);
    }
  };
}

Clean up and document the return value of mockRaf


angular.module('app', []).controller('AppCtrl', function ($scope, $http) {
	$scope.results = [];

	$scope.loadUsers = function() {
		$http.get('/elements')
			.success(function(data) {
				$scope.results = data;
			})
			.error(function(err) {
				$scope.results = err;
			});
	}

	$scope.clickElement = function (element) {
		element.count += 1;
		var promiseElement = $http.put('/elements/' + element.id, element)
		promiseElement.then(function(elem) {
			$scope.results[element.id] = elem;
		})
	};
});

angular.module('app', []).controller('AppCtrl', function ($scope, $http) {
	$scope.results = [];

	$scope.loadUsers = function() {
		$http.get('/elements')
			.success(function(data) {
				$scope.results = data;
			})
			.error(function(err) {
				$scope.results = err;
			});
	}

	$scope.clickElement = function (element) {
		var promiseElement = $http.put('/elements/' + element.id, {count: element.count + 1})
		promiseElement.then(function(elem) {
			element.count = elem.data.count;
		})
	};
});

Correct put method to work correctly


const express = require('express');
const router = express.Router();
const cms = require('../cms.js');
const mongoose = require('mongoose');
const Shuttle = require("../schema/shuttle.js");
const helperLib = require("../helper.js").helpers;
const helper = new helperLib();
module.exports = router;
router.get('/', function(req, res) {
	if (!req.session || !req.session.cas_user) {
		res.redirect("/login");
		return;
	}
	var rcs_id = req.session.cas_user.toLowerCase();
	if (helper.isAdmin(rcs_id)) {
		var query = Shuttle.find({}).lean();
		query.exec(function(err, docs) {
			res.send(docs);
		});
	} else {
		var query = Shuttle.find({}).lean();
		// Ensure non-admin users cannot see other riders, nor the waitlist for a shuttle.
		query.select('-riders');
		query.select('-waitlist');
		query.exec(function(err, docs) {
			res.send(docs);
		});
	}
});

const express = require('express');
const router = express.Router();
const cms = require('../cms.js');
const mongoose = require('mongoose');
const Shuttle = require("../schema/shuttle.js");
const helperLib = require("../helper.js").helpers;
const helper = new helperLib();
module.exports = router;
router.get('/', function(req, res) {
	if (!req.session || !req.session.cas_user) {
		res.redirect("/login");
		return;
	}
	var rcs_id = req.session.cas_user.toLowerCase();
	if (helper.isAdmin(rcs_id)) {
		var query = Shuttle.find({}).lean();
		query.exec(function(err, docs) {

			res.send({"data":docs});
		});
	} else {
		var query = Shuttle.find({}).lean();
		// Ensure non-admin users cannot see other riders, nor the waitlist for a shuttle.
		query.select('-riders');
		query.select('-waitlist');
		query.exec(function(err, docs) {
			res.send(docs);
		});
	}
});

Make get shuttles api route more secure by encapsulating array in data key


require('dashboard/core');
require('dashboard/model');

Dashboard.GitHubAdpater = DS.Adapter.extend({
  PREFIX: 'https://api.github.com',

  ajax: function(url, target, callback) {
    Ember.$.ajax({
      url: this.PREFIX + url,
      dataType: 'jsonp',
      context: this,
      success: function(data) {
        this._ajaxSuccess(data, target, callback);
      }
    });
  },

  _ajaxSuccess: function(response, target, callback) {
    this._updateLimits(response);
    if (Ember.typeOf(target) === 'function') {
      target.apply(this, [response.data]);
    } else {
      Ember.tryInvoke(target, callback, [response.data]);
    }
  },

  _updateLimits: function(response) {
    if (response.meta) {
      this.set('remaining', response.meta['X-RateLimit-Remaining']);
      this.set('limit', response.meta['X-RateLimit-Limit']);
    }
  },

  findQuery: function(store, type, query, modelArray) {
    if (Dashboard.Repository.detect(type) && 'watched' === query.type) {
      this.watchedRepositories(query.username, modelArray, 'load');
    }
  },

  watchedRepositories: function(username, target, callback) {
    this.ajax('/users/%@/watched'.fmt(username), target, callback);
  }
});

require('dashboard/core');
require('dashboard/model');

Dashboard.GitHubAdpater = DS.Adapter.extend({
  PREFIX: 'https://api.github.com',

  ajax: function(url, target, callback) {
    Ember.$.ajax({
      url: this.PREFIX + url,
      dataType: 'jsonp',
      context: this,
      success: function(data) {
        this._ajaxSuccess(data, target, callback);
      }
    });
  },

  _ajaxSuccess: function(response, target, callback) {
    this._updateLimits(response);
    if (Ember.typeOf(target) === 'function') {
      target.apply(this, [response.data]);
    } else {
      Ember.tryInvoke(target, callback, [response.data]);
    }
  },

  _updateLimits: function(response) {
    if (response.meta) {
      this.set('remaining', response.meta['X-RateLimit-Remaining']);
      this.set('limit', response.meta['X-RateLimit-Limit']);
    }
  },

  find: function(store, type, id) {
    if (Dashboard.Repository.detect(type)) {
      this.ajax('/repos/%@'.fmt(id), function(data) {
        store.load(type, id, data);
      });
    }
  },

  findQuery: function(store, type, query, modelArray) {
    if (Dashboard.Repository.detect(type) && 'watched' === query.type) {
      this.watchedRepositories(query.username, modelArray, 'load');
    }
  },

  watchedRepositories: function(username, target, callback) {
    this.ajax('/users/%@/watched'.fmt(username), target, callback);
  }
});

Implement find for Repository on GitHubAdpater


import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    submit: function () {
      var
        self = this,
        content = this.controller.get('firstSnippet'),
        snippet = this.store.createRecord('snippet', {
          content: content,
      });

      snippet.save().then(function () {
        var draft = self.store.createRecord('draft', {
          firstLine: content.slice(0, 30),
          contributionStatus: 'cooldown',
          canAdmin: true,
          snippetCount: 1,
          lastSnippet: snippet,
        });

        return draft.save();
      }).then(function () {
        return self.transitionTo('index');
      });
    }
  }
});

import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    submit: function () {
      var
        self = this,
        content = this.controller.get('firstSnippet'),
        snippet = this.store.createRecord('snippet', {
          content: content,
      });

      snippet.save().then(function () {
        return self.transitionTo('index');
      });
    }
  }
});

Create the Draft server-side instead.


"use strict";
var screenshot = require('../../lib/pipes/screenshot.js');
var testcases = require('../files/hash.json');
var restbase = require('../../lib/pipes/restbase');
var pipe = require('../..');

describe('screenshot', function () {
    testcases.forEach(function (tc) {
        it('should take screenshot of svg from ' + JSON.stringify(tc.input), function () {
            var folder = pipe.getFolder(tc.input, pipe.config.conf.out_dir);
            var getCheck = restbase.check(tc.input, pipe.config.conf.restbase_url);
            var getFormats = restbase.getOutputs(folder, getCheck);
            return getFormats
                .then(function (res) {
                    return res.get('svg')
                        .then(function (svg) {
                            return screenshot.snapshot(svg);
                        });
                });
        });
    });
});

"use strict";
var screenshot = require('../../lib/pipes/screenshot.js');
var testcases = require('../files/hash.json');
var restbase = require('../../lib/pipes/restbase');
var pipe = require('../..');

describe('screenshot', function () {
    testcases.forEach(function (tc) {
        it('should take screenshot of svg from ' + JSON.stringify(tc.input), function () {
            this.timeout(50000);
            var folder = pipe.getFolder(tc.input, pipe.config.conf.out_dir);
            var getCheck = restbase.check(tc.input, pipe.config.conf.restbase_url);
            var getFormats = restbase.getOutputs(folder, getCheck);
            return getFormats
                .then(function (res) {
                    return res.get('svg')
                        .then(function (svg) {
                            return screenshot.snapshot(svg);
                        });
                });
        });
    });
});

Increase timeout to allow travis tests to pass


const { configureStore } = require('../store');
const readline = require('readline');
const draw = require('./draw');
const { keys } = require('./input');
const actions = require('../actions');

const resize = (proc, store) => {
    const action = actions.resize({
        rows: proc.stdout.rows,
        columns: proc.stdout.columns
    });
    store.dispatch(action);
};

module.exports = (initialState, proc = process) => {
    const store = configureStore(proc, initialState);
    const onStateChange = draw(process, store);
    store.subscribe(onStateChange);
    onStateChange();
    proc.stdin.addListener('keypress', keys(store));
    proc.stdout.addListener('resize', () => resize(proc, store));
    resize(proc, store);
    readline.emitKeypressEvents(proc.stdin);
    proc.stdin.setRawMode(true);
};

const { configureStore } = require('../store');
const readline = require('readline');
const draw = require('./draw');
const { keys } = require('./input');
const actions = require('../actions');

const resize = (proc, store) => {
    const action = actions.resize({
        rows: proc.stdout.rows,
        columns: proc.stdout.columns
    });
    store.dispatch(action);
};

module.exports = (initialState, proc = process) => {
    const store = configureStore(proc, initialState);
    const onStateChange = draw(proc, store);
    store.subscribe(onStateChange);
    onStateChange();
    proc.stdin.addListener('keypress', keys(store));
    proc.stdout.addListener('resize', () => resize(proc, store));
    resize(proc, store);
    readline.emitKeypressEvents(proc.stdin);
    proc.stdin.setRawMode(true);
};

Remove use of process from global


var gulp        = require('gulp'),
    browserSync = require('browser-sync'),
    sass        = require('gulp-sass'),
    bower       = require('gulp-bower'),
    notify      = require('gulp-notify'),
    reload      = browserSync.reload,
    bs          = require("browser-sync").create(),
    Hexo = require('hexo'),
    hexo = new Hexo(process.cwd(), {});

var src = {
    scss: 'scss',
    css:  'source/css',
    ejs: 'layout'
};

// Static Server + watching scss/html files
gulp.task('serve', ['sass'], function() {

    // init starts the server
    bs.init({
        baseDir: "../../public"
    });

    // hexo.call('generate', {}).then(function(){
    //   console.log('Generating Files');
    // });

    // Now call methods on bs instead of the
    // main browserSync module export
    bs.reload("*.html");
    bs.reload("*.css");
});

// Compile sass into CSS
gulp.task('sass', function() {
    gulp.src(src.scss)
        .pipe(sass().on('error', sass.logError))
        .pipe(gulp.dest(src.css))
        .pipe(reload({stream: true}));
});

gulp.task('sass:watch', function () {
  gulp.watch('./scss/**/*.scss', ['sass']);
});

gulp.task('bower', function() {
  return bower()
    .pipe(gulp.dest('source/lib'))
});

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

var gulp        = require('gulp'),
    browserSync = require('browser-sync'),
    sass        = require('gulp-sass'),
    bower       = require('gulp-bower'),
    notify      = require('gulp-notify'),
    reload      = browserSync.reload,
    bs          = require("browser-sync").create(),
    Hexo = require('hexo'),
    hexo = new Hexo(process.cwd(), {});

var src = {
    scss: './scss/',
    css:  './source/css',
    ejs: 'layout'
};

// Static Server + watching scss/html files
gulp.task('serve', ['sass'], function() {

    // init starts the server
    bs.init({
        baseDir: "../../public"
    });

    // hexo.call('generate', {}).then(function(){
    //   console.log('Generating Files');
    // });

    // Now call methods on bs instead of the
    // main browserSync module export
    bs.reload("*.html");
    bs.reload("*.css");
});

// Compile sass into CSS
gulp.task('sass', function() {
    // gulp.src(src.scss + "/*/*.scss")
    gulp.src(src.scss + "{,*}/*.scss")
        .pipe(sass({}))
        // .pipe(gulp.dest(src.css))
        .pipe(gulp.dest('./css/'))
        .pipe(reload({stream: true}));
});

gulp.task('sass:watch', function () {
  gulp.watch('./scss/**/*.scss', ['sass']);
});

gulp.task('bower', function() {
  return bower()
    .pipe(gulp.dest('source/lib'))
});

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

Update and fix sass gulp path


    //Gulp and plugins
var gulp        = require('gulp'),
    mocha       = require('gulp-mocha'),
    plumber     = require('gulp-plumber'),
    watch       = require('gulp-watch');

gulp.task('exercises:language:runner', function() {
  gulp.src('exercises/language/*.js', {read: false})
    .pipe(plumber())
    .pipe(mocha({reporter: 'spec', bail: true}));
});

gulp.task('exercises:language:watcher', function() {
  gulp.watch('exercises/language/*.js', ['exercises:language:runner']);
});

gulp.task('exercises:language', ['exercises:language:watcher']);

    //Gulp and plugins
var gulp        = require('gulp'),
    concat      = require('gulp-concat'),
    plumber     = require('gulp-plumber'),
    watch       = require('gulp-watch'),
    runner      = require('gulp-mocha-phantomjs');

gulp.task('exercises:language:watcher', function() {
  gulp.watch('exercises/language/*_spec.js', ['exercises:language:builder', 'exercises:language:runner']);
});

gulp.task('exercises:language:builder', function() {
  gulp.src(['exercises/language/*.js'])
    .pipe(plumber())
    .pipe(concat('tests.js'))
    .pipe(gulp.dest('exercises/test_runner'))
});

gulp.task('exercises:language:runner', function () {
  gulp.src('exercises/test_runner/index.html')
    .pipe(plumber())
    .pipe(runner({mocha:{bail:true}}));
});

gulp.task('exercises:language', ['exercises:language:watcher']);

Update gulp tasks to use mocha-phantom


var gulp = require('gulp');
var sass = require('gulp-sass');
var bower = require('gulp-bower');
var minifyCSS = require('gulp-minify-css');

var paths = {
  css: 'src/styles/**/*.scss',
  fonts: 'bower_components/font-awesome/fonts/**/*'
};

gulp.task('bower', function() {
  return bower();
});

gulp.task('css', ['bower'], function() {
  return gulp.src(paths.css)
    .pipe(sass())
    .pipe(minifyCSS())
    .pipe(gulp.dest('public/css'));
});

gulp.task('fonts', ['bower'], function() {
  return gulp.src(paths.fonts)
    .pipe(gulp.dest('public/fonts'));
});

gulp.task('watch', function() {
  gulp.watch(paths.css, ['css']);
});

gulp.task('default', ['css', 'fonts']);

var gulp = require('gulp');
var sass = require('gulp-sass');
var bower = require('gulp-bower');
var minifyCSS = require('gulp-minify-css');

var paths = {
  css: 'src/styles/**/*.scss',
  fonts: 'bower_components/font-awesome/fonts/**/*'
};

gulp.task('bower', function() {
  return bower();
});

gulp.task('css', ['bower'], function() {
  return gulp.src(paths.css)
    .pipe(sass())
    .pipe(minifyCSS())
    .pipe(gulp.dest('public/css'));
});

gulp.task('fonts', ['bower'], function() {
  return gulp.src(paths.fonts)
    .pipe(gulp.dest('public/fonts'));
});

gulp.task('watch', ['default'], function() {
  gulp.watch(paths.css, ['css']);
});

gulp.task('default', ['css', 'fonts']);

Build the full project before gulp watch.


'use strict';

describe('my angular musicbrainz app', function () {

    beforeEach(function () {
        browser().navigateTo('app/index.html');
    });

    it('should automatically redirect to /search when location hash/fragment is empty', function () {
        expect(browser().location().url()).toBe('/search');
    });

    describe('search', function () {

        beforeEach(function () {
            browser().navigateTo('#/search');
        });

        it('should render search when user navigates to /search', function () {
            expect(element('#search-input-label').text()).
                toContain('music');
        });

        it('U2 album search', function () {
            input('searchText').enter('U2');
            element(':button').click();
            expect(element('#result-number').text()).
                toContain('22');

        });

    });

    describe('info', function () {

        beforeEach(function () {
            browser().navigateTo('#/info');
        });

        it('should render info when user navigates to /info', function () {
            expect(element('[ng-view] p:first').text()).
                toMatch(/Information/);
        });

    });
});

'use strict';

describe('my angular musicbrainz app', function () {

    beforeEach(function () {
        browser().navigateTo('app/index.html');
    });

    describe('search', function () {

        beforeEach(function () {
            browser().navigateTo('#/search');
        });

        it('should render search when user navigates to /search', function () {
            expect(element('#search-input-label').text()).
                toContain('music');
        });

        it('U2 album search', function () {
            input('searchText').enter('U2');
            element(':button').click();
            expect(element('#result-number').text()).
                toContain('22');

        });

    });

    describe('info', function () {

        beforeEach(function () {
            browser().navigateTo('#/info');
        });

        it('should render info when user navigates to /info', function () {
            expect(element('[ng-view] li:first').text()).
                toMatch(/Application version/);
        });

    });

    it('should automatically redirect to /search when location hash/fragment is empty', function () {
        expect(browser().location().url()).toBe('/search');
    });

});

Fix assertion into info e2e-test


'use strict';

var fs      = require('fs');
var hljs    = require('../../build');
var jsdom   = require('jsdom').jsdom;
var utility = require('../utility');

var filename = utility.buildPath('index.html'),
    page     = fs.readFileSync(filename, 'utf-8');

// Allows hljs to use document
global.document = jsdom(page);

// Setup hljs environment
hljs.configure({ tabReplace: '    ' });
hljs.initHighlighting();

describe('special cases test', function() {
  require('./explicitLanguage');
  require('./customMarkup');
  require('./languageAlias');
  require('./noHighlight');
  require('./subLanguages');
  require('./buildClassName');
});

'use strict';

var _       = require('lodash');
var fs      = require('fs');
var hljs    = require('../../build');
var jsdom   = require('jsdom').jsdom;
var utility = require('../utility');

var blocks,
    filename = utility.buildPath('index.html'),
    page     = fs.readFileSync(filename, 'utf-8');

// Allows hljs to use document
global.document = jsdom(page);

// Setup hljs environment
hljs.configure({ tabReplace: '    ' });
hljs.initHighlighting();

// Setup hljs for non-`<pre><code>` tests
hljs.configure({ useBR: true });

blocks = document.querySelectorAll('.code');
_.each(blocks, hljs.highlightBlock);

describe('special cases test', function() {
  require('./explicitLanguage');
  require('./customMarkup');
  require('./languageAlias');
  require('./noHighlight');
  require('./subLanguages');
  require('./buildClassName');
  require('./useBr');
});

Add br tests to special test group


module.exports = {
  htmlLang: '{{htmlLang}}',
  assetPath: '{{govukAssetPath}}',
  afterHeader: '{{$afterHeader}}{{/afterHeader}}',
  bodyClasses: '{{$bodyClasses}}{{/bodyClasses}}',
  bodyEnd: '{{$bodyEnd}}{{/bodyEnd}}',
  content: '{{$main}}{{/main}}',
  cookieMessage: '{{$cookieMessage}}{{/cookieMessage}}',
  footerSupportLinks: '{{$footerSupportLinks}}{{/footerSupportLinks}}',
  footerTop: '{{$footerTop}}{{/footerTop}}',
  head: '{{$head}}{{/head}}',
  headerClass: '{{$headerClass}}{{/headerClass}}',
  insideHeader: '{{$insideHeader}}{{/insideHeader}}',
  pageTitle: '{{$pageTitle}}{{/pageTitle}}',
  propositionHeader: '{{$propositionHeader}}{{/propositionHeader}}',
  skipLinkMessage: '{{$skipLinkMessage}}Skip to main content{{/skipLinkMessage}}',
  globalHeaderText: '{{$globalHeaderText}}GOV.UK{{/globalHeaderText}}',
  licenceMessage: '{{$licenceMessage}}
All content is available under the Open Government Licence v3.0, except where otherwise stated
{{/licenceMessage}}',
  crownCopyrightMessage: '{{$crownCopyrightMessage}}© Crown copyright{{/crownCopyrightMessage}}'
};

module.exports = {
  htmlLang: '{{htmlLang}}',
  assetPath: '{{govukAssetPath}}',
  afterHeader: '{{$afterHeader}}{{/afterHeader}}',
  bodyClasses: '{{$bodyClasses}}{{/bodyClasses}}',
  bodyEnd: '{{$bodyEnd}}{{/bodyEnd}}',
  content: '{{$main}}{{/main}}',
  cookieMessage: '{{$cookieMessage}}{{/cookieMessage}}',
  footerSupportLinks: '{{$footerSupportLinks}}{{/footerSupportLinks}}',
  footerTop: '{{$footerTop}}{{/footerTop}}',
  head: '{{$head}}{{/head}}',
  headerClass: '{{$headerClass}}{{/headerClass}}',
  homepageUrl: '{{$homepageUrl}}https://www.gov.uk{{/homepageUrl}}',
  logoLinkTitle: '{{$logoLinkTitle}}Go to the GOV.UK homepage{{/logoLinkTitle}}',
  insideHeader: '{{$insideHeader}}{{/insideHeader}}',
  pageTitle: '{{$pageTitle}}{{/pageTitle}}',
  propositionHeader: '{{$propositionHeader}}{{/propositionHeader}}',
  skipLinkMessage: '{{$skipLinkMessage}}Skip to main content{{/skipLinkMessage}}',
  globalHeaderText: '{{$globalHeaderText}}GOV.UK{{/globalHeaderText}}',
  licenceMessage: '{{$licenceMessage}}
All content is available under the Open Government Licence v3.0, except where otherwise stated
{{/licenceMessage}}',
  crownCopyrightMessage: '{{$crownCopyrightMessage}}© Crown copyright{{/crownCopyrightMessage}}'
};

Add default govuk link and logo title


// ---------------------------------------
// Test Environment Setup
// ---------------------------------------
import sinon from 'sinon'
import chai from 'chai'
import sinonChai from 'sinon-chai'
import chaiAsPromised from 'chai-as-promised'
import chaiEnzyme from 'chai-enzyme'

chai.use(sinonChai)
chai.use(chaiAsPromised)
chai.use(chaiEnzyme())

global.chai = chai
global.sinon = sinon
global.expect = chai.expect
global.should = chai.should()

// ---------------------------------------
// Require Tests
// ---------------------------------------
// for use with karma-webpack-with-fast-source-maps
const __karmaWebpackManifest__ = []; // eslint-disable-line
const inManifest = (path) => ~__karmaWebpackManifest__.indexOf(path)

// require all `tests/**/*.spec.js`
const testsContext = require.context('./', true, /\.spec\.js$/)

// only run tests that have changed after the first pass.
const testsToRun = testsContext.keys().filter(inManifest)
;(testsToRun.length ? testsToRun : testsContext.keys()).forEach(testsContext)

// require all `src/**/*.js` except for `main.js` (for isparta coverage reporting)
if (__COVERAGE__) {
  const componentsContext = require.context('../src/', true, /^((?!main|reducers).)*\.js$/)
  componentsContext.keys().forEach(componentsContext)
}

Remove unneeded coverage lines from tests bundler


var _plan={
    title:"simple plan",
    template_engine:"go",
    dependency:[
        "markdown",
        "yaml_front_matter",
    ],
    strategies:[
        {
            title:"markdown",
            patterns:["*md"],
            exec:["markdown"],
        },
    ]
};

Wu.setCustomPlan(_plan);

var _plan={
    title:"simple plan",
    template_engine:"go",
    dependencies:[
        "markdown",
    ],
    strategies:[
        {
            title:"markdown",
            patterns:["*md"],
            exec:["markdown"],
        },
    ]
};

Wu.setCustomPlan(_plan);

Fix typo on object field


import moment from 'moment'
import chalk from 'chalk'
import format from '../time'
import pad from 'pad'
import { hashPattern } from '../entry'

export {write as write}
export {getOutputs as getOutputs}

function write(entry) {
  const {detailed} = getOutputs(entry)

  console.log(detailed)
}

function getOutputs(entry) {
  const timePattern = new RegExp(/\s*/.source + entry.time + /\s*/.source, 'g')
  const id = `${chalk.gray(pad(entry._id, 10))}`
  const date = `${chalk.yellow(pad(moment(entry.from).format('ddd MMM DD'),9))}`
  const timeFrom = moment(entry.from)
  const timeTo = moment(entry.to)
  const time = `${timeFrom.format('hh:mma')}-${timeTo.format('hh:mma')}`
  const duration = chalk.green(format(entry.duration.minutes))
  const msg = entry.message
    .replace(hashPattern, chalk.cyan('$1'))
    .replace(timePattern, '')
  const tags = chalk.cyan([...entry.tags].join(' '))

  const detailed = `${id} ${date} ${time} ${duration} ${msg}`
  const simple = `${id} ${time} ${duration} ${msg}`

  return {id, date, duration, msg, tags, detailed, simple}
}

import moment from 'moment'
import chalk from 'chalk'
import format from '../time'
import pad from 'pad'
import { hashPattern } from '../entry'

export {write as write}
export {getOutputs as getOutputs}

function write(entry) {
  const {detailed} = getOutputs(entry)

  console.log(detailed)
}

function getOutputs(entry) {
  const timePattern = new RegExp(/\s*/.source + entry.time + /\s*/.source, 'g')
  const id = `${chalk.gray(pad(entry._id, 10))}`
  const date = `${chalk.yellow(pad(moment(entry.from).format('ddd MMM DD'),9))}`
  const timeFrom = moment(entry.from)
  const timeTo = moment(entry.to)
  const time = `${timeFrom.format('hh:mma')}-${timeTo.format('hh:mma')}`
  const duration = chalk.green(format(entry.duration.minutes))
  const msg = entry.message
    .replace(hashPattern, chalk.cyan('$1'))
    .replace(timePattern, ' ')
    .trim()
  const tags = chalk.cyan([...entry.tags].join(' '))

  const detailed = `${id} ${date} ${time} ${duration} ${msg}`
  const simple = `${id} ${time} ${duration} ${msg}`

  return {id, date, duration, msg, tags, detailed, simple}
}

Fix time extraction taking away needed spaces


// @flow

import { red } from 'chalk';
import R from 'ramda';

type Clog = typeof console.log;
type GraphQLError = { message: string };

export function exitNoConfig(clog: Clog): number {
  clog('Could not find .amazeeio.yml config file');
  return 1;
}

export function exitError(clog: Clog, ...errors: Array<string>): number {
  R.compose(
    R.apply(clog),
    R.tail,
    R.flatten,
    R.map(err => ['\n', err]),
    R.map(err => (err.stack ? red(err.stack) : red(err))),
  )(errors);
  return 1;
}

export function exitGraphQLError(
  clog: Clog,
  errors: Array<GraphQLError>,
  code?: number = 1,
): number {
  clog(red('Oops! The server returned errors:'));
  R.forEach(err => clog('\n', err), errors);
  return code;
}

// @flow

import { red } from 'chalk';
import R from 'ramda';

type Clog = typeof console.log;
type GraphQLError = { message: string };

// FIXME: Improve naming
export function exitError(clog: Clog, ...errors: Array<string>): number {
  R.compose(
    R.apply(clog),
    R.tail,
    R.chain(err => ['\n', err]),
    R.map(err => (err.stack ? red(err.stack) : red(err))),
  )(errors);
  return 1;
}

export function exitNoConfig(clog: Clog): number {
  return exitError(clog, '.amazeeio.yml config file not found.');
}

export function exitGraphQLError(clog: Clog, errors: Array<GraphQLError>): number {
  R.compose(
    R.apply(clog),
    R.tail,
    R.chain(err => ['\n', red(err)]),
    R.prepend(red('Oops! The server returned errors:')),
  )(errors);
  return 1;
}

Improve compose functions in error functions


//Function to create an DOM with the provided message string
//
×msgString

function notesCreateMsgBoxDom(msgString) {
	return "
×"+ msgString + "
";
}

$(function(){

	//Get elements from background script
	var notesMessageList = chrome.extension.getBackgroundPage().notesMessageListShare;
	//Add notes to the popup window
	for(var i =0; i < notesMessageList.length; i++) {
		//Add message to the notesMessage DOM div
		$("#notesMessages").append(notesCreateMsgBoxDom(notesMessageList[i]));
		//Add the position of message as data to the DOM element
		$("#notesMessages > .msgbox:last").data("notesListIndex",i.toString());
	}

    //Add click listeners for delete button
	$(".deletebtn").click(function() {
		console.log($(this).parent().data("notesListIndex"));
	});

	$("form").submit(function(){
		console.log("Form submitted");
		return false;
	});
});

//Function to create an DOM with the provided message string
//
×msgString

function notesCreateMsgBoxDom(msgString) {
	return "
×"+ msgString + "
";
}

$(function(){

	//Get elements from background script
	var notesMessageList = chrome.extension.getBackgroundPage().notesMessageListShare;
	//Add notes to the popup window
	for(var i =0; i < notesMessageList.length; i++) {
		//Add message to the notesMessage DOM div
		$("#notesMessages").append(notesCreateMsgBoxDom(notesMessageList[i]));
		//Add the position of message as data to the DOM element
		$("#notesMessages > .msgbox:last").data("notesListIndex",i.toString());
	}

    //Add click listeners for delete button
	$(".deletebtn").click(function() {
		console.log($(this).parent().data("notesListIndex"));
	});

	$("form").submit(function(){
		var notesUserMessage = $("input:first").val();
		if(notesUserMessage != "") {
			console.log(notesUserMessage);
		}
		return false;
	});
});

Use message is extracted from the input form


/**
 * Ripple Client Configuration
 *
 * Copy this file to config.js and edit to suit your preferences.
 */
var Options = {
  server: {
    trace :         true,
    trusted:        true,
    local_signing:  true,

    servers: [
      { host: 's_west.ripple.com', port: 443, secure: true },
      { host: 's_east.ripple.com', port: 443, secure: true }
    ],

    connection_offset: 1
  },

  blobvault : 'https://blobvault.payward.com',

  // If set, login will persist across sessions (page reload). This is mostly
  // intended for developers, be careful about using this in a real setting.
  persistent_auth : false,

  // Number of transactions each page has in balance tab notifications
  transactions_per_page: 50,

  // Configure bridges
  bridge: {
    out: {
//    'bitcoin': 'localhost:3000'
//    'bitcoin': 'https://www.bitstamp.net/ripple/bridge/out/bitcoin/'
    }
  }
};

// Load client-side overrides
if (store.enabled) {
  $.extend(true, Options, JSON.parse(store.get('ripple_settings') || '{}'));
}

/**
 * Ripple Client Configuration
 *
 * Copy this file to config.js and edit to suit your preferences.
 */
var Options = {
  server: {
    trace :         true,
    trusted:        true,
    local_signing:  true,

    servers: [
      { host: 's_west.ripple.com', port: 443, secure: true },
      { host: 's_east.ripple.com', port: 443, secure: true }
    ],

    connection_offset: 0
  },

  blobvault : 'https://blobvault.payward.com',

  // If set, login will persist across sessions (page reload). This is mostly
  // intended for developers, be careful about using this in a real setting.
  persistent_auth : false,

  // Number of transactions each page has in balance tab notifications
  transactions_per_page: 50,

  // Configure bridges
  bridge: {
    out: {
//    'bitcoin': 'localhost:3000'
//    'bitcoin': 'https://www.bitstamp.net/ripple/bridge/out/bitcoin/'
    }
  }
};

// Load client-side overrides
if (store.enabled) {
  $.extend(true, Options, JSON.parse(store.get('ripple_settings') || '{}'));
}

Set default connection_offset to 0 seconds


import { FooterController } from './FooterController';

export function FooterDirective(){
  return {
    restrict: 'E',
    controller: FooterController,
    controllerAs: 'footer',
    scope: true,
    bindToController: {
      paging: '=',
      onPage: '&'
    },
    template:
      `

{{footer.paging.count}} total

 1">

`,
    replace: true
  };
};

Divide count by page size to determine if we should show the pager footer.


window.GobiertoAdmin.GobiertoCommonCustomFieldRecordsProgressPluginController = (function() {

  function GobiertoCommonCustomFieldRecordsProgressPluginController() {}

  var grid;

  GobiertoCommonCustomFieldRecordsProgressPluginController.prototype.form = function(opts = {}) {
    _handlePluginData(opts.uid);
  };

  function _applyPluginStyles(element, plugin_name_hint) {
    element.wrap("

");
  }

  function _handlePluginData(uid) {
    let element = $(`[data-uid=${uid}]`)
    let id = element.attr('id')
    let data = JSON.parse($(`#${id}`).find("input[name$='[value]'").val())

    _applyPluginStyles(element, "progress")
    _insertProgressPlugin(id, data)
  }

  function _insertProgressPlugin(id, data) {
    let element = $(`#${id}`)
    let formatted_data = data
      ? data.toLocaleString(I18n.locale, { style: 'percent', maximumFractionDigits: 1 })
      : "-"

    element.append(formatted_data);
    // element.append($('<input>', { disabled: true, type: 'text', val: formatted_data }))
  }

  return GobiertoCommonCustomFieldRecordsProgressPluginController;
})();

window.GobiertoAdmin.gobierto_common_custom_field_records_progress_plugin_controller = new GobiertoAdmin.GobiertoCommonCustomFieldRecordsProgressPluginController;

window.GobiertoAdmin.GobiertoCommonCustomFieldRecordsProgressPluginController = (function() {

  function GobiertoCommonCustomFieldRecordsProgressPluginController() {}

  GobiertoCommonCustomFieldRecordsProgressPluginController.prototype.form = function(opts = {}) {
    _handlePluginData(opts.uid);
  };

  function _handlePluginData(uid) {
    let element = $(`[data-uid=${uid}]`)
    let id = element.attr('id')
    let data = JSON.parse($(`#${id}`).find("input[name$='[value]'").val())

    _insertProgressPlugin(id, data)
  }

  function _insertProgressPlugin(id, data) {
    let element = $(`#${id}`)
    element.remove();
    let progress_select = $("select[id$='_progress'")
    if(progress_select.length) {
      progress_select.replaceWith(
        $('<input type="text" disabled="disabled">').val(
          data.toLocaleString(I18n.locale, { style: 'percent', maximumFractionDigits: 1 })
        )
      );
    }
  }

  return GobiertoCommonCustomFieldRecordsProgressPluginController;
})();

window.GobiertoAdmin.gobierto_common_custom_field_records_progress_plugin_controller = new GobiertoAdmin.GobiertoCommonCustomFieldRecordsProgressPluginController;

Change progress plugin javascript to replace progress with custom field value


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

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

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

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

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

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

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

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

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

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

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

    ajaxSpy('get', records);

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

Rename a variable so it makes a bit more sense


if(!window.console) console = {log: function() {}};

$(function(){
    $('body').ajaxComplete(function(event, XmlHttpRequest, ajaxOptions){
        if (XmlHttpRequest.getResponseHeader('X-Django-Requires-Auth')) {
            var next = window.location.pathname + window.location.hash;
            window.location = XmlHttpRequest.getResponseHeader('X-Django-Login-Url') + '?next=' + next;
        }
    });
});

Handle login required headers on the client side.


var utils = require('../utils')

module.exports = function ($provide, traceBuffer) {
  return {
    instrumentAll: function (modules) {
      modules.forEach(function (name) {
        $provide.decorator(name, ['$delegate', '$injector', function ($delegate, $injector) {
          utils.instrumentObject($delegate, $injector, {
            type: 'angular.factory',
          prefix: 'app.factory.' + name
          })
          return $delegate
        }])
      })
    }
  }
}

var utils = require('../utils')

module.exports = function ($provide, traceBuffer) {
  return {
    instrumentAll: function (modules) {
      modules.forEach(function (name) {
        $provide.decorator(name, ['$delegate', '$injector', function ($delegate, $injector) {
          utils.instrumentObject($delegate, $injector, {
            type: 'app.angular.factory',
            prefix: name
          })
          return $delegate
        }])
      })
    }
  }
}

Fix wrong type and prefix for Angular Factory traces


define(function(require) {

    'use strict';

    var zrUtil = require('zrender/core/util');

    var echartsAPIList = [
        'getDom', 'getZr', 'getWidth', 'getHeight', 'dispatchAction', 'isDisposed',
        'on', 'off', 'getDataURL', 'getConnectedDataURL', 'getModel', 'getOption'
    ];

    function ExtensionAPI(chartInstance) {
        zrUtil.each(echartsAPIList, function (name) {
            this[name] = zrUtil.bind(chartInstance[name], chartInstance);
        }, this);

        // Namespace used for extensions, including builtin components
        this._namespaces = {
            // Default echarts namespace
            echarts: {}
        };

        this._defaultNS = 'echarts';
    }

    var extensionProto = ExtensionAPI.prototype;

    /**
     * Create a namespace for extension or component
     * @param {string} ns
     */
    extensionProto.createNamespace = function (ns) {
        this._namespaces[ns] = {};
    };

    /**
     * Set default namespace
     * @param {string} ns
     */
    extensionProto.useNamespace = function (ns) {
        this._defaultNS = ns;
    };

    /**
     * Get value from namespace
     * @param {string} key
     * @param {string} [ns] Use default namespace defined by useNamespace
     */
    extensionProto.get = function (key, ns) {
        ns = ns || this._defaultNS;
        return this._namespaces[ns] && this._namespaces[ns][key];
    };

    /**
     * Put value to namespace
     * @param {string} key
     * @param {*} val
     * @param {string} [ns] Use default namespace defined by useNamespace
     */
    extensionProto.put = function (key, val, ns) {
        ns = ns || this._defaultNS;
        if (this._namespaces[ns]) {
            this._namespaces[ns][key] = val;
        }
    };

    /**
     * Dispose namespace
     * @param {string} key
     */
    extensionProto.disposeNamespace = function (ns) {
        delete this._namespaces[ns];
    };

    return ExtensionAPI;
});

define(function(require) {

    'use strict';

    var zrUtil = require('zrender/core/util');

    var echartsAPIList = [
        'getDom', 'getZr', 'getWidth', 'getHeight', 'dispatchAction', 'isDisposed',
        'on', 'off', 'getDataURL', 'getConnectedDataURL', 'getModel', 'getOption'
    ];

    function ExtensionAPI(chartInstance) {
        zrUtil.each(echartsAPIList, function (name) {
            this[name] = zrUtil.bind(chartInstance[name], chartInstance);
        }, this);
    }

    return ExtensionAPI;
});

Remove namespace add in previous commit


// jscs:disable
/* globals define */
String.prototype.toSnakeCase = function() {
  return this.replace(/([A-Z])/g, function(string) {
    return '_' + string.toLowerCase();
  });
};

(function() {
  'use strict';
  var _elev = window._elev = {};

  function _setup(config) {
    if (!config.enabled) {
      return;
    }

    var i, e;
    i = document.createElement("script"), i.type = 'text/javascript';
    i.async = 1, i.src = "https://static.elev.io/js/v3.js", e =
      document.getElementsByTagName("script")[0], e.parentNode.insertBefore(i, e);

    if (!config.accountId) {
      throw new Error('ENV.elevio.accountId must be defined in config/environment.js');
    }

    // elevio uses snake case for all their keys.
    // All the config for this addon uses camelCase
    for (var key in config) {
      if (config.hasOwnProperty(key)) {
        _elev[key.toSnakeCase()] = config[key];
      }
    }
  }

  function generateModule(name, values) {
    define(name, [], function() {
      'use strict';

      Object.defineProperty(values, '__esModule', {
        value: true
      });

      return values;
    });
  }

  generateModule('elevio', {
    default: _elev,
    _setup: _setup
  });
})();

// jscs:disable
/* globals define */
String.prototype.toSnakeCase = function() {
  return this.replace(/([A-Z])/g, function(string) {
    return '_' + string.toLowerCase();
  });
};

(function() {
  'use strict';
  var _elev = window._elev = {};

  function _setup(config) {
    if (config.enabled === false) {
      return;
    }

    var i, e;
    i = document.createElement("script"), i.type = 'text/javascript';
    i.async = 1, i.src = "https://static.elev.io/js/v3.js", e =
      document.getElementsByTagName("script")[0], e.parentNode.insertBefore(i, e);

    if (!config.accountId) {
      throw new Error('ENV.elevio.accountId must be defined in config/environment.js');
    }

    // elevio uses snake case for all their keys.
    // All the config for this addon uses camelCase
    for (var key in config) {
      if (config.hasOwnProperty(key)) {
        _elev[key.toSnakeCase()] = config[key];
      }
    }
  }

  function generateModule(name, values) {
    define(name, [], function() {
      'use strict';

      Object.defineProperty(values, '__esModule', {
        value: true
      });

      return values;
    });
  }

  generateModule('elevio', {
    default: _elev,
    _setup: _setup
  });
})();

Fix enabled flag not working when the user doesnt explicity set enabled to true in config


'use strict';

const { Suite } = require('./helpers');
const { config, data } = require('./fixtures/data.json');
const { DataFrame } = require('./src');

const run = async () => {
    const suite = Suite('Search');

    const dataFrame = DataFrame.fromJSON(config, data);
    suite.add('using query: "age:<20"', {
        fn() {
            dataFrame.search('age:<20');
        }
    });

    suite.add('using query: "age:>80 AND alive:false"', {
        fn() {
            dataFrame.search('age:>80 AND alive:false');
        }
    });

    return suite.run({
        async: true,
        initCount: 2,
        minSamples: 2,
        maxTime: 20,
    });
};
if (require.main === module) {
    run().then((suite) => {
        suite.on('complete', () => {});
    });
} else {
    module.exports = run;
}

'use strict';

const { Suite } = require('./helpers');
const { config, data } = require('./fixtures/data.json');
const { DataFrame } = require('./src');

const run = async () => {
    const suite = Suite('Search');

    const dataFrame = DataFrame.fromJSON(config, data);
    suite.add('using query: "age:<20"', {
        fn() {
            dataFrame.search('age:<20');
        }
    });

    suite.add('using query: "age:>80 AND alive:false"', {
        fn() {
            dataFrame.search('age:>80 AND alive:false');
        }
    });

    suite.add('using query: "birthday:>=\\"1990-01-04T00:00:00.000Z\\" AND alive:true"', {
        fn() {
            dataFrame.search('birthday:>="1990-01-04T00:00:00.000Z" AND alive:true');
        }
    });

    suite.add('using query: "ip:\\"192.198.0.0/24\\"', {
        fn() {
            dataFrame.search('ip:"192.198.0.0/24"');
        }
    });

    suite.add('using query: "location:geoDistance(point: "33, 26", distance:1000mi)"', {
        fn() {
            dataFrame.search('location:geoDistance(point: "33, 26", distance:1000mi)');
        }
    });

    suite.add('using query: "metadata.number_of_friends:>5"', {
        fn() {
            dataFrame.search('metadata.number_of_friends:>5');
        }
    });

    return suite.run({
        async: true,
        initCount: 2,
        minSamples: 2,
        maxTime: 20,
    });
};
if (require.main === module) {
    run().then((suite) => {
        suite.on('complete', () => {});
    });
} else {
    module.exports = run;
}

Improve data frame search benchmark


var canvas = document.querySelector("#gamevas");
canvas.width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
canvas.height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var ctx = canvas.getContext("2d");
var player, enemies, goal, held = 0, difficulty = 1, ticks = 0;
var screen = { x: 0, y: 0, width: canvas.width, height: canvas.height};
engn.makeDPad();
var levelSwitch = function (text, newlevel) {
  difficulty = newlevel;
  engn.keys.reset();
  setGame();
};
var renderThing = function (thing) {
  ctx.fillStyle = thing.color;
  ctx.fillRect(thing.x, thing.y, thing.width, thing.height);
};
var loop = new engn.Loop(60);
setGame();
loop.onUpdate(gameUpdate).onRender(gameRender).unfreeze();

var canvas = document.querySelector("#gamevas");
canvas.width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
canvas.height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var ctx = canvas.getContext("2d");
var player, enemies, boosts, goal, held = 0, difficulty = 1, ticks = 0;
var screen = { x: 0, y: 0, width: canvas.width, height: canvas.height};
engn.makeDPad();
var levelSwitch = function (text, newlevel) {
  difficulty = newlevel;
  engn.keys.reset();
  setGame();
};
var renderRect = function (thing) {
  ctx.fillStyle = thing.color;
  ctx.fillRect(thing.x, thing.y, thing.width, thing.height);
};
var renderCircle = function (thing) {
  ctx.fillStyle = thing.color;
  ctx.beginPath();
  ctx.ellipse(thing.x - thing.width / 2, thing.y - thing.height / 2,
    thing.width / 2, thing.height / 2, 0, 0, Math.PI * 2);
  ctx.fill();
};
var loop = new engn.Loop(60);
setGame();
loop.onUpdate(gameUpdate).onRender(gameRender).unfreeze();

Replace spurts with boost powerups.


var NwBuilder = require("node-webkit-builder");
var asap = require("pdenodeify");

module.exports = function(options){
	var nwOptions = {};

	// Convert the options to camelcase
	Object.keys(options).forEach(function(optName){
		nwOptions[toCamelcase(optName)] = options[optName];
	});

	// TODO fix this
	//nwOptions.files = this.filesSrc;

	var nw = new NwBuilder(nwOptions);

	nw.on("log", function(msg){
		console.error(msg);
	});

	var build = nw.build.bind(nw);
	return asap(build)();
};

function toCamelcase(str) {
	return str.replace(/\_+([a-z])/g, function (x, chr) { return chr.toUpperCase(); });
}

var NwBuilder = require("node-webkit-builder");
var asap = require("pdenodeify");
var path = require("path");

module.exports = function(options, buildResult){
	var nwOptions = {};

	// Convert the options to camelcase
	Object.keys(options).forEach(function(optName){
		nwOptions[toCamelcase(optName)] = options[optName];
	});

	// TODO fix this
	//nwOptions.files = this.filesSrc;

	var nw = new NwBuilder(nwOptions);

	nw.on("log", function(msg){
		console.error(msg);
	});

	// Set the bundlesPath as a file to use.
	var files = nwOptions.files || [];
	if(buildResult && buildResult.bundlesPath) {
		var bundlesPath = buildResult.bundlesPath;
		files.unshift(path.join(bundlesPath, "**/*"));
	}
	nwOptions.files = files;

	var build = nw.build.bind(nw);
	return asap(build)();
};

function toCamelcase(str) {
	return str.replace(/\_+([a-z])/g, function (x, chr) { return chr.toUpperCase(); });
}

Copy files from the bundlesPath


#!/usr/bin/env node
var raml2html = require('raml2html')

function die(message) {
    console.error(message)
    process.exit(1)
}

var args = process.argv.slice(2)
if (args.length !== 1) {
    die('Expected one argument: input RAML file')
}

var input = args[0]
var https = true
var config = raml2html.getDefaultConfig(
    https,
    './templates/template.handlebars',
    './templates/resource.handlebars',
    './templates/item.handlebars'
)

raml2html.render(
    input,
    config,
    function(result) { process.stdout.write(result) },
    function(error) { die('Error parsing: ' + error) }
)

#!/usr/bin/env node
var raml2html = require('raml2html')

function die(message) {
    console.error(message)
    process.exit(1)
}

var args = process.argv.slice(2)
if (args.length !== 1) {
    die('Expected one argument: input RAML file')
}

function template(x) {
    return path.join(__dirname, 'templates', x)
}

var input = args[0]
var https = true
var config = raml2html.getDefaultConfig(
    https,
    template('template.handlebars'),
    template('resource.handlebars'),
    template('item.handlebars')
)

raml2html.render(
    input,
    config,
    function(result) { process.stdout.write(result) },
    function(error) { die('Error parsing: ' + error) }
)

Load templates relative to source file


require("pixi.js");

import TileType from "./TileType";

var tileTypes;

/**
 * Load game tile types...
 */
function loadTileTypes() {
    console.log("Loading tile types...");

    var tileTypeConfig = require("../assets/tiles/tiles.json");
    var tileTypes = {};

    for (var tileTypeId in tileTypeConfig) {
        if (!tileTypeConfig.hasOwnProperty(tileTypeId)) { continue; }
        var tileTypeDef = tileTypeConfig[tileTypeId];
        var id = parseInt(tileTypeId);

        tileTypes[id] = new TileType(id, tileTypeDef.texture, tileTypeDef.encounter);
    }

    console.log("Loaded " + Object.keys(tileTypes).length + " tiles!");

    return tileTypes;
}
tileTypes = loadTileTypes();

// Init rendering
var stage = new PIXI.Container();
var renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);

requestAnimationFrame(animate);

// Add a test tile for testing.
var testTileTexture = PIXI.Texture.fromImage("assets/tiles/white01.png");
var testTile = new PIXI.Sprite(testTileTexture);
stage.addChild(testTile);

function animate() {
    requestAnimationFrame(animate);

    renderer.render(stage);
}

require("pixi.js");

import TileType from "./TileType";

// Constants
const ASSET_URL = "assets";

var tileTypes;

/**
 * Load game tile types...
 */
function loadTileTypes() {
    console.log("Loading tile types...");

    var tileTypeConfig = require("../assets/tiles/tiles.json");
    var tileTypes = {};

    for (var tileTypeId in tileTypeConfig) {
        if (!tileTypeConfig.hasOwnProperty(tileTypeId)) { continue; }
        var tileTypeDef = tileTypeConfig[tileTypeId];
        var id = parseInt(tileTypeId);

        tileTypes[id] = new TileType(id, tileTypeDef.texture, tileTypeDef.encounter);
    }

    console.log("Loaded " + Object.keys(tileTypes).length + " tiles!");

    return tileTypes;
}
tileTypes = loadTileTypes();

// Init rendering
var stage = new PIXI.Container();
var renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);

requestAnimationFrame(animate);

// Add a test tile for testing.
var testTileTexture = PIXI.Texture.fromImage(ASSET_URL + "/tiles/" + tileTypes[1].texture);
var testTile = new PIXI.Sprite(testTileTexture);
stage.addChild(testTile);

function animate() {
    requestAnimationFrame(animate);

    renderer.render(stage);
}

Test tile now gets it's texture from the tile type array.