Set a connection timeout for DevTools methods

Close #194

--- lib/external-request.js
+++ lib/external-request.js
@@ -1,4 +1,6 @@
 'use strict';
+
+const REQUEST_TIMEOUT = 10000;

 // callback(err, data)
 function externalRequest(transport, options, callback) {
@@ -15,6 +17,9 @@
             }
         });
     });
+    request.setTimeout(REQUEST_TIMEOUT, function () {
+        this.abort();
+    });
     request.on('error', function (err) {
         callback(err);
     });

<|original_code|>
'use strict';

// callback(err, data)
function externalRequest(transport, options, callback) {
    const request = transport.get(options, function (response) {
        let data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            if (response.statusCode === 200) {
                callback(null, data);
            } else {
                callback(new Error(data));
            }
        });
    });
    request.on('error', function (err) {
        callback(err);
    });
}

module.exports = externalRequest;

<|edits_diff|>
--- lib/external-request.js
+++ lib/external-request.js
@@ -1,4 +1,6 @@
 'use strict';
+
+const REQUEST_TIMEOUT = 10000;

 // callback(err, data)
 function externalRequest(transport, options, callback) {
<|current_version|>
'use strict';

const REQUEST_TIMEOUT = 10000;

// callback(err, data)
function externalRequest(transport, options, callback) {
    const request = transport.get(options, function (response) {
        let data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            if (response.statusCode === 200) {
                callback(null, data);
            } else {
                callback(new Error(data));
            }
        });
    });
    request.on('error', function (err) {
        callback(err);
    });
}

module.exports = externalRequest;

<|next_version|>
'use strict';

const REQUEST_TIMEOUT = 10000;

// callback(err, data)
function externalRequest(transport, options, callback) {
    const request = transport.get(options, function (response) {
        let data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            if (response.statusCode === 200) {
                callback(null, data);
            } else {
                callback(new Error(data));
            }
        });
    });
    request.setTimeout(REQUEST_TIMEOUT, function () {
        this.abort();
    });
    request.on('error', function (err) {
        callback(err);
    });
}

module.exports = externalRequest;


Fix title of paths page when redirected from professions page

--- app/professions-page/professionsPage.js
+++ app/professions-page/professionsPage.js
@@ -6,10 +6,12 @@
     ) {
         this.professions = currentProfessions.getCurrentData().professions;
         this.currentPaths = currentPaths;
+        this.currentProfessions = currentProfessions;
         this.$location = $location;
     }

     ProfessionsPageController.prototype.loadPaths = function(chosenProfession) {
+        this.currentProfessions.setNewData(chosenProfession);
         this.currentPaths.setNewData(chosenProfession.educationPaths);
         this.$location.path('/paths');
     };

<|original_code|>
var ProfessionsPageController = (function(){
    function ProfessionsPageController(
        currentProfessions,
        currentPaths,
        $location
    ) {
        this.professions = currentProfessions.getCurrentData().professions;
        this.currentPaths = currentPaths;
        this.$location = $location;
    }

    ProfessionsPageController.prototype.loadPaths = function(chosenProfession) {
        this.currentPaths.setNewData(chosenProfession.educationPaths);
        this.$location.path('/paths');
    };

    ProfessionsPageController.$inject = [
        'currentProfessions',
        'currentPaths',
        '$location'
    ];
    return ProfessionsPageController;
})();

function configProfessionsPageRoute($routeProvider) {
    $routeProvider.when('/professions', {
        templateUrl: 'professions-page/professionsPage.html',
        controller: ProfessionsPageController,
        controllerAs: 'professionsPage'
    });
}
configProfessionsPageRoute.$inject = ['$routeProvider'];

angular.module('myApp.searchPage', ['ngRoute'])
    .config(configProfessionsPageRoute);

<|edits_diff|>
--- app/professions-page/professionsPage.js
+++ app/professions-page/professionsPage.js
@@ -6,6 +6,7 @@
     ) {
         this.professions = currentProfessions.getCurrentData().professions;
         this.currentPaths = currentPaths;
+        this.currentProfessions = currentProfessions;
         this.$location = $location;
     }

<|current_version|>
var ProfessionsPageController = (function(){
    function ProfessionsPageController(
        currentProfessions,
        currentPaths,
        $location
    ) {
        this.professions = currentProfessions.getCurrentData().professions;
        this.currentPaths = currentPaths;
        this.currentProfessions = currentProfessions;
        this.$location = $location;
    }

    ProfessionsPageController.prototype.loadPaths = function(chosenProfession) {
        this.currentPaths.setNewData(chosenProfession.educationPaths);
        this.$location.path('/paths');
    };

    ProfessionsPageController.$inject = [
        'currentProfessions',
        'currentPaths',
        '$location'
    ];
    return ProfessionsPageController;
})();

function configProfessionsPageRoute($routeProvider) {
    $routeProvider.when('/professions', {
        templateUrl: 'professions-page/professionsPage.html',
        controller: ProfessionsPageController,
        controllerAs: 'professionsPage'
    });
}
configProfessionsPageRoute.$inject = ['$routeProvider'];

angular.module('myApp.searchPage', ['ngRoute'])
    .config(configProfessionsPageRoute);

<|next_version|>
var ProfessionsPageController = (function(){
    function ProfessionsPageController(
        currentProfessions,
        currentPaths,
        $location
    ) {
        this.professions = currentProfessions.getCurrentData().professions;
        this.currentPaths = currentPaths;
        this.currentProfessions = currentProfessions;
        this.$location = $location;
    }

    ProfessionsPageController.prototype.loadPaths = function(chosenProfession) {
        this.currentProfessions.setNewData(chosenProfession);
        this.currentPaths.setNewData(chosenProfession.educationPaths);
        this.$location.path('/paths');
    };

    ProfessionsPageController.$inject = [
        'currentProfessions',
        'currentPaths',
        '$location'
    ];
    return ProfessionsPageController;
})();

function configProfessionsPageRoute($routeProvider) {
    $routeProvider.when('/professions', {
        templateUrl: 'professions-page/professionsPage.html',
        controller: ProfessionsPageController,
        controllerAs: 'professionsPage'
    });
}
configProfessionsPageRoute.$inject = ['$routeProvider'];

angular.module('myApp.searchPage', ['ngRoute'])
    .config(configProfessionsPageRoute);


Set Web3 provider on contracts.

Set Web3 provider on contracts.

--- local_modules/webapp/app/model/Contracts.js
+++ local_modules/webapp/app/model/Contracts.js
@@ -1,3 +1,4 @@
+import Web3 from 'web3'
 import contract from 'truffle-contract'

 import RFQRegistryJSON from 'contracts/build/contracts/RFQRegistry.json'
@@ -6,4 +7,8 @@
 const RFQRegistry = contract(RFQRegistryJSON)
 const RFQ = contract(RFQJSON)

+const provider = new Web3.providers.HttpProvider('http://localhost:8545')
+RFQRegistry.setProvider(provider)
+RFQ.setProvider(provider)
+
 export { RFQ, RFQRegistry }

<|original_code|>
import contract from 'truffle-contract'

import RFQRegistryJSON from 'contracts/build/contracts/RFQRegistry.json'
import RFQJSON from 'contracts/build/contracts/RFQ.json'

const RFQRegistry = contract(RFQRegistryJSON)
const RFQ = contract(RFQJSON)

export { RFQ, RFQRegistry }

<|edits_diff|>
--- local_modules/webapp/app/model/Contracts.js
+++ local_modules/webapp/app/model/Contracts.js
@@ -1,3 +1,4 @@
+import Web3 from 'web3'
 import contract from 'truffle-contract'

 import RFQRegistryJSON from 'contracts/build/contracts/RFQRegistry.json'
<|current_version|>
import Web3 from 'web3'
import contract from 'truffle-contract'

import RFQRegistryJSON from 'contracts/build/contracts/RFQRegistry.json'
import RFQJSON from 'contracts/build/contracts/RFQ.json'

const RFQRegistry = contract(RFQRegistryJSON)
const RFQ = contract(RFQJSON)

export { RFQ, RFQRegistry }

<|next_version|>
import Web3 from 'web3'
import contract from 'truffle-contract'

import RFQRegistryJSON from 'contracts/build/contracts/RFQRegistry.json'
import RFQJSON from 'contracts/build/contracts/RFQ.json'

const RFQRegistry = contract(RFQRegistryJSON)
const RFQ = contract(RFQJSON)

const provider = new Web3.providers.HttpProvider('http://localhost:8545')
RFQRegistry.setProvider(provider)
RFQ.setProvider(provider)

export { RFQ, RFQRegistry }


Add Google Analytics tracking on events

Add Google Analytics tracking on events

--- lib/controllers/home/index.js
+++ lib/controllers/home/index.js
@@ -11,8 +11,12 @@
         $scope.alerts = [];

         $http.put('/api/subscriptions', data).success(function(){
+            ga('send', 'event', 'subscriptions', 'signup');
+
             $scope.alerts.push({type: 'success', msg: 'Done! Now when there\'s a new package version available we\'ll let you know.'});
         }).error(function(data) {
+            ga('send', 'exception', { 'exDescription': 'SignupError' });
+
             if (Array.isArray(data)) {
                 for (var i = 0; i < data.length; i++) {
                     $scope.alerts.push({type: 'error', msg: data[i].msg });

<|original_code|>
angular.module('npmalerts', ['ui.bootstrap']);
function SignUpCtrl($scope, $http) {
    $scope.alerts = [];

    $scope.closeAlert = function(index) {
        $scope.alerts.splice(index, 1);
    };

    $scope.submitWatch = function() {
        var data = { email: $scope.email, repo: $scope.url };
        $scope.alerts = [];

        $http.put('/api/subscriptions', data).success(function(){
            $scope.alerts.push({type: 'success', msg: 'Done! Now when there\'s a new package version available we\'ll let you know.'});
        }).error(function(data) {
            if (Array.isArray(data)) {
                for (var i = 0; i < data.length; i++) {
                    $scope.alerts.push({type: 'error', msg: data[i].msg });
                }
            } else {
                $scope.alerts.push({type: 'error', msg: data });
            }
        });
    };
}
<|edits_diff|>
--- lib/controllers/home/index.js
+++ lib/controllers/home/index.js
@@ -11,6 +11,8 @@
         $scope.alerts = [];

         $http.put('/api/subscriptions', data).success(function(){
+            ga('send', 'event', 'subscriptions', 'signup');
+
             $scope.alerts.push({type: 'success', msg: 'Done! Now when there\'s a new package version available we\'ll let you know.'});
         }).error(function(data) {
             if (Array.isArray(data)) {
<|current_version|>
angular.module('npmalerts', ['ui.bootstrap']);
function SignUpCtrl($scope, $http) {
    $scope.alerts = [];

    $scope.closeAlert = function(index) {
        $scope.alerts.splice(index, 1);
    };

    $scope.submitWatch = function() {
        var data = { email: $scope.email, repo: $scope.url };
        $scope.alerts = [];

        $http.put('/api/subscriptions', data).success(function(){
            ga('send', 'event', 'subscriptions', 'signup');

            $scope.alerts.push({type: 'success', msg: 'Done! Now when there\'s a new package version available we\'ll let you know.'});
        }).error(function(data) {
            if (Array.isArray(data)) {
                for (var i = 0; i < data.length; i++) {
                    $scope.alerts.push({type: 'error', msg: data[i].msg });
                }
            } else {
                $scope.alerts.push({type: 'error', msg: data });
            }
        });
    };
}
<|next_version|>
angular.module('npmalerts', ['ui.bootstrap']);
function SignUpCtrl($scope, $http) {
    $scope.alerts = [];

    $scope.closeAlert = function(index) {
        $scope.alerts.splice(index, 1);
    };

    $scope.submitWatch = function() {
        var data = { email: $scope.email, repo: $scope.url };
        $scope.alerts = [];

        $http.put('/api/subscriptions', data).success(function(){
            ga('send', 'event', 'subscriptions', 'signup');

            $scope.alerts.push({type: 'success', msg: 'Done! Now when there\'s a new package version available we\'ll let you know.'});
        }).error(function(data) {
            ga('send', 'exception', { 'exDescription': 'SignupError' });

            if (Array.isArray(data)) {
                for (var i = 0; i < data.length; i++) {
                    $scope.alerts.push({type: 'error', msg: data[i].msg });
                }
            } else {
                $scope.alerts.push({type: 'error', msg: data });
            }
        });
    };
}


Use edit controller as the default controller for OMIS edit app

--- src/apps/omis/apps/edit/controllers/edit-handler.js
+++ src/apps/omis/apps/edit/controllers/edit-handler.js
@@ -2,6 +2,7 @@
 const i18nFuture = require('i18n-future')
 const { reduce } = require('lodash')

+const EditController = require('../../../controllers/edit')
 const steps = require('../steps')
 const fields = require('../fields')
 const i18n = i18nFuture({
@@ -22,6 +23,7 @@
     name: 'edit',
     route: '/edit',
     template: '_layouts/form-wizard-step',
+    controller: EditController,
     translate: i18n.translate.bind(i18n),
   }
   const overrides = {

<|original_code|>
const path = require('path')
const i18nFuture = require('i18n-future')
const { reduce } = require('lodash')

const steps = require('../steps')
const fields = require('../fields')
const i18n = i18nFuture({
  path: path.resolve(__dirname, '../../../locales/__lng__/__ns__.json'),
})

function editHandler (req, res, next) {
  const step = steps[`/${req.params.step}`]
  const order = res.locals.order

  if (!step || !order) { return next() }

  const defaults = {
    buttonText: 'Save and return',
    returnText: 'Return without saving',
    disableFormAction: !order.editable,
    journeyName: 'edit',
    name: 'edit',
    route: '/edit',
    template: '_layouts/form-wizard-step',
    translate: i18n.translate.bind(i18n),
  }
  const overrides = {
    fields: reduce(step.fields, (result, field) => {
      result[field] = fields[field] || {}
      return result
    }, {}),
    backLink: path.resolve(req.baseUrl, '..'),
  }
  const options = Object.assign(defaults, step, overrides)
  const ControllerClass = options.controller

  res.breadcrumb(options.heading)

  new ControllerClass(options).requestHandler()(req, res, next)
}

module.exports = editHandler

<|edits_diff|>
--- src/apps/omis/apps/edit/controllers/edit-handler.js
+++ src/apps/omis/apps/edit/controllers/edit-handler.js
@@ -2,6 +2,7 @@
 const i18nFuture = require('i18n-future')
 const { reduce } = require('lodash')

+const EditController = require('../../../controllers/edit')
 const steps = require('../steps')
 const fields = require('../fields')
 const i18n = i18nFuture({
<|current_version|>
const path = require('path')
const i18nFuture = require('i18n-future')
const { reduce } = require('lodash')

const EditController = require('../../../controllers/edit')
const steps = require('../steps')
const fields = require('../fields')
const i18n = i18nFuture({
  path: path.resolve(__dirname, '../../../locales/__lng__/__ns__.json'),
})

function editHandler (req, res, next) {
  const step = steps[`/${req.params.step}`]
  const order = res.locals.order

  if (!step || !order) { return next() }

  const defaults = {
    buttonText: 'Save and return',
    returnText: 'Return without saving',
    disableFormAction: !order.editable,
    journeyName: 'edit',
    name: 'edit',
    route: '/edit',
    template: '_layouts/form-wizard-step',
    translate: i18n.translate.bind(i18n),
  }
  const overrides = {
    fields: reduce(step.fields, (result, field) => {
      result[field] = fields[field] || {}
      return result
    }, {}),
    backLink: path.resolve(req.baseUrl, '..'),
  }
  const options = Object.assign(defaults, step, overrides)
  const ControllerClass = options.controller

  res.breadcrumb(options.heading)

  new ControllerClass(options).requestHandler()(req, res, next)
}

module.exports = editHandler

<|next_version|>
const path = require('path')
const i18nFuture = require('i18n-future')
const { reduce } = require('lodash')

const EditController = require('../../../controllers/edit')
const steps = require('../steps')
const fields = require('../fields')
const i18n = i18nFuture({
  path: path.resolve(__dirname, '../../../locales/__lng__/__ns__.json'),
})

function editHandler (req, res, next) {
  const step = steps[`/${req.params.step}`]
  const order = res.locals.order

  if (!step || !order) { return next() }

  const defaults = {
    buttonText: 'Save and return',
    returnText: 'Return without saving',
    disableFormAction: !order.editable,
    journeyName: 'edit',
    name: 'edit',
    route: '/edit',
    template: '_layouts/form-wizard-step',
    controller: EditController,
    translate: i18n.translate.bind(i18n),
  }
  const overrides = {
    fields: reduce(step.fields, (result, field) => {
      result[field] = fields[field] || {}
      return result
    }, {}),
    backLink: path.resolve(req.baseUrl, '..'),
  }
  const options = Object.assign(defaults, step, overrides)
  const ControllerClass = options.controller

  res.breadcrumb(options.heading)

  new ControllerClass(options).requestHandler()(req, res, next)
}

module.exports = editHandler


Add helper to get project name

Add helper to get project name

--- src/util.js
+++ src/util.js
@@ -11,12 +11,18 @@
 // the License.

 import {getPackageDir} from './paths'
+import {join} from 'path'

 export function exitOnPackageNotFound() {
   if (getPackageDir())
     return
   process.stdout.write('No valid “package.json” found.')
   process.exit(1)
+}
+
+export function getProjectName() {
+  const PACKAGE_JSON = join(getPackageDir(), 'package.json')
+  return require(PACKAGE_JSON).name
 }

 export function pickNonFalsy(obj:Object):Object {

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

import {getPackageDir} from './paths'

export function exitOnPackageNotFound() {
  if (getPackageDir())
    return
  process.stdout.write('No valid “package.json” found.')
  process.exit(1)
}

export function pickNonFalsy(obj:Object):Object {
  let result = {}
  for (let prop in obj) {
    if (obj[prop])
      result[prop] = obj[prop]
  }
  return result
}

<|edits_diff|>
--- src/util.js
+++ src/util.js
@@ -11,6 +11,7 @@
 // the License.

 import {getPackageDir} from './paths'
+import {join} from 'path'

 export function exitOnPackageNotFound() {
   if (getPackageDir())
<|current_version|>
// 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.

import {getPackageDir} from './paths'
import {join} from 'path'

export function exitOnPackageNotFound() {
  if (getPackageDir())
    return
  process.stdout.write('No valid “package.json” found.')
  process.exit(1)
}

export function pickNonFalsy(obj:Object):Object {
  let result = {}
  for (let prop in obj) {
    if (obj[prop])
      result[prop] = obj[prop]
  }
  return result
}

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

import {getPackageDir} from './paths'
import {join} from 'path'

export function exitOnPackageNotFound() {
  if (getPackageDir())
    return
  process.stdout.write('No valid “package.json” found.')
  process.exit(1)
}

export function getProjectName() {
  const PACKAGE_JSON = join(getPackageDir(), 'package.json')
  return require(PACKAGE_JSON).name
}

export function pickNonFalsy(obj:Object):Object {
  let result = {}
  for (let prop in obj) {
    if (obj[prop])
      result[prop] = obj[prop]
  }
  return result
}


Add reference tests for created objects

Add reference tests for created objects

--- src/main.js
+++ src/main.js
@@ -11,11 +11,13 @@
 const a2 = load(A, context);
 const a3 = load(A, {[D]: 'test'});

+assert.equal(a1, a2);
 assert.equal(a1.d, a2.d);
 assert.equal(a1.b, a2.b);
 assert.equal(a1.c, a2.c);
 assert.equal(a1.b.c.d, a2.b.c.d);

+assert.notEqual(a1, a3);
 assert.notEqual(a1.d, a3.d);
 assert.notEqual(a1.b, a3.b);
 assert.notEqual(a1.c, a3.c);

<|original_code|>
import {load} from "Injector";
import A from "example/A";
import D from "example/D";
import assert from "./assert";
import Context from "./di/Context";

const d = load(D, {name:'injected instance'});
const context = new Context({[D]: d});

const a1 = load(A, context);
const a2 = load(A, context);
const a3 = load(A, {[D]: 'test'});

assert.equal(a1.d, a2.d);
assert.equal(a1.b, a2.b);
assert.equal(a1.c, a2.c);
assert.equal(a1.b.c.d, a2.b.c.d);

assert.notEqual(a1.d, a3.d);
assert.notEqual(a1.b, a3.b);
assert.notEqual(a1.c, a3.c);
assert.notEqual(a1.b.c.d, a3.b.c.d);

<|edits_diff|>
--- src/main.js
+++ src/main.js
@@ -11,6 +11,7 @@
 const a2 = load(A, context);
 const a3 = load(A, {[D]: 'test'});

+assert.equal(a1, a2);
 assert.equal(a1.d, a2.d);
 assert.equal(a1.b, a2.b);
 assert.equal(a1.c, a2.c);
<|current_version|>
import {load} from "Injector";
import A from "example/A";
import D from "example/D";
import assert from "./assert";
import Context from "./di/Context";

const d = load(D, {name:'injected instance'});
const context = new Context({[D]: d});

const a1 = load(A, context);
const a2 = load(A, context);
const a3 = load(A, {[D]: 'test'});

assert.equal(a1, a2);
assert.equal(a1.d, a2.d);
assert.equal(a1.b, a2.b);
assert.equal(a1.c, a2.c);
assert.equal(a1.b.c.d, a2.b.c.d);

assert.notEqual(a1.d, a3.d);
assert.notEqual(a1.b, a3.b);
assert.notEqual(a1.c, a3.c);
assert.notEqual(a1.b.c.d, a3.b.c.d);

<|next_version|>
import {load} from "Injector";
import A from "example/A";
import D from "example/D";
import assert from "./assert";
import Context from "./di/Context";

const d = load(D, {name:'injected instance'});
const context = new Context({[D]: d});

const a1 = load(A, context);
const a2 = load(A, context);
const a3 = load(A, {[D]: 'test'});

assert.equal(a1, a2);
assert.equal(a1.d, a2.d);
assert.equal(a1.b, a2.b);
assert.equal(a1.c, a2.c);
assert.equal(a1.b.c.d, a2.b.c.d);

assert.notEqual(a1, a3);
assert.notEqual(a1.d, a3.d);
assert.notEqual(a1.b, a3.b);
assert.notEqual(a1.c, a3.c);
assert.notEqual(a1.b.c.d, a3.b.c.d);


Increase default test-until timeout to 5000ms

--- test/runner.js
+++ test/runner.js
@@ -2,8 +2,13 @@
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';

+import until from 'test-until';
+
 chai.use(chaiAsPromised);
 global.assert = chai.assert;
+
+// Give tests that rely on filesystem event delivery lots of breathing room.
+until.setDefaultTimeout(5000);

 module.exports = createRunner({
   reporter: 'spec',

<|original_code|>
import {createRunner} from 'atom-mocha-test-runner';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';

chai.use(chaiAsPromised);
global.assert = chai.assert;

module.exports = createRunner({
  reporter: 'spec',
  overrideTestPaths: [/spec$/, /test/],
});

<|edits_diff|>
--- test/runner.js
+++ test/runner.js
@@ -1,6 +1,8 @@
 import {createRunner} from 'atom-mocha-test-runner';
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
+
+import until from 'test-until';

 chai.use(chaiAsPromised);
 global.assert = chai.assert;
<|current_version|>
import {createRunner} from 'atom-mocha-test-runner';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';

import until from 'test-until';

chai.use(chaiAsPromised);
global.assert = chai.assert;

module.exports = createRunner({
  reporter: 'spec',
  overrideTestPaths: [/spec$/, /test/],
});

<|next_version|>
import {createRunner} from 'atom-mocha-test-runner';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';

import until from 'test-until';

chai.use(chaiAsPromised);
global.assert = chai.assert;

// Give tests that rely on filesystem event delivery lots of breathing room.
until.setDefaultTimeout(5000);

module.exports = createRunner({
  reporter: 'spec',
  overrideTestPaths: [/spec$/, /test/],
});


Add idea reducer to root reducer

Add idea reducer to root reducer

--- web/static/js/reducers/index.js
+++ web/static/js/reducers/index.js
@@ -1,9 +1,11 @@
 import { combineReducers } from "redux"

 import user from "./user"
+import idea from "./idea"

 const rootReducer = combineReducers({
   user,
+  idea,
 })

 export default rootReducer

<|original_code|>
import { combineReducers } from "redux"

import user from "./user"

const rootReducer = combineReducers({
  user,
})

export default rootReducer

<|edits_diff|>
--- web/static/js/reducers/index.js
+++ web/static/js/reducers/index.js
@@ -1,6 +1,7 @@
 import { combineReducers } from "redux"

 import user from "./user"
+import idea from "./idea"

 const rootReducer = combineReducers({
   user,
<|current_version|>
import { combineReducers } from "redux"

import user from "./user"
import idea from "./idea"

const rootReducer = combineReducers({
  user,
})

export default rootReducer

<|next_version|>
import { combineReducers } from "redux"

import user from "./user"
import idea from "./idea"

const rootReducer = combineReducers({
  user,
  idea,
})

export default rootReducer


Add merge to to global package exports

Add merge to to global package exports

--- index.js
+++ index.js
@@ -5,6 +5,8 @@
 const FileProvider = require('./lib/providers/file-provider');
 const EnvProvider = require('./lib/providers/env-provider');
 const Configurator = require('./lib/configurator');
+
+const merge = require('./lib/utils/merge');

 function main() {
     let configurator = new Configurator();
@@ -15,6 +17,8 @@
     configurator.register('file', FileProvider);
     configurator.register('env', EnvProvider);

+    configurator.utils = { merge };
+
     return configurator;
 }

<|original_code|>
'use strict'

const LiteralProvider = require('./lib/providers/literal-provider');
const CliProvider = require('./lib/providers/cli-provider');
const FileProvider = require('./lib/providers/file-provider');
const EnvProvider = require('./lib/providers/env-provider');
const Configurator = require('./lib/configurator');

function main() {
    let configurator = new Configurator();

    // Register all of the builtin providers
    configurator.register('literal', LiteralProvider);
    configurator.register('cli', CliProvider);
    configurator.register('file', FileProvider);
    configurator.register('env', EnvProvider);

    return configurator;
}

module.exports = main();

<|edits_diff|>
--- index.js
+++ index.js
@@ -5,6 +5,8 @@
 const FileProvider = require('./lib/providers/file-provider');
 const EnvProvider = require('./lib/providers/env-provider');
 const Configurator = require('./lib/configurator');
+
+const merge = require('./lib/utils/merge');

 function main() {
     let configurator = new Configurator();
<|current_version|>
'use strict'

const LiteralProvider = require('./lib/providers/literal-provider');
const CliProvider = require('./lib/providers/cli-provider');
const FileProvider = require('./lib/providers/file-provider');
const EnvProvider = require('./lib/providers/env-provider');
const Configurator = require('./lib/configurator');

const merge = require('./lib/utils/merge');

function main() {
    let configurator = new Configurator();

    // Register all of the builtin providers
    configurator.register('literal', LiteralProvider);
    configurator.register('cli', CliProvider);
    configurator.register('file', FileProvider);
    configurator.register('env', EnvProvider);

    return configurator;
}

module.exports = main();

<|next_version|>
'use strict'

const LiteralProvider = require('./lib/providers/literal-provider');
const CliProvider = require('./lib/providers/cli-provider');
const FileProvider = require('./lib/providers/file-provider');
const EnvProvider = require('./lib/providers/env-provider');
const Configurator = require('./lib/configurator');

const merge = require('./lib/utils/merge');

function main() {
    let configurator = new Configurator();

    // Register all of the builtin providers
    configurator.register('literal', LiteralProvider);
    configurator.register('cli', CliProvider);
    configurator.register('file', FileProvider);
    configurator.register('env', EnvProvider);

    configurator.utils = { merge };

    return configurator;
}

module.exports = main();


import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './Harta.css';

const Participant = ({ text, color }) => {
  return (
    <div
      style={color}
      className="avatar-participant">
      <span>{text}</span>
    </div>
  );
};

export default class Harta extends Component {
  constructor(props) {
    super(props);
    this.state = {
      culoriParticipanti: []
    };
  }

  static defaultProps = {
    center: {lat: 47.6401534, lng: 26.2572495},
    zoom: 17,
    participanti: {},
  };

  render() {
    const participant = this.props.participanti.map((p, index) => {
      return <Participant key={index}
        lat={p.lastLocation.latitude}
        lng={p.lastLocation.longitude}
        text={p.id}
      />;
    });

    return (
      <GoogleMapReact
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}
      >{participant}</GoogleMapReact>
    );
  }
}

import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './Harta.css';

const Participant = ({ text, color }) => {
  return (
    <div
      style={color}
      className="avatar-participant">
      <span>{text}</span>
    </div>
  );
};

const createMapOptions = (maps) => {
  return {
    mapTypeId: maps.MapTypeId.SATELLITE
  }
}

export default class Harta extends Component {
  constructor(props) {
    super(props);
    this.state = {
      culoriParticipanti: []
    };
  }

  static defaultProps = {
    center: {lat: 47.6401534, lng: 26.2572495},
    zoom: 17,
    participanti: {},
  };

  render() {
    const participant = this.props.participanti.map((p, index) => {
      return <Participant key={index}
        lat={p.lastLocation.latitude}
        lng={p.lastLocation.longitude}
        text={p.id}
      />;
    });

    return (
      <GoogleMapReact
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}
        options={createMapOptions}
      >{participant}</GoogleMapReact>
    );
  }
}

Set map type to satellite

Set map type to satellite

--- src/Harta.js
+++ src/Harta.js
@@ -12,6 +12,11 @@
   );
 };

+const createMapOptions = (maps) => {
+  return {
+    mapTypeId: maps.MapTypeId.SATELLITE
+  }
+}

 export default class Harta extends Component {
   constructor(props) {
@@ -40,6 +45,7 @@
       <GoogleMapReact
         defaultCenter={this.props.center}
         defaultZoom={this.props.zoom}
+        options={createMapOptions}
       >{participant}</GoogleMapReact>
     );
   }

import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './Harta.css';

const Participant = ({ text, color }) => {
  return (
    <div
      style={color}
      className="avatar-participant">
      <span>{text}</span>
    </div>
  );
};

const createMapOptions = (maps) => {
  return {
    mapTypeId: maps.MapTypeId.SATELLITE
  }
}

export default class Harta extends Component {
  constructor(props) {
    super(props);
    this.state = {
      culoriParticipanti: []
    };
  }

  static defaultProps = {
    center: {lat: 47.6401534, lng: 26.2572495},
    zoom: 17,
    participanti: {},
  };

  render() {
    const participant = this.props.participanti.map((p, index) => {
      return <Participant key={index}
        lat={p.lastLocation.latitude}
        lng={p.lastLocation.longitude}
        text={p.id}
      />;
    });

    return (
      <GoogleMapReact
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}
      >{participant}</GoogleMapReact>
    );
  }
}

<|original_code|>
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './Harta.css';

const Participant = ({ text, color }) => {
  return (

      {text}

  );
};

export default class Harta extends Component {
  constructor(props) {
    super(props);
    this.state = {
      culoriParticipanti: []
    };
  }

  static defaultProps = {
    center: {lat: 47.6401534, lng: 26.2572495},
    zoom: 17,
    participanti: {},
  };

  render() {
    const participant = this.props.participanti.map((p, index) => {
      return <Participant key={index}
        lat={p.lastLocation.latitude}
        lng={p.lastLocation.longitude}
        text={p.id}
      />;
    });

    return (
      <GoogleMapReact
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}
      >{participant}</GoogleMapReact>
    );
  }
}

<|edits_diff|>
--- src/Harta.js
+++ src/Harta.js
@@ -12,6 +12,11 @@
   );
 };

+const createMapOptions = (maps) => {
+  return {
+    mapTypeId: maps.MapTypeId.SATELLITE
+  }
+}

 export default class Harta extends Component {
   constructor(props) {
<|current_version|>
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './Harta.css';

const Participant = ({ text, color }) => {
  return (

      {text}

  );
};

const createMapOptions = (maps) => {
  return {
    mapTypeId: maps.MapTypeId.SATELLITE
  }
}

export default class Harta extends Component {
  constructor(props) {
    super(props);
    this.state = {
      culoriParticipanti: []
    };
  }

  static defaultProps = {
    center: {lat: 47.6401534, lng: 26.2572495},
    zoom: 17,
    participanti: {},
  };

  render() {
    const participant = this.props.participanti.map((p, index) => {
      return <Participant key={index}
        lat={p.lastLocation.latitude}
        lng={p.lastLocation.longitude}
        text={p.id}
      />;
    });

    return (
      <GoogleMapReact
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}
      >{participant}</GoogleMapReact>
    );
  }
}

<|next_version|>
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
import './Harta.css';

const Participant = ({ text, color }) => {
  return (

      {text}

  );
};

const createMapOptions = (maps) => {
  return {
    mapTypeId: maps.MapTypeId.SATELLITE
  }
}

export default class Harta extends Component {
  constructor(props) {
    super(props);
    this.state = {
      culoriParticipanti: []
    };
  }

  static defaultProps = {
    center: {lat: 47.6401534, lng: 26.2572495},
    zoom: 17,
    participanti: {},
  };

  render() {
    const participant = this.props.participanti.map((p, index) => {
      return <Participant key={index}
        lat={p.lastLocation.latitude}
        lng={p.lastLocation.longitude}
        text={p.id}
      />;
    });

    return (
      <GoogleMapReact
        defaultCenter={this.props.center}
        defaultZoom={this.props.zoom}
        options={createMapOptions}
      >{participant}</GoogleMapReact>
    );
  }
}


Fix JSCS of generated model files

Fix JSCS of generated model files

--- blueprints/flexberry-model-init/files/__root__/models/__name__.js
+++ blueprints/flexberry-model-init/files/__root__/models/__name__.js
@@ -1,10 +1,14 @@
 import { Model as <%= className %>Mixin<%if (projections) {%>, defineProjections<%}%> } from '../mixins/regenerated/models/<%= name %>';
 import <%if(parentModelName) {%><%= parentClassName %>Model from './<%= parentModelName %>';<%}else{%>{ Projection } from 'ember-flexberry-data';<%}%>
+
 let Model = <%if(parentModelName) {%><%= parentClassName %>Model.extend<%}else{%>Projection.Model.extend<%}%>(<%= className %>Mixin, {

 });
+
 <%if(parentModelName) {%>Model.reopenClass({
   _parentModelName: '<%= parentModelName %>'
 });<%}%>
+
 <%if(projections) {%>defineProjections(Model);<%}%>
+
 export default Model;

<|original_code|>
import { Model as <%= className %>Mixin<%if (projections) {%>, defineProjections<%}%> } from '../mixins/regenerated/models/<%= name %>';
import <%if(parentModelName) {%><%= parentClassName %>Model from './<%= parentModelName %>';<%}else{%>{ Projection } from 'ember-flexberry-data';<%}%>
let Model = <%if(parentModelName) {%><%= parentClassName %>Model.extend<%}else{%>Projection.Model.extend<%}%>(<%= className %>Mixin, {

});
<%if(parentModelName) {%>Model.reopenClass({
  _parentModelName: '<%= parentModelName %>'
});<%}%>
<%if(projections) {%>defineProjections(Model);<%}%>
export default Model;

<|edits_diff|>
--- blueprints/flexberry-model-init/files/__root__/models/__name__.js
+++ blueprints/flexberry-model-init/files/__root__/models/__name__.js
@@ -1,10 +1,13 @@
 import { Model as <%= className %>Mixin<%if (projections) {%>, defineProjections<%}%> } from '../mixins/regenerated/models/<%= name %>';
 import <%if(parentModelName) {%><%= parentClassName %>Model from './<%= parentModelName %>';<%}else{%>{ Projection } from 'ember-flexberry-data';<%}%>
+
 let Model = <%if(parentModelName) {%><%= parentClassName %>Model.extend<%}else{%>Projection.Model.extend<%}%>(<%= className %>Mixin, {

 });
+
 <%if(parentModelName) {%>Model.reopenClass({
   _parentModelName: '<%= parentModelName %>'
 });<%}%>
+
 <%if(projections) {%>defineProjections(Model);<%}%>
 export default Model;
<|current_version|>
import { Model as <%= className %>Mixin<%if (projections) {%>, defineProjections<%}%> } from '../mixins/regenerated/models/<%= name %>';
import <%if(parentModelName) {%><%= parentClassName %>Model from './<%= parentModelName %>';<%}else{%>{ Projection } from 'ember-flexberry-data';<%}%>

let Model = <%if(parentModelName) {%><%= parentClassName %>Model.extend<%}else{%>Projection.Model.extend<%}%>(<%= className %>Mixin, {

});

<%if(parentModelName) {%>Model.reopenClass({
  _parentModelName: '<%= parentModelName %>'
});<%}%>

<%if(projections) {%>defineProjections(Model);<%}%>
export default Model;

<|next_version|>
import { Model as <%= className %>Mixin<%if (projections) {%>, defineProjections<%}%> } from '../mixins/regenerated/models/<%= name %>';
import <%if(parentModelName) {%><%= parentClassName %>Model from './<%= parentModelName %>';<%}else{%>{ Projection } from 'ember-flexberry-data';<%}%>

let Model = <%if(parentModelName) {%><%= parentClassName %>Model.extend<%}else{%>Projection.Model.extend<%}%>(<%= className %>Mixin, {

});

<%if(parentModelName) {%>Model.reopenClass({
  _parentModelName: '<%= parentModelName %>'
});<%}%>

<%if(projections) {%>defineProjections(Model);<%}%>

export default Model;


Add memory session to bot

Add memory session to bot

--- index.js
+++ index.js
@@ -1,4 +1,5 @@
 const Telegraf = require('telegraf');
+const { memorySession } = require('telegraf');

 let userManager = require('./user-manager');

@@ -7,6 +8,10 @@

 const bot = new Telegraf(BOT_API_TOKEN);

+bot.use(memorySession);
+
+
+
 bot.startPolling();

 console.log('Bot start polling....');

<|original_code|>
const Telegraf = require('telegraf');

let userManager = require('./user-manager');

// Enter bot API Token on here or add as environment varialbe
const BOT_API_TOKEN = process.env.API_TOKEN || '';

const bot = new Telegraf(BOT_API_TOKEN);

bot.startPolling();

console.log('Bot start polling....');

<|edits_diff|>
--- index.js
+++ index.js
@@ -1,4 +1,5 @@
 const Telegraf = require('telegraf');
+const { memorySession } = require('telegraf');

 let userManager = require('./user-manager');

<|current_version|>
const Telegraf = require('telegraf');
const { memorySession } = require('telegraf');

let userManager = require('./user-manager');

// Enter bot API Token on here or add as environment varialbe
const BOT_API_TOKEN = process.env.API_TOKEN || '';

const bot = new Telegraf(BOT_API_TOKEN);

bot.startPolling();

console.log('Bot start polling....');

<|next_version|>
const Telegraf = require('telegraf');
const { memorySession } = require('telegraf');

let userManager = require('./user-manager');

// Enter bot API Token on here or add as environment varialbe
const BOT_API_TOKEN = process.env.API_TOKEN || '';

const bot = new Telegraf(BOT_API_TOKEN);

bot.use(memorySession);

bot.startPolling();

console.log('Bot start polling....');


Fix ApolloClient tests in phantomjs

Fix ApolloClient tests in phantomjs

--- specs/client/apollo-client.spec.js
+++ specs/client/apollo-client.spec.js
@@ -2,6 +2,7 @@
 /* eslint-env mocha */
 import chai from 'chai';
 import gql from 'graphql-tag';
+import { Promise } from 'meteor/promise';
 import { ApolloClient } from 'apollo-client';
 import { InMemoryCache } from 'apollo-cache-inmemory';
 import { getDDPLink } from '../../lib/client/apollo-link-ddp';
@@ -9,6 +10,9 @@

 describe('ApolloClient with DDP link', function () {
   beforeEach(function () {
+    // The ApolloClient won't recognize Promise in package tests unless exported like this
+    global.Promise = Promise;
+
     this.client = new ApolloClient({
       link: getDDPLink(),
       cache: new InMemoryCache(),

<|original_code|>
/* eslint-disable prefer-arrow-callback, func-names */
/* eslint-env mocha */
import chai from 'chai';
import gql from 'graphql-tag';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { getDDPLink } from '../../lib/client/apollo-link-ddp';
import { FOO_CHANGED_TOPIC } from '../data/resolvers';

describe('ApolloClient with DDP link', function () {
  beforeEach(function () {
    this.client = new ApolloClient({
      link: getDDPLink(),
      cache: new InMemoryCache(),
    });
  });

  describe('#query', function () {
    it('returns query data', async function () {
      const { data } = await this.client.query({ query: gql`query { foo }` });

      chai.expect(data.foo).to.be.a('string');
    });

    it('returns subscription data', function (done) {
      const message = { fooSub: 'bar' };
      const observer = this.client.subscribe({ query: gql`subscription { fooSub }` });

      const subscription = observer.subscribe({
        next: (data) => {
          try {
            chai.expect(data).to.deep.equal(message);
            subscription.unsubscribe();
            done();
          } catch (e) {
            done(e);
          }
        },
      });

      Meteor.call('ddp-apollo/publish', FOO_CHANGED_TOPIC, message);
    });
  });
});

<|edits_diff|>
--- specs/client/apollo-client.spec.js
+++ specs/client/apollo-client.spec.js
@@ -2,6 +2,7 @@
 /* eslint-env mocha */
 import chai from 'chai';
 import gql from 'graphql-tag';
+import { Promise } from 'meteor/promise';
 import { ApolloClient } from 'apollo-client';
 import { InMemoryCache } from 'apollo-cache-inmemory';
 import { getDDPLink } from '../../lib/client/apollo-link-ddp';
<|current_version|>
/* eslint-disable prefer-arrow-callback, func-names */
/* eslint-env mocha */
import chai from 'chai';
import gql from 'graphql-tag';
import { Promise } from 'meteor/promise';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { getDDPLink } from '../../lib/client/apollo-link-ddp';
import { FOO_CHANGED_TOPIC } from '../data/resolvers';

describe('ApolloClient with DDP link', function () {
  beforeEach(function () {
    this.client = new ApolloClient({
      link: getDDPLink(),
      cache: new InMemoryCache(),
    });
  });

  describe('#query', function () {
    it('returns query data', async function () {
      const { data } = await this.client.query({ query: gql`query { foo }` });

      chai.expect(data.foo).to.be.a('string');
    });

    it('returns subscription data', function (done) {
      const message = { fooSub: 'bar' };
      const observer = this.client.subscribe({ query: gql`subscription { fooSub }` });

      const subscription = observer.subscribe({
        next: (data) => {
          try {
            chai.expect(data).to.deep.equal(message);
            subscription.unsubscribe();
            done();
          } catch (e) {
            done(e);
          }
        },
      });

      Meteor.call('ddp-apollo/publish', FOO_CHANGED_TOPIC, message);
    });
  });
});

<|next_version|>
/* eslint-disable prefer-arrow-callback, func-names */
/* eslint-env mocha */
import chai from 'chai';
import gql from 'graphql-tag';
import { Promise } from 'meteor/promise';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { getDDPLink } from '../../lib/client/apollo-link-ddp';
import { FOO_CHANGED_TOPIC } from '../data/resolvers';

describe('ApolloClient with DDP link', function () {
  beforeEach(function () {
    // The ApolloClient won't recognize Promise in package tests unless exported like this
    global.Promise = Promise;

    this.client = new ApolloClient({
      link: getDDPLink(),
      cache: new InMemoryCache(),
    });
  });

  describe('#query', function () {
    it('returns query data', async function () {
      const { data } = await this.client.query({ query: gql`query { foo }` });

      chai.expect(data.foo).to.be.a('string');
    });

    it('returns subscription data', function (done) {
      const message = { fooSub: 'bar' };
      const observer = this.client.subscribe({ query: gql`subscription { fooSub }` });

      const subscription = observer.subscribe({
        next: (data) => {
          try {
            chai.expect(data).to.deep.equal(message);
            subscription.unsubscribe();
            done();
          } catch (e) {
            done(e);
          }
        },
      });

      Meteor.call('ddp-apollo/publish', FOO_CHANGED_TOPIC, message);
    });
  });
});


Fix test to register collisions

Fix test to register collisions

--- test/destroy_planes_test.js
+++ test/destroy_planes_test.js
@@ -10,9 +10,13 @@

 	it('knows when they collide', function() {
 	    var detector = new CollisionDetector();
+	    player.border = player.makeBorder();
+	    computer.border = computer.makeBorder();
 	    var first = detector.check(player, computer);
 	    assert.equal(first, false);
 	    player.y--;
+	    player.border = player.makeBorder();
+	    computer.border = computer.makeBorder();
 	    var collision = detector.check(player, computer);
 	    assert.equal(collision, true);
 	});

<|original_code|>
const assert = require('chai').assert;

const Plane = require('../lib/javascripts/plane');
const CollisionDetector = require('../lib/javascripts/collision_detector')

describe('Collision detector', function() {
    context('with one player and one computer', function() {
	var player = new Plane({type: "player", x: 93, y: 125});
	var computer = new Plane({type: "computer", x: 100, y: 100})

	it('knows when they collide', function() {
	    var detector = new CollisionDetector();
	    var first = detector.check(player, computer);
	    assert.equal(first, false);
	    player.y--;
	    var collision = detector.check(player, computer);
	    assert.equal(collision, true);
	});
    });

});

<|edits_diff|>
--- test/destroy_planes_test.js
+++ test/destroy_planes_test.js
@@ -10,6 +10,8 @@

 	it('knows when they collide', function() {
 	    var detector = new CollisionDetector();
+	    player.border = player.makeBorder();
+	    computer.border = computer.makeBorder();
 	    var first = detector.check(player, computer);
 	    assert.equal(first, false);
 	    player.y--;
<|current_version|>
const assert = require('chai').assert;

const Plane = require('../lib/javascripts/plane');
const CollisionDetector = require('../lib/javascripts/collision_detector')

describe('Collision detector', function() {
    context('with one player and one computer', function() {
	var player = new Plane({type: "player", x: 93, y: 125});
	var computer = new Plane({type: "computer", x: 100, y: 100})

	it('knows when they collide', function() {
	    var detector = new CollisionDetector();
	    player.border = player.makeBorder();
	    computer.border = computer.makeBorder();
	    var first = detector.check(player, computer);
	    assert.equal(first, false);
	    player.y--;
	    var collision = detector.check(player, computer);
	    assert.equal(collision, true);
	});
    });

});

<|next_version|>
const assert = require('chai').assert;

const Plane = require('../lib/javascripts/plane');
const CollisionDetector = require('../lib/javascripts/collision_detector')

describe('Collision detector', function() {
    context('with one player and one computer', function() {
	var player = new Plane({type: "player", x: 93, y: 125});
	var computer = new Plane({type: "computer", x: 100, y: 100})

	it('knows when they collide', function() {
	    var detector = new CollisionDetector();
	    player.border = player.makeBorder();
	    computer.border = computer.makeBorder();
	    var first = detector.check(player, computer);
	    assert.equal(first, false);
	    player.y--;
	    player.border = player.makeBorder();
	    computer.border = computer.makeBorder();
	    var collision = detector.check(player, computer);
	    assert.equal(collision, true);
	});
    });

});


Add better commenting to floorMult filter.

--- app/js/filters.js
+++ app/js/filters.js
@@ -1,15 +1,20 @@
 /* Filter for finding the next-smallest multiple of input number */
 angular.module('sknFloorMultFilter', []).filter('floorMult', function() {
     return function(input, multSize) {
+        /* if input is already a multiple of multSize, return */
         if(input % multSize === 0) {
             return input;
         }
         else {
+            /* Ensure input is a whole number */
             var inputFloor = Math.floor(input);
+            /* if inputFloor is a multiple of multSize, return inputFloor */
             if(inputFloor % multSize === 0) {
                 return inputFloor;
             }
             else {
+                /* subtract 1 from inputFloor until inputFloor
+                is a mulple of multSize. Return modified inputFloor.*/
                 for(var i = 1; i < multSize; ++i) {
                     if((inputFloor - i) % multSize === 0) {
                         return inputFloor - i;

<|original_code|>
/* Filter for finding the next-smallest multiple of input number */
angular.module('sknFloorMultFilter', []).filter('floorMult', function() {
    return function(input, multSize) {
        if(input % multSize === 0) {
            return input;
        }
        else {
            var inputFloor = Math.floor(input);
            if(inputFloor % multSize === 0) {
                return inputFloor;
            }
            else {
                for(var i = 1; i < multSize; ++i) {
                    if((inputFloor - i) % multSize === 0) {
                        return inputFloor - i;
                    }
                }
            }
        return input;
        }
    }
});

/*Filter for month day, year from WP REST API date*/
angular.module('sknDateFilter', []).filter('date', function() {
    return function(input) {
        var months = [
            "January",
            "February",
            "March",
            "April",
            "May",
            "June",
            "July",
            "August",
            "September",
            "October",
            "November",
            "December"
        ];
        var year = input.substr(0, 4);
        var month = months[parseInt(input.substr(5, 2)) - 1];
        var day = input.substr(8, 2);
        var dateString = day + " " + month + " " + year;
        return dateString;
    }
});

<|edits_diff|>
--- app/js/filters.js
+++ app/js/filters.js
@@ -1,11 +1,14 @@
 /* Filter for finding the next-smallest multiple of input number */
 angular.module('sknFloorMultFilter', []).filter('floorMult', function() {
     return function(input, multSize) {
+        /* if input is already a multiple of multSize, return */
         if(input % multSize === 0) {
             return input;
         }
         else {
+            /* Ensure input is a whole number */
             var inputFloor = Math.floor(input);
+            /* if inputFloor is a multiple of multSize, return inputFloor */
             if(inputFloor % multSize === 0) {
                 return inputFloor;
             }
<|current_version|>
/* Filter for finding the next-smallest multiple of input number */
angular.module('sknFloorMultFilter', []).filter('floorMult', function() {
    return function(input, multSize) {
        /* if input is already a multiple of multSize, return */
        if(input % multSize === 0) {
            return input;
        }
        else {
            /* Ensure input is a whole number */
            var inputFloor = Math.floor(input);
            /* if inputFloor is a multiple of multSize, return inputFloor */
            if(inputFloor % multSize === 0) {
                return inputFloor;
            }
            else {
                for(var i = 1; i < multSize; ++i) {
                    if((inputFloor - i) % multSize === 0) {
                        return inputFloor - i;
                    }
                }
            }
        return input;
        }
    }
});

/*Filter for month day, year from WP REST API date*/
angular.module('sknDateFilter', []).filter('date', function() {
    return function(input) {
        var months = [
            "January",
            "February",
            "March",
            "April",
            "May",
            "June",
            "July",
            "August",
            "September",
            "October",
            "November",
            "December"
        ];
        var year = input.substr(0, 4);
        var month = months[parseInt(input.substr(5, 2)) - 1];
        var day = input.substr(8, 2);
        var dateString = day + " " + month + " " + year;
        return dateString;
    }
});

<|next_version|>
/* Filter for finding the next-smallest multiple of input number */
angular.module('sknFloorMultFilter', []).filter('floorMult', function() {
    return function(input, multSize) {
        /* if input is already a multiple of multSize, return */
        if(input % multSize === 0) {
            return input;
        }
        else {
            /* Ensure input is a whole number */
            var inputFloor = Math.floor(input);
            /* if inputFloor is a multiple of multSize, return inputFloor */
            if(inputFloor % multSize === 0) {
                return inputFloor;
            }
            else {
                /* subtract 1 from inputFloor until inputFloor
                is a mulple of multSize. Return modified inputFloor.*/
                for(var i = 1; i < multSize; ++i) {
                    if((inputFloor - i) % multSize === 0) {
                        return inputFloor - i;
                    }
                }
            }
        return input;
        }
    }
});

/*Filter for month day, year from WP REST API date*/
angular.module('sknDateFilter', []).filter('date', function() {
    return function(input) {
        var months = [
            "January",
            "February",
            "March",
            "April",
            "May",
            "June",
            "July",
            "August",
            "September",
            "October",
            "November",
            "December"
        ];
        var year = input.substr(0, 4);
        var month = months[parseInt(input.substr(5, 2)) - 1];
        var day = input.substr(8, 2);
        var dateString = day + " " + month + " " + year;
        return dateString;
    }
});


Add get_messages, get_thread, and send_message url strings

--- custom_modules/constants.js
+++ custom_modules/constants.js
@@ -7,9 +7,12 @@
     user_questions: 'http://www.okcupid.com/profile/{username}/questions?okc_api=1&low={low}',
     get_visitors: 'http://www.okcupid.com/visitors?okc_api=1',
     quickmatch: 'http://www.okcupid.com/quickmatch?okc_api=1',
+    get_messages: 'https://www.okcupid.com/messages?okc_api=1',
+    get_thread: 'https://www.okcupid.com/messages?okc_api=1&readmsg=true&threadid={thread_id}',

     // OAuth API
     like: 'https://www.okcupid.com/1/apitun/profile/{userid}/like',
     unlike: 'https://www.okcupid.com/1/apitun/profile/{userid}/unlike',
+    send_message: 'https://www.okcupid.com/1/apitun/messages/send',
 	}
 }

<|original_code|>
module.exports = {
    URLS: {
    login: 'https://www.okcupid.com/login',
    rate: 'http://www.okcupid.com/quickmatch',
    visit_user: 'http://www.okcupid.com/profile/{username}',
    user_profile: 'http://www.okcupid.com/profile/{username}?okc_api=1',
    user_questions: 'http://www.okcupid.com/profile/{username}/questions?okc_api=1&low={low}',
    get_visitors: 'http://www.okcupid.com/visitors?okc_api=1',
    quickmatch: 'http://www.okcupid.com/quickmatch?okc_api=1',

    // OAuth API
    like: 'https://www.okcupid.com/1/apitun/profile/{userid}/like',
    unlike: 'https://www.okcupid.com/1/apitun/profile/{userid}/unlike',
	}
}

<|edits_diff|>
--- custom_modules/constants.js
+++ custom_modules/constants.js
@@ -7,6 +7,8 @@
     user_questions: 'http://www.okcupid.com/profile/{username}/questions?okc_api=1&low={low}',
     get_visitors: 'http://www.okcupid.com/visitors?okc_api=1',
     quickmatch: 'http://www.okcupid.com/quickmatch?okc_api=1',
+    get_messages: 'https://www.okcupid.com/messages?okc_api=1',
+    get_thread: 'https://www.okcupid.com/messages?okc_api=1&readmsg=true&threadid={thread_id}',

     // OAuth API
     like: 'https://www.okcupid.com/1/apitun/profile/{userid}/like',
<|current_version|>
module.exports = {
    URLS: {
    login: 'https://www.okcupid.com/login',
    rate: 'http://www.okcupid.com/quickmatch',
    visit_user: 'http://www.okcupid.com/profile/{username}',
    user_profile: 'http://www.okcupid.com/profile/{username}?okc_api=1',
    user_questions: 'http://www.okcupid.com/profile/{username}/questions?okc_api=1&low={low}',
    get_visitors: 'http://www.okcupid.com/visitors?okc_api=1',
    quickmatch: 'http://www.okcupid.com/quickmatch?okc_api=1',
    get_messages: 'https://www.okcupid.com/messages?okc_api=1',
    get_thread: 'https://www.okcupid.com/messages?okc_api=1&readmsg=true&threadid={thread_id}',

    // OAuth API
    like: 'https://www.okcupid.com/1/apitun/profile/{userid}/like',
    unlike: 'https://www.okcupid.com/1/apitun/profile/{userid}/unlike',
	}
}

<|next_version|>
module.exports = {
    URLS: {
    login: 'https://www.okcupid.com/login',
    rate: 'http://www.okcupid.com/quickmatch',
    visit_user: 'http://www.okcupid.com/profile/{username}',
    user_profile: 'http://www.okcupid.com/profile/{username}?okc_api=1',
    user_questions: 'http://www.okcupid.com/profile/{username}/questions?okc_api=1&low={low}',
    get_visitors: 'http://www.okcupid.com/visitors?okc_api=1',
    quickmatch: 'http://www.okcupid.com/quickmatch?okc_api=1',
    get_messages: 'https://www.okcupid.com/messages?okc_api=1',
    get_thread: 'https://www.okcupid.com/messages?okc_api=1&readmsg=true&threadid={thread_id}',

    // OAuth API
    like: 'https://www.okcupid.com/1/apitun/profile/{userid}/like',
    unlike: 'https://www.okcupid.com/1/apitun/profile/{userid}/unlike',
    send_message: 'https://www.okcupid.com/1/apitun/messages/send',
	}
}


Add a class to past stops for styling purposes

--- app/components/rt-arrival.js
+++ app/components/rt-arrival.js
@@ -8,9 +8,14 @@
   clock: inject.service(),
   attributeBindings: ['style'],
   classNames: ['rt-arrival'],
+  classNameBindings: ['isPast:rt-arrival--past'],

   timeFromNow: Ember.computed('clock.time', function() {
     return moment(this.get('arrival.time')).fromNow();
+  }),
+
+  isPast: Ember.computed('clock.time', function() {
+    return new Date(this.get('arrival.time')) < new Date();
   }),

   style: Ember.computed('arrival.route_id', function() {

<|original_code|>
import Ember from 'ember';
import moment from 'moment';
import stringToHue from 'bus-detective/utils/string-to-hue';
var inject = Ember.inject;

export default Ember.Component.extend({
  tagName: 'li',
  clock: inject.service(),
  attributeBindings: ['style'],
  classNames: ['rt-arrival'],

  timeFromNow: Ember.computed('clock.time', function() {
    return moment(this.get('arrival.time')).fromNow();
  }),

  style: Ember.computed('arrival.route_id', function() {
    var hue = stringToHue(this.get('arrival.route_id').toString());
    return `color:            hsl(${hue}, 60%, 25%);
            background-color: hsl(${hue}, 40%, 95%);
            border-color:     hsl(${hue}, 40%, 80%);`;
  })
});

<|edits_diff|>
--- app/components/rt-arrival.js
+++ app/components/rt-arrival.js
@@ -8,6 +8,7 @@
   clock: inject.service(),
   attributeBindings: ['style'],
   classNames: ['rt-arrival'],
+  classNameBindings: ['isPast:rt-arrival--past'],

   timeFromNow: Ember.computed('clock.time', function() {
     return moment(this.get('arrival.time')).fromNow();
<|current_version|>
import Ember from 'ember';
import moment from 'moment';
import stringToHue from 'bus-detective/utils/string-to-hue';
var inject = Ember.inject;

export default Ember.Component.extend({
  tagName: 'li',
  clock: inject.service(),
  attributeBindings: ['style'],
  classNames: ['rt-arrival'],
  classNameBindings: ['isPast:rt-arrival--past'],

  timeFromNow: Ember.computed('clock.time', function() {
    return moment(this.get('arrival.time')).fromNow();
  }),

  style: Ember.computed('arrival.route_id', function() {
    var hue = stringToHue(this.get('arrival.route_id').toString());
    return `color:            hsl(${hue}, 60%, 25%);
            background-color: hsl(${hue}, 40%, 95%);
            border-color:     hsl(${hue}, 40%, 80%);`;
  })
});

<|next_version|>
import Ember from 'ember';
import moment from 'moment';
import stringToHue from 'bus-detective/utils/string-to-hue';
var inject = Ember.inject;

export default Ember.Component.extend({
  tagName: 'li',
  clock: inject.service(),
  attributeBindings: ['style'],
  classNames: ['rt-arrival'],
  classNameBindings: ['isPast:rt-arrival--past'],

  timeFromNow: Ember.computed('clock.time', function() {
    return moment(this.get('arrival.time')).fromNow();
  }),

  isPast: Ember.computed('clock.time', function() {
    return new Date(this.get('arrival.time')) < new Date();
  }),

  style: Ember.computed('arrival.route_id', function() {
    var hue = stringToHue(this.get('arrival.route_id').toString());
    return `color:            hsl(${hue}, 60%, 25%);
            background-color: hsl(${hue}, 40%, 95%);
            border-color:     hsl(${hue}, 40%, 80%);`;
  })
});


Add js to gulp watch

Add js to gulp watch

--- gulpfile.js
+++ gulpfile.js
@@ -8,6 +8,8 @@
 var uglify = require("gulp-uglify");

+// SASS compilation and minification
+
 gulp.task("sass", function() {
   gulp.src("./sass/**/*.sass")
     .pipe(sourcemaps.init())
@@ -15,6 +17,9 @@
     .pipe(sourcemaps.write())
     .pipe(gulp.dest("./dist"));
 });
+
+
+// JS compilation and minification

 gulp.task("js", function() {
   // Build all the scripts from a directory into a file.
@@ -33,8 +38,12 @@
   buildScriptsForPage("js/emailsent", "emailsent.js");
 });

+
+// Watching
+
 gulp.task("watch", function() {
   gulp.watch("./sass/**/*.sass", ["sass"]);
+  gulp.watch("./js/**/*.js", ["js"]);
 });

 gulp.task("default", ["watch"]);

<|original_code|>
var gulp = require("gulp");

var sourcemaps = require("gulp-sourcemaps");

var sass = require("gulp-sass");

var concat = require("gulp-concat");
var uglify = require("gulp-uglify");

gulp.task("sass", function() {
  gulp.src("./sass/**/*.sass")
    .pipe(sourcemaps.init())
    .pipe(sass({outputStyle: "compressed"}))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest("./dist"));
});

gulp.task("js", function() {
  // Build all the scripts from a directory into a file.
  function buildScriptsForPage(dir, path) {
    gulp.src(dir+"/*.js")
      .pipe(sourcemaps.init())
      .pipe(concat(path))
      .pipe(uglify())
      .pipe(sourcemaps.write())
      .pipe(gulp.dest("./dist"));
  }

  // Scripts for the front page
  buildScriptsForPage("js/home", "home.js");
  // Scrips for the "email sent" page
  buildScriptsForPage("js/emailsent", "emailsent.js");
});

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

gulp.task("default", ["watch"]);

<|edits_diff|>
--- gulpfile.js
+++ gulpfile.js
@@ -8,6 +8,8 @@
 var uglify = require("gulp-uglify");

+// SASS compilation and minification
+
 gulp.task("sass", function() {
   gulp.src("./sass/**/*.sass")
     .pipe(sourcemaps.init())
@@ -15,6 +17,9 @@
     .pipe(sourcemaps.write())
     .pipe(gulp.dest("./dist"));
 });
+
+
+// JS compilation and minification

 gulp.task("js", function() {
   // Build all the scripts from a directory into a file.
@@ -33,6 +38,9 @@
   buildScriptsForPage("js/emailsent", "emailsent.js");
 });

+
+// Watching
+
 gulp.task("watch", function() {
   gulp.watch("./sass/**/*.sass", ["sass"]);
 });
<|current_version|>
var gulp = require("gulp");

var sourcemaps = require("gulp-sourcemaps");

var sass = require("gulp-sass");

var concat = require("gulp-concat");
var uglify = require("gulp-uglify");

// SASS compilation and minification

gulp.task("sass", function() {
  gulp.src("./sass/**/*.sass")
    .pipe(sourcemaps.init())
    .pipe(sass({outputStyle: "compressed"}))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest("./dist"));
});

// JS compilation and minification

gulp.task("js", function() {
  // Build all the scripts from a directory into a file.
  function buildScriptsForPage(dir, path) {
    gulp.src(dir+"/*.js")
      .pipe(sourcemaps.init())
      .pipe(concat(path))
      .pipe(uglify())
      .pipe(sourcemaps.write())
      .pipe(gulp.dest("./dist"));
  }

  // Scripts for the front page
  buildScriptsForPage("js/home", "home.js");
  // Scrips for the "email sent" page
  buildScriptsForPage("js/emailsent", "emailsent.js");
});

// Watching

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

gulp.task("default", ["watch"]);

<|next_version|>
var gulp = require("gulp");

var sourcemaps = require("gulp-sourcemaps");

var sass = require("gulp-sass");

var concat = require("gulp-concat");
var uglify = require("gulp-uglify");

// SASS compilation and minification

gulp.task("sass", function() {
  gulp.src("./sass/**/*.sass")
    .pipe(sourcemaps.init())
    .pipe(sass({outputStyle: "compressed"}))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest("./dist"));
});

// JS compilation and minification

gulp.task("js", function() {
  // Build all the scripts from a directory into a file.
  function buildScriptsForPage(dir, path) {
    gulp.src(dir+"/*.js")
      .pipe(sourcemaps.init())
      .pipe(concat(path))
      .pipe(uglify())
      .pipe(sourcemaps.write())
      .pipe(gulp.dest("./dist"));
  }

  // Scripts for the front page
  buildScriptsForPage("js/home", "home.js");
  // Scrips for the "email sent" page
  buildScriptsForPage("js/emailsent", "emailsent.js");
});

// Watching

gulp.task("watch", function() {
  gulp.watch("./sass/**/*.sass", ["sass"]);
  gulp.watch("./js/**/*.js", ["js"]);
});

gulp.task("default", ["watch"]);


Update text index to include url

Update text index to include url

--- src/lib/db.js
+++ src/lib/db.js
@@ -9,6 +9,7 @@
             instance = db
             //Set up db index on pages collection
             instance.collection('pages').ensureIndex({
+                "url": "text",
                 "title": "text",
                 "post.city": "text",
                 "post.content": "text",
@@ -17,6 +18,7 @@
             }, {
                 "weights": {
                     "title": 20,
+                    "url": 18,
                     "post.city": 15,
                     "post.food": 10,
                     "post.product_type": 5,

<|original_code|>
var client = require('mongodb').MongoClient

var instance = false

module.exports = {
    connect: function(config, callback) {
        client.connect(config.database.host+config.database.name, function(err, db){
            //Make db instance available to the rest of the module
            instance = db
            //Set up db index on pages collection
            instance.collection('pages').ensureIndex({
                "title": "text",
                "post.city": "text",
                "post.content": "text",
                "post.food": "text",
                "post.product_type": "text"
            }, {
                "weights": {
                    "title": 20,
                    "post.city": 15,
                    "post.food": 10,
                    "post.product_type": 5,
                    "post.content": 3
                },
                "default_language": "swedish"
            })

            callback(db)

        })
    },
    instance: function() {
        return instance
    },
    disconnect: function() {
        instance.close()
    }
}
<|edits_diff|>
--- src/lib/db.js
+++ src/lib/db.js
@@ -9,6 +9,7 @@
             instance = db
             //Set up db index on pages collection
             instance.collection('pages').ensureIndex({
+                "url": "text",
                 "title": "text",
                 "post.city": "text",
                 "post.content": "text",
<|current_version|>
var client = require('mongodb').MongoClient

var instance = false

module.exports = {
    connect: function(config, callback) {
        client.connect(config.database.host+config.database.name, function(err, db){
            //Make db instance available to the rest of the module
            instance = db
            //Set up db index on pages collection
            instance.collection('pages').ensureIndex({
                "url": "text",
                "title": "text",
                "post.city": "text",
                "post.content": "text",
                "post.food": "text",
                "post.product_type": "text"
            }, {
                "weights": {
                    "title": 20,
                    "post.city": 15,
                    "post.food": 10,
                    "post.product_type": 5,
                    "post.content": 3
                },
                "default_language": "swedish"
            })

            callback(db)

        })
    },
    instance: function() {
        return instance
    },
    disconnect: function() {
        instance.close()
    }
}
<|next_version|>
var client = require('mongodb').MongoClient

var instance = false

module.exports = {
    connect: function(config, callback) {
        client.connect(config.database.host+config.database.name, function(err, db){
            //Make db instance available to the rest of the module
            instance = db
            //Set up db index on pages collection
            instance.collection('pages').ensureIndex({
                "url": "text",
                "title": "text",
                "post.city": "text",
                "post.content": "text",
                "post.food": "text",
                "post.product_type": "text"
            }, {
                "weights": {
                    "title": 20,
                    "url": 18,
                    "post.city": 15,
                    "post.food": 10,
                    "post.product_type": 5,
                    "post.content": 3
                },
                "default_language": "swedish"
            })

            callback(db)

        })
    },
    instance: function() {
        return instance
    },
    disconnect: function() {
        instance.close()
    }
}


Set SocialLinks to row layout

Set SocialLinks to row layout

--- src/components/SocialLinks/styled.js
+++ src/components/SocialLinks/styled.js
@@ -1,4 +1,5 @@
 import styled from 'styled-components'
+import mediaQuery from '../../styles/mediaQuery'

 export const SocialLinksWrapper = styled.nav``

@@ -9,6 +10,10 @@
   grid-auto-columns: 3.2rem;
   align-items: center;
   list-style: none;
+
+  ${mediaQuery.lessThan('socialLinks')`
+    grid-auto-flow: row;
+  `}
 `

 export const SocialLinksItem = styled.li``

<|original_code|>
import styled from 'styled-components'

export const SocialLinksWrapper = styled.nav``

export const SocialLinksList = styled.ul`
  display: grid;
  grid-gap: 0.8rem;
  grid-auto-flow: column;
  grid-auto-columns: 3.2rem;
  align-items: center;
  list-style: none;
`

export const SocialLinksItem = styled.li``

export const SocialLinksLink = styled.a`
  color: var(--text);
  transition: color 0.3s;
  font-size: 2.4rem;

  &:hover {
    color: var(--accent);
  }
`

<|edits_diff|>
--- src/components/SocialLinks/styled.js
+++ src/components/SocialLinks/styled.js
@@ -1,4 +1,5 @@
 import styled from 'styled-components'
+import mediaQuery from '../../styles/mediaQuery'

 export const SocialLinksWrapper = styled.nav``

<|current_version|>
import styled from 'styled-components'
import mediaQuery from '../../styles/mediaQuery'

export const SocialLinksWrapper = styled.nav``

export const SocialLinksList = styled.ul`
  display: grid;
  grid-gap: 0.8rem;
  grid-auto-flow: column;
  grid-auto-columns: 3.2rem;
  align-items: center;
  list-style: none;
`

export const SocialLinksItem = styled.li``

export const SocialLinksLink = styled.a`
  color: var(--text);
  transition: color 0.3s;
  font-size: 2.4rem;

  &:hover {
    color: var(--accent);
  }
`

<|next_version|>
import styled from 'styled-components'
import mediaQuery from '../../styles/mediaQuery'

export const SocialLinksWrapper = styled.nav``

export const SocialLinksList = styled.ul`
  display: grid;
  grid-gap: 0.8rem;
  grid-auto-flow: column;
  grid-auto-columns: 3.2rem;
  align-items: center;
  list-style: none;

  ${mediaQuery.lessThan('socialLinks')`
    grid-auto-flow: row;
  `}
`

export const SocialLinksItem = styled.li``

export const SocialLinksLink = styled.a`
  color: var(--text);
  transition: color 0.3s;
  font-size: 2.4rem;

  &:hover {
    color: var(--accent);
  }
`


Fix can't insert when grouping.

Fix can't insert when grouping.

--- app/assets/js/controller/sophancong/SoPhanCongListCtr.js
+++ app/assets/js/controller/sophancong/SoPhanCongListCtr.js
@@ -18,8 +18,10 @@
         this.callParent(arguments);
     },
     addNewRow: function () {
+        var lastModel = this.getView().getStore().last();
         var rec = Ext.create(this.modelClass);
         rec.set('phongBangId', this.getPhongBangId());
+        rec.set('ngayPhanCong', lastModel.get('ngayPhanCong'));
         this.mainStore.insert(this.mainStore.count(), rec);
     }
 });

<|original_code|>
/**
 * Created by dungvn3000 on 3/11/14.
 */

Ext.define('sunerp.controller.sophancong.SoPhanCongListCtr', {
    extend: 'sunerp.controller.core.BaseListEditController',
    modelClass: 'sunerp.model.SoPhanCong',
    inject: ['soPhanCongStore', 'userService'],
    config: {
        soPhanCongStore: null,
        phongBangId: null,
        userService: null
    },
    searchField: "nhanVien.maNv",
    init: function () {
        this.mainStore = this.getSoPhanCongStore();
        this.setPhongBangId(this.getUserService().getCurrentUser().phongBangId);
        this.callParent(arguments);
    },
    addNewRow: function () {
        var rec = Ext.create(this.modelClass);
        rec.set('phongBangId', this.getPhongBangId());
        this.mainStore.insert(this.mainStore.count(), rec);
    }
});
<|edits_diff|>
--- app/assets/js/controller/sophancong/SoPhanCongListCtr.js
+++ app/assets/js/controller/sophancong/SoPhanCongListCtr.js
@@ -18,6 +18,7 @@
         this.callParent(arguments);
     },
     addNewRow: function () {
+        var lastModel = this.getView().getStore().last();
         var rec = Ext.create(this.modelClass);
         rec.set('phongBangId', this.getPhongBangId());
         this.mainStore.insert(this.mainStore.count(), rec);
<|current_version|>
/**
 * Created by dungvn3000 on 3/11/14.
 */

Ext.define('sunerp.controller.sophancong.SoPhanCongListCtr', {
    extend: 'sunerp.controller.core.BaseListEditController',
    modelClass: 'sunerp.model.SoPhanCong',
    inject: ['soPhanCongStore', 'userService'],
    config: {
        soPhanCongStore: null,
        phongBangId: null,
        userService: null
    },
    searchField: "nhanVien.maNv",
    init: function () {
        this.mainStore = this.getSoPhanCongStore();
        this.setPhongBangId(this.getUserService().getCurrentUser().phongBangId);
        this.callParent(arguments);
    },
    addNewRow: function () {
        var lastModel = this.getView().getStore().last();
        var rec = Ext.create(this.modelClass);
        rec.set('phongBangId', this.getPhongBangId());
        this.mainStore.insert(this.mainStore.count(), rec);
    }
});
<|next_version|>
/**
 * Created by dungvn3000 on 3/11/14.
 */

Ext.define('sunerp.controller.sophancong.SoPhanCongListCtr', {
    extend: 'sunerp.controller.core.BaseListEditController',
    modelClass: 'sunerp.model.SoPhanCong',
    inject: ['soPhanCongStore', 'userService'],
    config: {
        soPhanCongStore: null,
        phongBangId: null,
        userService: null
    },
    searchField: "nhanVien.maNv",
    init: function () {
        this.mainStore = this.getSoPhanCongStore();
        this.setPhongBangId(this.getUserService().getCurrentUser().phongBangId);
        this.callParent(arguments);
    },
    addNewRow: function () {
        var lastModel = this.getView().getStore().last();
        var rec = Ext.create(this.modelClass);
        rec.set('phongBangId', this.getPhongBangId());
        rec.set('ngayPhanCong', lastModel.get('ngayPhanCong'));
        this.mainStore.insert(this.mainStore.count(), rec);
    }
});


Set initial state from app settings

Set initial state from app settings

--- app/reducers/cards.js
+++ app/reducers/cards.js
@@ -1,5 +1,11 @@
+
+const AppSettings = require('../AppSettings');

 var initialState = {
+  'weather': AppSettings.WEATHER_CARD_ENABLED,
+  'shuttle': AppSettings.SHUTTLE_CARD_ENABLED,
+  'events': AppSettings.EVENTS_CARD_ENABLED,
+  'news': AppSettings.NEWS_CARD_ENABLED
 }

 function cards(state = initialState, action) {

<|original_code|>

var initialState = {
}

function cards(state = initialState, action) {
  switch (action.type) {
    case 'SHOW_CARD':
      var newState = {...state};
      if (newState[action.id])
        newState[action.id] = true;
      return newState;

    case 'HIDE_CARD':
      var newState = {...state};
      if (newState[action.id])
        newState[action.id] = false;
      return newState;

    case 'ADD_CARD':
      var newState = {...state};
      // check for duplicate, early exit
      if (newState[action.id])
        return newState;

      newState[action.id] = true;
      return newState;

    case 'DELETE_CARD':
      var newState = {...state};
      delete newState[action.id];
      return newState;
  }
  return state;
}

module.exports = cards

<|edits_diff|>
--- app/reducers/cards.js
+++ app/reducers/cards.js
@@ -1,3 +1,5 @@
+
+const AppSettings = require('../AppSettings');

 var initialState = {
 }
<|current_version|>

const AppSettings = require('../AppSettings');

var initialState = {
}

function cards(state = initialState, action) {
  switch (action.type) {
    case 'SHOW_CARD':
      var newState = {...state};
      if (newState[action.id])
        newState[action.id] = true;
      return newState;

    case 'HIDE_CARD':
      var newState = {...state};
      if (newState[action.id])
        newState[action.id] = false;
      return newState;

    case 'ADD_CARD':
      var newState = {...state};
      // check for duplicate, early exit
      if (newState[action.id])
        return newState;

      newState[action.id] = true;
      return newState;

    case 'DELETE_CARD':
      var newState = {...state};
      delete newState[action.id];
      return newState;
  }
  return state;
}

module.exports = cards

<|next_version|>

const AppSettings = require('../AppSettings');

var initialState = {
  'weather': AppSettings.WEATHER_CARD_ENABLED,
  'shuttle': AppSettings.SHUTTLE_CARD_ENABLED,
  'events': AppSettings.EVENTS_CARD_ENABLED,
  'news': AppSettings.NEWS_CARD_ENABLED
}

function cards(state = initialState, action) {
  switch (action.type) {
    case 'SHOW_CARD':
      var newState = {...state};
      if (newState[action.id])
        newState[action.id] = true;
      return newState;

    case 'HIDE_CARD':
      var newState = {...state};
      if (newState[action.id])
        newState[action.id] = false;
      return newState;

    case 'ADD_CARD':
      var newState = {...state};
      // check for duplicate, early exit
      if (newState[action.id])
        return newState;

      newState[action.id] = true;
      return newState;

    case 'DELETE_CARD':
      var newState = {...state};
      delete newState[action.id];
      return newState;
  }
  return state;
}

module.exports = cards


import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { EntriesShape } from "../prop-types/entry.js";
import Entry from "./Entry.js";
import { List, AutoSizer } from "react-virtualized";

class Entries extends PureComponent {
    rowRenderer = ({ key, index, style }) => {
        const { entries, onSelectEntry, autoLoginEnabled = true } = this.props;
        return (
            <div style={style} key={key}>
                <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />
            </div>
        );
    };

    render() {
        const { entries } = this.props;
        return (
            <AutoSizer>
                {({ height, width }) => (
                    <List
                        width={width}
                        height={height}
                        rowCount={entries.length}
                        rowHeight={66}
                        rowRenderer={this.rowRenderer}
                        overscanRowCount={10}
                    />
                )}
            </AutoSizer>
        );
    }
}

Entries.propTypes = {
    entries: EntriesShape,
    sourcesUnlocked: PropTypes.number,
    autoLoginEnabled: PropTypes.bool,
    onSelectEntry: PropTypes.func.isRequired
};

export default Entries;

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { Divider } from "@blueprintjs/core";
import { EntriesShape } from "../prop-types/entry.js";
import Entry from "./Entry.js";
import { List, AutoSizer } from "react-virtualized";

class Entries extends PureComponent {
    rowRenderer = ({ key, index, style }) => {
        const { entries, onSelectEntry, autoLoginEnabled = true } = this.props;
        return (
            <div style={style} key={key}>
                <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />
                <Divider />
            </div>
        );
    };

    render() {
        const { entries } = this.props;
        return (
            <AutoSizer>
                {({ height, width }) => (
                    <List
                        width={width}
                        height={height}
                        rowCount={entries.length}
                        rowHeight={66}
                        rowRenderer={this.rowRenderer}
                        overscanRowCount={10}
                    />
                )}
            </AutoSizer>
        );
    }
}

Entries.propTypes = {
    entries: EntriesShape,
    sourcesUnlocked: PropTypes.number,
    autoLoginEnabled: PropTypes.bool,
    onSelectEntry: PropTypes.func.isRequired
};

export default Entries;

Add divider to the list

Add divider to the list

--- source/shared/components/Entries.js
+++ source/shared/components/Entries.js
@@ -1,6 +1,7 @@
 import React, { PureComponent } from "react";
 import PropTypes from "prop-types";
 import styled from "styled-components";
+import { Divider } from "@blueprintjs/core";
 import { EntriesShape } from "../prop-types/entry.js";
 import Entry from "./Entry.js";
 import { List, AutoSizer } from "react-virtualized";
@@ -11,6 +12,7 @@
         return (
             <div style={style} key={key}>
                 <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />
+                <Divider />
             </div>
         );
     };

import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { Divider } from "@blueprintjs/core";
import { EntriesShape } from "../prop-types/entry.js";
import Entry from "./Entry.js";
import { List, AutoSizer } from "react-virtualized";

class Entries extends PureComponent {
    rowRenderer = ({ key, index, style }) => {
        const { entries, onSelectEntry, autoLoginEnabled = true } = this.props;
        return (
            <div style={style} key={key}>
                <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />
            </div>
        );
    };

    render() {
        const { entries } = this.props;
        return (
            <AutoSizer>
                {({ height, width }) => (
                    <List
                        width={width}
                        height={height}
                        rowCount={entries.length}
                        rowHeight={66}
                        rowRenderer={this.rowRenderer}
                        overscanRowCount={10}
                    />
                )}
            </AutoSizer>
        );
    }
}

Entries.propTypes = {
    entries: EntriesShape,
    sourcesUnlocked: PropTypes.number,
    autoLoginEnabled: PropTypes.bool,
    onSelectEntry: PropTypes.func.isRequired
};

export default Entries;

<|original_code|>
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { EntriesShape } from "../prop-types/entry.js";
import Entry from "./Entry.js";
import { List, AutoSizer } from "react-virtualized";

class Entries extends PureComponent {
    rowRenderer = ({ key, index, style }) => {
        const { entries, onSelectEntry, autoLoginEnabled = true } = this.props;
        return (

                <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />

        );
    };

    render() {
        const { entries } = this.props;
        return (
            <AutoSizer>
                {({ height, width }) => (
                    <List
                        width={width}
                        height={height}
                        rowCount={entries.length}
                        rowHeight={66}
                        rowRenderer={this.rowRenderer}
                        overscanRowCount={10}
                    />
                )}
            </AutoSizer>
        );
    }
}

Entries.propTypes = {
    entries: EntriesShape,
    sourcesUnlocked: PropTypes.number,
    autoLoginEnabled: PropTypes.bool,
    onSelectEntry: PropTypes.func.isRequired
};

export default Entries;

<|edits_diff|>
--- source/shared/components/Entries.js
+++ source/shared/components/Entries.js
@@ -1,6 +1,7 @@
 import React, { PureComponent } from "react";
 import PropTypes from "prop-types";
 import styled from "styled-components";
+import { Divider } from "@blueprintjs/core";
 import { EntriesShape } from "../prop-types/entry.js";
 import Entry from "./Entry.js";
 import { List, AutoSizer } from "react-virtualized";
<|current_version|>
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { Divider } from "@blueprintjs/core";
import { EntriesShape } from "../prop-types/entry.js";
import Entry from "./Entry.js";
import { List, AutoSizer } from "react-virtualized";

class Entries extends PureComponent {
    rowRenderer = ({ key, index, style }) => {
        const { entries, onSelectEntry, autoLoginEnabled = true } = this.props;
        return (

                <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />

        );
    };

    render() {
        const { entries } = this.props;
        return (
            <AutoSizer>
                {({ height, width }) => (
                    <List
                        width={width}
                        height={height}
                        rowCount={entries.length}
                        rowHeight={66}
                        rowRenderer={this.rowRenderer}
                        overscanRowCount={10}
                    />
                )}
            </AutoSizer>
        );
    }
}

Entries.propTypes = {
    entries: EntriesShape,
    sourcesUnlocked: PropTypes.number,
    autoLoginEnabled: PropTypes.bool,
    onSelectEntry: PropTypes.func.isRequired
};

export default Entries;

<|next_version|>
import React, { PureComponent } from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import { Divider } from "@blueprintjs/core";
import { EntriesShape } from "../prop-types/entry.js";
import Entry from "./Entry.js";
import { List, AutoSizer } from "react-virtualized";

class Entries extends PureComponent {
    rowRenderer = ({ key, index, style }) => {
        const { entries, onSelectEntry, autoLoginEnabled = true } = this.props;
        return (

                <Entry entry={entries[index]} onSelectEntry={onSelectEntry} autoLoginEnabled={autoLoginEnabled} />
                <Divider />

        );
    };

    render() {
        const { entries } = this.props;
        return (
            <AutoSizer>
                {({ height, width }) => (
                    <List
                        width={width}
                        height={height}
                        rowCount={entries.length}
                        rowHeight={66}
                        rowRenderer={this.rowRenderer}
                        overscanRowCount={10}
                    />
                )}
            </AutoSizer>
        );
    }
}

Entries.propTypes = {
    entries: EntriesShape,
    sourcesUnlocked: PropTypes.number,
    autoLoginEnabled: PropTypes.bool,
    onSelectEntry: PropTypes.func.isRequired
};

export default Entries;


Allow credentials for CORS requests

Allow credentials for CORS requests

--- js/hal/http/client.js
+++ js/hal/http/client.js
@@ -9,6 +9,9 @@
   var jqxhr = $.ajax({
     url: url,
     dataType: 'json',
+    xhrFields: {
+      withCredentials: true
+    },
     headers: this.defaultHeaders,
     success: function(resource, textStatus, jqXHR) {
       self.vent.trigger('response', {
@@ -25,6 +28,8 @@
 HAL.Http.Client.prototype.request = function(opts) {
   var self = this;
   opts.dataType = 'json';
+  opts.xhrFields = opts.xhrFields || {};
+  opts.xhrFields.withCredentials = opts.xhrFields.withCredentials || true;
   self.vent.trigger('location-change', { url: opts.url });
   return jqxhr = $.ajax(opts);
 };

<|original_code|>
HAL.Http.Client = function(opts) {
  this.vent = opts.vent;
  this.defaultHeaders = { 'Accept': 'application/hal+json, application/json, */*; q=0.01' };
};

HAL.Http.Client.prototype.get = function(url) {
  var self = this;
  this.vent.trigger('location-change', { url: url });
  var jqxhr = $.ajax({
    url: url,
    dataType: 'json',
    headers: this.defaultHeaders,
    success: function(resource, textStatus, jqXHR) {
      self.vent.trigger('response', {
        resource: resource,
        jqxhr: jqXHR,
        headers: jqXHR.getAllResponseHeaders()
      });
    }
  }).error(function() {
    self.vent.trigger('fail-response', { jqxhr: jqxhr });
  });
};

HAL.Http.Client.prototype.request = function(opts) {
  var self = this;
  opts.dataType = 'json';
  self.vent.trigger('location-change', { url: opts.url });
  return jqxhr = $.ajax(opts);
};

HAL.Http.Client.prototype.updateDefaultHeaders = function(headers) {
  this.defaultHeaders = headers;
};

HAL.Http.Client.prototype.getDefaultHeaders = function() {
  return this.defaultHeaders;
};

<|edits_diff|>
--- js/hal/http/client.js
+++ js/hal/http/client.js
@@ -9,6 +9,9 @@
   var jqxhr = $.ajax({
     url: url,
     dataType: 'json',
+    xhrFields: {
+      withCredentials: true
+    },
     headers: this.defaultHeaders,
     success: function(resource, textStatus, jqXHR) {
       self.vent.trigger('response', {
<|current_version|>
HAL.Http.Client = function(opts) {
  this.vent = opts.vent;
  this.defaultHeaders = { 'Accept': 'application/hal+json, application/json, */*; q=0.01' };
};

HAL.Http.Client.prototype.get = function(url) {
  var self = this;
  this.vent.trigger('location-change', { url: url });
  var jqxhr = $.ajax({
    url: url,
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    headers: this.defaultHeaders,
    success: function(resource, textStatus, jqXHR) {
      self.vent.trigger('response', {
        resource: resource,
        jqxhr: jqXHR,
        headers: jqXHR.getAllResponseHeaders()
      });
    }
  }).error(function() {
    self.vent.trigger('fail-response', { jqxhr: jqxhr });
  });
};

HAL.Http.Client.prototype.request = function(opts) {
  var self = this;
  opts.dataType = 'json';
  self.vent.trigger('location-change', { url: opts.url });
  return jqxhr = $.ajax(opts);
};

HAL.Http.Client.prototype.updateDefaultHeaders = function(headers) {
  this.defaultHeaders = headers;
};

HAL.Http.Client.prototype.getDefaultHeaders = function() {
  return this.defaultHeaders;
};

<|next_version|>
HAL.Http.Client = function(opts) {
  this.vent = opts.vent;
  this.defaultHeaders = { 'Accept': 'application/hal+json, application/json, */*; q=0.01' };
};

HAL.Http.Client.prototype.get = function(url) {
  var self = this;
  this.vent.trigger('location-change', { url: url });
  var jqxhr = $.ajax({
    url: url,
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    headers: this.defaultHeaders,
    success: function(resource, textStatus, jqXHR) {
      self.vent.trigger('response', {
        resource: resource,
        jqxhr: jqXHR,
        headers: jqXHR.getAllResponseHeaders()
      });
    }
  }).error(function() {
    self.vent.trigger('fail-response', { jqxhr: jqxhr });
  });
};

HAL.Http.Client.prototype.request = function(opts) {
  var self = this;
  opts.dataType = 'json';
  opts.xhrFields = opts.xhrFields || {};
  opts.xhrFields.withCredentials = opts.xhrFields.withCredentials || true;
  self.vent.trigger('location-change', { url: opts.url });
  return jqxhr = $.ajax(opts);
};

HAL.Http.Client.prototype.updateDefaultHeaders = function(headers) {
  this.defaultHeaders = headers;
};

HAL.Http.Client.prototype.getDefaultHeaders = function() {
  return this.defaultHeaders;
};